This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF Connect SDK - fast RSSI sampling maybe via nrfxlib

Hi,

I would like to port an existing contiki-ng code to nRF Connect SDK. Within this code, I need to sample the 2.4GHz radio RSSI value around 50000 times in a short time. My first try was by using the nrf_802154.h library from nrfxlib. Please find below the code and prj.conf.

main.c

#include <zephyr.h>
#include <stdio.h>
#include <stdbool.h>
#include <nrf_802154.h>

#define CHANNEL 26

int init_radio_to_channel(uint8_t channel)
{
	if (false == nrf_802154_receive())
	{
		printf("Failed to change radio state\n");
		return -1;
	}

	nrf_802154_channel_set(channel);

	printf("Successfully enabled the radio and changed channel to %d\n", channel);
	return 0;
}

void main(void)
{
	if (init_radio_to_channel(CHANNEL))
	{
		return;
	}

	int64_t timer_full = k_uptime_get();
	int8_t rssi = 0;
	uint32_t idx = 0;
	while (idx < 50000)
	{
		if (false == nrf_802154_rssi_measure_begin())
		{
			printf("Failed to measure rssi value\n");
			continue;
		}
		rssi = nrf_802154_rssi_last_get();
		idx++;
	}
	printf("Loop iteration count: %d -> consumed time(ms): %lld\n", idx, k_uptime_delta(&timer_full));
}

prj.con

CONFIG_NRF_802154_RADIO_DRIVER=y
CONFIG_NRF_802154_SOURCE_HAL_NORDIC=y

The code works fine, but it's to slow for my usecase.

We can observe an significant difference by comparing contiki-ng and ncs code.

I main, 735 to 9ms is something. Both codes where flashed to the same nrf52840-dk with an constant jammer next to it. The jammer simply spams the same channel constantly. So both codes were run in the same physical environment.

# Zephyr ncs
*** Booting Zephyr OS build v2.7.0-ncs1  ***
Successfully enabled the radio and changed channel to 26
Loop iteration count: 50000 -> consumed time(ms): 735

# Contiki-ng
[INFO: Main      ] Starting Contiki-NG-release
....
Loop iteration count: 50000 -> consumed time(ms): 90

Just for reference here the contiki-ng code.

PROCESS_THREAD(simple_rssi_sampler, ev, data)
{
        PROCESS_BEGIN();
        NETSTACK_MAC.off();
        NETSTACK_RADIO.on();

        if (NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, 26) != RADIO_RESULT_OK)
        {
                printf("ERROR: failed to change radio channel\n");
                return -1;
        }

        rtimer_clock_t timer_full = RTIMER_NOW();
        int rssi = 0;
        uint32_t idx = 0;
        while (idx < 50000)
        {
                if (NETSTACK_RADIO.get_value(RADIO_PARAM_RSSI, &rssi) != RADIO_RESULT_OK)
                {
                        printf("Failed to fetch RSSI value");
                }
                idx++;
        }
        printf("Loop iteration count: %ld -> consumed time(ms): %ld\n", idx, (RTIMER_NOW() - timer_full) * 1000 / RTIMER_SECOND);
        PROCESS_END();
}

 After some resource, it seems like contiki is build upon the nRF5 SDK.

---

Now my question. Is there a faster way to read the RSSI value?

Maybe via the hal (hardware abstraction layer) from nrfxlib, ./modules/hal/nordic/nrfx/hal/nrf_radio.h looks quite promising. At least it looks similar to the nRF5 SDK used by contiki-ng. However, I have not really an idea how to start.

Are there maybe some example codes how to use it?

Regards,

Andreas

Parents
  • Hi Andreas

    If I understand you correctly the ncs code allows you to sample the RSSI 50000 times in 735ms?

    This matches pretty well with the RSSI settling time, which is 15us as documented here.

    735ms / 50000 =  14.7us

    There is no gain in sampling the RSSI faster than the sampling time, since the RSSI value is filtered and will not change fast enough to provide any additional information. 

    I am not sure where your requirement of sampling the RSSI 50000 times comes from, but if you reduce the number of samples so that the total time is similar the end result should be the same. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    thank you very much for this hint. Just to get everything right, do we need to wait for this specific settle time before reading each RSSI value or just if the value has changed?

    If we have a look into the nrf802154 source code, I can observer the wait here nrf_802154_trx.c#L1101. However, this wait get's only executed if we have received a frame beforehand.

    This is not the case in my example code and using an constant jammer sending some garbage. Therefore, the wait is only executed ones, exactly for the first package (tested via a printf).

    So my question has changed to: Are we able to read RSSI values faster than this settle time or not?

    Regards

    Andi

  • Hi Andi

    I discussed this with the developer, and apparently there is no way to read the RSSI faster through the library. 

    You could bypass the library altogether, and read the RSSI through the registers:

    1) Clear the RSSIEND event
    2) Trigger the RSSISTART task
    3) Wait for the RSSIEND event to be set
    4) Read the RSSI from the RSSISAMPLE register

    This is a bit of a dirty hack though. Also, I still don't see the point of oversampling a filtered signal. Essentially you are just burning through CPU cycles and power to sample a bit of extra noise. 

    Best regards
    Torbjørn

Reply
  • Hi Andi

    I discussed this with the developer, and apparently there is no way to read the RSSI faster through the library. 

    You could bypass the library altogether, and read the RSSI through the registers:

    1) Clear the RSSIEND event
    2) Trigger the RSSISTART task
    3) Wait for the RSSIEND event to be set
    4) Read the RSSI from the RSSISAMPLE register

    This is a bit of a dirty hack though. Also, I still don't see the point of oversampling a filtered signal. Essentially you are just burning through CPU cycles and power to sample a bit of extra noise. 

    Best regards
    Torbjørn

Children
No Data
Related