2022-02-14 11:32 PM
Hi
I am learning to write driver code for SPI. I have an nucleo-L476RG development board with me implementing full-duplex transmit only operation and reading the output of a MOSI pin using a logic-analyzer. The Nucleo board is working as the master
So far this is my understanding of the SPI based on the reference manual.
SPI Parameters
SPI Peripheral - SPI1
Clock Frequency - 4 MHz
Baud Rate - SYS_CLK_DIV_64
CPHA - First Clock Edge
CPOL - Zero when Idle
LSB First - Data transmitted with MSB first
Data Size - 8 bits per frame
Communication Mode - Full duplex(BIDIMODE:0, BIDIOE:0, RXONLY: 0)
Software Slave Management - Enabled
Internal Slave Select -1
Device Mode - Master
GPIO Pin Configuration
GPIO A, Pin 5 -SPI CLK
PinMode - Alternate Function
Alternate function Mode - AF5
Output Type - Push-Pull
GPIO Speed - Default - Not configured
GPIO A, Pin 6 - SPI_MISO
PinMode - Alternate Function
Alternate function Mode - AF5
Output Type - Push-Pull
GPIO Speed - Default - Not configured
GPIO A, Pin 7 - SPI_MOSI
PinMode - Alternate Function
Alternate function Mode - AF5
Output Type - Push-Pull
GPIO Speed - Default - Not configured
GPIO A, Pin 4 - SPI_NSS
PinMode - Alternate Function
Alternate function Mode - AF5
Output Type - Push-Pull
GPIO Speed - Default - Not configured
Output from logic analyzer:
Case: 1 Data transferred: 0x1
Case :2 Data Transferred : 0x2F, Data Size(DS= 4)
I have implemented the blocking call for SPI so far in my logic,
Questions:
Solved! Go to Solution.
2022-02-15 07:13 AM
1+2) Show the actual code. You may be sending more data than you think due to data packing.
3) You can see max frequency of pins vs speed setting in the datasheet. If it's working, it's probably fine.
4) Writing 3x 8-bit values to DR in 2-line mode will produce 24 clocks.
2022-02-15 04:48 AM
Hi Tbone,
maybe we both take part in the same online course ... ;)
2022-02-15 07:13 AM
1+2) Show the actual code. You may be sending more data than you think due to data packing.
3) You can see max frequency of pins vs speed setting in the datasheet. If it's working, it's probably fine.
4) Writing 3x 8-bit values to DR in 2-line mode will produce 24 clocks.
2022-02-15 05:23 PM
My quick checklist:
The number of sck clocks depends on data transmitted, even dummy one when need to read from slave.
A master sck clock is completed once the reception is complete, not transmit buffer empty which is to avoid pause between transmitted bytes. The fifo relaxes this further.
The fifo is sensitive to the core data bus, if you write 8 bit, 8 bit is queued, if you write 16 bit, 2x8 bit will be queued for the 8 bit spi.
Nss is important to sync the slave, it is equivalent to a start stop bit.
Beware, when implementing later a spi slave in the mcu with dma in cyclic mode, your transmit fifo will clog when nss goes up, and you may need to sw reset and reconfigure the spi....
2022-02-16 08:17 AM
Hi TDK,
Thank you for your inputs, based on it I found that the controller was writing 16bit to the SPI1->DR register. Earlier I had implemented it as
//8 bit transfer ,pTxBuffer = pointer to uint8_t
pSPIx->SPI_DR = *pTxBuffer;
Now It works when after typecast now the code looks like
//8 bit transfer ,pTxBuffer = pointer to uint8_t
*((uint8_t*)&pSPIx->SPI_DR) = *pTxBuffer;
Now the logic analyzer send out 8 bit when the data size is configured as 8 bits
@Community member If you are still figuring out why 16 clocks are sent out when the data size is set as 8 bit, this might be a possible solution
2022-02-17 01:27 PM
I can confirm that's the way to code it! Funny, the teacher of the online course coded like Tbone in his first quote and it seemed to work fine for the stm32Fxxx µC, but not for the L-type! Of course, this is not documented in the ref man.
Dear ST staff, please tell the users in your manuals about those important facts!
2022-02-17 01:58 PM
2022-02-18 12:48 PM
Well TDK,
I think there is a misunderstanding. I was commenting on
//8 bit transfer ,pTxBuffer = pointer to uint8_t
*((uint8_t*)&pSPIx->SPI_DR) = *pTxBuffer;
As mentioned, a teacher on a course using the stm32Fxx type did not have to code like this to get the sending done. Data packing was not the issue.
Have a good day. ;)
2022-02-18 01:25 PM
Right, because the STM32F4 family doesn’t have data packing, so casting like this is not needed. I'm not sure of the miscommunication. I was responding to this:
> ... it seemed to work fine for the stm32Fxxx µC, but not for the L-type! Of course, this is not documented in the ref man.
Data packing is documented in the reference manual of the L4 and other families where it is a feature. It's not documented in the F4 and other families where it's not a feature. Perhaps you are saying something else, I'm not sure. No ill-will intended, cheers.