This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to execute a routine after successful connection to peripherial?

Hello, I am using ble_app_multilink_central example as a foundation of my app involving central - peripherial connection (S120 - S110). My app works nicely but i have problem accomplishing one thing - i need to synchronize some data between central and peripherial just after successful connection is established between them. Synchronizing routine should read certain characteristic on connected peripherial, and then conditionally write some other characteristic depending on readed value. I tried experimentally to attach this routine to the end of db_discovery_event_handler when all of peripherial characteristics are already discovered, but i get NRF_ERROR_BUSY (?) from sd_ble_gattc_write executed in my sync routine ( this works ok when executed later from main() ). So the question is: to which BLE event could i attach my sync routine to execute it when central - peripherial connection is fully established and ready to begin reading/writing characteristics between central and peripherial?

Parents
  • Woytekm,

    You cannot call the sd_ble_gattc_write function from an interrupt context above NRF_APP_PRIORITY_LOW (or APP_IRQ_PRIORITY_LOW, as defined in util_platform instead of nrf_soc). The event callbacks from the BLE stack are running at either softdevice priority low or softdevice priority high depending on the callback, which are both above NRF_APP_PRIORITY_LOW. Therefore the stack reports it's too busy at the current time to handle pushing new data on the output buffer. I forget exactly where this is documented, so if someone could provide a link as a comment to this answer I'd appreciate it.

    Probably your best option is to create a volatile flag that you set at the end of db_discovery_event_handler to trigger the synchronization process from the main context, and implement a state machine of some kind to hold off any other kind of data transfer until the sync process is complete. You'll have several milliseconds to get each command/read on the output buffer before the next connection interval from main (exact time depending on connection interval and length of time taken to execute any BLE event callbacks), so as long as your central device isn't doing much else at the time the system should work fine using this solution.

Reply
  • Woytekm,

    You cannot call the sd_ble_gattc_write function from an interrupt context above NRF_APP_PRIORITY_LOW (or APP_IRQ_PRIORITY_LOW, as defined in util_platform instead of nrf_soc). The event callbacks from the BLE stack are running at either softdevice priority low or softdevice priority high depending on the callback, which are both above NRF_APP_PRIORITY_LOW. Therefore the stack reports it's too busy at the current time to handle pushing new data on the output buffer. I forget exactly where this is documented, so if someone could provide a link as a comment to this answer I'd appreciate it.

    Probably your best option is to create a volatile flag that you set at the end of db_discovery_event_handler to trigger the synchronization process from the main context, and implement a state machine of some kind to hold off any other kind of data transfer until the sync process is complete. You'll have several milliseconds to get each command/read on the output buffer before the next connection interval from main (exact time depending on connection interval and length of time taken to execute any BLE event callbacks), so as long as your central device isn't doing much else at the time the system should work fine using this solution.

Children
Related