/********************************************** * PIC24FJ64GA002 family * BT_MP3: VS1011E応用 MP3再生プログラム * マイクロチップのMDDファイルシステムを使用 * SDカード内のMP3のファイルはルートにのみ保存 * ディレクトリは扱っていないので無視される * SD:SPI1 MP3:SPI2 * Bluetoothでリモコン、操作と曲名等の表示 ***********************************************/ #include #include "GenericTypeDefs.h" #include "FSIO.h" #include "VS1011.h" /* コンフィギュレーションの設定 */ _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1& FWDTEN_OFF ) /* 8MHz*PLL4=32MHz (Full Speed) */ _CONFIG2( IESO_OFF & FNOSC_FRCPLL & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_PRI & POSCMOD_NONE) /* MDDファイル用構造体のポインタ変数 */ FSFILE *fptr; size_t result; SearchRec Record; SearchRec *rptr = &Record; __attribute__((far)) unsigned char Buffer[512]; /* MP3用変数 */ BYTE Volume, ChgFlag, BASS, TREB; __attribute__((far)) unsigned char Header[1024]; unsigned int Index, locate, NameSize; /* BT用バッファ */ #define Max_Size 512 __attribute__((far)) unsigned char RcvBuf[64]; __attribute__((far)) unsigned char SndBuf[Max_Size]; /* Blutooth設定用コマンドデータ */ const unsigned char msg1[] = "$$$"; // コマンドモード指定 const unsigned char msg2[] = "SF,1\r"; // 初期化 const unsigned char msg3[] = "SN,BT_MP3\r"; // APのSSID指定 const unsigned char msg4[] = "R,1\r"; // 再起動 //const unsigned char msg4[] = "SA,4\r"; // 認証モード 150815 //const unsigned char msg5[] = "R,1\r"; // 再起動 150815 /* 関数プロトタイピング */ void SendUART(unsigned char Data); void SendBT(unsigned char * ptr, int size); void SendCmd(const unsigned char *cmd); void SendStr(unsigned char *ptr); void Transfer(void); /********* メイン関数 ***************************/ int main(void){ int i; CLKDIVbits.RCDIV = 0; // クロック1/1 /* 入出力ポート設定 */ AD1PCFG = 0xFFFF; // すべてデジタル TRISA = 0xFFFC; // TRISB = 0x878F; // /* スイッチ状態変化割り込みの許可 */ CNPU1 = 0x0001; // CN0(RA4) CNEN1 = 0x0001; CNPU2 = 0x6060; // CN29(RA3) CN30(RA2) CN21(RB9), CN22(RB8) CNEN2 = 0x6000; IPC4bits.CNIP = 5; // 割り込みレベル指定 IEC1bits.CNIE = 1; // 割り込み許可 /* UART1ピン割付 */ RPINR18bits.U1RXR = 2; // UART1 RX to RP2 RPOR1bits.RP3R = 3; // UART1 TX to RP3 /* UART1初期設定 115kbps */ U1MODE = 0x8808; // UART1初期設定 BRGH=1 U1STA = 0x0400; // UART1初期設定 U1BRG = 34; // 115kbps@32MHz IPC2bits.U1RXIP = 4; // UART1割り込みレベル IFS0bits.U1RXIF = 0; // 割り込みフラグクリア IEC0bits.U1RXIE = 1; // UART1受信割り込み許可 /* SPIのピン割り付け */ RPINR20bits.SDI1R = 7; // SDI1をRP7に RPOR3bits.RP6R = 8; // SCK1をRP6に RPOR2bits.RP5R = 7; // SDO1をRP5に RPINR22bits.SDI2R = 10; // SDI2をRP10に RPOR6bits.RP12R = 11; // SCK2をRP12に RPOR5bits.RP11R = 10; // SDO2をRP11に /*** Bluetoothモジュールの初期化 ****/ LATAbits.LATA1 = 0; // BT Reset delay_ms(200); // パルス幅確保 LATAbits.LATA1 = 1; // リセット解除 if(PORTAbits.RA4 == 0) // S2が押されていた場合のみ実行 { /** Bluetoothモジュール初期化 */ delay_ms(1000); // 初期化実行待ち SendCmd(msg1); // $$$ SendCmd(msg2); // 工場出荷時リセット SendCmd(msg3); // 名称付与 SendCmd(msg4); // リブート // SendCmd(msg4); // 認証モード 150815 // SendCmd(msg5); // リブート 150815 delay_ms(2000); // メッセージスキップ } /* 変数初期化 */ Index = 0; ChgFlag = 0; /* VS1011eの初期化 */ VS1011_Init(); // 初期化実行 Volume = 0x30; // 音量の初期設定 SetVolume(Volume, Volume); // 制御実行 BASS = 0; // 低音フラット TREB = 0; // 高音フラット SetBoost(BASS, 15, TREB, 5); // 制御実行 ChgFlag = 1; // 最初制御実行 /* VS1011のデバッグ時テスト用のコマンド  */ // VS1011_SineTest(); // 正弦波出力テスト // while(1); /* カードの実装確認とディレクトリ読み込み (永久待ち) */ while(!FSInit()); // FATの初期化 /* 最初のファイルのサーチ(ルートだけにMP3ファイルがあることが前提) */ result = FindFirst("*.*", ATTR_ARCHIVE, rptr); if(result == 0){ fptr = FSfopen(Record.filename, FS_READ); // ファイルのオープン } /**************** メインループ ********************************************/ while(1){ /* 音楽データの出力 */ if(fptr != 0){ // 正常にオープンできたか? /* ファイルのEOFまで音声データ連続出力 */ do{ /***** 更新フラグチェックと制御 *****/ if(ChgFlag){ // 更新ありか? ChgFlag = 0; // フラグクリア SetVolume(Volume, Volume); // 音量設定 SetBoost(BASS, 15, TREB, 5); // 音質設定 } /****** 音楽データの再生 ******/ SRbits.IPL = 7; // SPI処理中は割り込み禁止 MP3_XDCS_IO = 0; // データ用CSセット /* 512バイト単位でファイルリード */ result = FSfread(Buffer, 1, 512, fptr); // 512バイト読み出し for(i= 0; i 4) // 最高0(0dB) Volume -= 4; // 2dBずつ上げる ChgFlag = 1; // 変更フラグオン } if(PORTAbits.RA3 == 0){ // SW2音量ダウン if(Volume < 0xC0) // 最低を0xC0で制限(無音) Volume += 4; // 2dBずつ下げる ChgFlag = 1; // 変更フラグオン } if(PORTAbits.RA4 == 0){ // SW3 次のファイルへ FSfclose(fptr); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 /* 次のファイルをサーチ */ result = FindNext(rptr); // 次のファイルへ if((result==0)&&(Record.attributes==ATTR_ARCHIVE)){ // ファイルが見つかった場合 fptr = FSfopen(Record.filename, FS_READ); // ファイルをオープン Transfer(); // 曲情報送信 } else // ファイル見つからず終了の場合 { result = FindFirst("*.*", ATTR_ARCHIVE, rptr); //最初のファイルを探索 if(result == 0){ // 見つかった場合 fptr = FSfopen(Record.filename, FS_READ); // ファイルのオープン Transfer(); // 曲データ送信 } } } IFS1bits.CNIF = 0; // 割り込みフラグクリア } /****************************************** * UART受信割り込み処理関数 * 常に「E」受信まで取り込む *******************************************/ void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) { unsigned char data; while(U1STAbits.URXDA){ // 受信バッファにデータある間繰り返す /* 受信エラーチェック */ IFS0bits.U1RXIF = 0; // 割り込みフラグクリア if(U1STAbits.OERR || U1STAbits.FERR) { // 受信エラーありか? data = U1RXREG;; // バッファ取り出し U1STA &= 0xFFF0; // エラーフラグクリア U1MODE = 0; // UART1停止 U1MODE = 0x8808; // UART1再有効化 Index = 0; // バッファインデックスリセット } else { // 正常受信の場合 data = U1RXREG; // データ取得 if((Index < 5) && (data != 'E')){ // 終了マークか? RcvBuf[Index++] = data; // データをバッファに保存 } else{ // 終了の場合 /** 受信データ処理 **/ if(RcvBuf[0] == 'S'){ // 開始マーク確認 switch(RcvBuf[1]){ // コマンド種別で分岐 case 'U': // 音量アップコマンドの場合 if(Volume > 4) // 最高0(0dB) Volume -= 4; // アップ ChgFlag = 1; // 変更フラグセット break; case 'L': // 音量ダウンコマンドの場合 if(Volume < 0xC0) // 最低を0xC0で制限(無音) Volume += 4; // 音量ダウン ChgFlag = 1; // 変更フラグセット break; case 'B': // バスブースト if(BASS<15) // 15最大 BASS ++; // BASS Boostアップ ChgFlag = 1; // 変更フラグオン break; case 'C': // フラット設定 if(BASS > 0) // 最低0 BASS--; // Bassダウン ChgFlag = 1; // 変更フラグセット break; case 'H': // 高音ブースト if(TREB<7) // 7より小さい場合 TREB++; // 高音アップ ChgFlag = 1; // 変更フラグオン break; case 'I': // 高音ダウン if(TREB > 0) // 0より大きい場合 TREB--; // 高音ダウン ChgFlag = 1; // 変更フラグオン break; case 'N': // 曲送りコマンドの場合 FSfclose(fptr); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 /* 次のファイルをサーチ */ result = FindNext(rptr); // 次のファイルへ if((result==0)&&(Record.attributes==ATTR_ARCHIVE)){ // ファイルが見つかった場合 fptr = FSfopen(Record.filename, FS_READ); // ファイルをオープン Transfer(); // 曲情報送信 } else // ファイル見つからず終了の場合 { result = FindFirst("*.*", ATTR_ARCHIVE, rptr); //最初のファイルを探索 if(result == 0){ // 見つかった場合 fptr = FSfopen(Record.filename, FS_READ); // ファイルのオープン Transfer(); // 曲データ送信 } } break; default : // どれでもないとき break; // 何もしない } Index = 0; // バッファインデックスリセット } } } } } /***************************************** * UART 送信実行サブ関数 ******************************************/ void SendUART(unsigned char Data){ while(!U1STAbits.TRMT); // 送信レディー待ち U1TXREG = Data; // 送信実行 } /******************************************* * Bluetoothでデータを一括送信する関数 ******************************************/ void SendBT(unsigned char * ptr, int size) { int i; for(i= 0; i