cancel
Showing results for 
Search instead for 
Did you mean: 

Use stm32 crc to compare DS18B20 crc

Flour Beur
Associate II
Posted on February 25, 2018 at 11:10

Hello friend,

I have DS18B20. And I read his uniq ID with CRC.

And I know, that STM has crc calculator. 

So I read data from DS18B20:

  • 0xab 0x1 0x4b 0x46 0x7f 0xff 0x5 0x10 :

    CRC 0x92

And I use internal calculator on this datas.

But result is wrong, because I get:

0x19

And you can see 0x92 is different from 0x19.

For example:

read ID with CRC.

uint8_t *p = ds18b20_read_serial_number();

And CRC calculation:

uint8_t test_crc = CRC_Calculate8(p, 8, 1);

Any idea, what is wrong?

Here is function to calc CRC in STM32F767zi.

uint32_t CRC_Calculate8(uint8_t* arr, uint32_t count, uint8_t reset)

{

/* Reset CRC data register if necessary */

if (reset) {

/* Reset generator */

LL_CRC_ResetCRCCalculationUnit(CRC); //CRC->CR = CRC_CR_RESET;

}

/* Calculate CRC */

while (count--) {

/* Set new value */

LL_CRC_FeedData8(CRC, *arr++); //CRC->DR = *arr++;

}

/* Return data */

return LL_CRC_ReadData8(CRC); //CRC->DR;

}

#crc
9 REPLIES 9
Posted on February 25, 2018 at 11:51

They use a different polynomial, width or shift direction?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Flour Beur
Associate II
Posted on February 25, 2018 at 11:53

Ok. And can I recalculate to good value (for example some mask)?

Or I must sw calculating?
Posted on February 25, 2018 at 15:34

The hardware might be able to do it, but you likely spend as much time setting things up as doing the computation.

Here is an efficient 4-bit table implementation in software

// Dallas 1-Wire CRC Test App -

mailto:sourcer32@gmail.com

//  x^8 + x^5 + x^4 + 1 0x8C (0x131)

//  Right Shift

//  Initialized to Zero

uint8_t Crc8CQuick(uint8_t Crc, int Size, uint8_t *Buffer)

{

  static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C

    0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8, //

mailto:sourcer32@gmail.com

    0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 };

  while(Size--)

  {

    Crc ^= *Buffer++; // Apply Data

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];

  }

  return(Crc);

}

uint8_t Crc8CSlow(uint8_t Crc, int Size, uint8_t *Buffer)

{

  int i;

  while(Size--)

  {

    Crc ^= *Buffer++; // Apply Data

    for (i=0; i<8; i++) // 1-bit at a time

      if (Crc & 0x01)

        Crc = (Crc >> 1) ^ 0x8C; // Polynomial used in Dallas 1-Wire

      else

        Crc = (Crc >> 1);

  }

  return(Crc);

}

void test(void)

{

  uint8_t data[] = { // Supplied Test Data Vector

    0xab,0x01,0x4b,0x46,0x7f,0xff,0x05,0x10 }; // 0x92

  printf('%02X test\n', Crc8CQuick(0x00, sizeof(data), data));

  printf('%02X test\n', Crc8CSlow(0x00, sizeof(data), data));

}

Sorry about the formatting, will post a formatted version below but it will sit in moderation for a while.

Edit: Pastes better in FireFox than Chrome, will try a LL implementation later

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 25, 2018 at 15:41

I thought so. So I calculate CRC with the same result with this function:

♯ define CRC8INIT 0x00

♯ define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0

uint8_t ds18b20_crc8( uint8_t *data, uint16_t number_of_bytes_in_data )

{

   uint8_t crc;

   uint16_t loop_count;

   uint8_t bit_counter;

   uint8_t b;

   uint8_t feedback_bit;

   crc = CRC8INIT;

   for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++)

   {

      b = data[loop_count];

      bit_counter = 8;

      do {

            feedback_bit = (crc ^ b) & 0x01;

            if ( feedback_bit == 0x01 )

            {

                  crc = crc ^ CRC8POLY;

            }

            crc = (crc >> 1) & 0x7F;

            if ( feedback_bit == 0x01 )

            {

               crc = crc | 0x80;

            }

            b = b >> 1;

            bit_counter--;

      } while (bit_counter > 0);

   }

   return crc;

}
Posted on February 25, 2018 at 15:47

I think my implementation will spank that for speed

Even the slower serial version I have will be faster and smaller

uint8_t Crc8CSlow(uint8_t Crc, int Size, uint8_t *Buffer)

{

  int i;

  while(Size--)

  {

    Crc ^= *Buffer++; // Apply Data

    for (i=0; i<8; i++) // 1-bit at a time

      if (Crc & 0x01)

        Crc = (Crc >> 1) ^ 0x8C; // Polynomial used in Dallas 1-Wire

      else

        Crc = (Crc >> 1);

  }

  return(Crc);

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 25, 2018 at 15:55

// Dallas 1-Wire CRC Test App - sourcer32@gmail.com

//  x^8 + x^5 + x^4 + 1 0x8C (0x18C)

//  Right Shift

//  Initialized to Zero

uint8_t Crc8CQuick(uint8_t Crc, int Size, uint8_t *Buffer)

{

  static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C

    0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8, // sourcer32@gmail.com

    0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 };

  while(Size--)

  {

    Crc ^= *Buffer++; // Apply Data

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];

  }

  return(Crc);

}

