# SANPO SPI to FDCAN SANPO SPI to FDCAN lets a Jetson, Raspberry Pi, or another host controller send and receive CAN FD standard and extended frames. CAN FD requires SPI LONG mode with exactly 73 bytes per transfer. ## Switch to LONG Before Use Factory default is SPI SHORT, which cannot carry CAN FD. Send over USB serial as text: ```text AT+SPIMODE=LONG ``` Use a `CRLF` line ending. After receiving `OK`, wait at least 10 ms, then start 73-byte SPI transfers. The setting is saved across power cycles. `AT+CFGERASE` restores SHORT. Also query CAN FD bitrates: ```text AT+SETFDCAN? ``` Factory defaults are 1 Mbps arbitration and 5 Mbps data, with BRS always enabled. The data phase can be 2, 3, 4, or 5 Mbps. See [Communication Settings](baudrate_config). ## SPI Settings | Item | Setting | | --- | --- | | SPI mode | Mode 0 (CPOL=0, CPHA=0) | | Bit order | MSB First | | Transfer length | 72-byte message area + 1-byte CRC, 73 bytes total | | CRC-8 | Polynomial `0x07`, initial value `0x00`, no final XOR | ## Select a CAN FD Channel | SPI chip select | Channel | Target | | --- | --- | --- | | First MCU | `0x01` | CAN-1 | | First MCU | `0x02` | CAN-2 | | Second MCU | `0x03` | CAN-3 | | Second MCU | `0x04` | CAN-4 | | Either chip select | `0x00` | Both CAN FD interfaces on the current MCU | For transmission, `1/3` select the first local interface and `2/4` select the second. Replies only use local Channel `1/2`. ## Data Length Code | Code | Bytes | Code | Bytes | | --- | ---: | --- | ---: | | `00` | 0 | `08` | 8 | | `01` | 1 | `09` | 12 | | `02` | 2 | `0A` | 16 | | `03` | 3 | `0B` | 20 | | `04` | 4 | `0C` | 24 | | `05` | 5 | `0D` | 32 | | `06` | 6 | `0E` | 48 | | `07` | 7 | `0F` | 64 | ## 73-Byte Message ### Extended Frame | Byte position | Content | | --- | --- | | 0 to 1 | Fixed `45 46` (`EF`) | | 2 | Channel | | 3 to 6 | 29-bit CAN ID, most significant byte first | | 7 | Data length code `00` to `0F` | | 8 to 71 | Fixed 64-byte data area; fill unused bytes with `00` | | 72 | CRC-8 over the first 72 bytes | ### Standard Frame | Byte position | Content | | --- | --- | | 0 to 1 | Fixed `53 46` (`SF`) | | 2 | Channel | | 3 to 4 | Fixed `00 00` | | 5 to 6 | 11-bit CAN ID, most significant byte first | | 7 | Data length code `00` to `0F` | | 8 to 71 | Fixed 64-byte data area; fill unused bytes with `00` | | 72 | CRC-8 over the first 72 bytes | For Channel 1, extended ID `0x1F100101`, and 16 data bytes, the first 24 bytes are: ```text 45 46 01 1F 10 01 01 0A 01 01 01 01 42 00 00 00 01 01 64 00 78 56 34 12 ``` Append 48 bytes of `00`, then append CRC-8 over the first 72 bytes. The CRC algorithm is shown in [SANPO SPI to CAN](spi_can). ## Read CAN FD Feedback SPI is full duplex. Data read while sending a command may be an older reply or all zero. Continue sending 73-byte all-zero polling frames to read later feedback. For each nonzero frame, check: 1. Byte 73 matches CRC-8 over the first 72 bytes. 2. The header is `SF` or `EF`. 3. Channel is local `1/2`. 4. The length code is valid. 5. CAN ID and data match the target device protocol. ## Troubleshooting | Symptom | Action | | --- | --- | | Received data is all `00` | No feedback is queued; wait briefly and send another 73-byte empty frame | | No response in 23-byte mode | CAN FD requires LONG; switch and send exactly 73 bytes each time | | CRC fails | Check Mode 0, MSB First, fixed length, SPI clock, and chip-select timing | | CAN FD device does not reply | Check arbitration bitrate, data bitrate, BRS, Channel, ID, termination, wiring, and power | | Length code is valid but data is short | Always provide the complete 64-byte data area and pad unused bytes with `00` |