7676// Used by CPU2 to prevent CPU1 from writing/erasing data in flash memory.
7777#define SEMID_FLASH_CPU2 (7)
7878
79+ #define SEM_LOCK_SUCCESSFUL (0)
80+ #define SEM_LOCK_BUSY (1)
81+
7982#endif
8083
8184typedef struct {
@@ -291,6 +294,37 @@ int32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *siz
291294 return -1 ;
292295}
293296
297+
298+ #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
299+ static void flash_sync_lock_aquire (void ) {
300+ // Wait for flash interlocks
301+ for (;;) {
302+ // Wait for PES (if it's enabled, no-op if not).
303+ while (LL_FLASH_IsActiveFlag_OperationSuspended ()) {
304+ }
305+ // Check the flash hasn't already been locked elsewhere by CPU1
306+ if (LL_HSEM_GetStatus (HSEM , SEMID_FLASH_CPU1 ) == SEM_LOCK_SUCCESSFUL ) {
307+
308+ // Ensure CPU2 isn't already using the flash
309+ if (LL_HSEM_1StepLock (HSEM , SEMID_FLASH_CPU2 ) == SEM_LOCK_SUCCESSFUL ) {
310+ // Got the lock, continue flash operation
311+ break ;
312+ }
313+ // CPU2 Locked, release our semaphore / critical section to try again.
314+ LL_HSEM_ReleaseLock (HSEM , SEMID_FLASH_CPU2 , 0 );
315+ }
316+ MICROPY_EVENT_POLL_HOOK
317+ }
318+ }
319+
320+ static void flash_sync_lock_release (void ) {
321+ // Release flash lock.
322+ while (__HAL_FLASH_GET_FLAG (FLASH_FLAG_CFGBSY )) {
323+ }
324+ LL_HSEM_ReleaseLock (HSEM , SEMID_FLASH_CPU2 , 0 );
325+ }
326+ #endif // MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
327+
294328// Erase a single flash page which starts at the given address.
295329// The address will be converted to a bank and sector number.
296330int flash_erase (uint32_t flash_dest ) {
@@ -309,12 +343,8 @@ int flash_erase(uint32_t flash_dest) {
309343 // Tell the HCI controller stack we're starting an erase, so it
310344 // avoids radio activity for a while.
311345 rfcore_start_flash_erase ();
312- // Wait for PES.
313- while (LL_FLASH_IsActiveFlag_OperationSuspended ()) {
314- }
315- // Wait for flash lock.
316- while (LL_HSEM_1StepLock (HSEM , SEMID_FLASH_CPU2 )) {
317- }
346+ // Wait for flash semaphore locks
347+ flash_sync_lock_aquire ();
318348 #endif
319349
320350 // Clear pending flags (if any).
@@ -366,10 +396,8 @@ int flash_erase(uint32_t flash_dest) {
366396 HAL_StatusTypeDef status = HAL_FLASHEx_Erase (& EraseInitStruct , & SectorError );
367397
368398 #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
369- // Release flash lock.
370- while (__HAL_FLASH_GET_FLAG (FLASH_FLAG_CFGBSY )) {
371- }
372- LL_HSEM_ReleaseLock (HSEM , SEMID_FLASH_CPU2 , 0 );
399+ // Release flash sync lock.
400+ flash_sync_lock_release ();
373401 // Tell HCI controller that erase is over.
374402 rfcore_end_flash_erase ();
375403 #endif
@@ -395,12 +423,6 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
395423 // Unlock the flash for write.
396424 HAL_FLASH_Unlock ();
397425
398- #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
399- // Wait for PES.
400- while (LL_FLASH_IsActiveFlag_OperationSuspended ()) {
401- }
402- #endif
403-
404426 HAL_StatusTypeDef status = HAL_OK ;
405427
406428 #if defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32L4 ) || defined(STM32WB ) || defined(STM32WL )
@@ -410,18 +432,15 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
410432 uint64_t val = * (uint64_t * )src ;
411433
412434 #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
413- // Wait for flash lock.
414- while (LL_HSEM_1StepLock (HSEM , SEMID_FLASH_CPU2 )) {
415- }
435+ // Wait for flash interlocks
436+ flash_sync_lock_aquire ();
416437 #endif
417438
418439 status = HAL_FLASH_Program (FLASH_TYPEPROGRAM_DOUBLEWORD , flash_dest , val );
419440
420441 #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
421442 // Release flash lock.
422- LL_HSEM_ReleaseLock (HSEM , SEMID_FLASH_CPU2 , 0 );
423- while (__HAL_FLASH_GET_FLAG (FLASH_FLAG_CFGBSY )) {
424- }
443+ flash_sync_lock_release ();
425444 #endif
426445
427446 if (status != HAL_OK ) {
@@ -436,18 +455,15 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
436455 val = (val & 0xffffffff00000000uL ) | (* src );
437456
438457 #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
439- // Wait for flash lock.
440- while (LL_HSEM_1StepLock (HSEM , SEMID_FLASH_CPU2 )) {
441- }
458+ // Wait for flash interlocks
459+ flash_sync_lock_aquire ();
442460 #endif
443461
444462 status = HAL_FLASH_Program (FLASH_TYPEPROGRAM_DOUBLEWORD , flash_dest , val );
445463
446464 #if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
447465 // Release flash lock.
448- LL_HSEM_ReleaseLock (HSEM , SEMID_FLASH_CPU2 , 0 );
449- while (__HAL_FLASH_GET_FLAG (FLASH_FLAG_CFGBSY )) {
450- }
466+ flash_sync_lock_release ();
451467 #endif
452468 }
453469
0 commit comments