1010#include "led.h"
1111#include "log.h"
1212#include "version.h"
13+ #include "flash.h"
1314#include <stdio.h>
1415#include <string.h>
1516#include <stddef.h>
2223
2324#define NP_NAND_GOOD_BLOCK_MARK 0xFF
2425
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+
2532typedef enum
2633{
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 ,
3748} np_cmd_code_t ;
3849
3950enum
@@ -197,6 +208,12 @@ typedef struct __attribute__((__packed__))
197208 version_t version ;
198209} np_resp_version_t ;
199210
211+ typedef struct __attribute__((__packed__ ))
212+ {
213+ np_resp_t header ;
214+ uint8_t active_image ;
215+ } np_resp_active_image_t ;
216+
200217typedef struct
201218{
202219 uint32_t addr ;
@@ -210,12 +227,18 @@ typedef struct
210227 uint32_t offset ;
211228} np_page_t ;
212229
230+ typedef struct __attribute__((__packed__ ))
231+ {
232+ uint8_t active_image ;
233+ } boot_config_t ;
234+
213235typedef struct
214236{
215237 uint8_t * rx_buf ;
216238 uint32_t rx_buf_len ;
217239 uint32_t addr ;
218240 uint32_t len ;
241+ uint32_t base_addr ;
219242 uint32_t page_size ;
220243 uint32_t block_size ;
221244 uint32_t total_size ;
@@ -234,6 +257,7 @@ typedef struct
234257typedef struct
235258{
236259 int id ;
260+ bool is_chip_cmd ;
237261 int (* exec )(np_prog_t * prog );
238262} np_cmd_handler_t ;
239263
@@ -1118,17 +1142,268 @@ int np_cmd_version_get(np_prog_t *prog)
11181142 return 0 ;
11191143}
11201144
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+
11211392static np_cmd_handler_t cmd_handler [] =
11221393{
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 },
11321407};
11331408
11341409static bool np_cmd_is_valid (np_cmd_code_t code )
@@ -1148,19 +1423,18 @@ static int np_cmd_handler(np_prog_t *prog)
11481423 }
11491424 cmd = (np_cmd_t * )prog -> rx_buf ;
11501425
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-
11581426 if (!np_cmd_is_valid (cmd -> code ))
11591427 {
11601428 ERROR_PRINT ("Invalid cmd code %d\r\n" , cmd -> code );
11611429 return NP_ERR_CMD_INVALID ;
11621430 }
11631431
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+
11641438 return cmd_handler [cmd -> code ].exec (prog );
11651439}
11661440
0 commit comments