How does the advertise with timeout function work?
static const struct default_handlers_configuration user_default_hnd_conf = { // Configure the advertise operation used by the default handlers // Possible values: // - DEF_ADV_FOREVER // - DEF_ADV_WITH_TIMEOUT .adv_scenario = DEF_ADV_WITH_TIMEOUT,
// Configure the advertise period in case of DEF_ADV_WITH_TIMEOUT. // It is measured in timer units (3 min). Use MS_TO_TIMERUNITS macro to convert // from milliseconds (ms) to timer units. .advertise_period = MS_TO_TIMERUNITS(5000),
I have defined the above configuration. Advertisement timeout shall happen after 5 seconds.
After the timeout, which callback shall get called?
I want to advertise for 5 seconds then have a timeout and go to deep sleep mode. Then upon pressing a GPIO, my dialog will wake up and restart advertising. How shall I do?
Which callback/function shall I put the button wakeup press function so that when I press SW2 in dialog board, my system wakes up?
When will the below callback function be called?
Hi Satakshi,Thank you for posting your question online.You can either use the DEF_ADV_WITH_TIMEOUT option as your adv_scenario or you can implement it with a timer yourself, please refer on this ticket: Advertising with timeout in loop - Bluetooth Low Energy - Wireless Connectivity - Renesas Engineering Community
Satakshi_R said:I have defined the above configuration. Advertisement timeout shall happen after 5 seconds. After the timeout, which callback shall get called?
When you have set the DEF_ADV_WITH_TIMEOUT as your adv_scenario, the default advertise operation is going to call the app_easy_gap_undirected_advertise_with_timeout_start API:void default_advertise_operation(void) { if (user_default_hnd_conf.adv_scenario == DEF_ADV_FOREVER) { app_easy_gap_undirected_advertise_start(); } else if (user_default_hnd_conf.adv_scenario == DEF_ADV_WITH_TIMEOUT) { app_easy_gap_undirected_advertise_with_timeout_start(user_default_hnd_conf.advertise_period, adv_timeout_callback); //static void (*adv_timeout_callback)(void) } } /** **************************************************************************************** * @brief Start advertising for undirected connection with timeout start. * @param[in] delay Delay of the timer * @param[in] timeout_callback Timeout callback function **************************************************************************************** */ void app_easy_gap_undirected_advertise_with_timeout_start(uint32_t delay, void (*timeout_callback)(void)); /** **************************************************************************************** * @brief Stop advertising with timeout stop. **************************************************************************************** */ void app_easy_gap_advertise_with_timeout_stop(void);After the period of advertising you had set has passed, then the app_easy_gap_advertise_stop_handler will be executed to terminate the advertising. After that one of the callback functions for advertising is going to be executed:
void default_advertise_operation(void) { if (user_default_hnd_conf.adv_scenario == DEF_ADV_FOREVER) { app_easy_gap_undirected_advertise_start(); } else if (user_default_hnd_conf.adv_scenario == DEF_ADV_WITH_TIMEOUT) { app_easy_gap_undirected_advertise_with_timeout_start(user_default_hnd_conf.advertise_period, adv_timeout_callback); //static void (*adv_timeout_callback)(void) } } /** **************************************************************************************** * @brief Start advertising for undirected connection with timeout start. * @param[in] delay Delay of the timer * @param[in] timeout_callback Timeout callback function **************************************************************************************** */ void app_easy_gap_undirected_advertise_with_timeout_start(uint32_t delay, void (*timeout_callback)(void)); /** **************************************************************************************** * @brief Stop advertising with timeout stop. **************************************************************************************** */ void app_easy_gap_advertise_with_timeout_stop(void);
.app_on_adv_nonconn_complete = NULL, .app_on_adv_undirect_complete = NULL, .app_on_adv_direct_complete = NULL,
Thanks a lot for the reply.
As per the ticket shared by you, I defined my own timer and after 10 seconds, I called the following callback function:
void stop_adv_cb(void) { arch_printf("stop function called"); //Check if Timer for Advertising is unitiliazed and initialize him again if( app_adv_timeout_timer_used != EASY_TIMER_INVALID_TIMER) { app_adv_timeout_timer_used = EASY_TIMER_INVALID_TIMER; } //app_easy_gap_advertise_stop(); #if defined (CFG_EXT_SLEEP_WAKEUP_RTC) || defined (CFG_EXT_SLEEP_WAKEUP_TIMER1) || \ defined (CFG_DEEP_SLEEP_WAKEUP_RTC) || defined (CFG_DEEP_SLEEP_WAKEUP_TIMER1) // Ensure PD_TIM is open SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0); // Wait until PD_TIM is opened while ((GetWord16(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP); #else // Close PD_TIM SetBits16(PMU_CTRL_REG, TIM_SLEEP, 1); // Wait until PD_TIM is closed while ((GetWord16(SYS_STAT_REG) & TIM_IS_DOWN) != TIM_IS_DOWN); #endif spi_flash_power_down(); put_system_into_deep_sleep(); }
After the timeout, I am making the system go to deep sleep mode.
From this, I want GPIO wakeup of the dialog board and upon wake up, it shall resume the advertisement. For that I have defined the folllwoing functions and I am using SW2 for wakeup.
static void app_wakeup_cb(void) { // If state is not idle, ignore the message if (ke_state_get(TASK_APP) == APP_CONNECTABLE) { //default_advertise_operation(); user_app_adv_start(); } } static void app_resume_system_from_sleep(void) { #if !defined (__DA14531__) if (GetBits16(SYS_STAT_REG, PER_IS_DOWN)) { periph_init(); } #endif if (arch_ble_ext_wakeup_get()) { arch_set_sleep_mode(app_default_sleep_mode); arch_ble_force_wakeup(); arch_ble_ext_wakeup_off(); app_easy_wakeup(); } default_advertise_operation(); } static void app_button_press_cb(void) { app_resume_system_from_sleep(); app_button_enable(); } void app_button_enable(void) { app_easy_wakeup_set(app_wakeup_cb); wkupct_register_callback(app_button_press_cb); if (GPIO_GetPinStatus(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)) { wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // select pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN) WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low 1, // 1 event 0); // debouncing time = 0 } } void user_app_adv_undirect_complete(uint8_t status) { // If advertising was canceled then update advertising data and start advertising again if (status == GAP_ERR_CANCELED) { arch_ble_ext_wakeup_on(); // Configure wakeup button app_button_enable(); // app_adv_timeout_timer_used = app_easy_timer(START_ADV_IN_SEC, user_app_adv_start); } }
Is this correct, because my system is entering sleep mode after 10 seconds but when I press SW2, it is not waking up as I am not able to scan the device again. What could be the issue for the same?
In the function void_stop_adv_cb() I have made the system go into sleep mode. You are suggesting to put the sleep mode function inside the user_app_undirect_complete() function??
Also I have defined app_resume_system_from_sleep(). Whether that is required for deep sleep or not required ? Is there anything else required for deep sleep?
I have called the app_button_enable() inside usee_app_undirect_complete(). Is that correct? Where exactly do I have to call the app_button_enable callback? I am a bit confused and what are the exact configuration needed for waking up from deep sleep. Can u please help me?
Hi Satakshi,Thank you for the reply.Please find attached the ble_app_peripheral_adv_timeout_deep_sleep.zip file. I worked on SDK v6.0.18 with Dev Kit Pro and the DA14531MOD DB. I worked on a ble_app_peripheral example and I copied the Deep Sleep configuration from the prox_reporter example.After 5 seconds, the Advertising Stops and the DA14531 goes into Deep Sleep, then I press SW2 (P0_11) and I wake up the device, it automatically starts advertising for another 5 seconds and goes to Deep Sleep again. Please see the screenshots captured from the Power Profiler:It works on my side as expected. Please share any feedback. ble_app_peripheral_adv_timeout_deep_sleep.zipBest Regards,OV_Renesas
Thanks a lot for sharing the answer. I have updated my code as per your instructions. And now I am getting something as below.
After 10 seconds, dialog is going to sleep. Then when I press SW2 again I am getting the graph as shown above. Is 10 seconds a very short time because I am not able to scan it in the nrf connect in my mobile phone.
After 10 seconds if I press SW2 again, it is advertising but why am I not able to scan it in my mobile phone?
Also one more thing, if I am advertising continuously without any sleep mode implementation, then why is the average current constantly reducing?
Before:
After:
You can see in the before and after images, that average current value has decreased.
Hi Satakshi,Thank you for the reply.The Screenshot you shared shows that it took the DA14531 187ms to download the source code into SRAM. With the project I shared I was able to see a similar time between the Wake up controller interrupt and the DA14531 going back into Extended Sleep.
Satakshi_R said:After 10 seconds if I press SW2 again, it is advertising but why am I not able to scan it in my mobile phone?
I am only advertising for 5 seconds, and I am able to see my DA14531 advertising with the SmartBond App.Could you please test the project I shared on my previous answer?
Satakshi_R said:Also one more thing, if I am advertising continuously without any sleep mode implementation, then why is the average current constantly reducing?
If you want to measure the current measurement, you should enable the Power Profiler (Initialize-Start) after the FW has been downloaded into the DA14531. Ideally you should let the DA14531 for 2-10minutes running on the Power Profiler in order to see the Average Current Measurements. Best Regards,OV_Renesas
Apart from using the power profiler, I am trying to measure the average current with multimeter. I programmed and burned the code in OTP from smart snippets toolbox. After that, I removed the J9 jumper but when I am trying to calculate the value, multimeter shows 0. What could be the issue?
Hi Satakshi,Thank you for the reply.Is your Multimeter capable of measuring uA? You should be able to see the current measurement from the J9 Jumpers.Best Regards,OV_Renesas
Yes the multimeter is capable of measuring uA also. When I remove the shorted J9 jumper, the blue LED goes off in the dev kit pro. After that, I start measuring it but it shows 0 in mA mode also and uA mode also. Is there any additional step I should do in smart snippets toolbox ?
I forgot to change the macros like below:
#undef CFG_CODE_LOCATION_EXT #define CFG_CODE_LOCATION_OTP
#undef CFG_DEVELOPMENT_DEBUGAnd I burned the OTP image and header. After that my board is not getting detected. Did the wrong flashingdcaused some issue to the board?
Hi Satakshi,Thank you for the reply.
Satakshi_R said: When I remove the shorted J9 jumper, the blue LED goes off in the dev kit pro. After that, I start measuring it but it shows 0 in mA mode also and uA mode also. Is there any additional step I should do in smart snippets toolbox ?
Yes, the blue LED shows that the current circuit is active for the SmartSnippets Toolbox. No you would not need any other steps on the SmartSnippets Toolbox to measure the current consumption.Regarding the OTP:Are you able to see your device advertising or scanning?Please refer on the AN-B-072, on section 10. Boot from OTP, on page:22 and on section 4.Booting Sequence and Booting PinsBest Regards,OV_Renesas
Thanks a lot for the reply sir
One query if the steps are not properly followed or if I miss one step and burn the code in OTP wrongly will it damage the daughterboard?
Hi Satakshi,Thank you for the reply. It will not damage the daughterboard, but you will not be able to burn another firmware onto the OTP. If you burn any FW into the SPI Flash, does the DA14531 start advertising/scanning or is it stuck? Which steps exactly did you miss for the OTP programming?Best Regards,OV_Renesas
I forgot these steps in the software
#undef CFG_DEVELOPMENT_DEBUGI need to check with the SPI flash programmer also.After burning the FW in OTP, I am not able to do debugging in keil. AFter compilation of code,if I try to enter into debug mode, it shows the following:
Hi Satakshi,Thank you for the reply.For some reason the J-Link is not able to recognize the SWD interface on the board.On the fw you burned on the OTP did you implement any sleep mode? In sleep the DA14531 has the debugger disabled. If the DA14531 crashes during sleep or cannot wake-up you will not be able to access it via SWD, you will need to do 1-Wire UART in order to access the DA14531.Another reason could be that you are handling the SWD interface pins inside your code, and the J-link cannot access them. Best Regards,OV_Renesas
Hello sir,
I have implemented sleep mode in the code I burned in OTP.
I am using SW2 as the wakeup controller inside code. I think the board is not able to wake up once it has gone to sleep because I had faced similar issues previously that after sleeping I was not able to wake it up.
Hi Satakshi,Thank you for the reply.That would make sense. The DA14531 has gone into sleep mode. You press the SW2 to wake-it up, it searched to find where the firmware is stored to restore the application but due to the fact that you did not implement the OTP programming the correct way, the DA14531 is not being to find the source code so it is stuck. I would suggest to try to 1-Wire UART programming to access the SPI Flash (via the SmartSnippets Toolbox) and you could possibly use this board for testing.Best Regards,OV_Renesas