7
7
8
8
static CRC_HandleTypeDef current_state ;
9
9
static uint32_t final_xor ;
10
-
10
+ static uint32_t crc_mask ;
11
+
12
+ /* STM32 CRC preipheral features
13
+ +-------------------------+-----------------------+---------------+---------------+
14
+ | Feature | F1/L1/F2/F4 series | F0 series | L0/F3/L4/F7 |
15
+ +-========================+=======================+===============+===============+
16
+ | Reversibility option | NO | YES |
17
+ | on I/O data | | |
18
+ +-------------------------+-----------------------+---------------+---------------+
19
+ | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable |
20
+ | | | on 32 bits | on 8,16,32 |
21
+ +-------------------------+-----------------------+---------------+---------------+
22
+ | Handled data size in bit| 32 | 8,16,32 |
23
+ +-------------------------+---------------------------------------+---------------+
24
+ | Polynomial size in bit | 32 | 7,8,16,32 |
25
+ +-------------------------+---------------------------------------+---------------+
26
+ | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable |
27
+ +-------------------------+---------------------------------------+---------------+
28
+ */
11
29
bool hal_crc_is_supported (const crc_mbed_config_t * config )
12
30
{
13
31
if (config == NULL ) {
14
32
return false;
15
33
}
16
34
17
- if (config -> polynomial != POLY_32BIT_ANSI ) {
35
+ #if defined(TARGET_STM32F1 ) || defined(TARGET_STM32F2 ) || defined(TARGET_STM32F4 ) || defined(TARGET_STM32L1 )
36
+ if (config -> width != HAL_CRC_LENGTH_32B || config -> polynomial != POLY_32BIT_ANSI ||
37
+ config -> initial_xor != 0xFFFFFFFF || config -> reflect_in || config -> reflect_out ) {
18
38
return false;
19
39
}
20
-
21
- if (config -> width != 32 ) {
40
+ #elif defined( TARGET_STM32F0 )
41
+ if (config -> width != HAL_CRC_LENGTH_32B || config -> polynomial != POLY_32BIT_ANSI ) {
22
42
return false;
23
43
}
24
-
25
- if ((config -> final_xor != 0xFFFFFFFFU ) && (config -> final_xor != 0 )) {
44
+ #else
45
+ /* TARGET_STM32L0, TARGET_STM32F3, TARGET_STM32L4, TARGET_STM32F7 */
46
+ if (config -> width != HAL_CRC_LENGTH_32B && config -> width != HAL_CRC_LENGTH_16B &&
47
+ config -> width != HAL_CRC_LENGTH_8B && config -> width != HAL_CRC_LENGTH_7B ) {
26
48
return false;
27
49
}
50
+ #endif
28
51
29
52
return true;
30
53
}
31
54
55
+ static uint32_t get_crc_mask (int width )
56
+ {
57
+ return (width < 8 ? ((1u << 8 ) - 1 ) : (uint32_t )((uint64_t )(1ull << width ) - 1 ));
58
+ }
59
+
32
60
void hal_crc_compute_partial_start (const crc_mbed_config_t * config )
33
61
{
34
62
MBED_ASSERT (hal_crc_is_supported (config ));
35
63
36
64
__HAL_RCC_CRC_CLK_ENABLE ();
37
65
38
66
final_xor = config -> final_xor ;
67
+ crc_mask = get_crc_mask (config -> width );
39
68
40
69
current_state .Instance = CRC ;
70
+ #if !defined(TARGET_STM32F1 ) && !defined(TARGET_STM32F2 ) && !defined(TARGET_STM32F4 ) && !defined(TARGET_STM32L1 )
41
71
current_state .InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES ;
42
- current_state .Init .DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE ;
72
+ current_state .Init .DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE ;
43
73
current_state .Init .DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE ;
44
74
current_state .Init .InitValue = config -> initial_xor ;
45
- current_state .Init .CRCLength = CRC_POLYLENGTH_32B ;
75
+ current_state .Init .GeneratingPolynomial = config -> polynomial ;
76
+
77
+ switch (config -> width )
78
+ {
79
+ case HAL_CRC_LENGTH_32B :
80
+ current_state .Init .CRCLength = CRC_POLYLENGTH_32B ;
81
+ break ;
82
+
83
+ case HAL_CRC_LENGTH_16B :
84
+ current_state .Init .CRCLength = CRC_POLYLENGTH_16B ;
85
+ break ;
86
+ case HAL_CRC_LENGTH_8B :
87
+ current_state .Init .CRCLength = CRC_POLYLENGTH_8B ;
88
+ break ;
89
+ case HAL_CRC_LENGTH_7B :
90
+ current_state .Init .CRCLength = CRC_POLYLENGTH_7B ;
91
+ break ;
92
+ default :
93
+ MBED_ASSERT (false);
94
+ break ;
95
+ }
96
+
46
97
current_state .Init .InputDataInversionMode =
47
98
config -> reflect_in ? CRC_INPUTDATA_INVERSION_BYTE
48
99
: CRC_INPUTDATA_INVERSION_NONE ;
49
100
current_state .Init .OutputDataInversionMode =
50
101
config -> reflect_out ? CRC_OUTPUTDATA_INVERSION_ENABLE
51
102
: CRC_OUTPUTDATA_INVERSION_DISABLE ;
103
+ #endif
52
104
53
- HAL_CRC_Init (& current_state );
105
+ if (HAL_CRC_Init (& current_state ) != HAL_OK ) {
106
+ MBED_ASSERT (false);
107
+ }
54
108
}
55
109
56
110
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)
62
116
63
117
uint32_t hal_crc_get_result (void )
64
118
{
65
- const uint32_t result = current_state .Instance -> DR ;
66
-
67
- return (final_xor == 0xFFFFFFFFU ) ? ~result : result ;
119
+ uint32_t result = current_state .Instance -> DR ;
120
+
121
+ #if !defined(TARGET_STM32F1 ) && !defined(TARGET_STM32F2 ) && !defined(TARGET_STM32F4 ) && !defined(TARGET_STM32L1 )
122
+ /* The CRC-7 SD needs to shift left by 1 bit after obtaining the result, but the output
123
+ * inversion of CRC peripheral will convert the result before shift left by 1 bit, so
124
+ * the result seems to have shifted after the conversion.
125
+ *
126
+ * Example:
127
+ * [Gerenal setps]
128
+ * 1. Before output inversion: 0x75 (0111 0101)
129
+ * 2. Left shift by 1 bit: 0xEA (1110 1010)
130
+ * 3. After output inversion: 0x57 (0101 0111)
131
+ *
132
+ * [STM32 CRC peripheral steps]
133
+ * 1. Before output inversion: 0x75 (0111 0101)
134
+ * 2. After output inversion: 0x57 (0101 0111) <= no needs shift again
135
+ */
136
+ if (current_state .Init .CRCLength == CRC_POLYLENGTH_7B &&
137
+ current_state .Init .GeneratingPolynomial == POLY_7BIT_SD &&
138
+ current_state .Init .OutputDataInversionMode == CRC_OUTPUTDATA_INVERSION_DISABLE )
139
+ result = result << 1 ;
140
+ #endif
141
+ return (result ^ final_xor ) & crc_mask ;
68
142
}
69
143
70
144
#endif // DEVICE_CRC
0 commit comments