/* FastCRC library code is placed under the MIT license * Copyright (c) 2014-2019 Frank Bösing * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ // // HW-calculations are 32BIT // // Thanks to: // - Catalogue of parametrised CRC algorithms, CRC RevEng // http://reveng.sourceforge.net/crc-catalogue/ // // - Danjel McGougan (CRC-Table-Generator) // #include "Arduino.h" #if defined(KINETISK) #include "mk20dx128.h" #include "FastCRC.h" // =============================================== typedef struct { union { uint32_t CRC; //CRC Data register struct { uint16_t CRC16; uint16_t CRC16_1; }; struct { uint8_t CRC8; uint8_t CRC8_1; uint8_t CRC8_2; uint8_t CRC8_3; }; }; uint32_t GPOLY; //CRC Polynomial register uint32_t CTRL; //CRC Control register } CRC_T; static volatile CRC_T * const rCRC = (CRC_T *)0x40032000; #define CRC_CTRL_WAS 25 // Write CRC Data Register As Seed(1) / Data(0) #define CRC_CTRL_TCRC 24 // Width of CRC protocol (0=16 BIT, 1=32 BIT) #define CRC_CTRL_TOTR1 29 // TOTR[1] // ================= 7-BIT CRC =================== /** Constructor * Enables CRC-clock */ FastCRC7::FastCRC7(){ SIM_SCGC6 |= SIM_SCGC6_CRC; } /** CRC 7 * MultiMediaCard interface * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint8_t FastCRC7::crc7(const uint8_t *data, const uint16_t datalen) { // poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75 return (generic(0x09, 0, CRC_FLAG_NOREFLECT, data, datalen)); } /** Update * Call for subsequent calculations with previous seed * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint8_t FastCRC7::update(const uint8_t *data, const uint16_t datalen) { const uint8_t *src = data; const uint8_t *target = src + datalen; while (((uintptr_t)src & 0x03) != 0 && (src < target)) { rCRC->CRC8_3 = *src++; //Write 8 BIT } while (src <= target-4) { rCRC->CRC = *( uint32_t *)src; //Write 32 BIT src += 4; } while (src < target) { rCRC->CRC8_3 = *src++; //Write 8 Bit } //TODO: Check handling of CRC_CTRL_TOTR1 for other CRC7s /* if (rCRC->CTRL & (1<CRC8 >> 1; else */ return rCRC->CRC8_3 >> 1; } /** generic function for all 7-Bit CRCs * @param polynom Polynom * @param seed Seed * @param flags Flags * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint8_t FastCRC7::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const uint16_t datalen) { rCRC->CTRL = flags | (1<GPOLY = ((uint32_t)polynom)<<(24 + 1); // Set polynom rCRC->CRC = ((uint32_t)seed<<(24 + 1)); // Write seed rCRC->CTRL = flags | (1<CRC8_3 = *src++; //Write 8 BIT } while (src <= target-4) { rCRC->CRC = *( uint32_t *)src; //Write 32 BIT src += 4; } while (src < target) { rCRC->CRC8_3 = *src++; //Write 8 Bit } if (rCRC->CTRL & (1<CRC8; else return rCRC->CRC8_3; } /** generic function for all 8-Bit CRCs * @param polynom Polynom * @param seed Seed * @param flags Flags * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint8_t FastCRC8::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const uint16_t datalen) { rCRC->CTRL = flags | (1<GPOLY = ((uint32_t)polynom)<<24; // Set polynom rCRC->CRC = ((uint32_t)seed<<24); // Write seed rCRC->CTRL = flags | (1<CRC8_3 = *src++; //Write 8 BIT } while (src <= target-4) { rCRC->CRC = *( uint32_t *)src; //Write 32 BIT src += 4; } while (src < target) { rCRC->CRC8_3 = *src++; //Write 8 Bit } if (rCRC->CTRL & (1<CRC16; else return rCRC->CRC >> (32 - 14); } /** generic function for all 14-Bit CRCs * @param polynom Polynom * @param seed Seed * @param flags Flags * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint16_t FastCRC14::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen) { rCRC->CTRL = flags | (1<GPOLY = ((uint32_t)polynom) << (32 - 14); // set polynom rCRC->CRC = ((uint32_t)seed << (32 - 14) ); // this is the seed rCRC->CTRL = flags | (1<CRC8_3 = *src++; //Write 8 BIT } while (src <= target-4) { rCRC->CRC = *( uint32_t *)src; //Write 32 BIT src += 4; } while (src < target) { rCRC->CRC8_3 = *src++; //Write 8 Bit } if (rCRC->CTRL & (1<CRC16; else return rCRC->CRC16_1; } /** generic function for all 16-Bit CRCs * @param polynom Polynom * @param seed Seed * @param flags Flags * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint16_t FastCRC16::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen) { rCRC->CTRL = flags | (1<GPOLY = ((uint32_t)polynom)<<16; // set polynom rCRC->CRC = ((uint32_t)seed<<16); // this is the seed rCRC->CTRL = flags | (1<CRC8_3 = *src++; //Write 8 BIT } while (src <= target-4) { rCRC->CRC = *( uint32_t *)src; //Write 32 BIT src += 4; } while (src < target) { rCRC->CRC8_3 = *src++; //Write 8 Bit } return rCRC->CRC; } /** generic function for all 32-Bit CRCs * @param polynom Polynom * @param seed Seed * @param flags Flags * @param data Pointer to Data * @param datalen Length of Data * @return CRC value */ uint32_t FastCRC32::generic(const uint32_t polynom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen) { rCRC->CTRL = flags | (1<GPOLY = polynom; // Set polynom rCRC->CRC = seed; // This is the seed rCRC->CTRL = flags | (1<