Custom Radio channel

"Hello, I'm using NCS v2.4.2 with an nRF52840DK and attempting to configure a custom radio channel with frequencies like 2403MHz and 2405MHz.

I followed the provided instructions;

https://github.com/Simula-UiB/mesh-node/blob/main/net_core/src/radio.c

the link would be on BLE-Mesh, but I tried BLE with my configuration, which is given below.

radio configurations:

/**
 * @brief Start radio transmission
 */
int radio_send(uint8_t *data, size_t length)
{
    int ret = 0;
    
    /* Fill radio transmission buffer */
    memcpy(rf_tx_buf + RF_BUFFER_PAYLOAD_OFFSET, data, length);

    /* Set length */
    rf_tx_buf[RF_BUFFER_LENGTH_OFFSET] = length + 1;

    LOG_HEXDUMP_DBG(rf_tx_buf, length + 1, "Data TX");

    /* Get radio state */
    nrf_radio_state_t state = nrf_radio_state_get(NRF_RADIO);
    switch (state)
    {
    case NRF_RADIO_STATE_RX:
        /* Stop RX, trigger TXEN task from RXIDLE state */
        nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_STOP);
        trigger_tx();
        break;
    case NRF_RADIO_STATE_RXIDLE:
    case NRF_RADIO_STATE_DISABLED:
        /* Radio already in compatible state, trigger TXEN task */
        trigger_tx();
        break;
    case NRF_RADIO_STATE_TXIDLE:
        nrf_radio_packetptr_set(NRF_RADIO, rf_tx_buf);
        nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_START);
        break;
    default:
        /* Radio in incompatible state. Drop packet, for now */
        LOG_ERR("TX Failed, incompatible state. State: %d", state);
        ret = -EIO;
    }
    LOG_DBG("Finished TX");
    return ret;
}

void trigger_tx()
{
    nrf_radio_packetptr_set(NRF_RADIO, rf_tx_buf);
    nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
}

/**
 * @brief Initialize BLE radio
 */
void init_radio()
{
    LOG_INF("Initializing radio");
    /* Set modulation and bitrate */
    nrf_radio_mode_set(NRF_RADIO, NRF_RADIO_MODE_BLE_1MBIT); // NRF_RADIO_MODE_BLE_2MBIT
    /* Enable fast ramp up, transmit center when idle */
    nrf_radio_modecnf0_set(NRF_RADIO, true, RADIO_MODECNF0_DTX_Center);

    /* Set channel */
    nrf_radio_frequency_set(NRF_RADIO, 2426); // 2442 Mhz

    /* Set radio transmission power */
    nrf_radio_txpower_set(NRF_RADIO, TX_POWER);

    /* Set packet config */
    nrf_radio_packet_conf_t pkt_conf = {
        .lflen = 8UL, // Length field length in bits
        .s0len = 0UL,
        .s1len = 0UL,
        .s1incl = false,
        .plen = NRF_RADIO_PREAMBLE_LENGTH_16BIT,
        .crcinc = false, // CRC included in length field
        .statlen = 0UL,
        .balen = 4UL,
        .big_endian = true,
        .maxlen = MAX_MESSAGE_SIZE, // Max payload length
        .whiteen = false            // Packet whitening
    };
    nrf_radio_packet_configure(NRF_RADIO, &pkt_conf);

    /* Address */
    nrf_radio_base0_set(NRF_RADIO, 0xAAAAAAAAAA);
    nrf_radio_prefix0_set(NRF_RADIO, 0x42U);
    nrf_radio_txaddress_set(NRF_RADIO, 0x00U); // Transmit using logical address 0 (base0 and prefix0)
    // nrf_radio_rxaddresses_set(NRF_RADIO, 0x01U); // Enable RX of logical address 0

    /* CRC Config */
    nrf_radio_crc_configure(NRF_RADIO,
                            2, // 2 byte CRC
                            NRF_RADIO_CRC_ADDR_INCLUDE,
                            0x1021); // Polynomial: x16 + x12 + x5 + 1

    /* Shortcuts */
    nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK); // Ready -> Start shortcut
}

main

/**
 * @brief Initialize power and clock peripherals
 */
static void init_power_clock(void)
{
    nrfx_clock_init(NULL);
    nrfx_power_init(NULL);
    nrfx_clock_start(NRF_CLOCK_DOMAIN_HFCLK);
    nrfx_clock_start(NRF_CLOCK_DOMAIN_LFCLK);
    while (!(nrfx_clock_hfclk_is_running() &&
             nrfx_clock_lfclk_is_running()))
    {
        /* Just waiting */
    }
}

void main(void)
{
    init_power_clock();
    /* Radio init */
    init_radio();
    LOG_INF("Radio initialized");

    uint8_t msg = 0xAA;
    while (1)
    {
        radio_send(&msg, 1);
        k_msleep(2000); // Allow logs time to flush
    }
}



Despite the code running without issues, I'm not receiving any messages on nRF Sniffer when monitoring with Wireshark.

