mirror of https://github.com/ARMmbed/mbed-os.git
Revise MbedCRC template
* Use compile-time detection of hardware CRC capability, so unneeded code and tables do not go into the image. * Add global JSON config option to allow choice between no tables, 16-entry tables or 256-entry tables for software CRC. Default set to 16-entry, reducing ROM size from previous 256-entry. * Allow manual override in template parameter to force software or bitwise CRC for a particular instance. * Micro-optimisations, particularly use of `RBIT` instruction and optimising bitwise computation using inline assembler. Incompatible changes: * Remove special-case "POLY_32BIT_REV_ANSI" - users can use standard POLY_32BIT_ANSI, which now uses the same 16-entry tables by default, or can use hardware acceleration, which was disabled for POLY_32BIT_REV_ANSI. MbedCRC<POLY_32BIT_ANSI, 32, CrcMode::TABLE> can be used to force software like POLY_32BIT_REV_ANSI. * The precomputed table for POLY_16BIT_IBM had errors - this has been corrected, but software CRC results will be different from the previous software calculation. * < 8-bit CRC results are no longer are shifted up in the output value, but placed in the lowest bits, like other sizes. This means that code performing the SD command CRC will now need to use `(crc << 1) | 1`, rather than `crc | 1`.pull/11957/head
parent
fe22bc023e
commit
a995c162ac
|
@ -25,32 +25,62 @@ using namespace utest::v1;
|
|||
|
||||
void test_supported_polynomials()
|
||||
{
|
||||
char test[] = "123456789";
|
||||
const char test[] = "123456789";
|
||||
uint32_t crc;
|
||||
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xEA, crc);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x75, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0x7F, 0, false, false);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x50, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0x2B, 0, false, false);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x3A, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0x7F, false, false);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x0A, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0x2B, false, false);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x5E, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0, true, false);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x52, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0, false, true);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x57, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_8BIT_CCITT, 8> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xF4, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_16BIT_CCITT, 16> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0x29B1, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_16BIT_IBM, 16> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xBB3D, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<POLY_32BIT_ANSI, 32> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xCBF43926, crc);
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +92,8 @@ void test_partial_crc()
|
|||
{
|
||||
MbedCRC<POLY_16BIT_CCITT, 16> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial_start(&crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test, 4, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test[4], 5, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial(test, 4, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial_stop(&crc));
|
||||
|
||||
TEST_ASSERT_EQUAL(0x29B1, crc);
|
||||
|
@ -81,8 +111,8 @@ void test_sd_crc()
|
|||
test[2] = 0x00;
|
||||
test[3] = 0x00;
|
||||
test[4] = 0x00;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
|
||||
crc = (crc | 0x1) & 0xFF;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
|
||||
crc = (crc << 1) | 0x1;
|
||||
TEST_ASSERT_EQUAL(0x95, crc);
|
||||
|
||||
test[0] = 0x48;
|
||||
|
@ -90,8 +120,8 @@ void test_sd_crc()
|
|||
test[2] = 0x00;
|
||||
test[3] = 0x01;
|
||||
test[4] = 0xAA;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
|
||||
crc = (crc | 0x1) & 0xFF;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
|
||||
crc = (crc << 1) | 0x1;
|
||||
TEST_ASSERT_EQUAL(0x87, crc);
|
||||
|
||||
test[0] = 0x51;
|
||||
|
@ -99,13 +129,13 @@ void test_sd_crc()
|
|||
test[2] = 0x00;
|
||||
test[3] = 0x00;
|
||||
test[4] = 0x00;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
|
||||
crc = (crc | 0x1) & 0xFF;
|
||||
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
|
||||
crc = (crc << 1) | 0x1;
|
||||
TEST_ASSERT_EQUAL(0x55, crc);
|
||||
|
||||
MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false);
|
||||
memset(test, 0xFF, 512);
|
||||
TEST_ASSERT_EQUAL(0, crc16.compute((void *)test, 512, &crc));
|
||||
TEST_ASSERT_EQUAL(0, crc16.compute(test, 512, &crc));
|
||||
TEST_ASSERT_EQUAL(0x7FA1, crc);
|
||||
}
|
||||
|
||||
|
@ -115,12 +145,12 @@ void test_any_polynomial()
|
|||
uint32_t crc;
|
||||
{
|
||||
MbedCRC<0x3D65, 16> ct(0x0, 0xFFFF, 0, 0);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xC2B7, crc);
|
||||
}
|
||||
{
|
||||
MbedCRC<0x1EDC6F41, 32> ct(0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xE3069283, crc);
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +160,7 @@ void test_thread(void)
|
|||
char test[] = "123456789";
|
||||
uint32_t crc;
|
||||
MbedCRC<POLY_32BIT_ANSI, 32> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xCBF43926, crc);
|
||||
}
|
||||
|
||||
|
@ -143,11 +173,11 @@ void test_thread_safety()
|
|||
MbedCRC<POLY_16BIT_IBM, 16> ct;
|
||||
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial_start(&crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test, 4, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial(test, 4, &crc));
|
||||
|
||||
Thread t1(osPriorityNormal1, 380);
|
||||
t1.start(callback(test_thread));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test[4], 5, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute_partial_stop(&crc));
|
||||
TEST_ASSERT_EQUAL(0xBB3D, crc);
|
||||
|
||||
|
|
|
@ -14,3 +14,19 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include <stdint.h>
|
||||
static inline uint32_t __RBIT(uint32_t x)
|
||||
{
|
||||
x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);
|
||||
x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2);
|
||||
x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
|
||||
x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);
|
||||
x = (x >> 16) | (x << 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,27 +17,19 @@
|
|||
#ifndef MBED_CRC_API_H
|
||||
#define MBED_CRC_API_H
|
||||
|
||||
#include "drivers/internal/TableCRC.h"
|
||||
#include "cmsis.h"
|
||||
#include "hal/crc_api.h"
|
||||
#ifdef DEVICE_CRC
|
||||
#include "device.h"
|
||||
#endif
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
|
||||
/* This is an invalid warning from the compiler for the below section of code
|
||||
if ((width < 8) && (NULL == _crc_table)) {
|
||||
p_crc = (uint32_t)(p_crc << (8 - width));
|
||||
}
|
||||
Compiler warns of the shift operation with width as it is width=(std::uint8_t),
|
||||
but we check for ( width < 8) before performing shift, so it should not be an issue.
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#pragma diag_suppress 62 // Shift count is negative
|
||||
#elif defined ( __GNUC__ )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshift-count-negative"
|
||||
#elif defined (__ICCARM__)
|
||||
#pragma diag_suppress=Pe062 // Shift count is negative
|
||||
#endif
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers-public-api */
|
||||
|
@ -49,10 +41,49 @@ namespace mbed {
|
|||
|
||||
extern SingletonPtr<PlatformMutex> mbed_crc_mutex;
|
||||
|
||||
/** CRC mode selection
|
||||
*/
|
||||
enum class CrcMode {
|
||||
HARDWARE, /// Use hardware (if available), else table-based computation
|
||||
TABLE, /// Use table-based computation (if table available), else bitwise
|
||||
BITWISE /// Always use bitwise manual computation
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_ONLY
|
||||
namespace impl {
|
||||
template<uint32_t polynomial, uint8_t width, CrcMode mode>
|
||||
class MbedCRC;
|
||||
|
||||
constexpr bool have_crc_table(uint32_t polynomial, uint8_t width)
|
||||
{
|
||||
#if MBED_CRC_TABLE_SIZE > 0
|
||||
return (polynomial == POLY_32BIT_ANSI && width == 32) ||
|
||||
(polynomial == POLY_16BIT_IBM && width == 16) ||
|
||||
(polynomial == POLY_16BIT_CCITT && width == 16) ||
|
||||
(polynomial == POLY_8BIT_CCITT && width == 8) ||
|
||||
(polynomial == POLY_7BIT_SD && width == 7);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr CrcMode choose_crc_mode(uint32_t polynomial, uint8_t width, CrcMode mode_limit)
|
||||
{
|
||||
return
|
||||
#if DEVICE_CRC
|
||||
mode_limit == CrcMode::HARDWARE && HAL_CRC_IS_SUPPORTED(polynomial, width) ? CrcMode::HARDWARE :
|
||||
#endif
|
||||
mode_limit <= CrcMode::TABLE && have_crc_table(polynomial, width) ? CrcMode::TABLE :
|
||||
CrcMode::BITWISE;
|
||||
}
|
||||
#endif // DOXYGEN_ONLY
|
||||
|
||||
} // namespace impl
|
||||
|
||||
/** CRC object provides CRC generation through hardware or software
|
||||
*
|
||||
* CRC sums can be generated using three different methods: hardware, software ROM tables
|
||||
* and bitwise computation. The mode used is selected automatically based on required
|
||||
* and bitwise computation. The mode used is normally selected automatically based on required
|
||||
* polynomial and hardware capabilities. Any polynomial in standard form (`x^3 + x + 1`)
|
||||
* can be used for computation, but custom ones can affect the performance.
|
||||
*
|
||||
|
@ -62,10 +93,17 @@ extern SingletonPtr<PlatformMutex> mbed_crc_mutex;
|
|||
* configuration is supported, it will accelerate the software computations. If ROM tables
|
||||
* are not available for the selected polynomial, then CRC is computed at run time bit by bit
|
||||
* for all data input.
|
||||
*
|
||||
* If desired, the mode can be manually limited for a given instance by specifying the mode_limit
|
||||
* template parameter. This might be appropriate to ensure a table is not pulled in for a
|
||||
* non-speed-critical CRC, or to avoid the hardware set-up overhead if you know you will be
|
||||
* calling `compute` with very small data sizes.
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* @tparam polynomial CRC polynomial value in hex
|
||||
* @tparam width CRC polynomial width
|
||||
* @tparam width CRC polynomial width
|
||||
* @tparam mode_limit Maximum amount of acceleration to use
|
||||
*
|
||||
* Example: Compute CRC data
|
||||
* @code
|
||||
|
@ -106,23 +144,25 @@ extern SingletonPtr<PlatformMutex> mbed_crc_mutex;
|
|||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template <uint32_t polynomial = POLY_32BIT_ANSI, uint8_t width = 32>
|
||||
class MbedCRC {
|
||||
template <uint32_t polynomial = POLY_32BIT_ANSI, uint8_t width = 32, CrcMode mode_limit = CrcMode::HARDWARE>
|
||||
class MbedCRC {
|
||||
impl::MbedCRC<polynomial, width, impl::choose_crc_mode(polynomial, width, mode_limit)> crc_impl;
|
||||
|
||||
public:
|
||||
/* Backwards compatibility */
|
||||
enum CrcMode {
|
||||
#if DEVICE_CRC
|
||||
HARDWARE = 0,
|
||||
HARDWARE = int(::mbed::CrcMode::HARDWARE),
|
||||
#endif
|
||||
TABLE = 1,
|
||||
BITWISE
|
||||
TABLE = int(::mbed::CrcMode::TABLE),
|
||||
BITWISE = int(::mbed::CrcMode::BITWISE)
|
||||
};
|
||||
|
||||
typedef uint64_t crc_data_size_t;
|
||||
typedef size_t crc_data_size_t;
|
||||
|
||||
/** Lifetime of CRC object
|
||||
*
|
||||
* @param initial_xor Inital value/seed to Xor
|
||||
* @param initial_xor Initial value/seed to Xor
|
||||
* @param final_xor Final Xor value
|
||||
* @param reflect_data
|
||||
* @param reflect_remainder
|
||||
|
@ -132,20 +172,15 @@ public:
|
|||
* MbedCRC <POLY_16BIT_CCITT, 32> ct; --- Invalid, compilation error
|
||||
* MbedCRC <POLY_16BIT_CCITT, 32> ct (i,f,rd,rr) Constructor can be used for not supported polynomials
|
||||
* MbedCRC<POLY_16BIT_CCITT, 16> sd(0, 0, false, false); Constructor can also be used for supported
|
||||
* polynomials with different intial/final/reflect values
|
||||
* polynomials with different initial/final/reflect values
|
||||
*
|
||||
*/
|
||||
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_impl(initial_xor, final_xor, reflect_data, reflect_remainder)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
|
||||
MbedCRC();
|
||||
virtual ~MbedCRC()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/** Compute CRC for the data input
|
||||
* Compute CRC performs the initialization, computation and collection of
|
||||
|
@ -158,28 +193,7 @@ public:
|
|||
*/
|
||||
int32_t compute(const void *buffer, crc_data_size_t size, uint32_t *crc)
|
||||
{
|
||||
MBED_ASSERT(crc != NULL);
|
||||
int32_t status = 0;
|
||||
|
||||
status = compute_partial_start(crc);
|
||||
if (0 != status) {
|
||||
unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
status = compute_partial(buffer, size, crc);
|
||||
if (0 != status) {
|
||||
unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
status = compute_partial_stop(crc);
|
||||
if (0 != status) {
|
||||
*crc = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
return crc_impl.compute(buffer, size, crc);
|
||||
}
|
||||
|
||||
/** Compute partial CRC for the data input.
|
||||
|
@ -205,27 +219,7 @@ public:
|
|||
*/
|
||||
int32_t compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
switch (_mode) {
|
||||
#if DEVICE_CRC
|
||||
case HARDWARE:
|
||||
hal_crc_compute_partial(static_cast<const uint8_t *>(buffer), size);
|
||||
*crc = 0;
|
||||
break;
|
||||
#endif
|
||||
case TABLE:
|
||||
status = table_compute_partial(buffer, size, crc);
|
||||
break;
|
||||
case BITWISE:
|
||||
status = bitwise_compute_partial(buffer, size, crc);
|
||||
break;
|
||||
default:
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
return crc_impl.compute_partial(buffer, size, crc);
|
||||
}
|
||||
|
||||
/** Compute partial start, indicate start of partial computation.
|
||||
|
@ -240,10 +234,128 @@ public:
|
|||
*/
|
||||
int32_t compute_partial_start(uint32_t *crc)
|
||||
{
|
||||
MBED_ASSERT(crc != NULL);
|
||||
return crc_impl.compute_partial_start(crc);
|
||||
}
|
||||
|
||||
/** Get the final CRC value of partial computation.
|
||||
*
|
||||
* CRC value available in partial computation is not correct CRC, as some
|
||||
* algorithms require remainder to be reflected and final value to be XORed
|
||||
* This API is used to perform final computation to get correct CRC value.
|
||||
*
|
||||
* @param crc CRC result
|
||||
* @return 0 on success or a negative in case of failure.
|
||||
*/
|
||||
int32_t compute_partial_stop(uint32_t *crc)
|
||||
{
|
||||
return crc_impl.compute_partial_stop(crc);
|
||||
}
|
||||
|
||||
/** Get the current CRC polynomial.
|
||||
*
|
||||
* @return Polynomial value
|
||||
*/
|
||||
static constexpr uint32_t get_polynomial()
|
||||
{
|
||||
return polynomial;
|
||||
}
|
||||
|
||||
/** Get the current CRC width
|
||||
*
|
||||
* @return CRC width
|
||||
*/
|
||||
static constexpr uint8_t get_width()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN_ONLY)
|
||||
/* Internal implementation - basically same as public, but actual mode locked in */
|
||||
namespace impl {
|
||||
|
||||
template <uint32_t polynomial, uint8_t width, CrcMode mode>
|
||||
class MbedCRC {
|
||||
public:
|
||||
typedef size_t crc_data_size_t;
|
||||
|
||||
MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder) :
|
||||
_initial_value(adjust_initial_value(initial_xor, reflect_data)),
|
||||
_final_xor(final_xor),
|
||||
_reflect_data(reflect_data),
|
||||
_reflect_remainder(reflect_remainder)
|
||||
{
|
||||
static_assert(width <= 32, "Max 32-bit CRC supported");
|
||||
}
|
||||
|
||||
/** Compute CRC for the data input
|
||||
* Compute CRC performs the initialization, computation and collection of
|
||||
* final CRC.
|
||||
*
|
||||
* @param buffer Data bytes
|
||||
* @param size Size of data
|
||||
* @param crc CRC is the output value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int32_t compute(const void *buffer, crc_data_size_t size, uint32_t *crc)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
status = compute_partial_start(crc);
|
||||
if (0 != status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = compute_partial(buffer, size, crc);
|
||||
if (0 != status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = compute_partial_stop(crc);
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Compute partial CRC for the data input.
|
||||
*
|
||||
* CRC data if not available fully, CRC can be computed in parts with available data.
|
||||
*
|
||||
* In case of hardware, intermediate values and states are saved by hardware. Mutex
|
||||
* locking is used to serialize access to hardware CRC.
|
||||
*
|
||||
* In case of software CRC, previous CRC output should be passed as argument to the
|
||||
* current compute_partial call. Please note the intermediate CRC value is maintained by
|
||||
* application and not the driver.
|
||||
*
|
||||
* @pre: Call `compute_partial_start` to start the partial CRC calculation.
|
||||
* @post: Call `compute_partial_stop` to get the final CRC value.
|
||||
*
|
||||
* @param buffer Data bytes
|
||||
* @param size Size of data
|
||||
* @param crc CRC value is intermediate CRC value filled by API.
|
||||
* @return 0 on success or a negative error code on failure
|
||||
* @note: CRC as output in compute_partial is not final CRC value, call `compute_partial_stop`
|
||||
* to get final correct CRC value.
|
||||
*/
|
||||
int32_t compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc)
|
||||
{
|
||||
const uint8_t *data = static_cast<const uint8_t *>(buffer);
|
||||
return do_compute_partial(data, size, crc);
|
||||
}
|
||||
|
||||
/** Compute partial start, indicate start of partial computation.
|
||||
*
|
||||
* This API should be called before performing any partial computation
|
||||
* with compute_partial API.
|
||||
*
|
||||
* @param crc Initial CRC value set by the API
|
||||
* @return 0 on success or a negative in case of failure
|
||||
* @note: CRC is an out parameter and must be reused with compute_partial
|
||||
* and `compute_partial_stop` without any modifications in application.
|
||||
*/
|
||||
int32_t compute_partial_start(uint32_t *crc)
|
||||
{
|
||||
#if DEVICE_CRC
|
||||
if (_mode == HARDWARE) {
|
||||
if (mode == CrcMode::HARDWARE) {
|
||||
lock();
|
||||
crc_mbed_config_t config;
|
||||
config.polynomial = polynomial;
|
||||
|
@ -272,62 +384,143 @@ public:
|
|||
*/
|
||||
int32_t compute_partial_stop(uint32_t *crc)
|
||||
{
|
||||
MBED_ASSERT(crc != NULL);
|
||||
|
||||
#if DEVICE_CRC
|
||||
if (_mode == HARDWARE) {
|
||||
if (mode == CrcMode::HARDWARE) {
|
||||
*crc = hal_crc_get_result();
|
||||
unlock();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
uint32_t p_crc = *crc;
|
||||
if ((width < 8) && (NULL == _crc_table)) {
|
||||
p_crc = (uint32_t)(p_crc << (8 - width));
|
||||
uint_fast32_t p_crc = *crc;
|
||||
if (mode == CrcMode::BITWISE) {
|
||||
if (_reflect_data) {
|
||||
/* CRC has MSB in bottom bit of register */
|
||||
if (!_reflect_remainder) {
|
||||
p_crc = reflect_crc(p_crc);
|
||||
}
|
||||
} else {
|
||||
/* CRC has MSB in top bit of register */
|
||||
p_crc = _reflect_remainder ? reflect_register(p_crc) : shift_right(p_crc);
|
||||
}
|
||||
} else { // TABLE
|
||||
/* CRC has MSB in bottom bit of register */
|
||||
if (!_reflect_remainder) {
|
||||
p_crc = reflect_crc(p_crc);
|
||||
}
|
||||
}
|
||||
// Optimized algorithm for 32BitANSI does not need additional reflect_remainder
|
||||
if ((TABLE == _mode) && (POLY_32BIT_REV_ANSI == polynomial)) {
|
||||
*crc = (p_crc ^ _final_xor) & get_crc_mask();
|
||||
} else {
|
||||
*crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask();
|
||||
}
|
||||
unlock();
|
||||
|
||||
p_crc ^= _final_xor;
|
||||
p_crc &= get_crc_mask();
|
||||
*crc = p_crc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Get the current CRC polynomial.
|
||||
*
|
||||
* @return Polynomial value
|
||||
*/
|
||||
uint32_t get_polynomial(void) const
|
||||
{
|
||||
return polynomial;
|
||||
}
|
||||
|
||||
/** Get the current CRC width
|
||||
*
|
||||
* @return CRC width
|
||||
*/
|
||||
uint8_t get_width(void) const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN_ONLY)
|
||||
private:
|
||||
uint32_t _initial_value;
|
||||
uint32_t _final_xor;
|
||||
bool _reflect_data;
|
||||
bool _reflect_remainder;
|
||||
uint32_t *_crc_table;
|
||||
CrcMode _mode;
|
||||
/** Get the current CRC polynomial, reflected at bottom of register.
|
||||
*
|
||||
* @return Reflected polynomial value (so x^width term would be at bit -1)
|
||||
*/
|
||||
static constexpr uint32_t get_reflected_polynomial()
|
||||
{
|
||||
/* Doing this hard way to keep it C++11 constexpr and hence ARM C 5 compatible */
|
||||
return shift_right(((polynomial & 0x00000001) << 31) |
|
||||
((polynomial & 0x00000002) << 29) |
|
||||
((polynomial & 0x00000004) << 27) |
|
||||
((polynomial & 0x00000008) << 25) |
|
||||
((polynomial & 0x00000010) << 23) |
|
||||
((polynomial & 0x00000020) << 21) |
|
||||
((polynomial & 0x00000040) << 19) |
|
||||
((polynomial & 0x00000080) << 17) |
|
||||
((polynomial & 0x00000100) << 15) |
|
||||
((polynomial & 0x00000200) << 13) |
|
||||
((polynomial & 0x00000400) << 11) |
|
||||
((polynomial & 0x00000800) << 9) |
|
||||
((polynomial & 0x00001000) << 7) |
|
||||
((polynomial & 0x00002000) << 5) |
|
||||
((polynomial & 0x00004000) << 3) |
|
||||
((polynomial & 0x00008000) << 1) |
|
||||
((polynomial & 0x00010000) >> 1) |
|
||||
((polynomial & 0x00020000) >> 3) |
|
||||
((polynomial & 0x00040000) >> 5) |
|
||||
((polynomial & 0x00080000) >> 7) |
|
||||
((polynomial & 0x00100000) >> 9) |
|
||||
((polynomial & 0x00200000) >> 11) |
|
||||
((polynomial & 0x00400000) >> 13) |
|
||||
((polynomial & 0x00800000) >> 15) |
|
||||
((polynomial & 0x01000000) >> 17) |
|
||||
((polynomial & 0x02000000) >> 19) |
|
||||
((polynomial & 0x04000000) >> 21) |
|
||||
((polynomial & 0x08000000) >> 23) |
|
||||
((polynomial & 0x10000000) >> 25) |
|
||||
((polynomial & 0x20000000) >> 27) |
|
||||
((polynomial & 0x40000000) >> 29) |
|
||||
((polynomial & 0x80000000) >> 31));
|
||||
}
|
||||
|
||||
/** Get the current CRC polynomial, at top of register.
|
||||
*
|
||||
* @return Shifted polynomial value (so x^width term would be at bit 32)
|
||||
*/
|
||||
static constexpr uint32_t get_top_polynomial()
|
||||
{
|
||||
return shift_left(polynomial);
|
||||
}
|
||||
|
||||
const uint32_t _initial_value;
|
||||
const uint32_t _final_xor;
|
||||
const bool _reflect_data;
|
||||
const bool _reflect_remainder;
|
||||
|
||||
// *INDENT-OFF*
|
||||
using crc_table_t = std::conditional_t<width <= 8, uint8_t,
|
||||
std::conditional_t<width <= 16, uint16_t,
|
||||
uint32_t
|
||||
>>;
|
||||
// *INDENT-ON*
|
||||
|
||||
/* Not [MBED_CRC_TABLE_SIZE] as that could be [0], which is illegal.
|
||||
* We do need the declaration to always exist so that do_compute_partial<TABLE> is always well-formed,
|
||||
* but we never actually use it MBED_CRC_TABLE_SIZE is 0.
|
||||
*/
|
||||
static const crc_table_t _crc_table[];
|
||||
|
||||
static uint32_t adjust_initial_value(uint32_t initial_xor, bool reflect_data)
|
||||
{
|
||||
/* As initial_xor is almost certain to be constant all zeros or ones, try to
|
||||
* process that a constant, avoiding an RBIT instruction (or worse).
|
||||
*/
|
||||
if (initial_xor == 0 || initial_xor == (get_crc_mask() & -1U)) {
|
||||
/* Only possible adjustment is shifting to top for bitwise */
|
||||
if (mode == CrcMode::BITWISE && !reflect_data) {
|
||||
return shift_left(initial_xor);
|
||||
} else {
|
||||
return initial_xor;
|
||||
}
|
||||
}
|
||||
|
||||
/* Weird or non-constant initial value - need to think about reflection */
|
||||
if (mode == CrcMode::BITWISE) {
|
||||
/* For bitwise calculation, CRC register is reflected if data is, to match input.
|
||||
* (MSB at bottom of register). If not reflected, it is at the top of the register
|
||||
* (MSB at top of register).
|
||||
*/
|
||||
return reflect_data ? reflect_crc(initial_xor) : shift_left(initial_xor);
|
||||
} else if (mode == CrcMode::TABLE) {
|
||||
/* For table calculation, CRC value is reflected, to match tables.
|
||||
* (MSB at bottom of register). */
|
||||
return reflect_crc(initial_xor);
|
||||
} else { // CrcMode::HARDWARE
|
||||
return initial_xor;
|
||||
}
|
||||
}
|
||||
|
||||
/** Acquire exclusive access to CRC hardware/software.
|
||||
*/
|
||||
void lock()
|
||||
static void lock()
|
||||
{
|
||||
#if DEVICE_CRC
|
||||
if (_mode == HARDWARE) {
|
||||
if (mode == CrcMode::HARDWARE) {
|
||||
mbed_crc_mutex->lock();
|
||||
}
|
||||
#endif
|
||||
|
@ -335,88 +528,180 @@ private:
|
|||
|
||||
/** Release exclusive access to CRC hardware/software.
|
||||
*/
|
||||
virtual void unlock()
|
||||
static void unlock()
|
||||
{
|
||||
#if DEVICE_CRC
|
||||
if (_mode == HARDWARE) {
|
||||
if (mode == CrcMode::HARDWARE) {
|
||||
mbed_crc_mutex->unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Get the current CRC data size.
|
||||
*
|
||||
* @return CRC data size in bytes
|
||||
*/
|
||||
uint8_t get_data_size(void) const
|
||||
{
|
||||
return (width <= 8 ? 1 : (width <= 16 ? 2 : 4));
|
||||
}
|
||||
|
||||
/** Get the top bit of current CRC.
|
||||
*
|
||||
* @return Top bit is set high for respective data width of current CRC
|
||||
* Top bit for CRC width less then 8 bits will be set as 8th bit.
|
||||
*/
|
||||
uint32_t get_top_bit(void) const
|
||||
{
|
||||
return (width < 8 ? (1u << 7) : (uint32_t)(1ul << (width - 1)));
|
||||
}
|
||||
|
||||
/** Get the CRC data mask.
|
||||
*
|
||||
* @return CRC data mask is generated based on current CRC width
|
||||
*/
|
||||
uint32_t get_crc_mask(void) const
|
||||
static constexpr uint32_t get_crc_mask()
|
||||
{
|
||||
return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
|
||||
return (uint32_t)((uint32_t)2U << (width - 1)) - 1U;
|
||||
}
|
||||
|
||||
/** Final value of CRC is reflected.
|
||||
/** Data bytes may need to be reflected.
|
||||
*
|
||||
* @param data final crc value, which should be reflected
|
||||
* @return Reflected CRC value
|
||||
* @param data value to be reflected (bottom 8 bits)
|
||||
* @return Reflected value (bottom 8 bits)
|
||||
*/
|
||||
uint32_t reflect_remainder(uint32_t data) const
|
||||
static uint_fast32_t reflect_byte(uint_fast32_t data)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return __RBIT(data) >> 24;
|
||||
}
|
||||
|
||||
/** Data bytes are reflected.
|
||||
/** CRC values may need to be reflected.
|
||||
*
|
||||
* @param data value to be reflected
|
||||
* @return Reflected data value
|
||||
* @param CRC value to be reflected (width bits at bottom of 32-bit word)
|
||||
* @return Reflected value (still at bottom of 32-bit word)
|
||||
*/
|
||||
uint32_t reflect_bytes(uint32_t data) const
|
||||
static uint32_t reflect_crc(uint32_t data)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return __RBIT(data) >> (32 - width);
|
||||
}
|
||||
|
||||
/** Register values may need to be reflected.
|
||||
*
|
||||
* @param Register value to be reflected (full 32-bit value)
|
||||
* @return Reflected value (full 32-bit value)
|
||||
*/
|
||||
static uint32_t reflect_register(uint32_t data)
|
||||
{
|
||||
return __RBIT(data);
|
||||
}
|
||||
|
||||
/** Register values may need to be shifted left.
|
||||
*
|
||||
* @param Register value to be shifted up (in bottom width bits)
|
||||
* @return Shifted value (in top width bits)
|
||||
*/
|
||||
static constexpr uint32_t shift_left(uint32_t data)
|
||||
{
|
||||
return data << (32 - width);
|
||||
}
|
||||
|
||||
/** Register values may need to be shifted right.
|
||||
*
|
||||
* @param Register value to be shifted right (in top width bits)
|
||||
* @return Shifted value (in bottom width bits)
|
||||
*/
|
||||
static constexpr uint32_t shift_right(uint32_t data)
|
||||
{
|
||||
return data >> (32 - width);
|
||||
}
|
||||
|
||||
/* Check to see if we can do assembler optimizations */
|
||||
#if ((defined __GNUC__ || defined __clang__) && !defined __CC_ARM) && \
|
||||
(defined __arm__ || defined __ARM_ARCH)
|
||||
#if (__ARM_ARCH_7M__ == 1U) || \
|
||||
(__ARM_ARCH_7EM__ == 1U) || \
|
||||
(__ARM_ARCH_8M_MAIN__ == 1U) || \
|
||||
(__ARM_ARCH_7A__ == 1U)
|
||||
/* ARM that has Thumb-2 - same unified assembly is good for either ARM or Thumb state (LSRS; IT CS; EORCS reg/imm) */
|
||||
#define MBED_CRC_ARM_THUMB2 1
|
||||
#define MBED_CRC_THUMB1 0
|
||||
#elif (__ARM_ARCH_6M__ == 1U) || \
|
||||
(__ARM_ARCH_8M_BASE__ == 1U)
|
||||
/* Thumb-1-only ARM-M device - use Thumb-1 compatible assembly with branch (LSRS; BCC; EORS reg) */
|
||||
#define MBED_CRC_ARM_THUMB2 0
|
||||
#define MBED_CRC_THUMB1 1
|
||||
#else // __ARM_ARCH_xxx
|
||||
#error "Unknown ARM architecture for CRC optimization"
|
||||
#endif // __ARM_ARCH_xxx
|
||||
#else // __arm__ || defined __ICC_ARM__ || defined __ARM_ARCH
|
||||
/* Seem to be compiling for non-ARM, or an unsupported toolchain, so stick with C implementations */
|
||||
#define MBED_CRC_ARM_THUMB2 0
|
||||
#define MBED_CRC_THUMB1 0
|
||||
#endif
|
||||
|
||||
// *INDENT-OFF*
|
||||
/** Process 1 bit of non-reflected CRC
|
||||
*
|
||||
* Shift the p_crc register left 1 bit - if a one is shifted
|
||||
* out, exclusive-or with the polynomial mask.
|
||||
*
|
||||
* Assembler optimizations can be applied here, to make
|
||||
* use of the CPU's carry output from shifts.
|
||||
*
|
||||
* @param p_crc input register value
|
||||
* @return updated register value
|
||||
*/
|
||||
static uint_fast32_t do_1_bit_normal(uint_fast32_t p_crc)
|
||||
{
|
||||
#if MBED_CRC_ARM_THUMB2
|
||||
__asm(".syntax unified\n\t"
|
||||
"LSLS" "\t%[p_crc], %[p_crc], #1\n\t"
|
||||
"IT" "\tCS\n\t"
|
||||
"EORCS" "\t%[p_crc], %[poly]"
|
||||
: [p_crc] "+&r" (p_crc)
|
||||
: [poly] "rI" (get_top_polynomial())
|
||||
: "cc");
|
||||
#elif MBED_CRC_THUMB1
|
||||
__asm(".syntax unified\n\t"
|
||||
"LSLS" "\t%[p_crc], %[p_crc], #1\n\t"
|
||||
"BCC" "\t%=f\n\t"
|
||||
"EORS" "\t%[p_crc], %[poly]\n"
|
||||
"%=:"
|
||||
: [p_crc] "+&l" (p_crc)
|
||||
: [poly] "l" (get_top_polynomial())
|
||||
: "cc");
|
||||
#else
|
||||
if (p_crc & 0x80000000) {
|
||||
p_crc = (p_crc << 1) ^ get_top_polynomial();
|
||||
} else {
|
||||
p_crc = (p_crc << 1);
|
||||
}
|
||||
#endif
|
||||
return p_crc;
|
||||
}
|
||||
|
||||
/** Process 1 bit of reflected CRC
|
||||
*
|
||||
* Shift the p_crc register right 1 bit - if a one is shifted
|
||||
* out, exclusive-or with the polynomial mask.
|
||||
*
|
||||
* Assembler optimizations can be applied here, to make
|
||||
* use of the CPU's carry output from shifts.
|
||||
*
|
||||
* @param p_crc input register value
|
||||
* @return updated register value
|
||||
*/
|
||||
static uint_fast32_t do_1_bit_reflected(uint_fast32_t p_crc)
|
||||
{
|
||||
#if MBED_CRC_ARM_THUMB2
|
||||
__asm(".syntax unified\n\t"
|
||||
"LSRS" "\t%[p_crc], %[p_crc], #1\n\t"
|
||||
"IT" "\tCS\n\t"
|
||||
"EORCS" "\t%[p_crc], %[poly]"
|
||||
: [p_crc] "+&r" (p_crc)
|
||||
: [poly] "rI" (get_reflected_polynomial())
|
||||
: "cc");
|
||||
#elif MBED_CRC_THUMB1
|
||||
__asm(".syntax unified\n\t"
|
||||
"LSRS" "\t%[p_crc], %[p_crc], #1\n\t"
|
||||
"BCC" "\t%=f\n\t"
|
||||
"EORS" "\t%[p_crc], %[poly]\n"
|
||||
"%=:"
|
||||
: [p_crc] "+&l" (p_crc)
|
||||
: [poly] "l" (get_reflected_polynomial())
|
||||
: "cc");
|
||||
#else
|
||||
if (p_crc & 1) {
|
||||
p_crc = (p_crc >> 1) ^ get_reflected_polynomial();
|
||||
} else {
|
||||
p_crc = (p_crc >> 1);
|
||||
}
|
||||
#endif
|
||||
return p_crc;
|
||||
}
|
||||
// *INDENT-ON*
|
||||
|
||||
/** Bitwise CRC computation.
|
||||
*
|
||||
* @param buffer data buffer
|
||||
|
@ -424,40 +709,36 @@ private:
|
|||
* @param crc CRC value is filled in, but the value is not the final
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
int32_t bitwise_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
|
||||
template<CrcMode mode_ = mode>
|
||||
std::enable_if_t<mode_ == CrcMode::BITWISE, int32_t>
|
||||
do_compute_partial(const uint8_t *data, crc_data_size_t size, uint32_t *crc) const
|
||||
{
|
||||
MBED_ASSERT(crc != NULL);
|
||||
uint_fast32_t p_crc = *crc;
|
||||
|
||||
const uint8_t *data = static_cast<const uint8_t *>(buffer);
|
||||
uint32_t p_crc = *crc;
|
||||
|
||||
if (width < 8) {
|
||||
uint8_t data_byte;
|
||||
if (_reflect_data) {
|
||||
/* Everything is reflected to match data - MSB of polynomial at bottom of 32-bit register */
|
||||
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;
|
||||
p_crc ^= data[byte];
|
||||
|
||||
// Perform modulo-2 division, a bit at a time
|
||||
for (unsigned int bit = 8; bit > 0; --bit) {
|
||||
p_crc = do_1_bit_reflected(p_crc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Polynomial is shifted to put MSB of polynomial at top of 32-bit register */
|
||||
for (crc_data_size_t byte = 0; byte < size; byte++) {
|
||||
p_crc ^= (reflect_bytes(data[byte]) << (width - 8));
|
||||
p_crc ^= (uint_fast32_t) data[byte] << 24;
|
||||
|
||||
// Perform modulo-2 division, a bit at a time
|
||||
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);
|
||||
}
|
||||
for (unsigned int bit = 8; bit > 0; --bit) {
|
||||
p_crc = do_1_bit_normal(p_crc);
|
||||
}
|
||||
}
|
||||
}
|
||||
*crc = p_crc & get_crc_mask();
|
||||
|
||||
*crc = p_crc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -468,105 +749,92 @@ private:
|
|||
* @param crc CRC value is filled in, but the value is not the final
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
int32_t table_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
|
||||
template<CrcMode mode_ = mode>
|
||||
std::enable_if_t<mode_ == CrcMode::TABLE, int32_t>
|
||||
do_compute_partial(const uint8_t *data, crc_data_size_t size, uint32_t *crc) const
|
||||
{
|
||||
MBED_ASSERT(crc != NULL);
|
||||
uint_fast32_t p_crc = *crc;
|
||||
// GCC has been observed to not hoist the load of _reflect_data out of the loop
|
||||
// Note the inversion because table and CRC are reflected - data must be
|
||||
bool reflect = !_reflect_data;
|
||||
|
||||
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;
|
||||
if (POLY_32BIT_REV_ANSI == polynomial) {
|
||||
for (crc_data_size_t i = 0; i < size; i++) {
|
||||
p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 0)) & 0xf];
|
||||
p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 4)) & 0xf];
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
for (crc_data_size_t byte = 0; byte < size; byte++) {
|
||||
uint_fast32_t data_byte = data[byte];
|
||||
if (reflect) {
|
||||
data_byte = reflect_byte(data_byte);
|
||||
}
|
||||
#if MBED_CRC_TABLE_SIZE == 16
|
||||
p_crc = _crc_table[(data_byte ^ p_crc) & 0xF] ^ (p_crc >> 4);
|
||||
data_byte >>= 4;
|
||||
p_crc = _crc_table[(data_byte ^ p_crc) & 0xF] ^ (p_crc >> 4);
|
||||
#else
|
||||
p_crc = _crc_table[(data_byte ^ p_crc) & 0xFF] ^ (p_crc >> 8);
|
||||
#endif
|
||||
}
|
||||
*crc = p_crc & get_crc_mask();
|
||||
*crc = p_crc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Constructor init called from all specialized cases of constructor.
|
||||
* Note: All constructor common code should be in this function.
|
||||
#ifdef DEVICE_CRC
|
||||
/** Hardware CRC computation.
|
||||
*
|
||||
* @param buffer data buffer
|
||||
* @param size size of the data
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
void mbed_crc_ctor(void)
|
||||
template<CrcMode mode_ = mode>
|
||||
std::enable_if_t<mode_ == CrcMode::HARDWARE, int32_t>
|
||||
do_compute_partial(const uint8_t *data, crc_data_size_t size, uint32_t *) const
|
||||
{
|
||||
MBED_STATIC_ASSERT(width <= 32, "Max 32-bit CRC supported");
|
||||
|
||||
#if DEVICE_CRC
|
||||
if (POLY_32BIT_REV_ANSI != polynomial) {
|
||||
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;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (polynomial) {
|
||||
case POLY_32BIT_ANSI:
|
||||
_crc_table = (uint32_t *)Table_CRC_32bit_ANSI;
|
||||
break;
|
||||
case POLY_32BIT_REV_ANSI:
|
||||
_crc_table = (uint32_t *)Table_CRC_32bit_Rev_ANSI;
|
||||
break;
|
||||
case POLY_8BIT_CCITT:
|
||||
_crc_table = (uint32_t *)Table_CRC_8bit_CCITT;
|
||||
break;
|
||||
case POLY_7BIT_SD:
|
||||
_crc_table = (uint32_t *)Table_CRC_7Bit_SD;
|
||||
break;
|
||||
case POLY_16BIT_CCITT:
|
||||
_crc_table = (uint32_t *)Table_CRC_16bit_CCITT;
|
||||
break;
|
||||
case POLY_16BIT_IBM:
|
||||
_crc_table = (uint32_t *)Table_CRC_16bit_IBM;
|
||||
break;
|
||||
default:
|
||||
_crc_table = NULL;
|
||||
break;
|
||||
}
|
||||
_mode = (_crc_table != NULL) ? TABLE : BITWISE;
|
||||
hal_crc_compute_partial(data, size);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#elif defined ( __GNUC__ )
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined (__ICCARM__)
|
||||
#endif
|
||||
} // namespace impl
|
||||
|
||||
#endif // !defined(DOXYGEN_ONLY)
|
||||
|
||||
/* Default values for different types of polynomials
|
||||
*/
|
||||
template<>
|
||||
inline MbedCRC<POLY_32BIT_ANSI, 32>::MbedCRC() : MbedCRC(0xFFFFFFFF, 0xFFFFFFFF, true, true)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline MbedCRC<POLY_16BIT_IBM, 16>::MbedCRC() : MbedCRC(0, 0, true, true)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline MbedCRC<POLY_16BIT_CCITT, 16>::MbedCRC() : MbedCRC(0xFFFF, 0, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline MbedCRC<POLY_7BIT_SD, 7>::MbedCRC(): MbedCRC(0, 0, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline MbedCRC<POLY_8BIT_CCITT, 8>::MbedCRC(): MbedCRC(0, 0, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
/* Internal helper for mbed_error.c crash recovery */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
uint32_t mbed_tiny_compute_crc32(const void *data, int datalen);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TABLE_CRC_H
|
||||
#define TABLE_CRC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers-internal-api
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MBED_CRC_TABLE_SIZE 256
|
||||
#define MBED_OPTIMIZED_CRC_TABLE_SIZE 16
|
||||
|
||||
extern const uint8_t Table_CRC_7Bit_SD[MBED_CRC_TABLE_SIZE];
|
||||
extern const uint8_t Table_CRC_8bit_CCITT[MBED_CRC_TABLE_SIZE];
|
||||
extern const uint16_t Table_CRC_16bit_CCITT[MBED_CRC_TABLE_SIZE];
|
||||
extern const uint16_t Table_CRC_16bit_IBM[MBED_CRC_TABLE_SIZE];
|
||||
extern const uint32_t Table_CRC_32bit_ANSI[MBED_CRC_TABLE_SIZE];
|
||||
extern const uint32_t Table_CRC_32bit_Rev_ANSI[MBED_OPTIMIZED_CRC_TABLE_SIZE];
|
||||
|
||||
/** @}*/
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
|
@ -9,6 +9,11 @@
|
|||
"help": "Default RX buffer size for a UARTSerial instance (unit Bytes))",
|
||||
"value": 256
|
||||
},
|
||||
"crc-table-size": {
|
||||
"macro_name": "MBED_CRC_TABLE_SIZE",
|
||||
"help": "Number of entries in each of MbedCRC's pre-computed software tables. Higher values increase speed, but also increase image size. The value has no effect if the target performs the CRC in hardware. Permitted values are 0, 16 or 256.",
|
||||
"value": 16
|
||||
},
|
||||
"spi_count_max": {
|
||||
"help": "The maximum number of SPI peripherals used at the same time. Determines RAM allocated for SPI peripheral management. If null, limit determined by hardware.",
|
||||
"value": null
|
||||
|
|
|
@ -17,59 +17,132 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include "drivers/MbedCRC.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SingletonPtr<PlatformMutex> mbed_crc_mutex;
|
||||
|
||||
/* Default values for different types of polynomials
|
||||
*/
|
||||
template<>
|
||||
MbedCRC<POLY_32BIT_ANSI, 32>::MbedCRC():
|
||||
_initial_value(~(0x0)), _final_xor(~(0x0)), _reflect_data(true), _reflect_remainder(true),
|
||||
_crc_table((uint32_t *)Table_CRC_32bit_ANSI)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
MBED_STATIC_ASSERT(MBED_CRC_TABLE_SIZE == 0 || MBED_CRC_TABLE_SIZE == 16 || MBED_CRC_TABLE_SIZE == 256,
|
||||
"Configuration setting drivers.crc-table-size must be set to 0, 16 or 256");
|
||||
|
||||
#if MBED_CRC_TABLE_SIZE > 0
|
||||
|
||||
/* Tables are arranged for LSB first input. This means they're optimised
|
||||
* for reflect_data == true and reflect_result == true. If using 16-entry
|
||||
* tables, we need every 16th entry of the 256-entry table - this macro
|
||||
* filters.
|
||||
*/
|
||||
#if MBED_CRC_TABLE_SIZE == 16
|
||||
#define CRCS(x0, ...) x0
|
||||
#else
|
||||
#define CRCS(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<>
|
||||
MbedCRC<POLY_32BIT_REV_ANSI, 32>::MbedCRC():
|
||||
_initial_value(~(0x0)), _final_xor(~(0x0)), _reflect_data(false), _reflect_remainder(false),
|
||||
_crc_table((uint32_t *)Table_CRC_32bit_Rev_ANSI)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
const uint8_t MbedCRC<POLY_7BIT_SD, 7, CrcMode::TABLE>::_crc_table[MBED_CRC_TABLE_SIZE] = {
|
||||
CRCS(0x00, 0x41, 0x13, 0x52, 0x26, 0x67, 0x35, 0x74, 0x4c, 0x0d, 0x5f, 0x1e, 0x6a, 0x2b, 0x79, 0x38),
|
||||
CRCS(0x09, 0x48, 0x1a, 0x5b, 0x2f, 0x6e, 0x3c, 0x7d, 0x45, 0x04, 0x56, 0x17, 0x63, 0x22, 0x70, 0x31),
|
||||
CRCS(0x12, 0x53, 0x01, 0x40, 0x34, 0x75, 0x27, 0x66, 0x5e, 0x1f, 0x4d, 0x0c, 0x78, 0x39, 0x6b, 0x2a),
|
||||
CRCS(0x1b, 0x5a, 0x08, 0x49, 0x3d, 0x7c, 0x2e, 0x6f, 0x57, 0x16, 0x44, 0x05, 0x71, 0x30, 0x62, 0x23),
|
||||
CRCS(0x24, 0x65, 0x37, 0x76, 0x02, 0x43, 0x11, 0x50, 0x68, 0x29, 0x7b, 0x3a, 0x4e, 0x0f, 0x5d, 0x1c),
|
||||
CRCS(0x2d, 0x6c, 0x3e, 0x7f, 0x0b, 0x4a, 0x18, 0x59, 0x61, 0x20, 0x72, 0x33, 0x47, 0x06, 0x54, 0x15),
|
||||
CRCS(0x36, 0x77, 0x25, 0x64, 0x10, 0x51, 0x03, 0x42, 0x7a, 0x3b, 0x69, 0x28, 0x5c, 0x1d, 0x4f, 0x0e),
|
||||
CRCS(0x3f, 0x7e, 0x2c, 0x6d, 0x19, 0x58, 0x0a, 0x4b, 0x73, 0x32, 0x60, 0x21, 0x55, 0x14, 0x46, 0x07),
|
||||
CRCS(0x48, 0x09, 0x5b, 0x1a, 0x6e, 0x2f, 0x7d, 0x3c, 0x04, 0x45, 0x17, 0x56, 0x22, 0x63, 0x31, 0x70),
|
||||
CRCS(0x41, 0x00, 0x52, 0x13, 0x67, 0x26, 0x74, 0x35, 0x0d, 0x4c, 0x1e, 0x5f, 0x2b, 0x6a, 0x38, 0x79),
|
||||
CRCS(0x5a, 0x1b, 0x49, 0x08, 0x7c, 0x3d, 0x6f, 0x2e, 0x16, 0x57, 0x05, 0x44, 0x30, 0x71, 0x23, 0x62),
|
||||
CRCS(0x53, 0x12, 0x40, 0x01, 0x75, 0x34, 0x66, 0x27, 0x1f, 0x5e, 0x0c, 0x4d, 0x39, 0x78, 0x2a, 0x6b),
|
||||
CRCS(0x6c, 0x2d, 0x7f, 0x3e, 0x4a, 0x0b, 0x59, 0x18, 0x20, 0x61, 0x33, 0x72, 0x06, 0x47, 0x15, 0x54),
|
||||
CRCS(0x65, 0x24, 0x76, 0x37, 0x43, 0x02, 0x50, 0x11, 0x29, 0x68, 0x3a, 0x7b, 0x0f, 0x4e, 0x1c, 0x5d),
|
||||
CRCS(0x7e, 0x3f, 0x6d, 0x2c, 0x58, 0x19, 0x4b, 0x0a, 0x32, 0x73, 0x21, 0x60, 0x14, 0x55, 0x07, 0x46),
|
||||
CRCS(0x77, 0x36, 0x64, 0x25, 0x51, 0x10, 0x42, 0x03, 0x3b, 0x7a, 0x28, 0x69, 0x1d, 0x5c, 0x0e, 0x4f)
|
||||
};
|
||||
|
||||
template<>
|
||||
MbedCRC<POLY_16BIT_IBM, 16>::MbedCRC():
|
||||
_initial_value(0), _final_xor(0), _reflect_data(true), _reflect_remainder(true),
|
||||
_crc_table((uint32_t *)Table_CRC_16bit_IBM)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
const uint8_t MbedCRC<POLY_8BIT_CCITT, 8, CrcMode::TABLE>::_crc_table[MBED_CRC_TABLE_SIZE] = {
|
||||
CRCS(0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b),
|
||||
CRCS(0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67),
|
||||
CRCS(0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43),
|
||||
CRCS(0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f),
|
||||
CRCS(0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b),
|
||||
CRCS(0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17),
|
||||
CRCS(0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33),
|
||||
CRCS(0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f),
|
||||
CRCS(0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b),
|
||||
CRCS(0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87),
|
||||
CRCS(0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3),
|
||||
CRCS(0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf),
|
||||
CRCS(0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb),
|
||||
CRCS(0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7),
|
||||
CRCS(0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3),
|
||||
CRCS(0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf)
|
||||
};
|
||||
|
||||
template<>
|
||||
MbedCRC<POLY_16BIT_CCITT, 16>::MbedCRC():
|
||||
_initial_value(~(0x0)), _final_xor(0), _reflect_data(false), _reflect_remainder(false),
|
||||
_crc_table((uint32_t *)Table_CRC_16bit_CCITT)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
const uint16_t MbedCRC<POLY_16BIT_CCITT, 16, CrcMode::TABLE>::_crc_table[MBED_CRC_TABLE_SIZE] = {
|
||||
CRCS(0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7),
|
||||
CRCS(0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876),
|
||||
CRCS(0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5),
|
||||
CRCS(0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974),
|
||||
CRCS(0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3),
|
||||
CRCS(0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72),
|
||||
CRCS(0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1),
|
||||
CRCS(0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70),
|
||||
CRCS(0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff),
|
||||
CRCS(0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e),
|
||||
CRCS(0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd),
|
||||
CRCS(0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c),
|
||||
CRCS(0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb),
|
||||
CRCS(0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a),
|
||||
CRCS(0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9),
|
||||
CRCS(0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78)
|
||||
};
|
||||
|
||||
template<>
|
||||
MbedCRC<POLY_7BIT_SD, 7>::MbedCRC():
|
||||
_initial_value(0), _final_xor(0), _reflect_data(false), _reflect_remainder(false),
|
||||
_crc_table((uint32_t *)Table_CRC_7Bit_SD)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
const uint16_t MbedCRC<POLY_16BIT_IBM, 16, CrcMode::TABLE>::_crc_table[MBED_CRC_TABLE_SIZE] = {
|
||||
CRCS(0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440),
|
||||
CRCS(0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841),
|
||||
CRCS(0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41),
|
||||
CRCS(0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040),
|
||||
CRCS(0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441),
|
||||
CRCS(0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840),
|
||||
CRCS(0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40),
|
||||
CRCS(0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041),
|
||||
CRCS(0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441),
|
||||
CRCS(0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840),
|
||||
CRCS(0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40),
|
||||
CRCS(0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041),
|
||||
CRCS(0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440),
|
||||
CRCS(0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841),
|
||||
CRCS(0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41),
|
||||
CRCS(0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040)
|
||||
};
|
||||
|
||||
template<>
|
||||
MbedCRC<POLY_8BIT_CCITT, 8>::MbedCRC():
|
||||
_initial_value(0), _final_xor(0), _reflect_data(false), _reflect_remainder(false),
|
||||
_crc_table((uint32_t *)Table_CRC_8bit_CCITT)
|
||||
{
|
||||
mbed_crc_ctor();
|
||||
}
|
||||
const uint32_t MbedCRC<POLY_32BIT_ANSI, 32, CrcMode::TABLE>::_crc_table[MBED_CRC_TABLE_SIZE] = {
|
||||
CRCS(0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91),
|
||||
CRCS(0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5),
|
||||
CRCS(0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59),
|
||||
CRCS(0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d),
|
||||
CRCS(0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01),
|
||||
CRCS(0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65),
|
||||
CRCS(0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9),
|
||||
CRCS(0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad),
|
||||
CRCS(0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1),
|
||||
CRCS(0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5),
|
||||
CRCS(0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79),
|
||||
CRCS(0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d),
|
||||
CRCS(0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21),
|
||||
CRCS(0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45),
|
||||
CRCS(0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9),
|
||||
CRCS(0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d)
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
#endif // MBED_CRC_TABLE_SIZE > 0
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "drivers/internal/TableCRC.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
extern const uint8_t Table_CRC_7Bit_SD[MBED_CRC_TABLE_SIZE] = {
|
||||
0x0, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e, 0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee,
|
||||
0x32, 0x20, 0x16, 0x4, 0x7a, 0x68, 0x5e, 0x4c, 0xa2, 0xb0, 0x86, 0x94, 0xea, 0xf8, 0xce, 0xdc,
|
||||
0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x8, 0x1a, 0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a,
|
||||
0x56, 0x44, 0x72, 0x60, 0x1e, 0xc, 0x3a, 0x28, 0xc6, 0xd4, 0xe2, 0xf0, 0x8e, 0x9c, 0xaa, 0xb8,
|
||||
0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6, 0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x2, 0x34, 0x26,
|
||||
0xfa, 0xe8, 0xde, 0xcc, 0xb2, 0xa0, 0x96, 0x84, 0x6a, 0x78, 0x4e, 0x5c, 0x22, 0x30, 0x6, 0x14,
|
||||
0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, 0xc0, 0xd2, 0x3c, 0x2e, 0x18, 0xa, 0x74, 0x66, 0x50, 0x42,
|
||||
0x9e, 0x8c, 0xba, 0xa8, 0xd6, 0xc4, 0xf2, 0xe0, 0xe, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x70,
|
||||
0x82, 0x90, 0xa6, 0xb4, 0xca, 0xd8, 0xee, 0xfc, 0x12, 0x0, 0x36, 0x24, 0x5a, 0x48, 0x7e, 0x6c,
|
||||
0xb0, 0xa2, 0x94, 0x86, 0xf8, 0xea, 0xdc, 0xce, 0x20, 0x32, 0x4, 0x16, 0x68, 0x7a, 0x4c, 0x5e,
|
||||
0xe6, 0xf4, 0xc2, 0xd0, 0xae, 0xbc, 0x8a, 0x98, 0x76, 0x64, 0x52, 0x40, 0x3e, 0x2c, 0x1a, 0x8,
|
||||
0xd4, 0xc6, 0xf0, 0xe2, 0x9c, 0x8e, 0xb8, 0xaa, 0x44, 0x56, 0x60, 0x72, 0xc, 0x1e, 0x28, 0x3a,
|
||||
0x4a, 0x58, 0x6e, 0x7c, 0x2, 0x10, 0x26, 0x34, 0xda, 0xc8, 0xfe, 0xec, 0x92, 0x80, 0xb6, 0xa4,
|
||||
0x78, 0x6a, 0x5c, 0x4e, 0x30, 0x22, 0x14, 0x6, 0xe8, 0xfa, 0xcc, 0xde, 0xa0, 0xb2, 0x84, 0x96,
|
||||
0x2e, 0x3c, 0xa, 0x18, 0x66, 0x74, 0x42, 0x50, 0xbe, 0xac, 0x9a, 0x88, 0xf6, 0xe4, 0xd2, 0xc0,
|
||||
0x1c, 0xe, 0x38, 0x2a, 0x54, 0x46, 0x70, 0x62, 0x8c, 0x9e, 0xa8, 0xba, 0xc4, 0xd6, 0xe0, 0xf2
|
||||
};
|
||||
|
||||
extern const uint8_t Table_CRC_8bit_CCITT[MBED_CRC_TABLE_SIZE] = {
|
||||
0x0, 0x7, 0xe, 0x9, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
|
||||
0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
|
||||
0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
|
||||
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
|
||||
0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
|
||||
0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
|
||||
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x3, 0x4, 0xd, 0xa,
|
||||
0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
|
||||
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
|
||||
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
|
||||
0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
|
||||
0x19, 0x1e, 0x17, 0x10, 0x5, 0x2, 0xb, 0xc, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
|
||||
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
|
||||
0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x6, 0x1, 0x8, 0xf, 0x1a, 0x1d, 0x14, 0x13,
|
||||
0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
|
||||
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
|
||||
};
|
||||
|
||||
extern const uint16_t Table_CRC_16bit_CCITT[MBED_CRC_TABLE_SIZE] = {
|
||||
0x0, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
|
||||
0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x420, 0x1401,
|
||||
0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
|
||||
0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
|
||||
0x1a71, 0xa50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0xc60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
|
||||
0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0xe70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
|
||||
0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0xa1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x2b1, 0x1290, 0x22f3, 0x32d2,
|
||||
0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
|
||||
0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
|
||||
0x18c0, 0x8e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0xaf1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
|
||||
0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0xcc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
|
||||
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||
};
|
||||
|
||||
extern const uint16_t Table_CRC_16bit_IBM[MBED_CRC_TABLE_SIZE] = {
|
||||
0x0, 0x8005, 0x800f, 0xa, 0x801b, 0x1e, 0x14, 0x8011, 0x8033, 0x36, 0x3c, 0x8039,
|
||||
0x28, 0x802d, 0x8027, 0x22, 0x8063, 0x66, 0x6c, 0x8069, 0x78, 0x807d, 0x8077, 0x72,
|
||||
0x50, 0x8055, 0x805f, 0x5a, 0x804b, 0x4e, 0x44, 0x8041, 0x80c3, 0xc6, 0xcc, 0x80c9,
|
||||
0xd8, 0x80dd, 0x80d7, 0xd2, 0xf0, 0x80f5, 0x80ff, 0xfa, 0x80eb, 0xee, 0xe4, 0x80e1,
|
||||
0xa0, 0x80a5, 0x80af, 0xaa, 0x80bb, 0xbe, 0xb4, 0x80b1, 0x8093, 0x96, 0x9c, 0x8099,
|
||||
0x88, 0x808d, 0x8087, 0x82, 0x8183, 0x186, 0x18c, 0x8189, 0x198, 0x819d, 0x8197, 0x192,
|
||||
0x1b0, 0x81b5, 0x81bf, 0x1ba, 0x81ab, 0x1ae, 0x1a4, 0x81a1, 0x1e0, 0x81e5, 0x81ef, 0x1ea,
|
||||
0x81fb, 0x1fe, 0x1f4, 0x81f1, 0x81d3, 0x1d6, 0x1dc, 0x81d9, 0x1c8, 0x81cd, 0x81c7, 0x1c2,
|
||||
0x140, 0x8145, 0x814f, 0x14a, 0x815b, 0x15e, 0x154, 0x8151, 0x8173, 0x176, 0x17c, 0x8179,
|
||||
0x168, 0x816d, 0x8167, 0x162, 0x8123, 0x126, 0x12c, 0x8129, 0x138, 0x813d, 0x8137, 0x132,
|
||||
0x110, 0x8115, 0x811f, 0x11a, 0x810b, 0x10e, 0x104, 0x8101, 0x8303, 0x306, 0x30c, 0x8309,
|
||||
0x318, 0x831d, 0x8317, 0x312, 0x330, 0x8335, 0x833f, 0x33a, 0x832b, 0x32e, 0x324, 0x8321,
|
||||
0x360, 0x8365, 0x836f, 0x36a, 0x837b, 0x37e, 0x374, 0x8371, 0x8353, 0x356, 0x35c, 0x8359,
|
||||
0x348, 0x834d, 0x8347, 0x342, 0x3c0, 0x83c5, 0x83cf, 0x3ca, 0x83db, 0x3de, 0x3d4, 0x83d1,
|
||||
0x83f3, 0x3f6, 0x3fc, 0x83f9, 0x3e8, 0x83ed, 0x83e7, 0x3e2, 0x83a3, 0x3a6, 0x3ac, 0x83a9,
|
||||
0x3b8, 0x83bd, 0x83b7, 0x3b2, 0x390, 0x8395, 0x839f, 0x39a, 0x838b, 0x38e, 0x384, 0x8381,
|
||||
0x280, 0x8285, 0x828f, 0x28a, 0x829b, 0x29e, 0x294, 0x8291, 0x82b3, 0x2b6, 0x2bc, 0x82b9,
|
||||
0x2a8, 0x82ad, 0x82a7, 0x2a2, 0x82e3, 0x2e6, 0x2ec, 0x82e9, 0x2f8, 0x82fd, 0x82f7, 0x2f2,
|
||||
0x2d0, 0x82d5, 0x82df, 0x2da, 0x82cb, 0x2ce, 0x2c4, 0x82c1, 0x8243, 0x246, 0x24c, 0x8249,
|
||||
0x258, 0x825d, 0x8257, 0x252, 0x270, 0x8275, 0x827f, 0x27a, 0x826b, 0x26e, 0x264, 0x8261,
|
||||
0x220, 0x8225, 0x822f, 0x22a, 0x823b, 0x23e, 0x234, 0x8231, 0x8213, 0x216, 0x21c, 0x8219
|
||||
};
|
||||
|
||||
extern const uint32_t Table_CRC_32bit_ANSI[MBED_CRC_TABLE_SIZE] = {
|
||||
0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
|
||||
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
|
||||
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
|
||||
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
|
||||
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca,
|
||||
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
|
||||
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
|
||||
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
|
||||
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
|
||||
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
|
||||
0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
|
||||
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
|
||||
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
|
||||
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
|
||||
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
|
||||
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
|
||||
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
|
||||
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
extern const uint32_t Table_CRC_32bit_Rev_ANSI[MBED_OPTIMIZED_CRC_TABLE_SIZE] = {
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
||||
};
|
||||
|
||||
} // namespace mbed
|
Loading…
Reference in New Issue