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

Ant switch pattern and IQ sampling

Hi,

I'm working on direction finding with nrf52833dk (my own board latter on) and Nordic antenna matrix. I'm using NCS v1.6.0-rc2 and example Direction fing connectionless locator & bacon. I want to compute aoa and since i've only one antenna matrix i disabled aod of bacon example by adding "SET(OVERLAY_CONFIG "overlay-aoa.conf")" to CMakeLists.txt.

After few try, my locator found the beacon and print parameter as expected. I want to compute angle, so i print all IQ sample by modifying main.c with 

static void cte_recv_cb(struct bt_le_per_adv_sync *sync,
			struct bt_df_per_adv_sync_iq_samples_report const *report)
{
	printk("CTE[%u]: samples count %d, cte type %s, slot durations: %u [us], "
	       "packet status %s, RSSI %i\n",
	       bt_le_per_adv_sync_get_index(sync), report->sample_count,
	       cte_type2str(report->cte_type), report->slot_durations,
	       packet_status2str(report->packet_status), report->rssi);

        printk("IQ sample content : \n");
        for(int i=0; i<report->sample_count; i++){
                printk("sample[%d] = I:%d Q:%d\n", i, report->sample[i].i, report->sample[i].q);
        }
}

and include bluetooth/hci.h. I got on my output 

PER_ADV_SYNC[0]: [DEVICE]: 23:13:D2:D8:82:4B (random), tx_power 127, RSSI -63, CTE AOA, data length 0, data: 
CTE[0]: samples count 45, cte type AOA, slot durations: 2 [us], packet status CRC OK, RSSI -630
IQ sample content : 
sample[0] = I:5 Q:0
sample[1] = I:-6 Q:-1
sample[2] = I:5 Q:0
sample[3] = I:-6 Q:0
sample[4] = I:5 Q:-1
sample[5] = I:-6 Q:0
sample[6] = I:5 Q:-1
sample[7] = I:-6 Q:0
sample[8] = I:7 Q:8
sample[9] = I:15 Q:20
sample[10] = I:-17 Q:20
sample[11] = I:-4 Q:-5
sample[12] = I:-6 Q:14
sample[13] = I:-14 Q:-2
sample[14] = I:-7 Q:-6
sample[15] = I:-18 Q:-1
sample[16] = I:-1 Q:4
sample[17] = I:-15 Q:9
sample[18] = I:-7 Q:-32
sample[19] = I:4 Q:-11
sample[20] = I:10 Q:-23
sample[21] = I:26 Q:4
sample[22] = I:-3 Q:4
sample[23] = I:16 Q:-2
sample[24] = I:6 Q:12
sample[25] = I:-2 Q:7
sample[26] = I:9 Q:14
sample[27] = I:4 Q:-2
sample[28] = I:14 Q:8
sample[29] = I:-26 Q:20
sample[30] = I:-11 Q:1
sample[31] = I:-26 Q:3
sample[32] = I:-9 Q:-26
sample[33] = I:5 Q:0
sample[34] = I:-10 Q:-13
sample[35] = I:8 Q:-12
sample[36] = I:8 Q:-2
sample[37] = I:9 Q:-15
sample[38] = I:-3 Q:-4
sample[39] = I:-1 Q:-17
sample[40] = I:30 Q:10
sample[41] = I:6 Q:8
sample[42] = I:14 Q:21
sample[43] = I:-18 Q:21
sample[44] = I:-3 Q:-5

I have several question about the output :

  1. Why am i having 45 samples? I know there is a guard period and then as many samples as ant_pattern_length but it is 12 antenna long.
  2. Since there are more value than i expect, should i make an algorithm in order to discard the wrong one ?
  3. Is the values correct ? i know the swing of IQ value are bigger than those.
  4. Last but not least, where can i find in example project all the parameter such as TSAMPLESPACINGREF / TSAMPLESPACING / TSWITCHSPACING ?

I read very carefully your whitepaper, but i need a little help to put all this fine.

Regards,

