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

Files at this revision

API Documentation at this revision

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