-
Notifications
You must be signed in to change notification settings - Fork 847
AT32F4 flash handling #1542
Description
Summary
How should all these different parts be handled?
Description
#1150 actually #1151 introduced detection of ARTERY AT32F403A, F407 (and F407A) and F415 parts by listing their DBGMCU_IDCODE values, or part_id as referred in sources in src/target/stm32f1.c. I agree with the at32f41_detect() routine which assigns different flash sizes to F415 parts, but disagree with at32f40_detect() which makes them all appear as 256 KiB parts.
In the PR discussion and in the code comments there are concerns about "external memory" and "default layout".
- From my understanding of RM_AT32F403A_407_EN reference manual the MCUs have a "SPIM" external Quad I/O-like NOR Flash memory controller which can map into 0x0840_0000 base and perform transparent encryption. However, I'm now interested in internal flash only. 256 & 512 KiB flash parts have it all in a single bank in 2048-byte pages. 1 MiB parts employ two banks, the split address is at 0x0808_0000 (+512 KiB) and the second bank has individual FLASH_CTRL2 etc. registers.
- ZW & NZW split is a characteristic feature of most AT32F4 MCUs: first 128 KiB of Flash are always shadowed by 128 KiB of on-chip SRAM which cannot be reclaimed. Upwards from that, [by default] another (next) 128 KiB of Flash are shadowed/cached by 128 KiB of SRAM and this margin can be moved lower (or higher if there's more SRAM, like on F435). On F403A/F407, 96 leftover KiB of SRAM are by default available as work SRAM (but 96+128=224 max). This is controlled by option bytes. NZW flash runs at 72 MHz, for 240-288 MHz cores this incurs 4 wait states without caching (on jumps).
- Is it possible to use all of 512..1024 KiB flash on AT32F403A, particularly on WeActStudio.BlackPill AT32F403ACGU7, by registering bigger sizes / page counts in
stm32f1_add_flash()? - AT32F435/7 parts with 256 KiB are single-bank with 2048-byte pages, too; but parts with 1024 KiB flash are dual-bank, split equally, at 0x0808_0000 address (+512 KiB). These targets can be treated flash-wise like the F403A.
- But AT32F435/7 parts with 4096-byte pages (also 448 KiB, single-bank -- simple, not considered here) of 4032 KiB dual-bank flash are split at 0x0820_0000 address (+2048 KiB) which is unusual.
stm32f1.c has branches on 0x430U XL-density in mass_erase, flash_erase & flash_write routines:
blackmagic/src/target/stm32f1.c
Lines 619 to 621 in c4b988b
| /* If there's anything to write left over and we're on a part with a second bank, write to bank 2 */ | |
| const size_t remainder = len - offset; | |
| if (target->part_id == 0x430U && remainder) { |
but it relies on macros for +0x40 control registers offset (which is suitable) and +512 KiB second bank offset
blackmagic/src/target/stm32f1.c
Lines 66 to 68 in c4b988b
| #define FLASH_BANK1_OFFSET 0x00U | |
| #define FLASH_BANK2_OFFSET 0x40U | |
| #define FLASH_BANK_SPLIT 0x08080000U |
There are other targets already supporting dual-bank MCUs. Like stm32h7.c has a simple dual-bank support logic, or stm32f4.c has a rather convoluted one.
I am writing #1540 and I need recommendations on how to handle this situation. Maybe all of AT32F4 should be split out as a separate target, or a subset of functions (but stm32f1 flash API is not public), or just a set of distinct write/erase/mass_erase routines living in stm32f1.c will be enough (using its own macros for register manipulations)?