cancel
Showing results for 
Search instead for 
Did you mean: 

CRC-16 implementation to transmit via SPI bus in stm32L151

BR1
Associate II

Hi,

I have a requirement to transmit and receive CRC-16 hardware computed checksum via SPI in stm32L151 microcontroller.

As per the datasheet, i configured polynomial 0x1021 and enabled CRC.

the problem is, CRC register TXCRCR is updating for all instruction execution, i am expecting it has to update only when Data is written to data register SPI->DR.

please let me know, if my implementation is wrong and what is proper method of implementation.

Thank you

Regards,

Bharath R

5 REPLIES 5

> the problem is, CRC register TXCRCR is updating for all instruction execution

How do you know?

JW

If you did it wrong how would we know? You show no code

But you should run your data, and then push out the computed CRC for the last two bytes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@waclawek.jan and @Tesla DeLorean ,

thank you for reply,

Here is my code,

Initialization:

RCC->APB2ENR |= (1<<12); //Enable SPI1 Clock
SPI1->CR1 |= (1<<11); // DFF=1, 16 bit data
SPI1->CR1 |= (1<<0); // CPHA=1
SPI1->CR1 &= ~(1<<1); //CPOL=0
SPI1->CR1 |= (1<<0); // CPHA=1
SPI1->CR1 &= ~(1<<1); //CPOL=0
SPI1->CR1 &= ~(1<<2); // Slave Mode
SPI1->CR1 &= ~((1<<3)|(1<<4)|(1<<5)); // BR[2:0] = 000 not relevant in slave mode
SPI1->CR1 &= ~(1<<7); // LSBFIRST = 0, MSB first
SPI1->CR1 &= ~(1<<10); // RXONLY = 0, full-duplex
SPI1->CR1 &= ~(1<<2); // MSTR = 0; Slave configuration
SPI1->CR2 = 0;
SPI1->CRCPR = 0x1021; //x16+x12+x5+1;
SPI1->CR1 |= (1<<13); //CRCEN=1

RCC->APB2ENR |= (1<<12); // APB2 peripheral clock enable register: SPI 1 clock enable: 1: SPI 1 clock enabled
RCC->AHBENR |= (1<<2); //AHB peripheral clock enable register: IO port B clock enable: 1: IO port B clock enabled
GPIOB->MODER |= (2<<6)|(2<<8)|(2<<10); //GPIOA port mode register: Port x configuration bits: 10: Alternate function mode
//Output Type Register: 0:0 Output push-pull(reset state)
GPIOB->OSPEEDR |= (3<<6)|(3<<8)|(3<<10); //GPIO port output speed register: Port x configuration bits: 11: Very high speed
GPIOB->AFR[0] |= (5<<12)|(5<<16)|(5<<20); //GPIO alternate function low register: Alternate function selection for port x bit: 0101: AF5

SPI1->CR1 |= (1<<6); //SPE: SPI enable

At the time of transmit and receive :

Reset CRC register:
line1:    SPI1->CR1 &= ~(1<<6); //SPE: SPI enable
line 2:   SPI1->CR1 &= ~(1<<13); //CRCEN=0
line 3:   SPI1->CR1 |= (1<<13); //CRCEN=1
line 4:   SPI1->CR1 |= (1<<6); //SPE: SPI enable

line 5:   SPI1->DR =0x3412; // send dummy data

I am executing the code in debug mode,

Here, line 1 to line 4 is to reset CRC so that TXCRCR and RXCRCR registers should be reset.

Question  1: after 4th line execution, only TXCRCR register is resetting not RXCRCR.

Question  2: at line 4, TXCRCR register should not update (means it should be stay 0x0000) but it is updating.

Question  3: at line 5, once i load the dummy data to DR register example 0x3412,

as per CRC-16 CCITT, polynomial 0x1021, the expected CRC result should be 0xE62D but it is other value.

 

Regards,

Bharath R

>>once i load the dummy data to DR register example 0x3412, as per CRC-16 CCITT, polynomial 0x1021, the expected CRC result should be 0xE62D but it is other value.

What is "other value" in this context? Might help to unpack what's happening CRC's highly dependent on bit ordering and shift direction

The value is going to depend on the feed direction and byte ordering.

If the bytes expected on the wire are 0x12, 0x34

*((volatile uint8_t *)&SPI1->DR) = 0x12; // Might want to check TXE set first

*((volatile uint8_t *)&SPI1->DR) = 0x34;

Might expect 0x13C6 computed for MSB first. For the reverse byte order 0xFB22

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Other value means it's not same, it is changing every time.

I'm checking the TXCRCR register in the debug mode,

after line 3, TXCRCR will become 0x0000.

after line 4, TXCRCR register should be 0x0000 - is my understanding right?

after line 5, TXCRCR register should update to 0x13C6 for MSB first.

 

Thank you