diff --git a/TESTS/mbed_hal/crc/main.cpp b/TESTS/mbed_hal/crc/main.cpp index 5976059..f2bd505 100644 --- a/TESTS/mbed_hal/crc/main.cpp +++ b/TESTS/mbed_hal/crc/main.cpp @@ -54,7 +54,7 @@ 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) == true) { + if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) { num_of_supported_polynomials++; } @@ -68,7 +68,7 @@ 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) == true) { + if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) { 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_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) == true) { + if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) { const uint32_t first_part_bytes = 3; const uint32_t second_part_bytes = 1; @@ -117,7 +117,7 @@ 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) == true) { + if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) { if (pol_cnt == 0) { pol_idx[pol_cnt] = i; pol_cnt++; @@ -159,7 +159,7 @@ /* 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) == true) { + if (HAL_CRC_IS_SUPPORTED(test_cases[i].config_data.polynomial, test_cases[i].config_data.width)) { hal_crc_compute_partial_start(&test_cases[i].config_data); @@ -180,19 +180,12 @@ } } -/* 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) @@ -208,12 +201,12 @@ // *INDENT-OFF* TEST_CASE local_test_cases[] = { /* Predefined polynomials. */ - /* 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 }, + /* 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 }, /* 06 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, true }, 0x57 }, /* 07 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, false}, 0xF4 }, diff --git a/UNITTESTS/empty_baseline/unittest.cmake b/UNITTESTS/empty_baseline/unittest.cmake index ce761c1..15545ec 100644 --- a/UNITTESTS/empty_baseline/unittest.cmake +++ b/UNITTESTS/empty_baseline/unittest.cmake @@ -48,7 +48,7 @@ empty_baseline/empty_baseline.cpp ) -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(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(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}") diff --git a/hal/crc_api.h b/hal/crc_api.h index 5d3330b..5cae61b 100644 --- a/hal/crc_api.h +++ b/hal/crc_api.h @@ -28,17 +28,15 @@ * Different polynomial values supported */ typedef enum crc_polynomial { - POLY_OTHER = 0, ///< Custom polynomial + POLY_7BIT_SD = 0x09, ///< x7+x3+1 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_REV_ANSI = 0xEDB88320 ///< x31+x30+x29+x27+x26+x24+x23+x21+x20+x19+x15+x9+x8+x5 + POLY_32BIT_ANSI = 0x04C11DB7 ///< x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 } crc_polynomial_t; typedef struct crc_mbed_config { - /** CRC Polynomial. Example polynomial: 0x21 = 0010_0011 = x^5+x+1 */ + /** CRC Polynomial. Example polynomial: x^8+x^5+x+1 -> width = 8, polynomial = 0010_0011 = 0x21 */ uint32_t polynomial; /** CRC Bit Width */ uint32_t width; @@ -66,14 +64,12 @@ * * # Defined behaviour * - * * Function hal_crc_is_supported() returns true if platform supports hardware + * * Macro HAL_CRC_IS_SUPPORTED() evaluates true if platform supports hardware * CRC for the given polynomial/width - verified by test ::crc_is_supported_test. - * * Function hal_crc_is_supported() returns false if platform does not support hardware + * * Macro HAL_CRC_IS_SUPPORTED() evaluates false if platform does not support hardware * CRC for the given polynomial/width - verified by test ::crc_is_supported_test. - * * 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 + * * 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 * - 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, @@ -109,6 +105,24 @@ * * # 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) * @{ */ @@ -122,33 +136,6 @@ * */ -/** 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 @@ -163,7 +150,7 @@ * * 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() function. + * HAL_CRC_IS_SUPPORTED() macro. * * Calling hal_crc_compute_partial_start() multiple times without finalizing the * CRC calculation with hal_crc_get_result() overrides the current diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/cy_crc_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/cy_crc_api.c index e3a9891..87f2eb4 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/cy_crc_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/cy_crc_api.c @@ -19,6 +19,7 @@ #include "mbed_assert.h" #include "mbed_error.h" #include "cyhal_crc.h" +#include "objects.h" #if DEVICE_CRC @@ -30,11 +31,6 @@ 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) { @@ -43,7 +39,7 @@ } cy_crc_initialized = true; } - if (!hal_crc_is_supported(config)) { + if (!HAL_CRC_IS_SUPPORTED(config->polynomial, config->width)) { MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_UNSUPPORTED), "unsupported CRC width"); } cy_crc_cfg.width = config->width; @@ -77,12 +73,6 @@ } 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; } diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/objects.h b/targets/TARGET_Cypress/TARGET_PSOC6/objects.h index 9b52096..ac1655e 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/objects.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/objects.h @@ -121,6 +121,10 @@ }; #endif +#if DEVICE_CRC +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) <= 32) +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/mbed_crc_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/mbed_crc_api.c index d61f0b1..d8de507 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/mbed_crc_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/mbed_crc_api.c @@ -23,19 +23,6 @@ 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) { @@ -50,12 +37,7 @@ platform_config.seed = config->initial_xor; platform_config.reflectIn = config->reflect_in; platform_config.reflectOut = config->reflect_out; - if ((width == kCrcBits16 && config->final_xor == 0xFFFFU) || - (width == kCrcBits32 && config->final_xor == 0xFFFFFFFFU)) { - platform_config.complementChecksum = true; - } else { - platform_config.complementChecksum = false; - } + platform_config.complementChecksum = false; platform_config.crcBits = width; platform_config.crcResult = kCrcFinalChecksum; @@ -79,24 +61,15 @@ { 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); - if (manual_final_xor) { - result ^= final_xor; - result &= 0xFFFF; - } + result ^= final_xor; return result; case kCrcBits32: result = CRC_Get32bitResult(CRC0); - if (manual_final_xor) { - result ^= final_xor; - } + result ^= final_xor; return result; default: MBED_ASSERT("Unhandled switch case"); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/objects.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/objects.h index 0dec0dc..85b6004 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/objects.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/objects.h @@ -105,6 +105,10 @@ #include "us_ticker_defines.h" +#if DEVICE_CRC +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 16 || (width) == 32) +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h index 9b2f8a2..2381301 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h @@ -37,6 +37,7 @@ #include "stm32f0xx_ll_usart.h" #include "stm32f0xx_ll_tim.h" #include "stm32f0xx_ll_pwr.h" +#include "stm32f0xx_ll_crc.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h index d58f1aa..6f960dd 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h @@ -144,6 +144,8 @@ }; #endif +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32) + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h index a4e6096..e98f122 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h @@ -162,6 +162,8 @@ }; #endif +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32) + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32H7/objects.h b/targets/TARGET_STM/TARGET_STM32H7/objects.h index 5512111..afbd3ba 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -193,6 +193,8 @@ }; #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() diff --git a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h index 7c5a8dc..f4540c0 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h @@ -138,6 +138,8 @@ }; #endif +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32) + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h index daeb0a2..bbbcb52 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h @@ -168,4 +168,6 @@ }; #endif +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32) + #endif diff --git a/targets/TARGET_STM/TARGET_STM32WB/common_objects.h b/targets/TARGET_STM/TARGET_STM32WB/common_objects.h index 156caa8..b104d8f 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32WB/common_objects.h @@ -127,6 +127,8 @@ uint8_t channel; }; +#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32) + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index a904e4f..62d4bd5 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -8,6 +8,7 @@ static CRC_HandleTypeDef current_state; static uint32_t final_xor; static uint32_t crc_mask; +static uint32_t result; /* STM32 CRC preipheral features +-------------------------+-----------------------+---------------+---------------+ @@ -16,14 +17,13 @@ | Reversibility option | NO | YES | | on I/O data | | | +-------------------------+-----------------------+---------------+---------------+ - | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable | - | | | on 32 bits | on 8,16,32 | + | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | +-------------------------+-----------------------+---------------+---------------+ - | Handled data size in bit| 32 | 8,16,32 | + | Handled data size in bit| 32 | 8,16,32 | +-------------------------+---------------------------------------+---------------+ - | Polynomial size in bit | 32 | 7,8,16,32 | + | Polynomial size in bit | 32 | Fixed/Prog(#1)| 7,8,16,32 | +-------------------------+---------------------------------------+---------------+ - | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | + | Polynomial coefficients | Fixed to 0x4C11DB7 | Fixed/Prog(#1)| Programmable | +-------------------------+---------------------------------------+---------------+ #1 The STM32F0 series which supported polynomial in 7, 8, 16, 32 bits as below list: @@ -33,36 +33,15 @@ 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 (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1)); + return (uint32_t)((1ull << width) - 1); } void hal_crc_compute_partial_start(const crc_mbed_config_t *config) { - MBED_ASSERT(hal_crc_is_supported(config)); + MBED_ASSERT(HAL_CRC_IS_SUPPORTED(config->polynomial, config->width)); __HAL_RCC_CRC_CLK_ENABLE(); @@ -70,7 +49,7 @@ crc_mask = get_crc_mask(config->width); current_state.Instance = CRC; -#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B) +#ifdef 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; @@ -111,35 +90,12 @@ void hal_crc_compute_partial(const uint8_t *data, const size_t size) { if (data && size) { - HAL_CRC_Accumulate(¤t_state, (uint32_t *)data, size); + result = HAL_CRC_Accumulate(¤t_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; } diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/objects.h b/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/objects.h index 516388b..1e8d581 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/objects.h +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/objects.h @@ -166,6 +166,11 @@ }; #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 diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/crc_api.c b/targets/TARGET_Silicon_Labs/TARGET_EFM32/crc_api.c index 68ed6c7..316869a 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/crc_api.c +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/crc_api.c @@ -37,32 +37,8 @@ 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); @@ -85,11 +61,7 @@ // GPCRC operates on bit-reversed inputs and outputs vs the standard // defined by the mbed API, so reflect_in/out needs to be negated. - if (config->reflect_in) { - crc_init.reverseBits = false; - } else { - crc_init.reverseBits = true; - } + crc_init.reverseBits = !config->reflect_in; // Input is little-endian crc_init.reverseByteOrder = false; diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/crc_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/crc_api.c index 7875787..0250d5e 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/crc_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/crc_api.c @@ -20,48 +20,36 @@ #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. - // Form setting CRC form is CRC16. - TSB_CRC->TYP = 0x01; + // 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; } 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++) { - TSB_CRC->DIN = data[index]; + unsigned int byte = data[index]; + if (reflect) { + byte = __RBIT(byte) >> 24; + } + TSB_CRC->DIN = byte; } } } @@ -72,7 +60,14 @@ // Note: Please read [CRCCLC] twice and use the result of the 2nd time result = TSB_CRC->CLC; - result = TSB_CRC->CLC ^ final_xor; + result = TSB_CRC->CLC; + if (reflect_out) { + result = __RBIT(result); + if ((TSB_CRC->TYP & 0x0C) == 0) { + result >>= 16; + } + } + result ^= final_xor; return (result); } diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/objects.h b/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/objects.h index 43cd308..c14c662 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/objects.h +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/objects.h @@ -120,6 +120,9 @@ 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[];