This page describes in detail different aspects of the NCP platform design.
Spinel protocol usage
Spinel is a general management protocol for enabling a host device to communicate with NCP/RCP device and manage it. The OpenThread stack uses the Spinel NCP Protocol for configuration and bidirectional data sending over a serial link.
The protocol supports encapsulation of IPv6 packets and 802.15.4 frames, which allows for using the NCP full stack or the RCP tunnel modes. It also provides control over the co-processor state (for example, the change power state) and the 802.15.4 PHY and MAC parameters.
For details about the Spinel protocol, see Spinel Protocol specification.
- Framing protocol for Spinel
- The Spinel protocol is defined independently from the physical transport or framing. For this reason, any number of transports and framing protocols can be used with the protocol. See the UART and SPI section for recommendations.
Thread NCP/RCP Example provides a reference implementation of an OpenThread NCP and RCP for nRF52840, nRF52833, and nRF52811.
Spinel support on application processors
Use either wpantund or PySpinel to provide the Spinel support on application processors, depending on your needs.
wpantund
wpantund (WPAN Network Deamon) is a deamon that provides an implementation of the Spinel protocol for POSIX-compliant application processors (host side).
wpantund is available in the wpantund section of the OpenThread repository.
More specifically, wpantund provides:
- a user-space network interface that exposes a native IPv6 network interface to the Thread network;
- a set of command line tools to manage the NCP/RCP state and its behavior on the Thread network.
In the Thread Border Router example, wpantund runs on a Raspberry Pi and is used to forward IPv6 traffic between Thread and external networks.
PySpinel
PySpinel is a Python CLI module that provides several functions also implemented by wpantund. It is primarily targeted to CI tests, but can be used manually to experiment with and test the OpenThread NCP instances.
PySpinel is available in the pyspinel section of the OpenThread repository.
PySpinel is used to:
- add simulated NCP testing to continuous integration;
- automate testing of testbeds running NCP firmware on hardware;
- debug NCP builds of OpenThread;
- connect to a Thread network using the full stack mode and control an NCP from a Python script;
- connect to a Thread network from an application and perform the device firmware update (DFU) – in nRF Util for Thread (available from nRF5 SDK for Thread web page).
- Note
- In the nRF5 SDK for Thread and Zigbee there is no implementation of the Spinel protocol for non-POSIX application processors in this SDK.
Spinel reset detection
NCP can send several status codes to the host to indicate the return status of a command. These status codes are sent through Spinel using the PROP_LAST_STATUS define with the CMD_VALUE_IS command. The full list of status codes is available in the section 6 of the Spinel Protocol specification.
There is a number of reset-related status codes. Each of them indicates the reset cause, but not all are present in the Nordic platform implementation.
Status code
number | Reset cause name | Presence in the Nordic
platform implementation |
112 | STATUS_RESET_POWER_ON | ✔ |
113 | STATUS_RESET_EXTERNAL | ✔ |
114 | STATUS_RESET_SOFTWARE | ✔ |
115 | STATUS_RESET_FAULT | ✔ |
116 | STATUS_RESET_CRASH | ✖ |
117 | STATUS_RESET_ASSERT | ✖ |
118 | STATUS_RESET_OTHER | ✔
Represents OFF, LPCOMP, DIF, NFC, VBUS. |
119 | STATUS_RESET_UNKNOWN | ✖ |
120 | STATUS_RESET_WATCHDOG | ✔ |
UART and SPI
This section contains information about UART and SPI recommended settings (when using the Spinel protocol) and NCP/RCP data encoding over UART and SPI.
You can check and change the UART and SPI driver configuration in the platform-config.h
file, located at the following OpenThread directory:
- For nRF52840:
examples/platforms/nrf528xx/nrf52840
- For nRF52833:
examples/platforms/nrf528xx/nrf52833
- For nRF52811:
examples/platforms/nrf528xx/nrf52811
The recommended configuration can be changed depending on the needs of the application or product.
UART recommendations
- Recommended UART settings
- Use the following recommended default UART settings:
- Flow control
- UART Hardware Flow Control is recommended in the Nordic solution. Using Software Flow Control is neither recommended nor implemented.
- Hardware reset
- Use the Arduino-style hardware reset, where the DTR signal is coupled to the RES pin through a 0.01[micro]F capacitor. This causes the NCP to automatically reset whenever the serial port is opened.
- Note
- This hardware reset method is not used in Nordic's solution. It is recommended to dedicate one of your host pins to control the RES pin on the NCP, so that you can easily perform a hardware reset if necessary.
- Recommended UART signals
- The following UART signals are used in the Nordic solution:
- RX
- TX
- CTS (optional, can be replaced by software flow control)
- RTS (optional, can be replaced by software flow control)
- DTS (optional, not used)
- RES
SPI recommendations
- Recommended SPI signals
- The following SPI signals are recommended:
- CS: Chip Select (Host-to-NCP)
- CLK: Clock (Host-to-NCP)
- MOSI: Master-Output/Slave-Input
- MISO: Master-Input/Slave-Output
- IRQ: Host Interrupt (NCP-to-Host)
- The IRQ signal is used by NCP to indicate to the host that NCP has pending frames that are to be sent to the host. When asserted, the host must initiate an SPI transaction in a timely manner.
- RES: NCP Hardware Reset (Host-to-NCP)
- Recommended SPI properties
- The following SPI properties are recommended:
- CS is active low.
- CLK is active high.
- CLK speed is 1 MHz or 8 MHz.
- Data is valid on leading edge of CLK.
- Data is sent in multiples of 8 bits (octets).
- Octets are sent with the most significant bit first.
NCP/RCP data encoding over UART and SPI
NCP and RCP over UART and USB both use the HDLC-Lite data encoding framing protocol for framing, character escaping, and error detection using Frame Check Sequence (FCS).
Compared with the larger HDLC framing protocol, HDLC-Lite contains only the parts used for framing, escaping and CRC. All other HDLC parts are omitted in the Lite version.
The NCP over SPI use a proprietary framing protocol, which provides error detection and flags indicating presence of CRC, CRC failure, and reset. The NCP over SPI does not use HDLC-Lite. For more information, see the Appendix A, section A.2.1 in the Spinel Protocol specification.
- Note
- wpantund expects data encoded with HDLC-Lite. To communicate with the NCP over the SPI transport, use spi-hdlc-adapter.
Interface speed recommendations for logging
When using the Spinel protocol with SPI or UART interfaces and the OpenThread logging features, make sure to adopt the following recommendations:
- Do not use the debugging level logging over the UART interface with 115200 baud rate. This baud rate is too slow to correctly handle the data and logs. Use 1 Mhz, 8 Mhz for SPI or 1 Mbps for UART instead.
- Because of their verbosity, use the debug-related logging features only during the development stage. Do not use them after the product has been released.
- Extend the logging buffer to up to 32 kB to avoid losing logs.
For the reasoning behind these recommendations, see Performance measurement test results (NCP).
NCP/RCP communication details
The NCP/RCP transport architectures include a transmit (TX) buffer that stores all the data that are to be received by the host using the Spinel protocol.
NCP/RCP prioritization
Since the Spinel protocol does not enforce any prioritization for writing data, the OpenThread NCP and RCP architectures introduce a data prioritization of their own:
- High priority – for data in the TX buffer that must be written, including data that must be written as fast as possible.
- Low priority – for data in the TX buffer that can be delayed or can be dropped if a high priority message is awaiting to be written.
When the buffer is full, some of the low priority frames cannot be dropped and are delayed for later transmission. This happens for example with the Unsolicited update commands, where the low priority frames are themselves prioritized in the following order:
- Frames that can be delayed for later transmission ("delayable frames").
- Frames that cannot be delayed and are dropped when the TX buffer is full ("droppable frames").
Receiving and transmitting data
The Spinel communication is based on commands and responses. The host sends commands to NCP/RCP, and expects a response to each of them.
The commands and responses are tied together with the Transaction Identifier value (TID value) in the Spinel frame header. Responses have a non-zero TID value, and OpenThread NCP/RCP always gives them high priority.
The pending responses that do not fit into the TX buffer are queued for later execution. The queue is itself a buffer located above the TX buffer. If it is full or contains any pending reponses, sending of the delayable frames is postponed and all other low priority data is dropped.
Moreover, the Spinel allows sending unsolicited update commands from NCP to the host. See Transmitting data for details.
Receiving data and RX data flows
The section illustrates the RX data flows for UART and SPI for when the commands are received by NCP/RCP.
- Data RX flow for UART
Figure 1. Data RX flow for UART.
In this flow:
- UART interface stores up to 6 bytes in the hardware FIFO.
- HDLC-encoded data is stored in the Driver receive buffer.
- HDLC data is decoded and stored in the NCP UART Driver receive buffer.
- Spinel commands are dispatched and handled by proper routines.
- If a command requires a response, it will be added to the NCP response queue for later execution.
- Data RX flow for SPI
Figure 2. Data RX flow for SPI.
In this flow:
- SPI interface saves data into the NCP SPI RX buffer.
- NCP obtains pointer to the Spinel frame in the buffer and handles it.
- If a command requires a response, it will be added to the NCP response queue for later execution.
Transmitting data
NCP/RCP has the following process for sending responses:
- After a command is received, the reponse ends up in the NCP/RCP Response Queue.
- In the NCP/RCP Reponse Queue, the command is checked for the data required by the host.
- NCP/RCP gathers the data and writes the response to the TX buffer by emptying the NCP/RCP Response Queue.
- NCP/RCP sends the response from the TX buffer to the host.
- Unsolicited update commands
The Spinel also allows sending unsolicited update commands from NCP to the host, for example when NCP or a node receives a IPv6 packet that must be forwarded to the host.
The unsolicited update commands have the following characteristics:
- They are written to the TX buffer.
- They are asynchronous.
- All have the TID value equal to zero.
- They have low priority.
The unsolicited update commands include both delayable and droppable frames (see NCP/RCP prioritization), prioritized in the following order:
- Delayable frames:
- MAC, IPv6 and UDP forwarding stream properties.
- Property value notification commands, including last status update.
- Droppable frames:
- Debug stream for application.
- This is a separate log for application that has a property ID field that allows the application to distinguish different debug streams.
- Log.
- This is a log that can be used to report errors in the OpenThread stack to the host.
- Writing to the buffer
The responses and unsolicited update commands are written to the buffer using the following process:
- NCP/RCP attempts to empty the NCP/RCP Response Queue. If any response remains in the queue, it prevents the lower priority messages from being written to the buffer.
- Network frames from the Thread stack are added to the queue and a reattempt is made later.
- Property value notification commands are not sent and a reattempt is made later.
- Log and debug stream frames are dropped.
- NCP/RCP attempts to empty the OT Message Queue for pending MAC, IPv6, and UDP messages. The data from these pending messages is not directly copied into the NCP TX Buffer, but instead it is stored in the OT stack and associated with the Spinel frame. The data is copied just before transmission over UART/USB/SPI. This helps save the TX buffer space.
- NCP/RCP attempts to send all pending property value notification commands.
- If the buffer space is available and no responses are pending in the NCP/RCP Response Queue, NCP/RCP allows the logs and debug stream to be written to the TX buffer.
TX data flows
This section illustrates TX data flows for UART and SPI when sending responses and writing them to the TX buffer.
- Data TX flow for UART
Figure 3. Data TX flow for UART.
- Data TX flow for SPI
Figure 4. Data TX flow for SPI.
Portions of this page are reproduced from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.