Merge pull request #11946 from ARMmbed/revert-11559-crc

Revert "MbedCRC and CRC HAL revisions"
pull/11970/head
Martin Kojtal 2019-11-27 11:07:13 +01:00 committed by GitHub
commit b0751bf507
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 776 additions and 859 deletions

View File

@ -25,62 +25,32 @@ using namespace utest::v1;
void test_supported_polynomials()
{
const char test[] = "123456789";
char test[] = "123456789";
uint32_t crc;
{
MbedCRC<POLY_7BIT_SD, 7> ct;
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);
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xEA, crc);
}
{
MbedCRC<POLY_8BIT_CCITT, 8> ct;
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xF4, crc);
}
{
MbedCRC<POLY_16BIT_CCITT, 16> ct;
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0x29B1, crc);
}
{
MbedCRC<POLY_16BIT_IBM, 16> ct;
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xBB3D, crc);
}
{
MbedCRC<POLY_32BIT_ANSI, 32> ct;
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xCBF43926, crc);
}
}
@ -92,8 +62,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(test, 4, &crc));
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &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_stop(&crc));
TEST_ASSERT_EQUAL(0x29B1, crc);
@ -111,8 +81,8 @@ void test_sd_crc()
test[2] = 0x00;
test[3] = 0x00;
test[4] = 0x00;
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
crc = (crc << 1) | 0x1;
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
crc = (crc | 0x1) & 0xFF;
TEST_ASSERT_EQUAL(0x95, crc);
test[0] = 0x48;
@ -120,8 +90,8 @@ void test_sd_crc()
test[2] = 0x00;
test[3] = 0x01;
test[4] = 0xAA;
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
crc = (crc << 1) | 0x1;
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
crc = (crc | 0x1) & 0xFF;
TEST_ASSERT_EQUAL(0x87, crc);
test[0] = 0x51;
@ -129,13 +99,13 @@ void test_sd_crc()
test[2] = 0x00;
test[3] = 0x00;
test[4] = 0x00;
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
crc = (crc << 1) | 0x1;
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
crc = (crc | 0x1) & 0xFF;
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(test, 512, &crc));
TEST_ASSERT_EQUAL(0, crc16.compute((void *)test, 512, &crc));
TEST_ASSERT_EQUAL(0x7FA1, crc);
}
@ -145,12 +115,12 @@ void test_any_polynomial()
uint32_t crc;
{
MbedCRC<0x3D65, 16> ct(0x0, 0xFFFF, 0, 0);
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xC2B7, crc);
}
{
MbedCRC<0x1EDC6F41, 32> ct(0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xE3069283, crc);
}
}
@ -160,7 +130,7 @@ void test_thread(void)
char test[] = "123456789";
uint32_t crc;
MbedCRC<POLY_32BIT_ANSI, 32> ct;
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
TEST_ASSERT_EQUAL(0xCBF43926, crc);
}
@ -173,11 +143,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(test, 4, &crc));
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test, 4, &crc));
Thread t1(osPriorityNormal1, 380);
t1.start(callback(test_thread));
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &crc));
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test[4], 5, &crc));
TEST_ASSERT_EQUAL(0, ct.compute_partial_stop(&crc));
TEST_ASSERT_EQUAL(0xBB3D, crc);

View File

