Hello CIrcuit Dojo Community,

I am new to setting up SPI peripherals, and in the process of moving an accelerometer from I2C bus to SPI bus. What if any are typical sizes for SPI RX and TX buffers? Are these generally the size of or a bit larger than the longest byte array to write, and to read back respectively?

Curious as well, I’m writing code which builds against Zephyr 3.2.0, which of course provides a hardware abstracted API to the SPI interface of a given, supported board. I see that SPI peripherals often utilize Direct Memory Access controllers. From those of you with Zephyr and SPI experience, are SPI related DMA channels generally already called out in SoC device tree files, or board level dts? And if yes, is this sufficient to provide the configuration of those DMA channels without our writing additional code to do so?

I am searching for sample apps among Zephyr’s samples sub-directories.
I’m also reviewing Zephyr’s spi_bitbang project. Haven’t found clear answers yet and figure it may be wise to ask for some help from more experienced developers.

  • Ted

Progress update on SPI questions:

I’ve found a lot of good information regarding SPI receive buffers and transmit buffers, and their “typical” sizes. (There are not really typical SPI buffer sizes, as these depend on amount of data to be transferred which varies a lot per device). The spi_bitbang sample in Zephyr RTOS 3.2.0 gives a wealth of information on typical buffer sizing. In interesting fashion as well, Zephyr’s SPI application programmers’ interface expects not a pointer to a single buffer for TX or RX, but a pointer to one or more such buffers. From the routine that’s linked just above and starts on line 49 of spi_bitbang main.c, it’s clear that the series or arrays of small TX and RX buffers can be set up prior to the call to spi_transceive(), and that proper set up of multiple such buffer pairs can create a multi-step SPI transaction in just a single call to Zephyr’s API.

Per main.c line 70 it looks like SPI write actions are realized by setting the RX buffer pointer to zero. When the transaction acts like an I2C “write read” transaction then both RX and TX buffers must be non-zero.

I have found that to read by one byte via Zephyr spi API, I must specify TX and RX buffers to have size of two elements, both of them. The first element of TX buffer goes from controller to peripheral. The second element of RX buffer receives the data which is sent from SPI peripheral to SPI controller. Some bytes in each buffer are seemingly not used, but both buffers must have equal length. They must mirror each other in size.

Though I cannot confirm it, it looks like the answer to my question about DMA set up is that having DMA controller enabled in SoC level device tree source, and DMA channel references made in an enabled SPI controller node is sufficient to set up DMA for hardware, as opposed to bit-banged, SPI controller use.

I’d been spinning my wheels for a while, for not looking in the right place sooner. But I think we can mark my questions in this post answered.

  • Ted
Terms and Conditions | Privacy Policy