Sending advertising packets using NRF_RADIO

I have the following set up:

1) an NRF timer which triggers the timer-handler

2) an NRF radio peripheral which is triggered by the timer-handler

3) an NRF radio transmission which is fired in radio-handler

Timer-handler (interrupt routine):

void timer1_interrupt_handler(nrfx_timer_event_handler_t evt, void * p_context)
{

LOG_INF("========= Timer1 HANDLER =========");
    radio_interup_counter = 0;
    NRF_TIMER1 -> EVENTS_COMPARE[0] = 0;

    // Loging radio state before its activation
    state0 = nrf_radio_state_get(NRF_RADIO);
    
    // Reseting interupt setting and configuration
    nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFF);
	nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_END_MASK | NRF_RADIO_INT_READY_MASK);
    
    // Dummy packets to be sent by the radio interupt to follow
    // (Packets are already declared globally)
    packet.x = 23;
    packet.z = 67;
    packet.z = 15;
    
    // Packet pointer assignment
    NRF_RADIO->PACKETPTR = (uint32_t) &packet;
    
    // Firing the radio!
    NRF_RADIO->TASKS_TXEN = 1;
}

Radio handler (interrupt routine):

ISR_DIRECT_DECLARE(RADIO_ISR) {
    radio_interup_counter ++;
    if (radio_interup_counter == 1){
        LOG_INF("======= First RADIO HANDLER =======");
    } 

    // TASK-Start when READY is received
    if (NRF_RADIO->EVENTS_READY == 1) {
        NRF_RADIO->EVENTS_READY = 0;
        NRF_RADIO->TASKS_START = 1U;
        // Loging NRF_RADIO State
        state1 = nrf_radio_state_get(NRF_RADIO);
    }
    
    // Disabling Radio when END is received
    if (NRF_RADIO->EVENTS_END == 1) {
        NRF_RADIO->EVENTS_END = 0;
        NRF_RADIO->TASKS_DISABLE = 1U;
        // Loging NRF_RADIO State
        state2 = nrf_radio_state_get(NRF_RADIO);
    }

    // Creating some extra logging information (ADDRESS and Payload signals)
    if (NRF_RADIO->EVENTS_ADDRESS == 1U){
        state3 = 20;
    } else {state3 = 0;}

    state4 = 0;
    if (NRF_RADIO->EVENTS_PAYLOAD == 1U){
        state4 = 30;
    }


    if (radio_interup_counter == 2){
    //=======================================================
    // Loging Radio State Transitions
    LOG_INF("  Step_a: %d, Step_b: %d, Step_c: %d, Address: %d, Payload: %d", 
            state0, state1, state2, state3, state4);
    LOG_INF("======= Last RADIO HANDLER  =======");
    }

    ISR_DIRECT_PM();
    return 1;
}

This is the Log information 

[00:08:01.192,962] <inf> Logging_Name:========= Timer1 HANDLER =========
[00:08:01.215,393] <inf> Logging_Name:======= First RADIO HANDLER =======
[00:08:01.237,915] <inf> Logging_Name:  Step_a: 0, Step_b: 11, Step_c: 12, Address: 20, Payload: 30
[00:08:01.262,817] <inf> Logging_Name:======= Last RADIO HANDLER  =======

which means:
We do a full cycle of "Radio off (0)", "Transmission (11)", and "disabling (12)" where we received "Address" and "Payload" transmission signals.

Although this log shows that the radio is sending something, I do not get any message on my wireshark which is hooked up to the NRF_SINFFER.

MOREOVER: I tried to verify transmission by checking the power consumption of the DK.
This is the power-profile of this process that I get using NRF PPK2:

which clearly shows that NRF_RADIO is triggered every 2 seconds which is the timer timeout that I set;

if we look deeper:

Comparing to the NRF power online profiler for nrf52840, this does not show that the radio is actually sending anything.

For the radio configuration, I do the following:

