Hi Kumar,Thank you for posting your question online.
[email protected] said:I am trying to send my beaconing information on every 1hour one sample I am advertising. Running the timer internally using MCU core, and when time reaches 1 hour then I will enable the RF core beacon activity, advertise the beacon data and disable the RF core and do the process forever without rebooting the device. please suggest the logic. I am trying this logic in DA14531MOD hostless.
Yes, this is possible with the DA14531MOD.You can have the following scenario:You follow the ibeacon example and the ble_app_sleepmode example (inside the SDK6).Note: We also have on Git examples for Eddystone beacon.You can start a timer (i.e. for 5seconds), start advertising, after 5 seconds the timer will expire and we stop advertising.When we stop advertising you can implement either Extended Sleep without advertising or Deep Sleep.In both cases you can have RTC configured in order to set an interrupt after 1 hour. After 1 hour repeat.Please refer on our SDK6 examples and the Tutorials on the DA14531 product page for more information.Best Regards,OV_Renesas
/********************************************************************************************/ void user_app_adv_start(void) { if(bFlag_ble_beacon == false) { app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb); struct gapm_start_advertise_cmd* cmd; cmd = app_easy_gap_undirected_advertise_get_active(); app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure), 1); app_easy_gap_undirected_advertise_start(); } if(bFlag_ble_beacon == true) { ibeacon_adv_payload_t adv_payload; struct gapm_start_advertise_cmd *cmd; cmd = app_easy_gap_non_connectable_advertise_get_active(); adv_payload.flags[0] = FLAG_0; adv_payload.flags[1] = FLAG_1; adv_payload.flags[2] = FLAG_2; adv_payload.length = LENGTH; adv_payload.type = TYPE; adv_payload.company_id[0] = COMPANY_ID_0; adv_payload.company_id[1] = COMPANY_ID_1; adv_payload.beacon_type[0] = BEACON_TYPE_0; adv_payload.beacon_type[1] = BEACON_TYPE_1; uuid2hex((char *)UUID_STR, uuidWr); for(uint8_t i=0;i<16;i++) { adv_payload.uuid[i] = uuidWr[i]; } adv_payload.major[0]= MAJOR & 0x0FF; //high byte adv_payload.major[1]= MAJOR >> 8; //high byte adv_payload.minor[1]= MINOR & 0x0FF; //high byte adv_payload.minor[0]= MINOR >> 8; //high byte adv_payload.measured_power = MEASURED_POWER; memcpy(cmd->info.host.adv_data, &adv_payload, sizeof(ibeacon_adv_payload_t)); cmd->info.host.adv_data_len = sizeof(ibeacon_adv_payload_t); cmd->intv_min = MS_TO_BLESLOTS(bTransmission_Interval); cmd->intv_max = MS_TO_BLESLOTS(bTransmission_Interval); append_device_name(&cmd->info.host.scan_rsp_data_len, name_len, &(cmd->info.host.scan_rsp_data[cmd->info.host.scan_rsp_data_len]), hex_val_t); memcpy(cmd->info.host.adv_data, &adv_payload, sizeof(ibeacon_adv_payload_t)); cmd->info.host.adv_data_len = sizeof(ibeacon_adv_payload_t); app_easy_gap_non_connectable_advertise_start(); arch_set_sleep_mode(ARCH_EXT_SLEEP_ON); } else { } } /********************************************************************************************/ void user_app_adv_start_update_Fields(void) { ibeacon_adv_payload_t adv_payload; struct gapm_start_advertise_cmd *cmd = app_easy_gap_non_connectable_advertise_get_active(); adv_payload.flags[0] = FLAG_0; adv_payload.flags[1] = FLAG_1; adv_payload.flags[2] = FLAG_2; adv_payload.length = LENGTH; adv_payload.type = TYPE; adv_payload.company_id[0] = COMPANY_ID_0; adv_payload.company_id[1] = COMPANY_ID_1; adv_payload.beacon_type[0] = BEACON_TYPE_0; adv_payload.beacon_type[1] = BEACON_TYPE_1; uuid2hex((char *)UUID_STR, uuidWr); for(uint8_t i=0;i<16;i++) { adv_payload.uuid[i] = uuidWr[i]; } adv_payload.major[0]= MAJOR_Value & 0x0FF; //high byte adv_payload.major[1]= MAJOR_Value >> 8; //high byte adv_payload.minor[0]= MINOR_Value & 0x0FF; //high byte adv_payload.minor[1]= MINOR_Value >> 8; //high byte /* Set the advertising interval */ cmd->intv_min = MS_TO_BLESLOTS(2000); cmd->intv_max = MS_TO_BLESLOTS(2000); adv_payload.measured_power = RSSI_1mVal_measurePwr; append_device_name(&cmd->info.host.scan_rsp_data_len, name_len, &(cmd->info.host.scan_rsp_data[cmd->info.host.scan_rsp_data_len]), hex_val_t); memcpy(cmd->info.host.adv_data, &adv_payload, sizeof(ibeacon_adv_payload_t)); cmd->info.host.adv_data_len = sizeof(ibeacon_adv_payload_t); app_easy_gap_update_adv_data(cmd->info.host.adv_data, sizeof(ibeacon_adv_payload_t), cmd->info.host.scan_rsp_data, sizeof(cmd->info.host.scan_rsp_data)); } /********************************************************************************************/ void app_resume_system_from_sleep(void) { #if !defined (__DA14531__) if (GetBits16(SYS_STAT_REG, PER_IS_DOWN)) #endif { periph_init(); } 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(); } } /********************************************************************************************/ static void beacon_adv_data_update_timer_cb() { app_easy_gap_advertise_stop(); battery_percentage = battery_get_lvl(BATT_CR2032); app_resume_system_from_sleep(); user_app_adv_start_update_Fields(); user_app_adv_start(); app_adv_data_update_timer_used = app_easy_timer(((APP_ADV_DATA_UPDATE_TO_BEACON/30)*(30)), beacon_adv_data_update_timer_cb); //30Sec } /********************************************************************************************/ void user_app_disconnect(struct gapc_disconnect_ind const *param) { app_adv_data_update_timer_used = app_easy_timer(((APP_ADV_DATA_UPDATE_TO_BEACON/30)*(30)), beacon_adv_data_update_timer_cb); //30Sec } /********************************************************************************************/ void user_app_adv_undirect_complete(uint8_t status) { if (status == GAP_ERR_CANCELED) { user_app_adv_start(); } } /********************************************************************************************/ void user_app_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param) { if(bFlag_ble_beacon == false) { user_battery_message_handler(1); if (app_env[connection_idx].conidx != GAP_INVALID_CONIDX) { app_connection_idx = connection_idx; app_easy_timer_cancel(app_adv_data_update_timer_used); if ((param->con_interval < user_connection_param_conf.intv_min) || (param->con_interval > user_connection_param_conf.intv_max) || (param->con_latency != user_connection_param_conf.latency) || (param->sup_to != user_connection_param_conf.time_out)) { app_param_update_request_timer_used = app_easy_timer(APP_PARAM_UPDATE_REQUEST_TO, param_update_request_timer_cb); } } else { user_app_adv_start(); } default_app_on_connection(connection_idx, param); } } /****************************************************************************************/ void user_app_disconnect(struct gapc_disconnect_ind const *param) { user_battery_message_handler(0); if (app_param_update_request_timer_used != EASY_TIMER_INVALID_TIMER) { app_easy_timer_cancel(app_param_update_request_timer_used); app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER; } mnf_data_update(); bFlag_ble_beacon = false; First_user_app_disconnect_Flag = false; user_app_adv_start(); if(bFlag_ble_beacon == false) { user_battery_message_handler(0); if (app_param_update_request_timer_used != EASY_TIMER_INVALID_TIMER) { app_easy_timer_cancel(app_param_update_request_timer_used); app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER; } mnf_data_update(); app_adv_data_update_timer_used = app_easy_timer(((APP_ADV_DATA_UPDATE_TO_BEACON/30)*(30)), ibeacon_adv_data_update_timer_cb); user_app_adv_start(); bFlag_ble_beacon = true; bMode = RUNNING_MODE; First_user_app_disconnect_Flag = true; app_easy_gap_advertise_stop(); } #if (BLE_SUOTA_RECEIVER) // Issue a platform reset when it is requested by the suotar procedure if (suota_state.reboot_requested) { // Reboot request will be served suota_state.reboot_requested = 0; // Platform reset platform_reset(RESET_AFTER_SUOTA_UPDATE); } #endif } /****************************************************************************************/ void user_app_init(void) { (void)spi_flash_power_down(); rf_pa_pwr_set(RF_TX_PWR_LVL_0d0); RSSI_1mVal_measurePwr = 0xC5; fnLED_Toggle_Function(6); uuid2hex((char *)UUID_STR, uuidWr); app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER; mnf_data_init(); memcpy(stored_adv_data, USER_ADVERTISE_DATA, USER_ADVERTISE_DATA_LEN); stored_adv_data_len = USER_ADVERTISE_DATA_LEN; memcpy(stored_scan_rsp_data, USER_ADVERTISE_SCAN_RESPONSE_DATA, USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN); stored_scan_rsp_data_len = USER_ADVERTISE_SCAN_RESPONSE_DATA_LEN; default_app_on_init(); } /****************************************************************************************/
/** **************************************************************************************** * * @file user_callback_config.h * * @brief Callback functions configuration file. * * Copyright (C) 2015-2019 Dialog Semiconductor. * This computer program includes Confidential, Proprietary Information * of Dialog Semiconductor. All Rights Reserved. * **************************************************************************************** */ #ifndef _USER_CALLBACK_CONFIG_H_ #define _USER_CALLBACK_CONFIG_H_ /* * INCLUDE FILES **************************************************************************************** */ #include <stdio.h> #include "app_callback.h" #include "app_default_handlers.h" #include "app_entry_point.h" #include "app_prf_types.h" #if (BLE_APP_SEC) #include "app_bond_db.h" #endif // (BLE_APP_SEC) #include "user_peripheral.h" /* * LOCAL VARIABLE DEFINITIONS **************************************************************************************** */ static const struct app_suotar_cb user_app_suotar_cb = { .on_suotar_status_change = on_suotar_status_change, }; static const struct app_callbacks user_app_callbacks = { .app_on_connection = user_app_connection, .app_on_disconnect = user_app_disconnect, .app_on_update_params_rejected = NULL, .app_on_update_params_complete = NULL, .app_on_set_dev_config_complete = default_app_on_set_dev_config_complete, .app_on_adv_nonconn_complete = user_app_adv_undirect_complete,//NULL, .app_on_adv_undirect_complete = user_app_adv_undirect_complete, .app_on_adv_direct_complete = NULL, .app_on_db_init_complete = default_app_on_db_init_complete, .app_on_scanning_completed = NULL, .app_on_adv_report_ind = NULL, .app_on_get_dev_name = default_app_on_get_dev_name, .app_on_get_dev_appearance = default_app_on_get_dev_appearance, .app_on_get_dev_slv_pref_params = default_app_on_get_dev_slv_pref_params, .app_on_set_dev_info = default_app_on_set_dev_info, .app_on_data_length_change = NULL, .app_on_update_params_request = default_app_update_params_request, .app_on_generate_static_random_addr = default_app_generate_static_random_addr, .app_on_svc_changed_cfg_ind = NULL, .app_on_get_peer_features = NULL, #if (BLE_APP_SEC) .app_on_pairing_request = default_app_on_pairing_request, .app_on_tk_exch = user_app_on_tk_exch, .app_on_irk_exch = NULL, .app_on_csrk_exch = default_app_on_csrk_exch, .app_on_ltk_exch = default_app_on_ltk_exch, .app_on_pairing_succeeded = default_app_on_pairing_succeeded, .app_on_encrypt_ind = NULL, .app_on_encrypt_req_ind = default_app_on_encrypt_req_ind, .app_on_security_req_ind = NULL, .app_on_addr_solved_ind = default_app_on_addr_solved_ind, .app_on_addr_resolve_failed = default_app_on_addr_resolve_failed, .app_on_ral_cmp_evt = default_app_on_ral_cmp_evt, .app_on_ral_size_ind = NULL, .app_on_ral_addr_ind = NULL, #endif // (BLE_APP_SEC) }; #if (BLE_APP_SEC) static const struct app_bond_db_callbacks user_app_bond_db_callbacks = { .app_bdb_init = default_app_bdb_init, .app_bdb_get_size = default_app_bdb_get_size, .app_bdb_add_entry = default_app_bdb_add_entry, .app_bdb_remove_entry = NULL, .app_bdb_search_entry = default_app_bdb_search_entry, .app_bdb_get_number_of_stored_irks = default_app_bdb_get_number_of_stored_irks, .app_bdb_get_stored_irks = default_app_bdb_get_stored_irks, .app_bdb_get_device_info_from_slot = default_app_bdb_get_device_info_from_slot, }; #endif // (BLE_APP_SEC) /* * "app_process_catch_rest_cb" symbol handling: * - Use #define if "user_catch_rest_hndl" is defined by the user * - Use const declaration if "user_catch_rest_hndl" is NULL */ #define app_process_catch_rest_cb user_catch_rest_hndl // static const catch_rest_event_func_t app_process_catch_rest_cb = NULL; static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = { .app_on_init = user_app_init, // By default the watchdog timer is reloaded and resumed when the system wakes up. // The user has to take into account the watchdog timer handling (keep it running, // freeze it, reload it, resume it, etc), when the app_on_ble_powered() is being // called and may potentially affect the main loop. .app_on_ble_powered = NULL, // By default the watchdog timer is reloaded and resumed when the system wakes up. // The user has to take into account the watchdog timer handling (keep it running, // freeze it, reload it, resume it, etc), when the app_on_system_powered() is being // called and may potentially affect the main loop. .app_on_system_powered = NULL, .app_before_sleep = NULL, .app_validate_sleep = NULL, .app_going_to_sleep = NULL, .app_resume_from_sleep = NULL, }; // Default Handler Operations static const struct default_app_operations user_default_app_operations = { .default_operation_adv = user_app_adv_start, }; // Place in this structure the app_<profile>_db_create and app_<profile>_enable functions // for SIG profiles that do not have this function already implemented in the SDK // or if you want to override the functionality. Check the prf_func array in the SDK // for your reference of which profiles are supported. static const struct prf_func_callbacks user_prf_funcs[] = { {TASK_ID_INVALID, NULL, NULL} // DO NOT MOVE. Must always be last }; #endif // _USER_CALLBACK_CONFIG_H_
Hi Kumar,Thank you for the reply and the clarifications.When you have enabled Extended Sleep mode, the Watchdog timer is being handled automatically.When you have disabled Extended Sleep mode and there is no Advertising/Scanning (general activity of the BLE core) you will have to handle the Watchdog manually.You can use the following APIs:
/** **************************************************************************************** * @brief Watchdog resume. * About: Start the Watchdog **************************************************************************************** */ __STATIC_INLINE void wdg_resume(void) { #if (USE_WDOG) // Start WDOG SetWord16(RESET_FREEZE_REG, FRZ_WDOG); #endif } /** **************************************************************************************** * @brief Freeze Watchdog. Call wdg_resume() to resume operation. * About: Freeze the Watchdog **************************************************************************************** */ __STATIC_INLINE void wdg_freeze(void) { // Freeze WDOG SetWord16(SET_FREEZE_REG, FRZ_WDOG); } /** **************************************************************************************** * @brief Watchdog reload. * @param[in] period measured in 10.24ms units. * About: Load the default value and resume the watchdog **************************************************************************************** */ __STATIC_INLINE void wdg_reload(const int period) { #if (USE_WDOG) // WATCHDOG_DEFAULT_PERIOD * 10.24ms SetWord16(WATCHDOG_REG, WATCHDOG_DEFAULT_PERIOD); #endif }
Hi Kumar,Thank you for the reply.
[email protected] said:After you suggested again, I changed the heap size ---> #define DB_HEAP_SZ 4096. Then After 30 minutes the device rebooted. I mean crashed after 30 min
This means that the device was actually crashing due to heap exhaustion.Somewhere in side your code workflow there should be an issue that prevents the scheduler from freeing this memory space.
[email protected] said:You mean to say to call the WATCHDOG ? Where should I call these APIs? please suggest it to me.
What I mean by handling WatchDog:1) Include the arch_wdg.h file in your project2) When you disable Extended Sleep mode, then use the wdg_freeze API, and before you re-enable the Extended Sleep mode, then use the wdg_resume API.I still need to understand if you are utilizing Extended or Deep Sleep mode.If you could share the whole project in a zip file it would be easier for us to go through it and try to debug it on our side.Best Regards,OV_Renesas
Hi Renesas,
Hi Kumar,Thank you for providing the project.I am not able to recreate the issue on my side. I have left the project running for over 30 minutes on the Dev Kit Pro and I have connected multiple times via the SmartBond mobile application.After disconnect the device does not go into any Sleep mode or non-connectable advertising.Could you please share a high level explanation of how this project should work?i.e. 1) Advertise with Extended Sleep mode2) Connect3) Pair with LE Secure Connections4) Disconnect5) Start advertising with non-connectable mode and Extended Sleep6)etc.Best Regards,OV_Renesas
Can you share your device BT MAC address for sharing the pass key to access the device.
Regards,
Kumar
Hi Kumar,
[email protected] said:Can you share your device BT MAC address for sharing the pass key to access the device.
BR,OV_Renesas
Your MAC passkey displayed over the console. First you connect Bonding with this passkey enter.
Then you read the service Like major or minor etec and disconnect, then it will broadcast the ibeacon for every 30sec interval it is forever. I tried the last heap change but it crashed after 30 minutes.
Step1# Scan and connect with passkey (Bonding, If already bonding delete and again Bond it). Note: try to input within 10 secs.
Step2# Read the services
MAJOR {0x9e, 0x9c, 0xdf, 0x4f, 0xe0, 0xf3, 0x3e, 0x99, 0x6f, 0x46, 0x5a, 0xbf, 0x81, 0x5a, 0x00, 0x10}
MINOR {0x9a, 0x8c, 0xdf, 0x4f, 0xe0, 0xf3, 0x3e, 0x99, 0x6f, 0x46, 0x5a, 0xbf, 0x81, 0x5a, 0x00, 0x10}
Step3# Disconnect and go to non-connectable mode.
Step4# After 30 secs check the iBeacon data displaying.
Step5# After advertising over goes to Extended Sleep and again wakeup
[email protected] said: Step3# Disconnect and go to non-connectable mode.
I am not able to see the exact behavior you described. Specifically, the firmware you sent does not go into non-connectable mode after disconnect on my side. Best Regards,OV_Renesas
I tried with the same Firmware shared which is working for me. Find the snapshot for your reference. Download from the below link:
https://we.tl/t-oY90HIeNCH
Step#1 -> Click nRF Connect android app à Enable Bluetooth -à Enable Location
Step#2 -> Scan and check the device shows like BlackBox -- > Before connecting check Bonded or Not. If already bonded please click ---> “Delete bond information” (click this option at right connect 3 dots). Once it delete it shows NOT BONDED
Step#3 -> Now click on ---> Connect ----> try to read last service /characteristic (xxxx000002a19) click ---> it will ask Bluetooth pairing request ----> Enter the your password PIN as :: 177408 ---> If it PIN correct it read the characteristics values >>> NOTE >>> If you are not entering within 15 sec PIN then it will repeat the Step#3 until it success.
Step#4 -> Now click on ---> DISCONNECT ----> Close the MAC tab ----> click / go to SCANNER ---> Refresh ---> You will see Black Box (Non-connectable) ---> It shows BLE information ----> Ery 30sec iBeacon advertisement displayed.
And the below serial print logs can be seen.
----------------------------------------------------------------------------------------------------------------------------------
637440
=> ..user_app_adv_start (FIRST).. <=
=> user_app_disconnect <=
......default_app_on_pairing_succeeded............
=> ..user_app_adv_start (SECOND).. <=(((.....user_app_adv_undirect_complete.....)))
=> ..ibeacon_adv_data_update_timer_cb (FIRST).. <=
=> ..acc_app_resume_system_from_sleep (1).. <=
=> ..user_app_adv_start_new (THREE).. <=
=> ..user_app_adv_start (SECOND).. <=
Please check the same process and let us know. Please check with other Android app nRF Connect.
Thanks,
Francis