SPI2 Slave Register Configuration

akkhauv
Posts: 1
Joined: Sun Jan 04, 2026 4:48 pm

SPI2 Slave Register Configuration

Postby akkhauv » Sun Jan 04, 2026 5:40 pm

Hello,

I'm attempting to write a SPI Slave Driver for an OS which doesn't yet support that--Zephyr--and am starting by manually toggling registers to accomplish a non-dma, CPU-controlled full-duplex slave single transfer on the ESP32s3.

The pseudocode:

Code: Select all

// zero out all registers
zero_regs()

// configure SPI_SLAVE_REG
// set slave mode
set SPI_SLAVE_MODE = 1
// soft reset; this was included in the existing espressif-provided LL layer and resets the SPI clock line, CS line, and data line.
set SPI_SOFT_RESET = 1
set SPI_SOFT_RESET = 0
// operating in mode 0
set SPI_CLK_MODE = 0
set SPI_CLK_MODE_13 = 0
// if this is enabled, the number of bits received via MOSI is recorded in the SPI_SLV_DATA_BITLEN reg after the transaction completes.
set SPI_SLV_WRBUF_BITLEN_EN = 1

// configure SPI_CLK_GATE_REG
// I've tried this both with and without SPI_MST_CLK_ACTIVE and SPI_MST_CLK_SEL
set SPI_CLK_EN = 1
set SPI_MST_CLK_ACTIVE = 1
set SPI_MST_CLK_SEL = 1

// configure SPI_CTRL_REG
// set the polarity of the MOSI and MISO lines to high. This matches the master configuration.
set SPI_Q_POL = 1
set SPI_D_POL = 1

// configure SPI_USER_REG
// I've tried this both with and without MOSI and MISO set to 1, given that the documentation doesn't explicitly say these are needed for a full-duplex transfer, but it makes sense to have them. 
set SPI_USR_MOSI = 1
set SPI_USR_MISO = 1

// sanity check to ensure all registers are as expected; successful
log_sanity_check()

// Copy the contents to transceive into the expected DATA_BUF before transfer in W0-W15
prepare_data()

// signal transaction start
// Tried this both with and without; not sure if it's a master thing
set SPI_USR in SPI_CMD_REG = 1

// wait for the raw interrupt bit to be set
while (!SPI_TRANS_DONE_INT_RAW) /* no op */

// save the contents of DATA_BUF in W0-W15, which should now contain the data read from master, into a data struct
read_data()
I'm not going to include the actual code given that it's fairly dispersed, but the GPIO mux should be configured properly and the APB clock is enabled.

The slave successfully detects when the transaction is done, so SPI_TRANS_DONE_INT_RAW is being updated fine. However, the contents of DATA_BUF (W0-W15) never seem to be shifted out. If I populate W0-W15 with 0xbeefbeef before the transaction, for example, it'll remain 0xbeefbeef after the transaction. Additionally, SPI_SLV_DATA_BITLEN sets to 0, indicating that no data was read from the master.

It seems that people on this forum have come across this exact issue before--see viewtopic.php?t=11870--which makes me think it's an issue with the register configuration that we're both overlooking in the documentation, rather than elsewhere in my logic. That issue was never solved, and the poster ended up switching to DMA-driven rather than CPU-driven transfers.

I've done my best to follow the docs to a T, but I'm hoping someone knows something I've overlooked!

Thank you!

MicroController
Posts: 2661
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SPI2 Slave Register Configuration

Postby MicroController » Mon Jan 05, 2026 10:23 pm

https://github.com/espressif/esp-idf/bl ... ave.c#L675

Do you set up the number of bits to send?

akkhauv
Posts: 1
Joined: Sun Jan 04, 2026 4:48 pm

Re: SPI2 Slave Register Configuration

Postby akkhauv » Tue Jan 06, 2026 12:22 am

@MicroController Thanks for the response!! I did come across that--specifically for the s3, it doesn't seem to be used and leads to an empty function. From what I can tell in the docs, the s3 slave does not depend on having a predetermined bitlen stored anywhere, though there is the option to record the bitlen of a transaction after it finishes.

https://github.com/espressif/esp-idf/bl ... _ll.h#L960
Last edited by akkhauv on Tue Jan 06, 2026 12:32 am, edited 1 time in total.

Who is online

Users browsing this forum: Baidu [Spider] and 9 guests