Hi Dialog,
I want to make DA14580 working without any sleep mode and go into deep sleep mode after an I2C event.
I did the changes list below, however it seems DA is not really get into deep sleep mode.
1. I define CFG_DEEP_SLEEP in da15480_config.h and undefine
2. I comment code
#if (EXT_SLEEP_ENABLED)
app_set_extended_sleep();
#elif (DEEP_SLEEP_ENABLED)
app_set_deep_sleep();
#else
app_disable_sleep();
#endif
in main_func to disable sleep mode before I get an I2C package.
3. I add the this code when I get the I2C package:
app_stop_adv();
app_set_deep_sleep();
I saw DA stop advertising but I didn't see the power consumption decrease. It looks like the processor is not halted, it still consume me about 800uA.
Could you help me with how to set DA into Deep Sleep mode after an I2C event(any other event is fine, I just want to force set it into deep sleep mode) while do not use sleep mode before that.
谢谢!
Hi Zeyu:
First please make note of the following:
When you get out of deep sleep hardware uses a dedicated hardware block to copy application code from OTP to SysRam, then it passes the control to M0 processor to run from where it left off before going to deep sleep. Therefore a clean exit from deep sleep occurs only when the application software is in OTP.
If you are using flash memory, the same above steps will occur, resulting in whatever code was in OTP (most likely all zeroes if you have never burnt it) to be copied into sysRAM. M0 will try to execute it leading to a watch dog caused reset. BootRom will fetch code from flash memory and execute it from the beginning. This process takes around 2.5 to 3 seconds.
For the scenario you have described above i recommend the following:
- define CFG_DEEP_SLEEP in da15480_config.h,
- You can comment out the section in arch_main.c, but add one line at the bottom as shown below.
/*
#if (EXT_SLEEP_ENABLED)
app_set_extended_sleep();
#elif (DEEP_SLEEP_ENABLED)
app_set_deep_sleep();
#else
app_disable_sleep();
#endif
*/
app_disable_sleep();
Now you can have the following code at the end of your I2C transaction:
app_stop_adv();
app_set_deep_sleep();
使用上面的代码将改变go into deep sleep but will wake up every 10 seconds to take care of BLE.
If you donot want that to happen, then you need to have the following code:
app_stop_adv();
app_set_deep_sleep()
app_ble_ext_wakeup_on();
app_button_enable();
Now system will only wake up if an external interrupt occurs.
Your interrupt handler (app_button_press_cb) must have the following code:
if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
periph_init(); // re-init peripherals after exiting deep or extended sleep.
if (app_ble_ext_wakeup_get())
{
//Wakeup BLE here
app_disable_sleep();
SetBits32(GP_CONTROL_REG, BLE_WAKEUP_REQ, 1);
app_ble_ext_wakeup_off(); // use this if have used app_ble_ext_wakeup_on() before going to deep sleep
}
app_button_enable();
如果您的代码运行从闪存,代表lace the call to app_deep_sleep with app_set_extended sleep.
If you are loading code from external MCU to DA14580, you have two choices:
use extended sleep only: your power consumption will go to 1.x uA.But you would not have to reload code every time you wake up
use deep sleep: You will get some addition power savings. But you will have to load firmware onto sysRAM everytime
Thanks,
TR_DIALOG
Hi TR_Dialog,
Thanks a lot for your swift reply. I add app_disable_sleep(); after the comment and the application current consumption drop from 800uA to about 200uA. However I still wondering where does the 200uA come from. I tried to define DEVELOPMENT_DEBUG both 0 and 1. Also, I tried to undefine DEVELOPMENT_DEBUG. But the application still consumes 200 uA. Do you have any idea of that?
Basically, in our application, we do not care the wakeup staff because every time the system powers up, we will reload the FW into system ram through SPI bus.
谢谢!
Hi Tr_Dialog,
The problem is solved. Components connected to some DA pins consumes the extra current. I need to configure the PIN to certain mode before I enter deep sleep mode.
Thanks a lot for the help.
有调试好的睡眠例子工程,可以给我一份吗,谢谢!476369963@qq.com
if I want wake up it by ke_timer,how can I modifiy it.
thank you
Hi RandyYu,
Yes you can, just set up a kernel timer before fallingpermanently tosleep . For example if you want to advertise fall to sleep permanently and then start advertise again, you can stop advertising by invoking advertise_stop() and in the advertising stop callback set up a kernel timer. In the callback of the kernel timer you can invoke the advertise_start() in order to start advertise again.
Thanks MT_dialog
which function is the callback of the kernel timer ?
Hi RandyYu,
The declaration of the callback of each timer is a custom function that you insert as input when you start a timer. In case of the easy_timer api (on SDK 5) an examples would be app_easy_timer(time_you_need, callback_that_should_be_called_when_time_elapse). In case of the SDK you will have to declare the message and the callback in the app_task_handlers.h file like all the callbacks that are located in that file and in order to start the timer you need to invoke the app_timer_set() function.
Thanks MT_dialog