435 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			435 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT | ||
|  | be copied by any method or incorporated into another program without | ||
|  | the express written consent of Aerospace C.Power. This Information or any portion | ||
|  | thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  | is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  | liability for its use in any way and conveys no license or title under | ||
|  | any patent or copyright and makes no representation or warranty that this | ||
|  | Information is free from patent or copyright infringement. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | #include "os_types.h"
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #include "iot_diag.h"
 | ||
|  | #include "iot_io.h"
 | ||
|  | 
 | ||
|  | #include "ahb.h"
 | ||
|  | #include "pmu_hw.h"
 | ||
|  | #include "ana.h"
 | ||
|  | #include "clk.h"
 | ||
|  | #include "ddrc.h"
 | ||
|  | #include "ff.h"
 | ||
|  | #include "integer.h"
 | ||
|  | 
 | ||
|  | int uart_e_try_putc(int port, char c); | ||
|  | int uart_e_getc(int port); | ||
|  | 
 | ||
|  | #define COMMAND_MAX_SZ  (4096)
 | ||
|  | #define RECV_MAX_SZ (8 * 1024 * 1024)
 | ||
|  | #define RECV_START_ADDR (0x10000000)
 | ||
|  | 
 | ||
|  | typedef enum _command { | ||
|  |     ECDH = 1, | ||
|  |     ECDSA = 2, | ||
|  |     AES = 3, | ||
|  |     FLASH = 4, | ||
|  | } command_t; | ||
|  | 
 | ||
|  | typedef enum _field_type { | ||
|  |     FIELD_FATFS = 1, | ||
|  | } field_type_t; | ||
|  | 
 | ||
|  | typedef enum _flash_fmt_type { | ||
|  |     FMT_DIRECTORY = 0, | ||
|  |     FMT_FILENAME = 1, | ||
|  |     FMT_FILEDATA = 2, | ||
|  | } flash_fmt_type_t; | ||
|  | 
 | ||
|  | typedef enum _field_val_def { | ||
|  |     FIELD_FLASH_BURN = 1, | ||
|  | } field_val_def_t; | ||
|  | 
 | ||
|  | #pragma pack(push)    /* save the pack status */
 | ||
|  | #pragma pack(1)        /* 1 byte align */
 | ||
|  | 
 | ||
|  | typedef struct _field_header { | ||
|  |     uint8_t field_type; | ||
|  |     uint16_t field_len; | ||
|  |     uint8_t field_value; | ||
|  | } field_header_t; | ||
|  | 
 | ||
|  | typedef struct { | ||
|  |     uint32_t packet_sz; | ||
|  |     uint8_t command; | ||
|  |     uint8_t result; | ||
|  |     field_header_t header; | ||
|  |     uint8_t data[]; | ||
|  | } test_packet_t; | ||
|  | 
 | ||
|  | typedef struct _flash_fmt { | ||
|  |     uint8_t type; | ||
|  |     uint32_t len; | ||
|  |     uint8_t *data; | ||
|  | } flash_fmt_t; | ||
|  | 
 | ||
|  | typedef struct _flash_burn_info { | ||
|  |     flash_fmt_t dir; | ||
|  |     flash_fmt_t name; | ||
|  |     flash_fmt_t bin; | ||
|  | } flash_burn_into_t; | ||
|  | 
 | ||
|  | #pragma pack(pop)
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //static uint8_t command_buf[COMMAND_MAX_SZ];
 | ||
|  | uint8_t *command_buf = (uint8_t *) RECV_START_ADDR; | ||
|  | uint8_t *check_buf = (uint8_t *) (RECV_START_ADDR +  RECV_MAX_SZ); | ||
|  | static size_t pos = 0; | ||
|  | flash_burn_into_t flash_burn = {0}; | ||
|  | uint8_t response_buf[512]; | ||
|  | 
 | ||
|  | static FILINFO fno; | ||
|  | static FATFS fs; | ||
|  | static FIL fp; | ||
|  | static uint8_t work[FF_MAX_SS]; | ||
|  | 
 | ||
|  | TCHAR file_name[128] = {0}; | ||
|  | 
 | ||
