2017年6月3日土曜日

サンプルレートコンバータをArduinoのI2Cで制御

DE0nano用の自作オーディオ入出力基板のサンプルレートコンバータはI2Cで初期設定しないと動作しません。普通ならFPGAから制御するところですが、私の実力不足であえてAVRマイコン ATmega328を付けています。このAVRマイコンチップは、Arduino UNOと同じなのでArduinoの開発環境を使ってみることにしました。

AVRマイコンとArduinoピン名称の対比

次の表は、ATmega328とArduino UNO ピン名称の対応を示したものです。自作基板の設計段階では、ArduinoIDEを使う想定はなかったのでアナログ入力端子にデジタル入力を割り当ててしまいましたが、調べたところ特に問題なく使えるようです。



ArduinoでのI2C制御

こんな感じに書くだけで、I2Cが使えます。
Wire.begin(); // join i2c bus (address optional for master)
Wire.write(0x08);   // Register 08: Transmitter Control Register 2
Wire.write(0x00);
Wire.endTransmission();
Cで書くのとやってることは同じですが、わかりやすく関数化されてます。これ、シンプルで簡単にみえますけどI2Cの信号のやりとりをイメージできないとまるでブラックボックスです。何はともあれ、SRC4382のレジスタ設定をべた書きするだけで呆気なく動いてくれました。

今回のArduinoスケッチ

#include <Wire.h>

#define ASRC_INT  2
#define MCU_INT  3
#define MCU_RDY  4
#define DIPSW0  5
#define DIPSW1  6
#define DIPSW2  7
#define DIPSW3  8
#define LED3  9
#define LED4  10
#define RST  A3
#define SRC4382_ADDR  0x70


void setup() {
  pinMode(ASRC_INT, INPUT);
  pinMode(MCU_INT, INPUT);
  pinMode(MCU_RDY, OUTPUT);
  pinMode(DIPSW0, INPUT_PULLUP);
  pinMode(DIPSW1, INPUT_PULLUP);
  pinMode(DIPSW2, INPUT_PULLUP);
  pinMode(DIPSW3, INPUT_PULLUP);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(RST, INPUT);

  Wire.begin(); // join i2c bus (address optional for master)
  SRC4382_INIT();
}


void loop() {

}

void SRC4382_INIT() {
  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x01);   // Register 01: Power-Down and Reset
  Wire.write(0x37); 
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x03);   // Register 03: Port A Control Register 1
  Wire.write(0x30);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x07);   // Register 07: Transmitter Control Register 1
  Wire.write(0x60);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x08);   // Register 08: Transmitter Control Register 2
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x09);   // Register 09: Transmitter Control Register 3
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x0D);   // Register 0D: Receiver Control Register 1
  Wire.write(0x08);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x0E);   // Register 0E: Receiver Control Register 2
  Wire.write(0x08);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x0F);   // Receiver PLL1 Configuration Register 1
  Wire.write(0x22);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x10);   // Receiver PLL1 Configuration Register 2
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x11);   // Receiver PLL1 Configuration Register 3
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x2D);   // SRC Control Register 1
  Wire.write(0x02);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x2E);   // SRC Control Register 2
  Wire.write(0x20);
  Wire.endTransmission();

  Wire.beginTransmission(SRC4382_ADDR);
  Wire.write(0x2F);   // SRC Control Register 3
  Wire.write(0x00);
  Wire.endTransmission();
    
  }

0 件のコメント:

コメントを投稿