cancel
Showing results for 
Search instead for 
Did you mean: 

BLE mesh and FLASH access problem

lukasz2
Associate III

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.

0693W000000WE0xQAG.jpg

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.

0693W000000WEC5QAO.png

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?

8 REPLIES 8
EMECH
ST Employee

​Hello,

You cannot set the 2 features ENABLE_PROVISIONER_FEATURE and DYNAMIC_PROVISIONER at the same time.

Perhaps it is not clearly explained in the readme.txt file.

It seems that with the ENABLE_PROVISIONER_FEATURE, some FLASH trouble access happens after each reset of the board, this trouble will be solved in the next releasee.

Nevertheless the BLE_MeshLightingProvisioner project is an example of embedded provisioner, the default configuration settings of this project is the Dynamic provisioner.

In this configuration the FLASH accesses works.

The Dynamic provisioner feature is not so different than the provisioner feature, the diffference is that after initialization the device is seen as an unprovisioned device.

To become self provisioned and self configured, you have to open an external terminal with the following configuration:

  • Baud rate of 115200
  • Byte size of 8 
  • Parity None
  • Stop bits 1
  • Data Flow Control None

First unprovision the device:

  • manually (Press and maintain pressed the Reset button, press and maintain pressed the SW1 button, release the Reset button and wait the blinks of the blue LED, release the SW1 button) 
  • or with the command: atut set-2

And run the following command:

atep root

To be sure that the device is correctly provisioned and configured, just press SW1 button, if the blue LED is on it is OK, if not unprovisions the device and run again  the command atep root.

For a scan of the unprovisioned devices, run the command:

atep scan

UUID addresses of the unporvisioned devices are displayed as following:

Device-0 -> F81D4FAE7DEC4B53A154F6FB0726E1C0

To provision and configure the device run the command:

atep prvn-0 2

Where:

Parameter 0 is the displayed index of the device

Parameter 2 is the unicast address you want to associates to the provisioned node (1 is used for the provisioner Node)

After running this command, many lines are displayed on the terminal, till the following one:

38281 Appli_ConfigClient_ConfigureNode - **Node is configured**.

For any other questions, do not hesitate.

Best regards.

lukasz2
Associate III

Hello,

thank you for the answer.

I set only ENABLE_PROVISIONER_FEATURE so I did this right.

I want to use ENABLE_PROVISIONER_FEATURE because I will not have direct access to the final device. Self-provisioning and self-configuration will save a lot of time in my installation. The only thing is the unicast address should be different for each device. I want to use the serial number to generate the address and send it in the broadcast to the concentrator.

I will check the Dynamic provisioner feature maybe this will be better than configuration from the smartphone.

What about flash_driver.c provided in BLE_RfWithFlash example?

It will be included in Mesh example? Because I have trouble with store my own data/setting in FLASH.

Best Regards

Hello EMECH,

I play with Dynamic Provisioner. Below is the log from my attempts. Can you tell me what am I doing wrong, Because I can not provision any device?

Next NVM Address 080c703c 
Provisioned node 
Provisioned Node Address: [0001] 
 
 
********************
PB-ADV Enabled 
PB-GATT Enabled 
Feature: Relay Enabled 
Feature: Proxy Enabled 
Feature: Friend Enabled 
Models data will be saved in Flash 
Embedded Provisioner data saving enabled 
Number of Elements enabled: 1 
Neighbour Table is enabled 
Generic On Off Server Model enabled 
********************
 
BLE-Mesh Lighting Demo v1.12.007
 
BLE-Mesh Library v01.12.007
 
BLE Stack v1.6.0 Branch=0 Type=3
 
FUS v1.1.0
 
BD_MAC Address = [c0]:[e1]:[26]:[07]:[be]:[d2] 
 
UUID Address = [f8] [1d] [4f] [ae] [7d] [ec] [4b] [53] [a1] [54] [d2] [be] [07] [26] [e1] [c0] 
645 Model_RestoreStates - No Saved Data Found 
645 Generic_PowerOnOff_Set - Generic_PowerOnOff_Set callback received 
645 GenericModelServer_GetStatusRequestCb - response status enable 
 
Publishing the Power on state to address C000 
atep scan
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154BA380326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-2 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep prvn-0 2
 
atep prvn-0 2
 