|  | void _process_test_file() | ||
|  | { | ||
|  |     FRESULT res; | ||
|  |     uint32_t i = 0; | ||
|  |     // get file name
 | ||
|  |     flash_fmt_t *name = &flash_burn.name; | ||
|  |     uint8_t *tmp = (uint8_t *) file_name; | ||
|  | 
 | ||
|  |     for(i = 0; i < name->len; i++) { | ||
|  |         *(tmp+i) = *(name->data + i); | ||
|  |     } | ||
|  |     *(tmp + i) = '\0'; | ||
|  |     iot_printf("[_process_test_file]: %s\n", file_name); | ||
|  | 
 | ||
|  |     // open file
 | ||
|  |     res = f_open(&fp, file_name, FA_OPEN_EXISTING | FA_READ); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_open failed, res: %d\n", res); | ||
|  |     } else { | ||
|  |         iot_printf("f_open result: %d\n", res); | ||
|  |     } | ||
|  | 
 | ||
|  |     UINT br; | ||
|  |     FSIZE_t size; | ||
|  |     flash_fmt_t *bin = &flash_burn.bin; | ||
|  |     // get file size
 | ||
|  |     size = f_size(&fp); | ||
|  |     iot_printf("size: %d\n", size); | ||
|  |     res = f_read(&fp, check_buf, size, &br); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_read failed, res: %d\n", res); | ||
|  |     } else { | ||
|  |         iot_printf("f_read result: %d\n", res); | ||
|  |         iot_printf("f_read len: %d\n", br); | ||
|  |         // compare size
 | ||
|  |         if (size != bin->len) { | ||
|  |             iot_printf("[error] size not match[%d - %d].\n", bin->len, size); | ||
|  |         } else { | ||
|  |             iot_printf("file %s size match\n", file_name); | ||
|  |             // compare data
 | ||
|  |             for(i = 0; i < size; i++) { | ||
|  |                 if (*(check_buf+i) != *(bin->data + i)) { | ||
|  |                     iot_printf("[error] data not macth: %d[%02x - %02x]\n", | ||
|  |                         i, *(check_buf+i), *(bin->data + i)); | ||
|  |                     break; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |     } | ||
|  | 
 | ||
|  |     f_close(&fp); | ||
|  | } | ||
|  | 
 | ||
|  | int _process_write_file() | ||
|  | { | ||
|  |     int ret = 0; | ||
|  |     FRESULT res; | ||
|  |     uint32_t i = 0; | ||
|  |     // get file name
 | ||
|  |     flash_fmt_t *name = &flash_burn.name; | ||
|  |     uint8_t *tmp = (uint8_t *) file_name; | ||
|  | 
 | ||
|  |     for(i = 0; i < name->len; i++) { | ||
|  |         *(tmp+i) = *(name->data + i); | ||
|  |     } | ||
|  |     *(tmp + i) = '\0'; | ||
|  |     iot_printf("[_process_write_file]: %s\n", file_name); | ||
|  | 
 | ||
|  |     // open file
 | ||
|  |     res = f_open(&fp, file_name, FA_OPEN_ALWAYS | FA_WRITE); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_open failed, res: %d\n", res); | ||
|  |         return -1; | ||
|  |     } else { | ||
|  |         iot_printf("f_open result: %d\n", res); | ||
|  |     } | ||
|  | 
 | ||
|  |     // write file
 | ||
|  |     UINT bw; | ||
|  |     flash_fmt_t *bin = &flash_burn.bin; | ||
|  |     res = f_write(&fp, bin->data, bin->len, &bw); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_write failed, res: %d, %d\n", res, bw); | ||
|  |         return -1; | ||
|  |     } else { | ||
|  |         iot_printf("f_write result: %d, %d\n", res, bw); | ||
|  |         if (bin->len != bw) { | ||
|  |             iot_printf("f_write size not match....\n"); | ||
|  |             ret = 0; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     // close file
 | ||
|  |     f_close(&fp); | ||
|  | 
 | ||
|  |     _process_test_file(); | ||
|  | 
 | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | int _process_flash_burn | ||
|  |     (test_packet_t *packet, test_packet_t *response, size_t buf_sz) | ||
|  | { | ||
|  |     uint8_t *buffer = NULL; | ||
|  |     flash_fmt_t *fmt = NULL; | ||
|  | 
 | ||
|  |     if (packet->header.field_len != 1) { | ||
|  |         // unknown format
 | ||
|  |         return -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (FIELD_FATFS == packet->header.field_type) { | ||
|  |         // check FATFS field
 | ||
|  |         if (FIELD_FLASH_BURN == packet->header.field_value) { | ||
|  |             // handle FIELD_FLASH_BURN fied value
 | ||
|  | 
 | ||
|  |             // get directory info
 | ||
|  |             buffer = (uint8_t *) (packet->data); | ||
|  |             fmt = (flash_fmt_t *) buffer; | ||
|  |             if (FMT_DIRECTORY == fmt->type) { | ||
|  |                 // directory
 | ||
|  |                 flash_burn.dir.type = fmt->type; | ||
|  |                 flash_burn.dir.len = fmt->len; | ||
|  |                 flash_burn.dir.data = (uint8_t *)(&fmt->data); | ||
|  |             } else { | ||
|  |                 // unknown format
 | ||
|  |                 return -1; | ||
|  |             } | ||
|  | 
 | ||
|  |             // get file name info
 | ||
|  |             buffer = buffer + flash_burn.dir.len + \ | ||
|  |                 sizeof(flash_burn.dir.type) + sizeof(flash_burn.dir.len); | ||
|  |             fmt = (flash_fmt_t *) buffer; | ||
|  |             if (FMT_FILENAME == fmt->type) { | ||
|  |                 // file name
 | ||
|  |                 flash_burn.name.type = fmt->type; | ||
|  |                 flash_burn.name.len = fmt->len; | ||
|  |                 flash_burn.name.data = (uint8_t *)(&fmt->data); | ||
|  |             } else { | ||
|  |                 // unknown format
 | ||
|  |                 return -1; | ||
|  |             } | ||
|  | 
 | ||
|  |             // get file bin info
 | ||
|  |             buffer = buffer + flash_burn.name.len + \ | ||
|  |                 sizeof(flash_burn.name.type) + sizeof(flash_burn.name.len); | ||
|  |             fmt = (flash_fmt_t *) buffer; | ||
|  |             if (FMT_FILEDATA == fmt->type) { | ||
|  |                 // file bin
 | ||
|  |                 flash_burn.bin.type = fmt->type; | ||
|  |                 flash_burn.bin.len = fmt->len; | ||
|  |                 flash_burn.bin.data = (uint8_t *)(&fmt->data); | ||
|  |                 return _process_write_file(); | ||
|  |             } else { | ||
|  |                 // unknown format
 | ||
|  |                 return -1; | ||
|  |             } | ||
|  |         } else { | ||
|  |             // unsupport filed value
 | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |     } else { | ||
|  |         // unsupport field
 | ||
|  |         return -2; | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | int | ||
|  | _process_packet(test_packet_t *packet, test_packet_t *response, size_t buf_sz) | ||
|  | { | ||
|  |     int ret = -1; | ||
|  | 
 | ||
|  |     if (ECDH == packet->command) { | ||
|  |         ret = -1; | ||
|  |     } else if (ECDSA == packet->command) { | ||
|  |         ret = -1; | ||
|  |     } else if (AES == packet->command) { | ||
|  |         ret = -1; | ||
|  |     } else if (FLASH == packet->command) { | ||
|  |         ret = _process_flash_burn(packet, response, buf_sz); | ||
|  |     } else { | ||
|  |         ret = -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | int | ||
|  | process_test_data(uint8_t byte, uint8_t *buf, size_t buf_sz, size_t * data_sz) | ||
|  | { | ||
|  |     int ret = -1; | ||
|  |     command_buf[pos] = byte; | ||
|  |     ++pos; | ||
|  | 
 | ||
|  |     if (pos >= RECV_MAX_SZ) { | ||
|  |         pos = 0; | ||
|  |         return -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (pos > sizeof(uint32_t)) { | ||
|  |         test_packet_t *response = (test_packet_t *)buf; | ||
|  |         test_packet_t *packet; | ||
|  |         packet = (test_packet_t*)command_buf; | ||
|  | 
 | ||
|  |         if ((pos % (10*1024)) == 0) { | ||
|  |             iot_printf("recv pos: %d\n", pos); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (pos >= packet->packet_sz) { | ||
|  |             iot_printf("recving size: %d\n", pos); | ||
|  |             ret = _process_packet(packet, response, buf_sz); | ||
|  |             *data_sz = response->packet_sz; | ||
|  |             pos = 0; | ||
|  |             return ret; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return -1; | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t | ||
|  | uart_send_data(const unsigned char *seq, unsigned int len) | ||
|  | { | ||
|  |     char c; | ||
|  |     int i = 0; | ||
|  |     while(i < len) { | ||
|  |         c = *(seq+i); | ||
|  |         uart_e_try_putc(0, c); | ||
|  |         i++; | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void init_fatfs() | ||
|  | { | ||
|  |     FRESULT res; | ||
|  |     res = f_mount(&fs, "0:", 1); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_mount failed, res: %d\n", res); | ||
|  | 
 | ||
|  |         // create fat volume, and format partitions
 | ||
|  |         iot_printf("{fatfs create fat volume}\n"); | ||
|  |         #if 1
 | ||
|  |         iot_printf("\n-- test make fs --\n"); | ||
|  |         res = f_mkfs("0:", FM_ANY, 0, work, sizeof(work)); | ||
|  |         if (res) { | ||
|  |             iot_printf("[error] f_mkfs failed, res: %d\n", res); | ||
|  |         } else { | ||
|  |             iot_printf("f_mkfs result: %d\n", res); | ||
|  |         } | ||
|  |         #endif
 | ||
|  |     } else { | ||
|  |         iot_printf("f_mount result: %d\n", res); | ||
|  |     } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void download_hw_init() | ||
|  | { | ||
|  |     //change CPU core to 150M.
 | ||
|  |     clk_core_freq_set(CPU_FREQ_150M); | ||
|  | 
 | ||
|  |     /* init uart */ | ||
|  |     dbg_uart_init(); | ||
|  | 
 | ||
|  |     ahb_cache_disable(); | ||
|  |     /* init cache */ | ||
|  |     ddr_cache_init(); | ||
|  |     // enable ahb cache
 | ||
|  |     ahb_cache_enable(); | ||
|  |     //enable dmc cache;
 | ||
|  |     ahb_dmc_cache_enable(); | ||
|  |     //cache space init;
 | ||
|  |     ahb_cache_fill_valid_space(); | ||
|  | 
 | ||
|  |     // init fatfs
 | ||
|  |     init_fatfs(); | ||
|  | } | ||
|  | 
 | ||
|  | void fatfs_dir_access() | ||
|  | { | ||
|  |     FRESULT res; | ||
|  |     DIR dp; | ||
|  | 
 | ||
|  |     // test directory function
 | ||
|  |     iot_printf("\n{fatfs directory access test}\n"); | ||
|  |     iot_printf("-- test get filename by directory --\n"); | ||
|  |     res = f_opendir(&dp, "0:/"); | ||
|  |     if (res) { | ||
|  |         iot_printf("[error] f_opendir failed, res: %d\n", res); | ||
|  |     } else { | ||
|  |         iot_printf("f_opendir result: %d\n", res); | ||
|  |     } | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         res = f_readdir(&dp, &fno); | ||
|  | 
 | ||
|  |         if (res != FR_OK || fno.fname[0] == 0) { | ||
|  |             break; | ||
|  |         } else { | ||
|  |             iot_printf("get file name: %s\n", fno.fname); | ||
|  |         } | ||
|  |     } | ||
|  |     f_closedir(&dp); | ||
|  |     iot_printf("= fatfs directory access test =\n"); | ||
|  | } | ||
|  | 
 | ||
|  | int main(void) | ||
|  | { | ||
|  | 
 | ||
|  |     download_hw_init(); | ||
|  | 
 | ||
|  |     fatfs_dir_access(); | ||
|  | 
 | ||
|  |     size_t data_sz = 0; | ||
|  | 
 | ||
|  |     int c; | ||
|  |     while(true) { | ||
|  |         c = uart_e_getc(0); | ||
|  |         if (c >= 0) { | ||
|  |             if (0 == process_test_data | ||
|  |                 (c & 0xFF, response_buf,sizeof(response_buf), &data_sz)) { | ||
|  |                 iot_printf("Transform successfully...\n"); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     return 0; | ||
|  | } |