I also tried using the default channel index 38 (2426MHz), but I encountered the same issue of not receiving any messages.

Could you please review the configuration to identify any potential mistakes?"

  • Hi,

    Despite the code running without issues, I'm not receiving any messages on nRF Sniffer when monitoring with Wireshark.

    If you are using the nRF Sniffer for Bluetooth LE to sniff for packets, this is configured to look for Bluetooth LE packets only, on valid channels according to the Bluetooth specifications.

    All Bluetooth LE packets are using the same access address, see this example. It looks like you are using a different address in your code, so the packets are not received by the sniffer.

    The sniffer hardware can only scan on one channel at a time. Until you select a device to follow, it will only look for packets on the advertising channels (channel 37-39), and it will not use any channels not defined by the Bluetooth specification (2402-2480 MHz in 2 MHz steps).

    Best regards,
    Jørgen

  • Thanks for your quick response 

    All Bluetooth LE packets are using the same access address, see this example. It looks like you are using a different address in your code, so the packets are not received by the sniffer.

    If I change the access address for Bluetooth LE packets, will I be able to observe it on the sniffer, given the constraint that the sniffer hardware can only scan one channel at a time with a specific device selected to follow?


    The sniffer hardware can only scan on one channel at a time. Until you select a device to follow, it will only look for packets on the advertising channels (channel 37-39),

    Additionally, when using BLE APIs, I can easily monitor the BLE address, but in this scenario, how can I effectively monitor it? How can I set a BLE static address?


    and it will not use any channels not defined by the Bluetooth specification (2402-2480 MHz in 2 MHz steps).

    Lastly, if the sniffer disregards channels not defined by the Bluetooth specification (2402-2480 MHz in 2 MHz steps), what alternatives are available to monitor whether packets have been sent on (2403,2405MHz)or not?

  • hari said:
    If I change the access address for Bluetooth LE packets, will I be able to observe it on the sniffer, given the constraint that the sniffer hardware can only scan one channel at a time with a specific device selected to follow?

    If you set the correct address, the sniffer should be able to receive the packets. However, I'm not sure if the sniffer will also filter packets that do not follow the packet structure of BLE advertising packets.

    hari said:
    Additionally, when using BLE APIs, I can easily monitor the BLE address, but in this scenario, how can I effectively monitor it? How can I set a BLE static address?

    The BLE address is part of the packet header. I recommend you to read the Bluetooth Core specifications to understand how Bluetooth packets are formatted.

    hari said:
    Lastly, if the sniffer disregards channels not defined by the Bluetooth specification (2402-2480 MHz in 2 MHz steps), what alternatives are available to monitor whether packets have been sent on (2403,2405MHz)or not?

    It does not disregard packets, but since it is implemented to scan for BLE packets, it only supports scanning on channels that are defined by the BLE specifications.

    You can implement your own custom receiver using code similar to Radio Receiver Example from nRF5 SDK, but this will not integrate with Wireshark. Wireshark will also not work with non-Bluetooth formatted packets without writing your own packet dissector plugin.

    Best regards,
    Jørgen

  • Thank you for providing this information!

    If you set the correct address, the sniffer should be able to receive the packets. However, I'm not sure if the sniffer will also filter packets that do not follow the packet structure of BLE advertising packets.

    Now that I have set the correct address (access address), I can successfully receive it from another development kit with a radio receiver example, as you suggested earlier.

    My current question is, how do I configure my BLE advertising packets as ADV_NONCONN_IND, including parameters like Tx Address (such as BLE source address)?

    I have come across several references, but I couldn't find a clear understanding of how to configure the advertising PDU exactly for Bluetooth advertisement. I need to configure it in a way that aligns with my radio configuration, specifying a custom frequency for the BLE advertising packet.

    If I send the packet on Bluetooth advertisement channels, will the sniffer be able to receive the message?

    If i send the packet on custom channels (such as 2403, 2405, etc.), I will still be able to receive it from receiver.



  • hari said:

    My current question is, how do I configure my BLE advertising packets as ADV_NONCONN_IND, including parameters like Tx Address (such as BLE source address)?

    I have come across several references, but I couldn't find a clear understanding of how to configure the advertising PDU exactly for Bluetooth advertisement. I need to configure it in a way that aligns with my radio configuration, specifying a custom frequency for the BLE advertising packet.

    As said before, the Bluetooth Core specification is the best source for understanding the packet structure of advertising packets.

    The previously linked GitHub example is an open-source implementation of a Bluetooth advertiser. These links should help you understand how to construct the package and set the correct registers in the RADIO peripheral:

    hari said:
    If I send the packet on Bluetooth advertisement channels, will the sniffer be able to receive the message?

    Yes, as long as the package is constructed following the Bluetooth Core specifications, the sniffer should be able to receive the advertising packets transmitted on advertising channels.

    hari said:
    If i send the packet on custom channels (such as 2403, 2405, etc.), I will still be able to receive it from receiver.

    Yes, as long as the receiver is configured to receive packets on that frequency, address, etc, it should receive the packet.

Related