diff --git a/.gitignore b/.gitignore index cbfaeaa4d8661683c829fa584859fc89634f74e6..2fe594f7c736fc8bcdf91f7ece917a4fc9e2bebb 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ Objects/BootLoader.axf Objects/BootLoader.htm Objects/menu.d Objects/menu.o +Objects/BootLoader_sct.Bak +Objects/bsp_gpio.d +Objects/bsp_gpio.o diff --git a/BootLoader.uvoptx b/BootLoader.uvoptx index 1c05aa112c56511c241b27f726862923d5f1ddc1..8c569ecba89656fe4962996adaf15aa74bdd4bec 100644 --- a/BootLoader.uvoptx +++ b/BootLoader.uvoptx @@ -179,7 +179,7 @@ 1 1 1 - 0 + 1 0 0 .\bsp_uart.c @@ -259,6 +259,18 @@ 0 0 + + 1 + 8 + 1 + 0 + 0 + 0 + .\bsp_gpio.c + bsp_gpio.c + 0 + 0 + @@ -269,7 +281,7 @@ 0 2 - 8 + 9 1 0 0 @@ -281,7 +293,7 @@ 2 - 9 + 10 1 0 0 diff --git a/BootLoader.uvprojx b/BootLoader.uvprojx index 6dc9beade7fe47bc0f8d94c342ead09f3e65d86f..26ca09cf6641dc997a4b3c53cf5f25eca361f27d 100644 --- a/BootLoader.uvprojx +++ b/BootLoader.uvprojx @@ -277,7 +277,7 @@ 1 0x8000000 - 0x300000 + 0x8000 1 @@ -419,6 +419,11 @@ 5 .\ymodem.h + + bsp_gpio.c + 1 + .\bsp_gpio.c + diff --git a/bsp_gpio.c b/bsp_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..c5d8d9e28a0f2bdf517e68c30979e1481907aac0 --- /dev/null +++ b/bsp_gpio.c @@ -0,0 +1,38 @@ +/* + * @Author: Ma Yuchen + * @Date: 2022-11-24 23:09:29 + * @LastEditors: Ma YuChen + * @LastEditTime: 2022-11-25 00:18:25 + * @Description: file content + * @FilePath: \BootLoader\bsp_gpio.c + */ + +#include "bsp_gpio.h" +#include "gd32f4xx_gpio.h" + +void InitGpio(void) +{ + rcu_periph_clock_enable(RCU_GPIOD); + + gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1); + + gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0); +} + +void PowerOnBmcPeriph(void) +{ + gpio_bit_set(GPIOD, GPIO_PIN_1); +} + +void PowerOffBmcPeriph(void) +{ + gpio_bit_reset(GPIOD, GPIO_PIN_1); +} + +void ResetGpio(void) +{ + gpio_bit_reset(GPIOD, GPIO_PIN_1); + gpio_deinit(GPIOD); + rcu_periph_clock_disable(RCU_GPIOD); +} diff --git a/bsp_gpio.h b/bsp_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..04ef3e71d37f2413d7354dcc3a5b61eabd50e665 --- /dev/null +++ b/bsp_gpio.h @@ -0,0 +1,18 @@ +/* + * @Author: Ma Yuchen + * @Date: 2022-11-24 23:07:45 + * @LastEditors: Ma YuChen + * @LastEditTime: 2022-11-24 23:20:08 + * @Description: file content + * @FilePath: \BootLoader\bsp_gpio.h + */ + +#ifndef BSP_GPIO_H +#define BSP_GPIO_H + +void InitGpio(void); + +void PowerOnBmcPeriph(void); +void PowerOffBmcPeriph(void); +void ResetGpio(void); +#endif diff --git a/bsp_ocflash.h b/bsp_ocflash.h index 0f8c833db635b5aafb04ed3286dc781e5cb6f176..f754e874d027aad27fa3b6d8e7bf4656fb8e3815 100644 --- a/bsp_ocflash.h +++ b/bsp_ocflash.h @@ -2,24 +2,37 @@ * @Author: Ma Yuchen * @Date: 2022-11-23 12:18:51 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-23 22:20:10 + * @LastEditTime: 2022-11-24 22:26:37 * @Description: file content * @FilePath: \BootLoader\bsp_ocflash.h */ #ifndef BSP_OCFLASH_H #define BSP_OCFLASH_H +#include #include #define APPLICATION_ADDRESS (uint32_t)0x08008000 +#define USER_FLASH_END_ADDRESS (uint32_t)0x0807FFFF + +#define USER_FLASH_SIZE (USER_FLASH_END_ADDRESS-APPLICATION_ADDRESS+1) #define APPLICATION_START_SECTOR 2 -#define APPLICATION_END_SECTOR 11 +#define APPLICATION_END_SECTOR 7 typedef void (*pFunction)(void); void Flash_IF_Init(void); int Flash_IF_App_Erase(int StartSectorId, int EndSectorId); +/** + * @brief 按照4字节单位将缓存区数据烧写到Flash + * + * @param address [in out] 传输地址的指针 + * @param buffer [in] 数据缓存区 + * @param length [in] 数据缓存区长度 + * @return int 0 正确 -1 烧写错误 -2 回读错误 + */ +int Flash_IF_Write(__IO uint32_t *address, uint32_t *buffer, int length); #endif diff --git a/bsp_uart.c b/bsp_uart.c index 21ee7b41ca7d2dc4063cedff730e7145284b3485..fbfe9b67972ae2ab8fc60d4ebf93a1610e118f79 100644 --- a/bsp_uart.c +++ b/bsp_uart.c @@ -2,112 +2,112 @@ * @Author: Ma Yuchen * @Date: 2022-11-22 21:43:39 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-24 11:11:37 + * @LastEditTime: 2022-11-24 23:51:11 * @Description: file content * @FilePath: \BootLoader\bsp_uart.c */ #include "bsp_uart.h" -#include "gd32f4xx_usart.h" // GigaDevice::Device:StdPeripherals:USART +#include "gd32f4xx_usart.h" // GigaDevice::Device:StdPeripherals:USART -#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 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)) +#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A' + 10) : (c - 'a' + 10)) +#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c)) /** * @brief 初始化串口通信 - * + * */ void InitSerial(void) { - rcu_periph_clock_enable(RCU_UART6); - - nvic_irq_enable(UART6_IRQn, 2U,0U); - - gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8); - gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7); - - gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); - gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7 | GPIO_PIN_8); - - usart_deinit(UART6); - usart_baudrate_set(UART6, 115200U); - usart_word_length_set(UART6,USART_WL_8BIT); - usart_stop_bit_set(UART6,USART_STB_1BIT); - usart_parity_config(UART6,USART_PM_NONE); - - usart_receive_config(UART6,USART_RECEIVE_ENABLE); - usart_transmit_config(UART6, USART_TRANSMIT_ENABLE); - - // usart_interrupt_enable(UART6, USART_INTEN_RBNEIE); - usart_enable(UART6); + rcu_periph_clock_enable(RCU_GPIOE); + rcu_periph_clock_enable(RCU_UART6); + + // nvic_irq_enable(UART6_IRQn, 2U,0U); + + gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8); + gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7); + + gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7 | GPIO_PIN_8); + + usart_baudrate_set(UART6, 115200U); + usart_word_length_set(UART6, USART_WL_8BIT); + usart_stop_bit_set(UART6, USART_STB_1BIT); + usart_parity_config(UART6, USART_PM_NONE); + + usart_receive_config(UART6, USART_RECEIVE_ENABLE); + usart_transmit_config(UART6, USART_TRANSMIT_ENABLE); + + // usart_interrupt_enable(UART6, USART_INTEN_RBNEIE); + usart_enable(UART6); } void ResetSerial(void) { - usart_disable(UART6); - usart_deinit(UART6); + usart_deinit(UART6); + gpio_deinit(GPIOE); } /** * @brief 从串口设备中获取一个字节 - * + * * @param[out] key 存放字节数据的指针 * @return uint32_t 1:读取出一个数据 0:无数据 */ -uint32_t SerialKeyPressed(uint8_t* key) +uint32_t SerialKeyPressed(uint8_t *key) { - if(SET == usart_flag_get(UART6, USART_FLAG_RBNE)) - { - usart_flag_clear(UART6, USART_FLAG_RBNE); - *key= (uint8_t)usart_data_receive(UART6); - return 1; - } - else - { - return 0; - } + if (SET == usart_flag_get(UART6, USART_FLAG_RBNE)) + { + usart_flag_clear(UART6, USART_FLAG_RBNE); + *key = (uint8_t)usart_data_receive(UART6); + return 1; + } + else + { + return 0; + } } uint8_t GetKey(void) { - uint8_t key=0; - while (1) + uint8_t key = 0; + while (1) + { + if (SerialKeyPressed(&key)) { - if(SerialKeyPressed(&key)) - { - break; - } + break; } - return key; + } + return key; } void SerialPutChar(uint8_t c) { - usart_data_transmit(UART6, c); + usart_data_transmit(UART6, c); - while (RESET == usart_flag_get(UART6, USART_FLAG_TC)) - { - //roll wait - } + while (RESET == usart_flag_get(UART6, USART_FLAG_TC)) + { + // roll wait + } } -void Serial_PutString(uint8_t* s) +void Serial_PutString(uint8_t *s) { - while(*s !='\0') - { - SerialPutChar(*s); - s++; - } + while (*s != '\0') + { + SerialPutChar(*s); + s++; + } } -int Int2Str(uint8_t* str, int32_t intnum) +int Int2Str(uint8_t *str, int32_t intnum) { uint32_t i, Div = 1000000000, j = 0, Status = 0; @@ -117,7 +117,7 @@ int Int2Str(uint8_t* str, int32_t intnum) intnum = intnum % Div; Div /= 10; - if ((str[j-1] == '0') & (Status == 0)) + if ((str[j - 1] == '0') & (Status == 0)) { j = 0; } @@ -129,11 +129,11 @@ int Int2Str(uint8_t* str, int32_t intnum) } /** - * @brief Intel String trans to Integer - * - * @param inputstr - * @param intnum - * @return int + * @brief Intel String trans to Integer + * + * @param inputstr + * @param intnum + * @return int */ int Str2Int(uint8_t *inputstr, int32_t *intnum) { @@ -174,7 +174,7 @@ int Str2Int(uint8_t *inputstr, int32_t *intnum) } else /* max 10-digit decimal input */ { - for (i = 0;i < 11;i++) + for (i = 0; i < 11; i++) { if (inputstr[i] == '\0') { diff --git "a/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx" "b/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx" new file mode 100644 index 0000000000000000000000000000000000000000..a16cc9bfe46aecb8d93b3dba580901641099e9dd Binary files /dev/null and "b/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx" differ diff --git a/main.c b/main.c index 3be3b344e1a33f28e450535255272db6ee25c776..a2c78ed6bdf23fb3496e333a399d4672ff8b62e1 100644 --- a/main.c +++ b/main.c @@ -2,12 +2,13 @@ * @Author: Ma Yuchen * @Date: 2022-11-22 21:03:02 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-24 11:27:04 + * @LastEditTime: 2022-11-26 11:49:43 * @Description: file content * @FilePath: \BootLoader\main.c */ #include #include "menu.h" +#include "bsp_gpio.h" #include "bsp_uart.h" #include "bsp_ocflash.h" #include "systick.h" @@ -21,24 +22,34 @@ static int ExistApplication(void); int main(void) { - //初始化Core时钟 systick_config(); + //初始化GPIO并打开V3.3外设供电 + InitGpio(); + PowerOnBmcPeriph(); + delay_1ms(10); + //初始化串口 InitSerial(); + + SerialPutString("\r\nThanks for use this bootLoader\r\n"); if(GetIAPIntper() == 1) //如果获取到IAP请求中断则打印菜单进行IAP操作 { + Flash_IF_Init(); PrintMenu(); } //如果无请求则跳转到APP启动 else { + SerialPutString("\r\nRun App...\r\n"); RunApp(); } - return 0; + while(1) + { + } } int GetIAPIntper(void) @@ -75,7 +86,7 @@ void RunApp(void) int ExistApplication(void) { - if((*(__IO uint32_t *)APPLICATION_ADDRESS) & 0x2FFE0000 == 0x20000000) + if(((*(__IO uint32_t *)APPLICATION_ADDRESS) & 0x2FFE0000) == 0x20000000) { return 1; } diff --git a/menu.c b/menu.c index 7255d540d931bd4d63180378bacf62b3907c84f4..90bcae6b80607d3acc1d013033a8cc990d349a55 100644 --- a/menu.c +++ b/menu.c @@ -2,19 +2,20 @@ * @Author: Ma Yuchen * @Date: 2022-11-24 10:03:28 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-24 11:25:49 + * @LastEditTime: 2022-11-25 15:19:15 * @Description: file content * @FilePath: \BootLoader\menu.c */ #include "gd32f4xx.h" #include "menu.h" +#include "bsp_gpio.h" +#include "systick.h" -pFunction Jump_To_Application; -uint32_t JumpAddress; +static pFunction Jump_To_Application; +static uint32_t JumpAddress; -uint8_t tab_1024[PACKET_DATA_LENGTH] = {0}; -uint8_t FileName[FILE_NAME_LENGTH] = {0}; +static uint8_t tab_1024[PACKET_DATA_LENGTH] = {0}; void SerialDownLoad(void); @@ -25,6 +26,7 @@ void SerialDownLoad(void); void PrintMenu(void) { uint8_t key = 0; + uint8_t printProgramMenu=1; SerialPutString("\r\n=========================================================\r\n"); SerialPutString("\r\n= =\r\n"); @@ -34,10 +36,14 @@ void PrintMenu(void) while (1) { + if(printProgramMenu!=0) + { + printProgramMenu=0; SerialPutString("\r\n========================Main Menu========================\r\n"); SerialPutString("\r\n== Download Image To the GD32F4xx Internal Flash--------1\r\n"); SerialPutString("\r\n== Exec New Program-------------------------------------2\r\n"); SerialPutString("\r\n=========================================================\r\n"); + } key = GetKey(); @@ -45,14 +51,21 @@ void PrintMenu(void) // Download Image & program in flash { SerialDownLoad(); + printProgramMenu=1; } else if (key == 0x32) { LoadRunApplication(); + printProgramMenu=1; + return ; + } + else if(key == 0x1B) + { + } else { - SerialPutString("Invalid Num ! ==> The number should be either1,2\r\n"); + SerialPutString("\r\nInvalid Num ! ==> The number should be either1,2\r\n"); } } } @@ -63,7 +76,7 @@ void SerialDownLoad(void) int32_t Size=0; SerialPutString("\r\n Waiting for file to be sent ...\r\n"); - Size=Ymodem_Receive(&tab_1024); + Size=Ymodem_Receive(tab_1024); if(Size>0) { @@ -73,13 +86,22 @@ void SerialDownLoad(void) SerialPutString("\r\n Size: "); SerialPutString(Number); SerialPutString("Bytes\r\n"); - stringPutString("--------------------------\r\n"); + SerialPutString("--------------------------\r\n"); + } + else + { + SerialPutString("\r\n Warning Receive File failed!!\r\n"); } - } void LoadRunApplication(void) { + PowerOffBmcPeriph(); + ResetSerial(); + ResetGpio(); + + delay_1ms(500); + nvic_irq_disable(EXTI0_IRQn); JumpAddress = *(__IO uint32_t *)(APPLICATION_ADDRESS + 4); // application main address diff --git a/menu.h b/menu.h index 901ed972f4ba4cb9240473ccb358d9fe9c3e033a..3537aa2f67113760aa47035a53fb3fcec22be152 100644 --- a/menu.h +++ b/menu.h @@ -15,6 +15,8 @@ #include "bsp_ocflash.h" #include "bsp_uart.h" + + void PrintMenu(void); void LoadRunApplication(void); diff --git a/ymodem.c b/ymodem.c index 586530ff806665da3d6195551584b5e81edebbe1..cb6579317020c49bdef9339057afbaf9fdabd6f2 100644 --- a/ymodem.c +++ b/ymodem.c @@ -2,7 +2,7 @@ * @Author: Ma Yuchen * @Date: 2022-11-23 23:29:58 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-24 11:18:50 + * @LastEditTime: 2022-11-26 12:03:43 * @Description: file content * @FilePath: \BootLoader\ymodem.c */ @@ -10,8 +10,311 @@ #include "bsp_ocflash.h" #include "bsp_uart.h" -int Ymodem_Receive(uint8_t* buffer) +typedef struct _YModemInfo { - //TODO + int packet_length; + int file_size; + uint8_t session_done; + uint8_t session_begin; + uint8_t errors; + + uint8_t pakcets_received; + uint8_t file_done; + + uint8_t packet_data[PACKET_OVERHEAD + PACKET_DATA_LENGTH]; + + uint8_t revice[2]; +} YModemInfo; + +uint8_t FileName[FILE_NAME_LENGTH] = {0}; + +static int Receive_Byte(uint8_t *c, uint32_t timeout) +{ + while (timeout-- > 0) + { + if (1 == SerialKeyPressed(c)) + { + return 0; + } + } + + return -1; +} + +static int Send_Byte(uint8_t c) +{ + SerialPutChar(c); + return 0; +} + +static uint16_t UpdateCrc16(uint16_t crc, uint8_t d) +{ + uint8_t count = 8; + uint16_t newCrc = crc; + uint16_t data = d; + + while ((count--) > 0) + { + if (newCrc & 0x8000) + { + newCrc <<= 1; + newCrc += (((data <<= 1) & 0x0400) != 0); + newCrc ^= 0x1021; + } + else + { + newCrc <<= 1; + newCrc += (((data <<= 1) & 0x0400) != 0); + } + } + + return newCrc; +} + +static uint16_t ClcCrc16(const uint8_t *datas, int size) +{ + uint16_t crc = 0; + + const uint8_t *endofDatas = datas + size; + + while (datas < endofDatas) + { + crc = UpdateCrc16(crc, *datas); + datas++; + } + crc = UpdateCrc16(crc, 0); + crc = UpdateCrc16(crc, 0); + + return (crc & (uint16_t)0xffff); +} + +/** + * @brief + * + * @param buffer + * @param length + * @param timeout + * @return int + * 0 ok + * -1 receive timeout or header falied + * -2 packet no error + * -3 crc error + */ +static int Receive_Packet(uint8_t *buffer, int32_t *length, uint32_t timeout) +{ + uint16_t i, packet_size, computedcrc; + uint8_t data; + *length = 0; + + if (Receive_Byte(&data, timeout) != 0) + { + return -1; + } + + switch (data) + { + case SOH: + packet_size = PACKET_SIZE; + break; + case STX: + packet_size = PACKET_DATA_LENGTH; + break; + case CAN: + //if two CAN return length -1 + if((Receive_Byte(&data, timeout) == 0) && (CAN == data)) + { + *length=-1; + return 0; + } + else + { + return -1; + } + case EOT: + return 0; + default: + return -1; + } + + *buffer = data; // buffer store header in buffer[0]; + + // receive packet + for (i = 1; i < packet_size; i++) + { + if (Receive_Byte(buffer + i, timeout) != 0) + { + return -1; + } + } + + // check packet no + if (buffer[PACKET_NO_INDEX] != ((buffer[PACKET_NO_N_INDEX] ^ 0xff) & 0xff)) + { + return -2; + } + + computedcrc = ClcCrc16(buffer[PACKET_HEADER], (int)packet_size); + + if (computedcrc != (((uint16_t)buffer[packet_size + 3] << 8) | buffer[packet_size + 4])) + { + return -3; + } + + *length = packet_size; + return 0; } + +/** + * @brief 完成Ymodem 下Receiver的功能 + * 1.接收数据包 如果是第一次能判定为文件信息描述包 + * 2.接收所有的数据数据包,如果接收到合法的数据包,则提取数据后,直接烧写flash中 + * + * @param buffer + * @return int + */ +int Ymodem_Receive(uint8_t *buffer) +{ + YModemInfo yModemInfo; + int i; + uint8_t* buf_ptr; + uint8_t* file_ptr; + uint8_t fileSizeStr[FILE_SIZE_LENGTH]={0}; + //int fileLength = 0; + uint32_t flashDestination = APPLICATION_ADDRESS; + uint32_t ramSourceAddr=0; + + memset(&yModemInfo, 0, sizeof(YModemInfo)); + + + + //session + while (yModemInfo.session_done == 0) + { + yModemInfo.pakcets_received=0; + yModemInfo.file_done=0; + //packet + while (yModemInfo.file_done == 0) + { + switch (Receive_Packet(yModemInfo.packet_data, &(yModemInfo.packet_length), NAK_TIMEOUT)) + { + case 0: + yModemInfo.errors=0; + + switch (yModemInfo.packet_length) + { + //CAN + //abort by Sender + case -1: + Send_Byte(ACK); + return 0; + //End of this file transmission + case 0: + Send_Byte(ACK); + yModemInfo.file_done=1; + break; + default://Normal Packet + //Check receive pakcet number + if((yModemInfo.packet_data[PACKET_NO_INDEX] & 0xff) != (yModemInfo.pakcets_received & 0xff)) + { + Send_Byte(NAK); + } + else + { + if(yModemInfo.pakcets_received==0) + //Filename Packet + { + if(yModemInfo.packet_data[PACKET_HEADER] !=0) + { + for(i=0, file_ptr=yModemInfo.packet_data+PACKET_HEADER; + (*file_ptr!=0) && i (int32_t)(USER_FLASH_SIZE)) + { + //end session + Send_Byte(CAN); + Send_Byte(CAN); + + return -1; + } + + Flash_IF_App_Erase(APPLICATION_START_SECTOR, APPLICATION_END_SECTOR); + Send_Byte(ACK); + Send_Byte(CRC16); + } + else + { + Send_Byte(ACK); + yModemInfo.file_done=1; + yModemInfo.session_done=1; + break; + } + } + //Data Packet + else + { + // buf_ptr=buffer; + // memcpy(buf_ptr, yModemInfo.packet_data+PACKET_HEADER, (uint32_t)yModemInfo.packet_length); + + // ramSourceAddr=(uint32_t)buf_ptr; + ramSourceAddr=(uint32_t)(yModemInfo.packet_data+PACKET_HEADER); + if(0 == Flash_IF_Write(&flashDestination, (uint32_t *)ramSourceAddr, yModemInfo.pakcets_received/4)) + { + Send_Byte(ACK); + } + else + { + Send_Byte(CAN); + Send_Byte(CAN); + return -2; + } + } + + yModemInfo.pakcets_received++; + yModemInfo.session_begin=1; + } + break; + } + break; + case 1: + Send_Byte(CAN); + Send_Byte(CAN); + return -3; + default: + // 如果session已经开始 + if (yModemInfo.session_begin > 0) + // 则累计一次错误计数 + { + yModemInfo.errors++; + } + + if (yModemInfo.errors > MAX_ERRORS) + { + Send_Byte(CAN); + Send_Byte(CAN); + return 0; + } + + Send_Byte(CRC16); // Send ‘C' to CommInit + break; + } + } + } + + return yModemInfo.file_size; +} diff --git a/ymodem.h b/ymodem.h index 6a96b909de468e2796538c2ec84ebfbfbed5ad09..a71a416e69fbd5d1e5e771350208aeb3d7fbe2bf 100644 --- a/ymodem.h +++ b/ymodem.h @@ -2,14 +2,14 @@ * @Author: Ma Yuchen * @Date: 2022-11-23 23:30:07 * @LastEditors: Ma YuChen - * @LastEditTime: 2022-11-24 11:18:30 + * @LastEditTime: 2022-11-24 18:51:22 * @Description: Y Modem File Transport Protocol Define func * this Protocel can be used when uart is only IO interface on MCU * @FilePath: \BootLoader\ymodem.h */ #ifndef Y_MODEM_H #define Y_MODEM_H - +#include #include /*Ymodem Frame base on ASCII Encode*/ @@ -32,10 +32,14 @@ #define FILE_NAME_LENGTH (256) #define FILE_SIZE_LENGTH (16) +#define PACKET_NO_INDEX (1) +#define PACKET_NO_N_INDEX (2) + #define NAK_TIMEOUT (0x100000) #define MAX_ERRORS (5) +extern uint8_t FileName[]; int Ymodem_Receive(uint8_t* buffer);