From 1c2ffb8eb3a6f0bc6e62cbb1b81503f43a3db177 Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Fri, 11 Jan 2019 11:52:49 +0800 Subject: [PATCH 1/7] stm32: Improve the CRC function to support fully accumulate Tested on DISCO_L476VG and NUCLEO_L476RG --- targets/TARGET_STM/mbed_crc_api.c | 94 +++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 2a17ee2a63..1a94d7a5c4 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -7,28 +7,56 @@ static CRC_HandleTypeDef current_state; static uint32_t final_xor; +static uint32_t crc_mask; +/* STM32 CRC preipheral features + +-------------------------+-----------------------+---------------+---------------+ + | Feature | F1/L1/F2/F4 series | F0 series | L0/F3/L4/F7 | + +-========================+=======================+===============+===============+ + | Reversibility option | NO | YES | + | on I/O data | | | + +-------------------------+-----------------------+---------------+---------------+ + | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable | + | | | on 32 bits | on 8,16,32 | + +-------------------------+-----------------------+---------------+---------------+ + | Handled data size in bit| 32 | 8,16,32 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial size in bit | 32 | 7,8,16,32 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | + +-------------------------+---------------------------------------+---------------+ + */ bool hal_crc_is_supported(const crc_mbed_config_t *config) { if (config == NULL) { return false; } - if (config->polynomial != POLY_32BIT_ANSI) { +#if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1) + if (config->width != HAL_CRC_LENGTH_32B || config->polynomial != POLY_32BIT_ANSI || + config->initial_xor != 0xFFFFFFFF || config->reflect_in || config->reflect_out) { return false; } - - if (config->width != 32) { +#elif defined(TARGET_STM32F0) + if (config->width != HAL_CRC_LENGTH_32B || config->polynomial != POLY_32BIT_ANSI) { return false; } - - if ((config->final_xor != 0xFFFFFFFFU) && (config->final_xor != 0)) { +#else + /* TARGET_STM32L0, TARGET_STM32F3, TARGET_STM32L4, TARGET_STM32F7 */ + if (config->width != HAL_CRC_LENGTH_32B && config->width != HAL_CRC_LENGTH_16B && + config->width != HAL_CRC_LENGTH_8B && config->width != HAL_CRC_LENGTH_7B) { return false; } +#endif return true; } +static uint32_t get_crc_mask(int width) +{ + 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)); @@ -36,21 +64,47 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config) __HAL_RCC_CRC_CLK_ENABLE(); final_xor = config->final_xor; + crc_mask = get_crc_mask(config->width); current_state.Instance = CRC; +#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) current_state.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; - current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; current_state.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; current_state.Init.InitValue = config->initial_xor; - current_state.Init.CRCLength = CRC_POLYLENGTH_32B; + current_state.Init.GeneratingPolynomial = config->polynomial; + + switch (config->width) + { + case HAL_CRC_LENGTH_32B: + current_state.Init.CRCLength = CRC_POLYLENGTH_32B; + break; + + case HAL_CRC_LENGTH_16B: + current_state.Init.CRCLength = CRC_POLYLENGTH_16B; + break; + case HAL_CRC_LENGTH_8B: + current_state.Init.CRCLength = CRC_POLYLENGTH_8B; + break; + case HAL_CRC_LENGTH_7B: + current_state.Init.CRCLength = CRC_POLYLENGTH_7B; + break; + default: + MBED_ASSERT(false); + break; + } + current_state.Init.InputDataInversionMode = config->reflect_in ? CRC_INPUTDATA_INVERSION_BYTE : CRC_INPUTDATA_INVERSION_NONE; current_state.Init.OutputDataInversionMode = config->reflect_out ? CRC_OUTPUTDATA_INVERSION_ENABLE : CRC_OUTPUTDATA_INVERSION_DISABLE; +#endif - HAL_CRC_Init(¤t_state); + if (HAL_CRC_Init(¤t_state) != HAL_OK) { + MBED_ASSERT(false); + } } void hal_crc_compute_partial(const uint8_t *data, const size_t size) @@ -62,9 +116,29 @@ void hal_crc_compute_partial(const uint8_t *data, const size_t size) uint32_t hal_crc_get_result(void) { - const uint32_t result = current_state.Instance->DR; + uint32_t result = current_state.Instance->DR; - return (final_xor == 0xFFFFFFFFU) ? ~result : result; +#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) + /* 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; } #endif // DEVICE_CRC From 19cdba44520ef4c5f8dbe6a488b1fcd324166142 Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Fri, 11 Jan 2019 12:41:41 +0800 Subject: [PATCH 2/7] stm32: remove empty line --- targets/TARGET_STM/mbed_crc_api.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 1a94d7a5c4..6a8736494f 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -79,7 +79,6 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config) case HAL_CRC_LENGTH_32B: current_state.Init.CRCLength = CRC_POLYLENGTH_32B; break; - case HAL_CRC_LENGTH_16B: current_state.Init.CRCLength = CRC_POLYLENGTH_16B; break; From 603b8e6eb4294a6533a25224653634ffaab074d2 Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Sat, 12 Jan 2019 01:20:36 +0800 Subject: [PATCH 3/7] stm32: fix F1/F2/F4/L1 compile fail after enable CRC Those series have not CRC_POLYLENGTH_32B definition --- targets/TARGET_STM/mbed_crc_api.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 6a8736494f..3986fcc08e 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -33,18 +33,17 @@ bool hal_crc_is_supported(const crc_mbed_config_t *config) } #if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1) - if (config->width != HAL_CRC_LENGTH_32B || config->polynomial != POLY_32BIT_ANSI || + if (config->width != 32 || config->polynomial != POLY_32BIT_ANSI || config->initial_xor != 0xFFFFFFFF || config->reflect_in || config->reflect_out) { return false; } #elif defined(TARGET_STM32F0) - if (config->width != HAL_CRC_LENGTH_32B || config->polynomial != POLY_32BIT_ANSI) { + if (config->width != 32 || config->polynomial != POLY_32BIT_ANSI) { return false; } #else - /* TARGET_STM32L0, TARGET_STM32F3, TARGET_STM32L4, TARGET_STM32F7 */ - if (config->width != HAL_CRC_LENGTH_32B && config->width != HAL_CRC_LENGTH_16B && - config->width != HAL_CRC_LENGTH_8B && config->width != HAL_CRC_LENGTH_7B) { + /* Fully function support on L0, F3, L4, F7, H7 and newer series */ + if (config->width != 32 && config->width != 16 && config->width != 8 && config->width != 7) { return false; } #endif From 995594be2889d45d5b9bc9675b50f0c1947f9220 Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Sat, 12 Jan 2019 01:50:06 +0800 Subject: [PATCH 4/7] stm32: F1/F2/F4/L1 set to not supported HW CRC Currently, mbed supported input data format fix on bytes, so those devices are not supported at default. --- targets/TARGET_STM/mbed_crc_api.c | 41 +++++++++++++------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 3986fcc08e..d4c564d816 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -10,21 +10,21 @@ static uint32_t final_xor; static uint32_t crc_mask; /* STM32 CRC preipheral features - +-------------------------+-----------------------+---------------+---------------+ - | Feature | F1/L1/F2/F4 series | F0 series | L0/F3/L4/F7 | - +-========================+=======================+===============+===============+ + +-------------------------+-----------------------+-------------------------------+ + | Feature | F1/L1/F2/F4 series | F0/L0/F3/L4/F7/H7 or newer | + +-========================+=======================+===============================+ | Reversibility option | NO | YES | | on I/O data | | | - +-------------------------+-----------------------+---------------+---------------+ - | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable | - | | | on 32 bits | on 8,16,32 | - +-------------------------+-----------------------+---------------+---------------+ - | Handled data size in bit| 32 | 8,16,32 | - +-------------------------+---------------------------------------+---------------+ - | Polynomial size in bit | 32 | 7,8,16,32 | - +-------------------------+---------------------------------------+---------------+ - | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | - +-------------------------+---------------------------------------+---------------+ + +-------------------------+-----------------------+-------------------------------+ + | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable on 8, 16, 32 | + | | | bits | + +-------------------------+-----------------------+-------------------------------+ + | Handled data size in bit| 32 | 8, 16, 32 | + +-------------------------+-----------------------+-------------------------------+ + | Polynomial size in bit | 32 | 7, 8, 16, 32 | + +-------------------------+-----------------------+-------------------------------+ + | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | + +-------------------------+-----------------------+-------------------------------+ */ bool hal_crc_is_supported(const crc_mbed_config_t *config) { @@ -33,22 +33,15 @@ bool hal_crc_is_supported(const crc_mbed_config_t *config) } #if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1) - if (config->width != 32 || config->polynomial != POLY_32BIT_ANSI || - config->initial_xor != 0xFFFFFFFF || config->reflect_in || config->reflect_out) { - return false; - } -#elif defined(TARGET_STM32F0) - if (config->width != 32 || config->polynomial != POLY_32BIT_ANSI) { - return false; - } + /* Currently, mbed supported input data format fix on bytes, + so those devices are not supported at default. */ + return false; #else - /* Fully function support on L0, F3, L4, F7, H7 and newer series */ if (config->width != 32 && config->width != 16 && config->width != 8 && config->width != 7) { return false; } -#endif - return true; +#endif } static uint32_t get_crc_mask(int width) From 8d58f8bae725683a2ee5a352169901d95f345dbd Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Thu, 17 Jan 2019 16:28:53 +0800 Subject: [PATCH 5/7] stm32: fix some F0 target compile error --- targets/TARGET_STM/mbed_crc_api.c | 45 +++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index d4c564d816..061c4ee468 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -10,22 +10,29 @@ static uint32_t final_xor; static uint32_t crc_mask; /* STM32 CRC preipheral features - +-------------------------+-----------------------+-------------------------------+ - | Feature | F1/L1/F2/F4 series | F0/L0/F3/L4/F7/H7 or newer | - +-========================+=======================+===============================+ + +-------------------------+-----------------------+---------------+---------------+ + | Feature | F1/L1/F2/F4 series | F0 series (#1)| L0/F3/L4/F7 | + +-========================+=======================+===============+===============+ | Reversibility option | NO | YES | | on I/O data | | | - +-------------------------+-----------------------+-------------------------------+ - | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable on 8, 16, 32 | - | | | bits | - +-------------------------+-----------------------+-------------------------------+ - | Handled data size in bit| 32 | 8, 16, 32 | - +-------------------------+-----------------------+-------------------------------+ - | Polynomial size in bit | 32 | 7, 8, 16, 32 | - +-------------------------+-----------------------+-------------------------------+ - | Polynomial coefficients | Fixed to 0x4C11DB7 | 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 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial size in bit | 32 | 7,8,16,32 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | + +-------------------------+---------------------------------------+---------------+ + + #1 The STM32F0 series which supported polynomial in 7, 8, 16, 32 bits as below list: + STM32F071xB + STM32F072xB + STM32F078xx + STM32F091xC + STM32F098xx +*/ bool hal_crc_is_supported(const crc_mbed_config_t *config) { if (config == NULL) { @@ -36,6 +43,10 @@ bool hal_crc_is_supported(const crc_mbed_config_t *config) /* 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. STMF070RB, + 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; @@ -59,10 +70,10 @@ 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) +#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.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; current_state.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; + current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; current_state.Init.InitValue = config->initial_xor; current_state.Init.GeneratingPolynomial = config->polynomial; @@ -109,7 +120,7 @@ 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) +#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. From 559881598240994c6e7cb6ff1b6b61d394df5839 Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Thu, 17 Jan 2019 16:35:07 +0800 Subject: [PATCH 6/7] stm32: fix typo --- targets/TARGET_STM/mbed_crc_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 061c4ee468..14139ac3e8 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -44,7 +44,7 @@ bool hal_crc_is_supported(const crc_mbed_config_t *config) 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. STMF070RB, + /* Some targets are not support polynomial in 7, 8, 16 bits, ex. STM32F070RB, so those devices are not supported at default. */ return false; #else From 5ccdd67f6ce0dbaa027667445cf77e76a175b46b Mon Sep 17 00:00:00 2001 From: "kevin.ong" Date: Thu, 17 Jan 2019 16:39:31 +0800 Subject: [PATCH 7/7] stm32: fix indent style --- targets/TARGET_STM/mbed_crc_api.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 14139ac3e8..33023261f5 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -104,9 +104,9 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config) : CRC_OUTPUTDATA_INVERSION_DISABLE; #endif - if (HAL_CRC_Init(¤t_state) != HAL_OK) { - MBED_ASSERT(false); - } + if (HAL_CRC_Init(¤t_state) != HAL_OK) { + MBED_ASSERT(false); + } } void hal_crc_compute_partial(const uint8_t *data, const size_t size)