老版本GCU
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

509 行
15 KiB

  1. /************************************************************************
  2. * 模块名称:com.c
  3. * 程序功能:
  4. * 编 写 者:
  5. * 编写日期:2017-06-22
  6. * 修 改 者:
  7. * 修改日期:
  8. * 编译环境:KEIL4 MDK ARM V4.74
  9. * 硬件平台:STM32F103ZCT6
  10. ************************************************************************/
  11. /************************************************************************/
  12. /* */
  13. /* INCLUDES */
  14. /* */
  15. /************************************************************************/
  16. #include <stm32f10x.h>
  17. #include <stm32f10x_dma.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include "stm32f10x.h"
  21. #include "stm32f10x_usart.h"
  22. #include "stm32f10x_it.h"
  23. #include "com.h"
  24. #include "share.h"
  25. #include "crc.h"
  26. /************************************************************************/
  27. /* */
  28. /* DEFINITION */
  29. /* */
  30. /************************************************************************/
  31. /************************************************************************/
  32. /* */
  33. /* DECLARATION */
  34. /* */
  35. /************************************************************************/
  36. void delay_ms(uint32_t time);
  37. void ymodem_fun(void);
  38. uint8_t Get_state(void);
  39. uint8_t Dma_send_data(uint8_t *pdata, uint8_t len);
  40. /************************************************************************/
  41. /* */
  42. /* VARIABLE */
  43. /* */
  44. /************************************************************************/
  45. u8 m_SerialSendState = RS_SEND_IDLE;
  46. u8 m_SerialSendPos = 0;
  47. u8 m_SerialSendLen = 0;
  48. u8 m_SerialSendBuffer[RS232_MAX_PARAM_LENGTH];
  49. u8 m_SerialRecvState = RS_RECV_IDLE;
  50. u8 m_SerialRecvLen = 0;
  51. u8 m_SerialRecvPos = 0;
  52. u8 m_SerialRecvBuffer[Re_MAX_PARAM_LENGTH];
  53. u8 m_SerialRecvTransfer[Re_MAX_PARAM_LENGTH];
  54. u16 UpdateCodeData[STM_SECTOR_SIZE/2] ={0}; //1024个半字
  55. u16 CompareaData[STM_SECTOR_SIZE/2] ={0}; //1024个半字
  56. u32 addrCur = APPLICATION_PROGRAM_ADDRESS; //当前写入地址
  57. u32 addrSave = APPLICATION_UPDCODE_ADDRESS; //STM32_FLASH_BASE + (STM32_FLASH_SIZE - BACKUP_CODE_CACHE_SIZE) * 1024; //串口数据保存地址 0x08000000 + (256 - 50)*1024
  58. //u32 RecordAdd;
  59. u16 i = 0;
  60. u8 SectorNum = 0;//扇区数
  61. u16 m_ReceiveDataCurNum = 0;
  62. u16 m_ReceiveCodeDataU16 = 0;
  63. u16 m_IAPDateByteTotalSize = 0; //数据总位数
  64. u8 m_IAPDatePackageTotalSize = 0; //数据总包数
  65. u8 m_IAPDatePackageEND = 0; //已经传输完成的包数
  66. u8 m_finish = 0;
  67. u8 g_IAPCommondFlag = 0; //g_skip
  68. u8 CompareFlag = 1; //
  69. u8 Rewrite=3;
  70. uint8_t Rx_Flag = 0;
  71. //uint8_t Rx_Len = 0;
  72. //static u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];
  73. uint32_t last_upd_ticks = 0;
  74. /***********************************************************************/
  75. /************************************************************************/
  76. /* */
  77. /* IMPLEMENTATION */
  78. /* */
  79. /************************************************************************/
  80. uint8_t CheckAddSum(uint8_t *pdata, uint8_t len)
  81. {
  82. uint16_t sum = 0, i = 0;
  83. for(i = 0; i<len; i++) {
  84. sum+=pdata[i];
  85. }
  86. return (sum&0xff);
  87. }
  88. uint8_t IsDevCommandFrame(uint8_t *pdata, uint8_t len)
  89. {
  90. if( len == CMD_UPD_FRAME_LEN && pdata[0] == CMD_FRAME_HEADER && pdata[1] == CMD_UPD_FRAME_LEN
  91. && pdata[CMD_UPD_FRAME_LEN - 1] == CheckAddSum(pdata, CMD_UPD_FRAME_LEN-1)) {
  92. return 1;
  93. }
  94. return 0;
  95. }
  96. uint8_t Dma_send_data(uint8_t *pdata, uint8_t len)
  97. {
  98. /* while(USART_TX_FLAG); //等待上一次发送完成(USART2_TX_FLAG为1即还在发送数据)
  99. USART_TX_FLAG=1; //USART2发送标志(启动发送)
  100. USART_DMA_CHANNEL_TX->CMAR = (uint32_t)pdata; //设置要发送的数据地址
  101. USART_DMA_CHANNEL_TX->CNDTR = len; //设置要发送的字节数目
  102. DMA_Cmd(USART_DMA_CHANNEL_TX, ENABLE); //开始DMA发送
  103. */
  104. while (DMA_GetCurrDataCounter(USART_DMA_CHANNEL_TX));// 检查DMA发送通道内是否还有数据,等待发送完成
  105. if(!len) return 0;// 判断长度是否有效
  106. if(pdata==NULL) return 0;
  107. memcpy(Dma_Tx_Buffer, pdata,len);
  108. //DMA发送数据-要先关 设置发送长度 开启DMA
  109. DMA_Cmd(USART_DMA_CHANNEL_TX, DISABLE);
  110. USART_DMA_CHANNEL_TX->CNDTR = len;// 设置发送长度
  111. DMA_Cmd(USART_DMA_CHANNEL_TX, ENABLE); // 启动DMA发送
  112. return len;
  113. }
  114. void DMA2_Channel3_IRQHandler(void)
  115. {
  116. //USART_PutStr(USART1," DMA23:rn",9);
  117. DMA_ClearITPendingBit(DMA2_IT_TC3);
  118. DMA_ClearITPendingBit(DMA2_IT_TE3);
  119. DMA_Cmd(DMA2_Channel3, DISABLE); //关闭DMA,防止处理其间有数据
  120. DMA2_Channel3->CNDTR = DMA_RECV_BUF_SIZE; //重装填, for receiving
  121. DMA_Cmd(DMA2_Channel3, ENABLE); //处理完,重开DMA
  122. }
  123. void DMA2_Channel4_5_IRQHandler(void)
  124. {
  125. //USART_PutStr(USART1," DMA245:rn",9);
  126. DMA_ClearITPendingBit(DMA2_IT_TC5);
  127. DMA_ClearITPendingBit(DMA2_IT_TE5);
  128. DMA_Cmd(DMA2_Channel5, DISABLE); //关闭DMA,防止处理其间有数据
  129. DMA2_Channel5->CNDTR = 0; //重装填, for sending
  130. DMA_Cmd(DMA2_Channel5, ENABLE); //处理完,重开DMA
  131. }
  132. /***********************************************************************
  133. * 函 数 名: USART1_IRQHandler()
  134. * 功能描述: 系统
  135. * 函数说明:
  136. * 输 入: 无
  137. * 返 回:
  138. * 设 计 者:CYL 日期:2015-05-01
  139. * 修 改 者:CYL 日期:2015-05-01
  140. ***********************************************************************/
  141. void UART4_IRQHandler(void)
  142. {
  143. uint16_t data_len, i;
  144. //idle中断
  145. if(USART_GetITStatus(USART_NUM, USART_IT_IDLE) != RESET)
  146. {
  147. //清除状态寄存器和串口数据寄存器 // __HAL_UART_CLEAR_IDLEFLAG(&huart2); //
  148. data_len =USART_NUM->SR;
  149. data_len =USART_NUM->DR;
  150. //关闭DMA
  151. DMA_Cmd(USART_DMA_CHANNEL_RX, DISABLE);
  152. //读取接收buffer的数据
  153. data_len = DMA_RECV_BUF_SIZE - DMA_GetCurrDataCounter(USART_DMA_CHANNEL_RX);
  154. for (i = 0;i < data_len; i++)
  155. {
  156. m_SerialRecvBuffer[i]= Dma_Rx_Buffer[i];
  157. m_SerialRecvPos = i;
  158. }
  159. m_SerialRecvLen = data_len;
  160. //
  161. DMA_ClearFlag(USART_DMA_RX_CLR_FLAGS);
  162. //设置传输数据长度
  163. DMA_SetCurrDataCounter(USART_DMA_CHANNEL_RX, DMA_RECV_BUF_SIZE); //USART_DMA_CHANNEL_RX->CNDTR = DMA_RECV_BUF_SIZE;
  164. //打开DMA
  165. DMA_Cmd(USART_DMA_CHANNEL_RX, ENABLE);
  166. USART_ClearITPendingBit(USART_NUM, USART_IT_IDLE);
  167. if(m_SerialRecvState != RS_RECV_COMPLETE) //RecvTemp==m_SerialRecvBuffer[0]
  168. {
  169. Rx_Flag = 0;
  170. if(IsDevCommandFrame(m_SerialRecvBuffer, m_SerialRecvLen)) //command frame
  171. {
  172. if(m_SerialRecvBuffer[2] == CMD_DEV_UPDATE) { //update command
  173. Dma_send_data(m_SerialRecvBuffer, m_SerialRecvLen); //ack-update-
  174. delay_ms(5); //5ms
  175. m_SerialRecvState = RS_RECV_COMPLETE;
  176. g_IAPCommondFlag = 1;
  177. last_upd_ticks = g_SysTick;
  178. }
  179. }
  180. /* else if(m_SerialRecvBuffer[0] == 0x53 && m_SerialRecvPos == 0x08 && m_SerialRecvBuffer[7] == CheckCrc(&m_SerialRecvBuffer[2],5))
  181. {
  182. m_SerialRecvState = RS_RECV_COMPLETE;
  183. g_IAPCommondFlag = 1;
  184. }
  185. */
  186. else {
  187. m_SerialRecvPos = 0;
  188. m_SerialRecvLen = 0;
  189. m_SerialRecvState = RS_RECV_IDLE;
  190. }
  191. }
  192. else //if(m_SerialRecvState == RS_RECV_COMPLETE)
  193. {
  194. Rx_Flag = 1;
  195. }
  196. }
  197. }
  198. /***********************************************************************
  199. * 函 数 名: DFL_SerialInit()
  200. * 功能描述:
  201. * 函数说明:
  202. * 输 入: 无
  203. * 返 回:
  204. * 设 计 者:CYL 日期:2015-05-23
  205. * 修 改 者:CYL 日期:2015-05-23
  206. ***********************************************************************/
  207. void DFL_SerialInit(void)
  208. {
  209. m_SerialSendState = RS_SEND_IDLE;
  210. m_SerialSendLen = 0;
  211. m_SerialSendPos = 0;
  212. m_SerialRecvState = RS_RECV_IDLE;
  213. m_SerialRecvLen = 0;
  214. m_SerialRecvPos = 0;
  215. //DEBUG FOR UPDATE
  216. //m_SerialRecvState = RS_RECV_COMPLETE; //wangqy-debug
  217. //g_IAPCommondFlag = 1; //
  218. return;
  219. }
  220. /***********************************************************************
  221. * 函 数 名: AFL_SerialTask()
  222. * 功能描述:
  223. * 函数说明:
  224. * 输 入: 无
  225. * 返 回:
  226. * 设 计 者:TNT 日期:2015-05-01
  227. * 修 改 者:CYL 日期:2015-05-01
  228. ***********************************************************************/
  229. void AFL_SerialTask(void)
  230. {
  231. if(m_SerialRecvState != RS_RECV_COMPLETE)
  232. {
  233. return;
  234. }
  235. ymodem_fun();
  236. if(CompareFlag == 0) {
  237. g_IAPCommondFlag = 9; //update-error, stop
  238. }
  239. }
  240. ///////////Ymodem-transmission//////////////////////////////////////////////////////
  241. #define YMODEM_DATA_LEN 128
  242. /**
  243. * @bieaf CRC-16 校验
  244. *
  245. * @param addr 开始地址
  246. * @param num 长度
  247. * @param num CRC
  248. * @return crc 返回CRC的值
  249. */
  250. #define POLY 0x1021
  251. uint16_t crc16(unsigned char *addr, int num, uint16_t crc)
  252. {
  253. int i;
  254. for (; num > 0; num--) /* Step through bytes in memory */
  255. {
  256. crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/
  257. for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */
  258. {
  259. if (crc & 0x8000) /* b15 is set... */
  260. crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */
  261. else /* b15 is clear... */
  262. crc <<= 1; /* just rotate */
  263. } /* Loop for 8 bits */
  264. crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */
  265. } /* Loop until num=0 */
  266. return(crc); /* Return updated CRC */
  267. }
  268. /**
  269. * @bieaf 获取数据包的类型, 顺便进行校验
  270. *
  271. * @param buf 开始地址
  272. * @param len 长度
  273. * @return
  274. */
  275. unsigned char Check_CRC(unsigned char* buf, int len)
  276. {
  277. unsigned short crc = 0;
  278. /* 进行CRC校验 */
  279. if((buf[0]==SOH)&&(len >= YMODEM_DATA_LEN+5)) //YMODEM_DATA_LEN=128
  280. {
  281. crc = crc16(buf+3, YMODEM_DATA_LEN, crc);
  282. if(crc != (buf[YMODEM_DATA_LEN+3]<<8|buf[YMODEM_DATA_LEN+4]))
  283. {
  284. return 0;///< 没通过校验
  285. }
  286. /* 通过校验 */
  287. return 1;
  288. }
  289. return 0;
  290. }
  291. /* 设置升级的步骤 */
  292. static enum UPDATE_STATE update_state = TO_START;
  293. void Set_state(enum UPDATE_STATE state)
  294. {
  295. update_state = state;
  296. }
  297. /* 查询升级的步骤 */
  298. uint8_t Get_state(void)
  299. {
  300. return update_state;
  301. }
  302. void delay_ms(uint32_t time)
  303. {
  304. /*uint32_t target_ticks = g_SysTick+time;
  305. while(target_ticks < g_SysTick) {
  306. int i = 1;
  307. }*/
  308. u16 i=0;
  309. while(time--)
  310. {
  311. i=12000; //????
  312. while(i--) ;
  313. }
  314. }
  315. /* 发送指令 */
  316. void send_command(uint8_t command)
  317. {
  318. Dma_send_data(&command, 1);
  319. delay_ms(3);
  320. //HAL_UART_Transmit(&huart2, (uint8_t *)&command,1, 0xFFFF);
  321. //HAL_Delay(10);
  322. }
  323. uint8_t temp_buf[256] = {0};
  324. uint8_t temp_len = 0;
  325. /**
  326. * @bieaf YModem升级
  327. *
  328. * @param none
  329. * @return none
  330. */
  331. void ymodem_fun(void)
  332. {
  333. static uint8_t data_state = 0;
  334. int i;
  335. if(Get_state()==TO_START)
  336. {
  337. send_command(CCC);
  338. delay_ms(1000);
  339. }
  340. if(Rx_Flag) // Receive flag
  341. {
  342. Rx_Flag=0; // clean flag
  343. /* 拷贝 */
  344. temp_len = m_SerialRecvLen;
  345. for(i = 0; i < temp_len; i++)
  346. {
  347. temp_buf[i] = m_SerialRecvBuffer[i];
  348. }
  349. switch(temp_buf[0])
  350. {
  351. case SOH:///<数据包开始
  352. {
  353. //static unsigned int app2_size = 0;
  354. if(Check_CRC(temp_buf, temp_len)==1)///< 通过CRC16校验
  355. {
  356. if((Get_state()==TO_START)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 开始
  357. {
  358. printf("> Receive start...\r\n");
  359. Set_state(TO_RECEIVE_DATA);
  360. data_state = 0x01; //init data-index
  361. send_command(ACK);
  362. send_command(CCC);
  363. /* 擦除App2 */
  364. DHL_STMFlash_Erase(APPLICATION_UPDCODE_ADDRESS, BACKUP_CODE_CACHE_SIZE/2);
  365. last_upd_ticks = g_SysTick;
  366. }
  367. else if((Get_state()==TO_RECEIVE_END)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 结束
  368. {
  369. printf("> Receive end...\r\n");
  370. CompareFlag = 1; //ok, if not write to flash
  371. if(m_ReceiveDataCurNum > 0) //LAST页就写
  372. {
  373. for (i=m_ReceiveDataCurNum; i<STM_SECTOR_SIZE/2; i++) {
  374. UpdateCodeData[i] = 0xffff;
  375. }
  376. for(i=0; i<Rewrite; i++)
  377. {
  378. DHL_STMFlash_Write(addrSave,UpdateCodeData,STM_SECTOR_SIZE/2);
  379. DHL_STMFlash_Read(addrSave, CompareaData,STM_SECTOR_SIZE/2);
  380. CompareFlag = DHL_CompareBuffer(UpdateCodeData,CompareaData,STM_SECTOR_SIZE/2);
  381. if(CompareFlag == 1) //write ok
  382. {
  383. m_ReceiveDataCurNum=0;
  384. break;
  385. }
  386. }
  387. }
  388. if(CompareFlag == 1) { //write ok
  389. AFL_Write_StartMode(Startup_Update);
  390. //Set_state(TO_START);
  391. send_command(ACK);
  392. //System_SoftReset(); //system reset
  393. last_upd_ticks = g_SysTick;
  394. g_IAPCommondFlag = 2; //update-end, stop
  395. }
  396. }
  397. else if((Get_state()==TO_RECEIVE_DATA)&&(temp_buf[1] == data_state)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 接收数据
  398. {
  399. printf("> Receive data bag:%d byte\r\n",data_state * YMODEM_DATA_LEN); //YMODEM_DATA_LEN=128
  400. for(i=0; i<YMODEM_DATA_LEN; i+=2)
  401. {
  402. m_ReceiveCodeDataU16= ((((u16)temp_buf[i+4])<<8) | ((u16)temp_buf[i+3]));
  403. UpdateCodeData[m_ReceiveDataCurNum++] = m_ReceiveCodeDataU16;
  404. }
  405. CompareFlag = 1; //ok, if not write to flash
  406. if(m_ReceiveDataCurNum == STM_SECTOR_SIZE/2) //满一页就写
  407. {
  408. for(i=0; i<Rewrite; i++)
  409. {
  410. DHL_STMFlash_Write(addrSave,UpdateCodeData,STM_SECTOR_SIZE/2);
  411. DHL_STMFlash_Read(addrSave, CompareaData,STM_SECTOR_SIZE/2);
  412. CompareFlag = DHL_CompareBuffer(UpdateCodeData,CompareaData,STM_SECTOR_SIZE/2);
  413. if(CompareFlag == 1) //write ok
  414. {
  415. addrSave+= STM_SECTOR_SIZE;
  416. m_ReceiveDataCurNum=0;
  417. break;
  418. }
  419. }
  420. }
  421. /* 烧录程序 */
  422. //WriteFlash((Application_2_Addr + (data_state-1) * 128), (uint32_t *)(&temp_buf[3]), 32);
  423. if(CompareFlag == 1) { // write ok
  424. data_state++;
  425. send_command(ACK);
  426. }
  427. }
  428. }
  429. else
  430. {
  431. printf("> Notpass crc\r\n");
  432. }
  433. }break;
  434. case EOT://数据包 end of transmission
  435. {
  436. if(Get_state()==TO_RECEIVE_DATA)
  437. {
  438. printf("> Receive EOT1...\r\n");
  439. Set_state(TO_RECEIVE_EOT2);
  440. send_command(NACK);
  441. }
  442. else if(Get_state()==TO_RECEIVE_EOT2)
  443. {
  444. printf("> Receive EOT2...\r\n");
  445. Set_state(TO_RECEIVE_END);
  446. send_command(ACK);
  447. send_command(CCC);
  448. }
  449. else
  450. {
  451. printf("> Receive EOT, But error...\r\n");
  452. }
  453. }break;
  454. }
  455. }
  456. }
  457. /******************* (C) COPYRIGHT 2017 LECOOAI *****END OF FILE****/