mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_STM/mbed_crc_api.c@189:f392fc9709a3, 2019-02-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Feb 20 22:31:08 2019 +0000
- Revision:
- 189:f392fc9709a3
- Parent:
- 187:0387e8f68319
mbed library release version 165
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
186:707f6e361f3e | 1 | #include "crc_api.h" |
Anna Bridge |
186:707f6e361f3e | 2 | #include "device.h" |
Anna Bridge |
186:707f6e361f3e | 3 | |
Anna Bridge |
186:707f6e361f3e | 4 | #include "platform/mbed_assert.h" |
Anna Bridge |
186:707f6e361f3e | 5 | |
AnnaBridge | 189:f392fc9709a3 | 6 | #if DEVICE_CRC |
Anna Bridge |
186:707f6e361f3e | 7 | |
Anna Bridge |
186:707f6e361f3e | 8 | static CRC_HandleTypeDef current_state; |
Anna Bridge |
186:707f6e361f3e | 9 | static uint32_t final_xor; |
AnnaBridge | 189:f392fc9709a3 | 10 | static uint32_t crc_mask; |
Anna Bridge |
186:707f6e361f3e | 11 | |
AnnaBridge | 189:f392fc9709a3 | 12 | /* STM32 CRC preipheral features |
AnnaBridge | 189:f392fc9709a3 | 13 | +-------------------------+-----------------------+---------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 14 | | Feature | F1/L1/F2/F4 series | F0 series (#1)| L0/F3/L4/F7 | |
AnnaBridge | 189:f392fc9709a3 | 15 | +-========================+=======================+===============+===============+ |
AnnaBridge | 189:f392fc9709a3 | 16 | | Reversibility option | NO | YES | |
AnnaBridge | 189:f392fc9709a3 | 17 | | on I/O data | | | |
AnnaBridge | 189:f392fc9709a3 | 18 | +-------------------------+-----------------------+---------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 19 | | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable | |
AnnaBridge | 189:f392fc9709a3 | 20 | | | | on 32 bits | on 8,16,32 | |
AnnaBridge | 189:f392fc9709a3 | 21 | +-------------------------+-----------------------+---------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 22 | | Handled data size in bit| 32 | 8,16,32 | |
AnnaBridge | 189:f392fc9709a3 | 23 | +-------------------------+---------------------------------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 24 | | Polynomial size in bit | 32 | 7,8,16,32 | |
AnnaBridge | 189:f392fc9709a3 | 25 | +-------------------------+---------------------------------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 26 | | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | |
AnnaBridge | 189:f392fc9709a3 | 27 | +-------------------------+---------------------------------------+---------------+ |
AnnaBridge | 189:f392fc9709a3 | 28 | |
AnnaBridge | 189:f392fc9709a3 | 29 | #1 The STM32F0 series which supported polynomial in 7, 8, 16, 32 bits as below list: |
AnnaBridge | 189:f392fc9709a3 | 30 | STM32F071xB |
AnnaBridge | 189:f392fc9709a3 | 31 | STM32F072xB |
AnnaBridge | 189:f392fc9709a3 | 32 | STM32F078xx |
AnnaBridge | 189:f392fc9709a3 | 33 | STM32F091xC |
AnnaBridge | 189:f392fc9709a3 | 34 | STM32F098xx |
AnnaBridge | 189:f392fc9709a3 | 35 | */ |
AnnaBridge | 187:0387e8f68319 | 36 | bool hal_crc_is_supported(const crc_mbed_config_t *config) |
Anna Bridge |
186:707f6e361f3e | 37 | { |
AnnaBridge | 187:0387e8f68319 | 38 | if (config == NULL) { |
AnnaBridge | 187:0387e8f68319 | 39 | return false; |
AnnaBridge | 187:0387e8f68319 | 40 | } |
Anna Bridge |
186:707f6e361f3e | 41 | |
AnnaBridge | 189:f392fc9709a3 | 42 | #if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1) |
AnnaBridge | 189:f392fc9709a3 | 43 | /* Currently, mbed supported input data format fix on bytes, |
AnnaBridge | 189:f392fc9709a3 | 44 | so those devices are not supported at default. */ |
AnnaBridge | 189:f392fc9709a3 | 45 | return false; |
AnnaBridge | 189:f392fc9709a3 | 46 | #elif !defined(CRC_POLYLENGTH_7B) |
AnnaBridge | 189:f392fc9709a3 | 47 | /* Some targets are not support polynomial in 7, 8, 16 bits, ex. STM32F070RB, |
AnnaBridge | 189:f392fc9709a3 | 48 | so those devices are not supported at default. */ |
AnnaBridge | 189:f392fc9709a3 | 49 | return false; |
AnnaBridge | 189:f392fc9709a3 | 50 | #else |
AnnaBridge | 189:f392fc9709a3 | 51 | if (config->width != 32 && config->width != 16 && config->width != 8 && config->width != 7) { |
AnnaBridge | 187:0387e8f68319 | 52 | return false; |
AnnaBridge | 187:0387e8f68319 | 53 | } |
AnnaBridge | 189:f392fc9709a3 | 54 | return true; |
AnnaBridge | 189:f392fc9709a3 | 55 | #endif |
AnnaBridge | 189:f392fc9709a3 | 56 | } |
Anna Bridge |
186:707f6e361f3e | 57 | |
AnnaBridge | 189:f392fc9709a3 | 58 | static uint32_t get_crc_mask(int width) |
AnnaBridge | 189:f392fc9709a3 | 59 | { |
AnnaBridge | 189:f392fc9709a3 | 60 | return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1)); |
Anna Bridge |
186:707f6e361f3e | 61 | } |
Anna Bridge |
186:707f6e361f3e | 62 | |
AnnaBridge | 187:0387e8f68319 | 63 | void hal_crc_compute_partial_start(const crc_mbed_config_t *config) |
Anna Bridge |
186:707f6e361f3e | 64 | { |
AnnaBridge | 187:0387e8f68319 | 65 | MBED_ASSERT(hal_crc_is_supported(config)); |
Anna Bridge |
186:707f6e361f3e | 66 | |
AnnaBridge | 187:0387e8f68319 | 67 | __HAL_RCC_CRC_CLK_ENABLE(); |
Anna Bridge |
186:707f6e361f3e | 68 | |
AnnaBridge | 187:0387e8f68319 | 69 | final_xor = config->final_xor; |
AnnaBridge | 189:f392fc9709a3 | 70 | crc_mask = get_crc_mask(config->width); |
Anna Bridge |
186:707f6e361f3e | 71 | |
AnnaBridge | 187:0387e8f68319 | 72 | current_state.Instance = CRC; |
AnnaBridge | 189:f392fc9709a3 | 73 | #if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B) |
AnnaBridge | 187:0387e8f68319 | 74 | current_state.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; |
AnnaBridge | 187:0387e8f68319 | 75 | current_state.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; |
AnnaBridge | 189:f392fc9709a3 | 76 | current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 77 | current_state.Init.InitValue = config->initial_xor; |
AnnaBridge | 189:f392fc9709a3 | 78 | current_state.Init.GeneratingPolynomial = config->polynomial; |
AnnaBridge | 189:f392fc9709a3 | 79 | |
AnnaBridge | 189:f392fc9709a3 | 80 | switch (config->width) |
AnnaBridge | 189:f392fc9709a3 | 81 | { |
AnnaBridge | 189:f392fc9709a3 | 82 | case HAL_CRC_LENGTH_32B: |
AnnaBridge | 189:f392fc9709a3 | 83 | current_state.Init.CRCLength = CRC_POLYLENGTH_32B; |
AnnaBridge | 189:f392fc9709a3 | 84 | break; |
AnnaBridge | 189:f392fc9709a3 | 85 | case HAL_CRC_LENGTH_16B: |
AnnaBridge | 189:f392fc9709a3 | 86 | current_state.Init.CRCLength = CRC_POLYLENGTH_16B; |
AnnaBridge | 189:f392fc9709a3 | 87 | break; |
AnnaBridge | 189:f392fc9709a3 | 88 | case HAL_CRC_LENGTH_8B: |
AnnaBridge | 189:f392fc9709a3 | 89 | current_state.Init.CRCLength = CRC_POLYLENGTH_8B; |
AnnaBridge | 189:f392fc9709a3 | 90 | break; |
AnnaBridge | 189:f392fc9709a3 | 91 | case HAL_CRC_LENGTH_7B: |
AnnaBridge | 189:f392fc9709a3 | 92 | current_state.Init.CRCLength = CRC_POLYLENGTH_7B; |
AnnaBridge | 189:f392fc9709a3 | 93 | break; |
AnnaBridge | 189:f392fc9709a3 | 94 | default: |
AnnaBridge | 189:f392fc9709a3 | 95 | MBED_ASSERT(false); |
AnnaBridge | 189:f392fc9709a3 | 96 | break; |
AnnaBridge | 189:f392fc9709a3 | 97 | } |
AnnaBridge | 189:f392fc9709a3 | 98 | |
AnnaBridge | 187:0387e8f68319 | 99 | current_state.Init.InputDataInversionMode = |
AnnaBridge | 187:0387e8f68319 | 100 | config->reflect_in ? CRC_INPUTDATA_INVERSION_BYTE |
AnnaBridge | 187:0387e8f68319 | 101 | : CRC_INPUTDATA_INVERSION_NONE; |
AnnaBridge | 187:0387e8f68319 | 102 | current_state.Init.OutputDataInversionMode = |
AnnaBridge | 187:0387e8f68319 | 103 | config->reflect_out ? CRC_OUTPUTDATA_INVERSION_ENABLE |
AnnaBridge | 187:0387e8f68319 | 104 | : CRC_OUTPUTDATA_INVERSION_DISABLE; |
AnnaBridge | 189:f392fc9709a3 | 105 | #endif |
Anna Bridge |
186:707f6e361f3e | 106 | |
AnnaBridge | 189:f392fc9709a3 | 107 | if (HAL_CRC_Init(¤t_state) != HAL_OK) { |
AnnaBridge | 189:f392fc9709a3 | 108 | MBED_ASSERT(false); |
AnnaBridge | 189:f392fc9709a3 | 109 | } |
Anna Bridge |
186:707f6e361f3e | 110 | } |
Anna Bridge |
186:707f6e361f3e | 111 | |
Anna Bridge |
186:707f6e361f3e | 112 | void hal_crc_compute_partial(const uint8_t *data, const size_t size) |
Anna Bridge |
186:707f6e361f3e | 113 | { |
AnnaBridge | 187:0387e8f68319 | 114 | if (data && size) { |
AnnaBridge | 187:0387e8f68319 | 115 | HAL_CRC_Accumulate(¤t_state, (uint32_t *)data, size); |
AnnaBridge | 187:0387e8f68319 | 116 | } |
Anna Bridge |
186:707f6e361f3e | 117 | } |
Anna Bridge |
186:707f6e361f3e | 118 | |
Anna Bridge |
186:707f6e361f3e | 119 | uint32_t hal_crc_get_result(void) |
Anna Bridge |
186:707f6e361f3e | 120 | { |
AnnaBridge | 189:f392fc9709a3 | 121 | uint32_t result = current_state.Instance->DR; |
Anna Bridge |
186:707f6e361f3e | 122 | |
AnnaBridge | 189:f392fc9709a3 | 123 | #if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B) |
AnnaBridge | 189:f392fc9709a3 | 124 | /* The CRC-7 SD needs to shift left by 1 bit after obtaining the result, but the output |
AnnaBridge | 189:f392fc9709a3 | 125 | * inversion of CRC peripheral will convert the result before shift left by 1 bit, so |
AnnaBridge | 189:f392fc9709a3 | 126 | * the result seems to have shifted after the conversion. |
AnnaBridge | 189:f392fc9709a3 | 127 | * |
AnnaBridge | 189:f392fc9709a3 | 128 | * Example: |
AnnaBridge | 189:f392fc9709a3 | 129 | * [Gerenal setps] |
AnnaBridge | 189:f392fc9709a3 | 130 | * 1. Before output inversion: 0x75 (0111 0101) |
AnnaBridge | 189:f392fc9709a3 | 131 | * 2. Left shift by 1 bit: 0xEA (1110 1010) |
AnnaBridge | 189:f392fc9709a3 | 132 | * 3. After output inversion: 0x57 (0101 0111) |
AnnaBridge | 189:f392fc9709a3 | 133 | * |
AnnaBridge | 189:f392fc9709a3 | 134 | * [STM32 CRC peripheral steps] |
AnnaBridge | 189:f392fc9709a3 | 135 | * 1. Before output inversion: 0x75 (0111 0101) |
AnnaBridge | 189:f392fc9709a3 | 136 | * 2. After output inversion: 0x57 (0101 0111) <= no needs shift again |
AnnaBridge | 189:f392fc9709a3 | 137 | */ |
AnnaBridge | 189:f392fc9709a3 | 138 | if (current_state.Init.CRCLength == CRC_POLYLENGTH_7B && |
AnnaBridge | 189:f392fc9709a3 | 139 | current_state.Init.GeneratingPolynomial == POLY_7BIT_SD && |
AnnaBridge | 189:f392fc9709a3 | 140 | current_state.Init.OutputDataInversionMode == CRC_OUTPUTDATA_INVERSION_DISABLE) |
AnnaBridge | 189:f392fc9709a3 | 141 | result = result << 1; |
AnnaBridge | 189:f392fc9709a3 | 142 | #endif |
AnnaBridge | 189:f392fc9709a3 | 143 | return (result ^ final_xor) & crc_mask; |
Anna Bridge |
186:707f6e361f3e | 144 | } |
Anna Bridge |
186:707f6e361f3e | 145 | |
Anna Bridge |
186:707f6e361f3e | 146 | #endif // DEVICE_CRC |