10
10
#include "led.h"
11
11
#include "log.h"
12
12
#include "version.h"
13
+ #include "flash.h"
13
14
#include <stdio.h>
14
15
#include <string.h>
15
16
#include <stddef.h>
22
23
23
24
#define NP_NAND_GOOD_BLOCK_MARK 0xFF
24
25
26
+ #define BOOT_CONFIG_ADDR 0x08003800
27
+ #define FLASH_START_ADDR 0x08000000
28
+ #define FLASH_SIZE 0x40000
29
+ #define FLASH_PAGE_SIZE 0x800
30
+ #define FLASH_BLOCK_SIZE 0x800
31
+
25
32
typedef enum
26
33
{
27
- NP_CMD_NAND_READ_ID = 0x00 ,
28
- NP_CMD_NAND_ERASE = 0x01 ,
29
- NP_CMD_NAND_READ = 0x02 ,
30
- NP_CMD_NAND_WRITE_S = 0x03 ,
31
- NP_CMD_NAND_WRITE_D = 0x04 ,
32
- NP_CMD_NAND_WRITE_E = 0x05 ,
33
- NP_CMD_NAND_CONF = 0x06 ,
34
- NP_CMD_NAND_READ_BB = 0x07 ,
35
- NP_CMD_VERSION_GET = 0x08 ,
36
- NP_CMD_NAND_LAST = 0x09 ,
34
+ NP_CMD_NAND_READ_ID = 0x00 ,
35
+ NP_CMD_NAND_ERASE = 0x01 ,
36
+ NP_CMD_NAND_READ = 0x02 ,
37
+ NP_CMD_NAND_WRITE_S = 0x03 ,
38
+ NP_CMD_NAND_WRITE_D = 0x04 ,
39
+ NP_CMD_NAND_WRITE_E = 0x05 ,
40
+ NP_CMD_NAND_CONF = 0x06 ,
41
+ NP_CMD_NAND_READ_BB = 0x07 ,
42
+ NP_CMD_VERSION_GET = 0x08 ,
43
+ NP_CMD_ACTIVE_IMAGE_GET = 0x09 ,
44
+ NP_CMD_FW_UPDATE_S = 0x0a ,
45
+ NP_CMD_FW_UPDATE_D = 0x0b ,
46
+ NP_CMD_FW_UPDATE_E = 0x0c ,
47
+ NP_CMD_NAND_LAST = 0x0d ,
37
48
} np_cmd_code_t ;
38
49
39
50
enum
@@ -197,6 +208,12 @@ typedef struct __attribute__((__packed__))
197
208
version_t version ;
198
209
} np_resp_version_t ;
199
210
211
+ typedef struct __attribute__((__packed__ ))
212
+ {
213
+ np_resp_t header ;
214
+ uint8_t active_image ;
215
+ } np_resp_active_image_t ;
216
+
200
217
typedef struct
201
218
{
202
219
uint32_t addr ;
@@ -210,12 +227,18 @@ typedef struct
210
227
uint32_t offset ;
211
228
} np_page_t ;
212
229
230
+ typedef struct __attribute__((__packed__ ))
231
+ {
232
+ uint8_t active_image ;
233
+ } boot_config_t ;
234
+
213
235
typedef struct
214
236
{
215
237
uint8_t * rx_buf ;
216
238
uint32_t rx_buf_len ;
217
239
uint32_t addr ;
218
240
uint32_t len ;
241
+ uint32_t base_addr ;
219
242
uint32_t page_size ;
220
243
uint32_t block_size ;
221
244
uint32_t total_size ;
@@ -234,6 +257,7 @@ typedef struct
234
257
typedef struct
235
258
{
236
259
int id ;
260
+ bool is_chip_cmd ;
237
261
int (* exec )(np_prog_t * prog );
238
262
} np_cmd_handler_t ;
239
263
@@ -1118,17 +1142,268 @@ int np_cmd_version_get(np_prog_t *prog)
1118
1142
return 0 ;
1119
1143
}
1120
1144
1145
+ static int np_boot_config_read (boot_config_t * config )
1146
+ {
1147
+ if (flash_read (BOOT_CONFIG_ADDR , (uint8_t * )config , sizeof (boot_config_t ))
1148
+ < 0 )
1149
+ {
1150
+ return -1 ;
1151
+ }
1152
+
1153
+ return 0 ;
1154
+ }
1155
+
1156
+ static int np_boot_config_write (boot_config_t * config )
1157
+ {
1158
+ if (flash_page_erase (BOOT_CONFIG_ADDR ) < 0 )
1159
+ return -1 ;
1160
+
1161
+ if (flash_write (BOOT_CONFIG_ADDR , (uint8_t * )config , sizeof (boot_config_t ))
1162
+ < 0 )
1163
+ {
1164
+ return -1 ;
1165
+ }
1166
+
1167
+ return 0 ;
1168
+ }
1169
+
1170
+ static int np_cmd_active_image_get (np_prog_t * prog )
1171
+ {
1172
+ boot_config_t boot_config ;
1173
+ np_resp_active_image_t resp ;
1174
+ size_t resp_len = sizeof (resp );
1175
+
1176
+ DEBUG_PRINT ("Get active image command\r\n" );
1177
+
1178
+ if (np_boot_config_read (& boot_config ))
1179
+ return NP_ERR_INTERNAL ;
1180
+
1181
+ resp .header .code = NP_RESP_DATA ;
1182
+ resp .header .info = resp_len - sizeof (resp .header );
1183
+ resp .active_image = boot_config .active_image ;
1184
+
1185
+ if (np_comm_cb )
1186
+ np_comm_cb -> send ((uint8_t * )& resp , resp_len );
1187
+
1188
+ return 0 ;
1189
+ }
1190
+
1191
+ static int np_cmd_fw_update_start (np_prog_t * prog )
1192
+ {
1193
+ uint32_t addr , len ;
1194
+ np_write_start_cmd_t * write_start_cmd ;
1195
+
1196
+ if (prog -> rx_buf_len < sizeof (np_write_start_cmd_t ))
1197
+ {
1198
+ ERROR_PRINT ("Wrong buffer length for write start command %lu\r\n" ,
1199
+ prog -> rx_buf_len );
1200
+ return NP_ERR_LEN_INVALID ;
1201
+ }
1202
+
1203
+ write_start_cmd = (np_write_start_cmd_t * )prog -> rx_buf ;
1204
+ addr = write_start_cmd -> addr ;
1205
+ len = write_start_cmd -> len ;
1206
+
1207
+ DEBUG_PRINT ("Write at 0x%lx 0x%lx bytes command\r\n" , addr , len );
1208
+
1209
+ prog -> base_addr = FLASH_START_ADDR ;
1210
+ prog -> page_size = FLASH_PAGE_SIZE ;
1211
+ prog -> block_size = FLASH_BLOCK_SIZE ;
1212
+ prog -> total_size = FLASH_SIZE ;
1213
+
1214
+ if (addr + len > prog -> base_addr + prog -> total_size )
1215
+ {
1216
+ ERROR_PRINT ("Write address 0x%lx+0x%lx is more then flash size "
1217
+ "0x%lx\r\n" , addr , len , prog -> base_addr + prog -> total_size );
1218
+ return NP_ERR_ADDR_EXCEEDED ;
1219
+ }
1220
+
1221
+ if (addr % prog -> page_size )
1222
+ {
1223
+ ERROR_PRINT ("Address 0x%lx is not aligned to page size 0x%lx\r\n" , addr ,
1224
+ prog -> page_size );
1225
+ return NP_ERR_ADDR_NOT_ALIGN ;
1226
+ }
1227
+
1228
+ if (!len )
1229
+ {
1230
+ ERROR_PRINT ("Length is 0\r\n" );
1231
+ return NP_ERR_LEN_INVALID ;
1232
+ }
1233
+
1234
+ if (len % prog -> page_size )
1235
+ {
1236
+ ERROR_PRINT ("Length 0x%lx is not aligned to page size 0x%lx\r\n" , len ,
1237
+ prog -> page_size );
1238
+ return NP_ERR_LEN_NOT_ALIGN ;
1239
+ }
1240
+
1241
+ prog -> addr = addr ;
1242
+ prog -> len = len ;
1243
+ prog -> addr_is_set = 1 ;
1244
+
1245
+ prog -> page .page = addr / prog -> page_size ;
1246
+ prog -> page .offset = 0 ;
1247
+
1248
+ prog -> bytes_written = 0 ;
1249
+ prog -> bytes_ack = 0 ;
1250
+
1251
+ return np_send_ok_status ();
1252
+ }
1253
+
1254
+ static int np_cmd_fw_update_data (np_prog_t * prog )
1255
+ {
1256
+ uint32_t write_len , bytes_left , len ;
1257
+ np_write_data_cmd_t * write_data_cmd ;
1258
+
1259
+ if (prog -> rx_buf_len < sizeof (np_write_data_cmd_t ))
1260
+ {
1261
+ ERROR_PRINT ("Wrong buffer length for write data command %lu\r\n" ,
1262
+ prog -> rx_buf_len );
1263
+ return NP_ERR_LEN_INVALID ;
1264
+ }
1265
+
1266
+ write_data_cmd = (np_write_data_cmd_t * )prog -> rx_buf ;
1267
+ len = write_data_cmd -> len ;
1268
+ if (len + sizeof (np_write_data_cmd_t ) > NP_PACKET_BUF_SIZE )
1269
+ {
1270
+ ERROR_PRINT ("Data size is wrong 0x%lx\r\n" , len );
1271
+ return NP_ERR_CMD_DATA_SIZE ;
1272
+ }
1273
+
1274
+ if (len + sizeof (np_write_data_cmd_t ) != prog -> rx_buf_len )
1275
+ {
1276
+ ERROR_PRINT ("Buffer len 0x%lx is bigger then command 0x%lx\r\n" ,
1277
+ prog -> rx_buf_len , len + sizeof (np_write_data_cmd_t ));
1278
+ return NP_ERR_CMD_DATA_SIZE ;
1279
+ }
1280
+
1281
+ if (!prog -> addr_is_set )
1282
+ {
1283
+ ERROR_PRINT ("Write address is not set\r\n" );
1284
+ return NP_ERR_ADDR_INVALID ;
1285
+ }
1286
+
1287
+ if (prog -> page .offset + len > prog -> page_size )
1288
+ write_len = prog -> page_size - prog -> page .offset ;
1289
+ else
1290
+ write_len = len ;
1291
+
1292
+ memcpy (prog -> page .buf + prog -> page .offset , write_data_cmd -> data , write_len );
1293
+ prog -> page .offset += write_len ;
1294
+
1295
+ if (prog -> page .offset == prog -> page_size )
1296
+ {
1297
+ if (prog -> addr >= prog -> base_addr + prog -> total_size )
1298
+ {
1299
+ ERROR_PRINT ("Write address 0x%lx is more then flash size 0x%lx\r\n" ,
1300
+ prog -> addr , prog -> base_addr + prog -> total_size );
1301
+ return NP_ERR_ADDR_EXCEEDED ;
1302
+ }
1303
+
1304
+ if (flash_page_erase (prog -> addr ) < 0 )
1305
+ return NP_ERR_INTERNAL ;
1306
+
1307
+ if (flash_write (prog -> addr , prog -> page .buf , prog -> page_size ) < 0 )
1308
+ return NP_ERR_INTERNAL ;
1309
+
1310
+ prog -> addr += prog -> page_size ;
1311
+ prog -> page .page ++ ;
1312
+ prog -> page .offset = 0 ;
1313
+ }
1314
+
1315
+ bytes_left = len - write_len ;
1316
+ if (bytes_left )
1317
+ {
1318
+ memcpy (prog -> page .buf , write_data_cmd -> data + write_len , bytes_left );
1319
+ prog -> page .offset += bytes_left ;
1320
+ }
1321
+
1322
+ prog -> bytes_written += len ;
1323
+ if (prog -> bytes_written - prog -> bytes_ack >= prog -> page_size ||
1324
+ prog -> bytes_written == prog -> len )
1325
+ {
1326
+ if (np_send_write_ack (prog -> bytes_written ))
1327
+ return -1 ;
1328
+ prog -> bytes_ack = prog -> bytes_written ;
1329
+ }
1330
+
1331
+ if (prog -> bytes_written > prog -> len )
1332
+ {
1333
+ ERROR_PRINT ("Actual write data length 0x%lx is more then 0x%lx\r\n" ,
1334
+ prog -> bytes_written , prog -> len );
1335
+ return NP_ERR_LEN_EXCEEDED ;
1336
+ }
1337
+
1338
+ return 0 ;
1339
+ }
1340
+
1341
+ static int np_cmd_fw_update_end (np_prog_t * prog )
1342
+ {
1343
+ boot_config_t boot_config ;
1344
+
1345
+ prog -> addr_is_set = 0 ;
1346
+
1347
+ if (prog -> page .offset )
1348
+ {
1349
+ ERROR_PRINT ("Data of 0x%lx length was not written\r\n" ,
1350
+ prog -> page .offset );
1351
+ return NP_ERR_NAND_WR ;
1352
+ }
1353
+
1354
+ if (np_boot_config_read (& boot_config ))
1355
+ return NP_ERR_INTERNAL ;
1356
+
1357
+ boot_config .active_image = boot_config .active_image ? 0 : 1 ;
1358
+ if (np_boot_config_write (& boot_config ))
1359
+ return NP_ERR_INTERNAL ;
1360
+
1361
+ return np_send_ok_status ();
1362
+ }
1363
+
1364
+ static int np_cmd_fw_update (np_prog_t * prog )
1365
+ {
1366
+ np_cmd_t * cmd = (np_cmd_t * )prog -> rx_buf ;
1367
+ int ret = 0 ;
1368
+
1369
+ switch (cmd -> code )
1370
+ {
1371
+ case NP_CMD_FW_UPDATE_S :
1372
+ led_wr_set (true);
1373
+ ret = np_cmd_fw_update_start (prog );
1374
+ break ;
1375
+ case NP_CMD_FW_UPDATE_D :
1376
+ ret = np_cmd_fw_update_data (prog );
1377
+ break ;
1378
+ case NP_CMD_FW_UPDATE_E :
1379
+ ret = np_cmd_fw_update_end (prog );
1380
+ led_wr_set (false);
1381
+ break ;
1382
+ default :
1383
+ break ;
1384
+ }
1385
+
1386
+ if (ret < 0 )
1387
+ led_wr_set (false);
1388
+
1389
+ return ret ;
1390
+ }
1391
+
1121
1392
static np_cmd_handler_t cmd_handler [] =
1122
1393
{
1123
- { NP_CMD_NAND_READ_ID , np_cmd_nand_read_id },
1124
- { NP_CMD_NAND_ERASE , np_cmd_nand_erase },
1125
- { NP_CMD_NAND_READ , np_cmd_nand_read },
1126
- { NP_CMD_NAND_WRITE_S , np_cmd_nand_write },
1127
- { NP_CMD_NAND_WRITE_D , np_cmd_nand_write },
1128
- { NP_CMD_NAND_WRITE_E , np_cmd_nand_write },
1129
- { NP_CMD_NAND_CONF , np_cmd_nand_conf },
1130
- { NP_CMD_NAND_READ_BB , np_cmd_read_bad_blocks },
1131
- { NP_CMD_VERSION_GET , np_cmd_version_get },
1394
+ { NP_CMD_NAND_READ_ID , 1 , np_cmd_nand_read_id },
1395
+ { NP_CMD_NAND_ERASE , 1 , np_cmd_nand_erase },
1396
+ { NP_CMD_NAND_READ , 1 , np_cmd_nand_read },
1397
+ { NP_CMD_NAND_WRITE_S , 1 , np_cmd_nand_write },
1398
+ { NP_CMD_NAND_WRITE_D , 1 , np_cmd_nand_write },
1399
+ { NP_CMD_NAND_WRITE_E , 1 , np_cmd_nand_write },
1400
+ { NP_CMD_NAND_CONF , 0 , np_cmd_nand_conf },
1401
+ { NP_CMD_NAND_READ_BB , 1 , np_cmd_read_bad_blocks },
1402
+ { NP_CMD_VERSION_GET , 0 , np_cmd_version_get },
1403
+ { NP_CMD_ACTIVE_IMAGE_GET , 0 , np_cmd_active_image_get },
1404
+ { NP_CMD_FW_UPDATE_S , 0 , np_cmd_fw_update },
1405
+ { NP_CMD_FW_UPDATE_D , 0 , np_cmd_fw_update },
1406
+ { NP_CMD_FW_UPDATE_E , 0 , np_cmd_fw_update },
1132
1407
};
1133
1408
1134
1409
static bool np_cmd_is_valid (np_cmd_code_t code )
@@ -1148,19 +1423,18 @@ static int np_cmd_handler(np_prog_t *prog)
1148
1423
}
1149
1424
cmd = (np_cmd_t * )prog -> rx_buf ;
1150
1425
1151
- if (!prog -> chip_is_conf && cmd -> code != NP_CMD_NAND_CONF &&
1152
- cmd -> code != NP_CMD_VERSION_GET )
1153
- {
1154
- ERROR_PRINT ("Chip is not configured\r\n" );
1155
- return NP_ERR_CHIP_NOT_CONF ;
1156
- }
1157
-
1158
1426
if (!np_cmd_is_valid (cmd -> code ))
1159
1427
{
1160
1428
ERROR_PRINT ("Invalid cmd code %d\r\n" , cmd -> code );
1161
1429
return NP_ERR_CMD_INVALID ;
1162
1430
}
1163
1431
1432
+ if (!prog -> chip_is_conf && cmd_handler [cmd -> code ].is_chip_cmd )
1433
+ {
1434
+ ERROR_PRINT ("Chip is not configured\r\n" );
1435
+ return NP_ERR_CHIP_NOT_CONF ;
1436
+ }
1437
+
1164
1438
return cmd_handler [cmd -> code ].exec (prog );
1165
1439
}
1166
1440
0 commit comments