cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767 SPI slave weird behaviour

Seng Tak Goh
Associate III

Dear community,

I am facing a weird problem on using the SPI after migrating my codes from STM32F407 to STM32F767.

The SPI is configured as slave and interfaces with another STM32F406 MCU as master. The data received by the slave is sometimes shifted by one or two bytes. I am using the CMSIS middleware API. The same source code, when compile for another STM32F406 (which is my original target) runs without problem. I noticed that the Data Register of the SPI (SPIx_DR) is sometimes filled upto the 2nd byte even though Datasize (CR2 DR[0:3]) is set to 8-bit, and MSIZE and PSIZE in DMA are both 0 (BYTE). Comparing with the STM32F4 master the data register is consistently only using the lower 8 bits

I do not have the D_CACHE enabled so I have compiled the CMSIS driver with SPI_DCACHE=0. It has the CRC calculation enabled and it did not report any data corruption on both sides.

The master is able to receive the data correctly.

1 ACCEPTED SOLUTION

Accepted Solutions

SPI in 'F7 - in contrast to that in 'F4 - contains a FIFO, and supports something called Data packing. Read carefully the SPI chapter in RM and follow the guidelines.

Note, that observing SPI registers in debugger may result in data loss/confusion.

JW

View solution in original post

5 REPLIES 5

SPI in 'F7 - in contrast to that in 'F4 - contains a FIFO, and supports something called Data packing. Read carefully the SPI chapter in RM and follow the guidelines.

Note, that observing SPI registers in debugger may result in data loss/confusion.

JW

Hi Jan,

Thanks for the useful tip. I have been digging in and found out that having the CRC calculation enabled was the main problem.

It is weird that the DMA copies the CRC into my receive buffer sometimes and not always, causing the whole data alignment to shift, where some LSB bytes from the last transmission are copied to the MSB of the next transmission. Even flushing the RxFIFO doesn't help.

Disabling the CRC substantially improves the situation but not entirely. After some while of transferring, it starts to get data alignment problem, but much less frequent compared to when CRC is enabled.

In the RM it is stated that data packing is automatically managed when DMA is enabled. I am using CMSIS API to manage most of the initialisation (since I am using a common driver source code for both the STM32F7 and STM32F4 projects) and I have to assume that the API adheres to most of the rules specified in the RM.

SengTak

MasterT
Senior III

Options to try:

 hspi4.Init.DataSize          = SPI_DATASIZE_16BIT;

and

  hdma_spi4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

  hdma_spi4_rx.Init.MemDataAlignment  = DMA_MDATAALIGN_HALFWORD;

Logically, dma should works better if DataSize equals in all 3 instances.

I also notices, that SPI slave more stable in

 hspi4.Init.TIMode           = SPI_TIMODE_ENABLE;

with

 hspi4.Init.NSS            = SPI_NSS_HARD_INPUT;

Hi,

In my application the data size, and the DMA alignments have the same size.

Also have just found out in the RM, under the title "CRC Transfer Managed by DMA", the following interesting lines:

  1. The counter for the SPI transmission DMA channel has to be set to the number of data frames to transmit excluding the CRC frame...
  2. In full-duplex mode, the counter of the reception DMA channel can be set to the number of data frames to receive including the CRC
  3. In receive only mode, the DMA reception channel counter should contain only the amount of data transferred, excluding the CRC calculation...

Somehow in full duplex mode the CRC frame must be included into the number of bytes to be handled by DMA....but CMSIS SPI driver doesn't care about CRC (not sure why)..think this is the problem

MasterT
Senior III

I didn't use CRC in my application, interfacing stm32f767 to ad7693 adc, but I had similar issue with SPI - shifted bits in the received data pack. TI mode allows hardware sync SPI , it's some kind of trick to handle bugs in stm SPI implementation.