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

main.cpp

Committer:
suupen
Date:
16 months ago
Revision:
3:327bb0fcdf45
Parent:
2:52002844d0c6

File content as of revision 3:327bb0fcdf45:

/**
 GreenPak HEX file Writer

<Green Pak Hex file structure>
HEX fileのコードは以下を参照
https://ja.wikipedia.org/wiki/Intel_HEX

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になる

 <使い方>


<USB-Serialの通信設定値>
baudrate : PC_BOUDで変更可能(初期値=9600[bps]
bits     : 8bit
parity   : none
stopbit  : 1bit


*/

//#define DEBUG

#include "ctype.h"
#include "mbed.h"
#include <cstdint>
#include <stdio.h>
//#include <string.h>
#include "BufferedSerial.h"
//#include "mbed2/233/i2c_api.h"
//#include "mbed2/233/I2C.h"

// 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);
#define PC_BOUD (115200)
#define Z_pcBuffer (100) // PCからのコマンド保管用
char B_pcRx[Z_pcBuffer] __attribute__((
    section("AHBSRAM0"))); // RAMが足りないのでEthernet用エリアを使用
                           // (0x2007c000) (コピー元をそのまま転記した)

Timeout txSend; // 送信間隔作成用

// 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;
  }

  // 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]

// 送信処理状態遷移
typedef enum { Z_txIdle, Z_txStart, Z_txSend } txSend_t;
txSend_t M_txSend = Z_txIdle; // 0:受信完了(STX送信待ち) 1:STX以降CRまでの送信中

/**
 * 割り込み処理
 * 送信データ送信処理
 *   受信完了から送信開始の20[ms]の遅延
 *   送信データ1byte毎に2[ms]の遅延
 *   を入れて送信する
 */
void txDataSend(void) {
  static char *p;

  switch (M_txSend) {

  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;
  }
}

/**
 * main処理
 * 受信終了から送信開始までの20[ms]遅延設定
 *
 */
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;
  }

  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);
}

//*****************************************************************************
// 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);
}

////////////////////////////////////////////////////////////////////////////////
// resister un protect
////////////////////////////////////////////////////////////////////////////////
void resister_unprotect(uint8_t control_code) //@ss+
{
  // 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+

    // 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+


  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++) {

      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;


    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文から抜けなくなる。原因不明
            }

            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