Behaviour of PPI endpoint when using extended/periodic advertisement with CTE for direction finding

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

Parents
  • Glen,

    I am temporarily trying help out this this thread due to the debugging nature of it.

    If I read the issue correctly there seems to be two issues here.

    First being the multi trigger of the IRQ triggered by PPI events.

    I believe that EVENTS_PAYLOAD might not the right choice here. 

    Extended advertising works like below, let me see if I can get the alignment right

    ADV_EXT_IND   (primary)       ─┬─> [EVENTS_PAYLOAD]
                                   │
    AUX_ADV_IND   (auxiliary)     ─┬─> [EVENTS_PAYLOAD]
                                   │
    AUX_SYNC_IND  (periodic)      ─┬─> [EVENTS_PAYLOAD]
                                   │
    CTE                             ─┬─> [EVENTS_PAYLOAD] (optional, depending on setup)
    

    Each stage may cause EVENTS_PAYLOAD. 

    It is better to chose EVENTS_END but this will happen at the end of the packet which should not be an issue based on the description you gave so far.

    Second issue, The hardfault is clearly from overuse of allocated stack. It looks like it is the main thread from the logs that overused its stack. Increase the CONFIG_MAIN_STACK_SIZE in your prj.conf. Sometime it might happen that the neighboring thread can corrupt the stack of the other thread. To get a hint of this, it is best to enable CONFIG_THREAD_ANALYZER to get regular updates on the stack use of every thread in your system.

  • Hello Susheel,

    Thanks for your reply. To quickly address the suggestion for the second issue, setting the stack size to 4096 did fix the debugging issue I was seeing. Couldn't connect to RTT when I was debugging, but I could see from the RX side that it was receiving CTEs as expected. I was then able to verify that main only runs once and the IRQ_CONNECT call only gets called once.

    For the main issue, by setting the trigger to EVENT_END, I am still seeing multiple triggers

    So four triggers in the TXIdle state and one in the TX state. Whereas when I use EVENT_PAYLOAD, I see the following

    Five triggers in the TX state, which is one more than the setup you're outlining. Could this be related to the periodic advertising used? 

    Related, if the number of payloads is fixed (I am sending the same type of payload continuously), could I then just check that we have reached the correct number (in your setup example, since I am sending CTEs, 4 payloads, and then proceed as if things had been successfully transmitted? 

    Kind regards

    Glen

Reply
  • Hello Susheel,

    Thanks for your reply. To quickly address the suggestion for the second issue, setting the stack size to 4096 did fix the debugging issue I was seeing. Couldn't connect to RTT when I was debugging, but I could see from the RX side that it was receiving CTEs as expected. I was then able to verify that main only runs once and the IRQ_CONNECT call only gets called once.

    For the main issue, by setting the trigger to EVENT_END, I am still seeing multiple triggers

    So four triggers in the TXIdle state and one in the TX state. Whereas when I use EVENT_PAYLOAD, I see the following

    Five triggers in the TX state, which is one more than the setup you're outlining. Could this be related to the periodic advertising used? 

    Related, if the number of payloads is fixed (I am sending the same type of payload continuously), could I then just check that we have reached the correct number (in your setup example, since I am sending CTEs, 4 payloads, and then proceed as if things had been successfully transmitted? 

    Kind regards

    Glen

Children
No Data
Related