SANPO SPI to RS485

SANPO SPI to RS485 lets a Jetson, Raspberry Pi, or another host controller operate RS485 motors and devices in real time. The host sends raw RS485 commands inside fixed 23-byte SPI frames and reads device feedback during later transfers.

Use V47 or later firmware.

SPI Connection and Settings

Item

Setting

SPI mode

Mode 0

Bit order

MSB First

Transfer length

Exactly 23 bytes

Initial test clock

Start at 2 MHz

Recommended frame gap

At least 100 microseconds

Check

Byte 23 is CRC-8 over the first 22 bytes

Board chip select CS1 controls RS485-1 and RS485-2; CS2 controls RS485-3 and RS485-4. On a Linux host, software CS0 and CS1 normally connect to the board connectors marked CS1 and CS2.

Factory RS485 settings are 4 Mbps, one stop bit, no parity, and eight data bits. To save other settings, use AT+SETRS485 over USB as described in RS485 Raw Passthrough. For a temporary SPI-side change, use spi_set_baudrate.py. Temporary SPI-side settings are lost after a power cycle.

Example: configure the first RS485 channel selected by Linux SPI0 CS0 for 4 Mbps, 8-N-1:

sudo python3 spi_set_baudrate.py --spibus 0 --cs 0 --mode rs485 --rs485num 1 --baudrate 4000000 --stop-bits 1 --parity 0 --data-bits 8

Verify the result with an actual device command. The setting is not written to Flash.

Select an RS485 Channel

Board chip select

Channel

Target

CS1

0x01

RS485-1

CS1

0x02

RS485-2

CS2

0x03

RS485-3

CS2

0x04

RS485-4

CS1 or CS2

0x00

Both RS485 channels controlled by the selected MCU

23-Byte Transmit Frame

Byte position

Content

0 to 19

Raw RS485 data; pad to 20 bytes with 00

20

Channel

21

Raw-data length 1 to 20; use 0 for an empty polling frame

22

CRC-8 over the first 22 bytes

CRC-8 uses polynomial 0x07, initial value 0x00, and no final XOR. See SANPO SPI to CAN for sample code.

Send a 17-byte Unitree motor command on Channel 2:

FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C 00 00 00 02 11 67

Bytes 17 to 19 are padding, 02 is the Channel, 11 is hexadecimal for 17 bytes, and 67 is CRC-8.

Read RS485 Feedback

SPI is full duplex. Data returned while sending a command may be an older cached reply or all 00. To wait for feedback, continue sending all-zero 23-byte polling frames.

Reply format:

Byte position

Content

0 to 19

RS485 device feedback; pad to 20 bytes with 00

20

Source Channel: 0x01 for the first channel or 0x02 for the second

21

Actual feedback length 0 to 20

22

CRC-8 over the first 22 bytes

The reply Channel is local to the selected MCU. Feedback from RS485-3 and RS485-4 through CS2 therefore also reports 0x01 and 0x02. The host should verify CRC before reading Channel and length.

The Channel field is valid starting with V47. Earlier firmware always returned 00. Existing applications that ignore byte 20 remain compatible; new applications can use it to identify the source RS485 channel.

Examples

Limitations

  • A raw RS485 command can contain at most 20 bytes.

  • Raw data must not begin with 41 54, 45 54, or 53 54. Contact support if the device protocol uses one of these prefixes.

  • Every transfer must contain all 23 bytes, including padding and CRC.

Troubleshooting

Symptom

Action

Received data is all 00

No feedback is queued; wait briefly and send another empty frame

CRC fails

Check Mode 0, MSB First, 23-byte transfers, and then lower the SPI clock or increase the frame gap

RS485 device does not reply

Check chip select, Channel, raw-data length, RS485 settings, command checksum, A/B wiring, and power

Command is sent on both RS485 channels

Channel is 0x00; select a specific channel

Occasional loss during continuous high-rate traffic

Start at 2 MHz with a 100 microsecond frame gap and increase the rate only after stable testing