/* 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****/