static void radio_configure(void)
{

	const nrf_radio_packet_conf_t pkt_conf = {
		.lflen = 0,
		.s0len = 0,
		.s1len = 0,
		.maxlen = sizeof(struct packet_structure),
		.statlen = 0,
		.balen = 4,
		.big_endian = true,
		.whiteen = true,
	};

	nrf_radio_power_set(NRF_RADIO, true);
	nrf_radio_txpower_set(NRF_RADIO, NRF_RADIO_TXPOWER_0DBM);

	nrf_radio_mode_set(NRF_RADIO, RADIO_MODE_MODE_Ble_1Mbit);
	nrf_radio_modecnf0_set(NRF_RADIO, true, RADIO_MODECNF0_DTX_Center);

	nrf_radio_crc_configure(NRF_RADIO, 3, NRF_RADIO_CRC_ADDR_INCLUDE, 0x11021UL);
	nrf_radio_crcinit_set(NRF_RADIO, 0xFFFFFFUL);

	nrf_radio_packet_configure(NRF_RADIO, &pkt_conf);


    // Creating the access address
    uint32_t ACCESS_ADDRESS[5] = {0x8E, 0x89, 0xBE, 0xD6};
	nrf_radio_base0_set(NRF_RADIO,
		ACCESS_ADDRESS[2] << 24 | ACCESS_ADDRESS[1] << 16 |
		ACCESS_ADDRESS[0] << 8);
	nrf_radio_prefix0_set(NRF_RADIO, ACCESS_ADDRESS[0]);

	nrf_radio_txaddress_set(NRF_RADIO, 0);
	
	nrf_radio_rxaddresses_set(NRF_RADIO, BIT(0));

	uint32_t Channel_Frequency = 80;
    NRF_RADIO->FREQUENCY = Channel_Frequency;

	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);

}

I will be really thankful if you could help me understand why this code does not work.
I have checked almost everything, but still I am not able to figure out why this code does not work (does not send packets).

Any help or suggestion is very much appreciated.

Parents
  • Hi

    I assume you've set up the nRF Sniffer for BLE to use the Bluetooth Low Energy profile? If so, using just the NRF_RADIO without the SoftDevice to follow the Bluetooth specification you won't be able to detect "non-BLE" data. What exactly is your end goal here and what are you trying to see exactly? If the point is to test that the radio works correctly I'd recommend checking out the radio test example project for example. https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/nrf_radio_test_example.html 

    Best regards,

    Simon

  • Yes, I am using NRF sniffer hooked up to wireshark and sniffing on the BLE packets.
    My end goal is to create a proprietary communication protocol which is intractable and compatible with BLE.
    In this regard, I try to first build a simple advertiser and from there add more functionalities.
    Is there any CONFIG that I need to use to enable the soft device? How I can include the soft device so that my developed application works properly?

    In other words, how I can fix the issue? I have found  sd_softdevice_enable function, is that the one I need to include? Should I add this to my application?

    More detail on what I want to do; I basically want to send BLE advertising message on exact times and todo so, I want to use NRF_RADIO instead of the already developed BLE APIs, because the timing that I am looking for is different from the ones BLE stack implements, especially the fact that they introduce certain random delay between packets, which I do not want to have that uncertainty.

Reply
  • Yes, I am using NRF sniffer hooked up to wireshark and sniffing on the BLE packets.
    My end goal is to create a proprietary communication protocol which is intractable and compatible with BLE.
    In this regard, I try to first build a simple advertiser and from there add more functionalities.
    Is there any CONFIG that I need to use to enable the soft device? How I can include the soft device so that my developed application works properly?

    In other words, how I can fix the issue? I have found  sd_softdevice_enable function, is that the one I need to include? Should I add this to my application?

    More detail on what I want to do; I basically want to send BLE advertising message on exact times and todo so, I want to use NRF_RADIO instead of the already developed BLE APIs, because the timing that I am looking for is different from the ones BLE stack implements, especially the fact that they introduce certain random delay between packets, which I do not want to have that uncertainty.

