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
Kevin Bracey 2019-09-24 16:45:22 +03:00
parent 48f544f9e4
commit fe22bc023e
19 changed files with 103 additions and 208 deletions

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) == 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 },

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_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}")

View File

@ -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

View File

@ -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;
}

View File

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

View File

@ -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");

View File

@ -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

View File

@ -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" {

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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

View File

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

View File

@ -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

View File

@ -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(&current_state, (uint32_t *)data, size);
result = 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,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

View File

@ -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;

View File

@ -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);
}

View File

@ -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[];