Test command executed successfully
 
 
33996 BLEMesh_PbAdvLinkOpenCb - PB-ADV Link opened successfully 
 
40742 BLEMesh_PvnrDataInputCallback - Device Key: e2 db 93 b1 14 ac 1c 76 ab 41 36 05 d4 1a 37 ca 
40742 BLEMesh_PvnrDataInputCallback - App Key: 8c 70 1b 33 f5 14 0f 28 26 70 91 f5 70 83 ee dd 
40743 BLEMesh_PvnrDataInputCallback - Node Address Assigned = 0 
Device is provisioned by provisioner 
52347 BLEMesh_PbAdvLinkCloseCb - PB-ADV Link Closed successfully 
 
52347 AppliPrvnNvm_Process - Saving in SubPage[00000050] = 
54353 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
74353 ConfigClient_ChkRetries - Retry started 
 
76353 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
96353 ConfigClient_ChkRetries - Retry started 
 
98353 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
118353 ConfigClient_ErrorState - No response from Node 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep scan
 
atep scan
 
 
Device-0 -> F81D4FAE7DEC4B53A154BA380326E1C0
 
 
Device-1 -> F81D4FAE7DEC4B53A154034D0326E1C0
 
 
Device-2 -> F81D4FAE7DEC4B53A154DD340326E1C0
 
Test command executed successfully
 
atep prvn-1 2
 
atep prvn-1 2
 
Test command executed successfully
 
 
279597 BLEMesh_PbAdvLinkOpenCb - PB-ADV Link opened successfully 
 
289353 BLEMesh_PvnrDataInputCallback - Device Key: 1f 64 ed 5c 17 e3 99 7c 72 97 4a 8e c5 76 f0 05 
289354 BLEMesh_PvnrDataInputCallback - App Key: 8c 70 1b 33 f5 14 0f 28 26 70 91 f5 70 83 ee dd 
289355 BLEMesh_PvnrDataInputCallback - Node Address Assigned = 1 
Device is provisioned by provisioner 
293710 BLEMesh_PbAdvLinkCloseCb - PB-ADV Link Closed successfully 
 
293710 AppliPrvnNvm_Process - Saving in SubPage[00000078] = 
295710 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
315710 ConfigClient_ChkRetries - Retry started 
 
317710 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
337710 ConfigClient_ChkRetries - Retry started 
 
339710 ConfigClient_CompositionDataGet - Config CompositionDataGet Message 
359710 ConfigClient_ErrorState - No response from Node 

​Hi,

After the download of the software, to be sure that your device is unporvisioned:

Unprovision the device:

  • manually (Press and maintain pressed the Reset button, press and maintain pressed the SW1 button, release the Reset button and wait the blinks of the blue LED, release the SW1 button) 
  • or with the command: atut set-2

Run the following command for the self provisioning and the self configuration of your provisioner:

atep root

To be sure that your provisioner is correctly provisioned and configured, just press the  SW1 button, if the blue LED is on it is OK, if not unprovisions the device and run again the command atep root.

Now you can run a scan for the unprovisioned devices, with the command:

atep scan

UUID addresses of the unporvisioned devices are displayed as following:

Device-0 -> F81D4FAE7DEC4B53A154F6FB0726E1C0

To provision and configure the device run the command:

atep prvn-0 2

Where:

Parameter 0 is the displayed index of the device

Parameter 2 is the unicast address you want to associates to the provisioned node (1 is used for the provisioner Node)

After running this command, many lines are displayed on the terminal, till the following one:

38281 Appli_ConfigClient_ConfigureNode - **Node is configured**.

Best regards.

Hello,

There is the new cube version 1.7.0 but it seems that does not resolve any issue with Mesh and FLASH access.

​Hello,

Your are right there is no change concerning MESH and FLASH access in this new release.

The trouble you have faced with the ENABLE_PROVISIONER_FEATURE will be solved in the next release.

Did you test the BLE_MeshLightingProvisioner with the DYNAMIC_PROVISIONER defined (as set by default in the mesh_cfg_usr.h file) ?

Best regards.

Hello,

I write the post 14 days ago, please see above. I tested Dynamic provisioner and every time I got "No response from Node". Please see the included log.

Best Regards

Diego Freitas
Associate

Hello lukasz2,

I'm with the same problem! Did you manage to solve it? Thank you