Children
  • Hi

    Omid said:
    My end goal is to create a proprietary communication protocol which is intractable and compatible with BLE.

    This won't be possible I'm afraid. BLE is a strict protocol that will only be compatible with other BLE devices, and devices will need to be certified as per the Bluetooth SIG specification. The best way to do this would be to have the standard implementation of BLE with the SoftDevice, and have the proprietary communication protocol run "on the side" when BLE is not used.

    The SoftDevice will need to be flashed onto the board you're using as it is an image of its own. I'd recommend reading up on what the SoftDevice is and how to use it here. What SDK version are you planning on using, Since it seems like you're currently working with the nRF5 SDK, I'd also recommend checking out this nRF Connect SDK statement regarding the state of our SDKs and what we recommend for new designs.

    Regarding what you want to do, that's not possible, as the BLE stack and specification implements a randomized delay of 0-20ms between advertisements. Other BLE devices won't be compatible, and your device will be out of specification if you don't follow the BLE stack. If your application can't have this random delay, BLE won't be the stack you're looking for I'm afraid.

    Best regards,

    Simon


  • I am pretty sure that, if you advertise with the correct packet structure on 2480 MHz band, any BLE device will be able to see the advertisement. I believe this random delay wouldn't make any difference in detection of signals on 2480 MHz band which is the BLE advertising channel number 39. (The only issue could be packet loss due to collision, which is not my concern for now.)

    Also, let's put aside what is my end goal and not focus on the compatibility issue and let's forget about the BLE compatibility for now.
    (Although I know that people already have implemented similar proprietary protocols.)

    I am using nrf52840 sdk and nrf connect 2.2.

    Let's just assume I want to send "something" with NRF_RADIO.

    How I can verify that my transmitter is sending something.

    From the Power-profiler above, it does not seem to be  sending anything.

    Could you please analyze the code and tell me what could  have caused the issue?

  • Omid said:
    if you advertise with the correct packet structure on 2480 MHz band, any BLE device will be able to see the advertisement

    That may be, but it will be outside of the BLE specification and contradicting the BLE SIG, so you wouldn't be legally allowed to promote your device commercially as BLE compliant I believe, but if it's only for personal use I guess you'll be fine. 

    You should see that the radio peripheral is started with a spike of some kind in the Power Profiler for example. How have you connected the Power Profiler to the DK on your end? If you connect the VOUT cable from the PPK to the topmost pin on pin header P22 and either GND cable to GND on the DK, then power the DK with a USB cable as normal you should be able to see the current consumption of just the nRF52832. You could also use a sniffer of some kind to catch packets transmitted over the air. Using an additional DK with the nRF Sniffer firmware should be viable for example (if within the BLE range of channels).

    I'd recommend using the radio test sample project to see the radio peripheral with the radio_start() function for example.

    Best regards,

    Simon

  • Thanks Simor, as I mentioned in the origin question, I am already using the NRFSniffer which is hooked up to the wireshark. Also, I provided the PPK pictures which shows spikes, but those spikes do not match the ones mentioned on the NRF online power profile webpage.

    I am wondering what part of my code is wrong.
    I do not have any settings for soft device, so I suppose I am not using the soft device. Is that the issue?

    I already analyzed the radio_test sample and it seems everything I did match with that example. (As far as I am aware of).

  • The reason you see a discrepancy between the online power profiler and your own Power Profiler trace is because you're using the radio register by itself instead of the SoftDevice and BLE to advertise. The Online Power profiler specifically shows the current consumption of a BLE advertising event, and not just the nRF's radio peripheral running.

    I'm not able to spot a specific issue in your project code, and for just running a project bare-metal with the radio peripheral shouldn't require the SoftDevice, but it's strongly recommended to use for doing BLE communication.

    Are you using a DK or a custom board for testing this? This could also be a HW issue from what I can see.

    Best regards,

    Simon

Related