Skip to main content
Visitor II
October 30, 2023
Question

CRC-16 implementation to transmit via SPI bus in stm32L151

  • October 30, 2023
  • 2 replies
  • 1706 views

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

    This topic has been closed for replies.

    2 replies

    Super User
    October 30, 2023

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

    How do you know?

    JW

    Graduate II
    October 30, 2023

    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.

    BR1Author
    Visitor II
    October 30, 2023

    @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

    Graduate II
    October 30, 2023

    >>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