123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- #ifndef MBED_CRC_API_H
- #define MBED_CRC_API_H
- #include "drivers/TableCRC.h"
- #include "hal/crc_api.h"
- #include "platform/mbed_assert.h"
- #if defined ( __CC_ARM )
- #pragma diag_suppress 62
- #elif defined ( __GNUC__ )
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wshift-count-negative"
- #elif defined (__ICCARM__)
- #pragma diag_suppress=Pe062
- #endif
- namespace mbed {
- template <uint32_t polynomial = POLY_32BIT_ANSI, uint8_t width = 32>
- class MbedCRC {
- public:
- enum CrcMode { HARDWARE = 0, TABLE, BITWISE };
- public:
- typedef uint64_t crc_data_size_t;
-
- MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder) :
- _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data),
- _reflect_remainder(reflect_remainder), _crc_table(NULL)
- {
- mbed_crc_ctor();
- }
- MbedCRC();
- virtual ~MbedCRC()
- {
-
- }
-
- int32_t compute(void *buffer, crc_data_size_t size, uint32_t *crc)
- {
- MBED_ASSERT(crc != NULL);
- int32_t status;
- if (0 != (status = compute_partial_start(crc))) {
- *crc = 0;
- return status;
- }
- if (0 != (status = compute_partial(buffer, size, crc))) {
- *crc = 0;
- return status;
- }
- if (0 != (status = compute_partial_stop(crc))) {
- *crc = 0;
- return status;
- }
- return 0;
- }
-
- int32_t compute_partial(void *buffer, crc_data_size_t size, uint32_t *crc)
- {
- switch (_mode) {
- case HARDWARE:
- #ifdef DEVICE_CRC
- hal_crc_compute_partial((uint8_t *)buffer, size);
- #endif
- *crc = 0;
- return 0;
- case TABLE:
- return table_compute_partial(buffer, size, crc);
- case BITWISE:
- return bitwise_compute_partial(buffer, size, crc);
- }
- return -1;
- }
-
- int32_t compute_partial_start(uint32_t *crc)
- {
- MBED_ASSERT(crc != NULL);
- #ifdef DEVICE_CRC
- if (_mode == HARDWARE) {
- crc_mbed_config_t config;
- config.polynomial = polynomial;
- config.width = width;
- config.initial_xor = _initial_value;
- config.final_xor = _final_xor;
- config.reflect_in = _reflect_data;
- config.reflect_out = _reflect_remainder;
- hal_crc_compute_partial_start(&config);
- }
- #endif
- *crc = _initial_value;
- return 0;
- }
-
- int32_t compute_partial_stop(uint32_t *crc)
- {
- MBED_ASSERT(crc != NULL);
- if (_mode == HARDWARE) {
- #ifdef DEVICE_CRC
- *crc = hal_crc_get_result();
- return 0;
- #else
- return -1;
- #endif
- }
- uint32_t p_crc = *crc;
- if ((width < 8) && (NULL == _crc_table)) {
- p_crc = (uint32_t)(p_crc << (8 - width));
- }
- *crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask();
- return 0;
- }
-
- uint32_t get_polynomial(void) const
- {
- return polynomial;
- }
-
- uint8_t get_width(void) const
- {
- return width;
- }
- private:
- uint32_t _initial_value;
- uint32_t _final_xor;
- bool _reflect_data;
- bool _reflect_remainder;
- uint32_t *_crc_table;
- CrcMode _mode;
-
- uint8_t get_data_size(void) const
- {
- return (width <= 8 ? 1 : (width <= 16 ? 2 : 4));
- }
-
- uint32_t get_top_bit(void) const
- {
- return (width < 8 ? (1u << 7) : (uint32_t)(1ul << (width - 1)));
- }
-
- uint32_t get_crc_mask(void) const
- {
- return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
- }
-
- uint32_t reflect_remainder(uint32_t data) const
- {
- if (_reflect_remainder) {
- uint32_t reflection = 0x0;
- uint8_t const nBits = (width < 8 ? 8 : width);
- for (uint8_t bit = 0; bit < nBits; ++bit) {
- if (data & 0x01) {
- reflection |= (1 << ((nBits - 1) - bit));
- }
- data = (data >> 1);
- }
- return (reflection);
- } else {
- return data;
- }
- }
-
- uint32_t reflect_bytes(uint32_t data) const
- {
- if (_reflect_data) {
- uint32_t reflection = 0x0;
- for (uint8_t bit = 0; bit < 8; ++bit) {
- if (data & 0x01) {
- reflection |= (1 << (7 - bit));
- }
- data = (data >> 1);
- }
- return (reflection);
- } else {
- return data;
- }
- }
-
- int32_t bitwise_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
- {
- MBED_ASSERT(crc != NULL);
- MBED_ASSERT(buffer != NULL);
- const uint8_t *data = static_cast<const uint8_t *>(buffer);
- uint32_t p_crc = *crc;
- if (width < 8) {
- uint8_t data_byte;
- for (crc_data_size_t byte = 0; byte < size; byte++) {
- data_byte = reflect_bytes(data[byte]);
- for (uint8_t bit = 8; bit > 0; --bit) {
- p_crc <<= 1;
- if ((data_byte ^ p_crc) & get_top_bit()) {
- p_crc ^= polynomial;
- }
- data_byte <<= 1;
- }
- }
- } else {
- for (crc_data_size_t byte = 0; byte < size; byte++) {
- p_crc ^= (reflect_bytes(data[byte]) << (width - 8));
-
- for (uint8_t bit = 8; bit > 0; --bit) {
- if (p_crc & get_top_bit()) {
- p_crc = (p_crc << 1) ^ polynomial;
- } else {
- p_crc = (p_crc << 1);
- }
- }
- }
- }
- *crc = p_crc & get_crc_mask();
- return 0;
- }
-
- int32_t table_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
- {
- MBED_ASSERT(crc != NULL);
- MBED_ASSERT(buffer != NULL);
- const uint8_t *data = static_cast<const uint8_t *>(buffer);
- uint32_t p_crc = *crc;
- uint8_t data_byte = 0;
- if (width <= 8) {
- uint8_t *crc_table = (uint8_t *)_crc_table;
- for (crc_data_size_t byte = 0; byte < size; byte++) {
- data_byte = reflect_bytes(data[byte]) ^ p_crc;
- p_crc = crc_table[data_byte];
- }
- } else if (width <= 16) {
- uint16_t *crc_table = (uint16_t *)_crc_table;
- for (crc_data_size_t byte = 0; byte < size; byte++) {
- data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
- p_crc = crc_table[data_byte] ^ (p_crc << 8);
- }
- } else {
- uint32_t *crc_table = (uint32_t *)_crc_table;
- for (crc_data_size_t byte = 0; byte < size; byte++) {
- data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
- p_crc = crc_table[data_byte] ^ (p_crc << 8);
- }
- }
- *crc = p_crc & get_crc_mask();
- return 0;
- }
-
- void mbed_crc_ctor(void)
- {
- MBED_STATIC_ASSERT(width <= 32, "Max 32-bit CRC supported");
- _mode = (_crc_table != NULL) ? TABLE : BITWISE;
- #ifdef DEVICE_CRC
- crc_mbed_config_t config;
- config.polynomial = polynomial;
- config.width = width;
- config.initial_xor = _initial_value;
- config.final_xor = _final_xor;
- config.reflect_in = _reflect_data;
- config.reflect_out = _reflect_remainder;
- if (hal_crc_is_supported(&config)) {
- _mode = HARDWARE;
- }
- #endif
- }
- };
- #if defined ( __CC_ARM )
- #elif defined ( __GNUC__ )
- #pragma GCC diagnostic pop
- #elif defined (__ICCARM__)
- #endif
- }
- #endif
|