Network Processor Interface (NPI)

TI’s Network Processor Interface (NPI) is used for establishing a serial data link between a TI SoC and external MCUs or PCs. It is an abstraction layer above the serial interface (UART or SPI) that handles sending / receiving data power management, and data parsing. It is mainly used by TI’s network processor solutions.

Unified NPI

Note

This section has been updated to use appropriate language. The terms of controller and peripheral replace the terms of master and slave.

If Unified NPI is being referenced, it will be specifically referred to as “Unified NPI” or (UNPI). Anything that is not specifically called “Unified NPI” is Legacy NPI. However, the API’s and source files of the UNPI implementation will still always be called “NPI”.

Unified NPI offers some improvements over NPI in that it offers a unified frame format that is used by all transport layers.

TI provides the source code for UNPI and it can be found in the following files at <SDK_INSTALL_DIR>\source\ti\ble5stack\npi\src\unified

  • npi_task.c

  • npi_tl.c

  • npi_tl_spi.c or npi_tl_uart.c

  • npi_util.c

UNPI Architecture

UNPI is implemented as its own TI-RTOS task, and supports inter task communication and routing to the underlying serial interface drivers. See the diagram below for details:

../_images/unified_npi_block_diagram.png

Figure 57. Block Diagram for UNPI

UNPI Signaling

Each processor in an UNPI solution must occupy either the controller or peripheral role. The TI wireless SoC generally occupies the peripheral role in the network processor examples included in the SDK.

