Skip to content

SPI protocol

How the MAX22200's two-phase SPI access works, byte by byte, and how to read it on a logic analyser or in a log.

Every register access is two SPI transactions: the 8-bit Command Register with CMD high, then the data with CMD low. The driver's private writeCommandRegister() and readData32() / writeData32() / readData8() / writeData8() do exactly this; the references are datasheet Table 9 and Figures 7 and 10 to 13.

Command byte

Bit Name Meaning
7 RB/W 0 = read, 1 = write
6:5 RFU Write 0
4:1 A_BNK Register: 0x00 STATUS, 0x01 to 0x08 CFG_CH0 to CFG_CH7, 0x09 FAULT, 0x0A CFG_DPM
0 8bit/n32bits 1 = the data phase is 8 bits (bits [31:24] only), 0 = 32 bits

max22200::CommandReg::build(bank, write, mode8) builds it. The bytes you will see most:

Byte Access
0x00 / 0x80 Read / write STATUS, 32 bits
0x81 Write STATUS[31:24] (ONCH), 8 bits: channel on/off
0x02 / 0x82 Read / write CFG_CH0, 32 bits (CFG_CHn: 0x02 + 2n)
0x12 Read FAULT, 32 bits
0x14 / 0x94 Read / write CFG_DPM

While CMD is high the chip shifts STATUS[7:0], the fault flag byte, out on SDO. 0x04 there is COMER: the chip rejected the previous transfer. The driver keeps the byte; read it with GetLastFaultByte().

The command stays in force: every following CMD-low transfer is of the same type until a new command byte. The driver always sends a command before each data phase, so it never depends on this.

Data phase

Access SDI (host to chip) SDO (chip to host)
Write, 32 bits DATAIN[7:0], [15:8], [23:16], [31:24] STATUS[7:0], command echo, 0x00, 0x00
Read, 32 bits Don't care (FAULT on MAX22200A: clear mask) DATA[31:24], [23:16], [15:8], [7:0]
Write, 8 bits DATAIN[31:24] STATUS[7:0]
Read, 8 bits Don't care DATA[31:24]

32-bit writes go least significant byte first and 32-bit reads come most significant byte first; this is what the datasheet's figures show, and the driver follows it. Within each byte, bits are MSB first.

The chip counts clocks on writes: a 32-bit write checks the first 32, then every 8; an 8-bit write checks every 8. A wrong count is a communication error: the transfer is ignored and COMER sets (FAULT goes low only if M_COMF is 0; it is 1 after reset and Initialize() keeps it).

Selective clear on read (MAX22200A)

Reading FAULT on the MAX22200A clears only the bits whose SDI bit is high during the read. The SDI bytes line up with the SDO bytes: first OCP, then HHF, OLF, DPM. To clear the overcurrent flag of OUT4 alone, send 0x10 0x00 0x00 0x00 while reading. ClearChannelFaults(mask) sends the mask in all four bytes; ReadFaultRegisterSelectiveClear() takes one mask per fault type. The MAX22200 ignores SDI and clears every bit.

Decoding a log

The ESP32 port prints every transfer with ESP32_MAX22200_ENABLE_DETAILED_SPI_LOGGING. Two examples:

Log Meaning
SPI(1) TX: 82 RX: 03, then SPI(4) TX: 00 06 50 28 RX: 03 82 00 00 Write CFG_CH0 = 0x28500600; fault byte 0x03 (ACTIVE, UVM), command echoed
SPI(1) TX: 00 RX: 03, then SPI(4) TX: 00 00 00 00 RX: 00 04 00 03 Read STATUS = 0x00040003: no channel on, M_COMF set, ACTIVE = 1, UVM = 1

0x28500600 decodes as HOLD = 0x28 (40 / 127 of IFS), HIT = 0x50 (80 / 127), HIT_T = 6 (6 × 40 / 25 kHz = 9.6 ms) and CDR, low side, FREQ_CFG = 00. A requested 10 ms reads back as 9.6 ms: the HIT time is an 8-bit count of 40 chopping periods. When you test a write, compare the raw register value you wrote with the one you read; the values in milliamps and milliseconds are quantised.

Next

Drive modes explains what HIT, HOLD, HIT_T and FREQ_CFG do on the output.