cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1.. SPI CRC problem

hvan.winkoop9
Associate II
Posted on December 15, 2013 at 21:04

Hi,

After a few days of experimenting and struggeling my SPI application CRC check somehow still does not seem to work.

I'm using the STM32F103ZD uC. Master SPI1 sends data and slave SPI2 receives this data. MOSI/MISO/NSS/CLK pins are connected to their equal named pins. Both SPI's are connected to DMA1 using a 16-bit width data path. On both SPI's the CRC is enabled. Master SPI1 sends data, automatically followed by sending the 16-bits CRC. Slave SPI2 receives data correctly and when debugging the RXCRCR register shows exactly the same CRC as is transmitted by master SPI1. However, the status register of slave SPI2 still shows a CRCERR bit set meaning that the received and calculated CRC does not match the received CRC value. But is does.

I slightly tend to think that there is some hardware error in the uC but I'm not sure.

Is there anybody that has some positive experience with SPI and CRC calculations?

Thanks in advance,

Henk

#stm32-spi-dma-crc #spi-crc
5 REPLIES 5
Posted on December 15, 2013 at 21:26

The implementation is overly awkward. I might try to demonstrate it if I find some time.

I will observed that, generally, a CRC value feed into itself results with a 0, as it's effectively the remainder to a long division, and if continued for the bit length of the CRC you get an integer division with a remainder of zero. The excepts are where the bit direction changes, or the value is inverted.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
hvan.winkoop9
Associate II
Posted on December 16, 2013 at 20:06

Hi,

Maybe I can show here my implementation:

Next interrupt handlers are used:

- DMA1-TX-Channel3 TC (Transfer Complete) (DMA-TX)

- DMA1-RX-Channel4 TC (Transfer Complete) (DMA-RX)

- SPI1-NSS going active low

- SPI1-NSS going inactive high

Both DMA channels are set to 16-bits (Word) width.

- SPI1 starts sending data by:

   - setting DMA with amount of Words to transmit

   - CRC calculation is reset by disable/enable it

   - enable SPI1

      - the NSS pin goes low

      - MOSI data is tranmsitted

      - SCK is running

- on DMA-TX-TC (Transfer Complete) interrupt:

   - the CRCNEXT bit is set to have the CRC transmitted after the last data word

   - the application waits for BSY bit to go inactive (happens after CRC being send)

      - it then disables SPI1

- SPI2 automatically starts receiving data on falling edge of NSS

- on DMA-RX-TC (Transfer Complete) interrupt:

   - SPI2-NSS interrupt is set to inactive-high detection

- On SPI2-NSS inactive high edge detection:

   - CRC is checked by CRCERR bit

   - SPI2 is disabled

   - setting DMA with amount of Words to transmit

   - CRC calculation is reset by disable/enable it

   - SPI2 is enabled

On both SPI's CPOL and CPHA are set to default zero value meaning rx data is sampled starting on first high going SCK.

SPI2 SCK is set to input with pull-down. (Must match SPI1 SCK inactive state).

Regards,

Henk

hvan.winkoop9
Associate II
Posted on December 17, 2013 at 15:28

Hi,

I finally succeeded in implementing the CRC. After more than 30 hours experimenting (...) I discovered that after having received the CRC and examined the CRCERR bit one should execute a dummy read of the slave SPI Data Register (DR)! If not, the next calculated CRC will generate an error even if the received CRC is correct. I tested the CRC check by changing the master and slave polynoms in the debugger and also by using the master DMA-Channel Half-Transfer interrupt by setting the MOSI pin a short time to GPIO which disturbes the data stream.Each error is correctly detected. Care should be taken when examining the CRCERR bit because the CRC should be enabled then, otherwise the CRCERR bit will be cleared suggesting a correct CRC...(which has generated a lot of confusion). But at last it works fine now.

Thanks for listening anyway.

Henk

hrobinson
Associate II
Posted on January 06, 2014 at 21:04

Curiouser still...

I have a similar issue.  Doing SPI between two processors, using DMA.  All set up and working fine.  Almost... one glitch in the CRC:

if I run it all using 8 bit DMA and 8 bit SPI, all works fine.

if I run it all using 16 bit DMA and 16 bit SPI, all works fine - so long as I use LSB first in the SPI configuration.  CRC error reports 0, OK.

if I use 16 bit throughout but MSB first in the SPI configuration, the CRC fails.

But now if I do TWO reads from the DR before checking the CRC, it's Ok again.

How bizarre is that?!

hrobinson
Associate II
Posted on January 07, 2014 at 17:23

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6nd&d=%2Fa%2F0X0000000bvi%2F1rQjJgIwQXcGM_cfPibttphpdHHNv4Vv2E0rAIgKTzI&asPdf=false