#include #include #include #include "iodefine.h" #include "integer.h" #include "diskio.h" #include "ff.h" //#include "shuffle_play.h" #include "new_play.h" #include "play.h" #include "key_ctrl.h" extern FIL fobj; #define SEG_D PORTA.DR.BIT.B1 // CN1-2 #define SEG_E PORTA.DR.BIT.B3 // CN1-4 #define SEG_C PORTA.DR.BIT.B5 // CN1-6 #define SEG_B PORTA.DR.BIT.B7 // CN1-8 #define SEG_G PORT7.DR.BIT.B0 // CN3-3 #define SEG_A PORT7.DR.BIT.B2 // CN3-5 #define SEG_F PORT7.DR.BIT.B4 // CN3-7 #define KETA_01 PORT8.DR.BIT.B2 // CN3-15 #define KETA_10 PORTB.DR.BIT.B7 // CN1-16 #define HIST_FILE "\\hist.dat" // 履歴記録ファイル static int current_no[2]; // 0:現在のディレクトリ番号、1:現在のトラック番号 static int current_no_startup[2]; // 上記の履歴ファイル保存値 static int val_to_disp_flag; // 0:ディレクトリ番号をLED表示、1:トラック番号をLED表示 static int led_blink_flag; // 0:点滅しない、1:点滅する static FIL Fhist; // 履歴記録ファイル用 static DWORD current_track_dt; // //static int val_for_debug; // void ketaswitch_no_blink(); void ketaswitch_blink(); void ketaswitch_standby(); void ketaswitch_debug(); void (*p_ketaswitch)(); /* * 対象ディレクトリ下のMP3を順次実行する * first_track_no : 再生開始トラック番号(1〜) */ static FRESULT play_dir(char *dirname, int first_track_no){ FRESULT res; DIR Dir; FILINFO Finfo; current_no[1] = 0; // 再生中のトラック番号 if (current_no_startup[1] >= 1){ first_track_no = current_no_startup[1]; current_no_startup[1] = 0; } res = f_opendir(&Dir, dirname); if (res) goto play_dir_end; set_val_to_disp(LED_DISP_TRACK); // 再生中はトラック番号を表示 set_led_blink(STATE_PLAYING); // 点滅もオフ for (;;){ res = f_readdir(&Dir, &Finfo); if (res != FR_OK) break; if (!Finfo.fname[0]){ res = FR_NO_FILE; break; } if (strstr(Finfo.fname, ".mp3") || strstr(Finfo.fname, ".MP3")){ char mp3_file[128]; current_no[1]++; if (current_no[1] < first_track_no) continue; strcpy(mp3_file, dirname); strcat(mp3_file, "\\"); strcat(mp3_file, Finfo.fname); current_track_dt = (((DWORD)Finfo.fdate) << 16) | Finfo.ftime; // 再生 res = (FRESULT)play(mp3_file); if (res != FR_OK) break; // if (skip_mode == SKIP_TRACK_FW){ // 次の曲へ skip_mode = 0; } else if (skip_mode == SKIP_TRACK_BK){ // 前の曲へ skip_mode = 0; res = f_readdir(&Dir, NULL); // ディレクトリの先頭に戻る if (res != FR_OK) break; if (current_no[1] > 1) first_track_no = current_no[1] - 1; else first_track_no = 0; current_no[1] = 0; } else if (skip_mode == SKIP_DIR_10 || skip_mode == SKIP_DIR_01){ return FR_OK; } } } play_dir_end: return res; } /* * ルートディレクトリの下のサブディレクトリを順次たどっていき、各サブディレクトリ下のMP3を再生していく。 */ FRESULT new_play(){ FRESULT res; DIR Dir; FILINFO Finfo; int restart_dir_no; int pause_at_standby; int dir_no_at_standby; current_no[0] = 0; if (current_no_startup[0] >= 1){ restart_dir_no = current_no_startup[0]; current_no_startup[0] = 0; } else restart_dir_no = 0; res = f_opendir(&Dir, "\0"); // root dir. if (res) goto new_play_end; pause_at_standby = TRUE; set_standby(); // key_ctrl.c for (;;){ res = f_readdir(&Dir, &Finfo); if (res != FR_OK) break; if (!Finfo.fname[0]){ res = FR_NO_FILE; break; } if (Finfo.fattrib & AM_DIR){ // directory if (strcmp(Finfo.fname, "RECYCLER") != 0 && strstr(Finfo.fname, "TRASHE") == NULL && Finfo.fname[0] != '.'){ char subdir[64]; current_no[0]++; if (current_no[0] < restart_dir_no) continue; strcpy(subdir, "\0"); strcat(subdir, "\\"); strcat(subdir, Finfo.fname); // ディレクトリ再生開始前standby状態 dir_no_at_standby = current_no[0]; continue_standby: if (pause_at_standby == TRUE){ set_standby(); switch (key_cmd_chk_standby()){ case SKIP_TRACK_FW: case SKIP_TRACK_BK: goto continue_standby; break; case SKIP_DIR_10: // ディレクトリ番号の10の桁 { int n1, n2; n1 = current_no[0] % 10; n2 = current_no[0] / 10; if (n2 == 9) n2 = 0; else n2++; current_no[0] = n2*10 + n1; goto continue_standby; } break; case SKIP_DIR_01: // ディレクトリの1の桁 { int n1, n2; n1 = current_no[0] % 10; n2 = current_no[0] / 10; if (n1 == 9) n1 = 0; else n1++; current_no[0] = n2*10 + n1; goto continue_standby; } goto continue_standby; break; default: if (current_no[0] != dir_no_at_standby){ res = f_readdir(&Dir, NULL); // ディレクトリのオープン直後に戻る if (res != FR_OK) break; if (restart_dir_no != current_no[0]){ // 起動直後restart_dir_noにはcurrent_no_startup[0]が設定されている current_no_startup[1] = 0; // 保存されていたトラック番号を無効とする } restart_dir_no = current_no[0]; current_no[0] = 0; pause_at_standby = FALSE; continue; } else { } break; } } // ディレクトリ再生 play_dir(subdir, 1); if (skip_mode == SKIP_DIR_10 || skip_mode == SKIP_DIR_01){ // ディレクトリ再生中にスキップボタンが押されたとき pause_at_standby = TRUE; goto continue_standby; } else { pause_at_standby = FALSE; } } } } new_play_end: return res; } // 以下、LED表示 static void disp_0(){ SEG_A = 1; SEG_B = 1; SEG_C = 1; SEG_D = 1; SEG_E = 1; SEG_F = 1; SEG_G = 0; } static void disp_1(){ SEG_A = 0; SEG_B = 1; SEG_C = 1; SEG_D = 0; SEG_E = 0; SEG_F = 0; SEG_G = 0; } static void disp_2(){ SEG_A = 1; SEG_B = 1; SEG_C = 0; SEG_D = 1; SEG_E = 1; SEG_F = 0; SEG_G = 1; } static void disp_3(){ SEG_A = 1; SEG_B = 1; SEG_C = 1; SEG_D = 1; SEG_E = 0; SEG_F = 0; SEG_G = 1; } static void disp_4(){ SEG_A = 0; SEG_B = 1; SEG_C = 1; SEG_D = 0; SEG_E = 0; SEG_F = 1; SEG_G = 1; } static void disp_5(){ SEG_A = 1; SEG_B = 0; SEG_C = 1; SEG_D = 1; SEG_E = 0; SEG_F = 1; SEG_G = 1; } static void disp_6(){ SEG_A = 0; SEG_B = 0; SEG_C = 1; SEG_D = 1; SEG_E = 1; SEG_F = 1; SEG_G = 1; } static void disp_7(){ SEG_A = 1; SEG_B = 1; SEG_C = 1; SEG_D = 0; SEG_E = 0; SEG_F = 0; SEG_G = 0; } static void disp_8(){ SEG_A = 1; SEG_B = 1; SEG_C = 1; SEG_D = 1; SEG_E = 1; SEG_F = 1; SEG_G = 1; } static void disp_9(){ SEG_A = 1; SEG_B = 1; SEG_C = 1; SEG_D = 0; SEG_E = 0; SEG_F = 1; SEG_G = 1; } static void disp_no(){ SEG_A = 0; SEG_B = 0; SEG_C = 0; SEG_D = 0; SEG_E = 0; SEG_F = 0; SEG_G = 0; } static void disp_digit(int n){ switch (n){ case 0: disp_0(); break; case 1: disp_1(); break; case 2: disp_2(); break; case 3: disp_3(); break; case 4: disp_4(); break; case 5: disp_5(); break; case 6: disp_6(); break; case 7: disp_7(); break; case 8: disp_8(); break; case 9: disp_9(); break; default: disp_no(); break; } } /* * LED表示値の種類を決める * flag=0:ディレクトリ番号、flag=1:トラック番号 */ void set_val_to_disp(int flag){ val_to_disp_flag = flag; } /* * LEDの点滅状態設定 * state : 動作状態 */ void set_led_blink(int state){ led_blink_flag = state; if (led_blink_flag == STATE_PLAYING){ p_ketaswitch = ketaswitch_no_blink; } else if (led_blink_flag == STATE_PAUSE){ p_ketaswitch = ketaswitch_blink; } else if (led_blink_flag == STATE_STANDBY){ p_ketaswitch = ketaswitch_standby; } } /* * LEDの点滅状態設定 * on_off=0:点滅しない、1:する */ /* void set_led_blink(int on_off){ led_blink_flag = on_off; //p_ketaswitch = ketaswitch_debug; if (led_blink_flag == 1){ p_ketaswitch = ketaswitch_blink; } else { p_ketaswitch = ketaswitch_no_blink; } } */ /* * LED表示桁の切替 */ void ketaswitch(){ (*p_ketaswitch)(); } /* * LED表示桁の切替(ブリンクなし) */ void ketaswitch_no_blink(){ static int cur_keta; cur_keta ^= 1; if (cur_keta == 0){ // 1の桁 KETA_01 = 1; KETA_10 = 0; disp_digit(current_no[val_to_disp_flag] % 10); } else { // 10の桁 KETA_01 = 0; KETA_10 = 1; disp_digit(current_no[val_to_disp_flag] / 10); } } /* * LED表示桁の切替(ブリンク) */ void ketaswitch_blink(){ static int cur_keta; static int blink_count; static int blink_state; cur_keta ^= 1; blink_count++; if (blink_count == 50){ blink_state ^= 1; blink_count = 0; } if (cur_keta == 0){ // 1の桁 KETA_01 = 1; KETA_10 = 0; if (blink_state != 0){ disp_no(); } else { disp_digit(current_no[val_to_disp_flag] % 10); } } else { // 10の桁 KETA_01 = 0; KETA_10 = 1; if (blink_state != 0){ disp_no(); } else { disp_digit(current_no[val_to_disp_flag] / 10); } } } /* * */ void ketaswitch_standby(){ static int cur_keta; static int blink_count; static int blink_state; cur_keta ^= 1; blink_count++; if (blink_count == 50){ blink_state ^= 1; blink_count = 0; } if (cur_keta == 0){ // 1の桁 KETA_01 = 1; KETA_10 = 0; if (continuous_key_on == 0 && blink_state != 0){ disp_no(); } else { disp_digit(current_no[val_to_disp_flag] % 10); } } else { // 10の桁 KETA_01 = 0; KETA_10 = 1; if (continuous_key_on == 0 && blink_state != 0){ disp_no(); } else { disp_digit(current_no[val_to_disp_flag] / 10); } } } /* * LED表示桁の切替(val_for_debug表示) */ /*** void ketaswitch_debug(){ static int cur_keta; cur_keta ^= 1; if (cur_keta == 0){ // 1の桁 KETA_01 = 1; KETA_10 = 0; disp_digit(val_for_debug % 10); } else { // 10の桁 KETA_01 = 0; KETA_10 = 1; disp_digit(val_for_debug / 10); } } ***/ /* * LED駆動ポートの初期化 */ void init_trackno_led(){ set_led_blink(STATE_STANDBY); // アノード PORTA.DDR.BIT.B1 = 1; // PA1 is output PORTA.DDR.BIT.B3 = 1; PORTA.DDR.BIT.B5 = 1; PORTA.DDR.BIT.B7 = 1; PORT7.DDR.BIT.B0 = 1; PORT7.DDR.BIT.B2 = 1; PORT7.DDR.BIT.B4 = 1; // カソード PORTB.DDR.BIT.B7 = 1; PORT8.DDR.BIT.B2 = 1; } /* * 現在のディレクトリ番号、現在のトラック番号をSDカードに書き込む */ int write_history() { FRESULT res; UINT bw; if (current_no[0] == 0 || current_no[1] == 0) return 0; res = f_open(&Fhist, HIST_FILE, FA_CREATE_ALWAYS | FA_WRITE); if(res != FR_OK) goto hist_return; res = f_write(&Fhist, (void *)current_no, 2*sizeof(int), &bw); res = f_close(&Fhist); if(res != FR_OK) goto hist_return; hist_return: return (int)res; } /* * ディレクトリ番号、トラック番号をSDカードから取得する */ int read_history() { FRESULT res; UINT bw; res = f_open(&Fhist, HIST_FILE, FA_READ); if(res != FR_OK) goto hist_return; res = f_read(&Fhist, (void*)current_no_startup, 2*sizeof(int), &bw); if(res != FR_OK) goto hist_return; res = f_close(&Fhist); if(res != FR_OK) goto hist_return; hist_return: if(res != FR_OK){ current_no_startup[0] = 0; current_no_startup[1] = 0; } return (int)res; } /* * ff.cが要求する、ファイルのタイムスタンプ取得関数 */ DWORD get_fattime (void) { return current_track_dt; }