prox_reporter rtc_interrupt_hdlr trips twice when in ARCH_EXT_SLEEP_ON

⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at https://www.dialog-semiconductor.com/support . We’ll be fixing bugs / optimising the searching and tagging over the coming days.
10 posts / 0 new
Last post
andrewl
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-05 02:45
prox_reporter rtc_interrupt_hdlr trips twice when in ARCH_EXT_SLEEP_ON

Hi, folks,

 

I've been tracking a fairly irritating bug, and I finally managed to reproduce it on Dialog sample code.  I set up the prox_reporter with CFG_EXT_SLEEP_WAKEUP_RTC so that it will wake up from sleep via the RTC.

 

When I run the prox_reporter with ARCH_SLEEP_OFF, everything runs just fine.  The rtc_interrupt_hdlr trips once every 20 seconds (10 seconds of advertising and 10 seconds before the RTC hits).  That's all just ducky.

 

However, when I run the prox_reporter with ARCH_EXT_SLEEP_ON, after rtc_interrupt_hdlr fires, it then fires *again* 696ms later.  That's not good if you're trying to schedule something reliably.

 

This bug also seems to affect the Timer1 handler as that's what I was tracking down.  I'm reporting it on the RTC as it's a *LOT* easier and more obvious to catch this on the RTC handler.

 

That's too close to the advertising interval to be coincidence.  What is the BLE sleep code doing to cause this?  And how do I fix this?

 

Thanks.

Device: 
PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi andrewl,

Hi andrewl,

Thanks for your question. Let me try to explain how the prox_reporter works when the CFG_EXT_SLEEP_WAKEUP_RTC is defined.

Initially, the device will start adverting. The default sleep mode is extended sleep – see app_default_sleep_mode in user_config.h. This means that the system will go into extended sleep mode between advertising intervals, and it will wake-up automatically via the BLE timer.

After a pre-defined time (3min) – see .advertise_period in user_default_hnd_conf structure in user_config.h ( this value can be changed; for example 12000 advertising for 12sec) – the device will stop adverting and the app_advertise_complete() callback will be triggered and the chip will go into permanent sleep mode ( without advertising). In this callback the RTC is configured to trigger wake-up interrupt from extended sleep – see configure_rtc_wakeup().

If you go inside the configure_rtc_wakeup(), in the rtc_time_t time you can find the RTC configuration: 11h , 55min, 30 sec ) . So, the rtc_interrupt_hdlr() will be triggered when the advertisement has been stopped and after 11h , 55min, 30 sec and then chip will wake up.

I would recommend you to do a quick test and verify it with the SmartSnippets Toolbox Power Profiler.

Change the advertising period to 12 sec: .advertise_period = MS_TO_TIMERUNITS(12000),

Configure the RTC to wake up the DA14531 after 15 sec :  

rtc_time_t time = {.hour_mode = RTC_HOUR_MODE_24H, .pm_flag = 0, .hour = 00,
                       .minute = 00, .sec = 5, .hsec = 00};

Thanks, PM_Dialog

andrewl
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-05 02:45
 

Hi, PM_Dialog,

 

> After a pre-defined time (3min) – see .advertise_period in user_default_hnd_conf structure in user_config.h ( this value can be changed; for example 12000 advertising for 12sec)

Yes, the default is 3 min, I changed this down so that I could replicate the bug more quickly.

 

> If you go inside the configure_rtc_wakeup(), in the rtc_time_t time you can find the RTC configuration: 11h , 55min, 30 sec ) . So, the rtc_interrupt_hdlr() will be triggered when the advertisement has been stopped and after 11h , 55min, 30 sec and then chip will wake up.

No, that is NOT how this works.  The configure_rtc_wakeup() resets the time to 11:55:30 every pass through so that it can always set the alarm 10 seconds in the future relative to that.  So, whenever configure_rtc_wakeup() fires at the end of app_advertise_complete(), the RTC time gets reset and the alarm gets set for 10 seconds in the future.

The rtc_interrupt_hdlr() then fires 10 seconds in the future (sleep+10s).  That's fine.  If ARCH_EXT_SLEEP_ON is set, the problem is that it *also* fires again 696ms later (sleep+10+.696s).  That's not fine. 

I provided a solid explanation of a bug.  I have verified it both on my Agilent Oscilloscope and my Keithley Sourcemeter.  I've been down the rabbit hole hunting it, and I presented a way to replicate it in Dialog code.  Unless the response comes back talking about interrupt masking and possibly priority inversion, it's probably not an answer.

 

> I would recommend you to do a quick test and verify it with the SmartSnippets Toolbox Power Profiler.

I would recommend you hand this ticket off to someone with an oscilloscope.  How do I escalate this?

 

Thanks.

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi andrewl,

Hi andrewl,

Thanks for your comments. I will escalate this internally to start investigating this and I’ll get back to you.

Thanks, PM_Dialog

andrewl
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-05 02:45
Much appreciated.  Thanks for

Much appreciated.  Thanks for doing that.

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi andrewl,

Hi andrewl,

Please check configure_rtc_wakeup(). This function is triggered when the advertisement has been stopped in order to configure the RTC as a wake-up source.

According to configure_rtc_wakeup(), the alarm interrupt is explicitly set to 10 seconds - alarm_time.sec += 10;

The rtc_set_alarm(), takes as an input parameter the alarm_time and the RTC_ALARM_EN_SEC (Enable to trigger alarm when the sec in Time Alarm Register has been reached)

So, the rtc_interrupt_hdlr will generate an interrupt when alarm event occurs (every 10 seconds.)

If you change the alarm_time.sec + = 2 , you will see that the rtc_interrupt_hdlr fires up every 4 seconds.

Thanks, PM_Dialog

andrewl
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-05 02:45
> So, the rtc_interrupt_hdlr

> So, the rtc_interrupt_hdlr will generate an interrupt when alarm event occurs (every 10 seconds.)

 

Yes, that is true.  But it *also* generates another interrupt 696ms later when it goes to sleep.  Why?

 

I was emitting more than a little pique when I suggested that you find someone with an oscilloscope; however, you're not going to be able to debug this without doing that.

 

This bug causes hiccups if you have something that relies on the handler firing correctly.

 

Thanks.

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi andrewl,

Hi andrewl,

I am working on this, so I'll get back to you.

Thanks, PM_Dialog

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi andrewl,

Hi andrewl,

Sorry for the delay. Unfortunately, I am not able to replicate this. I am toggling the P08 when the configure_rtc_wakeup() is triggered and the P09 when the rtc_interrupt_hdlr() is triggered. Please see the attached screenshot. I probe the P08 and P09 with a logic analyzer.  The rtc_interrupt_hdlr() does not fire again 696ms later.

The device is adverting for 5 seconds and the configure_rtc_wakeup() is executing after 4 seconds.

Could you please share a screenshot from the oscilloscope so that I can understand it better?

Thanks, PM_Dialog

Attachment: 
andrewl
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-05 02:45
Sure.  Give me a couple days.

Sure.  Give me a couple days.  I'm in the process of moving this over to the "simple beacon" codebase which invokes quite a lot less machinery.  This should make it much easier to track down.