NRF minimal radio driver

Minimal driver for the NRF51 radio.

This driver uses the nRF5x radio in a proprietary/custom way, defining our own custom link layer. This custom link layer resembles some characteristics of the IEEE802.15.4 link layer, but is not at all compatible to it.

One key point is, that this custom link layer is only meant to operate between nRF5x devices, which let’s us make some very nice assumptions:

  • all communicating hosts are little-endian -> we define host byte order := network byte order

The driver is using a Nordic proprietary physical layer, configured to a bitrate of 2Mbit. The maximum payload length can be freely configured, but the maximal supported value is 250 byte (default is 200 byte).

We define the nrfmin link layer to use 16-bit addresses. On the physical layer we encode these addresses by putting these addresses into the 2 least significant bytes of the supported 5-byte addresses, while setting the other 3 bytes to 0xe7.

For out custom link layer, we define our own proprietary link layer format (all fields are in host byte order (little endian)):

byte0 byte1 - byte2 byte3 - byte4 byte5 byte7 - byteN
length src_addr dst_addr proto payload…
With:
  • length: length of the packet, including the header -> payload len + 6
  • src_addr: 16-bit source address
  • dst_addr: 16-bit destination address
  • proto: type of data transferred (similar to an Ethertype field)

SUMMARY: This driver / link layer supports:

  • 16-bit addressing (16-bit) -> extract default address from CPU ID
  • broadcast (broadcast address is ff:ff)
  • channels from 0 to 31 [2400MHz to 2524MHz, 4MHz per channel]
  • setting of TX power [+4dBm to -20dBm, in ~4dBm steps]
  • 8-bit packet type/proto field (to be used as seen fit)
  • setting device state (RX, SLEEP)

But so far no support for:

  • link layer ACKs
  • retransmissions

So far the driver uses only a single RX buffer that is locked until the data was read/discarded. This can potentially lead to a lot of packet loss -> using more than one buffer would help here…

NRFMIN_CHAN_MIN

nrfmin channel configuration

1
(0U)
NRFMIN_CHAN_DEFAULT
1
(0U)                /* 2400MHz */
NRFMIN_CHAN_MAX
1
(32)
NRFMIN_HDR_LEN

Export some information on header and packet lengths.

1
(sizeof(nrfmin_hdr_t))
NRFMIN_PKT_MAX
1
(NRFMIN_HDR_LEN + NRFMIN_PAYLOAD_MAX)
netdev.h::netdev_t nrfmin_dev

Export the netdev device descriptor.

const netdev.h::netdev_driver_t nrfmin_netdev

Reference to the netdev driver interface.

void nrfmin_setup(void)

Setup the device driver’s data structures.

uint16_t nrfmin_get_addr(void)

Get the currently active address.

Return values

  • the 16-bit node address
void nrfmin_set_addr(uint16_t addr)

Set the 16-bit radio address.

Parameters

addr:address to set

void nrfmin_get_pseudo_long_addr(uint16_t * addr)

Get a pseudo 64-bit long address (needed by IPv6 and 6LoWPAN)

As we do not support 64-bit addresses, we just make one up, for this we simply return 4 times concatenated the 16-bit address.

Parameters

addr:64-bit pseudo long address, as array of 4 * 16-bit

void nrfmin_get_iid(uint16_t * iid)

Get the IID build from the 16-bit node address.

Parameters

iid:the 64-bit IID, as array of 4 * 16-bit

uint16_t nrfmin_get_channel(void)

Get the current channel.

Return values

  • currently active channel
int nrfmin_set_channel(uint16_t chan)

Set the active channel.

Parameters

chan:targeted channel [0-31]

Return values

  • sizeof(uint16_t) on success
  • -EOVERFLOW if channel is not applicable
netopt.h::netopt_state_t nrfmin_get_state(void)

Get the current radio state.

Return values

  • state the radio is currently in
int nrfmin_set_state(netopt.h::netopt_state_t val)

Put the device into the given state.

Parameters

val:target state

Return values

  • sizeof(netopt_state_t) on success
  • -ENOTSUP if target state is not applicable
int16_t nrfmin_get_txpower(void)

Get the current transmit power.

Return values

  • transmission power in [dBm]
void nrfmin_set_txpower(int16_t power)

Set the used transmission power.

Parameters

power:targeted power, in [dBm]

NRFMIN_TXPOWER_DEFAULT

Default transmission power used.

1
(0)                 /* 0dBm */
NRFMIN_ADDR_BCAST

Export the default nrfmin broadcast address.

1
(0xffff)
NRFMIN_PAYLOAD_MAX

Default maximum payload length (must be <= 250)

1
(200U)
struct nrfmin_hdr_t

Header format used for our custom nrfmin link layer.

uint8_t len

packet length, including this header

uint16_t src_addr

source address of the packet

uint16_t dst_addr

destination address

uint8_t proto

protocol of payload

union nrfmin_pkt_t

In-memory structure of a nrfmin radio packet.