zephyr/ext/hal/nordic/drivers/README.md

129 lines
6.1 KiB
Markdown

# nRF 802.15.4 radio driver.
This driver implements only __non-beacon mode__ of operation.
It supports following __features__:
* reception of unicast and broadcast frames (with filtering),
* automatic sending ACK frames,
* setting pending bit in ACK frame according to pending data for given
destination,
* transmission of unicast and broadcast frames,
* automatic CCA procedure before transmission,
* automatic receiving ACK frames,
* low power mode (sleep),
* energy detection,
* promiscuous mode.
## Implementation details
The driver is a FSM. From API perspective it has 4 states. Most of those states
contains sub-states in implementation.
### FSM description
```
receive() transmit()
--------> -------->
Sleep Receive Transmit
<-------- | /|\<--------
sleep() | | receive() / transmitted() / busy_channel()
| |
energy_detection() | | energy_detected()
\|/ |
Energy detection
```
#### Transitions
The driver is initialized in the Sleep state. The higher layer should call
the receive() function to make the driver enter the Receive state and start
radio operations.
In basic applications radio should be most time in a Receive state. In this
state the radio receives incoming frames. Changing to any other state should be
performed from Receive state.
When a frame is received in Receive state the driver notifies the higher layer
by calling received() function. This function is called after reception of a
broadcast frame or after sending an ACK to a unicast frame.
In the promiscuous mode the higher layer is notified about all of the received
frames. Even if the frame was not destined to the receiving node.
To transmit a frame the higher layer should call the transmit() function. If
channel is busy the driver goes back to the Receive state and notifies the
higher layer by calling the busy_channel() function. If a broadcast frame was
transmitted the driver goes back to the Receive state and notifies the higher
layer by calling the transmitted() function. If a unicast frame was transmitted
and an ACK was received the driver goes back to the Receive state and notifies
the higher layer by calling the transmitted() function. If a unicast frame was
transmitted and there was no expected ACK received the higher layer shall call
the receive() function after the ACK timeout to make the driver go back to the
Receive state.
To perform an Energy Detection procedure the higher layer should call the
energy_detection() function. When the procedure is completed the driver goes
automatically back to the Receive state and notifies the higher layer with the
energy_detected() function.
#### States
##### Sleep
In this state the radio is in low power mode. It cannot transmit or receive any
frame.
##### Receive
In this state the radio receives 802.15.4 frames. It filters out frames with
invalid CRC, length, type, destination address.
If the driver receives unicast frame destined to the receiving node it
automatically transmits an ACK frame. According to 802.15.4 standard, an ACK
frame should be delayed aTurnaroundTime (192 uS) after reception of the ACKed
frame. To perform this delay the driver uses the TIFS timer in the radio
peripheral. This timer requires 3 shorts to work correctly:
1. END -> DISABLE
2. DISABLE -> TXEN
3. READY -> START
The driver has limited time after receiving of a frame to decide if an ACK
should be transmitted. If ACK should not be transmitted the driver must abort
sending ACK by disabling those shorts and triggering DISABLE task.
To use this limited time most effective the driver uses the Bit Counter feature
of the radio peripheral to get notification when the Frame Control field is
received and when the destination address is received. Those fields are used to
filter the frame before whole frame is received.
If all 3 shorts used to send ACK automatically are enabled the radio peripheral
sends ACK frames in loop. To prevent this during debugging process there are
only 2 shorts enabled when waiting for frame (1. and 2.) and 2 other shorts are
enabled in DISABLED event handler (1. and 3.). The first short is still enabled
to automatically disable transmitter after transmission of the ACK frame.
##### Transmit
In this state the radio performs the CCA procedure. If channel is free the radio
transmits requested frame. If an ACK was requested in the transmitted frame
the driver automatically receives the ACK frame in this state.
To prevent the TXIDLE peripheral state the driver uses 2 shorts in Transmit
state:
1. READY -> START
2. END -> DISABLE
Those shorts automatically start transmission of the frame when transmitter is
ready and disable transmitter when the frame was transmitted.
##### Energy detection
In this state the radio performs the Energy Detection procedure. During this
procedure the radio is busy and cannot change state to any other. The end of
this procedure is notified to the higher layer by a function call.
### Mutex and critical sections.
State transitions in the FSM can be requested simultaneously by the higher layer
and the IRQ handler. To prevent race conditions in the driver there is a mutex.
The mutex is unlocked only in the *Receive* state (*WaitingRxFrame* substate).
If there is requested state transition, the procedure shall lock the mutex
before state is changed. If mutex cannot be locked, another procedure has locked
it and is going to change the state.
The mutex is unlocked when the driver enters *Receive* state.
A race condition could also occur during handle of a requests from the higher
layer. Even if the receiver is stopped (TASK STOP) the END or DISABLED event can
be raised for a few uS after triggering the task. To prevent interrupt of the
higher layer request handler by IRQ handler, the higher layer request handlers
are performend in critical sections. The critical sections are implemented as
software interrupt requests with priority equal to the RADIO IRQ.