17 #ifndef MBED_CRC_API_H 18 #define MBED_CRC_API_H 20 #include "drivers/internal/TableCRC.h" 21 #include "hal/crc_api.h" 22 #include "platform/mbed_assert.h" 23 #include "platform/SingletonPtr.h" 24 #include "platform/PlatformMutex.h" 33 #if defined ( __CC_ARM ) 34 #pragma diag_suppress 62 // Shift count is negative 35 #elif defined ( __GNUC__ ) 36 #pragma GCC diagnostic push 37 #pragma GCC diagnostic ignored "-Wshift-count-negative" 38 #elif defined (__ICCARM__) 39 #pragma diag_suppress=Pe062 // Shift count is negative 109 template <u
int32_t polynomial = POLY_32BIT_ANSI, u
int8_t w
idth = 32>
121 typedef uint64_t crc_data_size_t;
138 MbedCRC(uint32_t initial_xor, uint32_t final_xor,
bool reflect_data,
bool reflect_remainder) :
139 _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data),
140 _reflect_remainder(reflect_remainder)
159 int32_t
compute(
const void *buffer, crc_data_size_t size, uint32_t *crc)
218 status = table_compute_partial(buffer, size, crc);
221 status = bitwise_compute_partial(buffer, size, crc);
246 if (_mode == HARDWARE) {
250 config.
width = width;
260 *crc = _initial_value;
278 if (_mode == HARDWARE) {
279 *crc = hal_crc_get_result();
284 uint32_t p_crc = *crc;
285 if ((width < 8) && (NULL == _crc_table)) {
286 p_crc = (uint32_t)(p_crc << (8 - width));
290 *crc = (p_crc ^ _final_xor) & get_crc_mask();
292 *crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask();
316 #if !defined(DOXYGEN_ONLY) 318 uint32_t _initial_value;
321 bool _reflect_remainder;
322 uint32_t *_crc_table;
330 if (_mode == HARDWARE) {
331 mbed_crc_mutex->
lock();
338 virtual void unlock()
341 if (_mode == HARDWARE) {
351 uint8_t get_data_size(
void)
const 353 return (width <= 8 ? 1 : (width <= 16 ? 2 : 4));
361 uint32_t get_top_bit(
void)
const 363 return (width < 8 ? (1u << 7) : (uint32_t)(1ul << (width - 1)));
370 uint32_t get_crc_mask(
void)
const 372 return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
380 uint32_t reflect_remainder(uint32_t data)
const 382 if (_reflect_remainder) {
383 uint32_t reflection = 0x0;
384 uint8_t
const nBits = (width < 8 ? 8 : width);
386 for (uint8_t bit = 0; bit < nBits; ++bit) {
388 reflection |= (1 << ((nBits - 1) - bit));
403 uint32_t reflect_bytes(uint32_t data)
const 406 uint32_t reflection = 0x0;
408 for (uint8_t bit = 0; bit < 8; ++bit) {
410 reflection |= (1 << (7 - bit));
427 int32_t bitwise_compute_partial(
const void *buffer, crc_data_size_t size, uint32_t *crc)
const 431 const uint8_t *data =
static_cast<const uint8_t *
>(buffer);
432 uint32_t p_crc = *crc;
436 for (crc_data_size_t byte = 0; byte < size; byte++) {
437 data_byte = reflect_bytes(data[byte]);
438 for (uint8_t bit = 8; bit > 0; --bit) {
440 if ((data_byte ^ p_crc) & get_top_bit()) {
447 for (crc_data_size_t byte = 0; byte < size; byte++) {
448 p_crc ^= (reflect_bytes(data[byte]) << (width - 8));
451 for (uint8_t bit = 8; bit > 0; --bit) {
452 if (p_crc & get_top_bit()) {
453 p_crc = (p_crc << 1) ^ polynomial;
455 p_crc = (p_crc << 1);
460 *crc = p_crc & get_crc_mask();
471 int32_t table_compute_partial(
const void *buffer, crc_data_size_t size, uint32_t *crc)
const 475 const uint8_t *data =
static_cast<const uint8_t *
>(buffer);
476 uint32_t p_crc = *crc;
477 uint8_t data_byte = 0;
480 uint8_t *crc_table = (uint8_t *)_crc_table;
481 for (crc_data_size_t byte = 0; byte < size; byte++) {
482 data_byte = reflect_bytes(data[byte]) ^ p_crc;
483 p_crc = crc_table[data_byte];
485 }
else if (width <= 16) {
486 uint16_t *crc_table = (uint16_t *)_crc_table;
487 for (crc_data_size_t byte = 0; byte < size; byte++) {
488 data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
489 p_crc = crc_table[data_byte] ^ (p_crc << 8);
492 uint32_t *crc_table = (uint32_t *)_crc_table;
494 for (crc_data_size_t i = 0; i < size; i++) {
495 p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 0)) & 0xf];
496 p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 4)) & 0xf];
499 for (crc_data_size_t byte = 0; byte < size; byte++) {
500 data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
501 p_crc = crc_table[data_byte] ^ (p_crc << 8);
505 *crc = p_crc & get_crc_mask();
512 void mbed_crc_ctor(
void)
520 config.
width = width;
533 switch (polynomial) {
535 _crc_table = (uint32_t *)Table_CRC_32bit_ANSI;
538 _crc_table = (uint32_t *)Table_CRC_32bit_Rev_ANSI;
541 _crc_table = (uint32_t *)Table_CRC_8bit_CCITT;
544 _crc_table = (uint32_t *)Table_CRC_7Bit_SD;
547 _crc_table = (uint32_t *)Table_CRC_16bit_CCITT;
550 _crc_table = (uint32_t *)Table_CRC_16bit_IBM;
556 _mode = (_crc_table != NULL) ? TABLE : BITWISE;
561 #if defined ( __CC_ARM ) 562 #elif defined ( __GNUC__ ) 563 #pragma GCC diagnostic pop 564 #elif defined (__ICCARM__)
int32_t compute(const void *buffer, crc_data_size_t size, uint32_t *crc)
Compute CRC for the data input Compute CRC performs the initialization, computation and collection of...
uint32_t get_polynomial(void) const
Get the current CRC polynomial.
uint32_t final_xor
Final xor value for the computation.
bool hal_crc_is_supported(const crc_mbed_config_t *config)
Determine if the current platform supports hardware CRC for given polynomial.
uint8_t get_width(void) const
Get the current CRC width.
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
Initialize the hardware CRC module with the given polynomial.
int32_t compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc)
Compute partial CRC for the data input.
uint32_t width
CRC Bit Width.
MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder)
Lifetime of CRC object.
int32_t compute_partial_start(uint32_t *crc)
Compute partial start, indicate start of partial computation.
CRC object provides CRC generation through hardware or software.
void hal_crc_compute_partial(const uint8_t *data, const size_t size)
Writes data to the current CRC module.
bool reflect_out
Reflect bits in final result before returning.
uint32_t polynomial
CRC Polynomial.
x31+x30+x29+x27+x26+x24+x23+x21+x20+x19+x15+x9+x8+x5
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
bool reflect_in
Reflect bits on input.
int32_t compute_partial_stop(uint32_t *crc)
Get the final CRC value of partial computation.
uint32_t initial_xor
Initial seed value for the computation.