mirror of https://github.com/ARMmbed/mbed-os.git
Update HAL CRC API
* Change "is supported" check to be a macro, so it can be done at compile-time. * Eliminate weird shift on 7-bit CRCs. * Add support for 32-bit CRCs and reversals to TMPM3HQ.pull/11957/head
parent
48f544f9e4
commit
fe22bc023e
|
@ -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) == 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_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) == 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_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) == 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 @@ 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) == 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 @@ 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) == 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 @@ 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)
|
||||
|
@ -208,12 +201,12 @@ int main()
|
|||
// *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 },
|
||||
|
|
|
@ -48,7 +48,7 @@ set(unittest-test-sources
|
|||
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}")
|
||||
|
|
|
@ -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 @@ extern "C" {
|
|||
*
|
||||
* # 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 @@ 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)
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
@ -122,33 +136,6 @@ 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
|
||||
|
@ -163,7 +150,7 @@ bool hal_crc_is_supported(const crc_mbed_config_t *config);
|
|||
*
|
||||
* 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
|
||||
|
|
|
@ -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 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) {
|
||||
|
@ -43,7 +39,7 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
|
|||
}
|
||||
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 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,10 @@ struct qspi_s {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if DEVICE_CRC
|
||||
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) <= 32)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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 @@ 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;
|
||||
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 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);
|
||||
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");
|
||||
|
|
|
@ -105,6 +105,10 @@ 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
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -144,6 +144,8 @@ 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
|
||||
|
|
|
@ -162,6 +162,8 @@ struct qspi_s {
|
|||
};
|
||||
#endif
|
||||
|
||||
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -193,6 +193,8 @@ 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()
|
||||
|
||||
|
|
|
@ -138,6 +138,8 @@ struct dac_s {
|
|||
};
|
||||
#endif
|
||||
|
||||
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -168,4 +168,6 @@ struct qspi_s {
|
|||
};
|
||||
#endif
|
||||
|
||||
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -127,6 +127,8 @@ 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
|
||||
|
|
|
@ -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 @@ static uint32_t crc_mask;
|
|||
| 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 @@ static uint32_t crc_mask;
|
|||
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 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
|
|||
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_start(const crc_mbed_config_t *config)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,11 @@ 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
|
||||
|
|
|
@ -37,32 +37,8 @@ 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);
|
||||
|
||||
|
@ -85,11 +61,7 @@ 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.
|
||||
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;
|
||||
|
|
|
@ -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 @@ 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 ^ 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);
|
||||
}
|
||||
|
|
|
@ -120,6 +120,9 @@ 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[];
|
||||
|
||||
|
|
Loading…
Reference in New Issue