Introduction
SIP-R stands for Serial Interface Protocol - Reliable
This is a protocol designed by Michael Richards and Marcel. It is designed specifically so tuning software can communicate with the ECU using a standard reliable protocol.
- It uses a pre-defined format that is easy to parse
- It provides forward and backward compatibility.
- It is stateless and provides ack packets for every command sent. This allows continuous tasks like sensor logging to occur without interruption while setting and map adjustments are made.
In an ideal world 2 layers are necessary.
- application layer is responsible for content dispatch (which byte means what?)
- network layer is responsible for reliable communications (CRC, acknowledge). It must be possible to leave out CRC, if the carrier (CAN, zipfile, etc...) provides CRC anyway.
Note that this 2 layer design does not add code complexity (only if runtime smarties are used to dynamically adjust network packet size, but that will definitely be left out initially). Everything (flags, pointers, code to print/parse them) is there either way, there is just a "(...)+" instead of "(...)" to allow multiple app.packets.
The justification for this:
- the application layer packets can be very short
- the overhead of a network packet is significant because of CRC, acknowledgement, and possibly routing and bandwidth. It is extremely prohibitive in wireless communications.
In future implmentations it may be necessary to allow the CRC step to be dropped if the transport layer is already reliable but in this case it adds a mere 2 bytes of overhead and is unlikely to have an performance impact.
Entering SIPR
On startup the ECU can switch to the SIPR protocol by sending the command 'Mas'. You can only enter this from the MENU_ZERO state because this does not make sense for a keyboard user. Upon entering the protocol the string "OK\n" will be sent.
Packet Format
Every packet must be sent in the following format:
Signature | Sequence | Type | Size | Data | CRC-16 |
1 byte | 1 byte | 1 byte | 1 byte | variable length of Size bytes | 2 bytes |
Discussion: The signature byte serves as a trigger to the receiver that a new packet is starting. 0x0A is defined as the byte to use. If the receiver gets a corrupted packet or times out receiving one it will return to a state where it is looking for a packet signature.
The sequence byte is necessary to ensure that ACK packets are matched with the command they refer to. If the tuning software sends 2 commands and one ACK becomes corrupted then the software must be able to correctly determine which command was accepted. In our case it is the responsibility of the sender to increment the sequence number with every command sent to ensure no collisions occur.
The type byte allows up to 255 different types of packets to be defined. In reality we expect to see about 30 different types. Should the need for more than 255 types ever arrive then an "extended" packet type could be defined by carrying extra type definition bytes into the data area.
There is only one byte designated for the data size. This means the largest possible packet will be 261 bytes - more than sufficient for the limited resources of the ECU. As apparent from the description above, size in this context refers only to the number of bytes in the data segment. In some packets it may also be valid to have 0 bytes of data.
Size number of bytes comprise the data segment or payload of a packet.
The last 2 bytes in a packet are the checksum bytes. In this implementation CRC-16 was chosen as an algorithm. This choice was made because of it's proven track record and library availability. The CRC is applied to the entire packet including the header bytes.
Packet Type Definitions
NAK
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x00
- Size: 0 (no data necessary)
- Response: none
- Description: The NAK packet is always sent in response to receiving an invalid (wrong CRC) or unrecognised (type not found) packet. In the future it may be necessary to add a reason byte to the data.
ACK
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x01
- Size: 0 (no data necessary)
- Response: none
- Description: The ACK packet is always sent in response to a command packet. The ACK packet tells the sender that the command was received, understood and processed.
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x01
- Size: 0 (no data necessary)
- Response: ACK
- Description: As a special case the tuning software can send an ACK and expect an ACK to be returned. This functions as a "Ping".
GET_VERSION
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x02
- Size: 0 (no data necessary)
- Response: GET_VERSION
- Description: The GET_VERSION packet is sent by the tuning software to determine the version of firmware it is communicating with. This detail is often necessary to determine the features available to the software.
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x02
- Size: 3
- Response: none
- Data: The 3 data bytes returned are the Major, Revision and Build numbers of the firmware. 0x01 0x00 0x03 for example would mean version 1.0.3
- Description: The GET_VERSION response packet provides the tuner with the firmware version.
SET_BAUD
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x03
- Size: 1
- Response: ACK
- Data: The byte here represents the baudrate as chosen from the following table.
byte | Baudrate |
0x01 | 9600 |
0x02 | 38400 |
0x03 | 57600 |
0x04 | 115200 |
- Description: The SET_BAUD command is a particular one. The ECU must respond in the current baudrate with it's ACK packet before switching baudrates. The tuning software must take care as missing the ACK packet may result in it retrying in the wrong baudrate. Once sent, the tuning software should wait for an ACK. Then resend. If it still does not receive an ACK then it should try switching to the new baudrate and sending one or more pings (ACK). Previously the data would have been the divisor needed to form the new baudrate. In the interest of portability I have chosen constants. In the future with an ARM processor the divisors may be different.
GET_TABLESIZE
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x04
- Size: 1
- Response: GET_TABLESIZE
- Data: Only 1 data byte is sent to specify the table we are querying.
byte | table |
0x01 | todo |
0x02 | todo |
0x03 | todo |
- Description: The GET_TABLESIZE packet is sent by the tuning software to determine the dimensions of a given table. Compiled options can alter the size of certain tables and knowing the correct sizes is very important
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x04
- Size: 2
- Response: none
- Data: the two data bytes correspond to the number of rows and columns respectively. a 5 row 2 column table would be sent as 0x05 0x02
- Description: The GET_TABLESIZE response tells the tuning software the dimensions of the specified table.
GET_TABLEDATA
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x05
- Size: 1
- Response: GET_TABLEDATA
- Data: Only 1 data byte is sent to specify the table we are querying.
byte | table |
0x01 | todo |
0x02 | todo |
0x03 | todo |
- Description: The GET_TABLEDATA packet is sent by the tuning software to retrieve all the data from the specified table. GET_TABLESIZE can be called to determine the rows and columns format of this data.
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x05
- Size: (determined by the actual size of the table)
- Response: none
- Data: The table data is returned as a byte stream.
- Description: The GET_TABLEDATA response sends the actual content of a table to the tuning software.
SET_TABLEDATA
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x06
- Size: 3
- Response: ACK
- Data: The first data byte identifies the table we are modifying. The second byte contains the offset within that table and the third byte is the actual data.
byte | table |
0x01 | todo |
0x02 | todo |
0x03 | todo |
- Description: The SET_TABLEDATA packet is sent by the tuning software to modify an entry within a table.
READ_SENSORS
- Sender: Tuner
- Sequence: Sequentially chosen by the sender.
- Type: 0x07
- Size: 2
- Response: READ_SENSORS
- Data: The first data byte specifies the number of data sets to return. 0 means stop sending and 255 means send continuously. The second byte specifies the delay between packets.
- Description: The READ_SENSORS packet is sent to request one or more sets of sensor data. The entire structure is returned in an effort to provide the maximum amount of data with a minimum amount of overhead. The repeat and delay bytes are very important for creating data logs as they allow the ECU to send the data at ECU determined intervals - more accurate and not subject to the stacking errors of the software generating the requests.
- Sender: ECU
- Sequence: Set the same as the packet it is responding to.
- Type: 0x07
- Size: to be determined
- Response: none
- Data: Data format as specified in the following table
offset | size | meaning |
See also
- GenBoard/BinaryProtocol - predecessor (almost same)