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);
}
Share