cancel
Showing results for 
Search instead for 
Did you mean: 

BLE advertising stops randomly when going in stop2 mode

oga
Associate III

hello every one

I'm working on a STM32WB35 custom board with full ble stack

what could cause C0 rf controler to stops advertising when going in stop2 mode?

to get focused on my bug I've build a simple app that use tiny LPM as ble_heartbeat example

except that I dont have any advertising frequency change I have no custom app

test purpose is to init ble stack start advertising and then go to stop 2 mode and advertise like this for ever

I'm allowing stop2 mode as soon as we finished APP_BLE_Init() function

 

  BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = NULL;
  BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 0;

  /**
   * Start to Advertise to be connected by a Client
   */
  Adv_Request(APP_BLE_FAST_ADV);

  /* USER CODE BEGIN APP_BLE_Init_2 */
  UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_BLE, UTIL_LPM_ENABLE);
  //DUMMYTSK_Init();
  /* USER CODE END APP_BLE_Init_2 */

  return;
}

 

 

Enter and Exit LowPower functions are sames as BLE_heartbeat exemple

 

 

static void EnterLowPower(void)
{
  /**
   * This function is called from CRITICAL SECTION
   */

  while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));

  if (! LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID))
  {
    if(LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB())
    {
      /* Release ENTRY_STOP_MODE semaphore */
      LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);

      Switch_On_HSI();
      __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
    }
  }
  else
  {
    Switch_On_HSI();
    __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
  }

  /* Release RCC semaphore */
  LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);

  return;
}

/**
  * @brief Restore the system to exit stop mode
  *  none
  * @retval none
  */
static void ExitLowPower(void)
{
  /* Release ENTRY_STOP_MODE semaphore */
  LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);

  while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));

  if(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
  {
/* Restore the clock configuration of the application in this user section */
/* USER CODE BEGIN ExitLowPower_1 */
	  Switch_On_HSE();
/* USER CODE END ExitLowPower_1 */
  }
  else
  {
/* If the application is not running on HSE restore the clock configuration in this user section */
/* USER CODE BEGIN ExitLowPower_2 */

/* USER CODE END ExitLowPower_2 */
  }

  /* Release RCC semaphore */
  LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);

  return;
}

/**
  * @brief Switch the system clock on HSI
  *  none
  * @retval none
  */
static void Switch_On_HSI(void)
{
  LL_RCC_HSI_Enable();
  while(!LL_RCC_HSI_IsReady());
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
  LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
  while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
  return;
}

/* USER CODE BEGIN Private_Functions */
void Switch_On_HSE(void)
{
  LL_RCC_HSE_Enable();
  __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);
  while(__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_1);
  while(!LL_RCC_HSE_IsReady());
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
  while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
  return;
}

 

 

the only difference is that I have added an LPM ID bit to be able to have trace even if LPM is enable

 

 

/******************************************************************************
 * LOW POWER
 ******************************************************************************/
/**
 * Supported requester to the MCU Low Power Manager - can be increased up  to 32
 * It list a bit mapping of all user of the Low Power Manager
 */
typedef enum
{
  CFG_LPM_APP,
  CFG_LPM_APP_BLE,
  /* USER CODE BEGIN CFG_LPM_Id_t */
  CFG_LPM_DBG_TRACE,
  /* USER CODE END CFG_LPM_Id_t */
} CFG_LPM_Id_t;

 

 

I have modified the app_conf.h to get the LPM and TRACE at same time

 

 

#ifdef _DEBUG_
#define CFG_LPM_SUPPORTED           1
#define CFG_DEBUGGER_SUPPORTED      1
#else
#define CFG_LPM_SUPPORTED           1
#define CFG_DEBUGGER_SUPPORTED      0
#endif

/**
 * When CFG_DEBUG_TRACE_FULL is set to 1, the trace are output with the API name, the file name and the line number
 * When CFG_DEBUG_TRACE_LIGHT is set to 1, only the debug message is output
 *
 * When both are set to 0, no trace are output
 * When both are set to 1,  CFG_DEBUG_TRACE_FULL is selected
 */
#define CFG_DEBUG_TRACE_LIGHT     0
#define CFG_DEBUG_TRACE_FULL      1

 

 

