cancel
Showing results for 
Search instead for 
Did you mean: 

Troubles with flash programming on STM32G474RE. Can`t write anything to bank 2.

Tsaf
Associate

Hi everyone, i`ve got trouble with InApp flash programming on STM32G474RE. While i`am trying to load some data to address higher than 0x08040000 (Bank 2) in dual bank mode by the internal bootloader (placed on address range from 0x08000000 to 0x08005000 and it takes data from external QSPI flash memory chip), the data in bank 2 is stay clear (Look at Image1).

But flash programming by internal InApp bootloader is always sucsessful (and Bank 2 too), when memory was erased before device powering up. Unfortunately application does`t allow to turn device off, so it`s necessary to find out another solution for this problem.0693W00000JQCzOQAX.pngAnd that is really strange, cause all pages in addr range from 0x08005000 to 0x0807FFFF have been erased previosly. Memory protection is off and no Option Bytes checked, which may affect on memory programming processes.

The programming function:

    while(!ready());//waiting for BSY flag is cleared

      FLASH->CR |= FLASH_CR_PG; //PG bit on

      *(volatile uint32_t*)address = (uint32_t)(word1);//uploading first word

      *(volatile uint32_t*)(address + 4) = (uint32_t)(word2);//uploading second word

      while(!ready()); // waiting for BSY flag is cleared

      FLASH->CR &= ~(FLASH_CR_PG); //Set PG bit off

Erase function follows:

void Erase(uint8_t start, uint8_t stop)

{

 while (FLASH->SR & FLASH_SR_BSY);

 if (stop <= 128) {

     for (page_index = start; page_index < (stop); page_index++)

     {

       MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

       SET_BIT(FLASH->CR, FLASH_CR_PER);

       SET_BIT(FLASH->CR, FLASH_CR_STRT);

       while (FLASH->SR & FLASH_SR_BSY);

       CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

     }

 }

 else {

     for (page_index = start; page_index < (127); page_index++)

     {

       MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

       SET_BIT(FLASH->CR, FLASH_CR_PER);

       SET_BIT(FLASH->CR, FLASH_CR_STRT);

       while (FLASH->SR & FLASH_SR_BSY);

       CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

     }

     SET_BIT (FLASH->CR, FLASH_CR_BKER);

     for (page_index = 128; page_index < (stop); page_index++)

     {

       MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

       SET_BIT(FLASH->CR, FLASH_CR_PER);

       SET_BIT(FLASH->CR, FLASH_CR_STRT);

       while (FLASH->SR & FLASH_SR_BSY);

       CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

     }

     CLEAR_BIT (FLASH->CR, FLASH_CR_BKER);

 }

}

Does anyone faced with such problem?

2 REPLIES 2
TDK
Guru

Maybe your uint8_t's are overflowing and causing issues. Would be helpful to see the full code, with calls to the given functions.

If you feel a post has answered your question, please click "Accept as Solution".
Tsaf
Associate

Thansk for your answer.

Sending the full code bellow:

#define MAIN_ADDRESS 0x08005000

void delay (unsigned long time);

void unlock (void);

void Erase_main(uint8_t start, uint8_t stop);

_Bool Program(uint32_t address, uint32_t data1,uint32_t data2);

_Bool EOP(void);

_Bool ready(void);

void teleport(uint32_t addr);

uint8_t buff[256];

uint64_t z, byte_inc;

uint8_t key[0x100], loh;

uint32_t page_index;

unsigned long addr =0x100000, flash_addr = MAIN_ADDRESS, heh, it;

uint32_t word1,word2;

int main(void)

{

 SCB->VTOR = 0x08000000;

 SystemInit();

 QuadSpi1Init();

 if (TIM2->ARR == 162) { // That is a reference point from main program, which telling us about necessary of software updating

 PWR->CR1 = 1<<PWR_CR1_VOS_Pos;

 unlock();

 FLASH->SR |= FLASH_SR_EOP | FLASH_SR_PGAERR | FLASH_SR_WRPERR|FLASH_SR_OPTVERR;

 Erase_main(10, 255);

while (1) {

delay (10);

QSPI_read_page (1, addr, &buff[0], 0x100);

   addr+= 0x100;

   byte_inc = 0;

   word1 = 0;

   word2 = 0;

if (it > 0) {

   if ((buff[0] == 0xFF) && (buff[2] == 0xFF) && (buff[3] == 0xFF) && (buff[8] == 0xFF) && (buff[43] == 0xFF) && (buff[45] == 0xFF) && (buff[112] == 0xFF)) {

 break;

   }

while (byte_inc < 0x100) {

   word1 = buff[byte_inc]|buff[byte_inc + 1]<<8|buff[byte_inc + 2]<<16|buff[byte_inc + 3]<<24;

   word2 = buff[byte_inc+4]|buff[byte_inc + 5]<<8|buff[byte_inc + 6]<<16|buff[byte_inc + 7]<<24;

   Program (flash_addr,word1,word2);

   flash_addr +=8;

   byte_inc += 8;

   }

 }

it = it + 1;

 }

 TIM2->ARR = 66; // This point tells main program that software has been updated

 teleport(MAIN_ADDRESS);

}

 else {

 teleport(MAIN_ADDRESS);

}

}

void teleport(uint32_t addr)

{

  uint32_t jump;

  typedef void(*pFunction)(void);

  pFunction Jump;

   __disable_irq();

   jump = *( uint32_t*) (addr + 4);

  Jump = (pFunction)jump;

   __set_MSP(*(__IO uint32_t*) addr);

  Jump();

}

void unlock (void) {

FLASH->KEYR = 0x45670123;

FLASH->KEYR = 0xCDEF89AB;

}

_Bool ready(void)

{

return !(FLASH->SR & FLASH_SR_BSY);

}

_Bool EOP(void)

{

if(FLASH->SR & FLASH_SR_EOP)

{

FLASH->SR |= FLASH_SR_EOP;

return 1;

}

return 0;

}

void Erase_main(uint8_t start, uint8_t stop)

{

 while (FLASH->SR & FLASH_SR_BSY);

 if (stop <= 128) {

   for (page_index = start; page_index < (stop); page_index++)

   {

    MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

    SET_BIT(FLASH->CR, FLASH_CR_PER);

    SET_BIT(FLASH->CR, FLASH_CR_STRT);

    while (FLASH->SR & FLASH_SR_BSY);

    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

   }

 }

 else {

   for (page_index = start; page_index < (127); page_index++)

   {

    MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

    SET_BIT(FLASH->CR, FLASH_CR_PER);

    SET_BIT(FLASH->CR, FLASH_CR_STRT);

    while (FLASH->SR & FLASH_SR_BSY);

    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

   }

   SET_BIT (FLASH->CR, FLASH_CR_BKER);

   for (page_index = 128; page_index < (stop); page_index++)

   {

    MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((page_index & 0xFFU) << FLASH_CR_PNB_Pos));

    SET_BIT(FLASH->CR, FLASH_CR_PER);

    SET_BIT(FLASH->CR, FLASH_CR_STRT);

    while (FLASH->SR & FLASH_SR_BSY);

    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

   }

   CLEAR_BIT (FLASH->CR, FLASH_CR_BKER);

 }

}

_Bool Program(uint32_t address, uint32_t data1,uint32_t data2)

{

while(!ready());

FLASH->CR |= FLASH_CR_PG;

*(volatile uint32_t*)address = (uint32_t)data1;

*(volatile uint32_t*)(address + 4U) = (uint32_t)(data2);

while(!ready());

FLASH->CR &= ~(FLASH_CR_PG);

if(!EOP())return 0;

return EOP();

}

void delay (unsigned long time) {

 for (heh = 0; heh <= time*170; heh ++) {

    __NOP();

 }

}