CRC32 Library for SAMD Microcontrollers (Arduino Zero, Adafruit Itsy Bitsy M0: ATSAMD21, Adafruit Metro M4: ATSAMD51, etc.)
Include and create the SAMD_CRC32 object.
#include <SAMD_CRC32.h>
// Create the CRC object
SAMD_CRC32 crc = SAMD_CRC32();
Provide a pointer to the data, the size of the data in bytes (multiple of 4 for hardware CRC, see Considerations), and a pointer to a variable to save the result to. Any addressable location is acceptable (program memory, ram, EEPROM, etc.).
uint32_t crc_result = 0;
crc.crc32(&data, sizeof(data), &crc_result);
// Result stored in crc_result
SAMD_CRC32();
: Object constructorvoid force_use_software_crc32(bool val);
: Sets whether or not to only use software CRCbool can_use_hardware_crc32();
: Gets whether or not hardware CRC can be used on this devicebool check_used_hardware_crc32();
: Gets whether or not the last CRC used hardware CRC (as opposed to software CRC)const char *get_hardware_status_msg();
: Gets the most recent CRC's status in message form (for printing)uint8_t get_hardware_status_code();
: Gets the most recent CRC's status codeconst char *decode_hardware_status_code(uint8_t code);
: Converts a CRC status code to message form (for printing)volatile uint8_t crc32(const void *data, size_t n_bytes, uint32_t *crc);
: Computes a CRC32, starting at the address of the provided data, ecompassingn_bytes
bytes. See Considerations.
Each time a CRC32 is calculated, status information is generated. Unless software CRC is disabled (see Precompiler Directives), a CRC will be calculated regardless of the status code. The status code illustrates whether or not hardware CRC was used, and if not, the reason.
Status codes are of type uint8_t
. Options are as defined in the ENUM hardware_crc_status
in the header file, and can take the following values:
OK
BUS_ERROR
NOT_WORD_ALIGNED
USER_FORCED_SOFTWARE
HARDWARE_NOT_SUPPORTED
HARDWARE_CRC32_IN_USE
A status code can be compared to these values in the following way:
uint8_t code = crc32(const void *data, size_t n_bytes, uint32_t *crc);
if ((hardware_crc_status)code == NOT_WORD_ALIGNED){
...
}
The following functions assist with status codes or status messages:
const char *get_hardware_status_msg();
: Gets the most recent CRC's status in message form (for printing)uint8_t get_hardware_status_code();
: Gets the most recent CRC's status codeconst char *decode_hardware_status_code(uint8_t code);
: Converts a CRC status code to message form (for printing)
There exists two precompiler directives that can be added to the header file to reduce the scope of this library. They are as follows:
#define SAMD_CRC32_NO_STATUS
SAMD_CRC32_NO_STATUS
: Removes status messages, status codes, and status helper functions (all features listed in Status Codes / Messages). Instead of the typical return codes, crc
will return a 0
if the hardware CRC implementation was used, or a 1
if software CRC was used. Using this directive will save about 24 bytes of program space, as well as some SRAM.
#define SAMD_CRC32_NO_SOFTWARE_CRC
SAMD_CRC32_NO_SOFTWARE_CRC
: Removes all software CRC support & code. If hardware CRC cannot be used (invalid length, bus error, etc.), no CRC will be calculated. Using this directive will save about 184 bytes of program space, as well as some SRAM.
The endian type of the device will make a difference for the CRC. In hardware, the CRC is calculated by stepping through memory directly. Note the endianness of the hardware you are using and note that you may have to flip the endianness of your data in order to get it to validate the CRC.
The SAMD hardware CRC32 implementation requires data to be in words of 32 bits (4 bytes). For example, calculating a 17 byte CRC32 with hardware would yield an erroneous CRC. In these cases where the data inputted to the CRC object is not 32-bit word aligned, the software CRC32 algorithm will be used instead.
When loaded to a device that does not have a supported CRC unit, a software CRC will be calculated instead. This is slower than the hardware CRC, but will work on most devices. The software algorithm was adapted from this source (Björn Samuelsson).
The hardware CRC32 implementation is about 10x faster than the included software CRC32 algorithm.
Speed tests using 96 bytes of empty data (as used in the examples):
Device | Hardware CRC32 | Software CRC32 |
---|---|---|
Adafruit Itsy Bitsy M0 (ATSAMD21, 48MHz) | 14.24μs/crc | 161.54μs/crc |
Teensy 3.6 (MK66FX1M0VMD18, 180MHz) | -- | 25.92μs/crc |
Arduino Nano (ATMega328P, 16MHz) | -- | 1164.31us/crc |
Arduino Pro Mini (ATMega328P, 8MHz) | -- | 2328.64us/crc |