Nathan

  • Hi Ekfving,

    I found a bug which block switching to slot_durations 0x1.

    The setup : direction finding locator and beacon, aoa mode only, change slot_durations from 0x2 to 0x1

    The output from locator : 

    Creating Periodic Advertising Sync...success.
    Waiting for periodic sync...
    PER_ADV_SYNC[0]: [DEVICE]: 21:9D:41:2C:45:8D (random) synced, Interval 0x0780 (2400 ms), PHY LE 2M
    success. Periodic sync established.
    Enable receiving of CTE...
    failed (err -22)
    Scan disable...Success.
    Waiting for periodic sync lost...
    PER_ADV_SYNC[0]: [DEVICE]: 21:9D:41:2C:45:8D (random), tx_power 127, RSSI -44, CTE AOA, data length 0, data: 
    PER_ADV_SYNC[0]: [DEVICE]: 21:9D:41:2C:45:8D (random), tx_power 127, RSSI -44, CTE AOA, data length 0, data: 

    The failed error prevent IQ sampling. The problem come from function validate_cte_rx_params in direction.c. If i put in comment the section about slot_durations check (222-226), the failed error disappear.

    static int validate_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params)
    {
    	if (!(params->cte_type &
    	      (BT_DF_CTE_TYPE_AOA | BT_DF_CTE_TYPE_AOD_1US | BT_DF_CTE_TYPE_AOD_2US))) {
    		return -EINVAL;
    	}
    
    	if (params->cte_type & BT_DF_CTE_TYPE_AOA) {
    		if (df_ant_info.num_ant < DF_SAMPLING_ANTENNA_NUMBER_MIN ||
    		    !BT_FEAT_LE_ANT_SWITCH_RX_AOA(bt_dev.le.features)) {
    			return -EINVAL;
    		}
    
    		/*if (!(params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
    		      (params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US &&
    		       DF_AOA_RX_1US_SUPPORT(df_ant_info.switch_sample_rates)))) {
    			return -EINVAL;
    		}*/
    
            // Workaround
            if (!(params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
    		      params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US)) {
    			return -EINVAL;
    		}
    
    		if (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
    		    params->num_ant_ids > df_ant_info.max_switch_pattern_len || !params->ant_ids) {
    			return -EINVAL;
    		}
    	}
    
    	return 0;
    }

    It is the "params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US && DF_AOA_RX_1US_SUPPORT(df_ant_info.switch_sample_rates)" that don't return 1, and therefore return error -EINVAL.

    In my build directory, in .conf, the CONFIG_BT_CTLR_DF_ANT_SWITCH_RX and CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US are set.

    Regards,

    Nathan

  • Hi Nathan!

    Sorry for not getting back to you sooner, I've been away for a week. Once again I will try to answer your questions, but our support for this is very limited.

    What you've found in the Bluetooth Spec and deduced from it seem correct. I think the reason it loops with an interval of 11 instead of 12 is that the first antenna is used in the reference period, and the looping pattern reverts to the one that started the sample period. This is what they define as "the beginning" in the spec. See figure 12, section 4 in the whitepaper.

    I'm glad to hear that you fixed the sampling issue. I'll have to get back to you on saturation and gain of IQ samples.

    Best regards,

    Håkon

  • Hi

    There is a comprehensive conversation available in this thread, just I try to write a fresh answer from my point of view, I hope it can help:

    Why am i having 45 samples? I know there is a guard period and then as many samples as ant_pattern_length but it is 12 antenna long.

    Number of samples doesn't depend on the antenna pattern size, it is dependent on two parameters:

    a. CTE duration

    b. TSAMPLESPACING (Corresponds to the 1us or 2us sample slots)

    The first parameter is chosen by the transmitter and can changed here, the default value is the maximum:

    https://github.com/nrfconnect/sdk-nrf/blob/master/samples/bluetooth/direction_finding_connectionless_tx/src/main.c#L20

    The second parameter is chosen by the receiver and can be modified here, the default value is 2us sample slot:

    https://github.com/nrfconnect/sdk-nrf/blob/master/samples/bluetooth/direction_finding_connectionless_rx/src/main.c#L232

    NOTE: At the time of writing this answer, there is a bug that prevents the receiver to work on 1us slot, an issue and fix has provided for this problem:

    Issue: https://github.com/zephyrproject-rtos/zephyr/issues/37305

    Fix: https://github.com/zephyrproject-rtos/zephyr/pull/37308

    Since there are more value than i expect, should i make an algorithm in order to discard the wrong one ?

    The numbers of values is correct, you can calculate it as:

    NumberOfValues = 8 + (CTELength - 12) / (2 * SampleSlot)

    Hint: 12 is total length of "Gaurd Period" and "Refrence Period" and despite of the TSAMPLESPACING, it generates 8 sample per "Refrence Period".

    e.g. for CTE with maximum length (160 us), and default value for sample slot (2 us), it will be:

    8 + (160 - 12) / ( 2 * 2)

    = 8 + 148 / 4 = 8 + 37 = 45

    s the values correct ? i know the swing of IQ value are bigger than those.

    At least I am receiving the same values, but I am not sure about it and should be evaluated with a reference, later.

    Last but not least, where can i find in example project all the parameter such as TSAMPLESPACINGREF / TSAMPLESPACING / TSWITCHSPACING ?

    These parameters are set by lower layers and is not accessible in application layer. Also it is not recommended to modify these values in lower layers, because they are set by experienced developers for each chip-set.

    but instead you can change the sample slot duration at this line as I mentioned before, it consequently will change those parameters in the lower layers:

    https://github.com/nrfconnect/sdk-nrf/blob/master/samples/bluetooth/direction_finding_connectionless_rx/src/main.c#L232

    Regards,

    Saleh

Related