¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | ****************************************************************************** |
| | | * @file STM32F0xx_IAP/src/ymodem.c |
| | | * @author MCD Application Team |
| | | * @version V1.0.0 |
| | | * @date 29-May-2012 |
| | | * @brief Main program body |
| | | ****************************************************************************** |
| | | * @attention |
| | | * |
| | | * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> |
| | | * |
| | | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); |
| | | * You may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at: |
| | | * |
| | | * http://www.st.com/software_license_agreement_liberty_v2 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | * |
| | | ****************************************************************************** |
| | | */ |
| | | /* Includes ------------------------------------------------------------------*/ |
| | | |
| | | #include "ymodem.h" |
| | | #include "string.h" |
| | | //#include "main.h" |
| | | #include "aes.h" |
| | | #include "mk_flash.h" |
| | | //#include "stm32f4xx_hal.h" |
| | | #include "AppConfig.h" |
| | | #include "mk_uart.h" |
| | | #include "mk_trace.h" |
| | | /** @addtogroup STM32F0xx_IAP |
| | | * @{ |
| | | */ |
| | | #define IS_AF(c) ((c >= 'A') && (c <= 'F')) |
| | | #define IS_af(c) ((c >= 'a') && (c <= 'f')) |
| | | #define IS_09(c) ((c >= '0') && (c <= '9')) |
| | | #define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c) |
| | | #define ISVALIDDEC(c) IS_09(c) |
| | | #define CONVERTDEC(c) (c - '0') |
| | | |
| | | #define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10)) |
| | | #define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c)) |
| | | /* Private typedef -----------------------------------------------------------*/ |
| | | /* Private define ------------------------------------------------------------*/ |
| | | /* Private macro -------------------------------------------------------------*/ |
| | | /* Private variables ---------------------------------------------------------*/ |
| | | extern uint8_t FileName[]; |
| | | extern void Int2Str(uint8_t* str, int32_t intnum); |
| | | //extern UART_HandleTypeDef huart1; |
| | | /* Private function prototypes -----------------------------------------------*/ |
| | | /* Private functions ---------------------------------------------------------*/ |
| | | uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum) |
| | | { |
| | | uint32_t i = 0, res = 0; |
| | | uint32_t val = 0; |
| | | |
| | | if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X')) |
| | | { |
| | | if (inputstr[2] == '\0') |
| | | { |
| | | return 0; |
| | | } |
| | | for (i = 2; i < 11; i++) |
| | | { |
| | | if (inputstr[i] == '\0') |
| | | { |
| | | *intnum = val; |
| | | /* return 1; */ |
| | | res = 1; |
| | | break; |
| | | } |
| | | if (ISVALIDHEX(inputstr[i])) |
| | | { |
| | | val = (val << 4) + CONVERTHEX(inputstr[i]); |
| | | } |
| | | else |
| | | { |
| | | /* return 0, Invalid input */ |
| | | res = 0; |
| | | break; |
| | | } |
| | | } |
| | | /* over 8 digit hex --invalid */ |
| | | if (i >= 11) |
| | | { |
| | | res = 0; |
| | | } |
| | | } |
| | | else /* max 10-digit decimal input */ |
| | | { |
| | | for (i = 0; i < 11; i++) |
| | | { |
| | | if (inputstr[i] == '\0') |
| | | { |
| | | *intnum = val; |
| | | /* return 1 */ |
| | | res = 1; |
| | | break; |
| | | } |
| | | else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0)) |
| | | { |
| | | val = val << 10; |
| | | *intnum = val; |
| | | res = 1; |
| | | break; |
| | | } |
| | | else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0)) |
| | | { |
| | | val = val << 20; |
| | | *intnum = val; |
| | | res = 1; |
| | | break; |
| | | } |
| | | else if (ISVALIDDEC(inputstr[i])) |
| | | { |
| | | val = val * 10 + CONVERTDEC(inputstr[i]); |
| | | } |
| | | else |
| | | { |
| | | /* return 0, Invalid input */ |
| | | res = 0; |
| | | break; |
| | | } |
| | | } |
| | | /* Over 10 digit decimal --invalid */ |
| | | if (i >= 11) |
| | | { |
| | | res = 0; |
| | | } |
| | | } |
| | | |
| | | return res; |
| | | } |
| | | /** |
| | | * @brief Receive byte from sender |
| | | * @param c: Character |
| | | * @param timeout: Timeout |
| | | * @retval 0: Byte received |
| | | * -1: Timeout |
| | | */ |
| | | int32_t Receive_Byte (uint8_t *c, uint32_t timeout) |
| | | { |
| | | while (timeout-- > 0) |
| | | { |
| | | if (SerialKeyPressed(c) == 1)//妿æ¶å°ä¸²å£æ°æ® |
| | | { |
| | | // Serial0_PutString("æ¥åæå"); |
| | | return 0; |
| | | } |
| | | } |
| | | // Serial0_PutString("æ¥å失败"); |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * @brief Send a byte |
| | | * @param c: Character |
| | | * @retval 0: Byte sent |
| | | */ |
| | | uint32_t Send_Byte (uint8_t c) |
| | | { |
| | | SerialPutChar(c); |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief Update CRC16 for input byte |
| | | * @param CRC input value |
| | | * @param input byte |
| | | * @retval Updated CRC value |
| | | */ |
| | | uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte) |
| | | { |
| | | uint32_t crc = crcIn; |
| | | uint32_t in = byte|0x100; |
| | | |
| | | do |
| | | { |
| | | crc <<= 1; |
| | | in <<= 1; |
| | | |
| | | if(in&0x100) |
| | | { |
| | | ++crc; |
| | | } |
| | | |
| | | if(crc&0x10000) |
| | | { |
| | | crc ^= 0x1021; |
| | | } |
| | | } while(!(in&0x10000)); |
| | | |
| | | return (crc&0xffffu); |
| | | } |
| | | |
| | | /** |
| | | * @brief Cal CRC16 for YModem Packet |
| | | * @param data |
| | | * @param length |
| | | * @retval CRC value |
| | | */ |
| | | uint16_t Cal_CRC16(const uint8_t* data, uint32_t size) |
| | | { |
| | | uint32_t crc = 0; |
| | | const uint8_t* dataEnd = data+size; |
| | | |
| | | while(data<dataEnd) |
| | | { |
| | | crc = UpdateCRC16(crc,*data++); |
| | | } |
| | | crc = UpdateCRC16(crc,0); |
| | | crc = UpdateCRC16(crc,0); |
| | | |
| | | return (crc&0xffffu); |
| | | } |
| | | |
| | | /** |
| | | * @brief Cal Check sum for YModem Packet |
| | | * @param data |
| | | * @param length |
| | | * @retval None |
| | | */ |
| | | uint8_t CalChecksum(const uint8_t* data, uint32_t size) |
| | | { |
| | | uint32_t sum = 0; |
| | | const uint8_t* dataEnd = data+size; |
| | | |
| | | while(data < dataEnd) |
| | | { |
| | | sum += *data++; |
| | | } |
| | | |
| | | return (sum&0xffu); |
| | | } |
| | | |
| | | /** |
| | | * @brief Receive a packet from sender |
| | | * @param data |
| | | * @param length |
| | | * @param timeout |
| | | * 0: end of transmission |
| | | * -1: abort by sender |
| | | * >0: packet length |
| | | * @retval 0: normally return |
| | | * -1: timeout or packet error |
| | | * 1: abort by user |
| | | */ |
| | | uint16_t current_seqno,flash_seqno,i2; |
| | | uint8_t c; |
| | | static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) |
| | | { |
| | | uint16_t packet_size, computedcrc; |
| | | |
| | | *length = 0; |
| | | if (Receive_Byte(&c, timeout) != 0)//è¿å0æåæ¶åæ°æ®,-1为没æ¶å°æ°æ® |
| | | { |
| | | return -1; |
| | | } |
| | | switch (c) |
| | | { |
| | | case SOH: |
| | | packet_size = PACKET_SIZE; |
| | | break; |
| | | case STX: |
| | | packet_size = PACKET_1K_SIZE; |
| | | break; |
| | | case EOT: |
| | | return 0; |
| | | case CA: |
| | | if ((Receive_Byte(&c, timeout) == 0) && (c == CA)) |
| | | { |
| | | *length = -1; |
| | | return 0; |
| | | } |
| | | else |
| | | { |
| | | return -1; |
| | | } |
| | | case ABORT1: |
| | | case ABORT2: |
| | | return 1; |
| | | default: |
| | | return -1; |
| | | } |
| | | *data = c;//æ¾å°1024+5åèçå
éé¢ |
| | | for (i2 = 1; i2 < (packet_size + PACKET_OVERHEAD); i2 ++) |
| | | { |
| | | if (Receive_Byte(data + i2, timeout) != 0)//ä¸æçæ¥æ¶1024åèæ¾å
¥ |
| | | { |
| | | return -1; |
| | | } |
| | | } |
| | | //æ£æµåºå·è¡¥ç æ¯æ¯å¦æ£ç¡® |
| | | if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) |
| | | { |
| | | |
| | | return 1; |
| | | } |
| | | if(current_seqno==data[PACKET_SEQNO_INDEX]||c==SOH) |
| | | { |
| | | current_seqno++; |
| | | } else { |
| | | return 1; |
| | | } |
| | | |
| | | /* Compute the CRC */ |
| | | computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size);//计ç®CRC16ç |
| | | /* Check that received CRC match the already computed CRC value |
| | | data[packet_size+3]<<8) | data[packet_size+4] contains the received CRC |
| | | computedcrc contains the computed CRC value */ |
| | | if (computedcrc != (uint16_t)((data[packet_size+3]<<8) | data[packet_size+4]))//æ£æµCRC16æ ¡éªç |
| | | { |
| | | /* CRC error */ |
| | | return 1; |
| | | } |
| | | |
| | | *length = packet_size; |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief Receive a file using the ymodem protocol |
| | | * @param buf: Address of the first byte |
| | | * @retval The size of the file |
| | | */ |
| | | extern volatile unsigned long time32_reset; |
| | | uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; //1024 + 5 |
| | | uint8_t bufferOut[16]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
| | | uint8_t *BufferIn; |
| | | int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; |
| | | uint32_t flashdestination, ramsource,tempaddress; |
| | | int32_t Ymodem_Receive (uint8_t *buf) |
| | | { |
| | | |
| | | aesDecInit();//AESè§£å¯åå§å |
| | | /* Initialize flashdestination variable */ |
| | | flashdestination = APP_CONFIG_APPLICATION_ADDRESS; //APP代ç çèµ·å§å°å,APP_CONFIG_APPLICATION_ADDRESS = 0x8005000,å¯å¨targetç颿 ¹æ®æ
åµè®¾ç½® |
| | | current_seqno=0; //è¿äºé½å¨ymodem.héé¢çå®è¿è¡è®¾ç½® |
| | | flash_seqno=2; |
| | | for (session_done = 0, errors = 0, session_begin = 0; ;)//æ»å¾ªç¯ç´è³æä»¶æ°æ®å
å
¨é¨åé宿 |
| | | { |
| | | for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) |
| | | { |
| | | |
| | | switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) |
| | | { |
| | | case 0://æåæ¥æ¶å°1K |
| | | errors = 0; |
| | | switch (packet_length) |
| | | { |
| | | /* Abort by sender */ |
| | | case - 1: //æ¥æ¶å¤±è´¥ |
| | | Send_Byte(ACK); //åå¤ |
| | | return 0; |
| | | /* End of transmission */ |
| | | case 0: |
| | | Send_Byte(ACK);//åå¤ |
| | | file_done = 1; |
| | | break; |
| | | /* Normal packet */ |
| | | default: //æ¥æ¶æå |
| | | if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) |
| | | { //åºå·00(æä»¶å) |
| | | Send_Byte(NAK); |
| | | |
| | | } |
| | | else |
| | | { |
| | | if (packets_received == 0)//æä»¶å(é¦å
) |
| | | { |
| | | /* Filename packet */ |
| | | if (packet_data[PACKET_HEADER] != 0)//æä»¶åå |
| | | { |
| | | /* Filename packet has valid data */ |
| | | for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) |
| | | { |
| | | FileName[i++] = *file_ptr++;//ä¿åæä»¶å |
| | | } |
| | | FileName[i++] = '\0';//åç¬¦ä¸²å½¢å¼ |
| | | for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));) |
| | | { |
| | | file_size[i++] = *file_ptr++;//æä»¶å¤§å° |
| | | } |
| | | file_size[i++] = '\0'; |
| | | Str2Int(file_size, &size);//Convert a string to an integer |
| | | |
| | | /* Test the size of the image to be sent */ |
| | | /* Image size is greater than Flash size */ |
| | | if (size > (APP_CONFIG_APPLICATION_SIZE + 1)) |
| | | { |
| | | /* End session */ |
| | | Send_Byte(CA); |
| | | Send_Byte(CA); |
| | | return -1; |
| | | } |
| | | /* erase user application area */ |
| | | // Flash_Init(); |
| | | // Flash_Erase(APP_CONFIG_APPLICATION_ADDRESS, APP_CONFIG_APPLICATION_SIZE);MK8000 ä¿®æ¹ |
| | | flash_erase(FLASH_ID0, APP_CONFIG_APPLICATION_ADDRESS, APP_CONFIG_APPLICATION_SIZE);//æ¦é¤APP |
| | | Send_Byte(ACK); |
| | | Send_Byte(CRC16); |
| | | } |
| | | /* Filename packet is empty, end session */ |
| | | else |
| | | { |
| | | Send_Byte(ACK); |
| | | file_done = 1; |
| | | session_done = 1; |
| | | break; |
| | | } |
| | | } |
| | | /* Data packet */ |
| | | else //æä»¶ä¿¡æ¯ä¿åå®åå¼å§æ¥æ¶æ°æ® |
| | | { |
| | | memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); |
| | | |
| | | /*----------------------------------------------------------------------------------------------*/ |
| | | BufferIn=buf; |
| | | for (j = 0; j < packet_length; j += 16) //æ¯æ¬¡è§£å¯16åè |
| | | { |
| | | //è§£å¯æ°æ®å
|
| | | aesDecrypt(BufferIn,bufferOut); //ç±äºåæ°ä½¿ç¨çæ¯æé,æä»¥è§£å¯å便§åå¨buféé¢ |
| | | BufferIn+=16; |
| | | } |
| | | /*----------------------------------------------------------------------------------------------*/ |
| | | |
| | | |
| | | /* Write received data in Flash */ //è¿ä¸ªsizeåæ°æ¯èªå·±å è¿å
¥ç,便äºå¤ææä»¶ä¼ è¾å®æ |
| | | // if (Flash_Write(flashdestination, buf, packet_length) == 0&&(flashdestination==tempaddress||tempaddress>size)) MK8000ä¿®æ¹ |
| | | // { |
| | | // flashdestination += packet_length; |
| | | // //åå
¥FLASH |
| | | // Send_Byte(ACK); |
| | | // flash_seqno++; |
| | | // time32_reset = 0; |
| | | // } |
| | | // else /* An error occurred while writing to Flash memory */ |
| | | // { |
| | | // /* End session */ |
| | | // Send_Byte(CA); |
| | | // Send_Byte(CA); |
| | | // return -2; |
| | | // } |
| | | ramsource = (uint32_t)buf; |
| | | tempaddress=APP_CONFIG_APPLICATION_ADDRESS+(current_seqno-1)*0x400; |
| | | if(flash_write_nbytes(FLASH_ID0,flashdestination, buf, packet_length)== 0&&(flashdestination==tempaddress||tempaddress>size)) |
| | | { |
| | | flashdestination += packet_length; |
| | | //åå
¥FLASH |
| | | Send_Byte(ACK); |
| | | flash_seqno++; |
| | | time32_reset = 0; |
| | | } |
| | | else |
| | | { |
| | | /* End session */ |
| | | Send_Byte(CA); |
| | | Send_Byte(CA); |
| | | return -2; |
| | | } |
| | | } |
| | | packets_received ++; |
| | | session_begin = 1; |
| | | } |
| | | } |
| | | break; |
| | | case 1: |
| | | Send_Byte(CA); |
| | | Send_Byte(CA); |
| | | return -3; |
| | | default://æ£éªé误 |
| | | if (session_begin > 0) |
| | | { |
| | | errors ++; |
| | | } |
| | | if (errors > MAX_ERRORS) |
| | | { |
| | | Send_Byte(CA); |
| | | Send_Byte(CA); |
| | | return 0; |
| | | } |
| | | |
| | | Send_Byte(CRC16); //åéæ ¡éªå¼ |
| | | break; |
| | | } |
| | | |
| | | if (file_done != 0) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (session_done != 0) //æä»¶åé宿 |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | return (int32_t)size; |
| | | } |
| | | |
| | | /** |
| | | * @brief check response using the ymodem protocol |
| | | * @param buf: Address of the first byte |
| | | * @retval The size of the file |
| | | */ |
| | | int32_t Ymodem_CheckResponse(uint8_t c) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief Prepare the first block |
| | | * @param timeout |
| | | * @retval None |
| | | */ |
| | | void Ymodem_PrepareIntialPacket(uint8_t *data, const uint8_t* fileName, uint32_t *length) |
| | | { |
| | | uint16_t i, j; |
| | | uint8_t file_ptr[10]; |
| | | |
| | | /* Make first three packet */ |
| | | data[0] = SOH; |
| | | data[1] = 0x00; |
| | | data[2] = 0xff; |
| | | |
| | | /* Filename packet has valid data */ |
| | | for (i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH); i++) |
| | | { |
| | | data[i + PACKET_HEADER] = fileName[i]; |
| | | } |
| | | |
| | | data[i + PACKET_HEADER] = 0x00; |
| | | |
| | | Int2Str (file_ptr, *length); |
| | | for (j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; ) |
| | | { |
| | | data[i++] = file_ptr[j++]; |
| | | } |
| | | |
| | | for (j = i; j < PACKET_SIZE + PACKET_HEADER; j++) |
| | | { |
| | | data[j] = 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief Prepare the data packet |
| | | * @param timeout |
| | | * @retval None |
| | | */ |
| | | void Ymodem_PreparePacket(uint8_t *SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk) |
| | | { |
| | | uint16_t i, size, packetSize; |
| | | uint8_t* file_ptr; |
| | | |
| | | /* Make first three packet */ |
| | | packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE; |
| | | size = sizeBlk < packetSize ? sizeBlk :packetSize; |
| | | if (packetSize == PACKET_1K_SIZE) |
| | | { |
| | | data[0] = STX; |
| | | } |
| | | else |
| | | { |
| | | data[0] = SOH; |
| | | } |
| | | data[1] = pktNo; |
| | | data[2] = (~pktNo); |
| | | file_ptr = SourceBuf; |
| | | |
| | | /* Filename packet has valid data */ |
| | | for (i = PACKET_HEADER; i < size + PACKET_HEADER; i++) |
| | | { |
| | | data[i] = *file_ptr++; |
| | | } |
| | | if ( size <= packetSize) |
| | | { |
| | | for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++) |
| | | { |
| | | data[i] = 0x1A; /* EOF (0x1A) or 0x00 */ |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief Transmit a data packet using the ymodem protocol |
| | | * @param data |
| | | * @param length |
| | | * @retval None |
| | | */ |
| | | void Ymodem_SendPacket(uint8_t *data, uint16_t length) |
| | | { |
| | | uint16_t i; |
| | | i = 0; |
| | | while (i < length) |
| | | { |
| | | Send_Byte(data[i]); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief Transmit a file using the ymodem protocol |
| | | * @param buf: Address of the first byte |
| | | * @retval The size of the file |
| | | */ |
| | | static struct UART_HANDLE_T uart_handle[UART_MAX_NUM] = { |
| | | { |
| | | .base = UART0, |
| | | .irq = UART0_IRQn, |
| | | .dma_rx_ch = DMA_CH4, |
| | | .dma_tx_ch = DMA_CH5, |
| | | }, |
| | | { |
| | | .base = UART1, |
| | | .irq = UART1_IRQn, |
| | | .dma_rx_ch = DMA_CH6, |
| | | .dma_tx_ch = DMA_CH7, |
| | | }, |
| | | }; |
| | | uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile) |
| | | { |
| | | uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; |
| | | uint8_t FileName[FILE_NAME_LENGTH]; |
| | | uint8_t *buf_ptr, tempCheckSum ; |
| | | uint16_t tempCRC, blkNumber; |
| | | uint8_t receivedC[2], CRC16_F = 0, i; |
| | | uint32_t errors = 0, ackReceived = 0, size = 0, pktSize; |
| | | |
| | | for (i = 0; i < (FILE_NAME_LENGTH - 1); i++) |
| | | { |
| | | FileName[i] = sendFileName[i]; |
| | | } |
| | | CRC16_F = 1; |
| | | |
| | | /* Prepare first block */ |
| | | Ymodem_PrepareIntialPacket(&packet_data[0], FileName, &sizeFile); |
| | | |
| | | do |
| | | { |
| | | /* Send Packet */ |
| | | Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER); |
| | | |
| | | /* Send CRC or Check Sum based on CRC16_F */ |
| | | if (CRC16_F) |
| | | { |
| | | tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE); |
| | | Send_Byte(tempCRC >> 8); |
| | | Send_Byte(tempCRC & 0xFF); |
| | | } |
| | | else |
| | | { |
| | | tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE); |
| | | Send_Byte(tempCheckSum); |
| | | } |
| | | |
| | | /* Wait for Ack and 'C' */ |
| | | if (Receive_Byte(&receivedC[0], 1000000) == 0) |
| | | { |
| | | if (receivedC[0] == ACK) |
| | | { |
| | | /* Packet transfered correctly */ |
| | | ackReceived = 1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | errors++; |
| | | } |
| | | } while (!ackReceived && (errors < 0x0A));//æ ¡éªé误éå |
| | | |
| | | if (errors >= 0x0A) |
| | | { |
| | | return errors; |
| | | } |
| | | buf_ptr = buf; |
| | | size = sizeFile; |
| | | blkNumber = 0x01; |
| | | |
| | | /* Here 1024 bytes package is used to send the packets */ |
| | | while (size) |
| | | { |
| | | /* Prepare next packet */ |
| | | Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size); |
| | | ackReceived = 0; |
| | | receivedC[0]= 0; |
| | | errors = 0; |
| | | do |
| | | { |
| | | /* Send next packet */ |
| | | if (size >= PACKET_1K_SIZE) |
| | | { |
| | | pktSize = PACKET_1K_SIZE; |
| | | |
| | | } |
| | | else |
| | | { |
| | | pktSize = PACKET_SIZE; |
| | | } |
| | | Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER); |
| | | /* Send CRC or Check Sum based on CRC16_F */ |
| | | if (CRC16_F) |
| | | { |
| | | tempCRC = Cal_CRC16(&packet_data[3], pktSize); |
| | | Send_Byte(tempCRC >> 8); |
| | | Send_Byte(tempCRC & 0xFF); |
| | | } |
| | | else |
| | | { |
| | | tempCheckSum = CalChecksum (&packet_data[3], pktSize); |
| | | Send_Byte(tempCheckSum); |
| | | } |
| | | |
| | | /* Wait for Ack */ |
| | | if (Receive_Byte(&receivedC[0], 1000000) == 0) |
| | | { if (receivedC[0] == ACK) |
| | | { |
| | | ackReceived = 1; |
| | | if (size > pktSize) |
| | | { |
| | | buf_ptr += pktSize; |
| | | size -= pktSize; |
| | | if (blkNumber == (APP_CONFIG_APPLICATION_SIZE/1024)) |
| | | { |
| | | return 0xFF; /* error */ |
| | | } |
| | | else |
| | | { |
| | | blkNumber++; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | buf_ptr += pktSize; |
| | | size = 0; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | errors++; |
| | | } |
| | | } while(!ackReceived && (errors < 0x0A)); |
| | | |
| | | /* Resend packet if NAK for a count of 10 else end of commuincation */ |
| | | if (errors >= 0x0A) |
| | | { |
| | | return errors; |
| | | } |
| | | |
| | | } |
| | | ackReceived = 0; |
| | | receivedC[0] = 0x00; |
| | | receivedC[1] = 0x00; |
| | | errors = 0; |
| | | do |
| | | { |
| | | Send_Byte(EOT); |
| | | /* Send (EOT); */ |
| | | /* Wait for Ack */ |
| | | //receivedC[0] = (uint16_t)(USART1->DR & (uint16_t)0x01FF); MK8000ä¿®æ¹ |
| | | receivedC[0]= (uint16_t)(uart_handle[1].base->RX_DATA&(uint16_t)0x01FF); |
| | | if (receivedC[0] == ACK) |
| | | { |
| | | ackReceived = 1; |
| | | } |
| | | |
| | | else |
| | | { |
| | | errors++; |
| | | } |
| | | /* Clear Overrun flag of the USART2 */ |
| | | //__HAL_UART_CLEAR_OREFLAG(&huart1); MK8000ä¿®æ¹ |
| | | // USART_ClearFlag(USART1, UART_FLAG_ORE); |
| | | } while (!ackReceived && (errors < 0x0A)); |
| | | |
| | | if (errors >= 0x0A) |
| | | { |
| | | return errors; |
| | | } |
| | | |
| | | /* Last packet preparation */ |
| | | ackReceived = 0; |
| | | receivedC[0] = 0x00; |
| | | receivedC[1] = 0x00; |
| | | errors = 0; |
| | | |
| | | packet_data[0] = SOH; |
| | | packet_data[1] = 0; |
| | | packet_data [2] = 0xFF; |
| | | |
| | | for (i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++) |
| | | { |
| | | packet_data [i] = 0x00; |
| | | } |
| | | |
| | | do |
| | | { |
| | | /* Send Packet */ |
| | | Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER); |
| | | |
| | | /* Send CRC or Check Sum based on CRC16_F */ |
| | | tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE); |
| | | Send_Byte(tempCRC >> 8); |
| | | Send_Byte(tempCRC & 0xFF); |
| | | |
| | | /* Wait for Ack and 'C' */ |
| | | if (Receive_Byte(&receivedC[1], 1000000) == 0) |
| | | { |
| | | if (receivedC[1] == ACK) |
| | | { |
| | | /* Packet transfered correctly */ |
| | | ackReceived = 1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | errors++; |
| | | } |
| | | } while (!ackReceived && (errors < 0x0A)); |
| | | |
| | | /* Resend packet if NAK for a count of 10 else end of commuincation */ |
| | | if (errors >= 0x0A) |
| | | { |
| | | return errors; |
| | | } |
| | | receivedC[0] = 0x00; |
| | | do |
| | | { |
| | | Send_Byte(EOT); |
| | | /* Send (EOT); */ |
| | | /* Wait for Ack */ |
| | | if ((Receive_Byte(&receivedC[0], 1000000) == 0) && receivedC[0] == ACK) |
| | | { |
| | | ackReceived = 1; |
| | | } |
| | | |
| | | else |
| | | { |
| | | errors++; |
| | | } |
| | | /* Clear Overrun flag of the USART2 */ |
| | | // __HAL_UART_CLEAR_OREFLAG(&huart1); MK8000ä¿®æ¹ |
| | | } while (!ackReceived && (errors < 0x0A)); |
| | | |
| | | if (errors >= 0x0A) |
| | | { |
| | | return errors; |
| | | } |
| | | return 0; /* file trasmitted successfully */ |
| | | } |
| | | |
| | | /** |
| | | * @} |
| | | */ |
| | | |
| | | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |