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

Incorrect RSSI samples in IEEE 802.15.4 RADIO mode

Hi,

we're developing a firmware for the nRF52811 that makes exhaustive use of RSSI sampling during packet reception. While this gives reliable results for Nordic proprietary and BLE RADIO modes (both for 1 MBit/s and 2 MBit/s), we encountered incorrect RSSI samples in IEEE 802.15.4 RADIO mode during specific parts of the packet.

We could reproduce this behaviour using the minimal working example specified below. The used HAL is not from Nordic but it should be self-descriptive anyway. We measured this for two different distances between the receiving and the transmitting antenna. As you can see from the diagram below, the sampled values around bits ~10 to ~15 and ~30 to ~55 are plausible. Indeed they match measurements done in other RADIO modes for the corresponding antenna distances. However, at the beginning, somewhere in the middle and at the end of the packet we get obviously incorrect RSSI samples. Furthermore, the signal level around bits ~10 to ~15 differs from that one around ~30 to ~55.

The only part of the manual with information about RSSI samples related to IEEE 802.15.4 mode is this in chapter 6.14.13.7:

When receiving a frame the RSSI (reported as negative dB) will be measured at three points during the reception. These three values will be sorted and the middle one selected (median 3) to be remapped within the LQI range.

Does this automatic RSSI sampling corrupt the RSSI sample values manually read from RSSISAMPLE register? Is there any chance to workaround this behaviour? What about the different signal levels? Many questions...

Thanks in advance and

best regards,

Gerrit Maus.

#include <libopencm3/nrf5/radio.h>
#include <libopencm3/nrf5/clock.h>
#include <libopencm3/cm3/nvic.h>

volatile uint8_t RSS[1000];
volatile uint16_t RSSC = 0;
volatile bool goOn = true;
uint8_t packet[255];

int main(){
	
	CLOCK_TASKS_HFCLKSTART = 1;
	while(!CLOCK_EVENTS_HFCLKSTARTED);
	
	RADIO_SFD = 0xcb; // Campus network's SFD
	RADIO_MODE = RADIO_MODE_MODE_IEEE802154_250KBIT;
	RADIO_CRCCNF = RADIO_CRCCNF_LEN_VAL(2)
	             | RADIO_CRCCNF_SKIPADDR_IEEE802154;
	RADIO_CRCPOLY = UINT32_C(0x11021);
	RADIO_CRCINIT = 0;
	RADIO_PCNF0 = RADIO_PCNF0_LFLEN_VAL(8)
	            | RADIO_PCNF0_PLEN_32BITZERO
	            | RADIO_PCNF0_CRCINC_INCLUDE;
	RADIO_PCNF1 = RADIO_PCNF1_MAXLEN_VAL(255);
	RADIO_FREQUENCY = 45; // 2445 MHz
	RADIO_PACKETPTR = (uint32_t) packet;
	
	nvic_enable_irq(NVIC_RADIO_IRQ);
	
	RADIO_SHORTS = RADIO_SHORTS_READY_START_ENABLED
	             | RADIO_SHORTS_PHYEND_DISABLE_ENABLED;
	RADIO_INTENSET = RADIO_INTENSET_RSSIEND_SET
	               | RADIO_INTENSET_FRAMESTART_SET;
	RADIO_TASKS_RXEN = 1;
	
	while(!RADIO_EVENTS_PHYEND){
		
		if(goOn){
			// Start another RSSI sampling process once
			// the previous one was processed by the ISR
			goOn = false;
			RADIO_TASKS_RSSISTART = 1;
		}
	}
	
	while(1);
	return 0;
}

void radio_isr(){

	if(RADIO_EVENTS_RSSIEND){
		RADIO_EVENTS_RSSIEND = 0;
		
		if(!RADIO_EVENTS_END && !RADIO_EVENTS_CRCOK){
			// Only process if packet is still on air!
			RSS[RSSC++] = RADIO_RSSISAMPLE;
			goOn = true;
		}
		
		while(RADIO_EVENTS_RSSIEND);
	}
	if(RADIO_EVENTS_FRAMESTART){
		RADIO_EVENTS_FRAMESTART = 0;
		RADIO_TASKS_RSSISTART = 1;
		while(RADIO_EVENTS_FRAMESTART);
	}
}

  • Check out this thread: https://devzone.nordicsemi.com/f/nordic-q-a/70152/rssi-meter-wildly-ineffective

    Especially the first reply: "RSSISETTLE is 15µs typical, meaning if you initate the RSSI measurement less than 15µs after the radio has started in RX, or less than 15µs after starting reception of a packet, the reported RSSI will not be correct. As you have not described how you are doing this it's hard for me to say decisively, but this is a somewhat common cause for incorrect RSSI readings."

    Kenneth

  • Hi Kenneth,

    Thank you for your reply and please excuse me if the following sounds a little harsh but did you actually read the issue?

    RSSISETTLE is 15µs typical, meaning if you initate the RSSI measurement less than 15µs after the radio has started in RX, or less than 15µs after starting reception of a packet, the reported RSSI will not be correct

    This is approximately the time for transmitting 4 bits in IEEE 802.15.4 mode.

    In my original post I presented the RSSI samples during 56 bits. We should hence see an eventual RSSI settling. Anyway, the plotted samples start from the FRAMESTART event, i.e. the RADIO had about 192 µs time to settle to the level of the signal. There was no external signal level change during the time of measurement. From this, there is no RSSI settling to be expected for the shown period.

    As you have not described how you are doing this

    There is a minimal working example attached to the original post…. You may try it yourself.

    Just to make my point clear: This is no question on how to configure RSSI sampling. RSSI sampling (analogue to the minimal working example above) works fine for BLE 1 MBit/s and 2 MBit/s RADIO modes as well as for Nordic proprietary 1 MBit/s and 2 MBit/s RADIO modes. We encountered these obviously incorrect RSSI samples only in IEEE 802.15.4 RADIO mode.

    From what is stated in the product specification, I cannot explain this behaviour. Can you? Slight smile

    Best regards,

    Gerrit.

  • I don't have good explanation, but I will ask internally if someone can explain. Are you able to add some pin toggling here for instance when RSSI is above/below -60dBm, just to make sure that the time scale here is fully correct/understood vs. bits.

    Kenneth

  • Hi Kenneth,

    Sorry for my late reply but I needed some time for testing. The good news: I can explain the first two obviously incorrect RSSI sampling periods. Due to a mistake in the provided minimal working example, the sampling started from the moment of the RXEN TASK. Originally, we encountered obviously incorrect RSSI samples towards the end of a received IEEE 802.15.4 packet during development of our IEEE 802.15.4 stack. We then started going into the details and wrote the provided minimal working example. Unfortunately it had the mentioned mistake in it.

    However, the problem at the end still exists, is reproducible and I can provide you the questioned measurement data.

    Below you find a diagram with RSS samples starting from the FRAMESTART event (first vertical line) up to the END event (last vertical line) during reception of an IEEE 802.15.4 packet. Note, that an RSS sample is discarded once the END event occurs. Hence all samples should be valid ones. However, the last few samples are obviously incorret, i.e. below -60 dBm (intermediate vertical line).

    This behaviour doesn't change when we use the PHYEND event instead of the END event for discarding RSSI samples as you may see from the measurement below. The vertical lines are, as it is also in the previous image, GPIO toggles.

    Just for reference, the next image shows the RSSI sample behaviour when receiving a BLE 2 MBit/s packet. There are only plausible RSSI samples until the END. Note, that the received packet is a bit shorter (in time) than those packets in the IEEE 802.15.4 mode. Anyway, the measurement continued until the END event occurred.

    The source codes for both scenarios (minimal working examples) are provided below.

    Again, please excuse the misleading measurements that we provided initially. However, we still have the issue of incorrect RSSI samples during the last ~2 µs of an IEEE 802.15.4 packet. We can, of course, workaround this by stopping the measurement a little bit earlier using the bit counter or something else. But at least I would like to report this behaviour and hear your thoughts.

    #include <libopencm3/nrf5/radio.h>
    #include <libopencm3/nrf5/clock.h>
    #include <libopencm3/nrf5/gpio.h>
    #include <libopencm3/cm3/nvic.h>
    
    volatile uint8_t RSS[1000];
    volatile uint16_t RSSC = 0;
    volatile bool goOn = false;
    
    int main(){
    	
    	
    	CLOCK_TASKS_HFCLKSTART = 1;
    	while(!CLOCK_EVENTS_HFCLKSTARTED);
    	
    	GPIO_DIRSET = GPIO2;
    	GPIO_OUTSET = GPIO2;
    	
    	uint8_t packet[255];
    	
    	RADIO_SFD = 0xcb; // Campus network's SFD
    	RADIO_MODE = RADIO_MODE_MODE_IEEE802154_250KBIT;
    	RADIO_CRCCNF = RADIO_CRCCNF_LEN_VAL(2)
    	             | RADIO_CRCCNF_SKIPADDR_IEEE802154;
    	RADIO_CRCPOLY = UINT32_C(0x11021);
    	RADIO_CRCINIT = 0;
    	RADIO_PCNF0 = RADIO_PCNF0_LFLEN_VAL(8)
    	            | RADIO_PCNF0_PLEN_32BITZERO
    	            | RADIO_PCNF0_CRCINC_INCLUDE;
    	RADIO_PCNF1 = RADIO_PCNF1_MAXLEN_VAL(255);
    	RADIO_FREQUENCY = 45; // 2445 MHz
    	RADIO_PACKETPTR = (uint32_t) packet;
    	
    	nvic_enable_irq(NVIC_RADIO_IRQ);
    	
    	RADIO_SHORTS = RADIO_SHORTS_READY_START_ENABLED
    	             | RADIO_SHORTS_PHYEND_DISABLE_ENABLED;
    	RADIO_INTENSET = RADIO_INTENSET_RSSIEND_SET
    	               | RADIO_INTENSET_FRAMESTART_SET
    	               | RADIO_INTENSET_END_SET;
    	
    	RADIO_TASKS_RXEN = 1;
    	
    	while(RADIO_STATE != RADIO_STATE_STATE_DISABLED){
    		
    		if(goOn){
    			// Start another RSSI sampling process once
    			// the previous one was processed by the ISR
    			goOn = false;
    			RADIO_TASKS_RSSISTART = 1;
    		}
    	}
    	
    	while(1);
    	return 0;
    }
    
    void radio_isr(){
    	
    	if(RADIO_EVENTS_RSSIEND){
    	
    		RADIO_EVENTS_RSSIEND = 0;
    		static bool below60 = true;
    		
    		if(!RADIO_EVENTS_END){
    			// Only process if packet is still on air!
    			RSS[RSSC++] = RADIO_RSSISAMPLE;
    			goOn = true;
    			if(RADIO_RSSISAMPLE >= 60 && below60){
    				below60 = false;
    				gpio_toggle(GPIO2);
    			}
    		}
    		
    		while(RADIO_EVENTS_RSSIEND);
    	}
    	else if(RADIO_EVENTS_FRAMESTART){
    	
    		RADIO_EVENTS_FRAMESTART = 0;
    		
    		RADIO_TASKS_RSSISTART = 1;
    		gpio_toggle(GPIO2);
    		gpio_toggle(GPIO2);
    		
    		while(RADIO_EVENTS_FRAMESTART);
    	}
    	else if(RADIO_EVENTS_END){
    	
    		RADIO_INTENCLR = RADIO_INTENCLR_END_CLEAR;
    		
    		gpio_toggle(GPIO2);
    		gpio_toggle(GPIO2);
    	}
    }
    #include <libopencm3/nrf5/radio.h>
    #include <libopencm3/nrf5/clock.h>
    #include <libopencm3/nrf5/gpio.h>
    #include <libopencm3/cm3/nvic.h>
    
    volatile uint8_t RSS[1000];
    volatile uint16_t RSSC = 0;
    volatile bool goOn = false;
    
    int main(){
    	
    	CLOCK_TASKS_HFCLKSTART = 1;
    	while(!CLOCK_EVENTS_HFCLKSTARTED);
    	
    	GPIO_DIRSET = GPIO2;
    	GPIO_OUTSET = GPIO2;
    	
    	uint8_t packet[255];
    	
    	RADIO_MODE = RADIO_MODE_MODE_BLE_2MBIT;
    	
    	RADIO_CRCCNF = RADIO_CRCCNF_LEN_VAL(3)
    	             | RADIO_CRCCNF_SKIPADDR_SKIP;
    
    	RADIO_CRCPOLY = UINT32_C(0x65b);
    	RADIO_CRCINIT = UINT32_C(0x55555555);
    	RADIO_PCNF1 = RADIO_PCNF1_MAXLEN_VAL(255)
    	            | RADIO_PCNF1_STATLEN_VAL(0)
    	            | RADIO_PCNF1_BALEN_VAL(3)
    	            | RADIO_PCNF1_ENDIAN_LITTLE
    	            | RADIO_PCNF1_WHITEEN_ENABLED;
    	RADIO_PCNF0 = RADIO_PCNF0_LFLEN_VAL(8)
    	            | RADIO_PCNF0_S0LEN_VAL(1)
    	            | RADIO_PCNF0_S1LEN_VAL(0)
    	            | RADIO_PCNF0_S1INCL_AUTOMATIC
    	            | RADIO_PCNF0_PLEN_16BIT
    	            | RADIO_PCNF0_CRCINC_EXCLUDE
    	            | RADIO_PCNF0_TERMLEN_VAL(0);
    	
    	RADIO_PREFIX0 = (UINT32_C(0x130517cb) >> 24) & 0xff;
    	RADIO_BASE0 = UINT32_C(0x130517cb) << 8;
    	RADIO_RXADDRESSES = RADIO_RXADDRESSES_ADDR0_ENABLED;
    	
    	RADIO_DATAWHITEIV = 37;
    	
    	RADIO_FREQUENCY = 45; // 2445 MHz
    	RADIO_PACKETPTR = (uint32_t) packet;
    	
    	nvic_enable_irq(NVIC_RADIO_IRQ);
    	
    	RADIO_SHORTS = RADIO_SHORTS_READY_START_ENABLED
    	             | RADIO_SHORTS_END_DISABLE_ENABLED;
    	RADIO_INTENSET = RADIO_INTENSET_RSSIEND_SET
    	               | RADIO_INTENSET_ADDRESS_SET
    	               | RADIO_INTENSET_END_SET;
    	
    	RADIO_TASKS_RXEN = 1;
    	
    	while(RADIO_STATE != RADIO_STATE_STATE_DISABLED){
    		
    		if(goOn){
    			// Start another RSSI sampling process once
    			// the previous one was processed by the ISR
    			goOn = false;
    			RADIO_TASKS_RSSISTART = 1;
    		}
    	}
    	
    	while(1);
    	return 0;
    }
    
    void radio_isr(){
    	
    	if(RADIO_EVENTS_RSSIEND){
    	
    		RADIO_EVENTS_RSSIEND = 0;
    		static bool below60 = true;
    		
    		if(!RADIO_EVENTS_END){
    			// Only process if packet is still on air!
    			RSS[RSSC++] = RADIO_RSSISAMPLE;
    			goOn = true;
    			if(RADIO_RSSISAMPLE >= 60 && below60){
    				below60 = false;
    				gpio_toggle(GPIO2);
    			}
    		}
    		
    		while(RADIO_EVENTS_RSSIEND);
    	}
    	if(RADIO_EVENTS_ADDRESS){
    	
    		RADIO_EVENTS_ADDRESS = 0;
    		
    		RADIO_TASKS_RSSISTART = 1;
    		gpio_toggle(GPIO2);
    		gpio_toggle(GPIO2);
    		
    		while(RADIO_EVENTS_ADDRESS);
    	}
    	if(RADIO_EVENTS_END){
    	
    		RADIO_INTENCLR = RADIO_INTENCLR_END_CLEAR;
    		
    		gpio_toggle(GPIO2);
    		gpio_toggle(GPIO2);
    	}
    }

    Best regards,

    Gerrit.

  • Good to hear you have found the issue with the start and middle measurement. I am not sure if I want to "disturb" the designers on your observation near the very end of the packet, likely the end event is slightly after the crc in this case due to internal margins (e.g. 802.15.4 use 250kbps:4us, while BLE I assume above is 1Mbps:1us).

    Best regards,
    Kenneth

Related