@ -54,7 +54,7 @@ void crc_is_supported_test()
uint32_t num_of_supported_polynomials = 0;
for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) {
if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) {
if (hal_crc_is_supported(&test_cases[i].config_data) == true) {
num_of_supported_polynomials++;
}
@ -68,7 +68,7 @@ void crc_is_supported_test()
void crc_calc_single_test()
{
for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) {
if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) {
if (hal_crc_is_supported(&test_cases[i].config_data) == true) {
hal_crc_compute_partial_start(&test_cases[i].config_data);
hal_crc_compute_partial((uint8_t *) input_data, strlen((const char *) input_data));
@ -84,7 +84,7 @@ void crc_calc_single_test()
void crc_calc_multi_test()
{
for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) {
if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) {
if (hal_crc_is_supported(&test_cases[i].config_data) == true) {
const uint32_t first_part_bytes = 3;
const uint32_t second_part_bytes = 1;
@ -117,7 +117,7 @@ void crc_reconfigure_test()
for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) {
/* Find two supported polynomials if possible. */
if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) {
if (hal_crc_is_supported(&test_cases[i].config_data) == true) {
if (pol_cnt == 0) {
pol_idx[pol_cnt] = i;
pol_cnt++;
@ -159,7 +159,7 @@ void crc_compute_partial_invalid_param_test()
/* At least one polynomial must be supported. */
for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) {
if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) {
if (hal_crc_is_supported(&test_cases[i].config_data) == true) {
hal_crc_compute_partial_start(&test_cases[i].config_data);
@ -180,12 +180,19 @@ void crc_compute_partial_invalid_param_test()
}
}
/* Test that hal_crc_is_supported() returns false if pointer to the config structure is undefined. */
void crc_is_supported_invalid_param_test()
{
TEST_ASSERT_EQUAL(false, hal_crc_is_supported(NULL));
}
Case cases[] = {
Case("test: supported polynomials.", crc_is_supported_test),
Case("test: CRC calculation - single input.", crc_calc_single_test),
Case("test: CRC calculation - multi input.", crc_calc_multi_test),
Case("test: re-configure without getting the result.", crc_reconfigure_test),
Case("test: hal_crc_compute_partial() - invalid parameters.", crc_compute_partial_invalid_param_test),
Case("test: hal_crc_is_supported() - invalid parameter.", crc_is_supported_invalid_param_test),
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
@ -201,12 +208,12 @@ int main()
// *INDENT-OFF*
TEST_CASE local_test_cases[] = {
/* Predefined polynomials. */
/* 00 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, false}, 0x75 },
/* 01 */{ {POLY_7BIT_SD , 7, 0x0000007F, 0x00000000, false, false}, 0x50 },
/* 02 */{ {POLY_7BIT_SD , 7, 0x0000002B, 0x00000000, false, false}, 0x3A },
/* 03 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000007F, false, false}, 0x0A },
/* 04 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000002B, false, false}, 0x5E },
/* 05 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, true , false}, 0x52 },
/* 00 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, false}, 0xEA },
/* 01 */{ {POLY_7BIT_SD , 7, 0x0000007F, 0x00000000, false, false}, 0xA0 },
/* 02 */{ {POLY_7BIT_SD , 7, 0x0000002B, 0x00000000, false, false}, 0x74 },
/* 03 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000007F, false, false}, 0x95 },
/* 04 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000002B, false, false}, 0xC1 },
/* 05 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, true , false}, 0xA4 },
/* 06 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, true }, 0x57 },
/* 07 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, false}, 0xF4 },

View File

@ -48,7 +48,7 @@ set(unittest-test-sources
empty_baseline/empty_baseline.cpp
)
set(DEVICE_FLAGS "-DDEVICE_ANALOGIN -DDEVICE_ANALOGOUT -DDEVICE_CAN -DDEVICE_ETHERNET -DDEVICE_FLASH -DDEVICE_I2C -DDEVICE_I2CSLAVE -DDEVICE_I2C_ASYNCH -DDEVICE_INTERRUPTIN -DDEVICE_LPTICKER -DDEVICE_PORTIN -DDEVICE_PORTINOUT -DDEVICE_PORTOUT -DDEVICE_PWMOUT -DDEVICE_QSPI -DDEVICE_SERIAL -DDEVICE_SERIAL_ASYNCH -DDEVICE_SERIAL_FC -DDEVICE_SPI -DDEVICE_SPISLAVE -DDEVICE_SPI_ASYNCH -DDEVICE_FLASH -DCOMPONENT_FLASHIAP")
set(DEVICE_FLAGS "-DDEVICE_ANALOGIN -DDEVICE_ANALOGOUT -DDEVICE_CAN -DDEVICE_CRC -DDEVICE_ETHERNET -DDEVICE_FLASH -DDEVICE_I2C -DDEVICE_I2CSLAVE -DDEVICE_I2C_ASYNCH -DDEVICE_INTERRUPTIN -DDEVICE_LPTICKER -DDEVICE_PORTIN -DDEVICE_PORTINOUT -DDEVICE_PORTOUT -DDEVICE_PWMOUT -DDEVICE_QSPI -DDEVICE_SERIAL -DDEVICE_SERIAL_ASYNCH -DDEVICE_SERIAL_FC -DDEVICE_SPI -DDEVICE_SPISLAVE -DDEVICE_SPI_ASYNCH -DDEVICE_FLASH -DCOMPONENT_FLASHIAP")
set(CONF_FLAGS "-DMBED_CONF_PLATFORM_CTHUNK_COUNT_MAX=10 -DMBED_CONF_DATAFLASH_SPI_FREQ=1 -DMBED_CONF_FLASHIAP_BLOCK_DEVICE_BASE_ADDRESS=0 -DMBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE=0 -DMBED_CONF_QSPIF_QSPI_FREQ=1 -DMBED_CONF_QSPIF_QSPI_MIN_READ_SIZE=1 -DMBED_CONF_QSPIF_QSPI_MIN_PROG_SIZE=1 -DMBED_LFS_READ_SIZE=64 -DMBED_LFS_PROG_SIZE=64 -DMBED_LFS_BLOCK_SIZE=512 -DMBED_LFS_LOOKAHEAD=512 -DFLASHIAP_APP_ROM_END_ADDR=0x80000 -DMBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE=1024 -DMBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS=0x80000 -DMBED_CONF_STORAGE_STORAGE_TYPE=default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DEVICE_FLAGS} ${CONF_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEVICE_FLAGS} ${CONF_FLAGS}")

View File

@ -14,19 +14,3 @@
* 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

View File

@ -252,7 +252,7 @@ const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC;
#if MBED_CONF_SD_CRC_ENABLED
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
_init_ref_count(0), _crc_on(crc_on)
_init_ref_count(0), _crc_on(crc_on), _crc16(0, 0, false, false)
#else
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
@ -678,11 +678,10 @@ uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg)
cmdPacket[4] = (arg >> 0);
#if MBED_CONF_SD_CRC_ENABLED
uint32_t crc;
if (_crc_on) {
MbedCRC<POLY_7BIT_SD, 7> crc7;
uint32_t crc;
crc7.compute(cmdPacket, 5, &crc);
cmdPacket[5] = ((uint8_t) crc << 1) | 0x01;
_crc7.compute((void *)cmdPacket, 5, &crc);
cmdPacket[5] = (char)(crc | 0x01);
} else
#endif
{
@ -900,13 +899,12 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length)
#if MBED_CONF_SD_CRC_ENABLED
if (_crc_on) {
mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false);
uint32_t crc_result;
// Compute and verify checksum
crc16.compute(buffer, length, &crc_result);
if (crc_result != crc) {
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n",
crc, crc_result);
_crc16.compute((void *)buffer, length, &crc_result);
if ((uint16_t)crc_result != crc) {
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx16 "\n",
crc, (uint16_t)crc_result);
_deselect();
return SD_BLOCK_DEVICE_ERROR_CRC;
}
@ -936,10 +934,9 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length)
#if MBED_CONF_SD_CRC_ENABLED
if (_crc_on) {
mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false);
uint32_t crc_result;
// Compute and verify checksum
crc16.compute((void *)buffer, length, &crc_result);
_crc16.compute((void *)buffer, length, &crc_result);
if ((uint16_t)crc_result != crc) {
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx16 "\n",
crc, (uint16_t)crc_result);
@ -965,9 +962,8 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len
#if MBED_CONF_SD_CRC_ENABLED
if (_crc_on) {
mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false);
// Compute CRC
crc16.compute(buffer, length, &crc);
_crc16.compute((void *)buffer, length, &crc);
}
#endif

View File

@ -256,6 +256,8 @@ private:
#if MBED_CONF_SD_CRC_ENABLED
bool _crc_on;
mbed::MbedCRC<POLY_7BIT_SD, 7> _crc7;
mbed::MbedCRC<POLY_16BIT_CCITT, 16> _crc16;
#endif
};

View File

@ -17,19 +17,27 @@
#ifndef MBED_CRC_API_H
#define MBED_CRC_API_H
#include "cmsis.h"
#include "drivers/internal/TableCRC.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"
#include <type_traits>
/* 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
namespace mbed {
/** \addtogroup drivers-public-api */
@ -41,49 +49,10 @@ 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 normally selected automatically based on required
* and bitwise computation. The mode used is 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.
*
@ -93,17 +62,10 @@ constexpr CrcMode choose_crc_mode(uint32_t polynomial, uint8_t width, CrcMode mo
* 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 mode_limit Maximum amount of acceleration to use
* @tparam width CRC polynomial width
*
* Example: Compute CRC data
* @code
@ -144,25 +106,23 @@ constexpr CrcMode choose_crc_mode(uint32_t polynomial, uint8_t width, CrcMode mo
* }
* @endcode
*/
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;
template <uint32_t polynomial = POLY_32BIT_ANSI, uint8_t width = 32>
class MbedCRC {
public:
/* Backwards compatibility */
enum CrcMode {
#if DEVICE_CRC
HARDWARE = int(::mbed::CrcMode::HARDWARE),
HARDWARE = 0,
#endif
TABLE = int(::mbed::CrcMode::TABLE),
BITWISE = int(::mbed::CrcMode::BITWISE)
TABLE = 1,
BITWISE
};
typedef size_t crc_data_size_t;
typedef uint64_t crc_data_size_t;
/** Lifetime of CRC object
*
* @param initial_xor Initial value/seed to Xor
* @param initial_xor Inital value/seed to Xor
* @param final_xor Final Xor value
* @param reflect_data
* @param reflect_remainder
@ -172,120 +132,19 @@ 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 initial/final/reflect values
* polynomials with different intial/final/reflect values
*
*/
MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder) :
crc_impl(initial_xor, final_xor, reflect_data, reflect_remainder)
{
}
MbedCRC();
/** 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)
{
return crc_impl.compute(buffer, size, crc);
}
/** 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)
{
return crc_impl.compute_partial(buffer, 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)
{
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),
_initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data),
_reflect_remainder(reflect_remainder)
{
static_assert(width <= 32, "Max 32-bit CRC supported");
mbed_crc_ctor();
}
MbedCRC();
virtual ~MbedCRC()
{
// Do nothing
}
/** Compute CRC for the data input
@ -299,20 +158,28 @@ public:
*/
int32_t compute(const void *buffer, crc_data_size_t size, uint32_t *crc)
{
int32_t status;
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;
}
/** Compute partial CRC for the data input.
@ -338,8 +205,27 @@ public:
*/
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);
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;
}
/** Compute partial start, indicate start of partial computation.
@ -354,8 +240,10 @@ public:
*/
int32_t compute_partial_start(uint32_t *crc)
{
MBED_ASSERT(crc != NULL);
#if DEVICE_CRC
if (mode == CrcMode::HARDWARE) {
if (_mode == HARDWARE) {
lock();
crc_mbed_config_t config;
config.polynomial = polynomial;
@ -384,143 +272,62 @@ public:
*/
int32_t compute_partial_stop(uint32_t *crc)
{
MBED_ASSERT(crc != NULL);
#if DEVICE_CRC
if (mode == CrcMode::HARDWARE) {
if (_mode == HARDWARE) {
*crc = hal_crc_get_result();
unlock();
return 0;
}
#endif
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);
}
uint32_t p_crc = *crc;
if ((width < 8) && (NULL == _crc_table)) {
p_crc = (uint32_t)(p_crc << (8 - width));
}
p_crc ^= _final_xor;
p_crc &= get_crc_mask();
*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();
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:
/** 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;
}
}
uint32_t _initial_value;
uint32_t _final_xor;
bool _reflect_data;
bool _reflect_remainder;
uint32_t *_crc_table;
CrcMode _mode;
/** Acquire exclusive access to CRC hardware/software.
*/
static void lock()
void lock()
{
#if DEVICE_CRC
if (mode == CrcMode::HARDWARE) {
if (_mode == HARDWARE) {
mbed_crc_mutex->lock();
}
#endif
@ -528,179 +335,87 @@ private:
/** Release exclusive access to CRC hardware/software.
*/
static void unlock()
virtual void unlock()
{
#if DEVICE_CRC
if (mode == CrcMode::HARDWARE) {
if (_mode == 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
*/
static constexpr uint32_t get_crc_mask()
uint32_t get_crc_mask(void) const
{
return (uint32_t)((uint32_t)2U << (width - 1)) - 1U;
return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
}
/** Data bytes may need to be reflected.
/** Final value of CRC is reflected.
*
* @param data value to be reflected (bottom 8 bits)
* @return Reflected value (bottom 8 bits)
* @param data final crc value, which should be reflected
* @return Reflected CRC value
*/
static uint_fast32_t reflect_byte(uint_fast32_t data)
uint32_t reflect_remainder(uint32_t data) const
{
return __RBIT(data) >> 24;
}
if (_reflect_remainder) {
uint32_t reflection = 0x0;
uint8_t const nBits = (width < 8 ? 8 : width);
/** CRC values may need to be reflected.
*
* @param CRC value to be reflected (width bits at bottom of 32-bit word)
* @return Reflected value (still at bottom of 32-bit word)
*/
static uint32_t reflect_crc(uint32_t 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();
for (uint8_t bit = 0; bit < nBits; ++bit) {
if (data & 0x01) {
reflection |= (1 << ((nBits - 1) - bit));
}
data = (data >> 1);
}
return (reflection);
} else {
p_crc = (p_crc << 1);
return data;
}
#endif
return p_crc;
}
/** Process 1 bit of reflected CRC
/** Data bytes are reflected.
*
* 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
* @param data value to be reflected
* @return Reflected data value
*/
static uint_fast32_t do_1_bit_reflected(uint_fast32_t p_crc)
uint32_t reflect_bytes(uint32_t data) const
{
#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();
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 {
p_crc = (p_crc >> 1);
return data;
}
#endif
return p_crc;
}
// *INDENT-ON*
/** Bitwise CRC computation.
*
@ -709,36 +424,40 @@ 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
*/
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
int32_t bitwise_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
{
uint_fast32_t p_crc = *crc;
MBED_ASSERT(crc != NULL);
if (_reflect_data) {
/* Everything is reflected to match data - MSB of polynomial at bottom of 32-bit register */
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++) {
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);
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 {
/* 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 ^= (uint_fast32_t) data[byte] << 24;
p_crc ^= (reflect_bytes(data[byte]) << (width - 8));
// Perform modulo-2 division, a bit at a time
for (unsigned int bit = 8; bit > 0; --bit) {
p_crc = do_1_bit_normal(p_crc);
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;
*crc = p_crc & get_crc_mask();
return 0;
}
@ -749,92 +468,105 @@ 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
*/
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
int32_t table_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
{
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;
MBED_ASSERT(crc != NULL);
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);
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);
}
}
#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;
*crc = p_crc & get_crc_mask();
return 0;
}
#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
/** Constructor init called from all specialized cases of constructor.
* Note: All constructor common code should be in this function.
*/
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
void mbed_crc_ctor(void)
{
hal_crc_compute_partial(data, size);
return 0;
}
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;
}
#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)
{
}
#if defined ( __CC_ARM )
#elif defined ( __GNUC__ )
#pragma GCC diagnostic pop
#elif defined (__ICCARM__)
#endif
/** @}*/
/** @}*/
} // 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

View File

@ -0,0 +1,42 @@
/* 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

View File

@ -9,11 +9,6 @@
"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

View File

@ -17,140 +17,59 @@
#include <stddef.h>
#include "drivers/MbedCRC.h"
#include "platform/mbed_assert.h"
namespace mbed {
SingletonPtr<PlatformMutex> mbed_crc_mutex;
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 {
/* 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();
}
template<>
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)
};
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();
}
template<>
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)
};
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();
}
template<>
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)
};
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();
}
template<>
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)
};
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();
}
template<>
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
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();
}
} // namespace mbed
extern "C" uint32_t mbed_tiny_compute_crc32(const void *data, int datalen)
{
mbed::MbedCRC<POLY_32BIT_ANSI, 32, mbed::CrcMode::BITWISE> crc32(0, 0, false, false);
uint32_t result;
crc32.compute(data, datalen, &result);
return result;
}

152
drivers/source/TableCRC.cpp Normal file
View File

@ -0,0 +1,152 @@
/* 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

View File

@ -25,10 +25,8 @@ namespace mbed {
extern "C" void lfs_crc(uint32_t *crc, const void *buffer, size_t size)
{
uint32_t initial_xor = *crc;
// lfs_cache_crc calls lfs_crc for every byte individually, so can't afford
// start-up overhead for hardware acceleration. Limit to table-based.
MbedCRC<POLY_32BIT_ANSI, 32, CrcMode::TABLE> ct(initial_xor, 0x0, true, true);
ct.compute(buffer, size, crc);
MbedCRC<POLY_32BIT_REV_ANSI, 32> ct(initial_xor, 0x0, true, false);
ct.compute((void *)buffer, size, (uint32_t *) crc);
}
////// Conversion functions //////

View File

@ -309,7 +309,7 @@ static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data
{
uint32_t crc;
MbedCRC<POLY_32BIT_ANSI, 32> ct(init_crc, 0x0, true, false);
ct.compute(data_buf, data_size, &crc);
ct.compute(const_cast<void *>(data_buf), data_size, &crc);
return crc;
}
#endif // DEVICE_FLASH

View File

@ -117,7 +117,7 @@ static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data
{
uint32_t crc;
MbedCRC<POLY_32BIT_ANSI, 32> ct(init_crc, 0x0, true, false);
ct.compute(data_buf, data_size, &crc);
ct.compute(const_cast<void *>(data_buf), data_size, &crc);
return crc;
}

View File

@ -28,15 +28,17 @@
* Different polynomial values supported
*/
typedef enum crc_polynomial {
POLY_7BIT_SD = 0x09, ///< x7+x3+1
POLY_OTHER = 0, ///< Custom polynomial
POLY_8BIT_CCITT = 0x07, ///< x8+x2+x+1
POLY_7BIT_SD = 0x9, ///< x7+x3+1
POLY_16BIT_CCITT = 0x1021, ///< x16+x12+x5+1
POLY_16BIT_IBM = 0x8005, ///< x16+x15+x2+1
POLY_32BIT_ANSI = 0x04C11DB7 ///< x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
POLY_32BIT_ANSI = 0x04C11DB7, ///< x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
POLY_32BIT_REV_ANSI = 0xEDB88320 ///< x31+x30+x29+x27+x26+x24+x23+x21+x20+x19+x15+x9+x8+x5
} crc_polynomial_t;
typedef struct crc_mbed_config {
/** CRC Polynomial. Example polynomial: x^8+x^5+x+1 -> width = 8, polynomial = 0010_0011 = 0x21 */
/** CRC Polynomial. Example polynomial: 0x21 = 0010_0011 = x^5+x+1 */
uint32_t polynomial;
/** CRC Bit Width */
uint32_t width;
@ -64,12 +66,14 @@ extern "C" {
*
* # Defined behaviour
*
* * Macro HAL_CRC_IS_SUPPORTED() evaluates true if platform supports hardware
* * Function hal_crc_is_supported() returns true if platform supports hardware
* CRC for the given polynomial/width - verified by test ::crc_is_supported_test.
* * Macro HAL_CRC_IS_SUPPORTED() evaluates false if platform does not support hardware
* * Function hal_crc_is_supported() returns false if platform does not support hardware
* CRC for the given polynomial/width - verified by test ::crc_is_supported_test.
* * If CRC module does not support any of the following settings: initial_xor, final_xor
* reflect_in, reflect_out, then these operations must be handled by the driver
* * Function hal_crc_is_supported() returns false if given pointer to configuration
* structure is undefined (NULL) - verified by test ::crc_is_supported_invalid_param_test.
* * If CRC module does not support one of the following settings: initial_xor, final_xor
* reflect_in, reflect_out, then these operations should be handled by the driver
* - Verified by test ::crc_calc_single_test.
* * Platform which supports hardware CRC must be able to handle at least one of the predefined
* polynomial/width configurations that can be constructed in the MbedCRC class: POLY_8BIT_CCITT,
@ -105,24 +109,6 @@ extern "C" {
*
* # Potential bugs
*
* # Macros
*
* Platform support for particular CRC polynomials is indicated by the
* macro HAL_CRC_IS_SUPPORTED(polynomial, width), which must be defined
* in device.h, or a file included from there.
*
* The macro must evaluate to a constant boolean expression when given
* constant parameters.
*
* The current platform must support the given polynomial with all possible
* other config parameters if the macro evaluates to true. These are:
* reflect in, reflect out, initial xor and final xor. If any of these settings
* of these settings cannot be configured, the polynomial is not supported.
*
* Example:
*
* #define HAL_CRC_IS_SUPPORTED(polynomial, width) \
* ((width) == 16 || ((width) == 32 && (polynomial) == POLY_32BIT_ANSI)
* @{
*/
@ -136,6 +122,33 @@ extern "C" {
*
*/
/** Determine if the current platform supports hardware CRC for given polynomial
*
* The purpose of this function is to inform the CRC Platform API whether the
* current platform has a hardware CRC module and that it can support the
* requested polynomial.
*
* Supported polynomials are restricted to the named polynomials that can be
* constructed in the MbedCRC class, POLY_8BIT_CCITT, POLY_7BIT_SD,
* POLY_16BIT_CCITT, POLY_16BIT_IBM and POLY_32BIT_ANSI.
*
* The current platform must support the given polynomials default parameters
* in order to return a true response. These include: reflect in, reflect out,
* initial xor and final xor. For example, POLY_32BIT_ANSI requires an initial
* and final xor of 0xFFFFFFFF, and reflection of both input and output. If any
* of these settings cannot be configured, the polynomial is not supported.
*
* This function is thread safe; it safe to call from multiple contexts if
* required.
*
* \param config Contains CRC configuration parameters for initializing the
* hardware CRC module. For example, polynomial and initial seed
* values.
*
* \return True if running if the polynomial is supported, false if not.
*/
bool hal_crc_is_supported(const crc_mbed_config_t *config);
/** Initialize the hardware CRC module with the given polynomial
*
* After calling this function, the CRC HAL module is ready to receive data
@ -150,7 +163,7 @@ extern "C" {
*
* This function must be called with a valid polynomial supported by the
* platform. The polynomial must be checked for support using the
* HAL_CRC_IS_SUPPORTED() macro.
* hal_crc_is_supported() function.
*
* Calling hal_crc_compute_partial_start() multiple times without finalizing the
* CRC calculation with hal_crc_get_result() overrides the current

View File

@ -27,7 +27,6 @@
#include "platform/mbed_power_mgmt.h"
#include "platform/mbed_stats.h"
#include "platform/source/TARGET_CORTEX_M/mbed_fault_handler.h"
#include "drivers/MbedCRC.h"
#include "mbed_rtx.h"
#ifdef MBED_CONF_RTOS_PRESENT
#include "rtx_os.h"
@ -65,6 +64,36 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign
//Global for populating the context in exception handler
static mbed_error_ctx *const report_error_ctx = (mbed_error_ctx *)(ERROR_CONTEXT_LOCATION);
static bool is_reboot_error_valid = false;
//Helper function to calculate CRC
//NOTE: It would have been better to use MbedCRC implementation. But
//MbedCRC uses table based calculation and we dont want to keep that table memory
//used up for this purpose. Also we cannot force bitwise calculation in MbedCRC
//and it also requires a new wrapper to be called from C implementation. Since
//we dont have many uses cases to create a C wrapper for MbedCRC and the data
//we calculate CRC on in this context is very less we will use a local
//implementation here.
static unsigned int compute_crc32(const void *data, int datalen)
{
const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */
unsigned int crc = 0; /* CRC value is 32bit */
unsigned char *buf = (unsigned char *)data;//use a temp variable to make code readable and to avoid typecasting issues.
for (; datalen > 0; datalen--) {
unsigned char b = *buf++;
crc ^= (unsigned int)(b << 24); /* move byte into upper 8bit */
for (int i = 0; i < 8; i++) {
/* is MSB 1 */
if ((crc & 0x80000000) != 0) {
crc = (unsigned int)((crc << 1) ^ polynomial);
} else {
crc <<= 1;
}
}
}
return crc;
}
#endif
//Helper function to halt the system
@ -217,7 +246,7 @@ mbed_error_status_t mbed_error_initialize(void)
//Just check if we have valid value for error_status, if error_status is positive(which is not valid), no need to check crc
if (report_error_ctx->error_status < 0) {
crc_val = mbed_tiny_compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
//Read report_error_ctx and check if CRC is correct, and with valid status code
if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) {
is_reboot_error_valid = true;
@ -229,7 +258,7 @@ mbed_error_status_t mbed_error_initialize(void)
if (report_error_ctx->error_reboot_count > 0) {
report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error
crc_val = mbed_tiny_compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
report_error_ctx->crc_error_ctx = crc_val;
//Enforce max-reboot only if auto reboot is enabled
@ -292,7 +321,7 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
uint32_t crc_val = 0;
crc_val = mbed_tiny_compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
//Read report_error_ctx and check if CRC is correct for report_error_ctx
if (report_error_ctx->crc_error_ctx == crc_val) {
uint32_t current_reboot_count = report_error_ctx->error_reboot_count;
@ -302,7 +331,7 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat
}
last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error
//Update the struct with crc
last_error_ctx.crc_error_ctx = mbed_tiny_compute_crc32(&last_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
last_error_ctx.crc_error_ctx = compute_crc32(&last_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
//Protect report_error_ctx while we update it
core_util_critical_section_enter();
memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx));
@ -355,7 +384,7 @@ mbed_error_status_t mbed_reset_reboot_count()
core_util_critical_section_enter();
report_error_ctx->error_reboot_count = 0;//Set reboot count to 0
//Update CRC
crc_val = mbed_tiny_compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx));
report_error_ctx->crc_error_ctx = crc_val;
core_util_critical_section_exit();
return MBED_SUCCESS;

View File

@ -19,7 +19,6 @@
#include "mbed_assert.h"
#include "mbed_error.h"
#include "cyhal_crc.h"
#include "objects.h"
#if DEVICE_CRC
@ -31,6 +30,11 @@ static cyhal_crc_t cy_crc;
static crc_algorithm_t cy_crc_cfg;
static bool cy_crc_initialized = false;
bool hal_crc_is_supported(const crc_mbed_config_t *config)
{
return config->width <= 32;
}
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
{
if (!cy_crc_initialized) {
@ -39,7 +43,7 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
}
cy_crc_initialized = true;
}
if (!HAL_CRC_IS_SUPPORTED(config->polynomial, config->width)) {
if (!hal_crc_is_supported(config)) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_UNSUPPORTED), "unsupported CRC width");
}
cy_crc_cfg.width = config->width;
@ -73,6 +77,12 @@ uint32_t hal_crc_get_result(void)
}
cyhal_crc_free(&cy_crc);
cy_crc_initialized = false;
// mbed expects result to be aligned unusually in this case
if (0 != (cy_crc_cfg.width % 8) && 0 == cy_crc_cfg.remReverse) {
value ^= cy_crc_cfg.remXor; // Undo result XOR
value <<= 8 - (cy_crc_cfg.width % 8); // Left align to nearest byte
value ^= cy_crc_cfg.remXor; // Redo result XOR
}
return value;
}

View File

@ -121,10 +121,6 @@ struct qspi_s {
};
#endif
#if DEVICE_CRC
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) <= 32)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -23,6 +23,19 @@
static crc_bits_t width;
static uint32_t final_xor;
bool hal_crc_is_supported(const crc_mbed_config_t* config)
{
if (config == NULL) {
return false;
}
if ((config->width != 32) && (config->width != 16)) {
return false;
}
return true;
}
void hal_crc_compute_partial_start(const crc_mbed_config_t* config)
{
if (config == NULL) {
@ -37,7 +50,12 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t* config)
platform_config.seed = config->initial_xor;
platform_config.reflectIn = config->reflect_in;
platform_config.reflectOut = config->reflect_out;
platform_config.complementChecksum = false;
if ((width == kCrcBits16 && config->final_xor == 0xFFFFU) ||
(width == kCrcBits32 && config->final_xor == 0xFFFFFFFFU)) {
platform_config.complementChecksum = true;
} else {
platform_config.complementChecksum = false;
}
platform_config.crcBits = width;
platform_config.crcResult = kCrcFinalChecksum;
@ -61,15 +79,24 @@ uint32_t hal_crc_get_result(void)
{
uint32_t result;
const bool manual_final_xor = ((final_xor != 0x00000000U) &&
((final_xor != 0xFFFFFFFFU && width == kCrcBits32) ||
(final_xor != 0xFFFFU && width == kCrcBits16)));
switch (width)
{
case kCrcBits16:
result = CRC_Get16bitResult(CRC0);
result ^= final_xor;
if (manual_final_xor) {
result ^= final_xor;
result &= 0xFFFF;
}
return result;
case kCrcBits32:
result = CRC_Get32bitResult(CRC0);
result ^= final_xor;
if (manual_final_xor) {
result ^= final_xor;
}
return result;
default:
MBED_ASSERT("Unhandled switch case");

View File

@ -105,10 +105,6 @@ struct qspi_s {
#include "us_ticker_defines.h"
#if DEVICE_CRC
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 16 || (width) == 32)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -36,7 +36,6 @@
#include "PinNames.h"
#include "stm32f0xx_ll_usart.h"
#include "stm32f0xx_ll_tim.h"
#include "stm32f0xx_ll_crc.h"
#ifdef __cplusplus
extern "C" {
@ -120,13 +119,6 @@ struct analogin_s {
uint8_t channel;
};
#ifdef CRC_PROG_POLYNOMIAL_SUPPORT
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#else
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 32 && (polynomial) == 0x04C11DB7)
#endif
#include "gpio_object.h"
#if DEVICE_ANALOGOUT

View File

@ -141,8 +141,6 @@ struct flash_s {
};
#endif
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -161,8 +161,6 @@ struct qspi_s {
};
#endif
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#ifdef __cplusplus
}
#endif

View File

@ -193,8 +193,6 @@ struct can_s {
};
#endif
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
/* rtc_api.c */
#define __HAL_RCC_PWR_CLK_ENABLE()

View File

@ -135,8 +135,6 @@ struct dac_s {
};
#endif
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#ifdef __cplusplus
}
#endif

View File

@ -165,6 +165,4 @@ struct qspi_s {
};
#endif
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#endif

View File

@ -126,8 +126,6 @@ struct analogin_s {
uint8_t channel;
};
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -8,7 +8,6 @@
static CRC_HandleTypeDef current_state;
static uint32_t final_xor;
static uint32_t crc_mask;
static uint32_t result;
/* STM32 CRC preipheral features
+-------------------------+-----------------------+---------------+---------------+
@ -17,13 +16,14 @@ static uint32_t result;
| Reversibility option | NO | YES |
| on I/O data | | |
+-------------------------+-----------------------+---------------+---------------+
| CRC initial Value | Fixed to 0xFFFFFFFF | Programmable |
| CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable |
| | | on 32 bits | on 8,16,32 |
+-------------------------+-----------------------+---------------+---------------+
| Handled data size in bit| 32 | 8,16,32 |
| Handled data size in bit| 32 | 8,16,32 |
+-------------------------+---------------------------------------+---------------+
| Polynomial size in bit | 32 | Fixed/Prog(#1)| 7,8,16,32 |
| Polynomial size in bit | 32 | 7,8,16,32 |
+-------------------------+---------------------------------------+---------------+
| Polynomial coefficients | Fixed to 0x4C11DB7 | Fixed/Prog(#1)| Programmable |
| Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable |
+-------------------------+---------------------------------------+---------------+
#1 The STM32F0 series which supported polynomial in 7, 8, 16, 32 bits as below list:
@ -33,15 +33,36 @@ static uint32_t result;
STM32F091xC
STM32F098xx
*/
bool hal_crc_is_supported(const crc_mbed_config_t *config)
{
if (config == NULL) {
return false;
}
#if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1)
/* Currently, mbed supported input data format fix on bytes,
so those devices are not supported at default. */
return false;
#elif !defined(CRC_POLYLENGTH_7B)
/* Some targets are not support polynomial in 7, 8, 16 bits, ex. STM32F070RB,
so those devices are not supported at default. */
return false;
#else
if (config->width != 32 && config->width != 16 && config->width != 8 && config->width != 7) {
return false;
}
return true;
#endif
}
static uint32_t get_crc_mask(int width)
{
return (uint32_t)((1ull << width) - 1);
return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
}
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
{
MBED_ASSERT(HAL_CRC_IS_SUPPORTED(config->polynomial, config->width));
MBED_ASSERT(hal_crc_is_supported(config));
__HAL_RCC_CRC_CLK_ENABLE();
@ -49,7 +70,7 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
crc_mask = get_crc_mask(config->width);
current_state.Instance = CRC;
#ifdef CRC_POLYLENGTH_7B
#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B)
current_state.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
current_state.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
@ -90,12 +111,35 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
void hal_crc_compute_partial(const uint8_t *data, const size_t size)
{
if (data && size) {
result = HAL_CRC_Accumulate(&current_state, (uint32_t *)data, size);
HAL_CRC_Accumulate(&current_state, (uint32_t *)data, size);
}
}
uint32_t hal_crc_get_result(void)
{
uint32_t result = current_state.Instance->DR;
#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B)
/* The CRC-7 SD needs to shift left by 1 bit after obtaining the result, but the output
* inversion of CRC peripheral will convert the result before shift left by 1 bit, so
* the result seems to have shifted after the conversion.
*
* Example:
* [Gerenal setps]
* 1. Before output inversion: 0x75 (0111 0101)
* 2. Left shift by 1 bit: 0xEA (1110 1010)
* 3. After output inversion: 0x57 (0101 0111)
*
* [STM32 CRC peripheral steps]
* 1. Before output inversion: 0x75 (0111 0101)
* 2. After output inversion: 0x57 (0101 0111) <= no needs shift again
*/
if (current_state.Init.CRCLength == CRC_POLYLENGTH_7B &&
current_state.Init.GeneratingPolynomial == POLY_7BIT_SD &&
current_state.Init.OutputDataInversionMode == CRC_OUTPUTDATA_INVERSION_DISABLE) {
result = result << 1;
}
#endif
return (result ^ final_xor) & crc_mask;
}

View File

@ -166,11 +166,6 @@ struct qspi_s {
};
#endif
#if DEVICE_CRC
//GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 16 || ((width) == 32 && (polynomial) == POLY_32BIT_ANSI))
#endif
#ifdef __cplusplus
}
#endif

View File

@ -37,8 +37,32 @@ static bool revOutput = false;
static bool enableWordInput = false;
static uint32_t final_xor;
bool hal_crc_is_supported(const crc_mbed_config_t *config)
{
//GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly
if (config == NULL) {
return false;
}
if (config->width == 16) {
return true;
} else if (config->width == 32) {
if (config->polynomial == POLY_32BIT_ANSI) {
return true;
} else {
return false;
}
} else {
return false;
}
}
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
{
if (!hal_crc_is_supported(config)) {
return;
}
CMU_ClockEnable(cmuClock_GPCRC, true);
GPCRC_Reset(GPCRC);
@ -61,7 +85,11 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
// GPCRC operates on bit-reversed inputs and outputs vs the standard
// defined by the mbed API, so reflect_in/out needs to be negated.
crc_init.reverseBits = !config->reflect_in;
if (config->reflect_in) {
crc_init.reverseBits = false;
} else {
crc_init.reverseBits = true;
}
// Input is little-endian
crc_init.reverseByteOrder = false;

View File

@ -20,36 +20,48 @@
#ifdef DEVICE_CRC
static bool reflect_in;
static bool reflect_out;
static uint32_t final_xor;
bool hal_crc_is_supported(const crc_mbed_config_t *config)
{
if (config == NULL) {
return false;
}
// Currently supported only CRC16_CCITT polynomial.
if (config->polynomial != POLY_16BIT_CCITT) {
return false;
}
if (config->width != 16) {
return false;
}
// Not support for reflect_in and reflect_out.
if ((config->reflect_in == true) || (config->reflect_out == true)) {
return false;
}
return true;
}
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
{
TSB_CG_FSYSENB_IPENB20 = 1;
// Intial Value as initial_xor
TSB_CRC->CLC = config->initial_xor;
reflect_in = config->reflect_in;
reflect_out = config->reflect_out;
final_xor = config->final_xor;
// Data width setting CRC data width is 8 bits (--01)
// Form setting CRC form is CRC16 (00--) or CRC32 (11--)
TSB_CRC->TYP = config->width == 16 ? 0x01 : 0x0D;
// Data width setting CRC data width is 8 bits.
// Form setting CRC form is CRC16.
TSB_CRC->TYP = 0x01;
}
void hal_crc_compute_partial(const uint8_t *data, const size_t size)
{
if (data && size) {
uint32_t index = 0U;
bool reflect = reflect_in;
for(index = 0U; index < size; index++) {
unsigned int byte = data[index];
if (reflect) {
byte = __RBIT(byte) >> 24;
}
TSB_CRC->DIN = byte;
TSB_CRC->DIN = data[index];
}
}
}
@ -60,14 +72,7 @@ uint32_t hal_crc_get_result(void)
// Note: Please read [CRCCLC] twice and use the result of the 2nd time
result = TSB_CRC->CLC;
result = TSB_CRC->CLC;
if (reflect_out) {
result = __RBIT(result);
if ((TSB_CRC->TYP & 0x0C) == 0) {
result >>= 16;
}
}
result ^= final_xor;
result = TSB_CRC->CLC ^ final_xor;
return (result);
}

View File

@ -120,9 +120,6 @@ struct flash_s {
int flash_inited;
};
#define HAL_CRC_IS_SUPPORTED(polynomial, width) (((width) == 16 && (polynomial) == 0x1021) || \
((width) == 32 && (polynomial) == 0x04C11DB7))
extern const gpio_regtypedef_t GPIO_SFRs[];
extern const uint32_t GPIO_Base[];