In order to facilitate switching between UART and SPI based Bluefruit LE modules, the Bluefruit LE SPI Friend and Shield uses the same AT command set at the UART modules (ATI, AT+HELP, etc.).  

These text-based AT commands are encoded as binary messages using a simple binary protocol we've named SDEP (Simple Data Exhange Protocol).

Most of the time, you never need to deal with SDEP directly, but we've documented the protocol here in case you need understand the Bluefruit LE SPI interface in depth!

SDEP Overview

SDEP was designed as a bus neutral protocol to handle binary commands and responses -- including error responses -- in a standard, easy to extend manner. 'Bus neutral' means that we can use SDEP regardless of the transport mechanism (USB HID, SPI, I2C, Wireless data over the air, etc.).

All SDEP messages have a four byte header, and in the case of the Bluefruit LE modules up to a 16 byte payloads. Larger messages are broken up into several 4+16 bytes message chunks which are rebuilt at either end of the transport bus. The 20 byte limit (4 byte header + 16 byte payload) was chosen to take into account the maximum packet size in Bluetooth Low Energy 4.0 (20 bytes per packet).

SPI Setup

While SDEP is bus neutral, in the case of the Bluefruit LE SPI Friend or Shield, an SPI transport is used with the following constraints and assumptions, largely to take into account the HW limitations of the nRF51822 system on chip:

SPI Hardware Requirements

  • The SPI clock should run <=4MHz
  • A 100us delay should be added between the moment that the CS line is asserted, and before any data is transmitted on the SPI bus
  • The CS line must remain asserted for the entire packet, rather than toggling CS every byte
  • The CS line can however be deasserted and then reasserted between individual SDEP packets (of up to 20 bytes each).
  • The SPI commands must be setup to transmit MSB (most significant bit) first (not LSB first)

IRQ Pin

The IRQ line is asserted by the Bluefruit LE SPI Friend/Shield as long as an entire SDEP packet is available in the buffer on the nRF51822, at which point you should read the packet, keeping the CS line asserted for the entire transaction (as detailed above).

The IRQ line will remain asserted as long as one or more packets are available, so the line may stay high after reading a packet, meaning that more packets are still available in the FIFO on the SPI secondary side.

SDEP Packet and SPI Error Identifier

Once CS has been asserted and the mandatory 100us delay has passed, a single byte should be read from the SPI bus which will indicate the type of payload available on the nRF51822 (see Message Type Indicator below for more information on SDEP message types). Keep CS asserted after this byte has been read in case you need to continue reading the rest of the frame.

