2021-12-06 01:55 PM
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;
2021-12-07 07:19 AM
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