cancel
Showing results for 
Search instead for 
Did you mean: 

Conflict between UART buffer size and Flash erasing on STM32G474

ABeau.4
Associate

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;

1 REPLY 1
ABeau.4
Associate

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