UMEHOSHI ITA TOP PAGE COMPUTER SHIEN LAB
#ifndef _MY_USB_CMD_H /* Guard against multiple inclusion */ #define _MY_USB_CMD_H void set_hex_string(uint16_t d, char s[]); char *set_decimal_string(int d, char s[], int width); int set_uint_str(uint32_t d, char s[], char c, int width); #define HEX(c) (c < 10 ? c + '0' : c - 10 + 'A') #define DEC(c) (c >= 'A' ? c - 'A' + 10: c - '0') extern int flagThrough;//スルーモードで 1 extern int flagEcho;// エコーモードで1 // --ここから: USB出力用リングバッファと関連関数---------------------------------- #define OB_SIZE 48 //16の倍数でなければならない。(out buffer size) #define OB_MAX (512+2) extern uint8_t outBuffers[OB_MAX][OB_SIZE] __attribute__((coherent, aligned(16))); extern uint32_t outDataNumb[OB_MAX]; //上記の各配列に記憶されるデータのbyte数 extern int outBuffCount;//これが「OB_MAX」に達した時点がバッファフル状態 extern int outDataCount;//outBuffersに記憶されるバイト数 extern int flagErrorSetOutData;//バッファフルでデータをsetOutDataを使うと、1がセット extern int numbOutputs;//outBuffers出力の始まりから送信終了まで、出力データ数を保持する void init_outBuffers();//上記出力用リングバッファ用変数の初期化(APP_State_Resetで利用) void send_16byte(uint32_t data); void send_char(char data); void setBreakBuffer(); void send_string(char *s);//文字列をUSBへ送信するための登録( API 関数) void send_hex_low(uint32_t d);//dの下位16ビットを16進8桁でUSBhの出力登録 void send_hex_hi(uint32_t d);//dの上位16ビットを16進8桁でUSBhの出力登録 void send_decimal(int d, int width);//dを10進でwidth幅文字列で出力登録 void send_padding_uint(uint32_t d, char c, int width);//uintの10進幅で出力登録 int get_capacity();// outBuffersの残りメモリブロック取得 bool request_acc_outbuff(uint16_t id);// outBuffers関連変数の使用権の取得 uint16_t release_acc_outbuff(uint16_t id);// outBuffers関連変数の使用権の開放 // dのdoubleをwの幅指定でprecisonの精度幅の文字列を送信。 void send_float(double d, int width, int precison); // dのdoubleをwの幅指定でprecisonの精度幅の指数表現文字列を送信。 void send_exponent(double d, int width, int precison); void send_ume_id(); int dummy_recive(uint8_t cdata);// USBからの置き換え可能な受信処理 void requset_send_usb_if_available(); uint8_t* getSendBuff();// 現在のバッファを終わらせて送信。 void noticeSendCcomplete(); // 上記送信処理が終わった通知に対する処理 // --ここまで: USB出力用リングバッファと関連関数---------------------------------- char select_command(uint8_t c);// // 逐次に受け取る引数がコマンドと判定したら実行 char set_commad_char(uint8_t c);// 逐次に受け取る引数で、コマンドを解析して記録 char set_recive_data(uint8_t cdata, int flagBreak) ;//上記2つを使った受信関数 #endif /* _MY_USB_CMD_H */
/* * USB の送受信アプリに必要な処理 * UMEHOSHI ITA USB受信の受け口となる関数「set_recive_data」の定義 * UMEHOSHI ITA USBからの送信命令 「send_string」「send_hex_low」「send_hex_hi」 * 「send_decimal」etc */ #include <stdint.h> #include <stdio.h> #include <string.h> #include <xc.h> #include "my_app.h" #include "my_usb_cmd.h" #include "my_beep.h" #include "my_sys.h" #include "my_uart.h" #include "common.h" int flagThrough = 0; //スルーモードで 1 static char code_to_nomal_mode[80] = "\ncode from through mode to nomal mode 123\r"; static int code_to_size = 0; //上記の文字サイズを記憶 static int code_to_nomal_idx = 0; // 上記の記憶、チェック用 int flagEcho = 1; // エコーモードで1 // "\nE\r" or "\rE\r" or "\rE\n" or "\nE\n" の受付で、1と0が交互に切り替わる。 char message[128]; // メッセージ用文字列の一時記憶用 void (*go_func)(void); // USBからの実行指示で実行する関数スタートアドレス記憶変数 int safetyflag= 1;// 書き込み範囲を制限 追加[2023-4] //dのデータ下位16ビットを16進4桁文字列にして、[5]の記憶域のsにセットする。 void set_hex_string(uint16_t d, char s[]) { int i; for (i = 3; i >= 0; i--) { char c = (char) (d & 0x0f); c = c >= 10 ? c - 10 + 'A' : c + '0'; s[i] = c; d >>= 4; } s[4] = '\x0'; } //dのintデータが符号付きの前提で、10進数文字列にして、[12]の記憶域のsにセットする。 // 幅指定は最大が11文字で、少ない場合は拡張され、戻り値で調整される。 //(戻り値はwidthを利用した、sからずれた値になり、戻り値を表示することで幅指定を実現) char *set_decimal_string(int d, char s[], int width) { s[0] = ' '; int x10 = 1000000000; int minus = d < 0; int sign_pos = -1; if (minus == 1) d = -d; //正に設定 int i = 1; for (; i <= 10; i++) { int x = d / x10; if (x != 0 && sign_pos == -1) sign_pos = i - 1; if (sign_pos == -1) { s[i] = ' '; } else { s[i] = x + '0'; } d -= x * x10; x10 /= 10; } char *p = s + (11 - width); if (sign_pos != -1) { s[sign_pos] = '+'; if (minus == 1) s[sign_pos] = '-'; if (11 - sign_pos > width) { p = s + sign_pos; } } else { s[10] = '0'; } return p; } // dの符号なしデータの10進文字列を[12]の記憶域のaにセットする。 // 幅指定は最大が11文字で、満たない部分はcで埋める。 // 幅が足りない指定の場合は、これに収まる下位の桁だけの文字列になる。 // 幅に収まる変換が正しくできた場合は、1を返す。 int set_uint_str(unsigned d, char s[], char c, int width) { char a[12]; int i = 0; while (i < width) { if (d == 0 && i > 0) a[i++] = c; else a[i++] = d % 10 + '0'; d /= 10; } int j = 0; for (j = 0; j < width; j++) { s[j] = a[--i]; } s[j] = 0; if (d != 0) return 0; return 1; } // USB出力用リングバッファ関連変数と関連関数 ====================================== uint32_t outDataNumb[OB_MAX]; // 下記の各配列に記憶されるデータのbyte数 uint8_t outBuffers[OB_MAX][OB_SIZE] __attribute__((coherent, aligned(16))); int idxSetOutBuf; //バッファからの取り出し先添え字 int idxGetOutBuf; //バッファへの入力先添え字(上と違う時、出力すべきデータがある) int outBuffCount; //これが「OB_MAX」に達した時点がバッファフル状態 int outDataCount = 0; //outBuffers全体に記憶されるバイト数 int idxSetCount; //outBuffers[idxGetOutBuf][idxSetCount]が現在の記憶域となる。 int flagErrorSetOutData; //バッファフルでデータをsetOutDataを使うと、1がセット // (これがセットされるとバッファへの設定は不可となり復帰は、リセットのみ) int numbOutputs = 0; //outBuffers出力の始まりから送信終了まで、出力データ数を保持する //getSendBuff関数で記憶され、noticeSendCcomplete関数で0になり、フラグ的な役割もある //上記outBuffers関連変数の排他制御管理変数 volatile uint16_t accessing_outbuffer __attribute__((section("sfrs"))); // 上記outBuffers関連変数の排他制御で、アクセス権を要求する // id は指定は、ID_ACCESS_XXXXXXの定義で決めて使う。 // 割り込み時にoutBuffersを操作する使う排他制御用の権限要求関数 bool request_acc_outbuff(uint16_t id) { if (accessing_outbuffer == id) { return true; } if (accessing_outbuffer != 0) { return false; } accessing_outbuffer |= id; if (accessing_outbuffer == id) { return true; // outBuffersへのアクセス権を得た } accessing_outbuffer &= ~id; return false; } // 上記割込み取得した権限を返す関数 uint16_t release_acc_outbuff(uint16_t id) { return accessing_outbuffer &= ~id; //出力バッフ利用終了 } // USBへの送信データがoutBuffersのバッファにあるならUSB送信を促す void requset_send_usb_if_available() { static int pre_outDataCount = 0; if (outBuffCount == 0 //出力すべき回数がゼロ && outDataCount > 0 //USBへの出力登録byte数がある。 && pre_outDataCount == outDataCount) { // 出力登録byte数に変動がない setBreakBuffer(); //USBへの出力すべき回数をアップ(出力を促す) } pre_outDataCount = outDataCount; //USBへの出力登録byte数 } //上記outBuffersの残り容量([OB_SIZE]のブロック数) // おおよその残りバイト数は、[この関数の戻り値]×OB_SIZEで算出できる。 int get_capacity() { return (OB_MAX - outBuffCount); //return outBuffCount; } // 上記 USB出力用リングバッファ関連変数 の初期化(APP_State_Resetで呼び出す) void init_outBuffers() { idxSetOutBuf = 0; //バッファからの取り出し先添え字 idxGetOutBuf = 0; //バッファへの入力先添え字(上と違う時、出力すべきデータがある) outBuffCount = 0; //これが「OB_MAX」に達した時点がバッファフル状態 outDataCount = 0; //outBuffers全体に記憶されるバイト数 idxSetCount = 0; //outBuffers[idxGetOutBuf][idxSetCount]が現在の記憶域となる。 // ( outDataNumb[]の配列に記憶直後にidxSetCountを0にする。) //flagErrorSetOutData = 0;//バッファフルでデータをsetOutDataを使うと、1がセット numbOutputs = 0; //outBuffers出力の始まりから送信終了まで、出力データ数を保持する accessing_outbuffer = 0; //上記変数がMy_APP_Tasks内でアクセス中の時true } // USBへの出力データを行う時にエラーチェックするサブ関数 static bool check_on_error() { static bool errorFlag = false; if (errorFlag) return false; if (outBuffCount + 1 >= OB_MAX - 2) {// -2の余裕 flagErrorSetOutData = 1; if (errorFlag == 0) {// バッファブロックの最後にエラー文字列をセット if (outDataNumb[idxSetOutBuf] != 0) {// ブロックにデータがある? if (++idxSetOutBuf >= OB_MAX) idxSetOutBuf = 0; //次のブロックへ idxSetCount = 0; outBuffCount++; } outBuffers[idxSetOutBuf][idxSetCount++] = '\r'; //"\r\nB ERR\r\n" outBuffers[idxSetOutBuf][idxSetCount++] = '\n'; outBuffers[idxSetOutBuf][idxSetCount++] = 'B'; outBuffers[idxSetOutBuf][idxSetCount++] = ' '; outBuffers[idxSetOutBuf][idxSetCount++] = 'E'; outBuffers[idxSetOutBuf][idxSetCount++] = 'R'; outBuffers[idxSetOutBuf][idxSetCount++] = 'R'; outBuffers[idxSetOutBuf][idxSetCount++] = '\r'; outBuffers[idxSetOutBuf][idxSetCount++] = '\n'; outDataNumb[idxSetOutBuf] = idxSetCount; // 1バッファ内のデータサイズ outDataCount += idxSetCount; // 全バッファ内のデータサイズ if (++idxSetOutBuf >= OB_MAX) idxSetOutBuf = 0; //次のブロックへ idxSetCount = 0; outBuffCount++; } errorFlag = true; return false; } return true; } // 引数の1byteを上記のUSB出力用バッファ入れる。 // outBuffers[idxSetOutBuf]バッファ内の位置や数などの情報も更新される // リングバッファのリング更新(idxSetOutBufの変更)はしない。 static uint8_t setOutData(uint8_t data) {//dataをバッファにセット if (appData.isConfigured == false) return 0; if (!check_on_error()) return 0; outBuffers[idxSetOutBuf][idxSetCount++] = data; outDataNumb[idxSetOutBuf] = idxSetCount; // 1バッファ内のデータサイズ outDataCount++; // 全バッファ内のデータサイズ return data; //check sum 計算用に使う戻れ値 } // sizeの個数数のデータをUSB出力用バッファ(outBuffers)に入れる。 // 出力バッファへのセットは、setOutDataを使う。 // outBuffers[idxSetOutBuf]が一杯になれば、idxSetOutBuf変更でリングバッファを更新 static uint16_t setOutDatas(uint8_t *datas, int size) { if (appData.isConfigured == false) return 0; int n = 0; uint16_t sum = 0; while (n < size) { if (flagErrorSetOutData == 1) break; if (idxSetCount >= OB_SIZE) { if (++idxSetOutBuf >= OB_MAX) {// 次のバッファに進む idxSetOutBuf = 0; // リングバッファの先頭に戻る。 } idxSetCount = 0; outBuffCount++; // バッファ使用数が増える } setOutData(datas[n]); //1byteをバッファにセット sum += datas[n++]; } return sum; } //文字列をUSB出力用バッファ入れる。 // setOutDatasを使う。(必要に応じて自動的にリングバッファを更新) static uint16_t setOutString(uint8_t *s) { int size = 0; while (s[size])size++; return setOutDatas(s, size); } // 現在使っているバッファを終わらせて、次のバッファを使うように進める。 // リングバッファを強制的更新(idxSetOutBufを変更する。) void setBreakBuffer() { if (appData.isConfigured == false) return; if (!check_on_error()) return; //if(outDataNumb[idxGetOutBuf] == 0) return;//現在のバッファが空ならリターン if (outDataNumb[idxSetOutBuf] == 0) return; //現在のバッファが空ならリターン if (++idxSetOutBuf >= OB_MAX) {// 次のバッファに進む idxSetOutBuf = 0; // リングバッファの先頭に戻る。 } idxSetCount = 0; outBuffCount++; // バッファ使用中の数が増える } // dataの1byteをUSB出力用バッファ(outBuffers)に入れる。(バイナリにも可能) void send_char(char data) { if (appData.isConfigured == false) return; if (flagErrorSetOutData == 1) return; if (idxSetCount >= OB_SIZE) { if (++idxSetOutBuf >= OB_MAX) {// 次のバッファに進む idxSetOutBuf = 0; // リングバッファの先頭に戻る。 } idxSetCount = 0; outBuffCount++; // バッファ使用数が増える } setOutData(data); //1byteをバッファにセット } // 2バイト、リトルエンディアンでUSB送信 void send_16byte(uint32_t data) { send_char(data & 0x0ff); send_char((data >> 8) & 0x0ff); setBreakBuffer(); } // sの文字列を、USBの出力バッファに登録する。(USBの初期化が済んでいない場合は無視) // (割り込みルーチンから呼ぶ場合は、注意が必要!) void send_string(char *s) { if (appData.isConfigured) {//USBが接続されて、初期化済みか? setOutString(s); setBreakBuffer(); } } // dのデータ下位16ビットを16進4桁でUSBの出力バッファに登録する。 void send_hex_low(uint32_t d) { char s[5]; set_hex_string(d, s); send_string(s); } // dのデータ上記16ビットを16進4桁でUSBの出力バッファに登録する。 void send_hex_hi(uint32_t d) { send_hex_low(d >> 16); } // dのintデータを10進10桁でUSBの出力バッファに登録する。 // 幅指定は最大が11文字で、少ない場合は拡張される。欠けずに表示する void send_decimal(int d, int width) { char s[12] = "-2147483648"; // 0x8fffffff if (d == 0x80000000) { send_string(s); return; } char *p=set_decimal_string(d, s, width); send_string(p); } // dの符号なしを幅指定の10文字列で送信する。幅に満たない空間はcで埋める void send_padding_uint(uint32_t d, char c, int width) { char s[12]; set_uint_str(d, s, c, width); // 0で埋めた10進文字列に send_string(s); } // dのdoubleをwの幅指定でprecisonの精度幅の文字列を送信。 void send_float(double d, int width, int precison) { char fmt[8]; char s[32]; sprintf(fmt, "%%%d.%df", width, precison); sprintf(s, fmt, d); send_string(s); } // dのdoubleをwの幅指定でprecisonの精度幅の指数表現文字列を送信。 void send_exponent(double d, int width, int precison) { char fmt[8]; char s[32]; sprintf(fmt, "%%%d.%de", width, precison); sprintf(s, fmt, d); send_string(s); } void send_ume_id(){ //send_string("ume202107"); send_string("ume202304");// 変更[2023-4] } // USB CDC の送信する時に、現在の対象となるバッファが必要で、その取得関数。 // (my_app.c のMy_APP_Tasks ( )の中で使う)) // グローバル変数のnumbOutputsに、送信データ数をセット(フラグ的な役割もある) uint8_t* getSendBuff() {// numbOutputs = outDataNumb[idxGetOutBuf]; // returnバッファ内のデータbyte数 outDataNumb[idxGetOutBuf] = 0; //バッファ内データ数クリア return &outBuffers[idxGetOutBuf][0]; } // 上記のgetSendBuffで得られたバッファの送信処理終了時点で、通知に対する処理 // (my_app.c のMy_APP_Tasks ( )の中で使う) // グローバル変数のnumbOutputsの送信データ数0に戻すを。(フラグ的な役割もある) void noticeSendCcomplete() { if (numbOutputs == 0) return; //出力中でないならなにもしない。 if (++idxGetOutBuf >= OB_MAX) { idxGetOutBuf = 0; //リングバッファなので先頭に戻る。 } outBuffCount--; // バッファ内の送出が終わったので、使用中バッファの数を減らす outDataCount -= numbOutputs; // 送信データ数で、バッファ内のデータ数を減らす numbOutputs = 0; } // USB出力用リングバッファと関連関数 ===========ここまで========================== // USB 受信コマンド関連の変数定義 ここから ====================================== uint8_t recieveSetBuffer[256]; //Sコマンドで受信したデータの格納用 int idxRecieveSet = 0; //---------------------------------------------- uint8_t hex_cmd; //受信コマンド文字 [G S R E T] uint8_t hex_num; //受信データ部のサイズ uint8_t hex_num_count = 0; // 上記 hex_num の数まで受信を数える制御用 uint32_t hex_adr; //受信データ部のアドレス uint8_t hex_typ; //受信データ種別 uint8_t hex_dat; //受信データ uint8_t hex_chk; //受信したチェックサム uint8_t hex_chk_calc; //上記チェックサムと比較するために受信データを加算する変数 // 以下の制御用変数は、対応する処理に移行する直前で0に戻す uint32_t hex_cnt = 0; //制御用で、受信データ数を数える。(SWITGHで分岐) uint32_t hex_low = 0; ////制御用で、16進で下位バイトの時に1 uint8_t flag_to_check_sum = 0; // 1になったらチェックサムを計算 uint8_t flag_hex_cmd_complete = 0; //1になった時がコマンド受信の終了 // USB 受信コマンド関連の変数定義 ======================================ここまで // USB 受信コマンド関連の関数定義 ここから ====================================== void send_command_char_response(uint8_t cdata) { send_char(cdata); //USBへ応答 if (_HANDLES[_IDX_DEF_POLLS_UART] == uart_cmd_mode_polling) { set_data_snd_uart(cdata); // uartSndBufへの送信データをセット } } void send_command_str_response(uint8_t *str) { int i = 0; while (str[i] != 0) { send_command_char_response(str[i++]); } } // data を 16進文字列に変換して得られるcolumnSiz個の文字並びを出力 // send_command_char_response関数を利用 static uint16_t send_uint_hex(uint32_t data, int columnSize) {//(設定したデータの合計を返す。これはチェックサムの計算に使われる。) uint16_t sum = 0; uint8_t d1; uint32_t mask = 0x0f << ((columnSize - 1) * 4); while (columnSize > 0) { d1 = (data & mask) >> ((columnSize - 1) * 4); d1 = HEX(d1); sum += d1; send_command_char_response(d1); columnSize--; mask >>= 4; } return sum; } // 「G」のデータ取得コマンドに対するレスポンス // 外部変数、hex_adr のアドレスより、hex_numのサイズ要求に対するレスポンス出力で、 // チェックサムを含めた文字列を、send_command_char_response関数、 // send_uint_hex関数で送出する。 void G_response2() { uint16_t sum = 0; sum += ':'; send_command_char_response(':'); sum += send_uint_hex(hex_num, 2); //データ数 sum += send_uint_hex((uint32_t) hex_adr, 8); //アドレス sum += send_uint_hex(0, 2); //種別コード uint8_t *p = (uint8_t *) hex_adr, *pEnd = (uint8_t *) hex_adr + hex_num; while (p < pEnd) { sum += send_uint_hex(*p++, 2); // 1byte設定 } sum = 0x100 - (0x0FF & sum); send_uint_hex(sum, 2); ///チェックサムの埋め込み send_command_char_response(0x0D); // 13のCRを埋め込み send_command_char_response(0x0A); // 10のLFを埋め込み(以上で改行の埋め込み) setBreakBuffer(); } // 「S」のデータ取得コマンドに対するレスポンス // recieveSetBufferの内容を、hex_adrのポインタが指す記憶域に設定する。 // (hex_numの個数だけ取り出してメモリに並べる) int setToMemory() { // EEPRO領域の書き込みを可能にする変更[2023-4] 以下変更 uint8_t n; if ( hex_adr >= 0x9D020000 && hex_adr <= 0x9D03FFFC || safetyflag==0) { if(hex_num % 4 != 0) { sprintf(message, "SET:%08X %d writes do not match\r\n", hex_adr, hex_num); return 1; // 書き込みが1ワードでない } uint32_t *adr = (uint32_t *)hex_adr; int rtv = 0; for (n = 0; n < hex_num; adr++) { uint32_t data=recieveSetBuffer[n++]; data+=recieveSetBuffer[n++]<<8; data+=recieveSetBuffer[n++]<<16; data+=recieveSetBuffer[n++]<<24; uint32_t *ptw = (uint32_t *)((uint32_t)adr+0x20000000); rtv += _nvm_write_word((uint32_t)ptw,data); if(rtv != 0){ sprintf(message, "SET:%08X Failed to write %02X.\r\n", hex_adr, data); return 1; // 書き込み失敗 } if(*adr != data){ sprintf(message, "SET:%08X %08X != %08X.\r\n", hex_adr, *adr, data); return 1; } } return 0; } else if(hex_adr >= 0x80000000 && hex_adr <= 0x8000ffff || hex_adr >= 0xa0000000 && hex_adr <= 0xa000ffff || safetyflag==0){ uint8_t *p = (uint8_t *) hex_adr; for (n = 0; n < hex_num; n++) {// RAM範囲のメモリ設定 *p++ = recieveSetBuffer[n]; } return 0; } return 1; }// EEPRO領域の書き込みを可能にする変更[2023-4] 以上変更 // 逐次に受け取る引数で、コマンドを解析データをグローバル変数へ記録 char set_commad_char(uint8_t cdata) { hex_cnt++; switch (hex_cnt) { case 1://コマンド文字 種別 S R G A hex_cmd = cdata; idxRecieveSet = 0; break; case 2://データ数取得スタート(16進文字のデータ) hex_num_count = hex_low = 0; hex_num = DEC(cdata); break; case 3://データ数取得セット(16進文字のデータ) hex_num <<= 4; hex_num += DEC(cdata); break; case 4://アドレス取得セット(16進文字のデータ)スタート hex_adr = DEC(cdata); break; case 5://アドレス数取得セット(16進文字のデータ) case 6: case 7: case 8: case 9: case 10: case 11: hex_adr <<= 4; hex_adr += DEC(cdata); break; case 12://レコード種別セット(16進文字のデータ)スタート hex_typ = DEC(cdata); break; case 13://レコード種別取得セット(16進文字のデータ) hex_typ <<= 4; hex_typ += DEC(cdata); break; default: if (hex_cmd == 'G' || hex_cmd == 'R') {// メモリ内容の要求コマンド flag_to_check_sum = 1; // cdataはチェックサム→検証へ } else if (hex_cmd == 'S') { if (hex_num_count < hex_num) {//セットデータ if (hex_low == 0) { hex_low = 1; hex_dat = DEC(cdata); } else if (hex_low == 1) { hex_low = 0; hex_num_count++; hex_dat <<= 4; hex_dat += DEC(cdata); recieveSetBuffer[idxRecieveSet++] = hex_dat; } } else if (hex_num_count == hex_num) {//データ取得終了 flag_to_check_sum = 1; // cdataはチェックサム→検証へ } } } // 受信用の記憶処理のブロック終わりでチェックサムの検証 1byte(16進2文字分) if (flag_to_check_sum == 1) { if (hex_low == 0) {//チェックサム受信 hex_chk = DEC(cdata); hex_low = 1; return 'R'; } else if (hex_low == 1) { hex_chk <<= 4; hex_chk += DEC(cdata); hex_low = 0; flag_to_check_sum = 0; if (((hex_chk_calc + hex_chk) & 0x0ff) != 0) { sprintf(message, "check sum error %c\r\n", cdata); send_command_str_response(message); return 'W'; //チェックサムのエラー } flag_hex_cmd_complete = 1; //受信処理の完結 return 'R'; // 送信バッファになにも設定していないことを知らせる。 } } hex_chk_calc += cdata; //チェックサム計算 return 'R'; // 送信バッファになにも設定していないことを知らせる。 } // 引数のデータの逐次に受け取る使い方で、コマンドと判定した時、そのコマンドを実行 char select_command(uint8_t cdata) { static uint8_t prev_cdata = 0; if (flagThrough == 1) { //スルーモードではUART1とスルーで通信するモード send_uart1(cdata); //UART1の送信用リングバッファに記憶 return 'R'; } if (flagEcho && !usb_receiver_disable_flag) { // エコーモード状態の時、USB受信データを、出力バッファに入れる。 send_command_char_response(cdata); } if (prev_cdata == 0x0D && cdata == 0x0A) { prev_cdata = cdata; if (hex_cnt == 2 && hex_cmd == 'E') {// エコーモード切り替え flag_to_check_sum = hex_chk_calc = hex_cnt = 0; flagEcho = !flagEcho; // エコーモード切り替え if (flagEcho) send_command_str_response("ECHO ON\r\n"); else send_command_str_response("ECHO OFF\r\n"); return 'W'; } if (hex_cnt == 2 && hex_cmd == 'T') {// スルーモードへ flag_to_check_sum = hex_chk_calc = hex_cnt = 0; send_command_str_response("Through Mode\r\n"); flagThrough = 1; flagErrorSetOutData = 0; init_outBuffers(); return 'W'; // 送信バッファにセットしたことを知らせる } flag_to_check_sum = hex_chk_calc = hex_cnt = 0; if (flag_hex_cmd_complete) {//命令確定後の受信コマンドによる分岐 flag_hex_cmd_complete = 0; if (hex_cmd == 'G') {// メモリ内容の取得 G_response2(); return 'W'; // 送信バッファにセットしたことを知らせる } else if (hex_cmd == 'S') {// メモリ設定 int r = setToMemory(); // 変更[2023-4] ここから if(r==0) { sprintf(message, "SET:%08X\r\n", hex_adr);//成功 send_command_str_response(message); }// 変更[2023-4] ここまで return 'W'; // 送信バッファにセットしたことを知らせる } else if (hex_cmd == 'R') { // 実行処理の登録 go_func = (void (*)())hex_adr; if (!usb_receiver_disable_flag) { sprintf(message, "START:%08X\r\n", hex_adr); send_command_str_response(message); return 'W'; // 送信バッファにセットしたことを知らせる } else { return 'R'; } } } if (hex_cnt != 0) {// これが成立することはチェックサムのエラー!! sprintf(message, "exception hex_cnt: %d\r\n", hex_cnt); send_command_str_response(message); return 'W'; } return 'R'; //無視(記憶しない) } prev_cdata = cdata; return 0; } // USB受信の置き換え可能なダミー関数 int dummy_recive(uint8_t cdata) { return 0; } // USBからの1byte受信で実行する。( コマンド解析して応答処理を実行 ) char set_recive_data(uint8_t cdata, int flagBreak) { int change = _RECIVE_USB_FUNC(cdata); if (change == 1) return 'R'; if (flagThrough == 1) { //スルーモードではUART1とスルーで通信するモード send_uart1(cdata); //UART1の送信用リングバッファに記憶 if (code_to_size == 0) { code_to_size = strlen(code_to_nomal_mode); code_to_nomal_idx = 0; } if (cdata == code_to_nomal_mode[code_to_nomal_idx]) { code_to_nomal_idx++; if (code_to_nomal_idx == code_to_size) { flagThrough = 0; // スルーモードからノーマルに遷移 code_to_nomal_idx = 0; } } else { code_to_nomal_idx = 0; } return 'R'; } char rtn = select_command(cdata); // 逐次に受け取る引数がコマンド判定実行 if (rtn != 0) return rtn; return set_commad_char(cdata); // 文字をコマンド解析バッファにセット }