openwch / ch583

The datasheet/SDK/HDK docmentation of Bluetooth LE RISC-V MCU CH582M/CH583M
Apache License 2.0
134 stars 32 forks source link

RTC wakeup example for PM demo #18

Closed 0x0fe closed 1 year ago

0x0fe commented 1 year ago

Hi, The PM demo only implements wake up from GPIO, which is certainly useful in some case but not as much as wake up from RTC. Also since many things are not wrapped in functions yet and there is just no demo for RTC it is unclear what need to be done to achieve deep sleep with RTC wakeup (with LSI).

Could you please update the PM example and add RTC wake up in it (with LSI as clock source)?

I tried to use the sleep function from the HAL directory in BLE demos, however it doesnt work, it never goes to sleep or it goes to sleep without waking up. My understanding is that the HAL functions are only used when working with BLE. In my case the BLE is not used, that is why i need a working implementation of PM demo wth RTC as wakeup source (LSI as clock source). Thanks.

zerosensei commented 1 year ago

Hi 0x0fe, here is a simple example to use RTC to wake up regularly:

  1. Select wakeup source as RTC and enable the interrupt by calling HAL_SleepInit();
  2. Implement the RTC ISR RTC_IRQHandler(), you can set RTC trigger time in the ISR if you want to trig the RTC regularly;
  3. Initialize RTC HAL_TimeInit(), and the function can calibrate RC if you use the LSI. If you don't use TMOS, you can remove TMOS_TimerInit();
  4. Set RTC trigger time RTC_SetTignTime(), and if you want to set a relative time, you can use it like this:

    void set_relative_time(uint32_t rel_time)
    {
    unsigned long irq_status;
    uint32_t curr_time, trig_time;
    
    SYS_DisableAllIrq(&irq_status);
    curr_time = RTC_GetCycle32k();
    trig_time = curr_time + rel_time;
    
    if(trig_time > 0xA8C00000) {
        trig_time -= 0xA8C00000;
    }
    RTC_SetTignTime(trig_time);
    SYS_RecoverIrq(irq_status);
    }
  5. Sleep when you want to sleep:
    while(1) {
        PRINT("sleep\n");
        DelayMs(10);
        LowPower_Sleep(RB_PWR_RAM2K | RB_PWR_RAM30K | RB_PWR_EXTEND);
        //Wait for HSE to stabilize, or wait with IDLE sleep, like in sleep.c
        DelayUs(1400);
        HSECFG_Current(HSE_RCur_100);
        PRINT("wake\n");
        // implement some functions
        DelayMs(100);
    }

    If you have more questions, you can contact our technical support: lpc@wch.cn, or ask in our forum: https://www.wch.cn/bbs. Thank you!

0x0fe commented 1 year ago

thank you this is a good example, it should be added in the SDK examples.