Skip to main content
ABeau.4
Associate
December 6, 2021
Question

Conflict between UART buffer size and Flash erasing on STM32G474

  • December 6, 2021
  • 1 reply
  • 896 views

Hi,

I'm having a problem that I simply cannot explain so any help is welcomed.

I'm trying to flash the G4 via UART, to put it simply the app receives a reflash request via UART then it erases the other bank that isnt being used and writes the new double words in it. switchs the bank boot pin then it performs a reset (I used this example as a base :https://github.com/barafael/g4-dual-bank-example)

At first the only code that was sent to tell the mcu that new code was being received was 'R' 'F' but then I decided to also add two bytes to say how many double words will be received.

Increasing the buffer size from 2 to 4 in HAL_UART_Receive_IT() (Line 160) call seems to then block the flash from erasing properly.

/* Private typedef -----------------------------------------------------------*/
typedef enum {
 STANDBY,
 CMDCHECK,	
 PREPARATION,
 FLASH_ERASING,
 FLASH_ERASE_DONE,
 FLASH_WRITE_IN_PROGRESS,
 FLASH_WRITE_DONE,
 UPDATE_DONE,
} updateState_t;
 
// Number of pages for firmware
#define NUM_PAGES 100
 
// Number of bytes for firmware
#define NUM_BYTES NUM_PAGES * FLASH_PAGE_SIZE
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef hlpuart1;
UART_HandleTypeDef huart4;
volatile updateState_t updateState = STANDBY;
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_UART4_Init(void);
 
/* Private user code ---------------------------------------------------------*/
uint32_t NUM_DOUBLEWORDS = NUM_BYTES / 8;
 
uint8_t RxBuffer[13]; //Contains the data received by the UART4 via interrupt
 //4 Bytes for the address, 8 for the doubleword and 1 for the checksum
bool newdata = false; //Global flags that tells the programme that new data has been received
struct Line
	{
 uint32_t Address;
	 uint64_t Data;	
	};
	
void HAL_GPIO_EXTI_Callback(uint16_t pin) 
{
 if (pin == GPIO_PIN_13) {
 if (updateState == STANDBY) 
					{
 updateState = PREPARATION;
 }
 }
 
}
 
void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) 
{ 
	if (updateState == FLASH_ERASING && ReturnValue == 0xffffffff) 
	 {
 updateState = FLASH_ERASE_DONE;
 } 
	else if (updateState == FLASH_WRITE_IN_PROGRESS)
	 {
 updateState = FLASH_WRITE_DONE;
 }
}
 
void toggleBankAndReset() 
{
 FLASH_OBProgramInitTypeDef OBInit;
 HAL_FLASH_Unlock();
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 HAL_FLASH_OB_Unlock();
 HAL_FLASHEx_OBGetConfig(&OBInit);
 
 OBInit.OptionType = OPTIONBYTE_USER;
 OBInit.USERType = OB_USER_BFB2;
 
 if (((OBInit.USERConfig) & (OB_BFB2_ENABLE)) == OB_BFB2_ENABLE) {
 OBInit.USERConfig = OB_BFB2_DISABLE;
 } else {
 OBInit.USERConfig = OB_BFB2_ENABLE;
 }
 if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {
 // uint32_t errorCode = HAL_FLASH_GetError();
 while (1) {
 HAL_Delay(1000);
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 }
 }
 if (HAL_FLASH_OB_Launch() != HAL_OK) {
 //uint32_t errorCode = HAL_FLASH_GetError();
 while (1) {
 HAL_Delay(200);
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 }
 }
 HAL_FLASH_OB_Lock();
 HAL_FLASH_Lock();
}
 
uint8_t getActiveBank() 
{
 volatile uint32_t remap = READ_BIT(SYSCFG->MEMRMP, 0x1 << 8);
 return remap == 0 ? 1 : 2;
}
 
int main(void)
{
 /* MCU Configuration--------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* Configure the system clock */
 SystemClock_Config();
	uint8_t UpDone[] = "Update done\r\n";
	uint8_t Bank1[] = "We are in bank 1\r\n";
 uint8_t Bank2[] = "We are in bank 2\r\n";		
 
	uint8_t Ready[] = {'R','D'};
	uint8_t ReqNbDW[] = {'N','D'};
 
	uint8_t BankR[2]; 
	uint8_t LReturn[] = "\r\n";
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_LPUART1_UART_Init();
 MX_UART4_Init();
 HAL_UART_Init(&huart4);
	 uint8_t bank = getActiveBank();
 
 uint32_t last = HAL_GetTick();
 
 uint32_t delay;
 if (bank == 1) 
 {	
 delay = 2000;
 } 
 else 
 {
	delay = 500;
 }
 
 /* Infinite loop */
	bool FromUART = false;
	bool ValidDoubleWord = false;
	bool RQNextDW = false;
	bool EOF = false;
	
	 uint32_t dest = 0x08040000;
	 uint32_t addr;
 uint8_t *src = (uint8_t*) 0x08000000;
	 
	 uint64_t Bothalf;
	 uint64_t Tophalf;
	 uint64_t doubleword;
	 uint64_t CopyDouble;
	
	uint8_t DataAnalyser[sizeof(RxBuffer)];
	
	
	//If I change this size from 2 to 4 the error happens
	HAL_UART_Receive_IT(&huart4,RxBuffer,2); //Get the UART ready to recieve the first data
 
while (1)
 {
		 uint32_t now = HAL_GetTick();
 if (now - last > delay) 
				{
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 last = now;
 }
 switch (updateState) 
	{case STANDBY:
		 if(newdata) //Set by Rx callback
	 {
		 newdata = false;
		 updateState = CMDCHECK;
		 }			 
 break;
	case CMDCHECK:
	 { 
	 if(RxBuffer[0] == 'R' && RxBuffer[1] == 'F') //Reflash code received
		 {						 
		 updateState = PREPARATION;
	 }
		break;					
 case PREPARATION: //Erase the unused bank
	{
 FLASH_EraseInitTypeDef erase = { 0 };
 erase.TypeErase = FLASH_TYPEERASE_PAGES;
 erase.Banks = bank == 1 ? FLASH_BANK_2 : FLASH_BANK_1;
 erase.NbPages = NUM_PAGES;
 erase.Page = 0;
 
 HAL_FLASH_Unlock();
						__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
 HAL_StatusTypeDef status = HAL_FLASHEx_Erase_IT(&erase);
 if (status != HAL_OK) {
 // TODO error case
 }
 
 updateState = FLASH_ERASING;
 }
 break;
 
 case FLASH_ERASING:
	 delay = 200; //Code gets stuck here
				
 uint32_t ErrCode = HAL_FLASH_GetError();
 
	 break;

This topic has been closed for replies.

1 reply

ABeau.4
ABeau.4Author
Associate
December 7, 2021

After testing around more it seems that the problem is that the RxBuffer array is global. Not sure why that is an issue for the flash