/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "fatfs.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "string.h" #include "stdio.h" #include "FLASH_SECTOR_H7.h" #include "fatfs_sd.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define TX_TIMEOUT ((uint32_t)100) #define RX_TIMEOUT HAL_MAX_DELAY #define CRC16 ((uint8_t)0x43) /* 'C' == 0x43, request 16-bit CRC */ /* Define the user application size */ #define USER_FLASH_SIZE ((uint32_t)0x00100000) /* Small default template application */ #define APPLICATION_ADDRESS (uint32_t)0x08100000 /* Start user code address: ADDR_FLASH_PAGE_8 */ #define CRC16_F #define MAX_RETRY 500 #define ret_error -1 #define RECV_BYTES 160 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ uint8_t aFileName[FILE_NAME_LENGTH]; /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ SPI_HandleTypeDef hspi1; UART_HandleTypeDef huart2; UART_HandleTypeDef huart3; /* USER CODE BEGIN PV */ char status[RECV_BYTES]; int resp = 0; uint32_t size = 0; uint8_t retry = 0; uint8_t rx_prompt[15] = {0}; FATFS fs; // file system FIL fil; // File FILINFO fno; FRESULT fresult; // result UINT br, bw; // File read/write count /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USB_OTG_HS_USB_Init(void); static void MX_USART3_UART_Init(void); static void MX_USART2_UART_Init(void); static void MX_SPI1_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length); static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk); uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte); uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size); uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size); COM_StatusTypeDef Ymodem_Transmit(uint8_t *p_buf, const uint8_t *p_file_name, uint32_t file_size); void Serial_PutString(char *p_string); char asciiToSentence(char str, int len); HAL_StatusTypeDef Serial_PutByte( uint8_t param ); static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout); void Int2Str(uint8_t *p_str, uint32_t intnum); uint32_t Str2Int(uint8_t *inputstr, uint32_t *intnum); COM_StatusTypeDef Ymodem_Receive(uint32_t *p_size); void handleData(void); int check_prompt(void); int download_file(void); int is_C_recv(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(resp == 0) { if(HAL_UART_Receive_IT(&huart2, (uint8_t*)status, RECV_BYTES) != HAL_OK) Error_Handler(); } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ COM_StatusTypeDef result = COM_OK; char *command; int8_t ret = 0; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USB_OTG_HS_USB_Init(); MX_USART3_UART_Init(); MX_USART2_UART_Init(); MX_SPI1_Init(); MX_FATFS_Init(); /* USER CODE BEGIN 2 */ //Download ROM Boot file to flash ret = download_file(); if(ret != 0) { return ret_error; } resp = 0; HAL_UART_Receive_IT(&huart2, (uint8_t*)status, RECV_BYTES); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (!resp) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(HAL_UART_Transmit(&huart2,(uint8_t *)"dd" , 2, TX_TIMEOUT) != HAL_OK) Error_Handler(); //Handle the received data handleData(); } Serial_PutString(status); HAL_Delay(800); if(HAL_UART_Transmit(&huart2,(uint8_t *)"down" , 4, TX_TIMEOUT) != HAL_OK) Error_Handler(); //Check for C ret = is_C_recv(); if(ret != 1) { return ret_error; } /* Transmit the ROM Boot flash image through ymodem protocol */ result = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"u-boot-7243i_v0.72_recovery_test.bin", size); if (result != COM_OK) { Serial_PutString("\n\rError Occurred while Transmitting ROM Boot File\n\r"); return ret_error; } else { Serial_PutString("\n\r ROM Boot File uploaded successfully \n\r"); } //Check for GDM7243> Prompt ret = check_prompt(); if(ret != 0) { return ret_error; } //Download SBL to flash ret = download_file(); if(ret != 0) { return ret_error; } command = "run imagedn\r"; if(HAL_UART_Transmit(&huart2,(uint8_t*)command,strlen(command), TX_TIMEOUT) != HAL_OK) Error_Handler(); ret = is_C_recv(); if(ret != 1) { return ret_error; } /* Transmit the SBL flash image through ymodem protocol */ result = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"sbl_7243i_v1.0_test.bin", size); if (result != COM_OK) { Serial_PutString("\n\rError Occurred while Transmitting Secondary Bootloader File\n\r"); return ret_error; } else { Serial_PutString("\n\r Secondary bootloader uploaded successfully \n\r"); } //Check for GDM7243 prompt ret = check_prompt(); if(ret != 0) { return ret_error; } command = "run sblsave\r"; if(HAL_UART_Transmit(&huart2,(uint8_t*)command,strlen(command), TX_TIMEOUT) != HAL_OK) Error_Handler(); //Check for GDM7243 prompt ret = check_prompt(); if(ret != 0) { return ret_error; } //Download U Boot File to Flash ret = download_file(); if(ret != 0) { return ret_error; } command = "run imagedn\r"; if(HAL_UART_Transmit(&huart2,(uint8_t*)command,strlen(command), TX_TIMEOUT) != HAL_OK) Error_Handler(); ret = is_C_recv(); if(ret != 1) { return ret_error; } /* Transmit the U Boot flash image through ymodem protocol */ result = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"u-boot-7243i_v0.72_test.bin", size); if (result != COM_OK) { Serial_PutString("\n\rError Occurred while Transmitting U Boot File\n\r"); return ret_error; } else { Serial_PutString("\n\r U Boot uploaded successfully \n\r"); } //Check for GDM7243 prompt ret = check_prompt(); if(ret != 0) { return ret_error; } command = "run bootsave\r"; if(HAL_UART_Transmit(&huart2,(uint8_t*)command,strlen(command), TX_TIMEOUT) != HAL_OK) Error_Handler(); //Check for GDM7243 prompt ret = check_prompt(); if(ret != 0) { return ret_error; } //Serial_PutString("Flashing Completed"); HAL_Delay (500); fresult = f_mount(&fs, "/", 1); if (fresult != FR_OK) Serial_PutString ("ERROR!!! in mounting SD CARD...\n\n"); else { Serial_PutString("\n\r SD CARD mounted successfully...\n\n"); fresult = f_open (&fil, "zephyr_20210506_nbiot_quad_12ec59.bin", FA_READ); /* Transmit the U Boot flash image through ymodem protocol */ result = Ymodem_Transmit(&fil, (const uint8_t*)"zephyr_20210506_nbiot_quad_12ec59.bin", 5601949); if (result != COM_OK) { Serial_PutString("\n\rError Occurred while Transmitting Image File\n\r"); return ret_error; } else { Serial_PutString("\n\r Image File uploaded successfully \n\r"); } } //return 0; /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 24; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /** * @brief SPI1 Initialization Function * @param None * @retval None */ static void MX_SPI1_Init(void) { /* USER CODE BEGIN SPI1_Init 0 */ /* USER CODE END SPI1_Init 0 */ /* USER CODE BEGIN SPI1_Init 1 */ /* USER CODE END SPI1_Init 1 */ /* SPI1 parameter configuration*/ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 0x0; hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; hspi1.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; hspi1.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI1_Init 2 */ /* USER CODE END SPI1_Init 2 */ } /** * @brief USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 921600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ } /** * @brief USART3 Initialization Function * @param None * @retval None */ static void MX_USART3_UART_Init(void) { /* USER CODE BEGIN USART3_Init 0 */ /* USER CODE END USART3_Init 0 */ /* USER CODE BEGIN USART3_Init 1 */ /* USER CODE END USART3_Init 1 */ huart3.Instance = USART3; huart3.Init.BaudRate = 921600; huart3.Init.WordLength = UART_WORDLENGTH_8B; huart3.Init.StopBits = UART_STOPBITS_1; huart3.Init.Parity = UART_PARITY_NONE; huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.OverSampling = UART_OVERSAMPLING_16; huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart3) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART3_Init 2 */ /* USER CODE END USART3_Init 2 */ } /** * @brief USB_OTG_HS Initialization Function * @param None * @retval None */ static void MX_USB_OTG_HS_USB_Init(void) { /* USER CODE BEGIN USB_OTG_HS_Init 0 */ /* USER CODE END USB_OTG_HS_Init 0 */ /* USER CODE BEGIN USB_OTG_HS_Init 1 */ /* USER CODE END USB_OTG_HS_Init 1 */ /* USER CODE BEGIN USB_OTG_HS_Init 2 */ /* USER CODE END USB_OTG_HS_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(USB_FS_PWR_EN_GPIO_Port, USB_FS_PWR_EN_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : B1_Pin */ GPIO_InitStruct.Pin = B1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : USB_FS_PWR_EN_Pin */ GPIO_InitStruct.Pin = USB_FS_PWR_EN_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(USB_FS_PWR_EN_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : LD1_Pin LD3_Pin */ GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PD14 */ GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /*Configure GPIO pin : USB_FS_OVCR_Pin */ GPIO_InitStruct.Pin = USB_FS_OVCR_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(USB_FS_OVCR_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : USB_FS_ID_Pin */ GPIO_InitStruct.Pin = USB_FS_ID_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS; HAL_GPIO_Init(USB_FS_ID_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : USB_FS_N_Pin USB_FS_P_Pin */ GPIO_InitStruct.Pin = USB_FS_N_Pin|USB_FS_P_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : LD2_Pin */ GPIO_InitStruct.Pin = LD2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ int is_C_recv() { retry = 0; uint8_t crc_recpt = 0; uint8_t cstat = 0; while( !crc_recpt) { if (HAL_UART_Receive(&huart2, &cstat, 1, RX_TIMEOUT) == HAL_OK) { if (cstat == CRC16) { crc_recpt = 1; return crc_recpt; } } retry ++; if( retry > MAX_RETRY) { Serial_PutString("\rCommand Not Executed Properly. Please try again later"); return ret_error; } } } int check_prompt() { retry = 0; while(strstr((char*)rx_prompt,"GDM7243") == NULL) { HAL_UART_Receive(&huart2, rx_prompt, 12, NAK_TIMEOUT); retry ++; if( retry > MAX_RETRY) { Serial_PutString("\rExitting..Please try again later.."); return ret_error; } } return 0; } int download_file() { COM_StatusTypeDef result = COM_OK; uint8_t number[11] = {0}; size = 0; Serial_PutString("Waiting for the file to be sent ... \n\r"); result = Ymodem_Receive( &size ); if (result == COM_OK) { Serial_PutString("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name: "); Serial_PutString((char*)aFileName); Int2Str(number, size); Serial_PutString("\n\r Size: "); Serial_PutString((char*)number); Serial_PutString(" Bytes\r\n"); Serial_PutString("-------------------\n"); return 0; } else if (result == COM_LIMIT) { Serial_PutString("\n\n\rThe image size is higher than the allowed space memory!\n\r"); return ret_error; } else if (result == COM_DATA) { Serial_PutString("\n\n\rVerification failed!\n\r"); return ret_error; } else if (result == COM_ABORT) { Serial_PutString("\r\n\nAborted by user.\n\r"); return ret_error; } else { Serial_PutString("\n\rFailed to receive the file!\n\r"); return ret_error; } } /** * @brief Transmit a file using the ymodem protocol * @param p_buf: Address of the first byte * @param p_file_name: Name of the file sent * @param file_size: Size of the transmission * @retval COM_StatusTypeDef result of the communication */ COM_StatusTypeDef Ymodem_Transmit (uint8_t *p_buf, const uint8_t *p_file_name, uint32_t file_size) { uint32_t errors = 0, ack_recpt = 0, size = 0, pkt_size; uint8_t *p_buf_int; COM_StatusTypeDef result = COM_OK; uint32_t blk_number = 1; uint8_t a_rx_ctrl[2]; uint8_t i; uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE]; #ifdef CRC16_F uint32_t temp_crc; #else /* CRC16_F */ uint8_t temp_chksum; #endif /* CRC16_F */ /* Prepare first block - header */ PrepareIntialPacket(aPacketData, p_file_name, file_size); while (( !ack_recpt ) && ( result == COM_OK )) { /* Send Packet */ HAL_UART_Transmit(&huart2, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT); /* Send CRC or Check Sum based on CRC16_F */ #ifdef CRC16_F temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE); uint8_t crc1 = temp_crc >> 8; uint8_t crc2 = temp_crc & 0xFF; HAL_UART_Transmit(&huart2, &crc1,1, NAK_TIMEOUT); HAL_UART_Transmit(&huart2, &crc2,1, NAK_TIMEOUT); #else /* CRC16_F */ temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE); HAL_UART_Transmit(&huart2, (uint8_t *)temp_chksum,1, NAK_TIMEOUT); #endif /* CRC16_F */ /* Wait for Ack and 'C' */ if (HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { if (a_rx_ctrl[0] == ACK) { Serial_PutString("Rcvd ACK"); ack_recpt = 1; } else if (a_rx_ctrl[0] == CA) { if ((HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA)) { HAL_Delay( 2 ); __HAL_UART_FLUSH_DRREGISTER(&huart2); __HAL_UART_CLEAR_IT(&huart2, UART_CLEAR_OREF); result = COM_ABORT; } } } else { errors++; } if (errors >= MAX_ERRORS) { result = COM_ERROR; } } p_buf_int = p_buf; size = file_size; /* Here 1024 bytes length is used to send the packets */ while ((size) && (result == COM_OK )) { /* Prepare next packet */ PreparePacket(p_buf_int, aPacketData, blk_number, size); ack_recpt = 0; a_rx_ctrl[0] = 0; errors = 0; /* Resend packet if NAK for few times else end of communication */ while (( !ack_recpt ) && ( result == COM_OK )) { /* Send next packet */ if (size >= PACKET_1K_SIZE) { pkt_size = PACKET_1K_SIZE; } else { pkt_size = PACKET_SIZE; } HAL_UART_Transmit(&huart2, &aPacketData[PACKET_START_INDEX], pkt_size + PACKET_HEADER_SIZE, NAK_TIMEOUT); /* Send CRC or Check Sum based on CRC16_F */ #ifdef CRC16_F temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], pkt_size); uint8_t crc1 = temp_crc >> 8; uint8_t crc2 = temp_crc & 0xFF; HAL_UART_Transmit(&huart2, &crc1,1, NAK_TIMEOUT); HAL_UART_Transmit(&huart2, &crc2,1, NAK_TIMEOUT); #else /* CRC16_F */ temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], pkt_size); Serial_PutByte(temp_chksum); #endif /* CRC16_F */ /* Wait for Ack */ if ((HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK)) { ack_recpt = 1; if (size > pkt_size) { p_buf_int += pkt_size; size -= pkt_size; if (blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE)) { result = COM_LIMIT; /* boundary error */ } else { blk_number++; } } else { p_buf_int += pkt_size; size = 0; } } else { errors++; } /* Resend packet if NAK for a count of 10 else end of communication */ if (errors >= MAX_ERRORS) { result = COM_ERROR; } } } /* Sending End Of Transmission char */ ack_recpt = 0; a_rx_ctrl[0] = 0x00; errors = 0; uint8_t end = 0x04; while (( !ack_recpt ) && ( result == COM_OK )) { HAL_UART_Transmit(&huart2, &end,1, NAK_TIMEOUT); /* Wait for Ack */ if (HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { if (a_rx_ctrl[0] == ACK) { ack_recpt = 1; } else if (a_rx_ctrl[0] == CA) { if ((HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA)) { HAL_Delay( 2 ); __HAL_UART_FLUSH_DRREGISTER(&huart2); __HAL_UART_CLEAR_IT(&huart2, UART_CLEAR_OREF); result = COM_ABORT; } } } else { errors++; } if (errors >= MAX_ERRORS) { result = COM_ERROR; } } /* Empty packet sent - some terminal emulators need this to close session */ if ( result == COM_OK ) { /* Preparing an empty packet */ aPacketData[PACKET_START_INDEX] = SOH; aPacketData[PACKET_NUMBER_INDEX] = 0; aPacketData[PACKET_CNUMBER_INDEX] = 0xFF; for (i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++) { aPacketData [i] = 0x00; } /* Send Packet */ HAL_UART_Transmit(&huart2, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT); /* Send CRC or Check Sum based on CRC16_F */ #ifdef CRC16_F temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE); uint8_t crc1 = temp_crc >> 8; uint8_t crc2 = temp_crc & 0xFF; HAL_UART_Transmit(&huart2, &crc1,1, NAK_TIMEOUT); HAL_UART_Transmit(&huart2, &crc2,1, NAK_TIMEOUT); #else /* CRC16_F */ temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE); Serial_PutByte(temp_chksum); #endif /* CRC16_F */ /* Wait for Ack and 'C' */ if (HAL_UART_Receive(&huart2, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { if (a_rx_ctrl[0] == CA) { HAL_Delay( 2 ); __HAL_UART_FLUSH_DRREGISTER(&huart2); __HAL_UART_CLEAR_IT(&huart2, UART_CLEAR_OREF); result = COM_ABORT; } } } return result; /* file transmitted successfully */ } /** * @brief Receive a file using the ymodem protocol with CRC16. * @param p_size The size of the file. * @retval COM_StatusTypeDef result of reception/programming */ COM_StatusTypeDef Ymodem_Receive ( uint32_t *p_size ) { uint32_t i, packet_length, session_done = 0, file_done, errors = 0, session_begin = 0; uint32_t flashdestination, ramsource, filesize; uint8_t *file_ptr; uint8_t file_size[FILE_SIZE_LENGTH], tmp, packets_received; COM_StatusTypeDef result = COM_OK; uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE]; /* Initialize flashdestination variable */ flashdestination = APPLICATION_ADDRESS; while ((session_done == 0) && (result == COM_OK)) { packets_received = 0; file_done = 0; while ((file_done == 0) && (result == COM_OK)) { switch (ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT)) { case HAL_OK: errors = 0; switch (packet_length) { case 2: /* Abort by sender */ Serial_PutByte(ACK); result = COM_ABORT; break; case 0: /* End of transmission */ Serial_PutByte(ACK); file_done = 1; break; default: /* Normal packet */ if (aPacketData[PACKET_NUMBER_INDEX] != packets_received) { Serial_PutByte(NAK); } else { if (packets_received == 0) { /* File name packet */ if (aPacketData[PACKET_DATA_INDEX] != 0) { /* File name extraction */ i = 0; file_ptr = aPacketData + PACKET_DATA_INDEX; while ( (*file_ptr != 0) && (i < FILE_NAME_LENGTH)) { aFileName[i++] = *file_ptr++; } /* File size extraction */ aFileName[i++] = '\0'; i = 0; file_ptr ++; while ( (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH)) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &filesize); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (*p_size > (USER_FLASH_SIZE + 1)) { /* End session */ tmp = CA; HAL_UART_Transmit(&huart3, &tmp, 1, NAK_TIMEOUT); HAL_UART_Transmit(&huart3, &tmp, 1, NAK_TIMEOUT); result = COM_LIMIT; } /* erase user application area */ Flash_Erase_Data(); *p_size = filesize; Serial_PutByte(ACK); Serial_PutByte(CRC16); } /* File header packet is empty, end session */ else { Serial_PutByte(ACK); file_done = 1; session_done = 1; break; } } else /* Data packet */ { ramsource = (uint32_t) & aPacketData[PACKET_DATA_INDEX]; /* Write received data in Flash */ if (Flash_Write_Data(flashdestination, (uint32_t*) ramsource, packet_length/4) == FLASHIF_OK) { flashdestination += packet_length; Serial_PutByte(ACK); } else /* An error occurred while writing to Flash memory */ { /* End session */ Serial_PutByte(CA); Serial_PutByte(CA); result = COM_DATA; } } packets_received ++; session_begin = 1; } break; } break; case HAL_BUSY: /* Abort actually */ Serial_PutByte(CA); Serial_PutByte(CA); result = COM_ABORT; break; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { /* Abort communication */ Serial_PutByte(CA); Serial_PutByte(CA); } else { Serial_PutByte(CRC16); /* Ask for a packet */ } break; } } } return result; } /** * @brief Receive a packet from sender * @param data * @param length * 0: end of transmission * 2: abort by sender * >0: packet length * @param timeout * @retval HAL_OK: normally return * HAL_BUSY: abort by user */ static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout) { uint32_t crc; uint32_t packet_size = 0; HAL_StatusTypeDef status; uint8_t char1; *p_length = 0; status = HAL_UART_Receive(&huart3, &char1, 1, timeout); if (status == HAL_OK) { switch (char1) { case SOH: packet_size = PACKET_SIZE; break; case STX: packet_size = PACKET_1K_SIZE; break; case EOT: break; case CA: if ((HAL_UART_Receive(&huart3, &char1, 1, timeout) == HAL_OK) && (char1 == CA)) { packet_size = 2; } else { status = HAL_ERROR; } break; case ABORT1: case ABORT2: status = HAL_BUSY; break; default: status = HAL_ERROR; break; } *p_data = char1; if (packet_size >= PACKET_SIZE ) { status = HAL_UART_Receive(&huart3, &p_data[PACKET_NUMBER_INDEX], packet_size + PACKET_OVERHEAD_SIZE, timeout); /* Simple packet sanity check */ if (status == HAL_OK ) { if (p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE)) { packet_size = 0; status = HAL_ERROR; } else { /* Check packet CRC */ crc = p_data[ packet_size + PACKET_DATA_INDEX ] << 8; crc += p_data[ packet_size + PACKET_DATA_INDEX + 1 ]; if (Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc ) { packet_size = 0; status = HAL_ERROR; } } } else { packet_size = 0; } } } *p_length = packet_size; return status; } /** * @brief Print a string on the HyperTerminal * @param p_string: The string to be printed * @retval None */ void Serial_PutString(char *p_string) { uint16_t length = 0; while (p_string[length] != '\0') { length++; } HAL_UART_Transmit(&huart3, (uint8_t*)p_string, length, TX_TIMEOUT); } /** * @brief Transmit a byte to the HyperTerminal * @param param The byte to be sent * @retval HAL_StatusTypeDef HAL_OK if OK */ HAL_StatusTypeDef Serial_PutByte( uint8_t param ) { /* May be timeouted... */ if ( huart3.gState == HAL_UART_STATE_TIMEOUT ) { huart3.gState = HAL_UART_STATE_READY; } return HAL_UART_Transmit(&huart3, ¶m, 1, TX_TIMEOUT); } /** * @brief Convert a string to an integer * @param p_inputstr: The string to be converted * @param p_intnum: The integer value * @retval 1: Correct * 0: Error */ uint32_t Str2Int(uint8_t *p_inputstr, uint32_t *p_intnum) { uint32_t i = 0, res = 0; uint32_t val = 0; if ((p_inputstr[0] == '0') && ((p_inputstr[1] == 'x') || (p_inputstr[1] == 'X'))) { i = 2; while ( ( i < 11 ) && ( p_inputstr[i] != '\0' ) ) { if (ISVALIDHEX(p_inputstr[i])) { val = (val << 4) + CONVERTHEX(p_inputstr[i]); } else { /* Return 0, Invalid input */ res = 0; break; } i++; } /* valid result */ if (p_inputstr[i] == '\0') { *p_intnum = val; res = 1; } } else /* max 10-digit decimal input */ { while ( ( i < 11 ) && ( res != 1 ) ) { if (p_inputstr[i] == '\0') { *p_intnum = val; /* return 1 */ res = 1; } else if (((p_inputstr[i] == 'k') || (p_inputstr[i] == 'K')) && (i > 0)) { val = val << 10; *p_intnum = val; res = 1; } else if (((p_inputstr[i] == 'm') || (p_inputstr[i] == 'M')) && (i > 0)) { val = val << 20; *p_intnum = val; res = 1; } else if (ISVALIDDEC(p_inputstr[i])) { val = val * 10 + CONVERTDEC(p_inputstr[i]); } else { /* return 0, Invalid input */ res = 0; break; } i++; } } return res; } /** * @brief Convert an Integer to a string * @param p_str: The string output pointer * @param intnum: The integer to be converted * @retval None */ void Int2Str(uint8_t *p_str, uint32_t intnum) { uint32_t i, divider = 1000000000, pos = 0, status = 0; for (i = 0; i < 10; i++) { p_str[pos++] = (intnum / divider) + 48; intnum = intnum % divider; divider /= 10; if ((p_str[pos-1] == '0') & (status == 0)) { pos = 0; } else { status++; } } } /** * @brief Prepare the first block * @param p_data: output buffer * @param p_file_name: name of the file to be sent * @param length: length of the file to be sent in bytes * @retval None */ static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length) { uint32_t i, j = 0; uint8_t astring[10] = {0}; /* first 3 bytes are constant */ p_data[PACKET_START_INDEX] = SOH; p_data[PACKET_NUMBER_INDEX] = 0x00; p_data[PACKET_CNUMBER_INDEX] = 0xff; /* Filename written */ for (i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++) { p_data[i + PACKET_DATA_INDEX] = p_file_name[i]; } p_data[i + PACKET_DATA_INDEX] = 0x00; /* file size written */ Int2Str (astring, length); i = i + PACKET_DATA_INDEX + 1; while (astring[j] != '\0') { p_data[i++] = astring[j++]; } /* padding with zeros */ for (j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++) { p_data[j] = 0; } } /** * @brief Prepare the data packet * @param p_source: pointer to the data to be sent * @param p_packet: pointer to the output buffer * @param pkt_nr: number of the packet * @param size_blk: length of the block to be sent in bytes * @retval None */ static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk) { uint8_t *p_record ; uint32_t i, size , packet_size; /* Make first three packet */ packet_size = size_blk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE; size = size_blk < packet_size ? size_blk : packet_size; if (packet_size == PACKET_1K_SIZE) { p_packet[PACKET_START_INDEX] = STX; } else { p_packet[PACKET_START_INDEX] = SOH; } p_packet[PACKET_NUMBER_INDEX] = pkt_nr; p_packet[PACKET_CNUMBER_INDEX] = (~pkt_nr); p_record = p_source; /* Filename packet has valid data */ for (i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX;i++) { p_packet[i] = *p_record++; } if ( size <= packet_size) { for (i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++) { p_packet[i] = 0x1A; /* EOF (0x1A) or 0x00 */ } } } /** * @brief Calculate Check sum for YModem Packet * @param p_data Pointer to input data * @param size length of input data * @retval uint8_t checksum value */ uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size) { uint32_t sum = 0; const uint8_t *p_data_end = p_data + size; while (p_data < p_data_end ) { sum += *p_data++; } return (sum & 0xffu); } /** * @brief Cal CRC16 for YModem Packet * @param data * @param length * @retval None */ uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size) { uint32_t crc = 0; const uint8_t* dataEnd = p_data+size; while(p_data < dataEnd) crc = UpdateCRC16(crc, *p_data++); crc = UpdateCRC16(crc, 0); crc = UpdateCRC16(crc, 0); return crc&0xffffu; } /** * @brief Update CRC16 for input byte * @param crc_in input value * @param input byte * @retval None */ uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte) { uint32_t crc = crc_in; 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; } void handleData(void) { if(resp == 0) { if( strstr(status, "PLLR1") != NULL) { resp = 1; } } } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/