LoginSignup
4
1

More than 5 years have passed since last update.

Raspberry PI でYMF825を鳴らす

Last updated at Posted at 2018-01-02

YMF825をRaspberry PI(PI 3 model B)につないて、サンプルプログラムを動作させてみました。YMF825はFM音源です。

接続

setudzoku2.png

3.3V でも動作するかと思ったのですが、今は5Vでないと動作しませんでした。

サンプルプログラム

動作させたサンプルプログラムはこちら です。

コンパイルするには、
1. common の下の全ファイル
2. raspi の下のfmsd1_raspi.c
3. main 関数 ( fm825test.cと名前を付けました。 )
4. bcm2835 ライブラリ
が必要です。1,2,3 は全部まとめて同じフォルダーにコピーしました。

makefile

OBJS= fmasgn.o fmif.o fmnote.o\
    fmpart.o fmtone.o fmvoice.o fmsd1_raspi.o\
    fm825test.o

fm825test: $(OBJS)
    gcc -o fm825test $(OBJS) -l bcm2835

fmasgn.o:   fmasgn.c fmasgn.h fmtype.h
fmif.o:     fmif.c fmif.h 
fmnote.o:   fmnote.c fmnote.h fmtype.h
fmpart.o:   fmpart.c fmpart.h fmtype.h
fmtone.o:   fmtone.c fmtone.h fmtype.h
fmvoice.o:  fmvoice.c fmvoice.h fmtype.h
fmsd1_raspi.o:  fmsd1_raspi.c
fm825test.o:    fm825test.c fmif.h fmsd1.h  

.c.o:
    gcc -c $<

Main 関数

fm825test.c
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h> 
#include <bcm2835.h>

#include "fmif.h"
#include "fmsd1.h"

int main()
{
    int note=0x3c;

    if (!bcm2835_init()) return 1;

    initSPI();
    initSD1();
    Fmdriver_init();

    while(1){
        Fmdriver_sendMidi(0x90);
        Fmdriver_sendMidi(note);
        Fmdriver_sendMidi(0x7f);
        sleep(2);

        Fmdriver_sendMidi(0x80);
        Fmdriver_sendMidi(note);
        Fmdriver_sendMidi(0x7f);
        sleep(2);

        note++;
        if(note>0x48){ note=0x3c; }
    }
}

fmsd1_raspi.cにコード追加

一行だけ、fmsd1_raspi.cにプログラムを追加しました。Reset にGPIO 16(36番ピン)がアサインされていますが、GPIO 16 を出力モードにセットする、という行がないと動作しませんでした。

fmsd1_raspi.c

void initSD1( void )
{
    //  set Output Mode
    bcm2835_gpio_fsel(RST,BCM2835_GPIO_FSEL_OUTP); // <- 追加

バグかも

fmtone.cの中の、void Tone_sendTone( void )の中で、以下コメントアウトした行は、

        riPtr[0] = (td->voiceCommon & 0x60)>>5;
//      riPtr[1] = ((td->voiceCommon & 0xc0)>>3) | (td->voiceCommon & 0x07);
        riPtr[1] = ((td->voiceCommon & 0x18)<<3) | (td->voiceCommon & 0x07);

        for ( j=0; j<MAX_FM_OPERATOR; j++ ){
//          riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+0] = (td->opPrm[j][3] << 4) | (td->opPrm[j][0] & 0x08) | ((td->opPrm[j][0] & 0x01)<<2);
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+0] = (td->opPrm[j][3] << 4) | (td->opPrm[j][0] & 0x08) | ((td->opPrm[j][0] & 0x04)>>2);
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+1] = (td->opPrm[j][4] << 4) | td->opPrm[j][2];
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+2] = (td->opPrm[j][1] << 4) | td->opPrm[j][5];
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+3] = (td->opPrm[j][6] << 2) | (td->opPrm[j][0] & 0x03);
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+4] = td->opPrm[j][7];
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+5] = ((td->opPrm[j][8] & 0x0f) << 4) | ((td->opPrm[j][8] & 0xf0) >> 4);
            riPtr[MAX_ELEMENT_PRM+OPERATOR_PRM_REG_SZ*j+6] = (td->opPrm[j][9] << 3) | ((td->opPrm[j][0] & 0x70) >> 4);
        }

だと思われます。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1