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