data.txtに設定した文字列をUSB-Serialに出力し続けるプログラムです。 text dataを出力する装置の模擬装置として使用します。 data.txtはmbedのlocalに保管しておきます。
Dependencies: mbed BufferedSerial
<mbed側の準備>
serial_dummyはmbedのlocalに保管した data.txt のtext dataをUSB-serialから出力し続けるプログラムです。 text data を出力する装置の模擬として使用します。
data.txtの例は次のところにあります。 /media/uploads/suupen/data.txt
data.txt には出力する文字列のほかに、 1.USB-serial のbaudrate 9600[bps]の例
B9600
2.送信文字列の送信時間間隔 1000[ms]の例
T1000
を設定できます。 '>B','>T' のコマンドは、設定した次の行の文字列から有効になります。
<パソコン側の準備>
windowsの場合パソコンにUSB-serialのdriverをインストールする必要があります。 driver は次のページからダウンロードして下さい。 https://mbed.org/handbook/Windows-serial-configuration
Revision 3:327bb0fcdf45, committed 23 months ago
- Comitter:
- suupen
- Date:
- Fri Jan 06 11:06:27 2023 +0000
- Parent:
- 2:52002844d0c6
- Commit message:
- W/R/E????????????
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 52002844d0c6 -r 327bb0fcdf45 main.cpp --- a/main.cpp Sat Aug 02 10:05:35 2014 +0000 +++ b/main.cpp Fri Jan 06 11:06:27 2023 +0000 @@ -1,46 +1,41 @@ /** - serial data 送信ツール + GreenPak HEX file Writer + +<Green Pak Hex file structure> +HEX fileのコードは以下を参照 +https://ja.wikipedia.org/wiki/Intel_HEX - V00.01 : 140719 +start code +| byte count +| | address +| | | recode type +| | | | data checksum +↓ ↓ ↓ ↓ ↓ ↓ +: 10 0000 00 9F07003D0F0000000000000000000000 FE ↓ data +: 10 0010 00 00000000000000000000000000000000 E0 +:100020000000000000000000000000E0FB000000F5 +:10003000000000000000000000000000CFEFFC0006 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:1000600000303000303030300000303030000000E0 +:1000700030303030000000000000000000000000C0 +:10008000FA00FA663B1422300C0000000000000069 +:10009000000000000000000000000300000000005D +:1000A0000000002000010000000201000002000129 +:1000B0000000020100000200010000020100000235 +:1000C000000100000200010000000101000000002A +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F000000000000000000000000000000000A55B ↑ data +:00000001FF ← end code +0x0000 ~ 0x00ff の256byteになる <使い方> -"data.txt" に送信する文字列を設定し、mbedに保管する。 -mbedに通電するかRESET SW を押すとUSB-serialから文字列を出力する -<data.txtの設定方法> -1.コマンド - USB-serialのbaudrate - 9600[bps]を設定する場合 - >B9600 - >b9600 - - 文字列間の送信間隔 - 1000[ms]を設定する場合 - >T1000 -2.送信文字列 - asciiコードで文字を記述していく - 送信は一行毎となる - -3.data.txt設定例 -次の行から----------------- ->B9600 ->T100 -123456789 ->T200 -abcdefghi ->T300 -ABCDEFGHI - ->B9600 ->T1000 -123 -abc -ABC -ひとつ前の行まで------------- <USB-Serialの通信設定値> -baudrate : data.txtで設定可能(初期値=9600[bps] +baudrate : PC_BOUDで変更可能(初期値=9600[bps] bits : 8bit parity : none stopbit : 1bit @@ -50,41 +45,103 @@ //#define DEBUG +#include "ctype.h" #include "mbed.h" +#include <cstdint> #include <stdio.h> -#include "ctype.h" //#include <string.h> #include "BufferedSerial.h" +//#include "mbed2/233/i2c_api.h" +//#include "mbed2/233/I2C.h" -LocalFileSystem local("local"); // local file systemの設定 -//Serial pc(USBTX, USBRX); // usb-serialの設定 -#ifdef DEBUG -Serial chk(USBTX, USBRX); -#endif // DEBUG +// mbed内部のfilesystem +LocalFileSystem local("local"); // local file systemの設定 +#define Z_bufferNumber \ + (100) // HEX fileは1行44byteなのでこれ以上のbyte数があればよい(file + // systemは1行づつ読み込まれる) + +char buffer[Z_bufferNumber]; // 読みだしたデータの保管先 +// PCからのコマンド入力用USB-Uart +// 参考コードは DELICIA_BLE_CommDummy BufferedSerial pc(USBTX, USBRX); -//BufferedSerial pc(p9, p10); +#define PC_BOUD (115200) +#define Z_pcBuffer (100) // PCからのコマンド保管用 +char B_pcRx[Z_pcBuffer] __attribute__(( + section("AHBSRAM0"))); // RAMが足りないのでEthernet用エリアを使用 + // (0x2007c000) (コピー元をそのまま転記した) + Timeout txSend; // 送信間隔作成用 -DigitalOut ledopen(LED1); // 1:file open 0:file close -DigitalOut ledout(LED2); // 1: serial out -//DigitalOut lederror(LED4); +// mbedボード上の動作モニタLED +DigitalOut ledopen(LED1); // 1:file open 0:file close +DigitalOut ledout(LED2); // 1: serial out +// DigitalOut lederror(LED4); + +//*************************************************************************** +// 新規のコマンド受信用 +//*************************************************************************** +//============================================================================= +// PC 側処理 (command & data 送受信) +// main()から呼び出す。戻り値が"1"ならコマンド解析する。 +//============================================================================= +/** + * pc rx data + * @@para ans 0:受信中 1:受信完了 + */ +int pcRecive(void) { + static char *p = B_pcRx; + char data; + int ans = 0; +#define Z_00 (0x00) +#define Z_CR (0x0d) + + // buffer オーバーフロー対策 + if ((p - B_pcRx) >= Z_pcBuffer) { + p = B_pcRx; + *p = Z_00; + } -#define Z_bufferNumber (500) -char buffer[Z_bufferNumber]; // 読みだしたデータの保管先 + // 1文字受信処理 + while ((pc.readable() == 1) && ans == 0) { + // 受信データあり + data = pc.getc(); + + switch (data) { + case Z_CR: + *p = Z_00; + p = B_pcRx; + ans = 1; + break; + case ' ': + case ',': + // nothing + break; + default: + // 小文字のアルファベットを大文字に差し替える + if (('a' <= data) && (data <= 'z')) { + data -= ('a' - 'A'); + } + *p++ = data; + *p = Z_00; + break; + } + } + return (ans); +} + +//*************************************************************************** +// ベースのPC送信割り込み +//*************************************************************************** int D_start_wait_us = 100; // 送信開始時の待ち時間 (1/1 [us]/bit) min = 100[us] -int D_char_wait_us = 100; // キャラクタ間の送信間隔 ( 1/1 [ms]/bit) min = 100[us] +int D_char_wait_us = + 100; // キャラクタ間の送信間隔 ( 1/1 [ms]/bit) min = 100[us] // 送信処理状態遷移 -typedef enum { - Z_txIdle, - Z_txStart, - Z_txSend -} txSend_t; +typedef enum { Z_txIdle, Z_txStart, Z_txSend } txSend_t; txSend_t M_txSend = Z_txIdle; // 0:受信完了(STX送信待ち) 1:STX以降CRまでの送信中 - /** * 割り込み処理 * 送信データ送信処理 @@ -92,35 +149,36 @@ * 送信データ1byte毎に2[ms]の遅延 * を入れて送信する */ -void txDataSend(void) -{ - static char *p; +void txDataSend(void) { + static char *p; - switch(M_txSend) { + switch (M_txSend) { - case Z_txStart: - // STX ~ CR 送信 - p = buffer; - M_txSend = Z_txSend; - //brak; - case Z_txSend: - if(*p != 0x00) { - pc.putc(*p++); - txSend.attach_us(&txDataSend, D_char_wait_us); // 次回送信開始まで2[us]セット(時間は可変設定にする) - } - - else { - // 送信完了 - M_txSend = Z_txIdle; - txSend.detach(); - } - break; - case Z_txIdle: // defaultと同じ処理 - default: - // nothing - break; + case Z_txStart: + // STX ~ CR 送信 + p = buffer; + M_txSend = Z_txSend; + // brak; + case Z_txSend: + if (*p != 0x00) { + pc.putc(*p++); + wait(0.01); + txSend.attach_us( + &txDataSend, + D_char_wait_us); // 次回送信開始まで2[us]セット(時間は可変設定にする) } + else { + // 送信完了 + M_txSend = Z_txIdle; + txSend.detach(); + } + break; + case Z_txIdle: // defaultと同じ処理 + default: + // nothing + break; + } } /** @@ -128,151 +186,687 @@ * 受信終了から送信開始までの20[ms]遅延設定 * */ -void txDataWait(void) -{ - txSend.attach_us(&txDataSend, D_start_wait_us); // 受信完了からx[ms]経過待ち - M_txSend = Z_txStart; - +void txDataWait(void) { + txSend.attach_us(&txDataSend, D_start_wait_us); // 受信完了からx[ms]経過待ち + M_txSend = Z_txStart; } /** * 送信終了判定 * @@para int 戻り値 送信処理状況 1:送信完了 0:送信中 */ -int txSendEndCheck(void) -{ - int ans; - if(M_txSend == Z_txIdle) { - ans = 1; - } else { - ans = 0; +int txSendEndCheck(void) { + int ans; + if (M_txSend == Z_txIdle) { + ans = 1; + } else { + ans = 0; + } + + return (ans); +} + +/** asciiコード1文字をhexに変換 + * 引数: char* p : 文字の入った変数のポインタ + * 戻り値: 0 ~ 0x0f, 0xff:変換不能 + */ +uint8_t atoh1(char *p) { + char a = *p; + uint8_t ans = 0xff; + + if (('0' <= a) && (a <= '9')) { + ans = a - '0'; + } else if (('a' <= a) && (a <= 'f')) { + ans = a - 'a' + 0x0a; + } else if (('A' <= a) && (a <= 'F')) { + ans = a - 'A' + 0x0a; + } else { + ans = 0xff; + } + return (ans); +} + +/** asciiコード2文字をhexに変換 + * 引数: char* p: 文字の入った変数ポインタ + * 戻り値: 0x00 ~ 0xff (変換不能の場合は0xffにしている) + */ +uint8_t atoh2(char *p) { + uint8_t ans; + uint8_t up = atoh1(p); + uint8_t dn = atoh1(p + 1); + if ((up != 0xff) && (dn != 0xff)) { + ans = (up << 4) | dn; + } else { + // 変換不能 + ans = 0xff; + } + return (ans); +} + +uint8_t byteCount; +uint8_t address; // 上位8bitは必ず0x00になるので省略 +uint8_t recodeType; +uint8_t NVMData[16][16]; // NVM書き込み用データバッファ +uint8_t EEPROMData[16][16]; // EEPROM用書き込みデータバッファ + +uint8_t NVMFile = 0; // NVMファイルの読み込み結果 0:NG, 1:OK +uint8_t EEPROMFile = 0; // EEPROMファイルの読み込み結果 0:NG, 1:OK + +/** NVM fileを読み出す + * 対象ファイルは"NVM.hex"の決め打ち + * 戻り値: 0:データなし n:読み込み桁数(正常なら16になる) + */ +uint8_t NVMFileRead(void) { + uint8_t ans = 0; + FILE *fp; + char *p; + + pc.printf("NVM file read\n"); + + fp = fopen("/local/NVM.hex", "r"); + + while (fgets(buffer, Z_bufferNumber, fp) != NULL) { + p = buffer; + + while (*p != 0x00) { + switch (*p++) { + case ':': + byteCount = atoh2(p); + p += 2; + p += 2; + address = atoh2(p) >> 4; // 2byte addressの下位1byteを取得 + p += 2; + recodeType = atoh2(p); + p += 2; + + pc.printf("byte=%02x address=%02x type=%02x : ", byteCount, address, + recodeType); + wait(.1); + if (byteCount != 0x10) { + pc.printf("end of data\n"); + break; + } + + ans++; + for (uint8_t i = 0; i < 16; i++) { + NVMData[address][i] = atoh2(p); + p += 2; + pc.printf("%02x", NVMData[address][i]); + } + pc.printf("\n"); + } } + } + fclose(fp); - return(ans); + return (ans); +} + +//***************************************************************************** +// GreenPak のI2C処理 +//***************************************************************************** +I2C Wire(p9, p10); // sda, sci + +//@ss+ Block Address (Control Byte A10-8) +// A10 +// |A9 +// ||A8 +// xxxx 098xb +// xxxx 001xb :resster +// xxxx 010xb :NVM +// xxxx 110xb :EEPROM +#define RESISTER_CONFIG 0x02 // 0x01 << 1 //@ss+ +#define NVM_CONFIG 0x04 // 0x02 << 1 +#define EEPROM_CONFIG 0x06 // 0x03 << 1 + +#define MASK_CONTROLCODE \ + (0xf0) // I2Cアドレス部の ControlCode(上位4bit)を残すためのマスク + +int count = 0; +uint8_t slave_address = 0x00; +bool device_present[16] = {false}; +uint8_t data_array[16][16] = {}; + +typedef enum { NVM, EEPROM, RESISTER } greenPakMemory_t; +greenPakMemory_t NVMorEEPROM = NVM; // 読み書き対象 + +char i2cBuffer[10]; // I2C送受信用バッファ + +//////////////////////////////////////////////////////////////////////////////// +// power cycle +//////////////////////////////////////////////////////////////////////////////// +void powercycle(int code) { + pc.printf("Power Cycling!\n"); + // Software reset + // レジスタアドレス=0xc8 bit1を1にすると I2C resetをしてNVMのデータをレジスタに転送することができる + i2cBuffer[0] = 0xC8; + i2cBuffer[1] = 0x02; + Wire.write(code & MASK_CONTROLCODE, i2cBuffer, + 2); //@ss MASK_CONTROLCODEは Control Code:slave + // addressを残しresisterアクセスにするためのマスク + // pc.printf("Done Power Cycling!\n"); +} + +//////////////////////////////////////////////////////////////////////////////// +// ack polling +//////////////////////////////////////////////////////////////////////////////// +int ackPolling(int addressForAckPolling) { + int ans; + int nack_count = 0; + while (1) { + + ans = Wire.read(addressForAckPolling, i2cBuffer, 0); + if (ans == 0) { + return 0; + } + if (nack_count >= 1000) { + pc.printf("Geez! Something went wrong while programming!\n"); + return -1; + } + nack_count++; + wait(1); + } } - +//////////////////////////////////////////////////////////////////////////////// +// ping +//////////////////////////////////////////////////////////////////////////////// +void ping(void) { + int ans; - + for (int i = 0; i < 16; i++) { + ans = Wire.read(i << 4, i2cBuffer, 0); // ICに影響を与えないようにreadコマンドで確認する - + if (ans == 0) { + pc.printf("device 0x%02x", i); + pc.printf(" is present\n"); + device_present[i] = true; + } else { + pc.printf("device 0x%02x", i); + pc.printf(" is not present\n"); + device_present[i] = false; + } + } + wait(0.1); +} -int main() +//////////////////////////////////////////////////////////////////////////////// +// resister un protect +//////////////////////////////////////////////////////////////////////////////// +void resister_unprotect(uint8_t control_code) //@ss+ { - pc.baud(9600); - FILE *fp; -// int ans; - char *p; - int timer; // serial送信時間間隔 ( 1/1 [ms]/bit) - int baud; // usb-serialのbaudrate ( 1/1 [bps]/bit) + // resisiterのプロテクトをクリアする + // レジスタアドレス: 0xE1 にNVMのプロテクト領域がある (HM p.171) + // 下位2bit 00: read/write/erase 可能 + // 01: read禁止 + // 10: write/erase 禁止 + // 11: read/write/erase 禁止 + i2cBuffer[0] = 0xE1; + i2cBuffer[1] = 0x00; + Wire.write(control_code & MASK_CONTROLCODE, i2cBuffer, + 2); //@ss MASK_CONTROLCODEは Control Code:slave + // addressを残しresisterアクセスにするためのマスク + + i2cBuffer[0] = 0xE1; + Wire.write(control_code & MASK_CONTROLCODE, i2cBuffer, 1); + + Wire.read(control_code & MASK_CONTROLCODE, i2cBuffer, 1); + uint8_t val = i2cBuffer[0]; + pc.printf("0xE1 = %02x\n", val); // 0x00ならプロテクト解除されている +} + +//////////////////////////////////////////////////////////////////////////////// +// writeChip +//////////////////////////////////////////////////////////////////////////////// +#if 0 +// NVM書き込み試験用 +int writeChip(greenPakMemory_t NVMorEEPROM) { + i2cBuffer[0] = 0x00; + i2cBuffer[1] = 0x01; + i2cBuffer[2] = 0x02; + i2cBuffer[3] = 0x03; + i2cBuffer[4] = 0x04; + i2cBuffer[5] = 0x05; + i2cBuffer[6] = 0x06; + i2cBuffer[7] = 0x07; + i2cBuffer[8] = 0x08; + i2cBuffer[9] = 0x09; + i2cBuffer[10] = 0x0a; + i2cBuffer[11] = 0x0b; + i2cBuffer[12] = 0x0c; + i2cBuffer[13] = 0x0d; + i2cBuffer[14] = 0x0e; + i2cBuffer[15] = 0x0f; + i2cBuffer[16] = 0x10; + Wire.write(0x04, i2cBuffer, 17); + +} +#endif +#if 1 +int writeChip(greenPakMemory_t NVMorEEPROM) { + int control_code = 0x00; + int addressForAckPolling = 0x00; + bool RESISTER_selected = false; + bool NVM_selected = false; + bool EEPROM_selected = false; + + int ans; + + if (NVMorEEPROM == NVM) { + + control_code = slave_address << 4; + resister_unprotect(uint8_t(control_code)); //@ss+ - fp = fopen("/local/data.txt", "r"); - ledopen = 1; + // Serial.println(F("Writing NVM")); + // Set the slave address to 0x00 since the chip has just been erased + slave_address = 0x00; + // Set the control code to 0x00 since the chip has just been erased + control_code = 0x00; + control_code |= NVM_CONFIG; + NVM_selected = true; + addressForAckPolling = 0x00; + } else if (NVMorEEPROM == EEPROM) { + // pc.printf("Writing EEPROM\n"); + control_code = slave_address << 4; + control_code |= EEPROM_CONFIG; + EEPROM_selected = true; + addressForAckPolling = slave_address << 4; + } else if (NVMorEEPROM == RESISTER) //@ss+↓ + { + // Serial.println(F("Writing RESISTER")); + control_code = slave_address << 4; + control_code |= RESISTER_CONFIG; + RESISTER_selected = true; + addressForAckPolling = slave_address << 4; + } //@ss+↑ + + pc.printf("Control Code: 0x%02x\n", control_code); + + // Assign each byte to data_array[][] array; + // http://www.gammon.com.au/progmem + + // pc.printf("New NVM or EEPROM data:"); + if (NVM_selected) { + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + data_array[i][j] = NVMData[i][j]; + } + } + } else if (EEPROM_selected) { + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + data_array[i][j] = EEPROMData[i][j]; + } + } + } + + if (NVM_selected || RESISTER_selected) { + // slave_addressに設定されている値に差し替える + // レジスタアドレス=0xcaのbit3-0 にI2C slave address を設定する + // bit7-4: 0にすると下位4bitのアドレスが有効になる(1にするとIO2,3,4,5の端子状態がアドレスになる) + data_array[0xC][0xA] = (data_array[0xC][0xA] & 0xF0) | slave_address; + } + + // Write each byte of data_array[][] array to the chip + for (int i = 0; i < 16; i++) { + i2cBuffer[0] = i << 4; + pc.printf("%02x: ", i); + + for (int j = 0; j < 16; j++) { + i2cBuffer[j+1] = data_array[i][j]; + pc.printf("%02x ", data_array[i][j]); + } + ans = Wire.write(control_code, i2cBuffer, 17); + wait(0.01); + + if (ans != 0) { + pc.printf(" nack\n"); + pc.printf("Oh No! Something went wrong while programming!\n"); + Wire.stop(); + return -1; + } + + pc.printf(" ack "); + + + if (ackPolling(addressForAckPolling) == -1) { + return -1; + } else { + pc.printf("ready\n"); + wait(0.1); + } + } + + Wire.stop(); + + if (RESISTER_selected == false) { //@ss+ + powercycle(control_code); + } //@ss+ + return 0; +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +// eraseChip // 230105OK +//////////////////////////////////////////////////////////////////////////////// +int eraseChip(greenPakMemory_t NVMorEEPROM) { + int control_code = + (slave_address << 4) | + RESISTER_CONFIG; //@ss ControlCode(A14-11)=slaveAddress(4bit) + + // BlockAddress(A10-8)=000b + int addressForAckPolling = control_code; + + if (NVMorEEPROM == RESISTER) { //@ss+↓ + pc.printf("RESISTER don't erase area\n"); + return (0); + } //@ss+↑ + + resister_unprotect(uint8_t(control_code)); //@ss+ - while(1) { - if(fgets(buffer, Z_bufferNumber, fp) != NULL){ -// ans = fscanf(fp,"%s",buffer); -// if(ans != -1) { - p = buffer; - // 文字列 or 制御コマンド - //ここ - switch(*p){ - case '>': -// if(*p == '>') { - // コマンドとして処理する - p++; - switch(*p++) { - case 'T': - case 't': - switch(*p++) { - case 'F': - case 'f': - // serial data の送信間隔時間を設定 - timer = 0; - while(isdigit(*p) != 0) { - timer *= 10; - timer += (*p++ - '0'); - } - if(timer == 0) { - // 設定値が0の時は、最小値1[us]を設定する - // 100[us]以下にすると割り込みがかからなくなるのでその対策 - D_start_wait_us = 100; - } else { - D_start_wait_us = timer * 1000; - } -#ifdef DEBUG - chk.printf("timer = %06d\r\n",timer); -#endif // DEBUG - break; - case 'C': - case 'c': - // キャラクタ間隔時間(第二引数)の確認 - timer = 0; - while(isdigit(*p) != 0) { - timer *= 10; - timer += (*p++ - '0'); - } - if(timer == 0) { - // 設定値が0の時は、最小値1[us]を設定する - // 100[us]以下にすると割り込みがかからなくなるのでその対策 - D_char_wait_us = 100; - } else { - D_char_wait_us = timer * 1000; - } - break; - default: - break; - } - break; - case 'B': - case 'b': - // baudrate 設定 - baud = 0; - while(isdigit(*p) != 0) { - baud *= 10; - baud += (*p++ - '0'); - } - pc.baud(baud); -#ifdef DEBUG - chk.printf("baud = %d\r\n",baud); -#endif //DEBUG - break; - default: - // nothing - break; - } - //ここ - break; - case ';': - // comment - break; - default: - // } else { - // 出力文字列として処理する + for (uint8_t i = 0; i < 16; i++) { + pc.printf("Erasing page: 0x%02x ", i); + + i2cBuffer[0] = 0xE3; // I2C Word Address + //@ss Page Erase Register + //@ss bit7: ERSE 1 + //@ss bit4: ERSEB4 0: NVM, 1:EEPROM + //@ss bit3-0: ERSEB3-0: page address + if (NVMorEEPROM == NVM) { + pc.printf("NVM \n"); + i2cBuffer[1] = (0x80 | i); + } else if (NVMorEEPROM == EEPROM) { + pc.printf("EEPROM \n"); + i2cBuffer[1] = (0x90 | i); + } + Wire.write(control_code, i2cBuffer, + 2); //@ss Control BYte = ControlCode + Block Address + + wait(0.1); //@ss+ + + /* To accommodate for the non-I2C compliant ACK behavior of the Page Erase + * Byte, we've removed the software check for an I2C ACK and added the + * "Wire.endTransmission();" line to generate a stop condition. + * - Please reference "Issue 2: Non-I2C Compliant ACK Behavior for the NVM + * and EEPROM Page Erase Byte" in the SLG46824/6 (XC revision) errata + * document for more information. + * + * 要約: たまにNACKを返すことがあるので、無条件に終了させればよい。 + * //@ss220717+ + * https://medium.com/dialog-semiconductor/slg46824-6-arduino-programming-example-1459917da8b + * //@ss220717+ + */ + + //@ss tER(20ms)の処理終了待ち + if (ackPolling(addressForAckPolling) == -1) { + pc.printf("NG\n"); + return -1; + } else { + pc.printf("ready \n"); + wait(0.1); + } + } + + powercycle(control_code); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// readChip 230105OK +//////////////////////////////////////////////////////////////////////////////// +void readChip(greenPakMemory_t NVMorEEPROM) { //@ss220717+ + //@ssint readChip(String NVMorEEPROM) { //@ss220717- + // int control_code = slave_address << 4; + uint8_t control_code = slave_address << 4; + + //@ss I2C Block Addressの設定 + //@ss A9=1, A8=0: NVM (0x02) + //@ss A9=1, A8=1: EEPROM (0x03) + if (NVMorEEPROM == NVM) { + control_code |= NVM_CONFIG; + pc.printf("memory = NVM\n"); + } else if (NVMorEEPROM == EEPROM) { + control_code |= EEPROM_CONFIG; + pc.printf("memory = EEPROM\n"); + } else if (NVMorEEPROM == RESISTER) //@ss+↓ + { + control_code |= RESISTER_CONFIG; + pc.printf("memory = RESISTER\n"); + + } //@ss+↑ + + // pc.printf("memory = %02x\n",control_code); + + for (int i = 0; i < 16; i++) { + pc.printf("%02x :", i); //@ss+ + + i2cBuffer[0] = i << 4; + Wire.write(control_code, i2cBuffer, 1, true); + wait(0.01); + + Wire.read(control_code, i2cBuffer, 16, true); + + for (int j = 0; j < 16; j++) { + pc.printf("%02x ", i2cBuffer[j]); + } + pc.printf("\n"); + } + Wire.stop(); +} + +//***************************************************************************** +// main +//***************************************************************************** +#if 1 +int main() { + // pc.format(8,Serial::Even,1); + pc.baud(PC_BOUD); + Wire.frequency(10000); + + NVMFile = NVMFileRead(); + pc.printf("ans = %d", NVMFile); + while (1) { + // typedef enum { NVM, EEPROM, RESISTER } greenPakMemory_t; + // greenPakMemory_t NVMorEEPROM = NVM; // 読み書き対象 + + if (pcRecive() == 1) { + char *p = B_pcRx; + switch (*p++) { - txDataWait(); - while(txSendEndCheck() == 0) { - // 割り込みで送信中 - ledout = !ledout; // この行がないとwhile文から抜けなくなる。原因不明 - } + case 'A': + // スレーブアドレス変更 + uint8_t address; + address = atoh1(p); + if ((0 <= address) && (address <= 0xf)) { + pc.printf("old address = %02x\n", slave_address); + slave_address = address; + pc.printf("new address = %02x\n", slave_address); + } else { + pc.printf("now address = %02x\n", slave_address); + } + break; + case 'C': + pc.printf("slave address = %02x\n", slave_address); + + pc.printf("Memory = "); + + switch (NVMorEEPROM) { + case NVM: + pc.printf("NVM\n"); + break; + case EEPROM: + pc.printf("EEPROM\n"); + break; + case RESISTER: + pc.printf("RESISTER"); + break; + default: + pc.printf("unkown\n"); + break; + } + break; + case 'E': + pc.printf("erase start\n"); + if (eraseChip(NVMorEEPROM) == 0) { + pc.printf("erase OK\n"); + } else { + pc.printf("erase NG\n"); + } + break; + case 'S': + // 操作対象変更 + switch (*p++) { + case 'N': + NVMorEEPROM = NVM; + pc.printf("new select = NVM set\n"); + break; + case 'E': + NVMorEEPROM = EEPROM; + pc.printf("new select = EEPROM set\n"); + break; + case 'R': + NVMorEEPROM = RESISTER; + pc.printf("new select = RESISTER set\n"); + break; + default: + switch (NVMorEEPROM) { + case NVM: + pc.printf("now select = NVM\n"); + break; + case EEPROM: + pc.printf("now select = EEPROM\n"); + break; + case RESISTER: + pc.printf("now select = RESISTER"); + break; + default: + pc.printf("now select = unkown\n"); + break; + } + break; + } + break; + case 'P': + ping(); + break; + case 'R': + pc.printf("Reading chip!\n"); + readChip(NVMorEEPROM); + + break; + case 'W': + // erase + pc.printf("erase start\n"); + if (eraseChip(NVMorEEPROM) == 0) { + pc.printf("erase OK\n"); + } else { + pc.printf("erase NG\n"); + } + + // write + if (writeChip(NVMorEEPROM) == 0) { + pc.printf("write OK\n"); + } else { + pc.printf("write NG\n"); + } + break; + case 'D': + pc.printf("D input\n"); + break; + } + } + } +} +#endif + +#if 0 + +int main() { + pc.baud(115200); + FILE *fp; + // int ans; + char *p; + int timer; // serial送信時間間隔 ( 1/1 [ms]/bit) + int baud; // usb-serialのbaudrate ( 1/1 [bps]/bit) + + NVMFile = NVMFileRead(); + pc.printf("main main\n"); + + fp = fopen("/local/NVM.hex", "r"); + ledopen = 1; + + while (1) { + + if (fgets(buffer, Z_bufferNumber, fp) != NULL) { + // ans = fscanf(fp,"%s",buffer); + // if(ans != -1) { + p = buffer; -// pc.printf("%s\n",buffer); - wait_ms(timer); - //ここ - break; + for(uint8_t i = 0; i < 255; i++){ + pc.printf("*p(%d) = %02x\n",i, *(p+i)); + wait(0.1); + } + + // 文字列 or 制御コマンド + while (*p != 0x00) { + pc.printf("*p = %02x\n",*p); + switch (*p++) { + case ':': + byteCount = atoh2(p); + p += 2; + p += 2; + address = atoh2(p) >> 4; // 2byte addressの下位1byteを取得 + p += 2; + recodeType = atoh2(p); + p += 2; + + pc.printf("byte=%02x address=%02x type=%02x\n", byteCount, address, + recodeType); + wait(1); + if (byteCount != 0x10) { + wait(1); + break; + } + + for (uint8_t i = 0; i < 16; i++) { + NVMData[address][i] = atoh2(p); + p += 2; + pc.printf("%02x", NVMData[address][i]); + } + pc.printf("\n"); + } + } + +#if 0 + switch (*p++) { + + default: + // 出力文字列として処理する + txDataWait(); + while (txSendEndCheck() == 0) { + // 割り込みで送信中 + ledout = + !ledout; // この行がないとwhile文から抜けなくなる。原因不明 } - } else { - // 読みだすデータがなくなったら、先頭に戻す - fclose(fp); - ledopen = 0; -// wait_ms(timer); - fp = fopen("/local/data.txt", "r"); - ledopen = 1; - } + wait_ms(timer); + //ここ + break; + } +#endif + } else { + // 読みだすデータがなくなったら、先頭に戻す + pc.printf("\nend end end\n"); // ファイルの最後の"LF"の代わりに出力する + + fclose(fp); + ledopen = 0; + // wait_ms(timer); + + fp = fopen("/local/NVM.hex", "r"); + ledopen = 1; } + } } - +#endif