the dbg_trace.c functions have been modified accordingly

 

 

static void DbgTrace_TxCpltCallback(void)
{
#if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
  uint8_t* buf;
  uint16_t bufSize;

  BACKUP_PRIMASK();

  DISABLE_IRQ();			/**< Disable all interrupts by setting PRIMASK bit on Cortex*/
  /* Remove element just sent to UART */
  CircularQueue_Remove(&MsgDbgTraceQueue,&bufSize);

  /* Sense if new data to be sent */
  buf=CircularQueue_Sense(&MsgDbgTraceQueue,&bufSize);


  if ( buf != NULL) 
  {
    RESTORE_PRIMASK();
    DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback);
  } 
  else
  {
    DbgTracePeripheralReady = SET;
    RESTORE_PRIMASK();
  }

#else
  BACKUP_PRIMASK();

  DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/

  DbgTracePeripheralReady = SET;

  RESTORE_PRIMASK();
#endif

  if(DbgTracePeripheralReady==SET) UTIL_LPM_SetStopMode(1 << CFG_LPM_DBG_TRACE, UTIL_LPM_ENABLE);
}
#endif
size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize)
{
  size_t chars_written = 0;
  uint8_t* buffer;

  BACKUP_PRIMASK();

  /* Ignore flushes */
  if ( handle == -1 )
  {
    chars_written = ( size_t ) 0;
  }
  /* Only allow stdout/stderr output */
  else if ( ( handle != 1 ) && ( handle != 2 ) )
  {
    chars_written = ( size_t ) - 1;
  }
  /* Parameters OK, call the low-level character output routine */
  else if (bufSize != 0)
  {
    chars_written = bufSize;
    /* If queue emepty and TX free, send directly */
    /* CS Start */

#if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
    DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
    buffer=CircularQueue_Add(&MsgDbgTraceQueue,(uint8_t*)buf, bufSize,1);
    if (buffer && DbgTracePeripheralReady)
    {
      DbgTracePeripheralReady = RESET;
      RESTORE_PRIMASK();
      DbgOutputTraces((uint8_t*)buffer, bufSize, DbgTrace_TxCpltCallback);
    }
    else
    {
      RESTORE_PRIMASK();
    }
#else
    DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
    DbgTracePeripheralReady = RESET;
    RESTORE_PRIMASK();

    DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback);
    while (!DbgTracePeripheralReady);
#endif
    if(DbgTracePeripheralReady==RESET) UTIL_LPM_SetStopMode(1 << CFG_LPM_DBG_TRACE, UTIL_LPM_DISABLE);
    /* CS END */
  }
  return ( chars_written );
}

 

 

theses are all the differences from a totally fresh design generated by cube mx

and it works almost flawlessly

after the init and all prints finished main core is going to stop2 mode and is waked @ each adv frames

but some times the C0 stops sending adv and stops awaking  main core

I've tested on different board on some of them it appends after 30 mins or 1h on some other about 3 or 4 wake-up from stop2 cycle and most of time it appends direct after first stop2 mode switch

I have test with adding a periodic task that read C0 HW fault registers @SRAM2A

 

 

	uint32_t* p=SRAM2A_BASE;
	printf("C2 HW %08lX\n",*p);
	printf("C2 PC %08lX\n",*(p+4));
	printf("C2 LR %08lX\n",*(p+8));
	printf("C2 SP %08lX\n",*(p+12));

 

 

 and it shows no issue of hard fault 

 

I have also few HCI_HARDWARE_EVT_CODE that pops from time to time that I don't know how to avoid

[tl_mbox.c][OutputDbgTrace][758] ble evt: 0x10
[tl_mbox.c][OutputDbgTrace][761] payload: 01
[tl_mbox.c][OutputDbgTrace][776]

[app_ble.c][SVCCTL_App_Notification][476] >>== HCI_HARDWARE_ERROR_EVT_CODE

[app_ble.c][SVCCTL_App_Notification][477] Hardware Code = 0x01

I've try on a P-nucleoWB55 board and It didn't falls into any of theses tow bugs

any idea will be greatly appreciated

thanks for reading until here

 

0 REPLIES 0