The UART HCI protocol implements the Serialization PHY API using the UART interface.
UART HCI for serialization uses four standard UART lines: RX, TX, /CTS, and /RTS. Hardware flow control is enabled. The protocol supports full duplex communication. Serialization version of the HCI protocol has similar feature set as the stand-alone version provided in HCI transport library . However, implementation details are different due to API, signalling, and memory management required by the Serialization PHY API.
Packet format complies with the standard. However, because of memory shortage in the Connectivity Chip, the current implementation limits the packet size to 384 bytes. Every payload packet consists of a four-byte header followed by payload and CRC field.
Packet header contains SEQ, ACK numbers, data integrity check (DIP), reliable packet (RP) flags, LEN - numbers of bytes in the payload, and HCS - header checksum. Payload packets use
TYPE=0xE
- a vendor-specific type. Acknowledgement packets use
TYPE=0x0, SEQ=0, DIP=0, RP=0, LEN=0
.
The basic communication flow implemented in the HCI layer is shown in the figure below:
- Each payload packet requires an acknowledgement to complete a transmission. An acknowledgement packet has an ACK field set to number which indicates the next expected SEQ number.
- When the acknowledgement packet is not received within a time-out window, the packet is retransmitted.
- When a packet with an invalid SEQ is received (for example, for a retransmitted packet due to lost acknowledgement packet), the receiver sends an ACK to indicate the next expected packet.
The driver is split into two layers - HCI and SLIP.
HCI LAYER
The HCI layer is implemented as two event-driven state machines with separated micro schedulers for events coming from SER_PHY, SLIP layers, and timer.
The operation of receiver and transmitter state machines is shown in the following UML state diagram :
SLIP LAYER
UART HCI SLIP packet
Packets are transmitted in the following format:
, where both
TX_PACKET_START
and
TX_PACKET_END
are a
0xC0
byte.
-
On the RX line, you can observe a reception of a complete SLIP packet:
[RX_PACKET]=[0xC0 0xE8 0x3E 0x00 0xDA 0x41 0x42 0xDB 0xDC 0x78 0x8D 0xC0]At the beginning and the end of the packet, there are0xC0bytes that indicate packet start and packet end. -
Between both
0xC0symbols, the content of the packet is received. It includes higher level (HCI) header, CRC, and payload. There is also a SLIP escape sequence present:[0xDB 0xDC], which is an encoded 0xC0 character. - On the TX line, a part of a SLIP packet is shown.
UART HCI SLIP driver
The UART HCI SLIP protocol for serialization is implemented in the
ser_phy_uart_hci_slip.c
file. It uses
app_uart.c
as a low-level UART driver.
The implementation is event driven. Events from the low-level driver are handled in a static
ser_phy_uart_evt_callback()
function. Three types of
app_uart_evt_t
events are processed:
APP_UART_COMMUNICATION_ERROR
,
APP_UART_TX_EMPTY
, and
APP_UART_DATA
.
- In case of a APP_UART_COMMUNICATION_ERROR event, the error source (taken from app_uart_evt_t structure) is checked. If the source is parity or overrun error, then the upper layer is notified with SER_PHY_EVT_HW_ERROR . Error source is passed in the error_code member of the ser_phy_evt_hw_error_params_t structure.
-
APP_UART_TX_EMPTY
indicates a TXDRDY interrupt. In such case, a static function for transmission is called:
ser_phy_hci_tx_byte().- Note
-
When transmission of a packet begins, the
ser_phy_hci_tx_byte()function is called for the first time in theser_phy_hci_slip_tx_pkt_send()function. Later it is only called in the app_uart_evt_t event callback.
-
APP_UART_DATA
indicates an RXDRDY interrupt. In such case, a static function for reception
ser_phi_hci_rx_byte()is called, with the received byte as a parameter. The received byte is taken from the app_uart_evt_t structure.
Following ser_phy_hci_slip_evt_type_t , the events are sent to the upper layer:
- SER_PHY_HCI_SLIP_EVT_PKT_SENT , when all bytes of the packet are transmitted.
- SER_PHY_HCI_SLIP_EVT_ACK_SENT , when all bytes of the ACK packet are transmitted.
- SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED , when all bytes have been received. This event indicates how many bytes have been received to which memory address.
- SER_PHY_HCI_SLIP_EVT_HW_ERROR , when a hardware error is reported by the low-level driver.
Function
ser_phy_hci_slip_open()
initializes UART using the
APP_UART_INIT
macro with configuration structure of type
app_uart_comm_params_t
as input. It also registers the
SER_PHY_HCI_SLIP
event callback.
Function
ser_phy_hci_slip_close()
closes UART using the
app_uart_close()
function. It also deregisters the
SER_PHY_HCI_SLIP
event callback.