diff --git a/libraries/CRC/CRC12.cpp b/libraries/CRC/CRC12.cpp index 64a689e4..09645c69 100644 --- a/libraries/CRC/CRC12.cpp +++ b/libraries/CRC/CRC12.cpp @@ -14,6 +14,20 @@ CRC12::CRC12() } +CRC12::CRC12(uint16_t polynome, uint16_t XORstart, uint16_t XORend, bool reverseIn, bool reverseOut) +{ + _polynome = polynome; + _startMask = XORstart; + _endMask = XORend; + _reverseIn = reverseIn; + _reverseOut = reverseOut; + _crc = 0; + _started = false; + _count = 0; + _canYield = true; +} + + void CRC12::reset() { _polynome = CRC12_DEFAULT_POLYNOME; diff --git a/libraries/CRC/CRC12.h b/libraries/CRC/CRC12.h index 8235afe3..07a19fd7 100644 --- a/libraries/CRC/CRC12.h +++ b/libraries/CRC/CRC12.h @@ -1,6 +1,4 @@ #pragma once -#ifndef CRC12_H -#define CRC12_H // // FILE: CRC12.h // AUTHOR: Rob Tillaart @@ -18,6 +16,7 @@ class CRC12 { public: CRC12(); + CRC12(uint16_t polynome, uint16_t XORstart, uint16_t XORend, bool reverseIn, bool reverseOut); // set parameters to default void reset(); // set all to constructor defaults @@ -40,12 +39,12 @@ public: void add(uint8_t value); void add(const uint8_t * array, uint16_t length); - uint16_t getCRC(); // returns CRC - uint32_t count() { return _count; }; + uint16_t getCRC(); // returns CRC + uint32_t count() { return _count; }; // POWER USER ONLY - void enableYield() { _canYield = true; }; - void disableYield() { _canYield = false; }; + void enableYield() { _canYield = true; }; + void disableYield() { _canYield = false; }; private: uint16_t _reverse(uint16_t value); @@ -65,4 +64,4 @@ private: // -- END OF FILE -- -#endif + diff --git a/libraries/CRC/CRC16.cpp b/libraries/CRC/CRC16.cpp index f05a297f..cb465ee3 100644 --- a/libraries/CRC/CRC16.cpp +++ b/libraries/CRC/CRC16.cpp @@ -14,6 +14,20 @@ CRC16::CRC16() } +CRC16::CRC16(uint16_t polynome, uint16_t XORstart, uint16_t XORend, bool reverseIn, bool reverseOut) +{ + _polynome = polynome; + _startMask = XORstart; + _endMask = XORend; + _reverseIn = reverseIn; + _reverseOut = reverseOut; + _crc = 0; + _started = false; + _count = 0; + _canYield = true; +} + + void CRC16::reset() { _polynome = CRC16_DEFAULT_POLYNOME; diff --git a/libraries/CRC/CRC16.h b/libraries/CRC/CRC16.h index 97361c2e..9796b62d 100644 --- a/libraries/CRC/CRC16.h +++ b/libraries/CRC/CRC16.h @@ -1,6 +1,4 @@ #pragma once -#ifndef CRC16_H -#define CRC16_H // // FILE: CRC16.h // AUTHOR: Rob Tillaart @@ -17,6 +15,7 @@ class CRC16 { public: CRC16(); + CRC16(uint16_t polynome, uint16_t XORstart, uint16_t XORend, bool reverseIn, bool reverseOut); // set parameters to default void reset(); // set all to constructor defaults @@ -39,12 +38,12 @@ public: void add(uint8_t value); void add(const uint8_t * array, uint16_t length); - uint16_t getCRC(); // returns CRC - uint32_t count() { return _count; }; + uint16_t getCRC(); // returns CRC + uint32_t count() { return _count; }; // POWER USER ONLY - void enableYield() { _canYield = true; }; - void disableYield() { _canYield = false; }; + void enableYield() { _canYield = true; }; + void disableYield() { _canYield = false; }; private: uint16_t _reverse(uint16_t value); @@ -64,4 +63,4 @@ private: // -- END OF FILE -- -#endif + diff --git a/libraries/CRC/CRC32.cpp b/libraries/CRC/CRC32.cpp index b3814b46..4b4a031d 100644 --- a/libraries/CRC/CRC32.cpp +++ b/libraries/CRC/CRC32.cpp @@ -14,6 +14,20 @@ CRC32::CRC32() } +CRC32::CRC32(uint32_t polynome, uint32_t XORstart, uint32_t XORend, bool reverseIn, bool reverseOut) +{ + _polynome = polynome; + _startMask = XORstart; + _endMask = XORend; + _reverseIn = reverseIn; + _reverseOut = reverseOut; + _crc = 0; + _started = false; + _count = 0; + _canYield = true; +} + + void CRC32::reset() { _polynome = CRC32_DEFAULT_POLYNOME; diff --git a/libraries/CRC/CRC32.h b/libraries/CRC/CRC32.h index 101fc497..c5170755 100644 --- a/libraries/CRC/CRC32.h +++ b/libraries/CRC/CRC32.h @@ -1,6 +1,4 @@ #pragma once -#ifndef CRC32_H -#define CRC32_H // // FILE: CRC32.h // AUTHOR: Rob Tillaart @@ -17,6 +15,7 @@ class CRC32 { public: CRC32(); + CRC32(uint32_t polynome, uint32_t XORstart, uint32_t XORend, bool reverseIn, bool reverseOut); // set parameters to default void reset(); // set all to constructor defaults @@ -39,12 +38,12 @@ public: void add(uint8_t value); void add(const uint8_t * array, uint16_t length); - uint32_t getCRC(); // returns CRC - uint32_t count() { return _count; }; + uint32_t getCRC(); // returns CRC + uint32_t count() { return _count; }; // POWER USER ONLY - void enableYield() { _canYield = true; }; - void disableYield() { _canYield = false; }; + void enableYield() { _canYield = true; }; + void disableYield() { _canYield = false; }; private: uint32_t _reverse(uint32_t value); @@ -64,4 +63,4 @@ private: // -- END OF FILE -- -#endif + diff --git a/libraries/CRC/CRC64.cpp b/libraries/CRC/CRC64.cpp index 74a4c3d2..a7d85584 100644 --- a/libraries/CRC/CRC64.cpp +++ b/libraries/CRC/CRC64.cpp @@ -14,6 +14,20 @@ CRC64::CRC64() } +CRC64::CRC64(uint64_t polynome, uint64_t XORstart, uint64_t XORend, bool reverseIn, bool reverseOut) +{ + _polynome = polynome; + _startMask = XORstart; + _endMask = XORend; + _reverseIn = reverseIn; + _reverseOut = reverseOut; + _crc = 0; + _started = false; + _count = 0; + _canYield = true; +} + + void CRC64::reset() { _polynome = CRC64_DEFAULT_POLYNOME; diff --git a/libraries/CRC/CRC64.h b/libraries/CRC/CRC64.h index ea14037a..68628c3b 100644 --- a/libraries/CRC/CRC64.h +++ b/libraries/CRC/CRC64.h @@ -1,6 +1,4 @@ #pragma once -#ifndef CRC64_H -#define CRC64_H // // FILE: CRC64.h // AUTHOR: Rob Tillaart @@ -17,6 +15,7 @@ class CRC64 { public: CRC64(); + CRC64(uint64_t polynome, uint64_t XORstart, uint64_t XORend, bool reverseIn, bool reverseOut); // set parameters to default void reset(); // set all to constructor defaults @@ -39,12 +38,12 @@ public: void add(uint8_t value); void add(const uint8_t * array, uint16_t length); - uint64_t getCRC(); // returns CRC - uint64_t count() { return _count; }; + uint64_t getCRC(); // returns CRC + uint64_t count() { return _count; }; // POWER USER ONLY - void enableYield() { _canYield = true; }; - void disableYield() { _canYield = false; }; + void enableYield() { _canYield = true; }; + void disableYield() { _canYield = false; }; private: uint64_t _reverse(uint64_t value); @@ -64,4 +63,3 @@ private: // -- END OF FILE -- -#endif diff --git a/libraries/CRC/CRC8.cpp b/libraries/CRC/CRC8.cpp index f8f09d19..5c28e4f0 100644 --- a/libraries/CRC/CRC8.cpp +++ b/libraries/CRC/CRC8.cpp @@ -14,6 +14,20 @@ CRC8::CRC8() } +CRC8::CRC8(uint8_t polynome, uint8_t XORstart, uint8_t XORend, bool reverseIn, bool reverseOut) +{ + _polynome = polynome; + _startMask = XORstart; + _endMask = XORend; + _reverseIn = reverseIn; + _reverseOut = reverseOut; + _crc = 0; + _started = false; + _count = 0; + _canYield = true; +} + + void CRC8::reset() { _polynome = CRC8_DEFAULT_POLYNOME; diff --git a/libraries/CRC/CRC8.h b/libraries/CRC/CRC8.h index bd6db2b5..c7b9e1ef 100644 --- a/libraries/CRC/CRC8.h +++ b/libraries/CRC/CRC8.h @@ -1,6 +1,4 @@ #pragma once -#ifndef CRC8_H -#define CRC8_H // // FILE: CRC8.h // AUTHOR: Rob Tillaart @@ -17,6 +15,7 @@ class CRC8 { public: CRC8(); + CRC8(uint8_t polynome, uint8_t XORstart, uint8_t XORend, bool reverseIn, bool reverseOut); // set parameters to default void reset(); // set all to constructor defaults @@ -39,12 +38,12 @@ public: void add(uint8_t value); void add(const uint8_t * array, uint16_t length); - uint8_t getCRC(); // returns CRC - uint32_t count() { return _count; }; + uint8_t getCRC(); // returns CRC + uint32_t count() { return _count; }; // POWER USER ONLY - void enableYield() { _canYield = true; }; - void disableYield() { _canYield = false; }; + void enableYield() { _canYield = true; }; + void disableYield() { _canYield = false; }; private: uint8_t _reverse(uint8_t value); @@ -63,4 +62,4 @@ private: // -- END OF FILE -- -#endif + diff --git a/libraries/CRC/README.md b/libraries/CRC/README.md index 3756a6a3..3d3d1e8b 100644 --- a/libraries/CRC/README.md +++ b/libraries/CRC/README.md @@ -16,30 +16,31 @@ Arduino library with CRC8, CRC12, CRC16, CRC32 and CRC64 functions. Goal of this library is to have a flexible and portable set of generic CRC functions and classes. -The CRCx classes have a number of added values. Most important is that -they allow one to verify intermediate CRC values. This is useful if one -sends a "train of packets" which include a CRC so far. This detects both -errors in one packet but also missing packets, or injected packages. +The CRCx classes have a number of added values. +Most important is that they allow one to verify intermediate CRC values. +This is useful if one sends a "train of packets" which include a CRC so far. +This detects both errors in one single packet but also optional missing packets, +or even injected packets. -Another trick one can do is change the polynome or the reverse flag during -the process. This makes it harder to imitate. +Another trick one can do with the class CRCx is to change the polynome or +the reverse flag runtime during the process. This makes it harder to imitate. Furthermore the class allows to add values in single steps and continue too. -Finally the class version gives more readable code (imho) as the parameters +Finally the class version gives more readable code (IMHO) as the parameters are explicitly set. **Note** the classes have same names as the static functions, except the class -is UPPER case. So CRC8 is a class and **crc8()** is the function. +is UPPER case. So **CRC8** is a class and **crc8()** is the function. -Deeper tech info -https://en.wikipedia.org/wiki/Cyclic_redundancy_check +Deeper tech info - https://en.wikipedia.org/wiki/Cyclic_redundancy_check and many other websites. ## Interface CRC classes -These interfaces are very similar for CRC8, CRC12, CRC16, CRC32 and CRC64 class. +The interfaces are very similar for CRC8, CRC12, CRC16, CRC32 and CRC64 class. The only difference is the data type for polynome, start- and end-mask, and the returned CRC. @@ -48,8 +49,9 @@ and the returned CRC. Use **\#include "CRC8.h"** -- **CRC8()** Constructor. -- **void reset()** set all internals to constructor defaults. +- **CRC8()** default - parameterless - constructor. +- **CRC8(polynome, XORstart, XORend, reverseIn, reverseOut)** Constructor to set all parameters at once. +- **void reset()** set all internals to defaults of the **CRC8()** parameterless constructor. - **void restart()** reset internal CRC and count only; reuse values for other e.g polynome, XOR masks and reverse flags. - **void add(value)** add a single value to CRC calculation. @@ -62,7 +64,7 @@ a really large stream at intermediate moments, e.g. to link multiple packets. #### parameters -These parameters do not have defaults so the user must set them explicitly. +The parameters do not have defaults so the user must set them explicitly. - **void setPolynome(polynome)** set polynome, note reset sets a default polynome. - **void setStartXOR(start)** set start-mask, default 0. @@ -92,6 +94,9 @@ to handle interrupts etc. So use at own risk. _Note: the static functions in this library also call **yield()** but this cannot be disabled (for now)._ +_Note: a parameter could be a future option to set the number of adds before +**yield()** is called. **setYield(0)** would be disable it._ + ### Example snippet @@ -163,17 +168,20 @@ See examples. - https://en.wikipedia.org/wiki/Cyclic_redundancy_check - generic background. - http://zorc.breitbandkatze.de/crc.html - online CRC calculator (any base up to 64 is supported.) - https://crccalc.com/ - online CRC calculator to verify. +- https://www.lddgo.net/en/encrypt/crc - online CRC calculator ## Future - extend examples. - example showing multiple packages of data linked by their CRC. -- table versions for performance? (performance - memory discussion) +- table versions for performance? (performance - memory discussion). - stream version - 4 classes class? - **setCRC(value)** to be able to pick up where one left ? - can be done with **setStartXOR()** - - needs **getRawCRC()** without reverse and endmask + - needs **getRawCRC()** without reverse and end mask +- Think about default parameters for constructor **CRC8(polynome, XORstart, XORend, reverseIn, reverseOut)** + - same as reset so constructors merge? Note the CRC-functions do have defaults too. #### Exotic CRC's ? @@ -184,6 +192,8 @@ See examples. - One CRC() with #bits as parameter? - up to 64 bit for all missing ones.? - performance penalty +- One CRC() template class? + #### Won't diff --git a/libraries/CRC/library.json b/libraries/CRC/library.json index f15c0515..e010dcd6 100644 --- a/libraries/CRC/library.json +++ b/libraries/CRC/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/CRC" }, - "version": "0.3.0", + "version": "0.3.1", "license": "MIT", "frameworks": "arduino", "platforms": "*", diff --git a/libraries/CRC/library.properties b/libraries/CRC/library.properties index a91cf59c..eec88e67 100644 --- a/libraries/CRC/library.properties +++ b/libraries/CRC/library.properties @@ -1,5 +1,5 @@ name=CRC -version=0.3.0 +version=0.3.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library for CRC for Arduino diff --git a/libraries/CRC/releaseNotes.md b/libraries/CRC/releaseNotes.md index 4d708dfd..addd4fb0 100644 --- a/libraries/CRC/releaseNotes.md +++ b/libraries/CRC/releaseNotes.md @@ -1,6 +1,16 @@ # Release Notes +## 0.3.1 2022-05-20 + +- added constructors with all parameters. + CRC16(uint16_t polynome, uint16_t XORstart, uint16_t XORend, bool reverseIn, bool reverseOut); + All five parameters are mandatory, no defaults in this first release. + Defaults would allow the constructors merge in the future. +- remove #ifndef Header guards as these are not needed. +- update documentation + + ## 0.3.0 2022-04-15 - split CRC.h in CRC.h and CRC.cpp to fix #21 (again) diff --git a/libraries/CRC/test/unit_test_crc12.cpp b/libraries/CRC/test/unit_test_crc12.cpp index 7b88d539..629fd634 100644 --- a/libraries/CRC/test/unit_test_crc12.cpp +++ b/libraries/CRC/test/unit_test_crc12.cpp @@ -88,6 +88,15 @@ unittest(test_crc12) } +unittest(test_crc12_param) +{ + fprintf(stderr, "TEST CRC12\n"); + + CRC12 crc(0x080D, 0, 0, false, false); + crc.add(data, 9); + assertEqual(0xEFB, crc.getCRC()); +} + unittest_main() diff --git a/libraries/CRC/test/unit_test_crc16.cpp b/libraries/CRC/test/unit_test_crc16.cpp index 852d1c92..3e6e4dd0 100644 --- a/libraries/CRC/test/unit_test_crc16.cpp +++ b/libraries/CRC/test/unit_test_crc16.cpp @@ -304,6 +304,16 @@ unittest(test_crc16) } +unittest(test_crc16_param) +{ + fprintf(stderr, "TEST CRC16 PARAM\n"); + + CRC16 crc(0x1021, 0xFFFF, 0, false, false); + crc.add(data, 9); + assertEqual(0x29B1, crc.getCRC()); +} + + unittest_main() // -------- diff --git a/libraries/CRC/test/unit_test_crc32.cpp b/libraries/CRC/test/unit_test_crc32.cpp index e2b4bcb5..727a282c 100644 --- a/libraries/CRC/test/unit_test_crc32.cpp +++ b/libraries/CRC/test/unit_test_crc32.cpp @@ -180,6 +180,16 @@ unittest(test_crc32) } +unittest(test_crc32_param) +{ + fprintf(stderr, "TEST CRC32 PARAM\n"); + + CRC32 crc(0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true); + crc.add(data, 9); + assertEqual(0xCBF43926, crc.getCRC()); +} + + unittest_main() // -------- diff --git a/libraries/CRC/test/unit_test_crc64.cpp b/libraries/CRC/test/unit_test_crc64.cpp index 14702702..25f2004b 100644 --- a/libraries/CRC/test/unit_test_crc64.cpp +++ b/libraries/CRC/test/unit_test_crc64.cpp @@ -84,6 +84,20 @@ unittest(test_crc64) } +unittest(test_crc64_param) +{ + fprintf(stderr, "TEST CRC64 PARAM\n"); + + fprintf(stderr, "no reference yet\n"); + assertEqual(1, 1); + + // just a dummy test + CRC64 crc(0x04C11DB704C11DB7, 0, 0, false, false); + crc.add(data, 9); + assertEqual(0xCE5CA2AD34A16112, crc.getCRC()); // 14869938934466568466 +} + + unittest_main() // -------- diff --git a/libraries/CRC/test/unit_test_crc8.cpp b/libraries/CRC/test/unit_test_crc8.cpp index 3959d482..9d640d30 100644 --- a/libraries/CRC/test/unit_test_crc8.cpp +++ b/libraries/CRC/test/unit_test_crc8.cpp @@ -150,6 +150,16 @@ unittest(test_crc8) } +unittest(test_crc8_param) +{ + fprintf(stderr, "TEST CRC8 PARAM\n"); + + CRC8 crc(0x07, 0, 0, false, false); + crc.add(data, 9); + assertEqual(0xF4, crc.getCRC()); +} + + unittest_main() // --------