cancel
Showing results for 
Search instead for 
Did you mean: 

BLE_Heartrate CubeMX

SLevi.1
Associate III

I want to add a EXTI0 line to act as a wakeup. I took the BLE_Heartrate example as a base. Out tyhe box, it compiles & runs ok.

When I use CubeMX 6.16 to edit the BLE_Heartrate ioc to add PE0 as the EXTI0, next time I compile, I get an error that I'm missing stm32wbaxx_ll_utils.c.

If I "cure" this by copying the file from elsewhere, I get other file-not-found errors on stm32wbaxx_ResetHandler_GCC.s and app_bsp.c.

What gives? Surely the example provided by ST should be able to handle a minor change in the ioc file? The BLE_Heartrate and other BLE_ examples are inpenetrable and difficult to understand at the best of times. ST is not helping anybody by not explaining how the BLE_Heartrate example may be modified to get e.g. true low power stop2, how to set an RTC alarm to wake up from this.

9 REPLIES 9
grohmano
ST Employee

Hello @SLevi.1,

could you be please more specific about your setup and your goal. It can be quite variable even in wireless family devices.

Which version of SDK, which board (or MCU), which low-power mode and which IDE are you using?

I tried to simply add PE0 as EXTI0 in .ioc from CubeWBA 1.8.0 package meant to be for NUCLEO-WBA65 and it worked perfectly to me. However, if I do not know your specification, I cannot help you any further

 

Best Regards,

grohmanno

 

Hi,

I'm using STM32CubeIDE v1.19.1. I have STM32CubeMX v6.16.1 installed, but the IDE refuses to open the .ioc file directly as it insists CubeMX is at v6.15.0.

So I open the .ioc file by launching CubeMX myself. MCU Reference is "STM32WBA65RIVx", the Firmware Pakage Name & Version is "STM32Cube FW_WBA V1.8.0"

Ok, so I noticed in CubeMX that the project toolchain/IDE was set to EWARM, not STM32CubeIDE. Also If I select the "copy all used libraries into the project folder", the the missing files are appearing after all, so that would appear to be the answer. Who knew?

However, I think my comment about the understanding of the BLE_ examples still stands. There's plenty of stuff on the web about the low power capabilities of the stm32wba65, but it is not at all clear how all these are packaged up and wrapped in ST libraries such as HAL_PWR_ and LPM & the sequencer.

grohmano
ST Employee

Hi,

if you want to get understanding in terms of BLE with STM32, you can refer to ST Wiki - BLE.

There you can find references to various user manuals, application notes, YouTube tutorials too.

Also, you may find all of the BLE examples explained how they work, e.g. your Heart Rate example.

 

On ST Wiki, you may refer to pages about sequencer, PWR etc. too. 

 

If you need any further help, do not hesitate to ask

Best Regards,

grohmano

Hi Grohmano,

I'm starting to get somewhere with the BLE_Heartrate example. Now I'm running into the problem of too high current consumption on  my custom board when trying to use stop2 mode. The custom board has other components such as a SPI flash memory chip, a lora modem and a I2C gyro. I have implemented code to put all these devices into their respective low power modes.

If I run my code on the Nucleo devkit, current consumption goes down to 12uA as the BLE goes into it's LPM advertising stage. If I run the same code on my custom board, I cannot get the current down below approximately 550uA. On the custom board, if I comment out the BLE calls and any use of the scheduler or stm32_lpm, and use a direct call to HAL_PWR_EnterSTOPMode, the current drops down to 160uA which is more like acceptable.

As an experiment, I sacrificed a board and removed components one by one to see if I could find the culprit. Removing the flash, lora & gyro completely did not help much, so I know I'm putting them into low power modes.

So how do I know if/when the main and/or BLE cores are truly in stop2 mode? There must be something keeping one of the cores awake, or drawing excessive current. 

grohmano
ST Employee

Hi @SLevi.1,

firstly, STM32WBA65 is single-core MCU. There is not any BLE core, only the RADIO peripheral. And in order to MCU go to STOP2 mode, it is necessary that RADIO is in deep sleep mode.

To your question, the STOP2F status flag in the PWR status register (PWR_SR) indicates that the MCU was in
STOP2 mode. (reference manual, section 11.7.8)

 

I’d like to point out a few things you should pay attention to in your implementation in order to reduce consumption:

  • check PWR->CR1 register for low power mode selection
  • check SCB->SCR if SLEEPDEEP bit is set
  • verify on your board that SMPS pins (inductor, capacitor) are populated as ST recommends
  • ensure all unused GPIOs are low‑leakage

 

If you need any further help, do not hesitate to ask

Best Regards,

grohmano

Hi,

thanks for the suggestions; my stop2 current consumption os down to about 30uA now :)

However, the code wakes on a timer, and uses an SPI flash chip using HAL_ functions. Unfortunately, the HAL_ spi functions are littered with HAL_GetTick() calls. After coming out of stop2 mode, HAL_GetTick() is stuck - the value never increments. How can I get the sys tick running again for the duration of my timer callback?

grohmano
ST Employee

Hello, 

Systick is enabled by weak HAL_ResumeTick() function in UTIL_SEQ_Idle():

void UTIL_SEQ_Idle( void )
{
#if ( CFG_LPM_LEVEL != 0)
  HAL_SuspendTick();
#if (CFG_SCM_SUPPORTED == 1)
  /* SCM HSE BEGIN */
  SCM_HSE_StopStabilizationTimer();
  /* SCM HSE END */
#endif /* CFG_SCM_SUPPORTED */
  UTIL_LPM_Enter(0);
  HAL_ResumeTick();
#endif /* CFG_LPM_LEVEL */
  return;
}

 

You can either call this function in your timer callback, or you can set task in your timer callback and when the sequencer executes this task, SysTick should be already enabled (which I recommend).

Calling 

HAL_ResumeTick

is not re-enabling the systick. What clock is used for systick? I am using HSE & LSE. I enclose my SystemClock_Config function (generated by CubeMX) for you to see how they are set up:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY);

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_MEDIUMLOW);

  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE
                              |RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEDiv = RCC_HSE_DIV1;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK7|RCC_CLOCKTYPE_HCLK5;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB7CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.AHB5_PLL1_CLKDivider = RCC_SYSCLK_PLL1_DIV1;
  RCC_ClkInitStruct.AHB5_HSEHSI_CLKDivider = RCC_SYSCLK_HSEHSI_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }

   /* Select SysTick source clock */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);

   /* Re-Initialize Tick with new clock source */
  if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
  {
    Error_Handler();
  }
}

 

grohmano
ST Employee

Hello,

unfortunately, I do not think I can help you without seeing your code. If it is possible for you, please can you send me your project, so I can examine it further?

With the information I have, I would possibly expect that the problem could be:

  1. You call SPI_Transmit in some TIM_IRQ_Handler which has higher priority than SysTickHandler and therefore it does not increase. To solve this, just set sequencer task for SPI transmitting in your interrupt handler and then return back. It is generally recommended to have interrupt handler function as short as possible.
  2. Your SysTick source is HSE, you can try to switch it to LSE which is more power efficient and more likely available after waking from low-power mode. It probably is not the cause of your problem but it will help you to more optimize your code. You can do it with this:
/* Select SysTick source clock */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_LSE);

 

If these tips won't help and you cannot send your project, I recommend you open a case on our ST Online Support Center 

Best Regards,

grohmano