Update advertising address and data on the fly

8 posts / 0 new
Last post
Peter Luo
Offline
Last seen: 2 days 5 hours ago
Joined: 2016-01-17 13:37
Update advertising address and data on the fly

Hi Dialog,

We need update advertising address and data on the fly in main loop.
Attached arch_main.c can work except for the sometimes inconsistency of address and data.
For example, according to application logic, if we update in this way:
ADDR DATA
xx:xx:xx:xx:xx:00 Info00
xx:xx:xx:xx:xx:01 Info01

we should get following:
ADDR DATA
xx:xx:xx:xx:xx:00 Info00
xx:xx:xx:xx:xx:01 Info01

In fact, we sometimes get following unexpected result:
ADDR DATA
xx:xx:xx:xx:xx:01 Info00

We think, the advertising address update (through writing register BLE_BDADDRL_REG and BLE_BDADDRU_REG) can complete immediately,
the advertising data update (through GAPM_UPDATE_ADVERTISE_DATA message) is delayed or not synchronized with the advertising procedure.

Although the example ble_app_noncon in SDK 6 can implement our function without inconsistency, the cost seems high, we want to update anything in main loop to reduce current consumption.

So, is there any other way to update safely?

Thanks in advance!

Best Regards,
Peter

----------------------------------- arch_main.c ---------------------------------------------
...
uint8_t fly_update_count __attribute__((section("retention_mem_area0"), zero_init));

extern void adv_addr_update(void); /* Update advertising device address */
extern void adv_data_update(void); /* Update advertising data */
....

int main(void)
{
sleep_mode_t sleep_mode;

// initialize retention mode
init_retention_mode();

//global initialise
system_init();

/*
************************************************************************************
* Platform initialization
************************************************************************************
*/

while(1)
{
do {
// schedule all pending events
schedule_while_ble_on();
}
while (app_asynch_proc() != GOTO_SLEEP); //grant control to the application, try to go to power down
//if the application returns GOTO_SLEEP

// Update in here !!!
fly_update_count++;
if ((fly_update_count%50) == 0)
{
adv_addr_update();
adv_data_update();
}

...

//wait for interrupt and go to sleep if this is allowed
if (((!BLE_APP_PRESENT) && (check_gtl_state())) || (BLE_APP_PRESENT))
{
//Disable the interrupts
GLOBAL_INT_STOP();

app_asynch_sleep_proc();

// get the allowed sleep mode
// time from rwip_power_down() to WFI() must be kept as short as possible!!
sleep_mode = rwip_power_down();

if ((sleep_mode == mode_ext_sleep) || (sleep_mode == mode_ext_sleep_otp_copy))
{
//power down the radio and whatever is allowed
arch_goto_sleep(sleep_mode);

// In extended sleep mode the watchdog timer is disabled
// (power domain PD_SYS is automatically OFF). Although, if the debugger
// is attached the watchdog timer remains enabled and must be explicitly
// disabled.
if ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)
{
wdg_freeze(); // Stop watchdog timer
}

//wait for an interrupt to resume operation
WFI();

//resume operation
arch_resume_from_sleep();
}
else if (sleep_mode == mode_idle)
{
if (((!BLE_APP_PRESENT) && check_gtl_state()) || (BLE_APP_PRESENT))
{
//wait for an interrupt to resume operation
WFI();
}
}
// restore interrupts
GLOBAL_INT_START();
}
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
}
}

Keywords: 
Device: 
MT_dialog
Offline
Last seen: 3 days 16 hours ago
Staff
Joined: 2015-06-08 11:34
Hi Peter Luo,

Hi Peter Luo,

I am not sure about what is exactly is your request, regarding the advertising data update, as far as i can understand your problem is that the ble_app_nonconn project doesn't suit you because of the timer waking up, so you would like to reduce that extra waking up from the timer and send the command in order to update the advertising data while you are in the main loop. What you can try in order not to mess with the SDK is to place the advertising update command in the .app_on_ble_powered callback and then when issuing that command towards the stack you can force the BLE to stay on for a bit longer in order to make sure that the command that you ve placed to be scheduled by returning KEEP_POWERED, after the command has been scheduled then you can return GOTO_SLEEP from the app_on_ble_powered.

Regarding changing the bd address, it is not suggested to change the bd address of the device by directly writing in the 585's registers especially when the device advertises, you should let the stack handle any change, also it is not suggested to change the bd address of the device while advertising, so you will have to stop the advertising procedure change the db address and then advertise with the new bd address. In general the BLE specification regarding the fixed BLE addresses (public or static) defines that an address when static can change after eash power cycle, an address can either be fixed during the product's lifetime (public) or change during reboot, so in order to change the bd address without dealing with those kind of issues you should reset the stack and let the app_easy_gap_dev_configure() change the bd address of your device, use the app_easy_gap_dev_config_get_active() in order to get a ready message, change the bd address and change the address.

Thanks MT_dialog

Peter Luo
Offline
Last seen: 2 days 5 hours ago
Joined: 2016-01-17 13:37
Hi Dialog,

Hi Dialog,

Thank you so much for your so useful information!

BR/Peter

RAGHU.SBD
Offline
Last seen: 2 days 14 hours ago
Joined: 2019-01-16 20:50
Hi Dialog,

Hi Dialog,
I am trying to change the BD address on the fly as you have mentioned above. After boot up, I run a timer and in that I want to keep changing BD address to different values. I send a RESET to the stack and I do land at the app_easy_dev_configure() breakpoint. But how do I use the app_easy_gap_dev_config_get_active() to change BD address. Appreciate your help. Thanks.

PM_Dialog
Offline
Last seen: 20 hours 4 min ago
Staff
Joined: 2018-02-08 11:03
Hi RAGHU.SBD,

Hi RAGHU.SBD,

When then app_easy_gap_dev_configure() is triggered, you should modify it a little bit more like follow:

void app_easy_gap_dev_configure(void)

{

uint8_t bd[6] = {0xC2,0x2A,0x35,0xD7,0x7B,0xD3};

struct gapm_set_dev_config_cmd* cmd = app_easy_gap_dev_config_create_msg();

if (bd_flag) { memcpy(cmd->addr.addr, bd, 6); }

app_gapm_configure_msg_send(cmd);

set_dev_config_cmd = NULL;

}

Thanks, PM_Dialog

RAGHU.SBD
Offline
Last seen: 2 days 14 hours ago
Joined: 2019-01-16 20:50
Hi PM_Dialog

Hi PM_Dialog
Thank you for the reply. I have exactly done that.
I am trying to switch my BD address every 30 seconds using this technique by using the Timer.
After every reset, the device address is changed and in the user_app_adv_start() function, I restart my 30 seconds timer.
But seems like the timer runs only for couple of iterations...

Does resetting BLE stack has any limitations on how many times, we can do it.

Thanks.

PM_Dialog
Offline
Last seen: 20 hours 4 min ago
Staff
Joined: 2018-02-08 11:03
Hi RAGHU.SBD,

Hi RAGHU.SBD,

No, there isn’t any limitation om how many times the timer runs. How many times the timer runs? And when it is stopped running, do you get any assertion or a hardfault? Could you please run it in debug mode?

Thanks, PM_Dialog

RAGHU.SBD
Offline
Last seen: 2 days 14 hours ago
Joined: 2019-01-16 20:50
Hi PM_Dialog,

Hi PM_Dialog,

Thanks for the reply.
I don't get any assertions. I am running in debug mode. It seems to be a MULTIPLE timer issue, as many people have complained in other posts.
The moment I stop the second timer and run only this main timer, everything seems to work fine without any issue.

Any examples of multiple times ?

Thanks