Closed beckmx closed 9 months ago
I tested a BLE example but it drains the battery in 5 hours, a 3.7v 1200mah
@beckmx Which MCU are you targgeting? I spent some time tinkering with hibernate core on BL702 so maybe I will be able to help
I am using the bl616
Okey, but maybe the HBN core is same or at least very similar to BL702's. Could you explain in details what problems are you facing and/or what are you trying to achieve?
Sure, specifically talking about deep sleep i haven’t done anything really, but I created a BLE beacon which I want to deep sleep after broadcasting its bluetooth signal, should be the simplest way I believe
Okey, by basing on sources from diffrent versions of SDKs (bl_iot_sdk and bl_mcu_sdk). I was able to enter deep sleep in this way (it's almost original version from bl_mcu_sdk v 1.45 if i remmber correctly):
`ATTR_TCM_SECTION void hibernate_enter(enum hibernateLevel hibernate_level) { uint32_t tmpVal;
/* disable interrupts */
portDISABLE_INTERRUPTS();
/* disable 32kHz clock*/
if (hibernate_level >= HIBERNATE_LEVEL_2)
HBN_Power_Off_RC32K();
else
HBN_Power_On_RC32K();
HBN_Power_Down_Flash(NULL);
/* SF io select from efuse value */
uint32_t flash_select = BL_RD_WORD(0x40007074);
if (((flash_select >> 26) & 7) == 0) {
HBN_Set_Pad_23_28_Pullup();
}
/* Select RC32M */
GLB_Set_System_CLK(GLB_DLL_XTAL_NONE, GLB_SYS_CLK_RC32M);
/* power off xtal */
AON_Power_Off_XTAL();
GLB_Power_Off_DLL();
PDS_Power_Off_PLL();
/* HBN mode LDO level */
tmpVal = BL_RD_REG(HBN_BASE, HBN_CTL);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, HBN_LDO11_AON_VOUT_SEL, PM_HBN_LDO_LEVEL_DEFAULT);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, HBN_LDO11_RT_VOUT_SEL, PM_HBN_LDO_LEVEL_DEFAULT);
BL_WR_REG(HBN_BASE, HBN_CTL, tmpVal);
/* Set HBN flag */
BL_WR_REG(HBN_BASE, HBN_RSV0, HBN_STATUS_ENTER_FLAG);
tmpVal = BL_RD_REG(HBN_BASE, HBN_CTL);
/* Set HBN level, (HBN_PWRDN_HBN_RAM not use) */
switch (hibernate_level) {
case HIBERNATE_LEVEL_0:
tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_PWRDN_HBN_CORE);
tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_PWRDN_HBN_RTC);
break;
case HIBERNATE_LEVEL_1:
tmpVal = BL_SET_REG_BIT(tmpVal, HBN_PWRDN_HBN_CORE);
tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_PWRDN_HBN_RTC);
break;
case HIBERNATE_LEVEL_2:
tmpVal = BL_SET_REG_BIT(tmpVal, HBN_PWRDN_HBN_CORE);
tmpVal = BL_SET_REG_BIT(tmpVal, HBN_PWRDN_HBN_RTC);
break;
default:
break;
}
/* Set power on option:0 for por reset twice for robust 1 for reset only once*/
tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_PWR_ON_OPTION);
BL_WR_REG(HBN_BASE, HBN_CTL, tmpVal);
*(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIP + HBN_OUT0_IRQn) = 0;
*(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIP + HBN_OUT1_IRQn) = 0;
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, 0xffffffff);
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, 0);
/* Enable HBN mode */
tmpVal = BL_RD_REG(HBN_BASE, HBN_CTL);
tmpVal = BL_SET_REG_BIT(tmpVal, HBN_MODE);
BL_WR_REG(HBN_BASE, HBN_CTL, tmpVal);
while (1) {
GLB_SW_POR_Reset();
}
}`
What kind of wakeup source (GPIO/RTC/ACOMP etc) do you need in your application? Oh and I don't think you can rely on Boufallo team right now. They are quite unresponsive recently and when I was mailing with them some time ago, the customer service said they are having problems with insufficient work force.
Now, when you search the current repo using HBN_BASE
phrase, you will find this particular function:
https://github.com/bouffalolab/bouffalo_sdk/blob/c1a6aa7c46bd12393d43b50e520f7cda19005c37/drivers/soc/bl616/std/include/bl616_pm.h#L40
and that should be your starting point ;)
In case of any problems, don't hesitate to ask ;)
interesting... so i imported that header blb616_pm.h
and used pm_hbn_mode_enter(PM_HBN_LEVEL_0,3000);
in my code and compiled :0 i will try later with a real device :)
i guess, it's just like a blocking function if i understand it correctly? and then takes where it left? or resets the mcu? what was your experience there, i will post my results tomorrow
In case of deep sleep, it disables most of peripherals and almost turning off the MCU (sleep_level defines how many of them will be disable, i.e. deepest one let you wake-up MCU only from particular set of GPIOs). it's resetting the MCU after wake-up, I'm using "ATTR_HBN_NOINIT_SECTION" macro to preserve some state between wake-ups. There are some options with jump to specific address after wake-up and ram retention as well but I didn't investigate this deep enough.
Right, just call these api will work for deep sleep with pds and hbn, if you use others like acomp or gpio, should do some other configurations. We will push code for you for reference.
Thank you @sakumisu i am using Bluetooth so I am okay with an example to restart when it comes back from hbn
Have done
I tried the RTC deep sleep and works wonderfully, i even could make it work with a cr2450, but it only worked once, but worked :)
Hi @sakumisu ! I've just tried the new HBN and PDS examples. I tried hbn_rtc and pds_rtc. In both cases, the MCU seems to reset completely at wake up, after 1s.
However, if I understand correctly, PDS should allow to resume the execution of the firmware without a reset of the MCU, right? I tried changing the PDS level to lower values, but in those cases, the MCU would never wake up.
Would you like to explain the differences between HBN, PDS and the levels?
Thanks!
Hi @sakumisu ! I've just tried the new HBN and PDS examples. I tried hbn_rtc and pds_rtc. In both cases, the MCU seems to reset completely at wake up, after 1s.
However, if I understand correctly, PDS should allow to resume the execution of the firmware without a reset of the MCU, right? I tried changing the PDS level to lower values, but in those cases, the MCU would never wake up.
Would you like to explain the differences between HBN, PDS and the levels?
Thanks!
Only pds level 1 can run without reset, but level1 has high power dissipation, so we only suggest you to use pds15 in bl616.
BTW, due to the fact that this thread is quite active, can we have a example with RAM retention?
Only pds level 1 can run without reset, but level1 has high power dissipation, so we only suggest you to use pds15 in bl616.
What would be the power usage of the BL616 in PDS15 vs PDS1? And do I need to do anything special for the PDS1 mode to work? It doesn't seem to wake up at all in my tests.
BTW, due to the fact that this thread is quite active, can we have a example with RAM retention?
Can you describe more? Only variables in ram retention or other else?
Only pds level 1 can run without reset, but level1 has high power dissipation, so we only suggest you to use pds15 in bl616.
What would be the power usage of the BL616 in PDS15 vs PDS1? And do I need to do anything special for the PDS1 mode to work? It doesn't seem to wake up at all in my tests.
You should call pm_pds_irq_register before enter pds mode. See comments in Line 627.
Hello @sakumisu I noticed something wierd with the latest commits, I have this BLE code acting as a beacon, I have a task that is putting the bl616 into hbn mode (following the examples), in this first set of commits where the examples were introduced, this code was restarting correctly, with the latest changes, it hangs when stopping bluetooth:
void go_hbn(void *pvParameters) {
const TickType_t xDelay = 50 / portTICK_PERIOD_MS;
while (1) {
//turning off advertising from zephyr
vTaskDelay(xDelay);
int ret = set_adv_enable(false);
if (ret) {
printf("Restart adv fail. \r\n");<-----looks like it fails here
}
vTaskDelay(xDelay);
printf("Bluetooth turned off.\r\n");
bt_disable();<----hangs here
vTaskDelay(xDelay);
printf("Going to sleep.\r\n");
#if (PM_PDS_LDO_LEVEL_DEFAULT == 8)
printf("Going to sleep_0.\r\n");
printf("hbn_pattern:0x%08x\r\n",*((volatile uint32_t *)0x20010300));
hal_pm_ldo11_use_ext_dcdc();
bl_lp_hbn_init(0,0,1,0);
bl_lp_hbn_enter(&hbn_test_cfg);
#else
printf("Going to sleep_1.\r\n");
/* Wake up every 10 seconds by hb0 */
pm_hbn_mode_enter(PM_HBN_LEVEL_0, 32768*180);
#endif
}
}
int main(void)
{
board_init();
configASSERT((configMAX_PRIORITIES > 4));
uart0 = bflb_device_get_by_name("uart0");
shell_init_with_task(uart0);
printf("Configuring bt");
btblecontroller_em_config();
// /* Init rf */
printf("Configuring RF");
if (0 != rfparam_init(0, NULL, 0)) {
printf("PHY RF init failed!\r\n");
return 0;
}
printf("Configuring bt controller");
btble_controller_init(configMAX_PRIORITIES - 1);
hci_driver_init();
bt_addr_le_t ble_addr = { BT_ADDR_LE_RANDOM, addr };
bt_id_create(&ble_addr, NULL);
bt_enable(bt_enable_cb);
printf("Beacon started succesfully!");
xTaskCreate(go_hbn, "go_hbn", 1024, NULL, 1, NULL);
vTaskStartScheduler();
// create a freertos task to repeat every 5 seconds
while (1) {
/* code */
}
return 0;
}
hello @sakumisue, would you help me with an example for deep sleep mode? i was browsing the code but i dont find enough information on the sdk to invoke it
thanx a lot!