|
- /************************************************************************
- * 模块名称:com.c
- * 程序功能:
- * 编 写 者:
- * 编写日期:2017-06-22
- * 修 改 者:
- * 修改日期:
- * 编译环境:KEIL4 MDK ARM V4.74
- * 硬件平台:STM32F103ZCT6
- ************************************************************************/
- /************************************************************************/
- /* */
- /* INCLUDES */
- /* */
- /************************************************************************/
- #include <stm32f10x.h>
- #include <stm32f10x_dma.h>
- #include <string.h>
- #include <stdio.h>
- #include "stm32f10x.h"
- #include "stm32f10x_usart.h"
- #include "stm32f10x_it.h"
- #include "com.h"
- #include "share.h"
- #include "crc.h"
-
- /************************************************************************/
- /* */
- /* DEFINITION */
- /* */
- /************************************************************************/
-
-
- /************************************************************************/
- /* */
- /* DECLARATION */
- /* */
- /************************************************************************/
- void delay_ms(uint32_t time);
- void ymodem_fun(void);
- uint8_t Get_state(void);
- uint8_t Dma_send_data(uint8_t *pdata, uint8_t len);
-
- /************************************************************************/
- /* */
- /* VARIABLE */
- /* */
- /************************************************************************/
- u8 m_SerialSendState = RS_SEND_IDLE;
- u8 m_SerialSendPos = 0;
- u8 m_SerialSendLen = 0;
- u8 m_SerialSendBuffer[RS232_MAX_PARAM_LENGTH];
-
- u8 m_SerialRecvState = RS_RECV_IDLE;
- u8 m_SerialRecvLen = 0;
- u8 m_SerialRecvPos = 0;
- u8 m_SerialRecvBuffer[Re_MAX_PARAM_LENGTH];
- u8 m_SerialRecvTransfer[Re_MAX_PARAM_LENGTH];
-
- u16 UpdateCodeData[STM_SECTOR_SIZE/2] ={0}; //1024个半字
- u16 CompareaData[STM_SECTOR_SIZE/2] ={0}; //1024个半字
-
- u32 addrCur = APPLICATION_PROGRAM_ADDRESS; //当前写入地址
- u32 addrSave = APPLICATION_UPDCODE_ADDRESS; //STM32_FLASH_BASE + (STM32_FLASH_SIZE - BACKUP_CODE_CACHE_SIZE) * 1024; //串口数据保存地址 0x08000000 + (256 - 50)*1024
- //u32 RecordAdd;
-
-
- u16 i = 0;
- u8 SectorNum = 0;//扇区数
- u16 m_ReceiveDataCurNum = 0;
- u16 m_ReceiveCodeDataU16 = 0;
- u16 m_IAPDateByteTotalSize = 0; //数据总位数
- u8 m_IAPDatePackageTotalSize = 0; //数据总包数
- u8 m_IAPDatePackageEND = 0; //已经传输完成的包数
-
- u8 m_finish = 0;
-
- u8 g_IAPCommondFlag = 0; //g_skip
- u8 CompareFlag = 1; //
- u8 Rewrite=3;
-
- uint8_t Rx_Flag = 0;
- //uint8_t Rx_Len = 0;
- //static u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];
- uint32_t last_upd_ticks = 0;
- /***********************************************************************/
-
-
-
- /************************************************************************/
- /* */
- /* IMPLEMENTATION */
- /* */
- /************************************************************************/
- uint8_t CheckAddSum(uint8_t *pdata, uint8_t len)
- {
- uint16_t sum = 0, i = 0;
- for(i = 0; i<len; i++) {
- sum+=pdata[i];
- }
- return (sum&0xff);
- }
- uint8_t IsDevCommandFrame(uint8_t *pdata, uint8_t len)
- {
- if( len == CMD_UPD_FRAME_LEN && pdata[0] == CMD_FRAME_HEADER && pdata[1] == CMD_UPD_FRAME_LEN
- && pdata[CMD_UPD_FRAME_LEN - 1] == CheckAddSum(pdata, CMD_UPD_FRAME_LEN-1)) {
- return 1;
- }
- return 0;
- }
- uint8_t Dma_send_data(uint8_t *pdata, uint8_t len)
- {
- /* while(USART_TX_FLAG); //等待上一次发送完成(USART2_TX_FLAG为1即还在发送数据)
- USART_TX_FLAG=1; //USART2发送标志(启动发送)
- USART_DMA_CHANNEL_TX->CMAR = (uint32_t)pdata; //设置要发送的数据地址
- USART_DMA_CHANNEL_TX->CNDTR = len; //设置要发送的字节数目
- DMA_Cmd(USART_DMA_CHANNEL_TX, ENABLE); //开始DMA发送
- */
- while (DMA_GetCurrDataCounter(USART_DMA_CHANNEL_TX));// 检查DMA发送通道内是否还有数据,等待发送完成
- if(!len) return 0;// 判断长度是否有效
- if(pdata==NULL) return 0;
- memcpy(Dma_Tx_Buffer, pdata,len);
- //DMA发送数据-要先关 设置发送长度 开启DMA
- DMA_Cmd(USART_DMA_CHANNEL_TX, DISABLE);
- USART_DMA_CHANNEL_TX->CNDTR = len;// 设置发送长度
- DMA_Cmd(USART_DMA_CHANNEL_TX, ENABLE); // 启动DMA发送
- return len;
- }
-
- void DMA2_Channel3_IRQHandler(void)
- {
- //USART_PutStr(USART1," DMA23:rn",9);
- DMA_ClearITPendingBit(DMA2_IT_TC3);
- DMA_ClearITPendingBit(DMA2_IT_TE3);
-
- DMA_Cmd(DMA2_Channel3, DISABLE); //关闭DMA,防止处理其间有数据
-
- DMA2_Channel3->CNDTR = DMA_RECV_BUF_SIZE; //重装填, for receiving
-
- DMA_Cmd(DMA2_Channel3, ENABLE); //处理完,重开DMA
- }
- void DMA2_Channel4_5_IRQHandler(void)
- {
- //USART_PutStr(USART1," DMA245:rn",9);
- DMA_ClearITPendingBit(DMA2_IT_TC5);
- DMA_ClearITPendingBit(DMA2_IT_TE5);
-
- DMA_Cmd(DMA2_Channel5, DISABLE); //关闭DMA,防止处理其间有数据
-
- DMA2_Channel5->CNDTR = 0; //重装填, for sending
-
- DMA_Cmd(DMA2_Channel5, ENABLE); //处理完,重开DMA
- }
- /***********************************************************************
- * 函 数 名: USART1_IRQHandler()
- * 功能描述: 系统
- * 函数说明:
- * 输 入: 无
- * 返 回:
- * 设 计 者:CYL 日期:2015-05-01
- * 修 改 者:CYL 日期:2015-05-01
- ***********************************************************************/
- void UART4_IRQHandler(void)
- {
- uint16_t data_len, i;
-
- //idle中断
- if(USART_GetITStatus(USART_NUM, USART_IT_IDLE) != RESET)
- {
- //清除状态寄存器和串口数据寄存器 // __HAL_UART_CLEAR_IDLEFLAG(&huart2); //
- data_len =USART_NUM->SR;
- data_len =USART_NUM->DR;
- //关闭DMA
- DMA_Cmd(USART_DMA_CHANNEL_RX, DISABLE);
- //读取接收buffer的数据
- data_len = DMA_RECV_BUF_SIZE - DMA_GetCurrDataCounter(USART_DMA_CHANNEL_RX);
- for (i = 0;i < data_len; i++)
- {
- m_SerialRecvBuffer[i]= Dma_Rx_Buffer[i];
- m_SerialRecvPos = i;
- }
- m_SerialRecvLen = data_len;
- //
- DMA_ClearFlag(USART_DMA_RX_CLR_FLAGS);
- //设置传输数据长度
- DMA_SetCurrDataCounter(USART_DMA_CHANNEL_RX, DMA_RECV_BUF_SIZE); //USART_DMA_CHANNEL_RX->CNDTR = DMA_RECV_BUF_SIZE;
- //打开DMA
- DMA_Cmd(USART_DMA_CHANNEL_RX, ENABLE);
- USART_ClearITPendingBit(USART_NUM, USART_IT_IDLE);
-
- if(m_SerialRecvState != RS_RECV_COMPLETE) //RecvTemp==m_SerialRecvBuffer[0]
- {
- Rx_Flag = 0;
- if(IsDevCommandFrame(m_SerialRecvBuffer, m_SerialRecvLen)) //command frame
- {
- if(m_SerialRecvBuffer[2] == CMD_DEV_UPDATE) { //update command
- Dma_send_data(m_SerialRecvBuffer, m_SerialRecvLen); //ack-update-
- delay_ms(5); //5ms
- m_SerialRecvState = RS_RECV_COMPLETE;
- g_IAPCommondFlag = 1;
- last_upd_ticks = g_SysTick;
- }
- }
- /* else if(m_SerialRecvBuffer[0] == 0x53 && m_SerialRecvPos == 0x08 && m_SerialRecvBuffer[7] == CheckCrc(&m_SerialRecvBuffer[2],5))
- {
- m_SerialRecvState = RS_RECV_COMPLETE;
- g_IAPCommondFlag = 1;
- }
- */
- else {
- m_SerialRecvPos = 0;
- m_SerialRecvLen = 0;
- m_SerialRecvState = RS_RECV_IDLE;
- }
- }
- else //if(m_SerialRecvState == RS_RECV_COMPLETE)
- {
- Rx_Flag = 1;
- }
- }
- }
- /***********************************************************************
- * 函 数 名: DFL_SerialInit()
- * 功能描述:
- * 函数说明:
- * 输 入: 无
- * 返 回:
- * 设 计 者:CYL 日期:2015-05-23
- * 修 改 者:CYL 日期:2015-05-23
- ***********************************************************************/
- void DFL_SerialInit(void)
- {
- m_SerialSendState = RS_SEND_IDLE;
- m_SerialSendLen = 0;
- m_SerialSendPos = 0;
-
- m_SerialRecvState = RS_RECV_IDLE;
- m_SerialRecvLen = 0;
- m_SerialRecvPos = 0;
-
- //DEBUG FOR UPDATE
- //m_SerialRecvState = RS_RECV_COMPLETE; //wangqy-debug
- //g_IAPCommondFlag = 1; //
-
- return;
- }
-
-
- /***********************************************************************
- * 函 数 名: AFL_SerialTask()
- * 功能描述:
- * 函数说明:
- * 输 入: 无
- * 返 回:
- * 设 计 者:TNT 日期:2015-05-01
- * 修 改 者:CYL 日期:2015-05-01
- ***********************************************************************/
- void AFL_SerialTask(void)
- {
- if(m_SerialRecvState != RS_RECV_COMPLETE)
- {
- return;
- }
- ymodem_fun();
- if(CompareFlag == 0) {
- g_IAPCommondFlag = 9; //update-error, stop
- }
- }
-
- ///////////Ymodem-transmission//////////////////////////////////////////////////////
- #define YMODEM_DATA_LEN 128
-
- /**
- * @bieaf CRC-16 校验
- *
- * @param addr 开始地址
- * @param num 长度
- * @param num CRC
- * @return crc 返回CRC的值
- */
- #define POLY 0x1021
- uint16_t crc16(unsigned char *addr, int num, uint16_t crc)
- {
- int i;
- for (; num > 0; num--) /* Step through bytes in memory */
- {
- crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/
- for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */
- {
- if (crc & 0x8000) /* b15 is set... */
- crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */
- else /* b15 is clear... */
- crc <<= 1; /* just rotate */
- } /* Loop for 8 bits */
- crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */
- } /* Loop until num=0 */
- return(crc); /* Return updated CRC */
- }
-
-
-
- /**
- * @bieaf 获取数据包的类型, 顺便进行校验
- *
- * @param buf 开始地址
- * @param len 长度
- * @return
- */
- unsigned char Check_CRC(unsigned char* buf, int len)
- {
- unsigned short crc = 0;
-
- /* 进行CRC校验 */
- if((buf[0]==SOH)&&(len >= YMODEM_DATA_LEN+5)) //YMODEM_DATA_LEN=128
- {
- crc = crc16(buf+3, YMODEM_DATA_LEN, crc);
- if(crc != (buf[YMODEM_DATA_LEN+3]<<8|buf[YMODEM_DATA_LEN+4]))
- {
- return 0;///< 没通过校验
- }
-
- /* 通过校验 */
- return 1;
- }
- return 0;
- }
-
-
-
- /* 设置升级的步骤 */
- static enum UPDATE_STATE update_state = TO_START;
- void Set_state(enum UPDATE_STATE state)
- {
- update_state = state;
- }
-
-
- /* 查询升级的步骤 */
- uint8_t Get_state(void)
- {
- return update_state;
- }
- void delay_ms(uint32_t time)
- {
- /*uint32_t target_ticks = g_SysTick+time;
- while(target_ticks < g_SysTick) {
- int i = 1;
- }*/
- u16 i=0;
- while(time--)
- {
- i=12000; //????
- while(i--) ;
- }
- }
- /* 发送指令 */
- void send_command(uint8_t command)
- {
- Dma_send_data(&command, 1);
- delay_ms(3);
- //HAL_UART_Transmit(&huart2, (uint8_t *)&command,1, 0xFFFF);
- //HAL_Delay(10);
- }
-
-
- uint8_t temp_buf[256] = {0};
- uint8_t temp_len = 0;
-
- /**
- * @bieaf YModem升级
- *
- * @param none
- * @return none
- */
- void ymodem_fun(void)
- {
- static uint8_t data_state = 0;
- int i;
- if(Get_state()==TO_START)
- {
- send_command(CCC);
- delay_ms(1000);
- }
- if(Rx_Flag) // Receive flag
- {
- Rx_Flag=0; // clean flag
-
- /* 拷贝 */
- temp_len = m_SerialRecvLen;
- for(i = 0; i < temp_len; i++)
- {
- temp_buf[i] = m_SerialRecvBuffer[i];
- }
-
- switch(temp_buf[0])
- {
- case SOH:///<数据包开始
- {
- //static unsigned int app2_size = 0;
- if(Check_CRC(temp_buf, temp_len)==1)///< 通过CRC16校验
- {
- if((Get_state()==TO_START)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 开始
- {
- printf("> Receive start...\r\n");
-
- Set_state(TO_RECEIVE_DATA);
- data_state = 0x01; //init data-index
- send_command(ACK);
- send_command(CCC);
-
- /* 擦除App2 */
- DHL_STMFlash_Erase(APPLICATION_UPDCODE_ADDRESS, BACKUP_CODE_CACHE_SIZE/2);
- last_upd_ticks = g_SysTick;
- }
- else if((Get_state()==TO_RECEIVE_END)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 结束
- {
- printf("> Receive end...\r\n");
- CompareFlag = 1; //ok, if not write to flash
- if(m_ReceiveDataCurNum > 0) //LAST页就写
- {
- for (i=m_ReceiveDataCurNum; i<STM_SECTOR_SIZE/2; i++) {
- UpdateCodeData[i] = 0xffff;
- }
- for(i=0; i<Rewrite; i++)
- {
- DHL_STMFlash_Write(addrSave,UpdateCodeData,STM_SECTOR_SIZE/2);
- DHL_STMFlash_Read(addrSave, CompareaData,STM_SECTOR_SIZE/2);
- CompareFlag = DHL_CompareBuffer(UpdateCodeData,CompareaData,STM_SECTOR_SIZE/2);
- if(CompareFlag == 1) //write ok
- {
- m_ReceiveDataCurNum=0;
- break;
- }
- }
- }
- if(CompareFlag == 1) { //write ok
- AFL_Write_StartMode(Startup_Update);
- //Set_state(TO_START);
- send_command(ACK);
- //System_SoftReset(); //system reset
- last_upd_ticks = g_SysTick;
- g_IAPCommondFlag = 2; //update-end, stop
- }
- }
- else if((Get_state()==TO_RECEIVE_DATA)&&(temp_buf[1] == data_state)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 接收数据
- {
- printf("> Receive data bag:%d byte\r\n",data_state * YMODEM_DATA_LEN); //YMODEM_DATA_LEN=128
- for(i=0; i<YMODEM_DATA_LEN; i+=2)
- {
- m_ReceiveCodeDataU16= ((((u16)temp_buf[i+4])<<8) | ((u16)temp_buf[i+3]));
- UpdateCodeData[m_ReceiveDataCurNum++] = m_ReceiveCodeDataU16;
- }
- CompareFlag = 1; //ok, if not write to flash
- if(m_ReceiveDataCurNum == STM_SECTOR_SIZE/2) //满一页就写
- {
- for(i=0; i<Rewrite; i++)
- {
- DHL_STMFlash_Write(addrSave,UpdateCodeData,STM_SECTOR_SIZE/2);
- DHL_STMFlash_Read(addrSave, CompareaData,STM_SECTOR_SIZE/2);
- CompareFlag = DHL_CompareBuffer(UpdateCodeData,CompareaData,STM_SECTOR_SIZE/2);
- if(CompareFlag == 1) //write ok
- {
- addrSave+= STM_SECTOR_SIZE;
- m_ReceiveDataCurNum=0;
- break;
- }
- }
- }
- /* 烧录程序 */
- //WriteFlash((Application_2_Addr + (data_state-1) * 128), (uint32_t *)(&temp_buf[3]), 32);
- if(CompareFlag == 1) { // write ok
- data_state++;
- send_command(ACK);
- }
- }
- }
- else
- {
- printf("> Notpass crc\r\n");
- }
-
- }break;
- case EOT://数据包 end of transmission
- {
- if(Get_state()==TO_RECEIVE_DATA)
- {
- printf("> Receive EOT1...\r\n");
-
- Set_state(TO_RECEIVE_EOT2);
- send_command(NACK);
- }
- else if(Get_state()==TO_RECEIVE_EOT2)
- {
- printf("> Receive EOT2...\r\n");
-
- Set_state(TO_RECEIVE_END);
- send_command(ACK);
- send_command(CCC);
- }
- else
- {
- printf("> Receive EOT, But error...\r\n");
- }
- }break;
- }
- }
- }
- /******************* (C) COPYRIGHT 2017 LECOOAI *****END OF FILE****/
|