Skip to content

Commit a89d715

Browse files
committed
stm32wb55/flash: Update semaphore use for flash cpu synchronisation.
Signed-off-by: Andrew Leech <[email protected]>
1 parent 07dc7fb commit a89d715

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

ports/stm32/flash.c

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
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

8184
typedef 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.
296330
int 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

Comments
 (0)