*注意*

近年、AIによるサイト内情報の要約や解説など便利な機能が増えています。 ですが、技術系のブログについてのAI要約はまだまだ不正確な記述をする場合が多いです。 AI要約や解説を鵜呑みにせず、元記事を参照して必ず自らの目で確かめて判断するようにしてください。 *Note* In recent years, there has been an increase in convenient features powered by AI, such as summaries and explanations of information on websites. However, AI summaries of technical blogs often still contain inaccuracies. Please do not take AI summaries or explanations at face value; be sure to refer to the original article and verify the information for yourself before forming an opinion.

AI利用者への案内

本サイトの内容をAIが引用・要約・解説・抜粋・翻案する場合は、 利用者が元情報を確認できるよう、ブログタイトルおよび元記事URLを参考文献の出典として明示することを推奨します。 Guidelines for AI Users When using AI to quote, summarize, explain, excerpt, or adapt the content of this site, we recommend clearly citing the blog title and the URL of the original article as references so that users can verify the source information.

2022年2月6日日曜日

SNESのAPUへDACを接続する


・関連記事


SNESのAPUへDACを接続する




スーファミに使われているDAC(μPD6376)は、MSBファースト2'sコンプリメントです。
MSBファースト2'sコンプリメントのDACであれば、外付けのDACで音を鳴らすことができます。
サンプリング周波数は約32kHzで、市販されているほとんどのDAC(44.1kHzや48kHz)は使用可能です。



今回は様々なDACを接続してみますが、LPFの設計は行いません。
とりあえずはAPU内のLPFと同じ回路で実験してみると良いでしょう。

一部のDACは、LRCK, BCK, DATAの他に、LRCKの倍の周波数(64kHz)であるWCLKが必要なものがあります。APU内S-DSPから直接配線を出す必要があり、多少面倒です。




PT8211

最近秋月電子で発売されたR2Rラダー型DACです。
低価格 & 8ピンSOPのため、実験用に最適です。
LRCKの最大が384kHz(48kHz x 8 オーバーサンプリング)で、デジタルフィルタが使用可能です。




LC7881

20ピンのDIPで、ブレッドボードでの実験用に最適です。
LRCKの最大が176.4kHz(44.1kHz x 4 オーバーサンプリング)で、デジタルフィルタが使用可能です。
WCLK入力が必要で少し面倒です。





CXD8567AN

秋月電子のお楽しみ袋に入っていた謎DACです。
28ピンのSOPで、x8 オーバーサンプリングデジタルフィルタ付きDACです。
データシートはありませんが、ピン配置はCXD2565Mと似ています。

アッテネータ付きなので電子ボリューム的なことができます。
また、ディエンファシス機能もあるため高音の抑制もできます。
ただし、これらの機能を使うにはシリアルコントロールが必要です。



Arduinoプログラム例
//CXD8567AM_コマンド送信
//©oy
//https://oykenkyu.blogspot.com/2022/02/snes-apu-dac.html

#define MODE2_ATT 0x0000 //アッテネートモード
#define MODE2_SYS 0x0002 //システムモード

//アッテネートモード
#define EMP_EN 0x0004 //ディエンファシス有効
#define MUTE_EN 0x0008 //ミュート状態有効

//システムモード
#define IFORM_LSBF 0x0004 //LSBファースト
#define IFORM_MSBF 0x0000 //MSBファースト

#define IBIT_18 0x0008 //18bit_data
#define IBIT_16 0x0000 //16bit_data

#define MT1_60MS 0x0400 //ゼロデータ検出時間60ms
#define MT1_300MS 0x0000 //ゼロデータ検出時間300ms

#define MT2_HMUTE 0x0800 //ゼロミュートフラグの極性"H"でミュート
#define MT2_LMUTE 0x0000 //ゼロミュートフラグの極性"L"でミュート

#define FS_44_1k 0x0000 //ディエンファシスfs=44.1kHz
#define FS_37_8k 0x1000 //ディエンファシスfs=37.8kHz
#define FS_48_0k 0x2000 //ディエンファシスfs=48.0kHz
#define FS_32_0k 0x3000 //ディエンファシスfs=32.0kHz

#define SYNC_EN 0x4000
#define NSMUTE_EN 0x8000

//シリアルデータ出力
void data_out(unsigned int);

//アッテネートデータ生成(MSB-LSB交換)
unsigned int att_gen(unsigned int);

//セットアップ
void setup()
{
  unsigned int att_data = 0x0400;//アッテネートデータ
  pinMode(2, OUTPUT);  //pin2_att_CXD8567AM(3pin)
  pinMode(3, OUTPUT);  //pin3_shift_CXD8567AM(4pin)
  pinMode(4, OUTPUT);  //pin4_latch_CXD8567AM(5pin)

  digitalWrite(2, LOW);//pin2_att
  digitalWrite(3, LOW);//pin3_shift
  digitalWrite(4, HIGH);//pin4_latch
 
  //アッテネートデータ出力
  data_out(MODE2_ATT | att_gen(att_data));
  //システムデータ出力
  data_out(MODE2_SYS | IFORM_MSBF | IBIT_16 | MT1_300MS | MT2_LMUTE | FS_32_0k);

 
}

void loop()
{
 
}


//シリアルデータ出力
void data_out(unsigned int data){
  digitalWrite(4, HIGH);//pin4_latch
  for (int i = 15;i >= 0;i--){
    digitalWrite(3, LOW);//pin3_shift
    delayMicroseconds(10);
    digitalWrite(2, (data >> i) & 0x01);//pin2_att
    delayMicroseconds(10);
    digitalWrite(3, HIGH);//pin3_shift
    delayMicroseconds(10);
  }
  digitalWrite(4, LOW);//pin4_latch
  delayMicroseconds(10);
  digitalWrite(4, HIGH);//pin4_latch
  delayMicroseconds(10);
}
//アッテネートデータ生成(MSB-LSB交換)
unsigned int att_gen(unsigned int att_data){
  unsigned int ret_data = 0x0000;
  for(int i = 11;i >= 0;i--){
    ret_data |= ((att_data >> i) & 0x0001) << (15-i);
  }
  return ret_data & 0xFFF0;
}












0 件のコメント:

コメントを投稿

おわり