RDA5807MをArduinoで制御　DSP　ラジオモジュール　

#はじめに
* 電子工作の初心者としてDSPラジオに挑戦。
* 作例も多いRDA5807シリーズだが、複数のSlaveアドレスがあるなど、難しいところもあった。備忘録もかねて記録を残すもの。ほかのDSPラジオモジュールも解説予定。

#使用したもの
* Aitendoさんのモジュール。RDA5807-M2(http://www.aitendo.com/product/13265)
* IC（RDA5807M)のデータシート
* Arduino Uno互換機(ELEGOO)

#モジュールについて
* Aitendoさんには2種類のモジュールあり。「RDA5807-M2」と「RDA5807-M」。ここではM2を利用したが、Mについても後日更新予定（ほとんど違いがない）。
* モジュールのDIP変換については、先例がいくつかあり。私も手作業でやってみたが、Aitendoさんの専用基盤が扱いやすいと思う。

#配線
* モジュールの説明通りにつなぐだけ。イヤフォンに直接出力できる。出力コンデンサも不要。 
![RDA5807M2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/720dbe5f-3947-ea2f-0e58-cec166001571.jpeg)

#Slaveアドレスについて
* ここが一番わからなかった。結論から書くと以下の通り。
    * 0x10　レジスタ連続書込/読込用
    * 0X11　個別レジスタ書込/読込用　　
    * 0X60　TEA5767互換モード（ここでは取り扱わず）
* ArduinoのI2C Scanner を使うと、上記の3つのSlaveアドレスが表示される。複数のアドレスが同時に使えるモジュールは珍しいと思う（最後の考察ご参照）。これはArduino用のアドレスなので、他マイコンで利用する場合は適宜変換が必要。
* 0x10　レジスタ連続書込/読込用
    * このアドレスを用いると、自動的に以下のレジスタから連続して書き込まれる。個別のレジスタを指定する必要がない。書込：02Hから　　読込：0AHから。
    * 書込コード例。このコードで02Hと03Hにすべて0が書き込まれる。読込コード例は割愛（ほとんど使わないと思うので）。

```
Wire.beginTransmission(0X10); //continuous write
                              //no need to specify register
  Wire.write(0X00); // 02h(HighByte02) 
  Wire.write(0X00); // 02l(LowByte02)
  Wire.write(0X00); // 03h
  Wire.write(0X00); // 03l 
Wire.endTransmission();   
```
 
* 0x11　個別レジスタ書込/読込用
    * このアドレスを用いると、個別のレジスタに書き込むことになる。いわゆる普通のI2Cデバイスを利用するのと同じ。0X10より使いやすいので、0X11だけで十分な気もします。
    * 一応書込コード例。レジスタ05Hにデータを書き込めます。読込は割愛。普通のコードで読めます。

```
Wire.beginTransmission(0X11); //normal i2c
  Wire.write(0X05); // specify register 05h
  Wire.write(0X88); // 05h
  Wire.write(0b10001000); // 05l VOLUMExxxx
Wire.endTransmission();  
```

#コード作成のポイント
* TUNEビット　0→1。ここも解りにくかった。特定周波数をレジスタに書き込む場合、以下の手順を踏む必要がある。
    * まず、TUNEビット（03h.4)をゼロにする。
    * 次に、特定周波数とともに、TUNEビットを１としてレジスタに書き込む。
* DMUTEビット1（02h.14)。ENABLEビット1(02h.0)。モジュールを起動させるために、この2つのビットを設定する必要がある。

#動作コード
* 特定の周波数を書き込むシンプルなコード。上記のポイントも考慮してざっくり以下の形。詳細はコードとデータシート見てください。
    * レジスタ02hと03hに0を書き込む。TUNE、DMUTE、ENABLEがゼロになる。
    * 希望する周波数（ここでは80MHｚ）からCHANビット列を算出。
    * このCHANビット列とともに、TUNE、DMUTE、ENABLEを1としてレジスタ（02h、03h）に書き込む。
    * 続けて、04hと05hにVolumeなど書き込む。ここまではアドレス0x10を用いて連続書き込み。
    * 0x11の練習として、05hのVolumeを個別に書き込み。

```

#include <Wire.h>

//For Arduino Uno

/*
Simple code for RDA5807M. Sepcify frequency.
For Japanese FM station.
*/

/* 
Slave address: let's use I2C scanner.
You will find three slave addresses.
 0x10: automatic continuous read/write
        read: from 0AH   write: from 02H 
 0x11: specify register (normal i2c)
 0x60: tea5767 mode
*/

void setup()
{
delay(100);

Wire.begin();

//reset 02H and 03H 
//TUNE set to 0
Wire.beginTransmission(0X10); //continuous write
                              //no need to specify register
  Wire.write(0X00); // 02h(HighByte02) DMUTE0 
  Wire.write(0X00); // 02l(LowByte02)
  Wire.write(0X00); // 03h
  Wire.write(0X00); // 03l TUNE0 ENABLE0
Wire.endTransmission();

//write data from 02H to 05H. 
// FREQ -> CHAN -> 03

float freq  = 80 ;///Frequency! 80 82.5 93 78.2 

int chan = freq*10 - 760;
byte h3 = chan >>2; //Highbyte03
byte l3 = chan & 0b00000011;
l3 = l3<<6;
l3 = l3 | 0b00011000; //Lowbyte03 TUNE1 BAND10 SPACE00

Wire.beginTransmission(0X10); //continuous write
　Wire.write(0xc2); //02h DMUTE1 SEEK0 水晶利用
　Wire.write(0x85); //02l ENABLE1 CLK000(32768hz)
　Wire.write(h3); //03h freq 
　Wire.write(l3); //03l freq  TUNE0->1 BAND10
  Wire.write(0b00001010); //04h DE50
  Wire.write(0x00); //04l 
  Wire.write(0x88); //05h 
  Wire.write(0x81); //05l VOLUME0001
Wire.endTransmission();

delay(100);

//0x11: specify 05H. VOL0001->1000
Wire.beginTransmission(0X11); //normal i2c
  Wire.write(0X05); // specify register 05h
  Wire.write(0X88); // 05h
  Wire.write(0b10001000); // 05l VOLUMExxxx
Wire.endTransmission();
}

void loop() {
  // put your main code here, to run repeatedly:
}
```

#考察
* コード作成には、SILICON LABSのAN230が役に立った。
* ここ　(https://www.rockbox.org/wiki/FmTunerHardware) によると、RDA58XXシリーズはどうもSilicon LabsのSi47XXと似た作りになっている模様。このSi47XXシリーズ（後日公開予定）だが、発表が古いせいか、連続書込み方式しかサポートしておらず、コード作成が面倒くさい。
* RDA5807はおそらく、この連続書込み方式を引き継ぐとともに、利便性のために個別書込み方式もサポートしたと思われる。これが複数のアドレスを持っている理由と推定しています。

#おまけ
* 本件が上手く動いたため、ラジオモジュールにはまってしまい、以下のモジュール、ICにも手を出してしまいました。順不同でゆっくり公開予定。
* BK1088（癖があって難しい）、AR1019、SP3777、Si4730、Si4702、M6955、RDA5807（SEEK)、KT0915、QN8065/QN8035、TEA5767、RDA5807FP、RTC6218