// player_task.c // // --- public domain, no warranty. #include #include #include #include "lcd_task.h" #include "button_task.h" LOCAL ID PlyTsk; #define DELAY (Delay) /* モールス符号のテーブル */ #define DASH(x) (1 << (x)) #define DOT(x) (0 << (x)) typedef struct _mdef { UB length; UB code; } MDEF; LOCAL const MDEF MTable[] = { {6, DOT (0)|DASH(1)|DASH(2)|DOT (3)|DASH(4)|DOT (5) }, // @ {2, DOT (0)|DASH(1) }, // A {4, DASH(0)|DOT (1)|DOT (2)|DOT (3) }, // B {4, DASH(0)|DOT (1)|DASH(2)|DOT (3) }, // C {3, DASH(0)|DOT (1)|DOT (2) }, // D {1, DOT (0) }, // E {4, DOT (0)|DOT (1)|DASH(2)|DOT (3) }, // F {3, DASH(0)|DASH(1)|DOT (2) }, // G {4, DOT (0)|DOT (1)|DOT (2)|DOT (3) }, // H {2, DOT (0)|DOT (1) }, // I {4, DOT (0)|DASH(1)|DASH(2)|DASH(3) }, // J {3, DASH(0)|DOT (1)|DASH(2) }, // K {4, DOT (0)|DASH(1)|DOT (2)|DOT (3) }, // L {2, DASH(0)|DASH(1) }, // M {2, DASH(0)|DOT (1) }, // N {3, DASH(0)|DASH(1)|DASH(2) }, // O {4, DOT (0)|DASH(1)|DASH(2)|DOT (3) }, // P {4, DASH(0)|DASH(1)|DOT (2)|DASH(3) }, // Q {3, DOT (0)|DASH(1)|DOT (2) }, // R {3, DOT (0)|DOT (1)|DOT (2) }, // S {1, DASH(0) }, // T {3, DOT (0)|DOT (1)|DASH(2) }, // U {4, DOT (0)|DOT (1)|DOT (2)|DASH(3) }, // V {3, DOT (0)|DASH(1)|DASH(2) }, // W {4, DASH(0)|DOT (1)|DOT (2)|DASH(3) }, // X {4, DASH(0)|DOT (1)|DASH(2)|DASH(3) }, // Y {4, DASH(0)|DASH(1)|DOT (2)|DOT (3) }, // Z {0, 0}, // [ {0, 0}, // (backslash) {0, 0}, // ] {0, 0}, // ^ {0, 0}, // _ {0, 0}, // {0, 0}, // ! {6, DOT (0)|DASH(1)|DOT (2)|DOT (3)|DASH(4)|DOT (5) }, //"" {0, 0}, // # {0, 0}, // $ {0, 0}, // % {0, 0}, // & {6, DOT (0)|DASH(1)|DASH(2)|DASH(3)|DASH(4)|DOT (5) }, // ' {5, DASH(0)|DOT (1)|DASH(2)|DASH(3)|DOT (4) }, // ( {6, DASH(0)|DOT (1)|DASH(2)|DASH(3)|DOT (4)|DASH(5) }, // ) {4, DASH(0)|DOT (1)|DOT (2)|DASH(3) }, // * {5, DOT (0)|DASH(1)|DOT (2)|DASH(3)|DOT (4) }, // + {6, DASH(0)|DASH(1)|DOT (2)|DOT (3)|DASH(4)|DASH(5) }, // , {6, DASH(0)|DOT (1)|DOT (2)|DOT (3)|DOT (4)|DASH(5) }, // - {6, DOT (0)|DASH(1)|DOT (2)|DASH(3)|DOT (4)|DASH(5) }, // . {5, DASH(0)|DOT (1)|DOT (2)|DASH(3)|DOT (4) }, // / {5, DASH(0)|DASH(1)|DASH(2)|DASH(3)|DASH(4) }, // 0 {5, DOT (0)|DASH(1)|DASH(2)|DASH(3)|DASH(4) }, // 1 {5, DOT (0)|DOT (1)|DASH(2)|DASH(3)|DASH(4) }, // 2 {5, DOT (0)|DOT (1)|DOT (2)|DASH(3)|DASH(4) }, // 3 {5, DOT (0)|DOT (1)|DOT (2)|DOT (3)|DASH(4) }, // 4 {5, DOT (0)|DOT (1)|DOT (2)|DOT (3)|DOT (4) }, // 5 {5, DASH(0)|DOT (1)|DOT (2)|DOT (3)|DOT (4) }, // 6 {5, DASH(0)|DASH(1)|DOT (2)|DOT (3)|DOT (4) }, // 7 {5, DASH(0)|DASH(1)|DASH(2)|DOT (3)|DOT (4) }, // 8 {5, DASH(0)|DASH(1)|DASH(2)|DASH(3)|DOT (4) }, // 9 {6, DASH(0)|DASH(1)|DASH(2)|DOT (3)|DOT (4)|DOT (5) }, // : {0, 0}, // ; {0, 0}, // < {5, DASH(0)|DOT (1)|DOT (2)|DOT (3)|DASH(4) }, // = {0, 0}, // > {6, DOT (0)|DOT (1)|DASH(2)|DASH(3)|DOT (4)|DOT (5) }, // ? }; #define DOT_RATIO 1 #define DASH_RATIO 3 #define CHARSPACE_RATIO 3 #define WORDSPACE_RATIO 5 LOCAL INT CharSpaceMode = 0; #define P4DDR (_UB *)0x00ffffc5 #define P4DR (_UB *)0x00ffffc7 LOCAL void SetBuzzer(INT buzzer) { *P4DDR = 0xff; *P4DR = buzzer ? 0xff : 0x00; LEDFlg = buzzer; tk_rel_wai(LCDTsk); return; } /* 1文字単位の再生 */ LOCAL ER play_char(const MDEF *mdef) { ER er; INT i; /* 有効な文字でない場合は語間として扱う */ if (!mdef->length) { er = tk_dly_tsk(DELAY * WORDSPACE_RATIO); goto fin0; } /* 文字 */ for (i = 0; i < mdef->length; i++) { /* 長点ないし短点 */ SetBuzzer(1); if (mdef->code & (1 << i)) { er = tk_dly_tsk(DELAY * DASH_RATIO); } else { er = tk_dly_tsk(DELAY * DOT_RATIO); } SetBuzzer(0); if (er < E_OK) goto fin0; if (i != (mdef->length - 1)) { er = tk_dly_tsk(DELAY * DOT_RATIO); if (er < E_OK) goto fin0; } } /* 文字同士の間 */ if (CharSpaceMode) { er = tk_dly_tsk(DELAY * DOT_RATIO); } else { er = tk_dly_tsk(DELAY * CHARSPACE_RATIO); } if (er < E_OK) goto fin0; fin0: return er; } /* 文字列単位の再生 */ LOCAL ER play_string(const UB *code) { ER er; /* 各種初期設定 */ SetBuzzer(0); // ブザーoff CharSpaceMode = 0; // 文字間隔:通常 memset(&LCDBuf[0], ' ', 16); // 表示領域クリア tk_wup_tsk(LCDTsk); // LCD表示更新 er = E_OK; while (*code) { /* 文字表示 */ memcpy(&LCDBuf[0], &LCDBuf[1], 15); // スクロール LCDBuf[15] = *code; // 再生する文字を表示 tk_wup_tsk(LCDTsk); // 表示更新 /* 符号再生 */ if (*code == '_') { CharSpaceMode ^= 1; // 文字間隔:短縮 er = E_OK; } else { er = play_char(&MTable[*code & 0x3f]); } if (er < E_OK) goto fin0; code++; } fin0: return er; } /* 乱文作成 */ LOCAL UB buffer[128]; LOCAL UH RandomValue = 0; LOCAL UH RandomSeed = 0x4431; LOCAL UH random_8bit(void) { RandomValue = RandomValue * 5 + RandomSeed; return RandomValue >> 8; } LOCAL void random_string(void) { int i, n; LOCAL const UB start[] = "HR HR _BT_ "; LOCAL const UB end[] = "_AR_"; LOCAL const UB character[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,/"; memcpy(buffer, start, sizeof(start)); n = sizeof(start) - 1; for (i = 0; i < 32; i++) { buffer[i + n] = (!((i + 1) % 8)) ? ' ' : character[random_8bit() % (sizeof(character) - 1)]; } memcpy(&buffer[i + n], end, sizeof(end)); return; } /* 符号再生タスク */ LOCAL void player_task(void) { while (1) { random_string(); play_string(buffer); tk_dly_tsk(2500); } tk_exd_tsk(); } /* 符号再生タスク・起動部分 */ EXPORT ER player_task_init(W start) { W er; T_CTSK ctsk; /* 終了処理 */ if (start < 0) { er = E_OK; goto fin2; } /* 処理タスク作成 */ ctsk.exinf = NULL; ctsk.tskatr = TA_HLNG; ctsk.task = player_task; ctsk.itskpri = 26; ctsk.stksz = 512; er = tk_cre_tsk(&ctsk); if (er < E_OK) { tm_putstring((UB *)"player_task_init: tk_cre_tsk\n"); goto fin0; } PlyTsk = er; /* 処理タスク起動 */ er = tk_sta_tsk(PlyTsk, 0); if (er < E_OK) { tm_putstring((UB *)"player_task_init: tk_sta_tsk\n"); goto fin1; } goto fin0; fin2: tk_ter_tsk(PlyTsk); fin1: tk_del_tsk(PlyTsk); fin0: return er; }