cancel
Showing results for 
Search instead for 
Did you mean: 

CRC16 CCITT/AUG bad CRC generation

RCata
Associate III

Hi guys,

I am testing the CRC hardware of the STM32F722ZE in the NUCLEO board, but doesn't get a right result.

The CRC keys are: Poly=0x1021 and INIT value=0x1D0F

My two data input of 16-bit wide is: [0]=0x0031 [1]=0x0032.

Some CRC calculators gives 0xEA94, but STM32 gives 0x5197

My code:

// config

   CRC->INIT=0x1D0F;            // init value

   CRC->POL=0x1021;            // Poly

   CRC->CR=0x0008;               // No reverses. 16-bit poly

// calculating function:

   uint16_t val;

   CRC->CR|=CRC_CR_RESET;      // Reset

   while (length>0)

   {

      val=*data;

      CRC->DR=val;

      data++;

      length--;

   }

What I am doing wrong ? Thak you!

And another question.. Why CRC module and DMA aren't connected directly without need interrupts ?

References - Some CRC calculators:

http://www.tahapaksu.com/crc/

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

5 REPLIES 5

>>What I am doing wrong ? 

Try writing the data at the right width

*((volatile uint16_t *)&CRC->DR)=val;

Other than that you'd need to get more involved in the bit/byte ordering. I've posted several CRC related examples.

>>And another question.. Why CRC module and DMA aren't connected directly without need interrupts ?

Can't it just memory-to-memory via DMA2?

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

OMG! Thank you very much! That it works!. May in the datasheet or in the AN's could notify that.

STM32F7 have buffer and stall mechanism to prevent overrun. Are you suggesting directly a DMA memory(buffer) to memory(CRC->DR) transfers without waitings?

Regards

I don't recall the CRC unit having a DMA trigger source, so one could use a TIM on the same bus, or simply memory-to-memory where the destination was 16-bit (half-word) and non-incrementing.

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

Thanks mate, I will try this.

Clive, your idea is working. Thanks for your help!

This is the code for the people:

// CRC machine config:

//-----------------------------------------------------

   CRC->INIT=0x1D0F;            // init value

   CRC->POL=0x1021;            // Poy

   CRC->CR=0x0008;               // no reverses, 16-bit poly

// DMA2 Stream2 Channel 2 config:

//-----------------------------------------------------

   DMA2_Stream2->CR&=~DMA_SxCR_EN;        

   DMA2_Stream2->CR=0x04002A80;                     // Stream2 Channel2, No burst, low priority, no double buffer, no circular, #MEM 16b no inc (CRC->DR), @PERI 16b inc(I2CBUF), MEM->MEM, DMA flow controller, no ints

   DMA2_Stream2->M0AR=(uint32_t)&CRC->DR;

// No other parameters need to config. Must be configured in working function

// Working function

uint16_t crc16(uint16_t *data, uint16_t length)

{

   CRC->CR|=CRC_CR_RESET;                         // module reset

   DMA2_Stream2->PAR=(uint32_t)data;          // peripheral is source

   DMA2_Stream2->NDTR=length;                 // Num bytes transferred = 2*NDTR

   DMA2->LIFCR|=0x003F0000;                       // Lower int flags

   DMA2_Stream2->CR|=DMA_SxCR_EN;             // Launch transfer

   while(DMA2_Stream2->CR&DMA_SxCR_EN);   // Wait while working (for testing)

   return(CRC->DR & 0xFFFF);

}