2 ******************************************************************************
3 * @file stm32g4xx_hal_crc.c
4 * @author MCD Application Team
5 * @brief CRC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
8 * + Initialization and de-initialization functions
9 * + Peripheral Control functions
10 * + Peripheral State functions
13 ===============================================================================
14 ##### How to use this driver #####
15 ===============================================================================
17 (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
18 (+) Initialize CRC calculator
19 (++) specify generating polynomial (peripheral default or non-default one)
20 (++) specify initialization value (peripheral default or non-default one)
21 (++) specify input data format
22 (++) specify input or output data inversion mode if any
23 (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the
24 input data buffer starting with the previously computed CRC as
26 (+) Use HAL_CRC_Calculate() function to compute the CRC value of the
27 input data buffer starting with the defined initialization value
28 (default or non-default) to initiate CRC calculation
31 ******************************************************************************
34 * <h2><center>© Copyright (c) 2018 STMicroelectronics.
35 * All rights reserved.</center></h2>
37 * This software component is licensed by ST under BSD 3-Clause license,
38 * the "License"; You may not use this file except in compliance with the
39 * License. You may obtain a copy of the License at:
40 * opensource.org/licenses/BSD-3-Clause
42 ******************************************************************************
45 /* Includes ------------------------------------------------------------------*/
46 #include "stm32g4xx_hal.h"
48 /** @addtogroup STM32G4xx_HAL_Driver
53 * @brief CRC HAL module driver.
57 #ifdef HAL_CRC_MODULE_ENABLED
59 /* Private typedef -----------------------------------------------------------*/
60 /* Private define ------------------------------------------------------------*/
61 /* Private macro -------------------------------------------------------------*/
62 /* Private variables ---------------------------------------------------------*/
63 /* Private function prototypes -----------------------------------------------*/
64 /** @defgroup CRC_Private_Functions CRC Private Functions
67 static uint32_t CRC_Handle_8(CRC_HandleTypeDef
*hcrc
, uint8_t pBuffer
[], uint32_t BufferLength
);
68 static uint32_t CRC_Handle_16(CRC_HandleTypeDef
*hcrc
, uint16_t pBuffer
[], uint32_t BufferLength
);
73 /* Exported functions --------------------------------------------------------*/
75 /** @defgroup CRC_Exported_Functions CRC Exported Functions
79 /** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
80 * @brief Initialization and Configuration functions.
83 ===============================================================================
84 ##### Initialization and de-initialization functions #####
85 ===============================================================================
86 [..] This section provides functions allowing to:
87 (+) Initialize the CRC according to the specified parameters
88 in the CRC_InitTypeDef and create the associated handle
89 (+) DeInitialize the CRC peripheral
90 (+) Initialize the CRC MSP (MCU Specific Package)
91 (+) DeInitialize the CRC MSP
98 * @brief Initialize the CRC according to the specified
99 * parameters in the CRC_InitTypeDef and create the associated handle.
100 * @param hcrc CRC handle
103 HAL_StatusTypeDef
HAL_CRC_Init(CRC_HandleTypeDef
*hcrc
)
105 /* Check the CRC handle allocation */
111 /* Check the parameters */
112 assert_param(IS_CRC_ALL_INSTANCE(hcrc
->Instance
));
114 if (hcrc
->State
== HAL_CRC_STATE_RESET
)
116 /* Allocate lock resource and initialize it */
117 hcrc
->Lock
= HAL_UNLOCKED
;
118 /* Init the low level hardware */
119 HAL_CRC_MspInit(hcrc
);
122 hcrc
->State
= HAL_CRC_STATE_BUSY
;
124 /* check whether or not non-default generating polynomial has been
125 * picked up by user */
126 assert_param(IS_DEFAULT_POLYNOMIAL(hcrc
->Init
.DefaultPolynomialUse
));
127 if (hcrc
->Init
.DefaultPolynomialUse
== DEFAULT_POLYNOMIAL_ENABLE
)
129 /* initialize peripheral with default generating polynomial */
130 WRITE_REG(hcrc
->Instance
->POL
, DEFAULT_CRC32_POLY
);
131 MODIFY_REG(hcrc
->Instance
->CR
, CRC_CR_POLYSIZE
, CRC_POLYLENGTH_32B
);
135 /* initialize CRC peripheral with generating polynomial defined by user */
136 if (HAL_CRCEx_Polynomial_Set(hcrc
, hcrc
->Init
.GeneratingPolynomial
, hcrc
->Init
.CRCLength
) != HAL_OK
)
142 /* check whether or not non-default CRC initial value has been
143 * picked up by user */
144 assert_param(IS_DEFAULT_INIT_VALUE(hcrc
->Init
.DefaultInitValueUse
));
145 if (hcrc
->Init
.DefaultInitValueUse
== DEFAULT_INIT_VALUE_ENABLE
)
147 WRITE_REG(hcrc
->Instance
->INIT
, DEFAULT_CRC_INITVALUE
);
151 WRITE_REG(hcrc
->Instance
->INIT
, hcrc
->Init
.InitValue
);
155 /* set input data inversion mode */
156 assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc
->Init
.InputDataInversionMode
));
157 MODIFY_REG(hcrc
->Instance
->CR
, CRC_CR_REV_IN
, hcrc
->Init
.InputDataInversionMode
);
159 /* set output data inversion mode */
160 assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc
->Init
.OutputDataInversionMode
));
161 MODIFY_REG(hcrc
->Instance
->CR
, CRC_CR_REV_OUT
, hcrc
->Init
.OutputDataInversionMode
);
163 /* makes sure the input data format (bytes, halfwords or words stream)
164 * is properly specified by user */
165 assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc
->InputDataFormat
));
167 /* Change CRC peripheral state */
168 hcrc
->State
= HAL_CRC_STATE_READY
;
170 /* Return function status */
175 * @brief DeInitialize the CRC peripheral.
176 * @param hcrc CRC handle
179 HAL_StatusTypeDef
HAL_CRC_DeInit(CRC_HandleTypeDef
*hcrc
)
181 /* Check the CRC handle allocation */
187 /* Check the parameters */
188 assert_param(IS_CRC_ALL_INSTANCE(hcrc
->Instance
));
190 /* Check the CRC peripheral state */
191 if (hcrc
->State
== HAL_CRC_STATE_BUSY
)
196 /* Change CRC peripheral state */
197 hcrc
->State
= HAL_CRC_STATE_BUSY
;
199 /* Reset CRC calculation unit */
200 __HAL_CRC_DR_RESET(hcrc
);
202 /* Reset IDR register content */
203 CLEAR_BIT(hcrc
->Instance
->IDR
, CRC_IDR_IDR
);
205 /* DeInit the low level hardware */
206 HAL_CRC_MspDeInit(hcrc
);
208 /* Change CRC peripheral state */
209 hcrc
->State
= HAL_CRC_STATE_RESET
;
211 /* Process unlocked */
214 /* Return function status */
219 * @brief Initializes the CRC MSP.
220 * @param hcrc CRC handle
223 __weak
void HAL_CRC_MspInit(CRC_HandleTypeDef
*hcrc
)
225 /* Prevent unused argument(s) compilation warning */
228 /* NOTE : This function should not be modified, when the callback is needed,
229 the HAL_CRC_MspInit can be implemented in the user file
234 * @brief DeInitialize the CRC MSP.
235 * @param hcrc CRC handle
238 __weak
void HAL_CRC_MspDeInit(CRC_HandleTypeDef
*hcrc
)
240 /* Prevent unused argument(s) compilation warning */
243 /* NOTE : This function should not be modified, when the callback is needed,
244 the HAL_CRC_MspDeInit can be implemented in the user file
252 /** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
253 * @brief management functions.
256 ===============================================================================
257 ##### Peripheral Control functions #####
258 ===============================================================================
259 [..] This section provides functions allowing to:
260 (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
261 using combination of the previous CRC value and the new one.
265 (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
266 independently of the previous CRC value.
273 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
274 * starting with the previously computed CRC as initialization value.
275 * @param hcrc CRC handle
276 * @param pBuffer pointer to the input data buffer, exact input data format is
277 * provided by hcrc->InputDataFormat.
278 * @param BufferLength input data buffer length (number of bytes if pBuffer
279 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
280 * number of words if pBuffer type is * uint32_t).
281 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
282 * Input buffer pointers with other types simply need to be cast in uint32_t
283 * and the API will internally adjust its input data processing based on the
284 * handle field hcrc->InputDataFormat.
285 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
287 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef
*hcrc
, uint32_t pBuffer
[], uint32_t BufferLength
)
289 uint32_t index
; /* CRC input data buffer index */
290 uint32_t temp
= 0U; /* CRC output (read from hcrc->Instance->DR register) */
292 /* Change CRC peripheral state */
293 hcrc
->State
= HAL_CRC_STATE_BUSY
;
295 switch (hcrc
->InputDataFormat
)
297 case CRC_INPUTDATA_FORMAT_WORDS
:
298 /* Enter Data to the CRC calculator */
299 for (index
= 0U; index
< BufferLength
; index
++)
301 hcrc
->Instance
->DR
= pBuffer
[index
];
303 temp
= hcrc
->Instance
->DR
;
306 case CRC_INPUTDATA_FORMAT_BYTES
:
307 temp
= CRC_Handle_8(hcrc
, (uint8_t *)pBuffer
, BufferLength
);
310 case CRC_INPUTDATA_FORMAT_HALFWORDS
:
311 temp
= CRC_Handle_16(hcrc
, (uint16_t *)(void *)pBuffer
, BufferLength
); /* Derogation MisraC2012 R.11.5 */
317 /* Change CRC peripheral state */
318 hcrc
->State
= HAL_CRC_STATE_READY
;
320 /* Return the CRC computed value */
325 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
326 * starting with hcrc->Instance->INIT as initialization value.
327 * @param hcrc CRC handle
328 * @param pBuffer pointer to the input data buffer, exact input data format is
329 * provided by hcrc->InputDataFormat.
330 * @param BufferLength input data buffer length (number of bytes if pBuffer
331 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
332 * number of words if pBuffer type is * uint32_t).
333 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
334 * Input buffer pointers with other types simply need to be cast in uint32_t
335 * and the API will internally adjust its input data processing based on the
336 * handle field hcrc->InputDataFormat.
337 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
339 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef
*hcrc
, uint32_t pBuffer
[], uint32_t BufferLength
)
341 uint32_t index
; /* CRC input data buffer index */
342 uint32_t temp
= 0U; /* CRC output (read from hcrc->Instance->DR register) */
344 /* Change CRC peripheral state */
345 hcrc
->State
= HAL_CRC_STATE_BUSY
;
347 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
348 * written in hcrc->Instance->DR) */
349 __HAL_CRC_DR_RESET(hcrc
);
351 switch (hcrc
->InputDataFormat
)
353 case CRC_INPUTDATA_FORMAT_WORDS
:
354 /* Enter 32-bit input data to the CRC calculator */
355 for (index
= 0U; index
< BufferLength
; index
++)
357 hcrc
->Instance
->DR
= pBuffer
[index
];
359 temp
= hcrc
->Instance
->DR
;
362 case CRC_INPUTDATA_FORMAT_BYTES
:
363 /* Specific 8-bit input data handling */
364 temp
= CRC_Handle_8(hcrc
, (uint8_t *)pBuffer
, BufferLength
);
367 case CRC_INPUTDATA_FORMAT_HALFWORDS
:
368 /* Specific 16-bit input data handling */
369 temp
= CRC_Handle_16(hcrc
, (uint16_t *)(void *)pBuffer
, BufferLength
); /* Derogation MisraC2012 R.11.5 */
376 /* Change CRC peripheral state */
377 hcrc
->State
= HAL_CRC_STATE_READY
;
379 /* Return the CRC computed value */
387 /** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
388 * @brief Peripheral State functions.
391 ===============================================================================
392 ##### Peripheral State functions #####
393 ===============================================================================
395 This subsection permits to get in run-time the status of the peripheral.
402 * @brief Return the CRC handle state.
403 * @param hcrc CRC handle
406 HAL_CRC_StateTypeDef
HAL_CRC_GetState(CRC_HandleTypeDef
*hcrc
)
408 /* Return CRC handle state */
420 /** @addtogroup CRC_Private_Functions
425 * @brief Enter 8-bit input data to the CRC calculator.
426 * Specific data handling to optimize processing time.
427 * @param hcrc CRC handle
428 * @param pBuffer pointer to the input data buffer
429 * @param BufferLength input data buffer length
430 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
432 static uint32_t CRC_Handle_8(CRC_HandleTypeDef
*hcrc
, uint8_t pBuffer
[], uint32_t BufferLength
)
434 uint32_t i
; /* input data buffer index */
438 /* Processing time optimization: 4 bytes are entered in a row with a single word write,
439 * last bytes must be carefully fed to the CRC calculator to ensure a correct type
440 * handling by the peripheral */
441 for (i
= 0U; i
< (BufferLength
/ 4U); i
++)
443 hcrc
->Instance
->DR
= ((uint32_t)pBuffer
[4U * i
] << 24U) | \
444 ((uint32_t)pBuffer
[(4U * i
) + 1U] << 16U) | \
445 ((uint32_t)pBuffer
[(4U * i
) + 2U] << 8U) | \
446 (uint32_t)pBuffer
[(4U * i
) + 3U];
448 /* last bytes specific handling */
449 if ((BufferLength
% 4U) != 0U)
451 if ((BufferLength
% 4U) == 1U)
453 *(__IO
uint8_t *)(__IO
void *)(&hcrc
->Instance
->DR
) = pBuffer
[4U * i
]; /* Derogation MisraC2012 R.11.5 */
455 if ((BufferLength
% 4U) == 2U)
457 data
= ((uint16_t)(pBuffer
[4U * i
]) << 8U) | (uint16_t)pBuffer
[(4U * i
) + 1U];
458 pReg
= (__IO
uint16_t *)(__IO
void *)(&hcrc
->Instance
->DR
); /* Derogation MisraC2012 R.11.5 */
461 if ((BufferLength
% 4U) == 3U)
463 data
= ((uint16_t)(pBuffer
[4U * i
]) << 8U) | (uint16_t)pBuffer
[(4U * i
) + 1U];
464 pReg
= (__IO
uint16_t *)(__IO
void *)(&hcrc
->Instance
->DR
); /* Derogation MisraC2012 R.11.5 */
467 *(__IO
uint8_t *)(__IO
void *)(&hcrc
->Instance
->DR
) = pBuffer
[(4U * i
) + 2U]; /* Derogation MisraC2012 R.11.5 */
471 /* Return the CRC computed value */
472 return hcrc
->Instance
->DR
;
476 * @brief Enter 16-bit input data to the CRC calculator.
477 * Specific data handling to optimize processing time.
478 * @param hcrc CRC handle
479 * @param pBuffer pointer to the input data buffer
480 * @param BufferLength input data buffer length
481 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
483 static uint32_t CRC_Handle_16(CRC_HandleTypeDef
*hcrc
, uint16_t pBuffer
[], uint32_t BufferLength
)
485 uint32_t i
; /* input data buffer index */
488 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
489 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
490 * a correct type handling by the peripheral */
491 for (i
= 0U; i
< (BufferLength
/ 2U); i
++)
493 hcrc
->Instance
->DR
= ((uint32_t)pBuffer
[2U * i
] << 16U) | (uint32_t)pBuffer
[(2U * i
) + 1U];
495 if ((BufferLength
% 2U) != 0U)
497 pReg
= (__IO
uint16_t *)(__IO
void *)(&hcrc
->Instance
->DR
); /* Derogation MisraC2012 R.11.5 */
498 *pReg
= pBuffer
[2U * i
];
501 /* Return the CRC computed value */
502 return hcrc
->Instance
->DR
;
509 #endif /* HAL_CRC_MODULE_ENABLED */
518 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/