cancel
Showing results for 
Search instead for 
Did you mean: 

does dual-bank read-while-write work properly in stm32l071?

Maciej Suchinski
Associate II
Posted on August 03, 2017 at 10:36

I'm trying to reprogram the NVM (flash bank 2) while running code from flash bank 1 in STM32L071CB microcontroller.

As AN4808 and AN4767 stand, 'the memory interface is capable of reading both banks in parallel, or reading one bank while writing to the other...' but I'm experiencing some problems:

  1. Debugging shows that FWWERR bit goes high in the flash status register during flash bank 2 half-page write operation. It means that writting flash bank 2 has been stopped because of code fetching.
  2. Erasing bank 2 by code in bank 1 works properly.
  3. Writting by words bank 2 by code in bank 1 seems to work properly (but I'm having doubts if its only coincidence).
  4. Half-page writting ends with FWWERR bit set in FLASH_SR and zeros in the memory I'm trying to write.

I know I'm missing something but I can't find out what it is. Maybe someone had similar problem? I'm starting to think that there's something is wrong with the uC (errata sheet points out some problems with dual-bank switching mechanism, but it shouldn't be a problem in my case, because I'm not switching banks right now).

My function works properly when executed from RAM memory, but I'd rather want it to run from flash bank 1.

(you can take a look at the code here:

https://electronics.stackexchange.com/questions/321863/does-dual-bank-read-while-write-work-properly-in-stm32l071

)

SYSCLK is 16 MHz, checked on MCO with oscilloscope. PWR is in range 1 (the highest applicable).

Thanks for any help.

#flash-read-and-write #stm32l071 #dual-bank #firmware-update

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on September 19, 2017 at 16:43

Hi,

Reading-While-Write has some limitation in case of Multiple programming operation. See

http://www.st.com/content/ccc/resource/technical/document/reference_manual/21/bd/0f/bd/1c/88/40/f0/DM00108282.pdf/files/DM00108282.pdf/jcr:content/translations/en.DM00108282.pdf

§ 3.3.4 Writing/erasing the NVM - Program half-page in Flash program memory page 82:

'When a half-page operation starts, the memory interface waits for 16 addresses/data,

aborting (with a hard fault) all read accesses that are not a fetch (refer to

Fetch and

prefetch

). A fetch stops the half-page operation. The memory content remains

unchanged, the FWWERR error is set in the FLASH_SR register.'

This means that no fetch operation are allowed in the flash while feeding the memory interface with the 16 words (whatever the code is running in bank 1 and the half page programming is performed in bank 2) . Once the 16 words have been sent to the memory interface, you can resume execution from flash, i.e. during the physical writing of the data inside the flash bank (assuming your code is running in the other bank).  

In a nutshell, you need to execute from SRAM the feeding of the memory interface with the 16 words and make sure the interrupts will not cause fetch in flash memory (either mask all interrupts or relocate interrupt handlers and interrupts vector in SRAM).

Note: there is no such limitation in case of Single programming operation.

Regards

Bruno

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

12 REPLIES 12
Posted on August 03, 2017 at 14:06

Make sure you know exactly what part you are working with, and what die is inside. ST has had a somewhat liberal policy to die/marking, so while I think the part should act like a 128KB one, it might not.

If the die has 192 KB of FLASH the second bank starts at 0x08018000 rather than 0x08010000

Try your test at 0x08018000

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
164630CGIL2
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 03, 2017 at 15:00

Thans for your reply.

I've got CPUID = 0x410CC601 and DEVID = 0x447.

It stands for ARM rev0 / arch. ARMv6-M / Cortex M0+ core / STM32L0 family / patch 1 / Device cat. 5.

Reading DBGMCU->IDCODE & 0xFFFF0000 (REV_ID) gives me 'rev. Z'. Unless rev. Z stands for STM32L071xZ, then I don't think that's my problem.

Reading Flash size register (at 0x1FF8007C) gave me 128 KB.

I also tried writting half-page to the address of bank 2 from 192 KB flash devices (0x08018000), but I got the same result (FWWERR).

Posted on August 03, 2017 at 15:33

Is the system free standing, or attached to a debugger? FLASH issues are best debugged by outputting telemetry via a serial port rather than via a JTAG probe, you can't control what memory the debugger will touch or poke around with.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 04, 2017 at 10:11

Well I'm really confused right now. Today I've started debugging the same code as yesterday and FWWERR disappeared. I've tried both versions - with debugger attached and standalone. I'm trying to recreate the situation that caused FWWERR error right now. I'll let you know when something changes. The flash is still empty.

Edit:

OK, I got this error once again. This is my test code:

(with ST's example code from L0 snippets my uC behaves the same way)

volatile uint8_t flag_from_isr = 0;

int main(void){

    SystemCoreClockUpdate();

    bl_SystemInit(); // initialize nvm, pwr, bootloader uart, ...

    uint8_t test = 0xFF;

    bl_uart_send(&test, 1);

    // currently 0x08010000 (...) is empty so there's no need to erase

    /* prepare some data */

    uint32_t dummydata[32], i;

    for(i=0; i<32; i++){

        dummydata[i] = i;

    }

    test = 0x1;

    bl_uart_send(&test, 1);

    nvm_prog_write_halfpages((uint32_t *) 0x08010000, &dummydata[0], 2); // write 2 half-pages at the beginning of flash bank 2

    test = 0x2;

    bl_uart_send(&test, 1);

    while(1){

        /* check if FWWERR occured */

        if(flag_from_isr == 1){

            flag_from_isr = 0;

            test = 0xea;

            bl_uart_send(&test, 1);

        }

    }

}

------------ and in another file-----------

extern uint8_t flag_from_isr;

void FLASH_IRQHandler(void){

    volatile uint32_t source = FLASH->SR;

    if((source & (1 << 17)) == (1 << 17)){

        flag_from_isr = 1;

    }

    FLASH->SR |= (source & 0xFFFFFFF2); // clear all flags

}

On the oscilloscope there's a following sequence:

0xFF,   0x01,              (about 350 us of delay)             0x02, 0xEA

Posted on August 04, 2017 at 16:26

You should make sure the memory is clear, test first, don't assume.

Make sure you clear any pending status from the flash controller before starting your own interactions with it, the download process can leave it in an indeterminate state.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 19, 2017 at 16:43

Hi,

Reading-While-Write has some limitation in case of Multiple programming operation. See

http://www.st.com/content/ccc/resource/technical/document/reference_manual/21/bd/0f/bd/1c/88/40/f0/DM00108282.pdf/files/DM00108282.pdf/jcr:content/translations/en.DM00108282.pdf

§ 3.3.4 Writing/erasing the NVM - Program half-page in Flash program memory page 82:

'When a half-page operation starts, the memory interface waits for 16 addresses/data,

aborting (with a hard fault) all read accesses that are not a fetch (refer to

Fetch and

prefetch

). A fetch stops the half-page operation. The memory content remains

unchanged, the FWWERR error is set in the FLASH_SR register.'

This means that no fetch operation are allowed in the flash while feeding the memory interface with the 16 words (whatever the code is running in bank 1 and the half page programming is performed in bank 2) . Once the 16 words have been sent to the memory interface, you can resume execution from flash, i.e. during the physical writing of the data inside the flash bank (assuming your code is running in the other bank).  

In a nutshell, you need to execute from SRAM the feeding of the memory interface with the 16 words and make sure the interrupts will not cause fetch in flash memory (either mask all interrupts or relocate interrupt handlers and interrupts vector in SRAM).

Note: there is no such limitation in case of Single programming operation.

Regards

Bruno

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Posted on September 21, 2017 at 12:05

Hi,

thank you for your answer. I had to suspend my project for a while due to some (not uC realated) reasons, but when the project resumes, I'll rewrite the code. I'll probably just stick to the single programming operation.

Posted on October 16, 2017 at 05:53

I'm trying to do the same thing with my STM32L082 microcontroller, so I have been trying to use the half-page program function from HAL (RAM function)

When I use it, I still get a run-time error in the flash program status register FLASH_SR saying that the programming was interrupted by a fetch (bit 17, FWWERR).  When I step through the code with a debugger, I see that the program counter is 0x0800e190, which is in the middle of bank 1 of flash, which makes me think that the HAL '__RAM_FUNC HAL_FLASHEx_HalfPageProgram' isn't actually getting compiled into RAM. Is there something special I need to do to force the function into RAM?  I'm using System Workbench for STM32.

I searched around a bit and found a post that recommended I change the option in the flash_ramfunc.c file to have 'position independent code'. I checked that box but I'm still getting the FWWERR, and when I step the program counters are still in the bank 1 flash range, but now I get about a dozen PC halted console messages for every debug step.

Has anyone gotten the HAL half-page program RAM function to work, or at least load into RAM?

Thanks.

-Adrian