Hi,
I have some SPI devices that I need to drive. There will be 3 or 4 in a daisy-chain configuration where the bytes need to be shifted down the line of devices before CS is raised to trigger the decode of the instructions sent.
Is this something that can be done with the existing HAL or will I need to clone the SPI device code and modify it work with a chain of several devices?
TIA.
Daisy-chaining SPI
Moderator: RoccoMarco
- Giovanni
- Site Admin
- Posts: 14893
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 997 times
Re: Daisy-chaining SPI
Thanks, I have been looking at the doc for SPI Driver.
http://chibios.sourceforge.net/docs3/ha ... c8e5fbfe1f
Does "words" here refer to the variable length array elements? How does the driver interpret the difference?
If I want to send one byte, is this one "word".
If I need to send two bytes is the "data size" 2x uint8_t or 1x uint16_t ? What is n ?
Sorry if I have missed some information that is given, but there does not seen to be enough information in the doc to use the driver.
In the specific case I wanted to test, I need to send 3 bytes, then raise CS; this is repeated three times to a daisy-chain of three devices: one command byte , two return bytes. As you said it is effectively a continuous shift register. I have this working in C on arduino, so I understand the mechanics of the process, what is unclear is the spec for SPI Driver.
It would seem that I need three calls to spiExchange() with txbuf and rxbut set each time, but it is unclear from the doc how the driver will interpret n.
Perhaps some clarification is needed to the wording.
http://chibios.sourceforge.net/docs3/ha ... c8e5fbfe1f
Note
The buffers are organized as uint8_t arrays for data sizes below or equal to 8 bits else it is organized as uint16_t arrays.
Parameters
[in] spip pointer to the SPIDriver object
[in] n number of words to be exchanged
Does "words" here refer to the variable length array elements? How does the driver interpret the difference?
If I want to send one byte, is this one "word".
If I need to send two bytes is the "data size" 2x uint8_t or 1x uint16_t ? What is n ?
Sorry if I have missed some information that is given, but there does not seen to be enough information in the doc to use the driver.
In the specific case I wanted to test, I need to send 3 bytes, then raise CS; this is repeated three times to a daisy-chain of three devices: one command byte , two return bytes. As you said it is effectively a continuous shift register. I have this working in C on arduino, so I understand the mechanics of the process, what is unclear is the spec for SPI Driver.
It would seem that I need three calls to spiExchange() with txbuf and rxbut set each time, but it is unclear from the doc how the driver will interpret n.
Perhaps some clarification is needed to the wording.
- Giovanni
- Site Admin
- Posts: 14893
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 997 times
Re: Daisy-chaining SPI
The information has to be searched on the STM32 reference manual, the buffer elements size depends on the selected frame size, bytes up to 8 bits, half words up to 16 bits.
The number of chained devices does not matter, the only thing that matters the frame size and number of frames sent.
"n" is the number of frames, regardless the size.
Giovanni
The number of chained devices does not matter, the only thing that matters the frame size and number of frames sent.
"n" is the number of frames, regardless the size.
Giovanni
Re: Daisy-chaining SPI
Many thanks.
So it seems that the wording of the doxygen content is inaccurate.
As I understand your reply that should read 'frames' and not 'words'. That would make sense. It should then also be documented what frames means and where it comes from. It seems that it is platform specific rather then chibios specific. Presumably this information is supplied to chibios in something like mcuconf.h . The definition should be included in the description of the driver, since it is logically incomplete without it.
Ultimately this comes from the manufacturer's spec but it has to be provided to chibios somewhere. Again this should be referenced in the doc.
I appreciate your time in replying, perhaps the doc can be improved so that the question is not necessary.
PS the STM32F4 doc says that the frame can be 8 or 16b but I have not been able to find where and how this is configured. Presumably this is done by Chibios in the low level routines, perhaps low level SPI_init().
So it seems that the wording of the doxygen content is inaccurate.
Code: Select all
[in] n number of words to be exchangedAs I understand your reply that should read 'frames' and not 'words'. That would make sense. It should then also be documented what frames means and where it comes from. It seems that it is platform specific rather then chibios specific. Presumably this information is supplied to chibios in something like mcuconf.h . The definition should be included in the description of the driver, since it is logically incomplete without it.
Ultimately this comes from the manufacturer's spec but it has to be provided to chibios somewhere. Again this should be referenced in the doc.
I appreciate your time in replying, perhaps the doc can be improved so that the question is not necessary.
PS the STM32F4 doc says that the frame can be 8 or 16b but I have not been able to find where and how this is configured. Presumably this is done by Chibios in the low level routines, perhaps low level SPI_init().
Re: Daisy-chaining SPI
Code: Select all
173 void spi_lld_exchange(SPIDriver *spip, size_t n,
174 const void *txbuf, void *rxbuf) {
175
176 (void)spip;
177 (void)n;
178 (void)txbuf;
179 (void)rxbuf;
180
181 }Hang on, the whole SPI Driver thing is just a stub ?!
Re: Daisy-chaining SPI
I think you might be looking at the template file, rather than the source file, for spi_lld.c. If you go to os/hal/ports/STM32/LLD/SPIv1/spi_lld.c, for example, you will find that the spi_lld_exchange() function has indeed been implemented.
As for configuring the data frame format (to switch between 8-bit and 16-bit transmission/reception), see section 28.5.1 (page 903) of the STM32F4 reference manual RM0090. Specifically, you need to set the DFF bit in the SPI control register 1 (SPI_CR1) in order to enable 16-bit format.
In ChibiOS this can be achieved through the SPIConfig structure that is passed to spiStart(). This structure allows for bit masks to be written to the SPI_CR1 register. This is also how the baud rate is set as well as other configuration options such as MSB/LSB first, clock polarity and clock phase. See example below, where the baud rate is set to f_PCLK/64 and 16-bit data frame format.
For your daisy chaining scenario, you may want to do something like this:
Where txbuf and txbuf are your transmission and receiving buffers respectively, and n is the number of bytes you wish to transfer. Note that txbuf and rxbuf will need to be arrays of at least n elements.
Hope that helps.
As for configuring the data frame format (to switch between 8-bit and 16-bit transmission/reception), see section 28.5.1 (page 903) of the STM32F4 reference manual RM0090. Specifically, you need to set the DFF bit in the SPI control register 1 (SPI_CR1) in order to enable 16-bit format.
In ChibiOS this can be achieved through the SPIConfig structure that is passed to spiStart(). This structure allows for bit masks to be written to the SPI_CR1 register. This is also how the baud rate is set as well as other configuration options such as MSB/LSB first, clock polarity and clock phase. See example below, where the baud rate is set to f_PCLK/64 and 16-bit data frame format.
Code: Select all
static const SPIConfig spicfg = {
NULL,
GPIOE,
GPIOE_M_ENC_CS,
SPI_CR1_BR_2 | SPI_CR1_BR_0 | SPI_CR1_DFF
};For your daisy chaining scenario, you may want to do something like this:
Code: Select all
spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */
spiStart(&SPID1, &spicfg); /* Setup transfer parameters. */
spiSelect(&SPID1); /* Slave Select assertion. */
spiExchange(&SPID1, n,
txbuf, rxbuf); /* Atomic transfer operations. */
spiUnselect(&SPID1); /* Slave Select de-assertion. */
spiReleaseBus(&SPID1); /* Ownership release. */Where txbuf and txbuf are your transmission and receiving buffers respectively, and n is the number of bytes you wish to transfer. Note that txbuf and rxbuf will need to be arrays of at least n elements.
Hope that helps.
Re: Daisy-chaining SPI
Oh CRAP! I'd written a detailed reply but in the meantime phpBB logged me out then dumped my post when I log back in, Great. I'll just abbreviate: many thanks woodstock.
Apparently the 'datasheet' in rather incomplete. ( typical for ST )
Apparently the 'datasheet' in rather incomplete. ( typical for ST )