For the remainder of this section, the following terms will be used:

  • Application Processor ((AP): UNPI Controller (the host MCU)

  • Network Processor ((NP)): UNPI Peripheral (the TI network processor)

In order to properly manage the power domains of the device, there must be a way for an external host to wake the network processor from low power modes. This is done through the inclusion of the following pins:

  • Controller Ready (MRDY): A GPIO pin whose logic level indicates the state of the controller processor. MRDY is an active low (low true) signal. An MRDY event indicates that the controller processor is ready to send or receive data.

  • Peripheral Ready (SRDY): A GPIO pin whose logic level indicates the state of the peripheral processor. SRDY is an active low (low true) signal. An SRDY event indicates that the peripheral processor is ready to send or receive data.

In the peripheral role, MRDY is an input pin and SRDY is an output in. In the controller role, MRDY is an output pin and SRDY is an input pin.

UNPI Handshake

In order to start an UNPI transaction, there first must occur a handshake sequence using the MRDY and SRDY pins. This handshake is required in order to guarantee that both devices are awake and ready to send and/or receive data. Whichever device first starts the handshake sequence is termed the “initiator”. Either the peripheral or the controller may may be the imitator. The UNPI transaction is completed by the controller raising MRDY followed by the peripheral raising SRDY.

The figures below illustrate both controller and peripheral-initiated UNPI transactions

../_images/unified_npi_timing_master_initiates.png

Figure 58. Timing for Controller-Initiated UNPI Transaction

../_images/unified_npi_timing_slave_initiates.png

Figure 59. Timing for Peripheral-Initiated UNPI Transaction

Note

Bidirectional (full-duplex) messaging is also possible with UNPI. See the section below for more details.

Packet Format

The Unified NPI packet format consists of the following fields and is pictured below:

  • 1 byte Start of Frame (SOF): always 0xFE

  • 2 byte Length field in little-endian format (so LSB first)

  • 1 byte Type / Subsystem: that contains both message type and subsystem information as such:

    • Bits[7:5]: Message type, see the message type section for more info

    • Bits[4:0]: Subsystem ID field, used to help UNPI route the message to the appropriate place.

  • 1 byte command ID: opcode of the command being sent

  • variable length Payload: the length of the payload is defined by the length field.

  • 1 byte Frame Check Sequence (FCS): calculated by doing a XOR on each byte of the frame in the order they are sent / received on the bus. The SOF byte is always excluded from the FCS calculation.

../_images/unified_npi_packet_format.png

Figure 60. UNPI Packet Format

Message Types

There are three message types supported by Unified NPI. The type of message being sent is often dependent on which processor initiated the transaction. The message types are described below.

Code

Message Type

0x01

Synchronous Request (SREQ)

0x02

Asynchronous Request/Indication (AREQ/AIND)

0x03

Synchronous Response (SRESP)

Synchronous Messages

A Synchronous Request ((SREQ)) is a frame, defined by data content instead of the ordering of events of the physical interface, which is sent from the Host to NP where the next frame sent from NP to Host must be the Synchronous Response ((SRESP)) to that SREQ. Once a SREQ is sent, the UNPI interface blocks until a corresponding response (SRESP) is received.

Asynchronous Messages

There are two types of asynchronous messages: asynchronous request ((AREQ)) and asynchronous indication ((AIND)). These messages have the same frame, but the difference lies in whether the transfer was initiated by the network processor (AIND) or the host/application processor (AREQ).

Bidirectional Messaging

There are inherently collisions between messages in any protocol that allows asynchronous messaging (where a signal transition denotes the start of a message as with MRDY and SRDY). Instead of requiring intricate collision handling, the UNPI framework allows for bidirectional messaging to occur. This means that data can be sent from the AP to NP and from NP to the AP in the same message window regardless of the handshake order.

While reducing collision handling, bidirectional messaging adds some complexity to what operations must be performed or initiated by each device. For every AIND the NP initiates, it must prepare to both read and write when MRDY is asserted. For every REQ, the AP must prepare to both read and write once SRDY is asserted. Each device will also need to handle any FIFOs that could potentially be overrun during a message and check at the end of every message to see what, if anything, has been received.

The flow chart for bidirectional message is shown here:

../_images/unified_npi_bidirection.png

Figure 61. UNPI Bidirectional Flow Chart

Note

Bidirectional messaging is enabled regardless of power savings options

UNPI Usage

Currently, the UNPI protocol has been implemented using the UART and SPI drivers on CC23xx devices. There are certain driver specific settings that should be configured which are defined in the following sections.

Initially, the UNPI task doesn’t initiate the MRDY and SRDY pins; it will let the pins default to IOID_UNUSED. It is application’s responsibility to define these pins as such:

 1#define MDRY_PIN        Board_PIN_BUTTON0
 2#define SDRY_PIN        Board_PIN_BUTTON1
 3...
 4// NP Parameters for opening serial port to NP
 5static NPI_Params portParams;
 6...
 7#ifdef NPI_USE_UART
 8  NPITask_Params_init(NPI_SERIAL_TYPE_UART, &portParams);
 9#elif defined(NPI_USE_SPI)
10  NPITask_Params_init(NPI_SERIAL_TYPE_SPI, &portParams);
11#else
12#error "Must define NPI_USE_UART or NPI_USE_SPI for any project including NPI"
13#endif //NPI_USE_UART
14  portParams.stackSize = NPI_TASK_STACK_SIZE;
15  portParams.mrdyPinID = MDRY_PIN;
16  portParams.srdyPinID = SDRY_PIN;
17  portParams.bufSize   = 530;
18
19  // Kick off NPI
20  NPITask_open(&portParams);

UART

To use this configuration, the UART project configuration should be selected (if available). This configuration allows low power modes through the inclusion of the MRDY and SRDY signals. If a pre-made project configuration is not included in the SDK, then NPI_USE_UART must be defined as well as including the CC23xx UART drivers. If power management is needed, be sure to define POWER_SAVING and use the MRDY/SRDY signals. The NPI task sets up the UART port with the following settings:

Parameter

Default Value

Baud Rate

115200

Data Length

8

Parity

None

Stop Bits

1

Flow Control

None

Changing the baud rate can be done in the NPITask_Params_init() function as below:

1UART_Params_init(&params->portParams.uartParams);
2params->portParams.uartParams.readDataMode = UART_DATA_BINARY;
3params->portParams.uartParams.writeDataMode = UART_DATA_BINARY;
4params->portParams.uartParams.readMode = UART_MODE_CALLBACK;
5params->portParams.uartParams.writeMode = UART_MODE_CALLBACK;
6params->portParams.uartParams.readEcho = UART_ECHO_OFF;
7params->portParams.uartParams.baudRate= 460800;

SPI

In order to allow full duplex communication, the SPI configuration requires the use of MRDY and SRDY regardless of whether or not power management is enabled. In order to use SPI, use the project configuration included in the SDK (if applicable). If a project configuration is unavailable, then NPI_USE_SPI should be defined as well as including the CC23xx SPI drivers. If power savings is needed, be sure to define POWER_SAVING.

The NPI task will initialize the SPI with the following parameters

Parameter

Default Value

Bit Rate

800000

Data Length

8

Changing the bit rate can be done in the NPITask_Params_init() function as below:

1SPI_Params_init(&params->portParams.spiParams);
2params->portParams.spiParams.mode = SPI_PERIPHERAL;
3params->portParams.spiParams.bitRate = 8000000;
4params->portParams.spiParams.frameFormat = SPI_POL1_PHA1;

Implementing An NPI Controller

As stated above, the TI device operates as an NPI peripheral in the network processor use case. This means the external MCU must implement the controller UNPI role. When developing the NPI controller role on an external MCU, there are a couple things to keep in mind:

  • The NPI controller controls MRDY and thus controls when the NPI frame has completed.

  • Even when the peripheral is sending data, the controller must use the payload format to determine how many bytes it expects and raise MRDY when it has received them.

  • Since all packets use the same frame format regardless of protocol, the NPI controller can use the frame format to determine when to raise MRDY.

An example of an NPI controller implementation for UART can be found at <SDK_INSTALL_DIR>\source\ti\ble5stack\npi\src\unified\npi_tl_uart_m.c

Note

NPI_MASTER must be defined as a preprocessor symbol to use the above file.

When toggling MRDY / SRDY it is important to remember the following rules:

  • Each device must always initiate a read prior to asserting its respective output pin (MRDY with respect to the AP) regardless of the state of the its respective input pin (SRDY with respect to the AP).

  • Each device can only begin to write (or clock data in the case of SPI) once both MRDY and SRDY are asserted.

NPI limitations

The serial interface (SPI or UART) leveraged by the network processor to report data to the host processor has limited throughput. Systems designers should take this limitation into account, and make sure the amount of data reported by the network processor can be handled by the throughput offered by the serial link. Otherwise data and stack overflow may occur which lead to unexpected behaviors.

Note

Projects based on the host_test example may be affected by the limitation described above. In that case the error UTIL_SystemErrorEvent with status INVALID_INTERRUPT_ID may be raised.

Stack overflow can also be detected leveraging Debugging guide.

Long scan operations in busy environment lead the network processor to report significant amount of data. The amount of data reported can be estimated considering the number of scan results expected and the size of each scan report.

Data overflow risks can be reduced by increasing the throughput of the serial interface and/or reducing the amount of data reported.

  • The data throughput offered by the serial interface can be increased by changing the baudrate / bitrate. SPI generally offers higher throughput than UART. Device’s datasheet and drivers’ documentation provide details on the maximum throughputs supported by each serial interface.

  • The amount of data reported can be reduced following three approaches.

    • Reduce the scan duty cycle i.e. the ratio scan window vs scan interval

    • Enable filtering when scanning (see the section related to Obtain Advertising Channel from Advertising Report in the GAP Scanner documentation).

    • Shorten the reports sent through the serial interface by reducing the number of fields reported.

    Details on the way to implement these approaches are provided in the GAP Scanner section and in the BLE Stack API Reference (see the section about the GAP Scanner).