cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55 BLE and LPM

MahmoudAhmed11
Associate II

Hello,

I am using p-nucleo-wb55. I have a code with an RTC alarm interrupt triggered every 5 seconds. In the ISR, I set a sequencer task that sends a message via BLE. I have enabled the LPM as I want the MCU to enter sleep mode while it isn't working and only wakeup with the RTC alarm. I realized that the MCU doesn't stay in the sleep mode and when I debug, I realized that it wakes up so fast as the IPCC RX Interrupt is triggered continuously with high frequency.
How can I control this, knowing that I don't need the MCU to do any task through those 5 seconds, I just want it to sleep and wakeup only after 5 seconds.

Thanks in advance

12 REPLIES 12
MahmoudAhmed11
Associate II

Hello @FilipKremen 

Yes, I have checked and I can't find a solution to my problem.
Why shouldn't I add code in the main? I just put it in to make it easier to detect whether the MCU enters sleep mode or keeps blinking.

FilipKremen
ST Employee

Hello,

the LED keeps blinking because BLE advertising is running and it wakes up the MCU. If you comment this line  Adv_Request(APP_BLE_FAST_ADV); in app_ble.c file, it stops blinking.

I recommend reading low power section in STM32WB55 datasheet. (3.7.5)

Datasheet - STM32WB55xx STM32WB35xx - Multiprotocol wireless 32-bit MCU Arm<Sup>®</Sup>-based Cortex<Sup>®</Sup>-M4 with FPU, Bluetooth<Sup>®</Sup> 5.4 and 802.15.4 radio solution

Best regards,

Filip Kremen

mgatti
Associate II

Hello @MahmoudAhmed11 

I have a configuration similar to yours in which I only need to transmit the data contained in the advertisement.

I'll try to explain to you what I did, I hope you understand.

In the Adv_Cancel function, I added:

 

/* USER CODE BEGIN Adv_Cancel_2 */

activeFlag = false;
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);

/* USER CODE END Adv_Cancel_2 */

activeFlag is a boolean global variable (initialized to false)

Then I have the function:

 

static void Adv_Cancel_Req(void) {
/* USER CODE BEGIN Adv_Cancel_Req_1 */

/* USER CODE END Adv_Cancel_Req_1 */
UTIL_SEQ_SetTask(1 << CFG_TASK_ADV_CANCEL_ID, CFG_SCH_PRIO_0);
/* USER CODE BEGIN Adv_Cancel_Req_2 */

/* USER CODE END Adv_Cancel_Req_2 */
return;
}

 


And the function:

void Adv_Start(void) {

// ... manufacturer specific data update (into advertising array)

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

HW_TS_Start(myTimerFlag, (ADVERTISING_TIMEOUT_MS * 1000 / CFG_TS_TICK_VAL));
return;
}

 

 

In the APP_BLE_Init() function, I added:

/* USER CODE BEGIN APP_BLE_Init_2 */

HW_TS_Create(CFG_TIM_STOP_ADV, &(myTimerFlag), hw_ts_SingleShot, Adv_Cancel_Req);

/* USER CODE END APP_BLE_Init_2 */

 

In the while(1) loop, I don't directly call the MX_APPE_Process() function, but I call a state machine whose main states are:

  1. I acquire a series of data
  2. I transmit the packet; this state is in turn made up of several states:
    • "Initialization" state: if the activeFlag flag is false, I execute MX_APPE_Init() and set activeFlag=true
    • "Send data" state: I call the MX_APPE_Process() and Adv_Start() functions
    • "Wait" state: As long as the activeFlag flag is true, I continue to call the MX_APPE_Process() function; otherwise, I move to the next state.
  3. I put the microcontroller to sleep and ensure that, upon waking, it restarts from step 1.

 

This ensures that the device functions correctly. Each time I invoke the transmission procedure, packets are sent for a time equal to ADVERTISING_TIMEOUT_MS (I set it to 1000, or 1 second).

I hope the explanation is clear and that it can be of help to you.

What I haven't been able to achieve, however, is achieve similar behavior when enabling the Eddystone TML Beacon protocol (in STM32CubeMX: BT SIG Beacon = EDDYSTONE_TLM_BEACON).

I hope someone can help me.