Clive One

STM32F407 SPI - CRC_CALCULATION

Discussion created by Clive One on Jan 9, 2017
Latest reply on Jan 9, 2017 by Clive One

This is a discussion started on the Keil forum, I'm bring it here because it is of more general interest, and I can edit and respond to things here better

 

STM32F407 SPI - CRC_CALCULATION 

 

Here is a software implementation of the CRC-15 used by the LTC6804

http://cds.linear.com/docs/en/datasheet/680412fc.pdf 

 

//****************************************************************************
// CRC15 LTC6804 x15+x14+x10+x8+x7+x4+x3+1
//  http://cds.linear.com/docs/en/datasheet/680412fc.pdf
// Implementation Copyright (C) 2017 sourcer32@gmail.com All Rights Reserved
//****************************************************************************

#include <windows.h>

#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;

//****************************************************************************

uint16_t CRC15_Slow(uint16_t crc, uint8_t data)
{
  int i;

  crc = crc ^ ((uint16_t)data << 7);

  for(i=0; i<8; i++)
  {
    if (crc & 0x4000)
      crc = (crc << 1) ^ 0xC599; // 4599, but has added benefit of clearing high order bit
    else
      crc <<= 1;
  }

  return(crc);
}

//****************************************************************************

uint16_t CRC15_Quick(uint16_t crc, uint8_t data)
{
  static const uint16_t CRCTable[16] = { // LTC6804 15-bit CRC Polynomial x15+x14+x10+x8+x7+x4+x3+1
    0x0000,0x4599,0x4EAB,0x0B32,0x58CF,0x1D56,0x1664,0x53FD, // 0xC599 nibble table - sourcer32@gmail.com
    0x7407,0x319E,0x3AAC,0x7F35,0x2CC8,0x6951,0x6263,0x27FA };

  crc = crc ^ ((uint16_t)data << 7); // Align and apply data byte

  crc = (crc << 4) ^ CRCTable[(crc >> 11) & 0xF]; // Apply CRC 4-bits at a time, 2 rounds
  crc = (crc << 4) ^ CRCTable[(crc >> 11) & 0xF];

  return(crc);
}

//****************************************************************************

int main(int argc, char **argv)
{
  uint16_t crc;

  crc = 0x0010; // Initial state, per manual
  crc = CRC15_Slow(crc, 0x00); // Apply 0x0001 as two bytes, msb first
  crc = CRC15_Slow(crc, 0x01);
  printf("%04X\n", crc << 1); // 0x3D6E, per manual shift into most significant 15-bit, clearing the least

  crc = 0x0010;  // Initial state, per manual
  crc = CRC15_Quick(crc, 0x00); // Apply 0x0001 as two bytes, msb first
  crc = CRC15_Quick(crc, 0x01);
  printf("%04X\n", crc << 1); // 0x3D6E, per manual shift into most significant 15-bit, clearing the least

  return(1);
}

//****************************************************************************

Outcomes