DA14683 Pre-emptive Links to documents:
Datasheet = https://www.renesas.com/tw/en/document/dst/da14683-datasheet?r=1600766
Hardware design guide = https://www.renesas.com/tw/en/document/apn/b-061-application-note-da1468x-application-hardware-design-guidelines?r=1600766
Platform Reference = https://www.renesas.com/tw/en/document/mas/um-b-044-da1468x-software-platform-reference?r=1600766
Software Dev Guide = www.renesas.com/.../um-b-056-da1468x-software-developers-guide
Hardware:
Custom DA14683 Board
Latest SDK = 1.0.14.1081 (last updated in 2018)
Situation:
Relevant Threads:
1) "DA14683: Implementing a "soft power button". Push to sleep. Push again to wake."
https://community.renesas.com/wireles-connectivity/f/bluetooth-low-energy/29023/da14683-implementing-a-soft-power-button-push-to-sleep-push-again-to-wake
2) "DA14683: How to troubleshoot what is blocking extended sleep modes?"
https://community.renesas.com/wireles-connectivity/f/bluetooth-low-energy/28510/da14683-how-to-troubleshoot-what-is-blocking-extended-sleep-modes/100138#100138
3) DA14683: Can't sleep with debugger attached, where in the SDK does it abort?
https://community.renesas.com/wireles-connectivity/f/bluetooth-low-energy/28953/da14683-can-t-sleep-with-debugger-attached-where-in-the-sdk-does-it-abort
NOTE: Before anyone starts asking if these issues are custom hardware related, I can run both the pxp_reporter and BMS demos on my custom hardware, and both sleep with currents in the 300uA range. Given this information, if you still think this is still a hardware issue it would be helpful to maybe suggest some actual troubleshooting ideas instead of just saying "hardware issue".
To repeat my goal here, I'm trying to implement what is essentially a soft power button. Push to sleep. Push again to wake and reset the system. Because of this, I need to retain essentially nothing during sleep. I should be able to shut down everything. The only thing I really care about is being able to wake the system back up with the same button. The system will fully reboot on wake up.
I think I have finally got the DA14683 into a condition where there are no more parts of the system blocking sleep. I shut down everything I could find to shut down, and when I issue the "pm_set_sleep_mode(pm_mode_extended_sleep);" command it looks like it's actually doing it. Nothing is blocking anymore.
That's great, but the sleep current is still in the 3-6mA range. This is too high. Occasionally, after about 45 seconds or so it will drop down to about 600uA. This is still high, but barely acceptable. Sometimes it never drops down and stays in the 3-6mA range.
Questions:
1) How can I troubleshoot what is pulling current while in sleep mode?
Hi Nathan,
As mentioned in one of your previous threads, the SDK includes hooks that hold all the user-defined functions that will be usedby the Power Manager at every wakeup/sleep cycle.
/* * Structure that holds all the user-defined functions that will be used * by the Power Manager at every wakeup/sleep cycle. */ const adapter_call_backs_t timer_0_callbacks = { .ad_prepare_for_sleep = ad_prepare_for_sleep_cb, .ad_wake_up_ind = ad_wake_up_ind_cb, /* * Here, you can define a callback that hits in case the system was about * to sleep but eventually the sleep process was aborted. */ .ad_sleep_canceled = NULL, /* * Here, you can define a callback that hits once XTAL16MHz crystal is settled. */ .ad_xtal16m_ready_ind = NULL, /* * Here, you can define extra clock cycles needed for the system * to stay active, before entering sleep. */ .ad_sleep_preparation_time = 0 };
You can use any of those to debug the sleep mode.
In addition, please double check the following statements :
Have you checked all of these?
2) How can I determine specifically what is waking up the system every 2ms?
Do you have an active timer? You can toggle a GPIO in some of the main functions of your code to debug this. And the suggested hooks can be used in order to check if the sleep is cancelled or not
3) Would having the UART retargeted have a negative effect on the sleep system?
Please comment out UART functionality and run a test.
Regards,
PM_renesas
Thank you for the reply.
I would ask where the tutorial on how to setup and use the "adapter_call_backs_t" functions is, but I'm fairly confident that such a thing does not exist. As a quick Public Service Announcement, I'll try to do my best to write that brief explanation here as a start. As always, let me know if I get any of this wrong.
The struct of function pointers is defined in sys_power_mgr.h:
typedef struct _adptCB { bool (*ad_prepare_for_sleep)(void); void (*ad_sleep_canceled)(void); void (*ad_wake_up_ind)(bool); void (*ad_xtal16m_ready_ind)(void); uint8_t ad_sleep_preparation_time; } adapter_call_backs_t;
The typical use is that the adapters define specific callback functions for some or all of these events such as the following from ad_uart.c. (you can look in that file for what each of those specific callback functions is doing. It's different for each adapter):
const adapter_call_backs_t ad_uart_pm_call_backs = { .ad_prepare_for_sleep = ad_uart_prepare_for_sleep, .ad_sleep_canceled = ad_uart_sleep_canceled, .ad_wake_up_ind = ad_uart_wake_up_ind, .ad_xtal16m_ready_ind = ad_uart_xtal16m_ready_ind, .ad_sleep_preparation_time = 0 };
Then "register" the callbacks during init for that adapter such as again in ad_uart.c:
void ad_uart_init(void) { pm_register_adapter(&ad_uart_pm_call_backs); }
What this "registration" does is adds the struct of callbacks to the "pm_adapters_cb[]" array.
Ok. That's the setup.
How is it used?
In the sys_power_mgr.c file, the pm_sleep_enter() function cycles through the array at multiple times while trying to sleep.
void pm_sleep_enter(uint32_t low_power_periods) { //... // 5. Calculate the overhead added from the Adapters. if (!is_infinite) { for (i = 0; i < dg_configPM_MAX_ADAPTERS_CNT; i++) { p_Ad = pm_adapters_cb[i]; if (p_Ad != NULL) { if (sleep_period > p_Ad->ad_sleep_preparation_time) { sleep_time_reduction += p_Ad->ad_sleep_preparation_time; sleep_period -= p_Ad->ad_sleep_preparation_time; } else { sleep_period = 0; allow_entering_sleep = false; break; } } } } //... /* * Inquiry Adapters about the forthcoming sleep entry */ // 1. Inquiry Adapters for (i = dg_configPM_MAX_ADAPTERS_CNT - 1; i >= 0; i--) { p_Ad = pm_adapters_cb[i]; if ((p_Ad != NULL) && (p_Ad->ad_prepare_for_sleep != NULL)) { if (!p_Ad->ad_prepare_for_sleep()) { break; } } } //... }
The array is also used at wakeup in "pm_init_wake_up()"
static void pm_init_wake_up(void) { //... for (i = 0; i < dg_configPM_MAX_ADAPTERS_CNT; i++) { p_Ad = pm_adapters_cb[i]; if ((p_Ad != NULL) && (p_Ad->ad_wake_up_ind != NULL)) { p_Ad->ad_wake_up_ind(false); } } GLOBAL_INT_RESTORE(); if (call_adapters_xtal16m_ready_ind) { for (i = 0; i < dg_configPM_MAX_ADAPTERS_CNT; i++) { p_Ad = pm_adapters_cb[i]; if ((p_Ad != NULL) && (p_Ad->ad_xtal16m_ready_ind != NULL)) { p_Ad->ad_xtal16m_ready_ind(); } } } //... }
There are some other locations, but those are the ones primarily used when the system is sleeping/waking to determine if any adapter/sub-system wants to block or allow sleep and lets them prepare as required.
One thing to note here is that these callback structures/arrays are not inherently tied to the adapters. They are just functions that are defined and pushed into that array to be checked by the sleep routines. So if you have a custom task or sub-system that you want to have it's own callbacks that get executed when the system sleeps/wakes (such as the DSPS demo) then you just make functions, assign them to the pointer structure, and "register" as above and they will get cycled through the same checks at sleep/wake time. (There is a limit of only 16 array entries as defined by the default "#define dg_configPM_MAX_ADAPTERS_CNT (16)", but you can increase that.)
The next question may be.... Ok, given the above, and the PM_renesas's suggestion to use this system to debug sleep, how do you do that, especially given that the debugger can't be hooked up?
I guess you are supposed to find all the instances of all the adapter init routines that define these callbacks and add a printf function or something, like "UART SLEEP CANCELED" to notify when that function gets called? I'm not exactly sure how I'm supposed to disable the UART and run a test like this though.
If I use the debugger to step through the code, none of the above callbacks are preventing sleep. I have verified this. Can I be sure the system acts the same way with the debugger attached? Nope.
Ok. With that said, to do though your questions:
1) All tasks (except the IDLE task) should be suspended (not running). All the tasks should be in IDLE state.
I shut down all the tasks I created. Is there a list of running tasks I can check to confirm nothing else is running?
2) there are NO pending interrupts (put the sensor in sleep/power down mode )
When the debugger is attached, the sleep system does not return when checking if there are pending interrupts. Yes, I know the system won't sleep when the debugger is attached.
3) there is NO active transaction through the adapters interface
I closed all adapters that I opened before trying to sleep.
4) there are NO intensive write flash operations
Everything has been closed and shut down (radio, adapters, tasks, etc). If there is anything trying to write to the flash at this point I'm not sure what it will be.
5) the J-LINK debugger is not attached (there is no active debugging session)
Yes, I understand that the system won't sleep when the debugger is attached.
If you think the answers to the above concerns are not adequate and one of those concerns may still be what is causing my sleep problems, please let me know what I can specifically test to eliminate more possibilities.
Question: Would having the UART retargeted have a negative effect on the sleep system?
The UART is an important part of the firmware functionality at this point. "Commenting out" all instances of the UART usage will be non-trivial and not something I want to do as a casual test. I need you to confirm that you have some suspicion that having the UART RETARGETED would be causing the system to fail sleep before I go about that effort. Do you have a reason to think that having the UART RETARGETED would cause the system to fail to sleep?
1) All questions above.
2) Given the behavior that I detailed in my previous posts, and documented in my oscilloscope screenshots of sleep current and status, how would I go about determining why the system will sometimes sleep and other times not? And also, what is still pulling 3-6mA of current (as shown in the scope plots) when the system thinks it's sleeping?
Happy Holidays ping.
Happy New years Ping!
Jan 7th ping....
Jan 9th Ping. Yes, I know there was a holiday, but haven't heard from anyone in 28 days.
Jan 11th Ping.