cpu/stm32: unify support for flashpage/flashpage_raw with L0/L1/F0/F1 families#8768
cpu/stm32: unify support for flashpage/flashpage_raw with L0/L1/F0/F1 families#8768kYc0o merged 5 commits intoRIOT-OS:masterfrom
Conversation
kYc0o
left a comment
There was a problem hiding this comment.
Besides the comments on this PR, the flashpage_write_raw implementation is missing and I think it can bee added at the same time, since it's trivial and adds flexibility.
On the other hand, it looks a bit like a duplicate of #7712. I'd say we could merge both implementations to give a complete flashpage driver for the stm32l CPUs.
cpu/stm32_common/periph/flashpage.c
Outdated
| #define CNTRL_REG (FLASH->CR) | ||
| #define CNTRL_REG_LOCK (FLASH_CR_LOCK) | ||
| #define KEY_REG (FLASH->KEYR) | ||
| #define FLASHPAGE_LIMIT (FLASHPAGE_SIZE / 2) |
There was a problem hiding this comment.
This FLASHPAGE_LIMIT define is not documented and thus I don't see what is really about.
| FLASH->KEYR = FLASH_KEY2; | ||
| if (CNTRL_REG & CNTRL_REG_LOCK) { | ||
| KEY_REG = FLASH_KEY1; | ||
| KEY_REG = FLASH_KEY2; |
There was a problem hiding this comment.
You're redefining this values, but I don't see why you don't use them below, which makes me wonder what's the use of it after all.
There was a problem hiding this comment.
I'm sorry @kYc0o, but I'd like that you read this PR carefully before commenting (and also the datasheet). They are not reused below because they are not the same (FLASH->PEKEYR != FLASH->PRGKEYR).
There was a problem hiding this comment.
I know the datasheet and I know what is this about (my PR was there for about 6 months), I was referring to CTRL_REG and actually since you're defining KEY_REG you could also define KEY_PREG to be reused in other parts of the code, especially if your intention is to add the EEPROM driver.
cpu/stm32_common/periph/flashpage.c
Outdated
| #if defined(CPU_FAM_STM32L0) | ||
| DEBUG("[flashpage] unlocking the flash program memory\n"); | ||
| if (!(CNTRL_REG & CNTRL_REG_LOCK)) { | ||
| if (FLASH->PECR & FLASH_PECR_PRGLOCK) { |
There was a problem hiding this comment.
This nested if's seem a bit weird to me... especially because both CTRL_REG and FLASH->PECR are defining the same registers.
|
I'd tend to prefer this approach over #7712 but I also think |
I still think we can merge both approaches, no need to add more PRs or wait for them. As I said it's trivial and adds a lot of flexibility while writing into flash. What I propose is to add my changes to this PR, if @vincent-d likes it more. |
d5d3e07 to
0003aae
Compare
0003aae to
df326ea
Compare
Indeed there are good ideas on both sides. I updated this PR to integrate them and also added the flashpage_raw feature to stm32f0 and stm32f1. Tested in nucleo-f030, nucleo-l152 and b-l072z-lrwan1 boards and works. I'm not sure of the values for alignment and block size, so it may be worth checking that. |
vincent-d
left a comment
There was a problem hiding this comment.
Didn't test it but I have some comments. Looks already good in general.
cpu/stm32_common/periph/flashpage.c
Outdated
|
|
||
| #include "periph/flashpage.h" | ||
|
|
||
| #if defined(CPU_FAM_STM32L0) | defined(CPU_FAM_STM32L1) |
cpu/stm32_common/periph/flashpage.c
Outdated
|
|
||
| void flashpage_write_raw(void *target_addr, void *data, size_t len) | ||
| { | ||
| /* The actual minimal block size for writing is 16B, thus we |
There was a problem hiding this comment.
During my tests, it was actually possible to write even 4B, but I left 16B as the smallest.
cpu/stm32_common/periph/flashpage.c
Outdated
| #endif | ||
| uint32_t hsi_state = (RCC->CR & RCC_CR_HSION); | ||
|
|
||
| /* the internal RC oscillator (HSI) must be enabled */ |
There was a problem hiding this comment.
isn't it needed in flashpage_write_raw as well?
cpu/stm32_common/periph/flashpage.c
Outdated
|
|
||
| /* the internal RC oscillator (HSI) must be enabled */ | ||
| RCC->CR |= (RCC_CR_HSION); | ||
| while (!(RCC->CR & RCC_CR_HSIRDY)) {} |
There was a problem hiding this comment.
you could use stmclk_enable_hsi and stmclk_disable_hsi below
cpu/stm32_common/periph/flashpage.c
Outdated
| /* set PG bit and program page to flash */ | ||
| CNTRL_REG |= FLASH_CR_PG; | ||
| #endif | ||
| for (size_t i = 0; i < (FLASHPAGE_SIZE / FLASHPAGE_DIV); i++) { |
cpu/stm32_common/periph/flashpage.c
Outdated
| /* finally, lock the flash module again */ | ||
| DEBUG("flashpage] now locking the flash module again\n"); | ||
| FLASH->CR |= FLASH_CR_LOCK; | ||
| _lock(); |
There was a problem hiding this comment.
I'm wondering if it wouldn't be cleaner to lock right after erasing, as unlocking/locking are done again in flashpage_write_raw in case of writing
| uint32_t *data_addr = (uint32_t *)data; | ||
| #else | ||
| uint16_t *dst = target_addr; | ||
| uint16_t *data_addr = (uint16_t *)data; |
There was a problem hiding this comment.
There is something I'm not sure to understand here: this seems to allow half-word (i.e. 2 bytes) alignment, as FLASHPAGE_DIV seems to suggest too. But FLASHPAGE_RAW_ALIGNMENT and FLASHPAGE_RAW_BLOCKSIZE are 4 and then it's not allowed to write only 2 bytes.
Am I missing something?
|
@vincent-d @kYc0o, I tested more in depth the flashpage_raw feature: I think it works (not really sure how the test application is supposed to be used) with L0 and L1 but it crashes with F0 (I have no F1, except iotlab-m3 but have problem flashing this one). |
vincent-d
left a comment
There was a problem hiding this comment.
Works on b-l072z-lrwan1 but crashes on nucleo-f091 if HSI is not enabled before writing
| uint16_t *dst = (uint16_t *)target_addr; | ||
| uint16_t *data_addr = (uint16_t *)data; | ||
| #endif | ||
|
|
There was a problem hiding this comment.
HSI needs to be enabled here and disabled after locking, otherwise it crashes on stm32f091
There was a problem hiding this comment.
HSI needs to be enabled here and disabled after locking
Thanks, I'll try that
There was a problem hiding this comment.
Thanks a lot @vincent-d, that was it! I refactored a bit the code again and tested on nucleo-l073 and nucleo-f070, it works on both.
3dc2728 to
06392bb
Compare
|
@vincent-d @kYc0o, I think we are nearly good here. |
|
@kYc0o just missing your ACK, and we are good ! |
|
It looks ok. I'll test and give my ACK. |
|
Tested ACK. |
| */ | ||
| #define FLASHPAGE_RAW_BLOCKSIZE (2U) | ||
| /* Writing should be always 4 bytes aligned */ | ||
| #define FLASHPAGE_RAW_ALIGNMENT (4U) |
There was a problem hiding this comment.
@cladmi, It could be one of those 2 lines, can you test with a value of 2 ?
There was a problem hiding this comment.
With ENABLE_DEBUG (1) in stm32_common/periph/flashpage.c it works so it must be something else.
|
Broken on With |
Contribution description
This PR adapts the STM32 flashpage feature to make it work with the STM32L0 family. It has been tested with success on nucleo-l0xx and b-l072z-lrwan1 boards.
Issues/PRs references
None