Hi,
This is a followup on https://devzone.nordicsemi.com/f/nordic-q-a/119259/synchronisation-between-tx-and-rx-in-connectionless-direction-finding
We now have a synchronised counter being increment on TX and received at RX, which was the key issue in that post. Now, for additional accuracy in timing, we want to toggle a GPIO pin whenever a given packet with CTE is sent.
In the current setup, I set up the advertisement configuration as follows
static struct bt_le_adv_param param = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_USE_IDENTITY, BT_GAP_ADV_FAST_INT_MIN_1, BT_GAP_ADV_FAST_INT_MAX_1, NULL); static struct bt_le_ext_adv_start_param ext_adv_start_param = { .timeout = 0, .num_events = 1, }; static struct bt_le_per_adv_param per_adv_param = { .interval_min = BT_GAP_PER_ADV_FAST_INT_MIN_1, .interval_max = BT_GAP_PER_ADV_FAST_INT_MAX_1, .options = BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_NO_2M | BT_LE_ADV_OPT_USE_TX_POWER, };
and set up the `adv_sent_cb` as
static void adv_sent_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_sent_info *info) { int err; memcpy(&adv_data[8], &data_counter, sizeof(uint16_t)); LOG_INF("Set Periodic Advertising Data to %d", data_counter); err = bt_le_per_adv_set_data(adv_set, ad, ARRAY_SIZE(ad)); if (err) { LOG_ERR("Failed (err %d)\n", err); } serialise_counter(&protocol_data, data_counter); ble_protocol_data_send_and_clear_buffer(&protocol_data); // Guard against overflow if (data_counter < 65535) { data_counter++; } else { data_counter = 0; } LOG_INF("Extended advertising enable..."); err = bt_le_ext_adv_start(adv_set, &ext_adv_start_param); if (err) { LOG_ERR("failed (err %d)\n", err); return; } LOG_INF("success\n"); }
This works and I am able to receive CTEs at the RX end.
However, with respect to the GPIO toggling, when I set up the following with the intention of toggling the GPIO whenever the payload has been sent with the updated counter value
void ppi_init(void) { NRF_PPI->CH[1].EEP = (uint32_t)&NRF_RADIO->EVENTS_PAYLOAD; NRF_PPI->CH[1].TEP = (uint32_t)&NRF_EGU0->TASKS_TRIGGER[0]; NRF_PPI->CHENSET = PPI_CHENSET_CH1_Set << PPI_CHENSET_CH1_Pos; } void egu_init(void) { // Enable EGU interrupt NRF_EGU0->INTENSET = EGU_INTEN_TRIGGERED0_Msk; NVIC_SetPriority(SWI0_EGU0_IRQn, 6); NVIC_EnableIRQ(SWI0_EGU0_IRQn); } void SWI0_EGU0_IRQHandler(void) { if (NRF_EGU0->EVENTS_TRIGGERED[0]) { NRF_EGU0->EVENTS_TRIGGERED[0] = 0; LOG_DBG("Setting last sent data counter to %d (prev. value = %d)", data_counter, data_counter_last_sent); } }
I get the following output, with the trigger happening five times per extended advertisement packet
but I was only expecting one. My suspicion that it may be related to the fact that periodic advertisement is enabled, but I am not entirely sure, and as far as I can tell, that needs to be active for the periodic sync which receives CTEs on the RX side to function as intended.
Hopefully I've provided sufficient information, please let me know if I need to add additional details!
Kind regards
Glen