If a standard SDEP message type indicator (0x10, 0x20, 0x40 or 0x80) is encountered, keep reading as normal. There are two other indicators that should be taken into account, though, which indicate a problem on the nRF51822 SPI secondary side:

  • 0xFE: Secondary device not ready (wait a bit and try again)
  • 0xFF: Secondary device read overflow indicator (you've read more data than is available)

This means there are six possible response bytes reading the message type indicator (the first byte read after an SDEP command is sent): 0x10, 0x20, 0x40, 0x80, which indicate a valid message type, or 0xFE, 0xFF which indicate an error condition.

Sample Transaction

The following image shows a sample SDEP response that is spread over two packets (since the response is > 20 bytes in size). Notice that the IRQ line stays asserted between the packets since more than one packet was available in the FIFO on the Bluefruit LE SPI side:

SDEP (Simple Data Exchange Protocol)

The Simple Data Exchange Protocol (SDEP) can be used to send and receive binary messages between two connected devices using any binary serial bus (USB HID, USB Bulk, SPI, I2C, Wireless, etc.), exchanging data using one of four distinct message types (Command, Response, Alert and Error messages).

The protocol is designed to be flexible and extensible, with the only requirement being that individual messages are 20 bytes or smaller, and that the first byte of every message is a one byte (U8) identifier that indicates the message type, which defines the format for the remainder of the payload.

Endianness

All values larger than 8-bits are encoded in little endian format. Any deviation from this rule should be clearly documented.

Message Type Indicator

The first byte of every message is an 8-bit identifier called the Message Type Indicator. This value indicates the type of message being sent, and allows us to determine the format for the remainder of the message.

Message Type

Command

Response

Alert

Error

ID (U8)

0x10

0x20

0x40

0x80

SDEP Data Transactions

Either connected device can initiate SDEP transactions, though certain transport protocols imposes restrictions on who can initiate a transfer. The main device, for example, always initiates transactions with Bluetooth Low Energy or USB, meaning that secondary devices can only reply to incoming commands.

Every device that receives a Command Message must reply with a Response Message, Error Message or Alert message.

Message Types

Command Messages

Command messages (Message Type = 0x10) have the following structure:

Name

Message Type

Command ID

Payload Length

 

 

Payload

Type

U8

U16

U8

 

 

...

Meaning

Always '0x10'

Unique Command Identifier

[7] More data
[6-5] Reserved
[4-0] Payload length (0..16)

Optional command payload (parameters, etc.)

Command ID (bytes 1-2) and Payload Length (byte 3) are mandatory in any command message. The message payload is optional, and will be ignored if Payload Length is set to 0 bytes. When a message payload is present, it’s length can be anywhere from 1..16 bytes, to stay within the 20-byte maximum message length.

A long command (>16 bytes payload) must be divided into multiple packets. To facilitate this, the More data field (bit 7 of byte 3) is used to indicate whether additional packets are available for the same command. The SDEP receiver must continue to reads packets until it finds a packet with More data == 0, then assemble all sub-packets into one command if necessary.

The contents of the payload are user defined, and can change from one command to another.

A sample command message would be:

10 34 12 01 FF

0: Message Type (U8)

1+2: Command ID (U16)

3: Payload Len (U8)

4: Payload (...)

0x10

0x34 0x12

0x01

0xFF

  • The first byte is the Message Type (0x10), which identifies this as a command message.
  • The second and third bytes are 0x1234 (34 12 in little-endian notation), which is the unique command ID. This value will be compared against the command lookup table and redirected to an appropriate command handler function if a matching entry was found.
  • The fourth byte indicates that we have a message payload of 1 byte
  • The fifth byte is the 1 byte payload: 0xFF

Response Messages

Response messages (Message Type = 0x20) are generated in response to an incoming command, and have the following structure:

Name

Message Type

Command ID

Payload Length

 

 

Payload

Type

U8

U16

U8

  

 

 

Meaning

Always  '0x20'

Command ID this message is a response to

[7] More data
[6-5] Reserved
[4-0] Payload length (0..16)

Optional response payload (parameters, etc.)

By including the Command ID that this response message is related to, the recipient can more easily correlate responses and commands. This is useful in situations where multiple commands are sent, and some commands may take a longer period of time to execute than subsequent commands with a different command ID.

Response messages can only be generate in response to a command message, so the Command ID field should always be present.

A long response (>16 bytes payload) must be divided into multiple packets. Similar to long commands, the More data field (bit 7 of byte 3) is used to indicate whether additional packets are available for the same response. On responses that span more than one packet, the More data bit on the final packet will be set to 0 to indicate that this is the last packet in the sequence. The SDEP receiver must re-assemble all sub-packets in into one payload when necessary.

If more precise command/response correlation is required a custom protocol should be developed, where a unique message identifier is included in the payload of each command/response, but this is beyond the scope of this high-level protocol definition.

A sample response message would be:

20 34 12 01 FF

0: Message Type (U8)

1+2: Command ID (U16)

3: Payload Len (U8)

4: Payload

0x20

0x34 0x12

0x01

0xFF

  • The first byte is the Message Type (0x20), which identifies this as a response message.
  • The second and third bytes are 0x1234, which is the unique command ID that this response is related to.
  • The fourth byte indicates that we have a message payload of 1 byte.
  • The fifth byte is the 1 byte payload: 0xFF

Alert Messages

Alert messages (Message Type = 0x40) are sent whenever an alert condition is present on the system (low battery, etc.), and have the following structure:

Name

Message Type

Alert ID

Payload Length

Payload

Type

U8

U16

U8

...

Meaning

Always '0x40'

Unique ID for the Alert Condition

Payload Length (0..16)

Optional response payload

A sample alert message would be:

40 CD AB 04 42 07 00 10

0: Message Type (U8)

1+2: Alert ID (U16)

3: Payload Length

4+5+6+7: Payload

0x40

0xCD 0xAB

0x04

0x42 0x07 0x00 0x10

  • The first byte is the Message Type (0x40), which identifies this as an alert message.
  • The second and third bytes are 0xABCD, which is the unique alert ID.
  • The fourth byte indicates that we have a message payload of 4 bytes.
  • The last four bytes are the actual payload: 0x10000742 in this case, assuming we were transmitting a 32-bit value in little-endian format.

Standard Alert IDs

Alert IDs in the range of 0x0000 to 0x00FF are reserved for standard SDEP alerts, and may not be used by custom alerts.

The following alerts have been defined as a standard part of the protocol:

ID

0x0000

0x0001

0x0002

0x0003

Alert

Reserved

System Reset

Battery Low

Battery Critical

Description

Reserved for future use

The system is about to reset

The battery level is low

The battery level is critically low

Error Messages

Error messages (Message Type = 0x80) are returned whenever an error condition is present on the system, and have the following structure:

Name

Message Type

Error ID

Reserved

Type

U8

U16

U8

Meaning

Always '0x80'

Unique ID for the error condition

Reserved for future use

Whenever an error condition is present and the system needs to be alerted (such as a failed request, an attempt to access a non-existing resource, etc.) the system can return a specific error message with an appropriate Error ID.

A sample error message would be:

80 01 00 00

0: Message ID (U8)

1+2: Error ID (U16)

3: Reserved (U8)

0x80

0x01 0x00

0x00

Standard Error IDs

Error IDs in the range of 0x0000 to 0x00FF are reserved for standard SDEP errors, and may not be used by custom errors.

The following errors have been defined as a standard part of the protocol:

ID

0x0000

0x0001

0x0003

Error

Reserved

Invalid CMD ID

Invalid Payload

Description

Reserved for future use

CMD ID wasn't found in the lookup table

The message payload was invalid

Existing Commands

At present, there are only four SDEP commands implemented in the Bluefruit SPIFRIEND32 firmware:

  • SDEP_CMDTYPE_INITIALIZE = 0xBEEF
  • SDEP_CMDTYPE_AT_WRAPPER = 0x0A00
  • SDEP_CMDTYPE_BLE_UARTTX = 0x0A01
  • SDEP_CMDTYPE_BLE_UARTRX = 0x0A02

SDEP_CMDTYPE_INITIALIZE can be used to reset the SDEP system when a HW RST line isn't available.

The two SDEP_CMDTYPE_UART* commands send data over the BLE UART service.

SDEP_CMDTYPE_AT_WRAPPER is the command you will use most of the time, which is a wrapper that sends AT commands over the binary SDEP transport.  This isn't terribly efficient, and a binary mechanism would have taken less bytes per command, but it allows the reuse of all of the earlier AT parser commands without having to implement one wrapper for every command which would significantly increase the overall code size.

SDEP AT Wrapper Usage

To use the SDEP AT Wrapp you simply send the correct header, along with the AT command you which to send to the parser.  For example:

10-00-0A-03-‘a’-‘t’-‘I’
  • Message Type: 0x10 (Command)
  • Command ID: 0x0A00
  • Command Payload Length: 3 bytes
  • Command Payload: 'a' + 't' + 'i'

This will cause the ATI command to be executed, which will return basic system information.

This guide was first published on Aug 07, 2015. It was last updated on Mar 08, 2024.

This page (SDEP (SPI Data Transport)) was last updated on Mar 08, 2024.

Text editor powered by tinymce.