sidestep
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_crc.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_crc.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
7 * @brief CRC HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
10 * + Initialization and de-initialization functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
13 *
14 @verbatim
15 ===============================================================================
16 ##### CRC How to use this driver #####
17 ===============================================================================
18 [..]
19
20 (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
21
22 (#) Initialize CRC calculator
23 (++) specify generating polynomial (IP default or non-default one)
24 (++) specify initialization value (IP default or non-default one)
25 (++) specify input data format
26 (++) specify input or output data inversion mode if any
27
28 (#) Use HAL_CRC_Accumulate() function to compute the CRC value of the
29 input data buffer starting with the previously computed CRC as
30 initialization value
31
32 (#) Use HAL_CRC_Calculate() function to compute the CRC value of the
33 input data buffer starting with the defined initialization value
34 (default or non-default) to initiate CRC calculation
35
36 @endverbatim
37 ******************************************************************************
38 * @attention
39 *
40 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
41 *
42 * Redistribution and use in source and binary forms, with or without modification,
43 * are permitted provided that the following conditions are met:
44 * 1. Redistributions of source code must retain the above copyright notice,
45 * this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright notice,
47 * this list of conditions and the following disclaimer in the documentation
48 * and/or other materials provided with the distribution.
49 * 3. Neither the name of STMicroelectronics nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
59 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
60 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
61 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 *
64 ******************************************************************************
65 */
66
67 /* Includes ------------------------------------------------------------------*/
68 #include "stm32f7xx_hal.h"
69
70 /** @addtogroup STM32F7xx_HAL_Driver
71 * @{
72 */
73
74 /** @defgroup CRC CRC
75 * @brief CRC HAL module driver.
76 * @{
77 */
78
79 #ifdef HAL_CRC_MODULE_ENABLED
80
81 /* Private typedef -----------------------------------------------------------*/
82 /* Private define ------------------------------------------------------------*/
83 /* Private macro -------------------------------------------------------------*/
84 /* Private variables ---------------------------------------------------------*/
85 /* Private function prototypes -----------------------------------------------*/
86 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
87 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
88 /* Exported functions --------------------------------------------------------*/
89
90 /** @defgroup CRC_Exported_Functions CRC Exported Functions
91 * @{
92 */
93
94 /** @defgroup HAL_CRC_Group1 Initialization/de-initialization functions
95 * @brief Initialization and Configuration functions.
96 *
97 @verbatim
98 ===============================================================================
99 ##### Initialization and de-initialization functions #####
100 ===============================================================================
101 [..] This section provides functions allowing to:
102 (+) Initialize the CRC according to the specified parameters
103 in the CRC_InitTypeDef and create the associated handle
104 (+) DeInitialize the CRC peripheral
105 (+) Initialize the CRC MSP
106 (+) DeInitialize CRC MSP
107
108 @endverbatim
109 * @{
110 */
111
112 /**
113 * @brief Initialize the CRC according to the specified
114 * parameters in the CRC_InitTypeDef and create the associated handle.
115 * @param hcrc: CRC handle
116 * @retval HAL status
117 */
118 HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
119 {
120 /* Check the CRC handle allocation */
121 if(hcrc == NULL)
122 {
123 return HAL_ERROR;
124 }
125
126 /* Check the parameters */
127 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
128
129 if(hcrc->State == HAL_CRC_STATE_RESET)
130 {
131 /* Allocate lock resource and initialize it */
132 hcrc->Lock = HAL_UNLOCKED;
133 /* Init the low level hardware */
134 HAL_CRC_MspInit(hcrc);
135 }
136
137 /* Change CRC peripheral state */
138 hcrc->State = HAL_CRC_STATE_BUSY;
139
140 /* check whether or not non-default generating polynomial has been
141 * picked up by user */
142 assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
143 if(hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
144 {
145 /* initialize IP with default generating polynomial */
146 WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
147 MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
148 }
149 else
150 {
151 /* initialize CRC IP with generating polynomial defined by user */
152 if(HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
153 {
154 return HAL_ERROR;
155 }
156 }
157
158 /* check whether or not non-default CRC initial value has been
159 * picked up by user */
160 assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
161 if(hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
162 {
163 WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
164 }
165 else
166 {
167 WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
168 }
169
170
171 /* set input data inversion mode */
172 assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
173 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
174
175 /* set output data inversion mode */
176 assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
177 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
178
179 /* makes sure the input data format (bytes, halfwords or words stream)
180 * is properly specified by user */
181 assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
182
183 /* Change CRC peripheral state */
184 hcrc->State = HAL_CRC_STATE_READY;
185
186 /* Return function status */
187 return HAL_OK;
188 }
189
190 /**
191 * @brief DeInitialize the CRC peripheral.
192 * @param hcrc: CRC handle
193 * @retval HAL status
194 */
195 HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
196 {
197 /* Check the CRC handle allocation */
198 if(hcrc == NULL)
199 {
200 return HAL_ERROR;
201 }
202
203 /* Check the parameters */
204 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
205
206 /* Check the CRC peripheral state */
207 if(hcrc->State == HAL_CRC_STATE_BUSY)
208 {
209 return HAL_BUSY;
210 }
211
212 /* Change CRC peripheral state */
213 hcrc->State = HAL_CRC_STATE_BUSY;
214
215 /* Reset CRC calculation unit */
216 __HAL_CRC_DR_RESET(hcrc);
217
218 /* DeInit the low level hardware */
219 HAL_CRC_MspDeInit(hcrc);
220
221 /* Change CRC peripheral state */
222 hcrc->State = HAL_CRC_STATE_RESET;
223
224 /* Process unlocked */
225 __HAL_UNLOCK(hcrc);
226
227 /* Return function status */
228 return HAL_OK;
229 }
230
231 /**
232 * @brief Initialize the CRC MSP.
233 * @param hcrc: CRC handle
234 * @retval None
235 */
236 __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
237 {
238 /* Prevent unused argument(s) compilation warning */
239 UNUSED(hcrc);
240
241 /* NOTE : This function should not be modified, when the callback is needed,
242 the HAL_CRC_MspInit can be implemented in the user file
243 */
244 }
245
246 /**
247 * @brief DeInitialize the CRC MSP.
248 * @param hcrc: CRC handle
249 * @retval None
250 */
251 __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
252 {
253 /* Prevent unused argument(s) compilation warning */
254 UNUSED(hcrc);
255
256 /* NOTE : This function should not be modified, when the callback is needed,
257 the HAL_CRC_MspDeInit can be implemented in the user file
258 */
259 }
260
261 /**
262 * @}
263 */
264
265 /** @defgroup HAL_CRC_Group2 Peripheral Control functions
266 * @brief Peripheral Control functions
267 *
268 @verbatim
269 ==============================================================================
270 ##### Peripheral Control functions #####
271 ==============================================================================
272 [..] This section provides functions allowing to:
273 (+) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
274 using combination of the previous CRC value and the new one.
275
276 or
277
278 (+) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
279 independently of the previous CRC value.
280
281 @endverbatim
282 * @{
283 */
284
285 /**
286 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
287 * starting with the previously computed CRC as initialization value.
288 * @param hcrc: CRC handle
289 * @param pBuffer: pointer to the input data buffer, exact input data format is
290 * provided by hcrc->InputDataFormat.
291 * @param BufferLength: input data buffer length (number of bytes if pBuffer
292 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
293 * number of words if pBuffer type is * uint32_t).
294 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
295 * Input buffer pointers with other types simply need to be cast in uint32_t
296 * and the API will internally adjust its input data processing based on the
297 * handle field hcrc->InputDataFormat.
298 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
299 */
300 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
301 {
302 uint32_t index = 0; /* CRC input data buffer index */
303 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
304
305 /* Process locked */
306 __HAL_LOCK(hcrc);
307
308 /* Change CRC peripheral state */
309 hcrc->State = HAL_CRC_STATE_BUSY;
310
311 switch (hcrc->InputDataFormat)
312 {
313 case CRC_INPUTDATA_FORMAT_WORDS:
314 /* Enter Data to the CRC calculator */
315 for(index = 0; index < BufferLength; index++)
316 {
317 hcrc->Instance->DR = pBuffer[index];
318 }
319 temp = hcrc->Instance->DR;
320 break;
321
322 case CRC_INPUTDATA_FORMAT_BYTES:
323 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
324 break;
325
326 case CRC_INPUTDATA_FORMAT_HALFWORDS:
327 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
328 break;
329 default:
330 break;
331 }
332
333 /* Change CRC peripheral state */
334 hcrc->State = HAL_CRC_STATE_READY;
335
336 /* Process unlocked */
337 __HAL_UNLOCK(hcrc);
338
339 /* Return the CRC computed value */
340 return temp;
341 }
342
343 /**
344 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
345 * starting with hcrc->Instance->INIT as initialization value.
346 * @param hcrc: CRC handle
347 * @param pBuffer: pointer to the input data buffer, exact input data format is
348 * provided by hcrc->InputDataFormat.
349 * @param BufferLength: input data buffer length (number of bytes if pBuffer
350 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
351 * number of words if pBuffer type is * uint32_t).
352 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
353 * Input buffer pointers with other types simply need to be cast in uint32_t
354 * and the API will internally adjust its input data processing based on the
355 * handle field hcrc->InputDataFormat.
356 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
357 */
358 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
359 {
360 uint32_t index = 0; /* CRC input data buffer index */
361 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
362
363 /* Process locked */
364 __HAL_LOCK(hcrc);
365
366 /* Change CRC peripheral state */
367 hcrc->State = HAL_CRC_STATE_BUSY;
368
369 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
370 * written in hcrc->Instance->DR) */
371 __HAL_CRC_DR_RESET(hcrc);
372
373 switch (hcrc->InputDataFormat)
374 {
375 case CRC_INPUTDATA_FORMAT_WORDS:
376 /* Enter 32-bit input data to the CRC calculator */
377 for(index = 0; index < BufferLength; index++)
378 {
379 hcrc->Instance->DR = pBuffer[index];
380 }
381 temp = hcrc->Instance->DR;
382 break;
383
384 case CRC_INPUTDATA_FORMAT_BYTES:
385 /* Specific 8-bit input data handling */
386 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
387 break;
388
389 case CRC_INPUTDATA_FORMAT_HALFWORDS:
390 /* Specific 16-bit input data handling */
391 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
392 break;
393 default:
394 break;
395 }
396
397 /* Change CRC peripheral state */
398 hcrc->State = HAL_CRC_STATE_READY;
399
400 /* Process unlocked */
401 __HAL_UNLOCK(hcrc);
402
403 /* Return the CRC computed value */
404 return temp;
405 }
406
407 /**
408 * @brief Enter 8-bit input data to the CRC calculator.
409 * Specific data handling to optimize processing time.
410 * @param hcrc: CRC handle
411 * @param pBuffer: pointer to the input data buffer
412 * @param BufferLength: input data buffer length
413 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
414 */
415 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
416 {
417 uint32_t i = 0; /* input data buffer index */
418
419 /* Processing time optimization: 4 bytes are entered in a row with a single word write,
420 * last bytes must be carefully fed to the CRC calculator to ensure a correct type
421 * handling by the IP */
422 for(i = 0; i < (BufferLength/4); i++)
423 {
424 hcrc->Instance->DR = (uint32_t)(((uint32_t)(pBuffer[4*i])<<24) | ((uint32_t)(pBuffer[4*i+1])<<16) | ((uint32_t)(pBuffer[4*i+2])<<8) | (uint32_t)(pBuffer[4*i+3]));
425 }
426 /* last bytes specific handling */
427 if((BufferLength%4) != 0)
428 {
429 if(BufferLength%4 == 1)
430 {
431 *(__IO uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i];
432 }
433 if(BufferLength%4 == 2)
434 {
435 *(__IO uint16_t*) (&hcrc->Instance->DR) = (uint16_t)((uint16_t)((uint16_t)(pBuffer[4*i])<<8) | (uint16_t)(pBuffer[4*i+1]));
436 }
437 if(BufferLength%4 == 3)
438 {
439 *(__IO uint16_t*) (&hcrc->Instance->DR) = (uint16_t)((uint16_t)((uint16_t)(pBuffer[4*i])<<8) | (uint16_t)(pBuffer[4*i+1]));
440 *(__IO uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i+2];
441 }
442 }
443
444 /* Return the CRC computed value */
445 return hcrc->Instance->DR;
446 }
447
448 /**
449 * @brief Enter 16-bit input data to the CRC calculator.
450 * Specific data handling to optimize processing time.
451 * @param hcrc: CRC handle
452 * @param pBuffer: pointer to the input data buffer
453 * @param BufferLength: input data buffer length
454 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
455 */
456 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
457 {
458 uint32_t i = 0; /* input data buffer index */
459
460 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
461 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
462 * a correct type handling by the IP */
463 for(i = 0; i < (BufferLength/2); i++)
464 {
465 hcrc->Instance->DR = (((uint32_t)(pBuffer[2*i])<<16) | (uint32_t)(pBuffer[2*i+1]));
466 }
467 if((BufferLength%2) != 0)
468 {
469 *(__IO uint16_t*) (&hcrc->Instance->DR) = pBuffer[2*i];
470 }
471
472 /* Return the CRC computed value */
473 return hcrc->Instance->DR;
474 }
475
476 /**
477 * @}
478 */
479
480 /** @defgroup HAL_CRC_Group3 Peripheral State functions
481 * @brief Peripheral State functions.
482 *
483 @verbatim
484 ==============================================================================
485 ##### Peripheral State functions #####
486 ==============================================================================
487 [..]
488 This subsection permits to get in run-time the status of the peripheral
489 and the data flow.
490
491 @endverbatim
492 * @{
493 */
494
495 /**
496 * @brief Return the CRC state.
497 * @param hcrc: CRC handle
498 * @retval HAL state
499 */
500 HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
501 {
502 return hcrc->State;
503 }
504
505 /**
506 * @}
507 */
508
509 /**
510 * @}
511 */
512
513 #endif /* HAL_CRC_MODULE_ENABLED */
514 /**
515 * @}
516 */
517
518 /**
519 * @}
520 */
521
522 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/