sduinoは僕のような素人には難しすぎるのだが、プリミティブなマイコンの世界の新鮮さもあり、いろいろ試してみている。いきなり回路組んでコード書きまくるスキルは無いものの、まずは一通りの機能を試してみたいと思う。
今回はYAMAHAのFM音源チップを積んだYMF825を試す。小さくしなくていいからみんな使いやすいような汎用的なArduinoライブラリを出して敷居を下げるのが先ではないか?と強く思うのです。ということは、Arduino用のサンプルプログラムは分かりにくわけですが、逆にプリミティブな書き方になっているので、STM8BLUEことSTM8S103F3P6ボードでも動かせるのではないかと思い至ったわけです。
下記がそのコード。そのままでは動かないので手を入れていますが、変更点は少ないです。STM8BLUE用のピンアサインも入れておきました。SPI接続です。STM8BLUEは3.3V動作なんですが、6Vくらいでも動作するので、まあちょっと試すくらいなら5Vでも大丈夫でしょうということでYMF825ボードはデフォルトの5V設定のまま繋ぎました(これも本来はジャンパーで手軽に切り替え出来るべきなのに…)。ST-LINKの3.3VピンでSTM8BLUEに給電している場合は、STM8BLUEから5VをYMF825に給電できないので少し工夫が必要です。ST-LINKから給電しても良いでしょう。
コードの変更点は….
- SSとRSTのピン動作をノーマルなArduino方式に変えています。元サンプルではATmega328Pのレジスタを直接操作していますが、まとめて初期化するにはそれで良いと思うのですが、デバイスを固定化してしまうので、それを避けるため普通にしました。ただし、STM8BLUEでも同様にレジスタいじってというやり方はできます。ATmegaとは異なりますが。
- sduinoはC言語しか使えないのでC++のクラスとかが使えません。sduinoではそれっぽく関数に置き換わります。なお、SPI初期化の転送スピードの指定は適当にいれたら動いたのでそのままにしてます。
- サンプルを実行すると適当な音が繰り返されるのですが、元サンプルでは5音を繰り返すという音楽的に気持ち悪いフレーズだったので(わざと?)もう少しマシにしました。逆にわかりやすいフレーズが繰り返されるのでこれはこれでアレかもですがw
といったところ。まだワーニング出たりしますが、そもそも出まくりなので放置しています。YMF825のパラメータをいじるところは変えてません。仕様書見ましたが面倒くさそうだったので。そのうちチャレンジしてみたいと思っています。
いずれにしてもこの検証で、STM8BLUEでSPIが使えることがわかりました。他にも色々サンプルを動かしてみたいと思っています。
/* * ymf825board sample * original .ino * https://github.com/yamaha-webmusic/ymf825board/blob/master/sample1/ymf825board_sample1/ymf825board_sample1.ino * * modify for sduino(https://github.com/tenbaht/sduino) * * 11.01.2017 STM8S103F3P6 RST_N- PC4 (D6) SS - PA3 (D2) MOSI - PC6 (D8) MISO - PC7 (D9) SCK - PC5 (D7) */ #include //0 :5V 1:3.3V #define OUTPUT_power 0 #define SS_PIN PA3 #define RST_PIN PC4 // only for Arduino UNO void set_ss_pin(int val) { if(val ==HIGH){ digitalWrite(SS_PIN, HIGH); } else { digitalWrite(SS_PIN, LOW); } } // only for Arduino UNO void set_rst_pin(int val) { if(val ==HIGH){ digitalWrite(RST_PIN, HIGH); } else { digitalWrite(RST_PIN, LOW); } } void if_write(char addr,unsigned char* data,char num){ char i; char snd; set_ss_pin(LOW); SPI_transfer(addr); for(i=0;i<num;i++){ SPI_transfer(data[i]); } set_ss_pin(HIGH); } void if_s_write(char addr,unsigned char data){ if_write(addr,&data,1); } unsigned char if_s_read(char addr){ unsigned char rcv; set_ss_pin(LOW); SPI_transfer(0x80|addr); rcv = SPI_transfer(0x00); set_ss_pin(HIGH); return rcv; } void init_825(void) { set_rst_pin(LOW); delay(1); set_rst_pin(HIGH); if_s_write( 0x1D, OUTPUT_power ); if_s_write( 0x02, 0x0E ); delay(1); if_s_write( 0x00, 0x01 );//CLKEN if_s_write( 0x01, 0x00 ); //AKRST if_s_write( 0x1A, 0xA3 ); delay(1); if_s_write( 0x1A, 0x00 ); delay(30); if_s_write( 0x02, 0x04 );//AP1,AP3 delay(1); if_s_write( 0x02, 0x00 ); //add if_s_write( 0x19, 0xF0 );//MASTER VOL if_s_write( 0x1B, 0x3F );//interpolation if_s_write( 0x14, 0x00 );//interpolation if_s_write( 0x03, 0x01 );//Analog Gain if_s_write( 0x08, 0xF6 ); delay(21); if_s_write( 0x08, 0x00 ); if_s_write( 0x09, 0xF8 ); if_s_write( 0x0A, 0x00 ); if_s_write( 0x17, 0x40 );//MS_S if_s_write( 0x18, 0x00 ); } void set_tone(void){ unsigned char tone_data[35] ={ 0x81,//header //T_ADR 0 0x01,0x85, 0x00,0x7F,0xF4,0xBB,0x00,0x10,0x40, 0x00,0xAF,0xA0,0x0E,0x03,0x10,0x40, 0x00,0x2F,0xF3,0x9B,0x00,0x20,0x41, 0x00,0xAF,0xA0,0x0E,0x01,0x10,0x40, 0x80,0x03,0x81,0x80, }; if_s_write( 0x08, 0xF6 ); delay(1); if_s_write( 0x08, 0x00 ); if_write( 0x07, &tone_data[0], 35 );//write to FIFO } void set_ch(void){ if_s_write( 0x0F, 0x30 );// keyon = 0 if_s_write( 0x10, 0x71 );// chvol if_s_write( 0x11, 0x00 );// XVB if_s_write( 0x12, 0x08 );// FRAC if_s_write( 0x13, 0x00 );// FRAC } void keyon(unsigned char fnumh, unsigned char fnuml){ if_s_write( 0x0B, 0x00 );//voice num if_s_write( 0x0C, 0x54 );//vovol if_s_write( 0x0D, fnumh );//fnum if_s_write( 0x0E, fnuml );//fnum if_s_write( 0x0F, 0x40 );//keyon = 1 } void keyoff(void){ if_s_write( 0x0F, 0x00 );//keyon = 0 } void setup() { pinMode(SS_PIN,OUTPUT); pinMode(RST_PIN,OUTPUT); set_ss_pin(HIGH); SPI_begin(); SPI_beginTransaction(SPISettings(8000000L,MSBFIRST,SPI_MODE0)); init_825(); set_tone(); set_ch(); } void loop() { keyon(0x14,0x65); delay(500); keyoff(); delay(200); keyon(0x1c,0x11); delay(500); keyoff(); delay(200); keyon(0x1c,0x42); delay(500); keyoff(); delay(200); keyon(0x1c,0x5d); delay(500); keyoff(); delay(200); keyon(0x24,0x17); delay(500); keyoff(); delay(200); keyon(0x24,0x17); delay(500); keyoff(); delay(200); keyon(0x24,0x17); delay(1000); keyoff(); delay(400); }
コメントを残す