BLE mesh and FLASH access problem
Hello,
I am trying to develop app based on BLE_MeshLightingProvisioner example.
From the readme file, I know that the node can be self provisioned and configured when the ENABLE_PROVISIONER_FEATURE is defined. This is a great feature and I want to use it.
So I uncommented ENABLE_PROVISIONER_FEATURE define.
In this example, there is a problem with FLASH access. As can you see on the screenshot AppliPrvnNvm_Process tries to save data but it is always HAL_TIMEOUT.
After more tests I can see when microcontroller is fully cleared (RDP -> 0xBB -> 0xAA) this function works properly and returns HAL_OK.
But after reset there is always HAL_TIMEOUT returned.
The next problem with FLASH access is that I can not write my data to FLASH.

In the cube version 1.6.0 there is provided an example BLE_RfWithFlash with flash_driver.c.
The new flash driver should provide correct synchronization between the two cores during flash access.
I made the following changes based on this example.
Inside my mesh app I change MoblePalNvmWrite and MoblePalNvmErase using functions from flash_driver.c. Please look at the code below.
MOBLE_RESULT MoblePalNvmErase(MOBLEUINT32 address,
MOBLEUINT32 offset)
{
HAL_StatusTypeDef status = HAL_OK;
FLASH_EraseInitTypeDef erase;
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Page = GetPage(address + offset); /* 126 or 127 */;
erase.NbPages = FLASH_SECTOR_SIZE >> 12;
FD_EraseSectors(erase.Page, erase.NbPages);
return status == HAL_OK ? MOBLE_RESULT_SUCCESS : MOBLE_RESULT_FAIL;
}
MOBLE_RESULT MoblePalNvmWrite(MOBLEUINT32 address,
MOBLEUINT32 offset,
void const *buf,
MOBLEUINT32 size)
{
MOBLE_RESULT result = MOBLE_RESULT_SUCCESS;
if (offset > NVM_SIZE)
{
result = MOBLE_RESULT_INVALIDARG;
}
else if (size == 0)
{
result = MOBLE_RESULT_FALSE;
}
else if (offset + size > NVM_SIZE)
{
result = MOBLE_RESULT_INVALIDARG;
}
else if (offset & 3)
{
result = MOBLE_RESULT_INVALIDARG;
}
else if (size & 3)
{
result = MOBLE_RESULT_INVALIDARG;
}
else
{
size >>= 3;
uint64_t* src = (uint64_t*)buf;
for (size_t i = 0; i < size; i++)
{
do
{
FD_WriteSingleData(address + offset + (i <<3), src[i]);
} while(*((uint64_t*)(address + offset + (i <<3))) != src[i]);
}
}
return result;
}I also call SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7); at the end of void APP_BLE_Init( void );
There is more changes in stm32wbxx_it.c connected with using semaphores.
I also copied these wrap function to my project:
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
#if(CFG_USE_SEQ_TO_WAIT_FOR_SEM == 1)
WaitedSemStatus_t FD_WaitForSemAvailable(WaitedSemId_t WaitedSemId)
{
if(WaitedSemId == WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU1)
{
LL_HSEM_ClearFlag_C1ICR(HSEM, __HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)); /* There is a bug in __HAL_HSEM_CLEAR_FLAG() */
if(LL_HSEM_GetStatus(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID))
{
APP_DBG_MSG("\r\n\rWAIT UNTILL CPU1 ALLOWS FLASH OPERATION\n");
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID));
UTIL_SEQ_WaitEvt( 1<< CFG_IDLEEVT_FLASH_OPER_ALLOWED);
HAL_HSEM_DeactivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID));
}
}
if(WaitedSemId == WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU2)
{
LL_HSEM_ClearFlag_C1ICR(HSEM, __HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)); /* There is a bug in __HAL_HSEM_CLEAR_FLAG() */
if(LL_HSEM_GetStatus(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID))
{
APP_DBG_MSG("\r\n\rWAIT UNTILL CPU2 ALLOWS FLASH OPERATION\n");
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID));
UTIL_SEQ_WaitEvt( 1<< CFG_IDLEEVT_FLASH_OPER_ALLOWED);
HAL_HSEM_DeactivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID));
}
}
return WAITED_SEM_FREE;
}
#endif
void HAL_HSEM_FreeCallback(uint32_t SemMask)
{
if(SemMask == __HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID))
{
UTIL_SEQ_SetEvt(1<< CFG_IDLEEVT_FLASH_OPER_ALLOWED);
}
if(SemMask == __HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID))
{
UTIL_SEQ_SetEvt(1<< CFG_IDLEEVT_FLASH_OPER_ALLOWED);
}
}
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_HSEM_CLK_ENABLE();
/* System interrupt init*/
/* USER CODE BEGIN MspInit 1 */
/* HSEM_IRQn interrupt configuration */
HAL_NVIC_SetPriority(HSEM_IRQn, 15, 0);
HAL_NVIC_EnableIRQ(HSEM_IRQn);
/* USER CODE END MspInit 1 */
}
/* USER CODE END FD_WRAP_FUNCTIONS */On the screenshot you can see endless execution do {} while() because of flash write fails.

From this forum I know that there are problems with FLASH access in examples based on BLE. But in mesh write to FLASH does not work at all.
Anyone plays with BLE mesh and deal with this issue?