/** ########################################################################## ** Filename : ** Project : ** Module : ** Processor : ** Version : 1.0 ** Compiler : ** Date/Time : ** Abstract : ** Contents : ** Note : 此文档用于规范代码书写; * 注意, * 1.所有文件用UTF-8格式 * 2.tab键空格4个 * 3.各模块,都要有 初始化函数 init, 反初始化函数 deinit, * 周期任务task,进入休眠goto sleep, * 唤醒后 goto wake ,判断是否可休眠judge_pre_sleep 等主要函数接口 * 4. ** ** (c) Copyright dmdz Co.,Ltd ** -------------------------------------------------------------------------- ** R E V I S I O N H I S T O R Y ** -------------------------------------------------------------------------- ** Date Ver Author Description ** -20191106- --V01-- --LYJ--- --初版-- ** -20230602- --V1.0-- --mingyea--- --修改-- ** #########################################################################*/ /*--------------------------------------------------------------------------- - I N C L U D E F I L E S ----------------------------------------------------------------------------*/ #include "uartapp.h" #include "stdio.h" #include "norflash.h" #include "hardware.h" #include "bootapp.h" #include /*--------------------------------------------------------------------------- - D E F I N E S / M A C R O S ----------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- - T Y P E D E F I N I T I O N S ----------------------------------------------------------------------------*/ typedef enum { UARTAPP_INIT=0, UARTAPP_IDLE, UARTAPP_RXCMD, UARTAPP_RXSPIDATA, UARTAPP_STOPRX, UARTAPP_CRC, UARTAPP_STATENUM, }uartapp_mainstate_type; typedef enum { CMD31_Idle, CMD31_Erase, CMD31_ReqDownload, CMD31_WriteCRC, CMD31_MapMode, CMD31_CRC, CMD31_QuitMapMode, CMD31_MapModeTest, CMD31_NUM, }CMD31_type; /*--------------------------------------------------------------------------- - S T A T I C V A R I A B L E S ----------------------------------------------------------------------------*/ static uartapp_mainstate_type task_state; static uint8_t rxCpltFlag = 0,idleReqFlag=0,downloadReqFlag=0; static uint8_t rxbuf[512]; static uint16_t rxsize = 0,timeout_count=0; static uint32_t writeaddr = 0; /*--------------------------------------------------------------------------- * G L O B A L V A R I A B L E S ----------------------------------------------------------------------------*/ extern UART_HandleTypeDef huart1; extern uint32_t delaytest; extern uint8_t mapModeFlag; extern CRC_HandleTypeDef hcrc; /*--------------------------------------------------------------------------- - C O N S T A N T S ----------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- - F U N C T I O N P R O T O T Y P E ----------------------------------------------------------------------------*/ static void uartapp_cmdpro(uint8_t *data,uint16_t len); static void uartapp_cmd31(uint8_t *data,uint16_t len); //重定向,用于printf #if __GNUC__ int _write(int fd, char *ptr, int len) { (void)fd; //toggle_led(); // 这里测试是否走通 HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY); return len; } #else int __write(int handle, char *buf, int size) { if (handle == 1 || handle == 2) { // stdout 或 stderr HAL_UART_Transmit(&huart1, (uint8_t *)buf, size, HAL_MAX_DELAY); return size; } return -1; } #endif void crc_calc_init(void) { HAL_CRCEx_Polynomial_Set(&hcrc,0x1D,CRC_POLYLENGTH_8B); } uint32_t crc_calc(uint32_t addr,uint32_t len) { len = (len>>2); uint32_t crc = HAL_CRC_Calculate(&hcrc,(uint32_t*)addr,len); return (crc^0xffffffff); } void uartapp_init(void) { setvbuf(stdout, NULL, _IONBF, 0); // 禁用 stdout 缓冲,printf 立即输出 task_state = UARTAPP_INIT; } static void maintask_gotoidle(void) { task_state = UARTAPP_IDLE; HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rxbuf,512); rxCpltFlag = 0; rxsize = 0; timeout_count=0; } void uartapp_maintask(void) { switch (task_state) { case UARTAPP_INIT: __HAL_DMA_DISABLE_IT(huart1.hdmarx, DMA_IT_HT); maintask_gotoidle(); break; case UARTAPP_IDLE: if (rxCpltFlag == 1) { task_state = UARTAPP_RXCMD; timeout_count = 0; } timeout_count++; if (timeout_count > 5000) { maintask_gotoidle(); //HAL_UART_Transmit(&huart1,txbuf,3,1000); } break; case UARTAPP_RXCMD: if (rxbuf[0]==0x55 && rxbuf[1]==0xaa && rxsize > 3) { uartapp_cmdpro(rxbuf+2,rxsize-2); } else { printf("err rxsize=%d\n",rxsize); } if (downloadReqFlag == 1) { downloadReqFlag = 0; task_state = UARTAPP_RXSPIDATA; printf("wait spiflash data\n"); rxCpltFlag = 0; rxsize = 0; HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rxbuf,512); timeout_count = 0; } else { maintask_gotoidle(); } break; case UARTAPP_RXSPIDATA: timeout_count++; if (rxCpltFlag == 1) { timeout_count = 0; delaytest = 0; if (rxsize > 0) { NORFLASH_Write_NoCheck(rxbuf,writeaddr,rxsize); printf("write 0x%06X,0x%03X,delay %lu\n",writeaddr,rxsize,delaytest); } HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rxbuf,512); rxCpltFlag = 0; writeaddr += rxsize; rxsize = 0; } if (timeout_count > 5000) { maintask_gotoidle(); printf("rx timeout\n"); } if (idleReqFlag == 1) { idleReqFlag = 0; maintask_gotoidle(); printf("idleReqFlag=1\n"); } break; default: break; } } void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART1) { rxCpltFlag = 1; rxsize = Size; toggle_led(); } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { //rxCpltFlag = 1; //toggle_led(); //rxsize = 0xFF; //HAL_UART_Transmit(&huart1,txbuf,3,1000); } } static void uartapp_cmdpro(uint8_t *data,uint16_t len) { switch (data[0])//sid { case 0x31: uartapp_cmd31(data+1,len-1); break; default: break; } } static void uartapp_cmd31(uint8_t *data,uint16_t len) { if (len < 1) { return; } CMD31_type subid = data[0]; switch (subid) { case CMD31_Idle: idleReqFlag = 1; break; case CMD31_Erase: if (mapModeFlag == 0) { if (len >= 2) { bootApp_ReqErase(data[1]); } else { bootApp_ReqErase(0); } printf("start erase\n"); } break; case CMD31_ReqDownload: writeaddr = 0x100; downloadReqFlag = 1; break; case CMD31_CRC: uint32_t localcrc = 0,locallen = 0; if (ReadCRCInfo(&locallen,&localcrc)) { delaytest = 0; uint32_t starttime = SysTick->VAL; uint32_t crcvalue = crc_calc(EX_FLASH_APPINFO_ADDR,locallen); uint32_t endtime = (SysTick->VAL); uint32_t usedtime = delaytest*(SysTick->LOAD + 1) + endtime - starttime; printf("crc= %08lX,time=%ld\n",crcvalue,usedtime); printf("starttime= %ld,endtime=%ld,delaytest=%ld\n",starttime,endtime,delaytest); if (crcvalue == localcrc) { printf("crc ok\n"); } else { printf("crc err\n"); } } else { printf("no crc info\n"); } //crcReqFlag = 1; break; case CMD31_MapMode: NORFLASH_MemroyMapMode(); printf("mapmode\n"); break; case CMD31_QuitMapMode: NORFLASH_QuitMemroyMapMode(); break; case CMD31_MapModeTest: norflash_test(); break; case CMD31_WriteCRC: if (len == 9) { uint32_t datalen = (data[1]<<24) | (data[2]<<16) | (data[3]<<8) | data[4]; uint32_t crc = (data[5]<<24) | (data[6]<<16) | (data[7]<<8) | data[8]; WriteCRCInfo(datalen, crc); printf("write crc ok\n"); } else { printf("err len\n"); } break; default: break; } }