uint8_t Crc8CSlow(uint8_t Crc, int Size, uint8_t *Buffer)

{

  int i;

  while(Size--)

  {

    Crc ^= *Buffer++; // Apply Data

    for (i=0; i<8; i++) // 1-bit at a time

      if (Crc & 0x01)

        Crc = (Crc >> 1) ^ 0x8C; // Polynomial used in Dallas 1-Wire

      else

        Crc = (Crc >> 1);

  }

  return(Crc);

}

void test(void)

{

  uint8_t data[] = { // Supplied Test Data Vector

    0xab,0x01,0x4b,0x46,0x7f,0xff,0x05,0x10 }; // 0x92

  printf('%02X test\n', Crc8CQuick(0x00, sizeof(data), data));

  printf('%02X test\n', Crc8CSlow(0x00, sizeof(data), data));

}

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

�

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 25, 2018 at 17:04

// Dallas 1-wire CRC using STM32 hardware on models supporting user defined settings

// Bit more hacky than I'd like, rough framework lifted from

//  STM32Cube_FW_F7_V1.8.0\Projects\STM32F767ZI-Nucleo\Examples_LL\CRC\CRC_UserDefinedPolynomial

// CliveOne -

mailto:sourcer32@gmail.com

#include 'stm32f7xx_ll_bus.h'

#include 'stm32f7xx_ll_crc.h'

#define  CRC8_POLYNOMIAL_VALUE 0x31 // 0x8C poly reversed (STM32 left shifts)

/* Test vector */

static const uint8_t aDataBuffer[] = {

  0xab,0x01,0x4b,0x46,0x7f,0xff,0x05,0x10 }; // 0x92

/* Expected CRC Value */

uint8_t ubExpectedCRCValue = 0x92;

/* Used for storing CRC Value */

uint8_t ubCRCValue = 0;

/**

  * @brief  This function configures CRC Instance.

  * @note   This function is used to :

  *         -1- Enable peripheral clock for CRC.

  *         -2- Configure CRC functional parameters.

  * @note   Peripheral configuration is minimal configuration from reset values.

  *         Thus, some useless LL unitary functions calls below are provided as

  *         commented examples - setting is default configuration from reset.

  * @param  None

  * @retval None

  */

void Configure_CRC(void)

{

  /* (1) Enable peripheral clock for CRC                   *********************/

  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);

  /* (2) Configure CRC functional parameters  ********************************/

  /* Configure CRC calculation unit with user defined polynomial value, 8-bit long */

  LL_CRC_SetPolynomialCoef(CRC, CRC8_POLYNOMIAL_VALUE);

  LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_8B);

  LL_CRC_SetInitialData(CRC, 0); // ZERO

  LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_WORD); // STM32 backward

  LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_BIT); // reverse bit order on read

}

/**

  * @brief  This function performs CRC calculation on BufferSize bytes from input data buffer aDataBuffer.

  * @param  BufferSize Nb of bytes to be processed for CRC calculation

  * @retval 8-bit CRC value computed on input data buffer

  */

uint8_t Calculate_CRC(uint32_t BufferSize, uint8_t *Buffer)

{

  register uint32_t data = 0;

  register uint32_t index = 0;

  /* Compute the CRC of Data Buffer array*/

  for(index=0; index < (BufferSize / 4); index++)

  {

    data = (uint32_t)((Buffer[4 * index + 3] << 24) | (Buffer[4 * index + 2] << 16) | (Buffer[4 * index + 1] << 8) | Buffer[4 * index]);

    LL_CRC_FeedData32(CRC, data);

  }

  /* Last bytes specific handling */

  if ((BufferSize % 4) != 0)

  {

    if (BufferSize % 4 == 1)

    {

      LL_CRC_FeedData8(CRC, Buffer[4 * index]);

    }

    if (BufferSize % 4 == 2)

    {

      LL_CRC_FeedData16(CRC, (uint16_t)((Buffer[4 * index + 1]<<8) | Buffer[4 * index]));

    }

    if (BufferSize % 4 == 3)

    {

      LL_CRC_FeedData16(CRC, (uint16_t)((Buffer[4 * index + 1]<<8) | Buffer[4 * index]));

      LL_CRC_FeedData8(CRC, Buffer[4 * index + 2]);

    }

  }

  /* Return computed CRC value */

  return(LL_CRC_ReadData8(CRC));

}

/**

  * @brief  Check CRC computation result value.

  * @param  None

  * @retval None

  */

void CheckCRCResultValue(void)

{

  printf('CRC:%02X (%02X)\n', ubCRCValue, ubExpectedCRCValue);

  /* Compare the CRC value to the Expected one */

  if (ubCRCValue != ubExpectedCRCValue)

    puts('CRC **FAILED**');

  else

    puts('CRC Passed');

}

void Test(void)

{

  /* Configure CRC (CRC IP configuration using user-defined Polynomial value) */

  Configure_CRC();

  /* Perform CRC calculation on data contained in aDataBuffer */

  ubCRCValue = Calculate_CRC(sizeof(aDataBuffer), aDataBuffer);

  /* Check if CRC computed result value is equal to expected one */

  CheckCRCResultValue();

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 25, 2018 at 17:23

It is look like fantastic.

I'm trying it tomorrow. Thank you. 

i forgot to examples in CubeMX.

Posted on February 25, 2018 at 17:36

The HAL/Cube examples for the LL are pretty sparse. The above could be coded more efficiently.

I built the test framework on an STM32F746G-DISCO

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