@@ -20,7 +20,21 @@ LOG_MODULE_REGISTER(LOG_DOMAIN);
2020
2121#include "flash_stm32.h"
2222
23+ #if defined(FLASH_OPTR_DUAL_BANK )
24+ /* The stm32wba6x mcus have 2MB dual-bank */
25+ #define STM32_SERIES_MAX_FLASH 2048
26+ #define STM32_FLASH_HAS_2_BANKS (flash_device ) \
27+ (((FLASH_STM32_REGS(flash_device)->OPTR & FLASH_STM32_DBANK) \
28+ == FLASH_STM32_DBANK) \
29+ ? (true) : (false))
30+ #else
2331#define STM32_SERIES_MAX_FLASH 1024
32+ #define STM32_FLASH_HAS_2_BANKS (flash_device ) (false)
33+ #endif /* FLASH_OPTR_DUAL_BANK */
34+
35+ #define PAGES_PER_BANK ((FLASH_SIZE / FLASH_PAGE_SIZE) / 2)
36+
37+ #define BANK2_OFFSET (KB(STM32_SERIES_MAX_FLASH) / 2)
2438
2539#define ICACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */
2640#define ICACHE_INVALIDATE_TIMEOUT_VALUE 1U /* 1ms */
@@ -105,6 +119,34 @@ static int icache_wait_for_invalidate_complete(void)
105119 return status ;
106120}
107121
122+ /*
123+ * offset and len must be aligned on write-block-size for write,
124+ * positive and not beyond end of flash
125+ */
126+ bool flash_stm32_valid_range (const struct device * dev , off_t offset ,
127+ uint32_t len , bool write )
128+ {
129+ if (STM32_FLASH_HAS_2_BANKS (dev ) &&
130+ (CONFIG_FLASH_SIZE < STM32_SERIES_MAX_FLASH )) {
131+ /*
132+ * In case of bank1/2 discontinuity, the range should not
133+ * start before bank2 and end beyond bank1 at the same time.
134+ * Locations beyond bank2 are caught by
135+ * flash_stm32_range_exists.
136+ */
137+ if ((offset < BANK2_OFFSET ) &&
138+ (offset + len > FLASH_SIZE / 2 )) {
139+ return 0 ;
140+ }
141+ }
142+
143+ if (write && !flash_stm32_valid_write (offset , len )) {
144+ return false;
145+ }
146+
147+ return flash_stm32_range_exists (dev , offset , len );
148+ }
149+
108150static int write_qword (const struct device * dev , off_t offset , const uint32_t * buff )
109151{
110152 FLASH_TypeDef * regs = FLASH_STM32_REGS (dev );
@@ -282,6 +324,59 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
282324 return rc ;
283325}
284326
327+ #if defined(FLASH_OPTR_DUAL_BANK )
328+ /* The STM32WBA6x has a dual-bank flash */
329+ void flash_stm32_page_layout (const struct device * dev ,
330+ const struct flash_pages_layout * * layout ,
331+ size_t * layout_size )
332+ {
333+ static struct flash_pages_layout stm32_flash_layout [3 ];
334+ static size_t stm32_flash_layout_size ;
335+
336+ * layout = stm32_flash_layout ;
337+
338+ if (stm32_flash_layout [0 ].pages_count != 0 ) {
339+ /* Short circuit calculation logic if already performed (size is known) */
340+ * layout_size = stm32_flash_layout_size ;
341+ return ;
342+ }
343+
344+ if (STM32_FLASH_HAS_2_BANKS (dev ) &&
345+ (CONFIG_FLASH_SIZE < STM32_SERIES_MAX_FLASH )) {
346+ /* For device, which has space between banks 1 and 2 */
347+
348+ /* Bank1 */
349+ stm32_flash_layout [0 ].pages_count = PAGES_PER_BANK ;
350+ stm32_flash_layout [0 ].pages_size = FLASH_PAGE_SIZE ;
351+
352+ /* Dummy page corresponding to space between banks 1 and 2 */
353+ stm32_flash_layout [1 ].pages_count = 1 ;
354+ stm32_flash_layout [1 ].pages_size = BANK2_OFFSET
355+ - (PAGES_PER_BANK * FLASH_PAGE_SIZE );
356+
357+ /* Bank2 */
358+ stm32_flash_layout [2 ].pages_count = PAGES_PER_BANK ;
359+ stm32_flash_layout [2 ].pages_size = FLASH_PAGE_SIZE ;
360+
361+ stm32_flash_layout_size = ARRAY_SIZE (stm32_flash_layout );
362+ } else {
363+ /* For device, which has no space between banks 1 and 2 */
364+ if (STM32_FLASH_HAS_2_BANKS (dev )) {
365+ /* Considering one layout of full flash size, even with 2 banks */
366+ stm32_flash_layout [0 ].pages_count = FLASH_SIZE / FLASH_PAGE_SIZE ;
367+ stm32_flash_layout [0 ].pages_size = FLASH_PAGE_SIZE ;
368+ }
369+
370+ /*
371+ * In this case the stm32_flash_layout table has one single element
372+ * when read by the flash_get_page_info()
373+ */
374+ stm32_flash_layout_size = 1 ;
375+ }
376+
377+ * layout_size = stm32_flash_layout_size ;
378+ }
379+ #else
285380void flash_stm32_page_layout (const struct device * dev ,
286381 const struct flash_pages_layout * * layout ,
287382 size_t * layout_size )
@@ -301,3 +396,4 @@ void flash_stm32_page_layout(const struct device *dev,
301396 * layout = & stm32wba_flash_layout ;
302397 * layout_size = 1 ;
303398}
399+ #endif /* FLASH_OPTR_DUAL_BANK */
0 commit comments