diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/Makefile index 463b67808..e27bfd216 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/Makefile @@ -6,6 +6,9 @@ endif ifeq ($(CONFIG_BSP_USING_OTA),y) SRC_FILES += fsl_romapi.c flash.c mcuboot.c + ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y) + SRC_FILES += common.c ymodem.c + endif endif include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/common.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/common.c new file mode 100644 index 000000000..133fd7c69 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/common.c @@ -0,0 +1,275 @@ + +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: common.c +* @brief: file common.c +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/24 +*/ + + +#include "common.h" + +/** + * @brief Convert an Integer to a string + * @param str: The string + * @param intnum: The intger to be converted + * @retval None + */ +void Int2Str(uint8_t* str, int32_t intnum) +{ + uint32_t i, Div = 1000000000, j = 0, Status = 0; + + for (i = 0; i < 10; i++) + { + str[j++] = (intnum / Div) + 48; + + intnum = intnum % Div; + Div /= 10; + if ((str[j-1] == '0') & (Status == 0)) + { + j = 0; + } + else + { + Status++; + } + } +} + +/** + * @brief Convert a string to an integer + * @param inputstr: The string to be converted + * @param intnum: The intger value + * @retval 1: Correct + * 0: Error + */ +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 Get an integer from the HyperTerminal + * @param num: The inetger + * @retval 1: Correct + * 0: Error + */ +uint32_t GetIntegerInput(int32_t * num) +{ + uint8_t inputstr[16]; + + while (1) + { + GetInputString(inputstr); + if (inputstr[0] == '\0') continue; + if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0') + { + Serial_PutString("User Cancelled \r\n"); + return 0; + } + + if (Str2Int(inputstr, num) == 0) + { + Serial_PutString("Error, Input again: \r\n"); + } + else + { + return 1; + } + } +} + +/** + * @brief Test to see if a key has been pressed on the HyperTerminal + * @param key: The key pressed + * @retval 1: Correct + * 0: Error + */ +uint32_t SerialKeyPressed(uint8_t *key) +{ + if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART1)) + { + *key = LPUART_ReadByte(LPUART1); + return 1; + } + else + { + return 0; + } +} + +/** + * @brief Get a key from the HyperTerminal + * @param None + * @retval The Key Pressed + */ +uint8_t GetKey(void) +{ + uint8_t key = 0; + + /* Waiting for user input */ + while (1) + { + if (SerialKeyPressed((uint8_t*)&key)) break; + } + return key; + +} + +/** + * @brief Print a character on the HyperTerminal + * @param c: The character to be printed + * @retval None + */ +void SerialPutChar(uint8_t c) +{ + LPUART_WriteByte(LPUART1,c); + while(!(kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1))) + { + } +} + +/** + * @brief Print a string on the HyperTerminal + * @param s: The string to be printed + * @retval None + */ +void Serial_PutString(uint8_t *s) +{ + while (*s != '\0') + { + SerialPutChar(*s); + s++; + } +} + +/** + * @brief Get Input string from the HyperTerminal + * @param buffP: The input string + * @retval None + */ +void GetInputString (uint8_t * buffP) +{ + uint32_t bytes_read = 0; + uint8_t c = 0; + do + { + c = GetKey(); + if (c == '\r') + break; + if (c == '\b') /* Backspace */ + { + if (bytes_read > 0) + { + Serial_PutString("\b \b"); + bytes_read --; + } + continue; + } + if (bytes_read >= CMD_STRING_SIZE ) + { + Serial_PutString("Command string size overflow\r\n"); + bytes_read = 0; + continue; + } + if (c >= 0x20 && c <= 0x7E) + { + buffP[bytes_read++] = c; + SerialPutChar(c); + } + } + while (1); + Serial_PutString(("\n\r")); + buffP[bytes_read] = '\0'; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c index bf9278cb6..69f97ddf2 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c @@ -25,7 +25,7 @@ /******************************************************************************* * Prototypes ******************************************************************************/ - +uint8_t NorFlash_BUFFER[4096]; //4K buffer cache uint8_t buffer[FLASH_PAGE_SIZE]; //256 bytes buffer cache /******************************************************************************* * Variables @@ -264,13 +264,13 @@ status_t FLASH_EraseSector(uint32_t addr) * @param len : 字节数 * @retval kStatus_Success:完成 */ -status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len) +status_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len) { status_t status; addr &= 0x0FFFFFFF; __disable_irq(); norConfig.pageSize = len; - status = ROM_FLEXSPI_NorFlash_ProgramPage(0, &norConfig, addr, (const uint32_t *)buf); + status = ROM_FLEXSPI_NorFlash_ProgramPage(0, &norConfig, addr, buf); __enable_irq(); return status; @@ -282,7 +282,7 @@ status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len) * @param len : 字节数 * @retval kStatus_Success:完成 */ -status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len) +status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len) { status_t status; flexspi_xfer_t flashXfer; @@ -294,7 +294,7 @@ status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len) flashXfer.seqId = NOR_CMD_LUT_SEQ_IDX_READ; flashXfer.baseAddress = addr; flashXfer.isParallelModeEnable = false; - flashXfer.rxBuffer = (uint32_t *)buf; + flashXfer.rxBuffer = buf; flashXfer.rxSize = len; __disable_irq(); @@ -338,7 +338,7 @@ status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt) */ status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt) { - return FLASH_WritePage(start_addr, buf, byte_cnt); + return FLASH_WritePage(start_addr, (void *)buf, byte_cnt); } /** @@ -353,7 +353,7 @@ status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len) /* For FlexSPI Memory ReadBack, use IP Command instead of AXI command for security */ if((addr >= 0x60000000) && (addr < 0x70000000)) { - return FLASH_Read(addr, buf, len); + return FLASH_Read(addr, (void *)buf, len); } else @@ -433,4 +433,184 @@ status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize) } return (status_t)kStatus_Success; -} \ No newline at end of file +} + +status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize) +{ + uint16_t i; + uint32_t sectorNum = (imageSize%4096 != 0)? (imageSize/4096 + 1):(imageSize/4096); + + for(i=0;ipageRemain + { + pBuffer += pageRemain; + WriteAddr += pageRemain; + + NumByteToWrite -= pageRemain;//减去已经写入了的字节数 + if(NumByteToWrite > 256) + { + pageRemain = 256;//一次可以写入256个字节 + } + else + { + pageRemain = NumByteToWrite;//不够256个字节了 + } + } + } +} + +void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) +{ + uint32_t secPos; + uint16_t secOff; + uint16_t secRemain; + uint16_t i; + uint8_t *NorFlash_BUF = 0; + + NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K + + WriteAddr &= 0x0FFFFFFF; + + secPos = WriteAddr/SECTOR_SIZE;//扇区地址 + secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移 + secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小 + + if(NumByteToWrite <= secRemain) + { + secRemain = NumByteToWrite;//不大于4096个字节 + } + while(1) + { + FLASH_Read(FLASH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容 + for(i=0;i 4096) + { + secRemain = 4096;//下一个扇区还是写不完 + } + else + { + secRemain = NumByteToWrite;//下一个扇区可以写完了 + } + } + } +} + +#ifndef USE_HIGHT_SPEED_TRANS +uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength) +{ + uint32_t WriteAddr; + WriteAddr = *FlashAddress; + NorFlash_Write(Data,WriteAddr,DataLength); + *FlashAddress += DataLength; + return 0; +} +#else +uint8_t packetNum = 0; +uint32_t dataLen = 0; +uint32_t WriteAddr; +uint8_t dataBuff[5*1024]; +uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag) +{ + if(!doneFlag) + { + memcpy(&dataBuff[dataLen],Data,DataLength); + dataLen += DataLength; + packetNum ++; + if(1 == packetNum) + { + WriteAddr = *FlashAddress; + } + + if(dataLen>=4096) + { + NorFlash_Write(dataBuff,WriteAddr,dataLen); + packetNum = 0; + dataLen = 0; + } + *FlashAddress += DataLength; + } + else + { + NorFlash_Write(dataBuff,WriteAddr,dataLen); + packetNum = 0; + dataLen = 0; + } + return (0); +} +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c index 19e5ef712..617781a53 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c @@ -12,22 +12,16 @@ * @author AIIT XUOS Lab * @date 2023-04-03 */ - + +#include +#include #include "flash.h" -#include "stdint.h" #include "mcuboot.h" +#include "ymodem.h" +#include "common.h" #ifdef MCUBOOT_BOOTLOADER -static void JumpToApp(void) -{ - asm volatile("LDR R0, = 0x60100000"); - asm volatile("LDR R0, [R0]"); - asm volatile("MOV SP, R0"); - - asm volatile("LDR R0, = 0x60100000+4"); - asm volatile("LDR R0, [R0]"); - asm volatile("BX R0"); -} +extern void ImxrtMsDelay(uint32 ms); static uint32_t UartSrcFreq(void) { @@ -55,32 +49,72 @@ static void UartConfig(void) LPUART_Init(LPUART1, &config, UartSrcFreq()); } -static void SerialPutC(uint8_t c) +static void jump_to_application(void) { - LPUART_WriteByte(LPUART1, c); - while(!(kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1))) - { - } -} + SCB->VTOR = (uint32_t)0x60100000; -static void SerialPutString(uint8_t *s) -{ - while (*s != '\0') { - SerialPutC(*s); - s++; - } + asm volatile("LDR R0, = 0x60100000"); + asm volatile("LDR R0, [R0]"); + asm volatile("MOV SP, R0"); + + asm volatile("LDR R0, = 0x60100000+4"); + asm volatile("LDR R0, [R0]"); + asm volatile("BX R0"); } void BootLoaderJumpApp(void) { + uint8_t ch1, ch2; + uint32_t ret; + uint32_t timeout = 500; + BOARD_ConfigMPU(); BOARD_InitPins(); BOARD_BootClockRUN(); - UartConfig(); + SysTick_Config(SystemCoreClock / TICK_PER_SECOND); + + Serial_PutString("Please press 'space' key into menu in 5s !!!\r\n"); - SerialPutString("BOOTLOADER START AND JUMP TO APP[0x60100000]\n"); - SCB->VTOR = (uint32_t)0x60100000; - JumpToApp(); + while(timeout) + { + ret = (SerialKeyPressed((uint8_t*)&ch1)); + if(ret) break; + timeout--; + ImxrtMsDelay(10); + } + + while(1) + { + if((ret)&&(ch1 == 0x20)) + { + Serial_PutString("\r\nPlease slecet:"); + Serial_PutString("\r\n 1:run app"); + Serial_PutString("\r\n 2:update app"); + Serial_PutString("\r\n 3:reboot \r\n"); + + ch2 = GetKey(); + switch(ch2) + { + case 0x31: + jump_to_application(); + break; + case 0x32: + FLASH_Init(); + SerialDownload(); + FLASH_DeInit(); + break; + case 0x33: + __set_FAULTMASK(1); + NVIC_SystemReset(); + default: + break; + } + } + else + { + jump_to_application(); + } + } } #endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c new file mode 100644 index 000000000..fff3ef2be --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/ymodem.c @@ -0,0 +1,391 @@ + +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: ymodem.c +* @brief: file ymodem.c +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/24 +*/ + + +#include "common.h" +#include "ymodem.h" +#include "string.h" +#include "flash.h" + +#define BL_APP_VECTOR_TABLE_ADDRESS 0x60100000 + +uint8_t tab_1024[1024] ={0}; +uint8_t FileName[FILE_NAME_LENGTH]; + + +/** + * @brief Receive byte from sender + * @param c: Character + * @param timeout: Timeout + * @retval 0: Byte received + * -1: Timeout + */ +static int32_t Receive_Byte (uint8_t *c, uint32_t timeout) +{ + while (timeout-- > 0) + { + if (SerialKeyPressed(c) == 1) + { + return 0; + } + } + return -1; +} + +/** + * @brief Send a byte + * @param c: Character + * @retval 0: Byte sent + */ +static 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(data0: packet length + * @retval 0: normally return + * -1: timeout or packet error + * 1: abort by user + */ +static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout) +{ + uint16_t i, packet_size, computedcrc; + uint8_t c; + *length = 0; + if (Receive_Byte(&c, timeout) != 0) + { + 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; + for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++) + { + if (Receive_Byte(data + i, timeout) != 0) + { + return -1; + } + } + if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)) + { + return -1; + } + + /* Compute the CRC */ + computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size); + /* 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])) + { + /* 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 + */ +int32_t Ymodem_Receive (uint8_t *buf) +{ + uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; + int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; + uint32_t flashdestination; + + /* Initialize flashdestination variable */ + flashdestination = BL_APP_VECTOR_TABLE_ADDRESS; + + 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: + 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)) + { + 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); + + /* Test the size of the image to be sent */ + /* Image size is greater than Flash size */ + if (size > (USER_FLASH_SIZE + 1)) + { + /* End session */ + Send_Byte(CA); + Send_Byte(CA); + return -1; + } + /* erase user application area */ + + NOR_FLASH_Erase(BL_APP_VECTOR_TABLE_ADDRESS,size); + 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); + + /* Write received data in Flash */ +#ifndef USE_HIGHT_SPEED_TRANS + if (NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length) == 0) +#else + if (NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,0) == 0) +#endif + { + Send_Byte(ACK); + } + else /* An error occurred while writing to Flash memory */ + { + /* 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; + } + } +#ifdef USE_HIGHT_SPEED_TRANS + NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,1); +#endif + return (int32_t)size; +} + +/** + * @brief Download a file via serial port + * @param None + * @retval None + */ +void SerialDownload(void) +{ + uint8_t Number[10] = {0}; + int32_t Size = 0; + + Serial_PutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r"); + Size = Ymodem_Receive(&tab_1024[0]); + if (Size > 0) + { + Serial_PutString("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name: "); + Serial_PutString(FileName); + Int2Str(Number, Size); + Serial_PutString("\n\r Size: "); + Serial_PutString(Number); + Serial_PutString(" Bytes\r\n"); + Serial_PutString("-------------------\n"); + } + else if (Size == -1) + { + Serial_PutString("\n\n\rThe image size is higher than the allowed space memory!\n\r"); + } + else if (Size == -2) + { + Serial_PutString("\n\n\rVerification failed!\n\r"); + } + else if (Size == -3) + { + Serial_PutString("\r\n\nAborted by user.\n\r"); + } + else + { + Serial_PutString("\n\rFailed to receive the file!\n\r"); + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/common.h b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/common.h new file mode 100644 index 000000000..f645ac52f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/common.h @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: common.h +* @brief: file common.h +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/24 +*/ + +#ifndef _COMMON_H +#define _COMMON_H + +#include "fsl_common.h" +#include "fsl_lpuart.h" + +#define CMD_STRING_SIZE 128 +#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)) + +void Int2Str(uint8_t* str,int32_t intnum); +uint32_t Str2Int(uint8_t *inputstr,int32_t *intnum); +uint32_t GetIntegerInput(int32_t * num); +uint32_t SerialKeyPressed(uint8_t *key); +uint8_t GetKey(void); +void SerialPutChar(uint8_t c); +void Serial_PutString(uint8_t *s); +void GetInputString(uint8_t * buffP); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h index 46b96f58f..190854ac4 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/flash.h @@ -19,18 +19,32 @@ #include #include "fsl_romapi.h" +#define USE_HIGHT_SPEED_TRANS 1 +#define FLASH_BASE 0x60000000 +#define SECTOR_SIZE 0x1000 +#define FLASH_PAGE_SIZE 256 + void FLASH_Init(void); void FLASH_DeInit(void); uint32_t FLASH_GetSectorSize(void); -status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len); +status_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len); status_t FLASH_EraseSector(uint32_t addr); -status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len); -uint32_t FLASH_Test(uint32_t startAddr, uint32_t len); -uint32_t FLASH_GetProgramCmd(void); +status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len); status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt); status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt); status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len); status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize); +status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize); +status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize); +void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); +void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); +void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); +#ifndef USE_HIGHT_SPEED_TRANS +uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength); +#else +uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag); +#endif + #endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/ymodem.h b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/ymodem.h new file mode 100644 index 000000000..c2eac308c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/ymodem.h @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: ymodem.h +* @brief: file ymodem.h +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/24 +*/ + + +#ifndef _YMODEM_H_ +#define _YMODEM_H_ + +#include + +#define BL_APP_VECTOR_TABLE_ADDRESS 0x60100000 //Application start address +#define USER_FLASH_SIZE 0x100000 //Application package size is limited to 1M +#define PACKET_SEQNO_INDEX (1) +#define PACKET_SEQNO_COMP_INDEX (2) + +#define PACKET_HEADER (3) +#define PACKET_TRAILER (2) +#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER) +#define PACKET_SIZE (128) +#define PACKET_1K_SIZE (1024) + +#define FILE_NAME_LENGTH (256) +#define FILE_SIZE_LENGTH (16) + +#define SOH (0x01) /* start of 128-byte data packet */ +#define STX (0x02) /* start of 1024-byte data packet */ +#define EOT (0x04) /* end of transmission */ +#define ACK (0x06) /* acknowledge */ +#define NAK (0x15) /* negative acknowledge */ +#define CA (0x18) /* two of these in succession aborts transfer */ +#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */ + +#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */ +#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */ + +#define NAK_TIMEOUT (0x100000) +#define MAX_ERRORS (5) + +void SerialDownload(void); +int32_t Ymodem_Receive (uint8_t *); + +#endif