nlgplay for mbed
Dependencies: SDFileSystemEx mbed
main.cpp
00001 // 00002 // NLGPLAY : NLG file player for mbed 00003 // 00004 // example to write : 00005 // ./lpc21isp -bin file.bin /dev/cu.usbserial-??? 115200 12000 00006 // 00007 00008 #include "mbed.h" 00009 #include "SDFileSystem.h" 00010 #include "lcd.h" 00011 00012 #define USE_NBV3 00013 #define USE_FASTIO 00014 00015 #define NBCTRL_VER "Ver 1.13" 00016 00017 #pragma O3 00018 #pragma Otime 00019 00020 00021 // (pinname, mode) 00022 DigitalIn sw_play(dp24, PullUp); 00023 DigitalIn sw_next(dp10, PullUp); 00024 DigitalIn sw_prev(dp9, PullUp); 00025 00026 // LED 00027 DigitalOut led1(LED1, 0); 00028 DigitalOut led2(LED2, 0); 00029 00030 // SPI: MOSI, MISO, SCLK, CS 00031 SDFileSystem sd(dp2, dp1, dp6, dp25, "sd"); 00032 00033 // 00034 // nlg_emb.c 00035 // 00036 00037 #define CMD_PSG 0x00 00038 #define CMD_OPM 0x01 00039 #define CMD_OPM2 0x02 00040 #define CMD_IRQ 0x80 00041 00042 #define CMD_CTC0 0x81 00043 #define CMD_CTC3 0x82 00044 00045 #define NLG_VER (110) 00046 #define NLG_BASECLK (4000000) 00047 00048 FILE *nlg_file; 00049 00050 char nlg_title[65]; 00051 int nlg_baseclk; 00052 int nlg_tick; 00053 int nlg_length; 00054 int nlg_loop_ptr; 00055 int nlg_version; 00056 00057 int nlg_ctc0; 00058 int nlg_ctc3; 00059 00060 #define _WAIT for(int wcnt=0; wcnt < 2; wcnt++) 00061 00062 #ifndef USE_FASTIO 00063 // 通常IO 00064 00065 #define RCK io04 // pin4 , P0_11 00066 #define SCK io03 // pin17, P1_8 00067 #define DBS io01 // pin13, P1_4 00068 #define CTS io02 // pin26, P0_3 00069 00070 #define IO_A0 io05 00071 #define IO_WR io06 00072 00073 // (pinname, initial value) 00074 DigitalOut io01(dp13, 0); // P1_4 00075 DigitalOut io02(dp26, 0); // P0_3 00076 DigitalOut io03(dp17, 0); // P1_8 00077 DigitalOut io04(dp4, 0); // P0_11 00078 00079 DigitalOut io05(dp18, 0); // P1_9 00080 DigitalOut io06(dp11, 0); // P1_2 00081 00082 void ioInit() 00083 { 00084 } 00085 00086 // 16bit output 00087 void ioShiftOut(unsigned int data) 00088 { 00089 int i; 00090 00091 for(i = 0; i < 8; i++) 00092 { 00093 /* 2ビット分のデータをそれぞれ出力 */ 00094 if (data & 0x80) 00095 CTS = 1; 00096 else 00097 CTS = 0; 00098 00099 if (data & 0x8000) 00100 DBS = 1; 00101 else 00102 DBS = 0; 00103 00104 data <<= 1; 00105 00106 SCK = 1; 00107 // _WAIT; 00108 SCK = 0; 00109 // _WAIT; 00110 } 00111 00112 RCK = 1; 00113 // _WAIT; 00114 RCK = 0; 00115 // _WAIT; 00116 } 00117 #else 00118 00119 // 高速IO 00120 00121 #define RCK IO_04 00122 #define SCK IO_03 00123 #define DBS IO_01 00124 #define CTS IO_02 00125 00126 00127 #define IO_A0 io05 00128 #define IO_WR io06 00129 00130 DigitalOut io01(dp13, 0); // P1_4 00131 DigitalOut io02(dp26, 0); // P0_3 00132 DigitalOut io03(dp17, 0); // P1_8 00133 DigitalOut io04(dp4, 0); // P0_11 00134 00135 DigitalOut io05(dp18, 0); // P1_9 00136 DigitalOut io06(dp11, 0); // P1_2 00137 00138 00139 #define IO_01 (1<<4) // DBS P1_4 00140 #define IO_02 (1<<3) // CTS P0_3 00141 #define IO_03 (1<<8) // SCK P1_8 00142 #define IO_04 (1<<11) // RCK P0_11 00143 00144 00145 void ioInit() 00146 { 00147 // 出力 00148 LPC_GPIO0->DIR |= (IO_02 | IO_04); 00149 LPC_GPIO1->DIR |= (IO_01 | IO_03); 00150 } 00151 00152 // 16bit output 00153 void ioShiftOut(unsigned int data) 00154 { 00155 int i; 00156 00157 for(i = 0; i < 8; i++) 00158 { 00159 /* 2ビット分のデータをそれぞれ出力 */ 00160 if (data & 0x80) 00161 LPC_GPIO0->DATA |= CTS; 00162 else 00163 LPC_GPIO0->DATA &= ~CTS; 00164 00165 if (data & 0x8000) 00166 LPC_GPIO1->DATA |= DBS; 00167 else 00168 LPC_GPIO1->DATA &= ~DBS; 00169 00170 data <<= 1; 00171 00172 LPC_GPIO1->DATA |= SCK; 00173 LPC_GPIO1->DATA &= ~SCK; 00174 } 00175 00176 LPC_GPIO0->DATA |= RCK; 00177 LPC_GPIO0->DATA &= ~RCK; 00178 00179 } 00180 00181 #endif 00182 00183 00184 /* 制御信号定義 */ 00185 #define CS_PSG (1 << 1) 00186 #define CS_FM1 (1 << 2) 00187 #define CS_FM2 (1 << 3) 00188 #define A0 (1 << 4) 00189 #define WR (1 << 5) 00190 #define ICL (1 << 6) 00191 00192 /* アクティブローの制御信号 */ 00193 #define ACTLOW (CS_PSG | CS_FM1 | CS_FM2 | WR | ICL) 00194 00195 #ifdef USE_NBV3 00196 /* NBV3 16bit出力 */ 00197 void regOutBase(int addr, int data, int select) 00198 { 00199 /* アドレスを出力 */ 00200 /* A0をローにして待つ */ 00201 IO_A0 = 0; 00202 ioShiftOut((addr << 8) | (ACTLOW & ~(select | WR))); 00203 ioShiftOut((addr << 8) | (ACTLOW)); 00204 00205 00206 /* チップ側の処理を待つ */ 00207 00208 /* データを出力 */ 00209 /* A0をハイにして待つ */ 00210 IO_A0 = 1; 00211 ioShiftOut((data << 8) | (ACTLOW & ~(select | WR))); 00212 ioShiftOut((data << 8) | (ACTLOW)); 00213 00214 /* 処理を待つ */ 00215 } 00216 #else 00217 /* NBV2互換出力 */ 00218 void regOutBase(int addr, int data,int select) 00219 { 00220 /* アドレスを出力 */ 00221 /* A0をローにして待つ */ 00222 ioShiftOut((addr << 8) | (ACTLOW)); 00223 ioShiftOut((addr << 8) | (ACTLOW & ~(select | WR))); 00224 ioShiftOut((addr << 8) | (ACTLOW)); 00225 00226 /* チップ処理待ち */ 00227 00228 /* データを出力 */ 00229 /* A0をハイにして待つ */ 00230 ioShiftOut((data << 8) | A0 | (ACTLOW)); 00231 ioShiftOut((data << 8) | A0 | (ACTLOW & ~(select | WR))); 00232 ioShiftOut((data << 8) | A0 | (ACTLOW)); 00233 00234 /* チップ処理待ち */ 00235 } 00236 #endif 00237 00238 /* PSG出力 */ 00239 void regPSGOut(int addr, int data) 00240 { 00241 regOutBase(addr, data, CS_PSG); 00242 } 00243 00244 /* FM2出力 */ 00245 void regFM2Out(int addr, int data) 00246 { 00247 regOutBase(addr, data, CS_FM2); 00248 } 00249 00250 /* FM音源にデータを出力 */ 00251 void regFMOut(int addr,int data) 00252 { 00253 regOutBase(addr, data, CS_FM1); 00254 } 00255 00256 /* ボード消音 */ 00257 void boardMute(void) 00258 { 00259 int i; 00260 00261 /* PSG初期化 */ 00262 regPSGOut(0x00,0); 00263 regPSGOut(0x01,0); 00264 00265 regPSGOut(0x06, 0x00); 00266 regPSGOut(0x07, 0x3f); // ALL OFF 00267 regPSGOut(0x08, 0x00); // CH.A 0 00268 regPSGOut(0x09, 0x00); // CH.B 0 00269 regPSGOut(0x0a, 0x00); // CH.C 0 00270 00271 /* MUTE(disable) */ 00272 for(i = 0x20; i < 0x28; i++) 00273 { 00274 regFMOut(i, 0x00); 00275 regFM2Out(i, 0x00); 00276 } 00277 00278 // KEYOFF 00279 for(i = 0x00; i < 0x08; i++) 00280 { 00281 regFMOut(0x08, i & 0x07); 00282 regFM2Out(0x08, i & 0x07); 00283 } 00284 00285 // FORCE RELEASE 00286 for(i= 0x00; i < 0x20; i++) 00287 { 00288 regFMOut(0xE0 + i, 0x0f); 00289 regFM2Out(0xE0 + i, 0x0f); 00290 } 00291 } 00292 00293 00294 /* ボード初期化 */ 00295 void boardInit(void) 00296 { 00297 wait_ms(20); 00298 /* ICLのみをLOW(アクティブ)にする */ 00299 ioShiftOut(ACTLOW & ~(ICL)); 00300 wait_ms(150); 00301 00302 /* 元に戻す */ 00303 ioShiftOut(ACTLOW); 00304 wait_ms(10); 00305 } 00306 00307 typedef unsigned char byte; 00308 typedef unsigned short word; 00309 typedef unsigned long dword; 00310 00311 00312 // 変数読み出し(WORD) 00313 word ReadWORD(byte *p) 00314 { 00315 return 00316 ((word)p[0]) | 00317 ((word)p[1])<<8; 00318 } 00319 00320 // 変数読み出し(DWORD) 00321 dword ReadDWORD(byte *p) 00322 { 00323 return 00324 ((dword)p[0]) | 00325 ((dword)p[1])<<8 | 00326 ((dword)p[2])<<16 | 00327 ((dword)p[3])<<24; 00328 } 00329 00330 // NLGファイルを開く 00331 int OpenNLG(const char *file) 00332 { 00333 byte nlg_hdr[0x60]; 00334 00335 nlg_file = fopen(file, "rb"); 00336 00337 if (!nlg_file) 00338 { 00339 printf("File open error:%s\n", file); 00340 return -1; 00341 } 00342 00343 fread(nlg_hdr, 0x60, 1, nlg_file); 00344 00345 if (memcmp(nlg_hdr, "NLG1", 4) != 0) 00346 { 00347 printf("Unknown format!\n"); 00348 fclose(nlg_file); 00349 return -1; 00350 } 00351 00352 nlg_version = ReadWORD(nlg_hdr + 4); 00353 00354 memcpy(nlg_title, nlg_hdr + 8, 64); 00355 nlg_title[64]=0; 00356 00357 nlg_baseclk = ReadDWORD(nlg_hdr + 72); 00358 nlg_tick = ReadDWORD(nlg_hdr + 76); 00359 00360 nlg_length = ReadDWORD(nlg_hdr + 88); 00361 nlg_loop_ptr = (long)ReadDWORD(nlg_hdr + 92); 00362 00363 fseek(nlg_file, 0x60, SEEK_SET); 00364 00365 nlg_ctc0 = nlg_ctc3 = 0; 00366 00367 return 0; 00368 } 00369 00370 #if 0 00371 00372 00373 // 変数書き出し(WORD) 00374 inline void WriteWORD(byte *p,word val) 00375 { 00376 p[0] = (val & 0xff); 00377 p[1] = ((val>>8) & 0xff); 00378 } 00379 00380 // 変数書き出し(DWORD) 00381 inline void WriteDWORD(byte *p,dword val) 00382 { 00383 p[0] = (val & 0xff); 00384 p[1] = ((val>>8) & 0xff); 00385 p[2] = ((val>>16) & 0xff); 00386 p[3] = ((val>>24) & 0xff); 00387 } 00388 00389 // 書き込み用NLGファイルを開く 00390 int CreateNLG(const char *file) 00391 { 00392 byte hdr[0x80]; 00393 00394 nlg_file = fopen(file, "wb"); 00395 00396 if (!nlg_file) 00397 { 00398 printf("File open error:%s\n", file); 00399 return -1; 00400 } 00401 00402 memset(hdr, 0, 0x80); 00403 memcpy(hdr,"NLG1",4); 00404 00405 WriteWORD(hdr + 4, NLG_VER); // Version 00406 WriteDWORD(hdr + 72, NLG_BASECLK); // BaseCLK 00407 WriteDWORD(hdr + 76, 0); // Tick 00408 WriteDWORD(hdr + 88, 0); // Length 00409 WriteDWORD(hdr + 92, 0); // Loop Pointer 00410 00411 fwrite(hdr, 0x60, 1, nlg_file); 00412 00413 nlg_ctc0 = nlg_ctc3 = 0; 00414 00415 return 0; 00416 } 00417 00418 00419 // コマンドの書き込み 00420 void WriteNLG_CMD(int cmd) 00421 { 00422 if (!nlg_file) 00423 return; 00424 00425 fputc(cmd, nlg_file); 00426 } 00427 00428 // CTC定数の書き込み 00429 void WriteNLG_CTC(int cmd,int ctc) 00430 { 00431 if (!nlg_file) 00432 return; 00433 00434 fputc(cmd, nlg_file); 00435 fputc(ctc, nlg_file); 00436 } 00437 00438 // データの書き込み 00439 void WriteNLG_Data(int cmd,int addr,int data) 00440 { 00441 if (!nlg_file) 00442 return; 00443 00444 fputc(cmd, nlg_file); 00445 fputc(addr, nlg_file); 00446 fputc(data, nlg_file); 00447 } 00448 00449 #endif 00450 00451 // ファイルを閉じる 00452 void CloseNLG(void) 00453 { 00454 if (!nlg_file) 00455 return; 00456 00457 fclose(nlg_file); 00458 00459 #if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler 00460 free(nlg_file); 00461 #endif 00462 00463 nlg_file = NULL; 00464 } 00465 00466 // データの読み出し 00467 inline int ReadNLG(void) 00468 { 00469 return fgetc(nlg_file); 00470 } 00471 00472 // ファイルポインタの位置を取得 00473 inline long TellNLG(void) 00474 { 00475 return ftell(nlg_file); 00476 } 00477 00478 // ファイルポインタの位置を設定 00479 inline void SeekNLG(long pos) 00480 { 00481 fseek(nlg_file, pos, SEEK_SET); 00482 } 00483 00484 // タイトルの取得 00485 inline char *GetTitleNLG(void) 00486 { 00487 return nlg_title; 00488 } 00489 00490 // ティックの取得 00491 inline int GetTickNLG(void) 00492 { 00493 return nlg_tick; 00494 } 00495 00496 // Set Tick 00497 inline void SetTick(void) 00498 { 00499 nlg_tick = ((nlg_ctc0 * 256) * nlg_ctc3); 00500 // printf("nlg_tick=%d\n", nlg_tick); 00501 } 00502 00503 // CTC0値の設定 00504 void SetCTC0_NLG(int value) 00505 { 00506 nlg_ctc0 = value; 00507 SetTick(); 00508 } 00509 00510 // CTC3値の設定 00511 void SetCTC3_NLG(int value) 00512 { 00513 nlg_ctc3 = value; 00514 SetTick(); 00515 } 00516 00517 // 曲の長さを得る 00518 int GetLengthNLG(void) 00519 { 00520 return nlg_length; 00521 } 00522 00523 // ループポインタを得る 00524 int GetLoopPtrNLG(void) 00525 { 00526 return nlg_loop_ptr; 00527 } 00528 00529 // ベースクロックを得る 00530 int GetBaseClkNLG(void) 00531 { 00532 return nlg_baseclk; 00533 } 00534 00535 #define CMD_PSG 0x00 00536 #define CMD_OPM 0x01 00537 #define CMD_OPM2 0x02 00538 #define CMD_IRQ 0x80 00539 00540 #define CMD_CTC0 0x81 00541 #define CMD_CTC3 0x82 00542 00543 00544 /* 単位を扱いやすいように */ 00545 typedef unsigned char byte; 00546 typedef unsigned short word; 00547 typedef unsigned long dword; 00548 00549 /* NLGを処理するための構造体 */ 00550 typedef struct 00551 { 00552 int base_clk; 00553 int clk_per_sample; 00554 00555 int freeze; 00556 int total_samples; 00557 00558 int total_sec; 00559 00560 int current_samples; 00561 int tick; 00562 int tick_sec; 00563 00564 int irq_count; 00565 int irq_loop; 00566 long loop_address; 00567 00568 int irq_counter; 00569 int irq_counter2; 00570 00571 } NLG_R; 00572 00573 00574 /* 初期化 */ 00575 int initNLG(NLG_R *np, const char *nlg_name) 00576 { 00577 if (OpenNLG(nlg_name) < 0) 00578 return -1; 00579 00580 np->base_clk = GetBaseClkNLG(); 00581 00582 /* printf("Title:%s %d %d %dsec %d\n", 00583 GetTitleNLG(), 00584 GetBaseClkNLG(), 00585 GetTickNLG(), 00586 GetLengthNLG(), 00587 GetLoopPtrNLG()); 00588 */ 00589 00590 np->total_samples = 0; 00591 np->current_samples = 0; 00592 00593 np->total_sec = 0; 00594 00595 np->tick = 0; 00596 np->tick_sec = 0; 00597 00598 np->freeze = 0; 00599 00600 np->irq_count = 0; 00601 np->irq_loop = GetLoopPtrNLG(); 00602 np->loop_address = -1; 00603 00604 np->irq_counter = 0; 00605 np->irq_counter2 = 0; 00606 00607 return 0; 00608 } 00609 00610 /* PSGへの出力 */ 00611 void WritePSG(int addr,int value) 00612 { 00613 regPSGOut(addr, value); 00614 } 00615 00616 /* FM1への出力 */ 00617 void WriteOPM(int addr,int value) 00618 { 00619 regFMOut(addr, value); 00620 } 00621 00622 /* FM2への出力 */ 00623 void WriteOPM2(int addr,int value) 00624 { 00625 regFM2Out(addr, value); 00626 } 00627 00628 // stop flag 00629 bool g_stop = false; 00630 bool g_prev = false; 00631 00632 void DispNLG(NLG_R *np) 00633 { 00634 // printf("Time %02d:%02d\r",np->total_sec / 60, np->total_sec % 60); 00635 // fflush(stdout); 00636 00637 char buf[16]; 00638 sprintf(buf, "%02d:%02d", 00639 np->total_sec / 60, 00640 np->total_sec % 60); 00641 00642 lcd_setCursor(3,1); 00643 lcd_printStr(buf); 00644 } 00645 00646 // wait until release buttons 00647 void waitButtonRelease(void) 00648 { 00649 while(!sw_next || !sw_play || !sw_prev); 00650 } 00651 00652 // wait until press buttons 00653 void waitButtonPress(void) 00654 { 00655 while(sw_next && sw_play && sw_prev); 00656 } 00657 00658 /* NLGの再生 */ 00659 int PlayNLG(NLG_R *np, int sec) 00660 { 00661 int cmd; 00662 int addr, data; 00663 int result = 0; 00664 00665 int tick; 00666 int total_us = 0; 00667 int us_tick = np->base_clk / 1000000; 00668 00669 printf("start play\n"); 00670 Timer t; 00671 00672 t.start(); 00673 total_us = 0; 00674 00675 // wait until release buttons 00676 waitButtonRelease(); 00677 00678 DispNLG(np); 00679 00680 while(np->total_sec < sec && !g_stop) 00681 { 00682 // push next 00683 if (!sw_next) 00684 break; 00685 00686 // push prev 00687 if (!sw_prev) 00688 { 00689 g_prev = true; 00690 break; 00691 } 00692 00693 // push play 00694 if (!sw_play) 00695 { 00696 g_stop = true; 00697 break; 00698 } 00699 00700 /* ウエイトの処理 */ 00701 while (np->tick >= us_tick) 00702 { 00703 int us = np->tick / us_tick; 00704 np->tick -= (us * us_tick); 00705 00706 // 次のタイミングまで待つ 00707 while(t.read_us() < total_us + us); 00708 00709 total_us += us; 00710 00711 // 1秒ごとにリセットする 00712 if (total_us >= 1000000) 00713 { 00714 total_us -= t.read_us(); 00715 t.reset(); 00716 } 00717 // DELAY_NEXT(us); 00718 00719 // printf("delay : %dus\n",us); 00720 } 00721 00722 /* コマンドの読み出し */ 00723 cmd = ReadNLG(); 00724 if (cmd == EOF) 00725 { 00726 if (np->loop_address >= 0) 00727 { 00728 SeekNLG(np->loop_address); 00729 cmd = ReadNLG(); 00730 } 00731 else 00732 { 00733 result = EOF; 00734 break; 00735 } 00736 } 00737 00738 /* コマンドの処理 */ 00739 switch (cmd) 00740 { 00741 case CMD_PSG: 00742 addr = ReadNLG(); 00743 data = ReadNLG(); 00744 WritePSG(addr, data); 00745 break; 00746 case CMD_OPM: 00747 addr = ReadNLG(); 00748 data = ReadNLG(); 00749 WriteOPM(addr, data); 00750 break; 00751 case CMD_OPM2: 00752 addr = ReadNLG(); 00753 data = ReadNLG(); 00754 WriteOPM2(addr, data); 00755 break; 00756 case CMD_IRQ: 00757 tick = GetTickNLG(); 00758 np->tick_sec += tick; 00759 np->tick += tick; 00760 np->irq_count++; 00761 if (np->irq_count == np->irq_loop) 00762 { 00763 /* ループ位置の設定 */ 00764 np->loop_address = TellNLG(); 00765 np->loop_address -= 1; 00766 } 00767 np->irq_counter++; 00768 if (np->irq_counter >= 48) 00769 { 00770 np->irq_counter = 0; 00771 led1 = !led1; 00772 00773 np->irq_counter2++; 00774 if (np->irq_counter2 >= 4) 00775 { 00776 np->irq_counter2 = 0; 00777 led2 = !led2; 00778 } 00779 } 00780 break; 00781 case CMD_CTC0: 00782 SetCTC0_NLG(ReadNLG()); 00783 break; 00784 case CMD_CTC3: 00785 SetCTC3_NLG(ReadNLG()); 00786 break; 00787 00788 } 00789 /* 秒情報の表示 */ 00790 while (np->tick_sec >= np->base_clk) 00791 { 00792 np->tick_sec -= np->base_clk; 00793 np->total_sec++; 00794 00795 DispNLG(np); 00796 } 00797 } 00798 00799 return result; 00800 } 00801 00802 NLG_R n; 00803 00804 int nlg_play(const char *nlg_file) 00805 { 00806 printf("nlg_play:%s\n",nlg_file); 00807 00808 /* NLGの初期化 */ 00809 if (initNLG(&n, nlg_file) < 0) 00810 { 00811 lcd_printStrY(1, " ERROR!!"); 00812 printf("Failed to init.\n"); 00813 return -1; 00814 } 00815 00816 printf("Play..\n"); 00817 00818 /* 再生する */ 00819 PlayNLG(&n, 360); 00820 00821 /* mute */ 00822 boardMute(); 00823 00824 /* NLGファイルを閉じる */ 00825 CloseNLG(); 00826 00827 return 0; 00828 } 00829 00830 void error_sdcard(void) 00831 { 00832 lcd_printStr2("SD CARD", "ERROR!"); 00833 00834 while(1); 00835 } 00836 00837 int get_nlg_file(char *dest, int index) 00838 { 00839 char *cwd = "/sd/"; 00840 int count = -1; 00841 DIR *dir = opendir(cwd); 00842 00843 dest[0] = 0; 00844 00845 if (dir == NULL) 00846 { 00847 return -1; 00848 } 00849 struct dirent *dent; 00850 00851 while(1) 00852 { 00853 dent = readdir(dir); 00854 if (!dent) 00855 break; 00856 00857 // resource or hidden file 00858 if (dent->d_name[0] == '.') 00859 continue; 00860 00861 char *ext = strrchr(dent->d_name, '.'); 00862 if (!ext) 00863 continue; 00864 00865 if (strcasecmp(ext, ".nlg") != 0) 00866 continue; 00867 00868 if (count < 0) 00869 count = 0; 00870 00871 count++; 00872 00873 if (index < 0) 00874 continue; 00875 00876 if (count <= index) 00877 continue; 00878 00879 strcpy(dest, dent->d_name); 00880 break; 00881 } 00882 closedir(dir); 00883 return count; 00884 } 00885 00886 // 00887 // COM mode 00888 // 00889 void loop_for_com() 00890 { 00891 Serial pc(USBTX, USBRX); 00892 00893 lcd_printStrY(1,"COM MODE"); 00894 00895 pc.printf("com_mode\n"); 00896 00897 while(1) 00898 { 00899 unsigned char sw, adr, val; 00900 00901 sw = pc.getc(); 00902 if (sw == 0x00) 00903 continue; 00904 00905 adr = pc.getc(); 00906 val = pc.getc(); 00907 switch(sw) 00908 { 00909 case 1: 00910 regFMOut(adr, val); 00911 break; 00912 case 2: 00913 regFM2Out(adr, val); 00914 break; 00915 case 3: 00916 regPSGOut(adr, val); 00917 break; 00918 case 0x0f: 00919 pc.baud(9600 * val); 00920 break; 00921 } 00922 00923 // pc.printf("sw = %02x, adr = %02x, val = %02x\n", sw, adr, val); 00924 } 00925 } 00926 00927 // 00928 // title 00929 // 00930 void putTitle() 00931 { 00932 lcd_printStr2("NBCTRL", NBCTRL_VER); 00933 wait(1.5); 00934 } 00935 00936 // 情報の表示 00937 void show_info(int files) 00938 { 00939 char buf[16]; 00940 00941 Timer t; 00942 int result_us = 0; 00943 t.reset(); 00944 t.start(); 00945 00946 // actual timing 00947 regFMOut(0x20, 0x00); 00948 00949 result_us = t.read_us(); 00950 t.stop(); 00951 00952 printf("result_us=%dus\n", result_us); 00953 sprintf(buf, "R:%dus", result_us); 00954 lcd_printStrY(1, buf); 00955 wait(3); 00956 00957 sprintf(buf, "%8s", __DATE__); 00958 lcd_printStrYscr(1, buf); 00959 wait(3); 00960 00961 if (files < 0) 00962 lcd_printStrY(1, "NO FILES"); 00963 else 00964 { 00965 char buf[16]; 00966 sprintf(buf, "%3dfiles", files); 00967 lcd_printStrY(1, buf); 00968 } 00969 wait(3); 00970 lcd_cls(); 00971 } 00972 00973 // 00974 // main 00975 // 00976 int main() 00977 { 00978 bool info_mode = false; 00979 bool com_mode = false; 00980 00981 int files = 0; 00982 00983 char file[32]; 00984 char path[48]; 00985 00986 ioInit(); 00987 00988 wait_ms(20); 00989 00990 // reset SHIFT REGISTER 00991 ioShiftOut((0xFF << 8) | (ACTLOW)); 00992 00993 // モード 00994 if (!sw_next) 00995 info_mode = true; 00996 if (!sw_prev) 00997 com_mode = true; 00998 00999 // 初期化とタイトル表示 01000 lcd_init(); 01001 putTitle(); 01002 01003 // ボードの初期化 01004 boardInit(); 01005 01006 // 通信モードに移行 01007 if (com_mode) 01008 loop_for_com(); 01009 01010 files = get_nlg_file(file, -1); 01011 01012 // エラー表示 01013 if (files < 0) 01014 error_sdcard(); 01015 01016 // 情報モード 01017 if (info_mode) 01018 show_info(files); 01019 01020 01021 bool repeat_flag = false; 01022 int idx = 0; 01023 while(files > 0) 01024 { 01025 char buf[16]; 01026 01027 get_nlg_file(file, idx); 01028 01029 sprintf(path, "/sd/%s", file); 01030 printf("path=%s\n",path); 01031 01032 lcd_cls(); 01033 lcd_printStrY(0, file); 01034 01035 sprintf(buf, "%2d ", idx + 1); 01036 lcd_printStrY(1, buf); 01037 01038 nlg_play(path); 01039 01040 // wait for chattering 01041 wait(0.25); 01042 01043 // wait release 01044 waitButtonRelease(); 01045 01046 // if play button is pressed 01047 if (g_stop) 01048 { 01049 g_stop = false; 01050 g_prev = false; 01051 01052 lcd_printStrY(1, " STOP "); 01053 01054 // wait any button is pressed 01055 waitButtonPress(); 01056 01057 // 01058 if (!sw_prev) { 01059 lcd_printStrY(1, " PREV "); 01060 g_prev = true; 01061 } 01062 if (!sw_play) 01063 { 01064 lcd_printStrY(1, " PLAY "); 01065 repeat_flag = true; 01066 } 01067 if (!sw_next) 01068 { 01069 lcd_printStrY(1, " NEXT "); 01070 repeat_flag = false; 01071 } 01072 01073 // wait release 01074 waitButtonRelease(); 01075 01076 // reset board 01077 boardInit(); 01078 } 01079 01080 // play prev or next song 01081 if (g_prev) 01082 { 01083 g_prev = false; 01084 01085 if (idx - 1 >= 0) 01086 idx--; 01087 else 01088 idx = files - 1; 01089 01090 continue; 01091 } 01092 01093 if (!repeat_flag) 01094 { 01095 if (idx + 1 < files) 01096 idx++; 01097 else 01098 idx = 0; 01099 } 01100 repeat_flag = false; 01101 } 01102 }
Generated on Wed Aug 3 2022 10:50:43 by 1.7.2