hideakitai / ESP32SPISlave

SPI Slave library for ESP32
MIT License
50 stars 15 forks source link

Detecting incoming SPI message #35

Closed maarten-pennings closed 4 months ago

maarten-pennings commented 6 months ago

Hi Hideaki Tai, I was hoping you allow me to pick your brain once more. I'm using your lib and it is working, but I have one timing issue left.

I have a sort of sensor connected to an ESP32S3. The ESP "kicks" the sensor. Then the sensor starts its "measurement process" which takes between 5us and 15000us (guaranteed). Once the measurement is finished the sensor masters a 12 byte SPI message (at 2.4MHz) towards the ESP. There is one complication, the sensor does NOT have an SSEL line. So, I use one GPIO pin of the ESP and wire that to the SSEL line of the ESP. In conclusion, this is what the ESP does:

  slave.queue(); slave.trigger() // prepare reception of SPI message 
  kicksensor()
  GPIO.clear() // activate (own/self) SSEL
  sleep(15000us)
  GPIO.set() // deactivate SSEL
  assert( slave.hasTransactionsCompletedAndAllResultsReady(1) )
  pick up slave data

This is all working, but two things need improvement.

Hoping your insights into the inside of SPI slaving leads to some clever hints for me.

maarten-pennings commented 5 months ago

I was hoping that via setUserPostSetupCbAndArg I could monitor len or rx_buffer from spi_slave_transaction_t. But that doesn't work. See my github for the experiment I did.

hideakitai commented 5 months ago

I do not like that I have to sacrifice a GPIO pin. Is there another way to trigger SSEL or bypass it entirely (I have seen this on NXP MCUs)?

Sorry, I don't know about it.

I was hoping that via setUserPostSetupCbAndArg I could monitor len or rx_buffer from spi_slave_transaction_t. But that doesn't work.

I think you need to use setUserPostTransCbAndArg() to detect the receive event.

maarten-pennings commented 4 months ago

In the end, I tapped the SDA to a fresh GPIO pin and monitored edges there using an interrupt. I optimized the code so that the interrupt is enabled early enough.