Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed BufferedSerial
main.cpp@3:327bb0fcdf45, 2023-01-06 (annotated)
- Committer:
- suupen
- Date:
- Fri Jan 06 11:06:27 2023 +0000
- Revision:
- 3:327bb0fcdf45
- Parent:
- 2:52002844d0c6
W/R/E????????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
suupen | 0:7c6ad253848a | 1 | /** |
suupen | 3:327bb0fcdf45 | 2 | GreenPak HEX file Writer |
suupen | 3:327bb0fcdf45 | 3 | |
suupen | 3:327bb0fcdf45 | 4 | <Green Pak Hex file structure> |
suupen | 3:327bb0fcdf45 | 5 | HEX fileのコードは以下を参照 |
suupen | 3:327bb0fcdf45 | 6 | https://ja.wikipedia.org/wiki/Intel_HEX |
suupen | 2:52002844d0c6 | 7 | |
suupen | 3:327bb0fcdf45 | 8 | start code |
suupen | 3:327bb0fcdf45 | 9 | | byte count |
suupen | 3:327bb0fcdf45 | 10 | | | address |
suupen | 3:327bb0fcdf45 | 11 | | | | recode type |
suupen | 3:327bb0fcdf45 | 12 | | | | | data checksum |
suupen | 3:327bb0fcdf45 | 13 | ↓ ↓ ↓ ↓ ↓ ↓ |
suupen | 3:327bb0fcdf45 | 14 | : 10 0000 00 9F07003D0F0000000000000000000000 FE ↓ data |
suupen | 3:327bb0fcdf45 | 15 | : 10 0010 00 00000000000000000000000000000000 E0 |
suupen | 3:327bb0fcdf45 | 16 | :100020000000000000000000000000E0FB000000F5 |
suupen | 3:327bb0fcdf45 | 17 | :10003000000000000000000000000000CFEFFC0006 |
suupen | 3:327bb0fcdf45 | 18 | :1000400000000000000000000000000000000000B0 |
suupen | 3:327bb0fcdf45 | 19 | :1000500000000000000000000000000000000000A0 |
suupen | 3:327bb0fcdf45 | 20 | :1000600000303000303030300000303030000000E0 |
suupen | 3:327bb0fcdf45 | 21 | :1000700030303030000000000000000000000000C0 |
suupen | 3:327bb0fcdf45 | 22 | :10008000FA00FA663B1422300C0000000000000069 |
suupen | 3:327bb0fcdf45 | 23 | :10009000000000000000000000000300000000005D |
suupen | 3:327bb0fcdf45 | 24 | :1000A0000000002000010000000201000002000129 |
suupen | 3:327bb0fcdf45 | 25 | :1000B0000000020100000200010000020100000235 |
suupen | 3:327bb0fcdf45 | 26 | :1000C000000100000200010000000101000000002A |
suupen | 3:327bb0fcdf45 | 27 | :1000D0000000000000000000000000000000000020 |
suupen | 3:327bb0fcdf45 | 28 | :1000E0000000000000000000000000000000000010 |
suupen | 3:327bb0fcdf45 | 29 | :1000F000000000000000000000000000000000A55B ↑ data |
suupen | 3:327bb0fcdf45 | 30 | :00000001FF ← end code |
suupen | 2:52002844d0c6 | 31 | |
suupen | 3:327bb0fcdf45 | 32 | 0x0000 ~ 0x00ff の256byteになる |
suupen | 2:52002844d0c6 | 33 | |
suupen | 0:7c6ad253848a | 34 | <使い方> |
suupen | 0:7c6ad253848a | 35 | |
suupen | 0:7c6ad253848a | 36 | |
suupen | 0:7c6ad253848a | 37 | <USB-Serialの通信設定値> |
suupen | 3:327bb0fcdf45 | 38 | baudrate : PC_BOUDで変更可能(初期値=9600[bps] |
suupen | 0:7c6ad253848a | 39 | bits : 8bit |
suupen | 0:7c6ad253848a | 40 | parity : none |
suupen | 0:7c6ad253848a | 41 | stopbit : 1bit |
suupen | 0:7c6ad253848a | 42 | |
suupen | 0:7c6ad253848a | 43 | |
suupen | 0:7c6ad253848a | 44 | */ |
suupen | 2:52002844d0c6 | 45 | |
suupen | 2:52002844d0c6 | 46 | //#define DEBUG |
suupen | 2:52002844d0c6 | 47 | |
suupen | 3:327bb0fcdf45 | 48 | #include "ctype.h" |
suupen | 0:7c6ad253848a | 49 | #include "mbed.h" |
suupen | 3:327bb0fcdf45 | 50 | #include <cstdint> |
suupen | 2:52002844d0c6 | 51 | #include <stdio.h> |
suupen | 2:52002844d0c6 | 52 | //#include <string.h> |
suupen | 2:52002844d0c6 | 53 | #include "BufferedSerial.h" |
suupen | 3:327bb0fcdf45 | 54 | //#include "mbed2/233/i2c_api.h" |
suupen | 3:327bb0fcdf45 | 55 | //#include "mbed2/233/I2C.h" |
suupen | 0:7c6ad253848a | 56 | |
suupen | 3:327bb0fcdf45 | 57 | // mbed内部のfilesystem |
suupen | 3:327bb0fcdf45 | 58 | LocalFileSystem local("local"); // local file systemの設定 |
suupen | 3:327bb0fcdf45 | 59 | #define Z_bufferNumber \ |
suupen | 3:327bb0fcdf45 | 60 | (100) // HEX fileは1行44byteなのでこれ以上のbyte数があればよい(file |
suupen | 3:327bb0fcdf45 | 61 | // systemは1行づつ読み込まれる) |
suupen | 3:327bb0fcdf45 | 62 | |
suupen | 3:327bb0fcdf45 | 63 | char buffer[Z_bufferNumber]; // 読みだしたデータの保管先 |
suupen | 0:7c6ad253848a | 64 | |
suupen | 3:327bb0fcdf45 | 65 | // PCからのコマンド入力用USB-Uart |
suupen | 3:327bb0fcdf45 | 66 | // 参考コードは DELICIA_BLE_CommDummy |
suupen | 2:52002844d0c6 | 67 | BufferedSerial pc(USBTX, USBRX); |
suupen | 3:327bb0fcdf45 | 68 | #define PC_BOUD (115200) |
suupen | 3:327bb0fcdf45 | 69 | #define Z_pcBuffer (100) // PCからのコマンド保管用 |
suupen | 3:327bb0fcdf45 | 70 | char B_pcRx[Z_pcBuffer] __attribute__(( |
suupen | 3:327bb0fcdf45 | 71 | section("AHBSRAM0"))); // RAMが足りないのでEthernet用エリアを使用 |
suupen | 3:327bb0fcdf45 | 72 | // (0x2007c000) (コピー元をそのまま転記した) |
suupen | 3:327bb0fcdf45 | 73 | |
suupen | 1:c6e8a41200d9 | 74 | Timeout txSend; // 送信間隔作成用 |
suupen | 0:7c6ad253848a | 75 | |
suupen | 3:327bb0fcdf45 | 76 | // mbedボード上の動作モニタLED |
suupen | 3:327bb0fcdf45 | 77 | DigitalOut ledopen(LED1); // 1:file open 0:file close |
suupen | 3:327bb0fcdf45 | 78 | DigitalOut ledout(LED2); // 1: serial out |
suupen | 3:327bb0fcdf45 | 79 | // DigitalOut lederror(LED4); |
suupen | 3:327bb0fcdf45 | 80 | |
suupen | 3:327bb0fcdf45 | 81 | //*************************************************************************** |
suupen | 3:327bb0fcdf45 | 82 | // 新規のコマンド受信用 |
suupen | 3:327bb0fcdf45 | 83 | //*************************************************************************** |
suupen | 3:327bb0fcdf45 | 84 | //============================================================================= |
suupen | 3:327bb0fcdf45 | 85 | // PC 側処理 (command & data 送受信) |
suupen | 3:327bb0fcdf45 | 86 | // main()から呼び出す。戻り値が"1"ならコマンド解析する。 |
suupen | 3:327bb0fcdf45 | 87 | //============================================================================= |
suupen | 3:327bb0fcdf45 | 88 | /** |
suupen | 3:327bb0fcdf45 | 89 | * pc rx data |
suupen | 3:327bb0fcdf45 | 90 | * @@para ans 0:受信中 1:受信完了 |
suupen | 3:327bb0fcdf45 | 91 | */ |
suupen | 3:327bb0fcdf45 | 92 | int pcRecive(void) { |
suupen | 3:327bb0fcdf45 | 93 | static char *p = B_pcRx; |
suupen | 3:327bb0fcdf45 | 94 | char data; |
suupen | 3:327bb0fcdf45 | 95 | int ans = 0; |
suupen | 3:327bb0fcdf45 | 96 | #define Z_00 (0x00) |
suupen | 3:327bb0fcdf45 | 97 | #define Z_CR (0x0d) |
suupen | 3:327bb0fcdf45 | 98 | |
suupen | 3:327bb0fcdf45 | 99 | // buffer オーバーフロー対策 |
suupen | 3:327bb0fcdf45 | 100 | if ((p - B_pcRx) >= Z_pcBuffer) { |
suupen | 3:327bb0fcdf45 | 101 | p = B_pcRx; |
suupen | 3:327bb0fcdf45 | 102 | *p = Z_00; |
suupen | 3:327bb0fcdf45 | 103 | } |
suupen | 0:7c6ad253848a | 104 | |
suupen | 3:327bb0fcdf45 | 105 | // 1文字受信処理 |
suupen | 3:327bb0fcdf45 | 106 | while ((pc.readable() == 1) && ans == 0) { |
suupen | 3:327bb0fcdf45 | 107 | // 受信データあり |
suupen | 3:327bb0fcdf45 | 108 | data = pc.getc(); |
suupen | 3:327bb0fcdf45 | 109 | |
suupen | 3:327bb0fcdf45 | 110 | switch (data) { |
suupen | 3:327bb0fcdf45 | 111 | case Z_CR: |
suupen | 3:327bb0fcdf45 | 112 | *p = Z_00; |
suupen | 3:327bb0fcdf45 | 113 | p = B_pcRx; |
suupen | 3:327bb0fcdf45 | 114 | ans = 1; |
suupen | 3:327bb0fcdf45 | 115 | break; |
suupen | 3:327bb0fcdf45 | 116 | case ' ': |
suupen | 3:327bb0fcdf45 | 117 | case ',': |
suupen | 2:52002844d0c6 | 118 | |
suupen | 3:327bb0fcdf45 | 119 | // nothing |
suupen | 3:327bb0fcdf45 | 120 | break; |
suupen | 3:327bb0fcdf45 | 121 | default: |
suupen | 3:327bb0fcdf45 | 122 | // 小文字のアルファベットを大文字に差し替える |
suupen | 3:327bb0fcdf45 | 123 | if (('a' <= data) && (data <= 'z')) { |
suupen | 3:327bb0fcdf45 | 124 | data -= ('a' - 'A'); |
suupen | 3:327bb0fcdf45 | 125 | } |
suupen | 3:327bb0fcdf45 | 126 | *p++ = data; |
suupen | 3:327bb0fcdf45 | 127 | *p = Z_00; |
suupen | 3:327bb0fcdf45 | 128 | break; |
suupen | 3:327bb0fcdf45 | 129 | } |
suupen | 3:327bb0fcdf45 | 130 | } |
suupen | 3:327bb0fcdf45 | 131 | return (ans); |
suupen | 3:327bb0fcdf45 | 132 | } |
suupen | 3:327bb0fcdf45 | 133 | |
suupen | 3:327bb0fcdf45 | 134 | //*************************************************************************** |
suupen | 3:327bb0fcdf45 | 135 | // ベースのPC送信割り込み |
suupen | 3:327bb0fcdf45 | 136 | //*************************************************************************** |
suupen | 2:52002844d0c6 | 137 | int D_start_wait_us = 100; // 送信開始時の待ち時間 (1/1 [us]/bit) min = 100[us] |
suupen | 3:327bb0fcdf45 | 138 | int D_char_wait_us = |
suupen | 3:327bb0fcdf45 | 139 | 100; // キャラクタ間の送信間隔 ( 1/1 [ms]/bit) min = 100[us] |
suupen | 0:7c6ad253848a | 140 | |
suupen | 1:c6e8a41200d9 | 141 | // 送信処理状態遷移 |
suupen | 3:327bb0fcdf45 | 142 | typedef enum { Z_txIdle, Z_txStart, Z_txSend } txSend_t; |
suupen | 1:c6e8a41200d9 | 143 | txSend_t M_txSend = Z_txIdle; // 0:受信完了(STX送信待ち) 1:STX以降CRまでの送信中 |
suupen | 1:c6e8a41200d9 | 144 | |
suupen | 1:c6e8a41200d9 | 145 | /** |
suupen | 1:c6e8a41200d9 | 146 | * 割り込み処理 |
suupen | 1:c6e8a41200d9 | 147 | * 送信データ送信処理 |
suupen | 1:c6e8a41200d9 | 148 | * 受信完了から送信開始の20[ms]の遅延 |
suupen | 1:c6e8a41200d9 | 149 | * 送信データ1byte毎に2[ms]の遅延 |
suupen | 1:c6e8a41200d9 | 150 | * を入れて送信する |
suupen | 1:c6e8a41200d9 | 151 | */ |
suupen | 3:327bb0fcdf45 | 152 | void txDataSend(void) { |
suupen | 3:327bb0fcdf45 | 153 | static char *p; |
suupen | 1:c6e8a41200d9 | 154 | |
suupen | 3:327bb0fcdf45 | 155 | switch (M_txSend) { |
suupen | 1:c6e8a41200d9 | 156 | |
suupen | 3:327bb0fcdf45 | 157 | case Z_txStart: |
suupen | 3:327bb0fcdf45 | 158 | // STX ~ CR 送信 |
suupen | 3:327bb0fcdf45 | 159 | p = buffer; |
suupen | 3:327bb0fcdf45 | 160 | M_txSend = Z_txSend; |
suupen | 3:327bb0fcdf45 | 161 | // brak; |
suupen | 3:327bb0fcdf45 | 162 | case Z_txSend: |
suupen | 3:327bb0fcdf45 | 163 | if (*p != 0x00) { |
suupen | 3:327bb0fcdf45 | 164 | pc.putc(*p++); |
suupen | 3:327bb0fcdf45 | 165 | wait(0.01); |
suupen | 3:327bb0fcdf45 | 166 | txSend.attach_us( |
suupen | 3:327bb0fcdf45 | 167 | &txDataSend, |
suupen | 3:327bb0fcdf45 | 168 | D_char_wait_us); // 次回送信開始まで2[us]セット(時間は可変設定にする) |
suupen | 1:c6e8a41200d9 | 169 | } |
suupen | 1:c6e8a41200d9 | 170 | |
suupen | 3:327bb0fcdf45 | 171 | else { |
suupen | 3:327bb0fcdf45 | 172 | // 送信完了 |
suupen | 3:327bb0fcdf45 | 173 | M_txSend = Z_txIdle; |
suupen | 3:327bb0fcdf45 | 174 | txSend.detach(); |
suupen | 3:327bb0fcdf45 | 175 | } |
suupen | 3:327bb0fcdf45 | 176 | break; |
suupen | 3:327bb0fcdf45 | 177 | case Z_txIdle: // defaultと同じ処理 |
suupen | 3:327bb0fcdf45 | 178 | default: |
suupen | 3:327bb0fcdf45 | 179 | // nothing |
suupen | 3:327bb0fcdf45 | 180 | break; |
suupen | 3:327bb0fcdf45 | 181 | } |
suupen | 1:c6e8a41200d9 | 182 | } |
suupen | 1:c6e8a41200d9 | 183 | |
suupen | 1:c6e8a41200d9 | 184 | /** |
suupen | 1:c6e8a41200d9 | 185 | * main処理 |
suupen | 1:c6e8a41200d9 | 186 | * 受信終了から送信開始までの20[ms]遅延設定 |
suupen | 1:c6e8a41200d9 | 187 | * |
suupen | 1:c6e8a41200d9 | 188 | */ |
suupen | 3:327bb0fcdf45 | 189 | void txDataWait(void) { |
suupen | 3:327bb0fcdf45 | 190 | txSend.attach_us(&txDataSend, D_start_wait_us); // 受信完了からx[ms]経過待ち |
suupen | 3:327bb0fcdf45 | 191 | M_txSend = Z_txStart; |
suupen | 1:c6e8a41200d9 | 192 | } |
suupen | 1:c6e8a41200d9 | 193 | |
suupen | 1:c6e8a41200d9 | 194 | /** |
suupen | 1:c6e8a41200d9 | 195 | * 送信終了判定 |
suupen | 1:c6e8a41200d9 | 196 | * @@para int 戻り値 送信処理状況 1:送信完了 0:送信中 |
suupen | 1:c6e8a41200d9 | 197 | */ |
suupen | 3:327bb0fcdf45 | 198 | int txSendEndCheck(void) { |
suupen | 3:327bb0fcdf45 | 199 | int ans; |
suupen | 3:327bb0fcdf45 | 200 | if (M_txSend == Z_txIdle) { |
suupen | 3:327bb0fcdf45 | 201 | ans = 1; |
suupen | 3:327bb0fcdf45 | 202 | } else { |
suupen | 3:327bb0fcdf45 | 203 | ans = 0; |
suupen | 3:327bb0fcdf45 | 204 | } |
suupen | 3:327bb0fcdf45 | 205 | |
suupen | 3:327bb0fcdf45 | 206 | return (ans); |
suupen | 3:327bb0fcdf45 | 207 | } |
suupen | 3:327bb0fcdf45 | 208 | |
suupen | 3:327bb0fcdf45 | 209 | /** asciiコード1文字をhexに変換 |
suupen | 3:327bb0fcdf45 | 210 | * 引数: char* p : 文字の入った変数のポインタ |
suupen | 3:327bb0fcdf45 | 211 | * 戻り値: 0 ~ 0x0f, 0xff:変換不能 |
suupen | 3:327bb0fcdf45 | 212 | */ |
suupen | 3:327bb0fcdf45 | 213 | uint8_t atoh1(char *p) { |
suupen | 3:327bb0fcdf45 | 214 | char a = *p; |
suupen | 3:327bb0fcdf45 | 215 | uint8_t ans = 0xff; |
suupen | 3:327bb0fcdf45 | 216 | |
suupen | 3:327bb0fcdf45 | 217 | if (('0' <= a) && (a <= '9')) { |
suupen | 3:327bb0fcdf45 | 218 | ans = a - '0'; |
suupen | 3:327bb0fcdf45 | 219 | } else if (('a' <= a) && (a <= 'f')) { |
suupen | 3:327bb0fcdf45 | 220 | ans = a - 'a' + 0x0a; |
suupen | 3:327bb0fcdf45 | 221 | } else if (('A' <= a) && (a <= 'F')) { |
suupen | 3:327bb0fcdf45 | 222 | ans = a - 'A' + 0x0a; |
suupen | 3:327bb0fcdf45 | 223 | } else { |
suupen | 3:327bb0fcdf45 | 224 | ans = 0xff; |
suupen | 3:327bb0fcdf45 | 225 | } |
suupen | 3:327bb0fcdf45 | 226 | return (ans); |
suupen | 3:327bb0fcdf45 | 227 | } |
suupen | 3:327bb0fcdf45 | 228 | |
suupen | 3:327bb0fcdf45 | 229 | /** asciiコード2文字をhexに変換 |
suupen | 3:327bb0fcdf45 | 230 | * 引数: char* p: 文字の入った変数ポインタ |
suupen | 3:327bb0fcdf45 | 231 | * 戻り値: 0x00 ~ 0xff (変換不能の場合は0xffにしている) |
suupen | 3:327bb0fcdf45 | 232 | */ |
suupen | 3:327bb0fcdf45 | 233 | uint8_t atoh2(char *p) { |
suupen | 3:327bb0fcdf45 | 234 | uint8_t ans; |
suupen | 3:327bb0fcdf45 | 235 | uint8_t up = atoh1(p); |
suupen | 3:327bb0fcdf45 | 236 | uint8_t dn = atoh1(p + 1); |
suupen | 3:327bb0fcdf45 | 237 | if ((up != 0xff) && (dn != 0xff)) { |
suupen | 3:327bb0fcdf45 | 238 | ans = (up << 4) | dn; |
suupen | 3:327bb0fcdf45 | 239 | } else { |
suupen | 3:327bb0fcdf45 | 240 | // 変換不能 |
suupen | 3:327bb0fcdf45 | 241 | ans = 0xff; |
suupen | 3:327bb0fcdf45 | 242 | } |
suupen | 3:327bb0fcdf45 | 243 | return (ans); |
suupen | 3:327bb0fcdf45 | 244 | } |
suupen | 3:327bb0fcdf45 | 245 | |
suupen | 3:327bb0fcdf45 | 246 | uint8_t byteCount; |
suupen | 3:327bb0fcdf45 | 247 | uint8_t address; // 上位8bitは必ず0x00になるので省略 |
suupen | 3:327bb0fcdf45 | 248 | uint8_t recodeType; |
suupen | 3:327bb0fcdf45 | 249 | uint8_t NVMData[16][16]; // NVM書き込み用データバッファ |
suupen | 3:327bb0fcdf45 | 250 | uint8_t EEPROMData[16][16]; // EEPROM用書き込みデータバッファ |
suupen | 3:327bb0fcdf45 | 251 | |
suupen | 3:327bb0fcdf45 | 252 | uint8_t NVMFile = 0; // NVMファイルの読み込み結果 0:NG, 1:OK |
suupen | 3:327bb0fcdf45 | 253 | uint8_t EEPROMFile = 0; // EEPROMファイルの読み込み結果 0:NG, 1:OK |
suupen | 3:327bb0fcdf45 | 254 | |
suupen | 3:327bb0fcdf45 | 255 | /** NVM fileを読み出す |
suupen | 3:327bb0fcdf45 | 256 | * 対象ファイルは"NVM.hex"の決め打ち |
suupen | 3:327bb0fcdf45 | 257 | * 戻り値: 0:データなし n:読み込み桁数(正常なら16になる) |
suupen | 3:327bb0fcdf45 | 258 | */ |
suupen | 3:327bb0fcdf45 | 259 | uint8_t NVMFileRead(void) { |
suupen | 3:327bb0fcdf45 | 260 | uint8_t ans = 0; |
suupen | 3:327bb0fcdf45 | 261 | FILE *fp; |
suupen | 3:327bb0fcdf45 | 262 | char *p; |
suupen | 3:327bb0fcdf45 | 263 | |
suupen | 3:327bb0fcdf45 | 264 | pc.printf("NVM file read\n"); |
suupen | 3:327bb0fcdf45 | 265 | |
suupen | 3:327bb0fcdf45 | 266 | fp = fopen("/local/NVM.hex", "r"); |
suupen | 3:327bb0fcdf45 | 267 | |
suupen | 3:327bb0fcdf45 | 268 | while (fgets(buffer, Z_bufferNumber, fp) != NULL) { |
suupen | 3:327bb0fcdf45 | 269 | p = buffer; |
suupen | 3:327bb0fcdf45 | 270 | |
suupen | 3:327bb0fcdf45 | 271 | while (*p != 0x00) { |
suupen | 3:327bb0fcdf45 | 272 | switch (*p++) { |
suupen | 3:327bb0fcdf45 | 273 | case ':': |
suupen | 3:327bb0fcdf45 | 274 | byteCount = atoh2(p); |
suupen | 3:327bb0fcdf45 | 275 | p += 2; |
suupen | 3:327bb0fcdf45 | 276 | p += 2; |
suupen | 3:327bb0fcdf45 | 277 | address = atoh2(p) >> 4; // 2byte addressの下位1byteを取得 |
suupen | 3:327bb0fcdf45 | 278 | p += 2; |
suupen | 3:327bb0fcdf45 | 279 | recodeType = atoh2(p); |
suupen | 3:327bb0fcdf45 | 280 | p += 2; |
suupen | 3:327bb0fcdf45 | 281 | |
suupen | 3:327bb0fcdf45 | 282 | pc.printf("byte=%02x address=%02x type=%02x : ", byteCount, address, |
suupen | 3:327bb0fcdf45 | 283 | recodeType); |
suupen | 3:327bb0fcdf45 | 284 | wait(.1); |
suupen | 3:327bb0fcdf45 | 285 | if (byteCount != 0x10) { |
suupen | 3:327bb0fcdf45 | 286 | pc.printf("end of data\n"); |
suupen | 3:327bb0fcdf45 | 287 | break; |
suupen | 3:327bb0fcdf45 | 288 | } |
suupen | 3:327bb0fcdf45 | 289 | |
suupen | 3:327bb0fcdf45 | 290 | ans++; |
suupen | 3:327bb0fcdf45 | 291 | for (uint8_t i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 292 | NVMData[address][i] = atoh2(p); |
suupen | 3:327bb0fcdf45 | 293 | p += 2; |
suupen | 3:327bb0fcdf45 | 294 | pc.printf("%02x", NVMData[address][i]); |
suupen | 3:327bb0fcdf45 | 295 | } |
suupen | 3:327bb0fcdf45 | 296 | pc.printf("\n"); |
suupen | 3:327bb0fcdf45 | 297 | } |
suupen | 1:c6e8a41200d9 | 298 | } |
suupen | 3:327bb0fcdf45 | 299 | } |
suupen | 3:327bb0fcdf45 | 300 | fclose(fp); |
suupen | 1:c6e8a41200d9 | 301 | |
suupen | 3:327bb0fcdf45 | 302 | return (ans); |
suupen | 3:327bb0fcdf45 | 303 | } |
suupen | 3:327bb0fcdf45 | 304 | |
suupen | 3:327bb0fcdf45 | 305 | //***************************************************************************** |
suupen | 3:327bb0fcdf45 | 306 | // GreenPak のI2C処理 |
suupen | 3:327bb0fcdf45 | 307 | //***************************************************************************** |
suupen | 3:327bb0fcdf45 | 308 | I2C Wire(p9, p10); // sda, sci |
suupen | 3:327bb0fcdf45 | 309 | |
suupen | 3:327bb0fcdf45 | 310 | //@ss+ Block Address (Control Byte A10-8) |
suupen | 3:327bb0fcdf45 | 311 | // A10 |
suupen | 3:327bb0fcdf45 | 312 | // |A9 |
suupen | 3:327bb0fcdf45 | 313 | // ||A8 |
suupen | 3:327bb0fcdf45 | 314 | // xxxx 098xb |
suupen | 3:327bb0fcdf45 | 315 | // xxxx 001xb :resster |
suupen | 3:327bb0fcdf45 | 316 | // xxxx 010xb :NVM |
suupen | 3:327bb0fcdf45 | 317 | // xxxx 110xb :EEPROM |
suupen | 3:327bb0fcdf45 | 318 | #define RESISTER_CONFIG 0x02 // 0x01 << 1 //@ss+ |
suupen | 3:327bb0fcdf45 | 319 | #define NVM_CONFIG 0x04 // 0x02 << 1 |
suupen | 3:327bb0fcdf45 | 320 | #define EEPROM_CONFIG 0x06 // 0x03 << 1 |
suupen | 3:327bb0fcdf45 | 321 | |
suupen | 3:327bb0fcdf45 | 322 | #define MASK_CONTROLCODE \ |
suupen | 3:327bb0fcdf45 | 323 | (0xf0) // I2Cアドレス部の ControlCode(上位4bit)を残すためのマスク |
suupen | 3:327bb0fcdf45 | 324 | |
suupen | 3:327bb0fcdf45 | 325 | int count = 0; |
suupen | 3:327bb0fcdf45 | 326 | uint8_t slave_address = 0x00; |
suupen | 3:327bb0fcdf45 | 327 | bool device_present[16] = {false}; |
suupen | 3:327bb0fcdf45 | 328 | uint8_t data_array[16][16] = {}; |
suupen | 3:327bb0fcdf45 | 329 | |
suupen | 3:327bb0fcdf45 | 330 | typedef enum { NVM, EEPROM, RESISTER } greenPakMemory_t; |
suupen | 3:327bb0fcdf45 | 331 | greenPakMemory_t NVMorEEPROM = NVM; // 読み書き対象 |
suupen | 3:327bb0fcdf45 | 332 | |
suupen | 3:327bb0fcdf45 | 333 | char i2cBuffer[10]; // I2C送受信用バッファ |
suupen | 3:327bb0fcdf45 | 334 | |
suupen | 3:327bb0fcdf45 | 335 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 336 | // power cycle |
suupen | 3:327bb0fcdf45 | 337 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 338 | void powercycle(int code) { |
suupen | 3:327bb0fcdf45 | 339 | pc.printf("Power Cycling!\n"); |
suupen | 3:327bb0fcdf45 | 340 | // Software reset |
suupen | 3:327bb0fcdf45 | 341 | // レジスタアドレス=0xc8 bit1を1にすると I2C resetをしてNVMのデータをレジスタに転送することができる |
suupen | 3:327bb0fcdf45 | 342 | i2cBuffer[0] = 0xC8; |
suupen | 3:327bb0fcdf45 | 343 | i2cBuffer[1] = 0x02; |
suupen | 3:327bb0fcdf45 | 344 | Wire.write(code & MASK_CONTROLCODE, i2cBuffer, |
suupen | 3:327bb0fcdf45 | 345 | 2); //@ss MASK_CONTROLCODEは Control Code:slave |
suupen | 3:327bb0fcdf45 | 346 | // addressを残しresisterアクセスにするためのマスク |
suupen | 3:327bb0fcdf45 | 347 | // pc.printf("Done Power Cycling!\n"); |
suupen | 3:327bb0fcdf45 | 348 | } |
suupen | 3:327bb0fcdf45 | 349 | |
suupen | 3:327bb0fcdf45 | 350 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 351 | // ack polling |
suupen | 3:327bb0fcdf45 | 352 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 353 | int ackPolling(int addressForAckPolling) { |
suupen | 3:327bb0fcdf45 | 354 | int ans; |
suupen | 3:327bb0fcdf45 | 355 | int nack_count = 0; |
suupen | 3:327bb0fcdf45 | 356 | while (1) { |
suupen | 3:327bb0fcdf45 | 357 | |
suupen | 3:327bb0fcdf45 | 358 | ans = Wire.read(addressForAckPolling, i2cBuffer, 0); |
suupen | 3:327bb0fcdf45 | 359 | if (ans == 0) { |
suupen | 3:327bb0fcdf45 | 360 | return 0; |
suupen | 3:327bb0fcdf45 | 361 | } |
suupen | 3:327bb0fcdf45 | 362 | if (nack_count >= 1000) { |
suupen | 3:327bb0fcdf45 | 363 | pc.printf("Geez! Something went wrong while programming!\n"); |
suupen | 3:327bb0fcdf45 | 364 | return -1; |
suupen | 3:327bb0fcdf45 | 365 | } |
suupen | 3:327bb0fcdf45 | 366 | nack_count++; |
suupen | 3:327bb0fcdf45 | 367 | wait(1); |
suupen | 3:327bb0fcdf45 | 368 | } |
suupen | 1:c6e8a41200d9 | 369 | } |
suupen | 1:c6e8a41200d9 | 370 | |
suupen | 3:327bb0fcdf45 | 371 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 372 | // ping |
suupen | 3:327bb0fcdf45 | 373 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 374 | void ping(void) { |
suupen | 3:327bb0fcdf45 | 375 | int ans; |
suupen | 1:c6e8a41200d9 | 376 | |
suupen | 3:327bb0fcdf45 | 377 | for (int i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 378 | ans = Wire.read(i << 4, i2cBuffer, 0); // ICに影響を与えないようにreadコマンドで確認する |
suupen | 1:c6e8a41200d9 | 379 | |
suupen | 3:327bb0fcdf45 | 380 | if (ans == 0) { |
suupen | 3:327bb0fcdf45 | 381 | pc.printf("device 0x%02x", i); |
suupen | 3:327bb0fcdf45 | 382 | pc.printf(" is present\n"); |
suupen | 3:327bb0fcdf45 | 383 | device_present[i] = true; |
suupen | 3:327bb0fcdf45 | 384 | } else { |
suupen | 3:327bb0fcdf45 | 385 | pc.printf("device 0x%02x", i); |
suupen | 3:327bb0fcdf45 | 386 | pc.printf(" is not present\n"); |
suupen | 3:327bb0fcdf45 | 387 | device_present[i] = false; |
suupen | 3:327bb0fcdf45 | 388 | } |
suupen | 3:327bb0fcdf45 | 389 | } |
suupen | 3:327bb0fcdf45 | 390 | wait(0.1); |
suupen | 3:327bb0fcdf45 | 391 | } |
suupen | 0:7c6ad253848a | 392 | |
suupen | 3:327bb0fcdf45 | 393 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 394 | // resister un protect |
suupen | 3:327bb0fcdf45 | 395 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 396 | void resister_unprotect(uint8_t control_code) //@ss+ |
suupen | 0:7c6ad253848a | 397 | { |
suupen | 3:327bb0fcdf45 | 398 | // resisiterのプロテクトをクリアする |
suupen | 3:327bb0fcdf45 | 399 | // レジスタアドレス: 0xE1 にNVMのプロテクト領域がある (HM p.171) |
suupen | 3:327bb0fcdf45 | 400 | // 下位2bit 00: read/write/erase 可能 |
suupen | 3:327bb0fcdf45 | 401 | // 01: read禁止 |
suupen | 3:327bb0fcdf45 | 402 | // 10: write/erase 禁止 |
suupen | 3:327bb0fcdf45 | 403 | // 11: read/write/erase 禁止 |
suupen | 3:327bb0fcdf45 | 404 | i2cBuffer[0] = 0xE1; |
suupen | 3:327bb0fcdf45 | 405 | i2cBuffer[1] = 0x00; |
suupen | 3:327bb0fcdf45 | 406 | Wire.write(control_code & MASK_CONTROLCODE, i2cBuffer, |
suupen | 3:327bb0fcdf45 | 407 | 2); //@ss MASK_CONTROLCODEは Control Code:slave |
suupen | 3:327bb0fcdf45 | 408 | // addressを残しresisterアクセスにするためのマスク |
suupen | 3:327bb0fcdf45 | 409 | |
suupen | 3:327bb0fcdf45 | 410 | i2cBuffer[0] = 0xE1; |
suupen | 3:327bb0fcdf45 | 411 | Wire.write(control_code & MASK_CONTROLCODE, i2cBuffer, 1); |
suupen | 3:327bb0fcdf45 | 412 | |
suupen | 3:327bb0fcdf45 | 413 | Wire.read(control_code & MASK_CONTROLCODE, i2cBuffer, 1); |
suupen | 3:327bb0fcdf45 | 414 | uint8_t val = i2cBuffer[0]; |
suupen | 3:327bb0fcdf45 | 415 | pc.printf("0xE1 = %02x\n", val); // 0x00ならプロテクト解除されている |
suupen | 3:327bb0fcdf45 | 416 | } |
suupen | 3:327bb0fcdf45 | 417 | |
suupen | 3:327bb0fcdf45 | 418 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 419 | // writeChip |
suupen | 3:327bb0fcdf45 | 420 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 421 | #if 0 |
suupen | 3:327bb0fcdf45 | 422 | // NVM書き込み試験用 |
suupen | 3:327bb0fcdf45 | 423 | int writeChip(greenPakMemory_t NVMorEEPROM) { |
suupen | 3:327bb0fcdf45 | 424 | i2cBuffer[0] = 0x00; |
suupen | 3:327bb0fcdf45 | 425 | i2cBuffer[1] = 0x01; |
suupen | 3:327bb0fcdf45 | 426 | i2cBuffer[2] = 0x02; |
suupen | 3:327bb0fcdf45 | 427 | i2cBuffer[3] = 0x03; |
suupen | 3:327bb0fcdf45 | 428 | i2cBuffer[4] = 0x04; |
suupen | 3:327bb0fcdf45 | 429 | i2cBuffer[5] = 0x05; |
suupen | 3:327bb0fcdf45 | 430 | i2cBuffer[6] = 0x06; |
suupen | 3:327bb0fcdf45 | 431 | i2cBuffer[7] = 0x07; |
suupen | 3:327bb0fcdf45 | 432 | i2cBuffer[8] = 0x08; |
suupen | 3:327bb0fcdf45 | 433 | i2cBuffer[9] = 0x09; |
suupen | 3:327bb0fcdf45 | 434 | i2cBuffer[10] = 0x0a; |
suupen | 3:327bb0fcdf45 | 435 | i2cBuffer[11] = 0x0b; |
suupen | 3:327bb0fcdf45 | 436 | i2cBuffer[12] = 0x0c; |
suupen | 3:327bb0fcdf45 | 437 | i2cBuffer[13] = 0x0d; |
suupen | 3:327bb0fcdf45 | 438 | i2cBuffer[14] = 0x0e; |
suupen | 3:327bb0fcdf45 | 439 | i2cBuffer[15] = 0x0f; |
suupen | 3:327bb0fcdf45 | 440 | i2cBuffer[16] = 0x10; |
suupen | 3:327bb0fcdf45 | 441 | Wire.write(0x04, i2cBuffer, 17); |
suupen | 3:327bb0fcdf45 | 442 | |
suupen | 3:327bb0fcdf45 | 443 | } |
suupen | 3:327bb0fcdf45 | 444 | #endif |
suupen | 3:327bb0fcdf45 | 445 | #if 1 |
suupen | 3:327bb0fcdf45 | 446 | int writeChip(greenPakMemory_t NVMorEEPROM) { |
suupen | 3:327bb0fcdf45 | 447 | int control_code = 0x00; |
suupen | 3:327bb0fcdf45 | 448 | int addressForAckPolling = 0x00; |
suupen | 3:327bb0fcdf45 | 449 | bool RESISTER_selected = false; |
suupen | 3:327bb0fcdf45 | 450 | bool NVM_selected = false; |
suupen | 3:327bb0fcdf45 | 451 | bool EEPROM_selected = false; |
suupen | 3:327bb0fcdf45 | 452 | |
suupen | 3:327bb0fcdf45 | 453 | int ans; |
suupen | 3:327bb0fcdf45 | 454 | |
suupen | 3:327bb0fcdf45 | 455 | if (NVMorEEPROM == NVM) { |
suupen | 3:327bb0fcdf45 | 456 | |
suupen | 3:327bb0fcdf45 | 457 | control_code = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 458 | resister_unprotect(uint8_t(control_code)); //@ss+ |
suupen | 0:7c6ad253848a | 459 | |
suupen | 3:327bb0fcdf45 | 460 | // Serial.println(F("Writing NVM")); |
suupen | 3:327bb0fcdf45 | 461 | // Set the slave address to 0x00 since the chip has just been erased |
suupen | 3:327bb0fcdf45 | 462 | slave_address = 0x00; |
suupen | 3:327bb0fcdf45 | 463 | // Set the control code to 0x00 since the chip has just been erased |
suupen | 3:327bb0fcdf45 | 464 | control_code = 0x00; |
suupen | 3:327bb0fcdf45 | 465 | control_code |= NVM_CONFIG; |
suupen | 3:327bb0fcdf45 | 466 | NVM_selected = true; |
suupen | 3:327bb0fcdf45 | 467 | addressForAckPolling = 0x00; |
suupen | 3:327bb0fcdf45 | 468 | } else if (NVMorEEPROM == EEPROM) { |
suupen | 3:327bb0fcdf45 | 469 | // pc.printf("Writing EEPROM\n"); |
suupen | 3:327bb0fcdf45 | 470 | control_code = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 471 | control_code |= EEPROM_CONFIG; |
suupen | 3:327bb0fcdf45 | 472 | EEPROM_selected = true; |
suupen | 3:327bb0fcdf45 | 473 | addressForAckPolling = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 474 | } else if (NVMorEEPROM == RESISTER) //@ss+↓ |
suupen | 3:327bb0fcdf45 | 475 | { |
suupen | 3:327bb0fcdf45 | 476 | // Serial.println(F("Writing RESISTER")); |
suupen | 3:327bb0fcdf45 | 477 | control_code = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 478 | control_code |= RESISTER_CONFIG; |
suupen | 3:327bb0fcdf45 | 479 | RESISTER_selected = true; |
suupen | 3:327bb0fcdf45 | 480 | addressForAckPolling = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 481 | } //@ss+↑ |
suupen | 3:327bb0fcdf45 | 482 | |
suupen | 3:327bb0fcdf45 | 483 | pc.printf("Control Code: 0x%02x\n", control_code); |
suupen | 3:327bb0fcdf45 | 484 | |
suupen | 3:327bb0fcdf45 | 485 | // Assign each byte to data_array[][] array; |
suupen | 3:327bb0fcdf45 | 486 | // http://www.gammon.com.au/progmem |
suupen | 3:327bb0fcdf45 | 487 | |
suupen | 3:327bb0fcdf45 | 488 | // pc.printf("New NVM or EEPROM data:"); |
suupen | 3:327bb0fcdf45 | 489 | if (NVM_selected) { |
suupen | 3:327bb0fcdf45 | 490 | for (int i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 491 | for (int j = 0; j < 16; j++) { |
suupen | 3:327bb0fcdf45 | 492 | data_array[i][j] = NVMData[i][j]; |
suupen | 3:327bb0fcdf45 | 493 | } |
suupen | 3:327bb0fcdf45 | 494 | } |
suupen | 3:327bb0fcdf45 | 495 | } else if (EEPROM_selected) { |
suupen | 3:327bb0fcdf45 | 496 | for (int i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 497 | for (int j = 0; j < 16; j++) { |
suupen | 3:327bb0fcdf45 | 498 | data_array[i][j] = EEPROMData[i][j]; |
suupen | 3:327bb0fcdf45 | 499 | } |
suupen | 3:327bb0fcdf45 | 500 | } |
suupen | 3:327bb0fcdf45 | 501 | } |
suupen | 3:327bb0fcdf45 | 502 | |
suupen | 3:327bb0fcdf45 | 503 | if (NVM_selected || RESISTER_selected) { |
suupen | 3:327bb0fcdf45 | 504 | // slave_addressに設定されている値に差し替える |
suupen | 3:327bb0fcdf45 | 505 | // レジスタアドレス=0xcaのbit3-0 にI2C slave address を設定する |
suupen | 3:327bb0fcdf45 | 506 | // bit7-4: 0にすると下位4bitのアドレスが有効になる(1にするとIO2,3,4,5の端子状態がアドレスになる) |
suupen | 3:327bb0fcdf45 | 507 | data_array[0xC][0xA] = (data_array[0xC][0xA] & 0xF0) | slave_address; |
suupen | 3:327bb0fcdf45 | 508 | } |
suupen | 3:327bb0fcdf45 | 509 | |
suupen | 3:327bb0fcdf45 | 510 | // Write each byte of data_array[][] array to the chip |
suupen | 3:327bb0fcdf45 | 511 | for (int i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 512 | i2cBuffer[0] = i << 4; |
suupen | 3:327bb0fcdf45 | 513 | pc.printf("%02x: ", i); |
suupen | 3:327bb0fcdf45 | 514 | |
suupen | 3:327bb0fcdf45 | 515 | for (int j = 0; j < 16; j++) { |
suupen | 3:327bb0fcdf45 | 516 | i2cBuffer[j+1] = data_array[i][j]; |
suupen | 3:327bb0fcdf45 | 517 | pc.printf("%02x ", data_array[i][j]); |
suupen | 3:327bb0fcdf45 | 518 | } |
suupen | 3:327bb0fcdf45 | 519 | ans = Wire.write(control_code, i2cBuffer, 17); |
suupen | 3:327bb0fcdf45 | 520 | wait(0.01); |
suupen | 3:327bb0fcdf45 | 521 | |
suupen | 3:327bb0fcdf45 | 522 | if (ans != 0) { |
suupen | 3:327bb0fcdf45 | 523 | pc.printf(" nack\n"); |
suupen | 3:327bb0fcdf45 | 524 | pc.printf("Oh No! Something went wrong while programming!\n"); |
suupen | 3:327bb0fcdf45 | 525 | Wire.stop(); |
suupen | 3:327bb0fcdf45 | 526 | return -1; |
suupen | 3:327bb0fcdf45 | 527 | } |
suupen | 3:327bb0fcdf45 | 528 | |
suupen | 3:327bb0fcdf45 | 529 | pc.printf(" ack "); |
suupen | 3:327bb0fcdf45 | 530 | |
suupen | 3:327bb0fcdf45 | 531 | |
suupen | 3:327bb0fcdf45 | 532 | if (ackPolling(addressForAckPolling) == -1) { |
suupen | 3:327bb0fcdf45 | 533 | return -1; |
suupen | 3:327bb0fcdf45 | 534 | } else { |
suupen | 3:327bb0fcdf45 | 535 | pc.printf("ready\n"); |
suupen | 3:327bb0fcdf45 | 536 | wait(0.1); |
suupen | 3:327bb0fcdf45 | 537 | } |
suupen | 3:327bb0fcdf45 | 538 | } |
suupen | 3:327bb0fcdf45 | 539 | |
suupen | 3:327bb0fcdf45 | 540 | Wire.stop(); |
suupen | 3:327bb0fcdf45 | 541 | |
suupen | 3:327bb0fcdf45 | 542 | if (RESISTER_selected == false) { //@ss+ |
suupen | 3:327bb0fcdf45 | 543 | powercycle(control_code); |
suupen | 3:327bb0fcdf45 | 544 | } //@ss+ |
suupen | 3:327bb0fcdf45 | 545 | return 0; |
suupen | 3:327bb0fcdf45 | 546 | } |
suupen | 3:327bb0fcdf45 | 547 | #endif |
suupen | 3:327bb0fcdf45 | 548 | |
suupen | 3:327bb0fcdf45 | 549 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 550 | // eraseChip // 230105OK |
suupen | 3:327bb0fcdf45 | 551 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 552 | int eraseChip(greenPakMemory_t NVMorEEPROM) { |
suupen | 3:327bb0fcdf45 | 553 | int control_code = |
suupen | 3:327bb0fcdf45 | 554 | (slave_address << 4) | |
suupen | 3:327bb0fcdf45 | 555 | RESISTER_CONFIG; //@ss ControlCode(A14-11)=slaveAddress(4bit) + |
suupen | 3:327bb0fcdf45 | 556 | // BlockAddress(A10-8)=000b |
suupen | 3:327bb0fcdf45 | 557 | int addressForAckPolling = control_code; |
suupen | 3:327bb0fcdf45 | 558 | |
suupen | 3:327bb0fcdf45 | 559 | if (NVMorEEPROM == RESISTER) { //@ss+↓ |
suupen | 3:327bb0fcdf45 | 560 | pc.printf("RESISTER don't erase area\n"); |
suupen | 3:327bb0fcdf45 | 561 | return (0); |
suupen | 3:327bb0fcdf45 | 562 | } //@ss+↑ |
suupen | 3:327bb0fcdf45 | 563 | |
suupen | 3:327bb0fcdf45 | 564 | resister_unprotect(uint8_t(control_code)); //@ss+ |
suupen | 0:7c6ad253848a | 565 | |
suupen | 0:7c6ad253848a | 566 | |
suupen | 3:327bb0fcdf45 | 567 | for (uint8_t i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 568 | pc.printf("Erasing page: 0x%02x ", i); |
suupen | 3:327bb0fcdf45 | 569 | |
suupen | 3:327bb0fcdf45 | 570 | i2cBuffer[0] = 0xE3; // I2C Word Address |
suupen | 3:327bb0fcdf45 | 571 | //@ss Page Erase Register |
suupen | 3:327bb0fcdf45 | 572 | //@ss bit7: ERSE 1 |
suupen | 3:327bb0fcdf45 | 573 | //@ss bit4: ERSEB4 0: NVM, 1:EEPROM |
suupen | 3:327bb0fcdf45 | 574 | //@ss bit3-0: ERSEB3-0: page address |
suupen | 3:327bb0fcdf45 | 575 | if (NVMorEEPROM == NVM) { |
suupen | 3:327bb0fcdf45 | 576 | pc.printf("NVM \n"); |
suupen | 3:327bb0fcdf45 | 577 | i2cBuffer[1] = (0x80 | i); |
suupen | 3:327bb0fcdf45 | 578 | } else if (NVMorEEPROM == EEPROM) { |
suupen | 3:327bb0fcdf45 | 579 | pc.printf("EEPROM \n"); |
suupen | 3:327bb0fcdf45 | 580 | i2cBuffer[1] = (0x90 | i); |
suupen | 3:327bb0fcdf45 | 581 | } |
suupen | 3:327bb0fcdf45 | 582 | Wire.write(control_code, i2cBuffer, |
suupen | 3:327bb0fcdf45 | 583 | 2); //@ss Control BYte = ControlCode + Block Address |
suupen | 3:327bb0fcdf45 | 584 | |
suupen | 3:327bb0fcdf45 | 585 | wait(0.1); //@ss+ |
suupen | 3:327bb0fcdf45 | 586 | |
suupen | 3:327bb0fcdf45 | 587 | /* To accommodate for the non-I2C compliant ACK behavior of the Page Erase |
suupen | 3:327bb0fcdf45 | 588 | * Byte, we've removed the software check for an I2C ACK and added the |
suupen | 3:327bb0fcdf45 | 589 | * "Wire.endTransmission();" line to generate a stop condition. |
suupen | 3:327bb0fcdf45 | 590 | * - Please reference "Issue 2: Non-I2C Compliant ACK Behavior for the NVM |
suupen | 3:327bb0fcdf45 | 591 | * and EEPROM Page Erase Byte" in the SLG46824/6 (XC revision) errata |
suupen | 3:327bb0fcdf45 | 592 | * document for more information. |
suupen | 3:327bb0fcdf45 | 593 | * |
suupen | 3:327bb0fcdf45 | 594 | * 要約: たまにNACKを返すことがあるので、無条件に終了させればよい。 |
suupen | 3:327bb0fcdf45 | 595 | * //@ss220717+ |
suupen | 3:327bb0fcdf45 | 596 | * https://medium.com/dialog-semiconductor/slg46824-6-arduino-programming-example-1459917da8b |
suupen | 3:327bb0fcdf45 | 597 | * //@ss220717+ |
suupen | 3:327bb0fcdf45 | 598 | */ |
suupen | 3:327bb0fcdf45 | 599 | |
suupen | 3:327bb0fcdf45 | 600 | //@ss tER(20ms)の処理終了待ち |
suupen | 3:327bb0fcdf45 | 601 | if (ackPolling(addressForAckPolling) == -1) { |
suupen | 3:327bb0fcdf45 | 602 | pc.printf("NG\n"); |
suupen | 3:327bb0fcdf45 | 603 | return -1; |
suupen | 3:327bb0fcdf45 | 604 | } else { |
suupen | 3:327bb0fcdf45 | 605 | pc.printf("ready \n"); |
suupen | 3:327bb0fcdf45 | 606 | wait(0.1); |
suupen | 3:327bb0fcdf45 | 607 | } |
suupen | 3:327bb0fcdf45 | 608 | } |
suupen | 3:327bb0fcdf45 | 609 | |
suupen | 3:327bb0fcdf45 | 610 | powercycle(control_code); |
suupen | 3:327bb0fcdf45 | 611 | return 0; |
suupen | 3:327bb0fcdf45 | 612 | } |
suupen | 3:327bb0fcdf45 | 613 | |
suupen | 3:327bb0fcdf45 | 614 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 615 | // readChip 230105OK |
suupen | 3:327bb0fcdf45 | 616 | //////////////////////////////////////////////////////////////////////////////// |
suupen | 3:327bb0fcdf45 | 617 | void readChip(greenPakMemory_t NVMorEEPROM) { //@ss220717+ |
suupen | 3:327bb0fcdf45 | 618 | //@ssint readChip(String NVMorEEPROM) { //@ss220717- |
suupen | 3:327bb0fcdf45 | 619 | // int control_code = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 620 | uint8_t control_code = slave_address << 4; |
suupen | 3:327bb0fcdf45 | 621 | |
suupen | 3:327bb0fcdf45 | 622 | //@ss I2C Block Addressの設定 |
suupen | 3:327bb0fcdf45 | 623 | //@ss A9=1, A8=0: NVM (0x02) |
suupen | 3:327bb0fcdf45 | 624 | //@ss A9=1, A8=1: EEPROM (0x03) |
suupen | 3:327bb0fcdf45 | 625 | if (NVMorEEPROM == NVM) { |
suupen | 3:327bb0fcdf45 | 626 | control_code |= NVM_CONFIG; |
suupen | 3:327bb0fcdf45 | 627 | pc.printf("memory = NVM\n"); |
suupen | 3:327bb0fcdf45 | 628 | } else if (NVMorEEPROM == EEPROM) { |
suupen | 3:327bb0fcdf45 | 629 | control_code |= EEPROM_CONFIG; |
suupen | 3:327bb0fcdf45 | 630 | pc.printf("memory = EEPROM\n"); |
suupen | 3:327bb0fcdf45 | 631 | } else if (NVMorEEPROM == RESISTER) //@ss+↓ |
suupen | 3:327bb0fcdf45 | 632 | { |
suupen | 3:327bb0fcdf45 | 633 | control_code |= RESISTER_CONFIG; |
suupen | 3:327bb0fcdf45 | 634 | pc.printf("memory = RESISTER\n"); |
suupen | 3:327bb0fcdf45 | 635 | |
suupen | 3:327bb0fcdf45 | 636 | } //@ss+↑ |
suupen | 3:327bb0fcdf45 | 637 | |
suupen | 3:327bb0fcdf45 | 638 | // pc.printf("memory = %02x\n",control_code); |
suupen | 3:327bb0fcdf45 | 639 | |
suupen | 3:327bb0fcdf45 | 640 | for (int i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 641 | pc.printf("%02x :", i); //@ss+ |
suupen | 3:327bb0fcdf45 | 642 | |
suupen | 3:327bb0fcdf45 | 643 | i2cBuffer[0] = i << 4; |
suupen | 3:327bb0fcdf45 | 644 | Wire.write(control_code, i2cBuffer, 1, true); |
suupen | 3:327bb0fcdf45 | 645 | wait(0.01); |
suupen | 3:327bb0fcdf45 | 646 | |
suupen | 3:327bb0fcdf45 | 647 | Wire.read(control_code, i2cBuffer, 16, true); |
suupen | 3:327bb0fcdf45 | 648 | |
suupen | 3:327bb0fcdf45 | 649 | for (int j = 0; j < 16; j++) { |
suupen | 3:327bb0fcdf45 | 650 | pc.printf("%02x ", i2cBuffer[j]); |
suupen | 3:327bb0fcdf45 | 651 | } |
suupen | 3:327bb0fcdf45 | 652 | pc.printf("\n"); |
suupen | 3:327bb0fcdf45 | 653 | } |
suupen | 3:327bb0fcdf45 | 654 | Wire.stop(); |
suupen | 3:327bb0fcdf45 | 655 | } |
suupen | 3:327bb0fcdf45 | 656 | |
suupen | 3:327bb0fcdf45 | 657 | //***************************************************************************** |
suupen | 3:327bb0fcdf45 | 658 | // main |
suupen | 3:327bb0fcdf45 | 659 | //***************************************************************************** |
suupen | 3:327bb0fcdf45 | 660 | #if 1 |
suupen | 3:327bb0fcdf45 | 661 | int main() { |
suupen | 3:327bb0fcdf45 | 662 | // pc.format(8,Serial::Even,1); |
suupen | 3:327bb0fcdf45 | 663 | pc.baud(PC_BOUD); |
suupen | 3:327bb0fcdf45 | 664 | Wire.frequency(10000); |
suupen | 3:327bb0fcdf45 | 665 | |
suupen | 3:327bb0fcdf45 | 666 | NVMFile = NVMFileRead(); |
suupen | 3:327bb0fcdf45 | 667 | pc.printf("ans = %d", NVMFile); |
suupen | 3:327bb0fcdf45 | 668 | while (1) { |
suupen | 3:327bb0fcdf45 | 669 | // typedef enum { NVM, EEPROM, RESISTER } greenPakMemory_t; |
suupen | 3:327bb0fcdf45 | 670 | // greenPakMemory_t NVMorEEPROM = NVM; // 読み書き対象 |
suupen | 3:327bb0fcdf45 | 671 | |
suupen | 3:327bb0fcdf45 | 672 | if (pcRecive() == 1) { |
suupen | 3:327bb0fcdf45 | 673 | char *p = B_pcRx; |
suupen | 3:327bb0fcdf45 | 674 | switch (*p++) { |
suupen | 1:c6e8a41200d9 | 675 | |
suupen | 3:327bb0fcdf45 | 676 | case 'A': |
suupen | 3:327bb0fcdf45 | 677 | // スレーブアドレス変更 |
suupen | 3:327bb0fcdf45 | 678 | uint8_t address; |
suupen | 3:327bb0fcdf45 | 679 | address = atoh1(p); |
suupen | 3:327bb0fcdf45 | 680 | if ((0 <= address) && (address <= 0xf)) { |
suupen | 3:327bb0fcdf45 | 681 | pc.printf("old address = %02x\n", slave_address); |
suupen | 3:327bb0fcdf45 | 682 | slave_address = address; |
suupen | 3:327bb0fcdf45 | 683 | pc.printf("new address = %02x\n", slave_address); |
suupen | 3:327bb0fcdf45 | 684 | } else { |
suupen | 3:327bb0fcdf45 | 685 | pc.printf("now address = %02x\n", slave_address); |
suupen | 3:327bb0fcdf45 | 686 | } |
suupen | 3:327bb0fcdf45 | 687 | break; |
suupen | 3:327bb0fcdf45 | 688 | case 'C': |
suupen | 3:327bb0fcdf45 | 689 | pc.printf("slave address = %02x\n", slave_address); |
suupen | 3:327bb0fcdf45 | 690 | |
suupen | 3:327bb0fcdf45 | 691 | pc.printf("Memory = "); |
suupen | 3:327bb0fcdf45 | 692 | |
suupen | 3:327bb0fcdf45 | 693 | switch (NVMorEEPROM) { |
suupen | 3:327bb0fcdf45 | 694 | case NVM: |
suupen | 3:327bb0fcdf45 | 695 | pc.printf("NVM\n"); |
suupen | 3:327bb0fcdf45 | 696 | break; |
suupen | 3:327bb0fcdf45 | 697 | case EEPROM: |
suupen | 3:327bb0fcdf45 | 698 | pc.printf("EEPROM\n"); |
suupen | 3:327bb0fcdf45 | 699 | break; |
suupen | 3:327bb0fcdf45 | 700 | case RESISTER: |
suupen | 3:327bb0fcdf45 | 701 | pc.printf("RESISTER"); |
suupen | 3:327bb0fcdf45 | 702 | break; |
suupen | 3:327bb0fcdf45 | 703 | default: |
suupen | 3:327bb0fcdf45 | 704 | pc.printf("unkown\n"); |
suupen | 3:327bb0fcdf45 | 705 | break; |
suupen | 3:327bb0fcdf45 | 706 | } |
suupen | 3:327bb0fcdf45 | 707 | break; |
suupen | 3:327bb0fcdf45 | 708 | case 'E': |
suupen | 3:327bb0fcdf45 | 709 | pc.printf("erase start\n"); |
suupen | 3:327bb0fcdf45 | 710 | if (eraseChip(NVMorEEPROM) == 0) { |
suupen | 3:327bb0fcdf45 | 711 | pc.printf("erase OK\n"); |
suupen | 3:327bb0fcdf45 | 712 | } else { |
suupen | 3:327bb0fcdf45 | 713 | pc.printf("erase NG\n"); |
suupen | 3:327bb0fcdf45 | 714 | } |
suupen | 3:327bb0fcdf45 | 715 | break; |
suupen | 3:327bb0fcdf45 | 716 | case 'S': |
suupen | 3:327bb0fcdf45 | 717 | // 操作対象変更 |
suupen | 3:327bb0fcdf45 | 718 | switch (*p++) { |
suupen | 3:327bb0fcdf45 | 719 | case 'N': |
suupen | 3:327bb0fcdf45 | 720 | NVMorEEPROM = NVM; |
suupen | 3:327bb0fcdf45 | 721 | pc.printf("new select = NVM set\n"); |
suupen | 3:327bb0fcdf45 | 722 | break; |
suupen | 3:327bb0fcdf45 | 723 | case 'E': |
suupen | 3:327bb0fcdf45 | 724 | NVMorEEPROM = EEPROM; |
suupen | 3:327bb0fcdf45 | 725 | pc.printf("new select = EEPROM set\n"); |
suupen | 3:327bb0fcdf45 | 726 | break; |
suupen | 3:327bb0fcdf45 | 727 | case 'R': |
suupen | 3:327bb0fcdf45 | 728 | NVMorEEPROM = RESISTER; |
suupen | 3:327bb0fcdf45 | 729 | pc.printf("new select = RESISTER set\n"); |
suupen | 3:327bb0fcdf45 | 730 | break; |
suupen | 3:327bb0fcdf45 | 731 | default: |
suupen | 3:327bb0fcdf45 | 732 | switch (NVMorEEPROM) { |
suupen | 3:327bb0fcdf45 | 733 | case NVM: |
suupen | 3:327bb0fcdf45 | 734 | pc.printf("now select = NVM\n"); |
suupen | 3:327bb0fcdf45 | 735 | break; |
suupen | 3:327bb0fcdf45 | 736 | case EEPROM: |
suupen | 3:327bb0fcdf45 | 737 | pc.printf("now select = EEPROM\n"); |
suupen | 3:327bb0fcdf45 | 738 | break; |
suupen | 3:327bb0fcdf45 | 739 | case RESISTER: |
suupen | 3:327bb0fcdf45 | 740 | pc.printf("now select = RESISTER"); |
suupen | 3:327bb0fcdf45 | 741 | break; |
suupen | 3:327bb0fcdf45 | 742 | default: |
suupen | 3:327bb0fcdf45 | 743 | pc.printf("now select = unkown\n"); |
suupen | 3:327bb0fcdf45 | 744 | break; |
suupen | 3:327bb0fcdf45 | 745 | } |
suupen | 3:327bb0fcdf45 | 746 | break; |
suupen | 3:327bb0fcdf45 | 747 | } |
suupen | 3:327bb0fcdf45 | 748 | break; |
suupen | 3:327bb0fcdf45 | 749 | case 'P': |
suupen | 3:327bb0fcdf45 | 750 | ping(); |
suupen | 3:327bb0fcdf45 | 751 | break; |
suupen | 3:327bb0fcdf45 | 752 | case 'R': |
suupen | 3:327bb0fcdf45 | 753 | pc.printf("Reading chip!\n"); |
suupen | 3:327bb0fcdf45 | 754 | readChip(NVMorEEPROM); |
suupen | 3:327bb0fcdf45 | 755 | |
suupen | 3:327bb0fcdf45 | 756 | break; |
suupen | 3:327bb0fcdf45 | 757 | case 'W': |
suupen | 3:327bb0fcdf45 | 758 | // erase |
suupen | 3:327bb0fcdf45 | 759 | pc.printf("erase start\n"); |
suupen | 3:327bb0fcdf45 | 760 | if (eraseChip(NVMorEEPROM) == 0) { |
suupen | 3:327bb0fcdf45 | 761 | pc.printf("erase OK\n"); |
suupen | 3:327bb0fcdf45 | 762 | } else { |
suupen | 3:327bb0fcdf45 | 763 | pc.printf("erase NG\n"); |
suupen | 3:327bb0fcdf45 | 764 | } |
suupen | 3:327bb0fcdf45 | 765 | |
suupen | 3:327bb0fcdf45 | 766 | // write |
suupen | 3:327bb0fcdf45 | 767 | if (writeChip(NVMorEEPROM) == 0) { |
suupen | 3:327bb0fcdf45 | 768 | pc.printf("write OK\n"); |
suupen | 3:327bb0fcdf45 | 769 | } else { |
suupen | 3:327bb0fcdf45 | 770 | pc.printf("write NG\n"); |
suupen | 3:327bb0fcdf45 | 771 | } |
suupen | 3:327bb0fcdf45 | 772 | break; |
suupen | 3:327bb0fcdf45 | 773 | case 'D': |
suupen | 3:327bb0fcdf45 | 774 | pc.printf("D input\n"); |
suupen | 3:327bb0fcdf45 | 775 | break; |
suupen | 3:327bb0fcdf45 | 776 | } |
suupen | 3:327bb0fcdf45 | 777 | } |
suupen | 3:327bb0fcdf45 | 778 | } |
suupen | 3:327bb0fcdf45 | 779 | } |
suupen | 3:327bb0fcdf45 | 780 | #endif |
suupen | 3:327bb0fcdf45 | 781 | |
suupen | 3:327bb0fcdf45 | 782 | #if 0 |
suupen | 3:327bb0fcdf45 | 783 | |
suupen | 3:327bb0fcdf45 | 784 | int main() { |
suupen | 3:327bb0fcdf45 | 785 | pc.baud(115200); |
suupen | 3:327bb0fcdf45 | 786 | FILE *fp; |
suupen | 3:327bb0fcdf45 | 787 | // int ans; |
suupen | 3:327bb0fcdf45 | 788 | char *p; |
suupen | 3:327bb0fcdf45 | 789 | int timer; // serial送信時間間隔 ( 1/1 [ms]/bit) |
suupen | 3:327bb0fcdf45 | 790 | int baud; // usb-serialのbaudrate ( 1/1 [bps]/bit) |
suupen | 3:327bb0fcdf45 | 791 | |
suupen | 3:327bb0fcdf45 | 792 | NVMFile = NVMFileRead(); |
suupen | 3:327bb0fcdf45 | 793 | pc.printf("main main\n"); |
suupen | 3:327bb0fcdf45 | 794 | |
suupen | 3:327bb0fcdf45 | 795 | fp = fopen("/local/NVM.hex", "r"); |
suupen | 3:327bb0fcdf45 | 796 | ledopen = 1; |
suupen | 3:327bb0fcdf45 | 797 | |
suupen | 3:327bb0fcdf45 | 798 | while (1) { |
suupen | 3:327bb0fcdf45 | 799 | |
suupen | 3:327bb0fcdf45 | 800 | if (fgets(buffer, Z_bufferNumber, fp) != NULL) { |
suupen | 3:327bb0fcdf45 | 801 | // ans = fscanf(fp,"%s",buffer); |
suupen | 3:327bb0fcdf45 | 802 | // if(ans != -1) { |
suupen | 3:327bb0fcdf45 | 803 | p = buffer; |
suupen | 2:52002844d0c6 | 804 | |
suupen | 1:c6e8a41200d9 | 805 | |
suupen | 3:327bb0fcdf45 | 806 | for(uint8_t i = 0; i < 255; i++){ |
suupen | 3:327bb0fcdf45 | 807 | pc.printf("*p(%d) = %02x\n",i, *(p+i)); |
suupen | 3:327bb0fcdf45 | 808 | wait(0.1); |
suupen | 3:327bb0fcdf45 | 809 | } |
suupen | 3:327bb0fcdf45 | 810 | |
suupen | 3:327bb0fcdf45 | 811 | // 文字列 or 制御コマンド |
suupen | 3:327bb0fcdf45 | 812 | while (*p != 0x00) { |
suupen | 3:327bb0fcdf45 | 813 | pc.printf("*p = %02x\n",*p); |
suupen | 3:327bb0fcdf45 | 814 | switch (*p++) { |
suupen | 3:327bb0fcdf45 | 815 | case ':': |
suupen | 3:327bb0fcdf45 | 816 | byteCount = atoh2(p); |
suupen | 3:327bb0fcdf45 | 817 | p += 2; |
suupen | 3:327bb0fcdf45 | 818 | p += 2; |
suupen | 3:327bb0fcdf45 | 819 | address = atoh2(p) >> 4; // 2byte addressの下位1byteを取得 |
suupen | 3:327bb0fcdf45 | 820 | p += 2; |
suupen | 3:327bb0fcdf45 | 821 | recodeType = atoh2(p); |
suupen | 3:327bb0fcdf45 | 822 | p += 2; |
suupen | 3:327bb0fcdf45 | 823 | |
suupen | 3:327bb0fcdf45 | 824 | pc.printf("byte=%02x address=%02x type=%02x\n", byteCount, address, |
suupen | 3:327bb0fcdf45 | 825 | recodeType); |
suupen | 3:327bb0fcdf45 | 826 | wait(1); |
suupen | 3:327bb0fcdf45 | 827 | if (byteCount != 0x10) { |
suupen | 3:327bb0fcdf45 | 828 | wait(1); |
suupen | 3:327bb0fcdf45 | 829 | break; |
suupen | 3:327bb0fcdf45 | 830 | } |
suupen | 3:327bb0fcdf45 | 831 | |
suupen | 3:327bb0fcdf45 | 832 | for (uint8_t i = 0; i < 16; i++) { |
suupen | 3:327bb0fcdf45 | 833 | NVMData[address][i] = atoh2(p); |
suupen | 3:327bb0fcdf45 | 834 | p += 2; |
suupen | 3:327bb0fcdf45 | 835 | pc.printf("%02x", NVMData[address][i]); |
suupen | 3:327bb0fcdf45 | 836 | } |
suupen | 3:327bb0fcdf45 | 837 | pc.printf("\n"); |
suupen | 3:327bb0fcdf45 | 838 | } |
suupen | 3:327bb0fcdf45 | 839 | } |
suupen | 3:327bb0fcdf45 | 840 | |
suupen | 3:327bb0fcdf45 | 841 | #if 0 |
suupen | 3:327bb0fcdf45 | 842 | switch (*p++) { |
suupen | 3:327bb0fcdf45 | 843 | |
suupen | 3:327bb0fcdf45 | 844 | default: |
suupen | 3:327bb0fcdf45 | 845 | // 出力文字列として処理する |
suupen | 3:327bb0fcdf45 | 846 | txDataWait(); |
suupen | 3:327bb0fcdf45 | 847 | while (txSendEndCheck() == 0) { |
suupen | 3:327bb0fcdf45 | 848 | // 割り込みで送信中 |
suupen | 3:327bb0fcdf45 | 849 | ledout = |
suupen | 3:327bb0fcdf45 | 850 | !ledout; // この行がないとwhile文から抜けなくなる。原因不明 |
suupen | 0:7c6ad253848a | 851 | } |
suupen | 0:7c6ad253848a | 852 | |
suupen | 3:327bb0fcdf45 | 853 | wait_ms(timer); |
suupen | 3:327bb0fcdf45 | 854 | //ここ |
suupen | 3:327bb0fcdf45 | 855 | break; |
suupen | 3:327bb0fcdf45 | 856 | } |
suupen | 3:327bb0fcdf45 | 857 | #endif |
suupen | 3:327bb0fcdf45 | 858 | } else { |
suupen | 3:327bb0fcdf45 | 859 | // 読みだすデータがなくなったら、先頭に戻す |
suupen | 3:327bb0fcdf45 | 860 | pc.printf("\nend end end\n"); // ファイルの最後の"LF"の代わりに出力する |
suupen | 3:327bb0fcdf45 | 861 | |
suupen | 3:327bb0fcdf45 | 862 | fclose(fp); |
suupen | 3:327bb0fcdf45 | 863 | ledopen = 0; |
suupen | 3:327bb0fcdf45 | 864 | // wait_ms(timer); |
suupen | 3:327bb0fcdf45 | 865 | |
suupen | 3:327bb0fcdf45 | 866 | fp = fopen("/local/NVM.hex", "r"); |
suupen | 3:327bb0fcdf45 | 867 | ledopen = 1; |
suupen | 0:7c6ad253848a | 868 | } |
suupen | 3:327bb0fcdf45 | 869 | } |
suupen | 0:7c6ad253848a | 870 | } |
suupen | 2:52002844d0c6 | 871 | |
suupen | 3:327bb0fcdf45 | 872 | #endif |