2 ******************************************************************************
3 * @file stm32l0xx_hal_crc.c
4 * @author MCD Application Team
6 * @date 06-February-2015
7 * @brief CRC HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the CRC peripheral:
11 * + Initialization and de-initialization functions
12 * + Peripheral Control functions
13 * + Peripheral State functions
16 ===============================================================================
17 ##### CRC How to use this driver #####
18 ===============================================================================
21 (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
23 (#) Initialize CRC calculator
24 (++) specify generating polynomial (IP default or non-default one)
25 (++) specify initialization value (IP default or non-default one)
26 (++) specify input data format
27 (++) specify input or output data inversion mode if any
29 (#) Use HAL_CRC_Accumulate() function to compute the CRC value of the
30 input data buffer starting with the previously computed CRC as
33 (#) Use HAL_CRC_Calculate() function to compute the CRC value of the
34 input data buffer starting with the defined initialization value
35 (default or non-default) to initiate CRC calculation
38 ******************************************************************************
41 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
43 * Redistribution and use in source and binary forms, with or without modification,
44 * are permitted provided that the following conditions are met:
45 * 1. Redistributions of source code must retain the above copyright notice,
46 * this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright notice,
48 * this list of conditions and the following disclaimer in the documentation
49 * and/or other materials provided with the distribution.
50 * 3. Neither the name of STMicroelectronics nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
61 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
63 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 ******************************************************************************
68 /* Includes ------------------------------------------------------------------*/
69 #include "stm32l0xx_hal.h"
71 /** @addtogroup STM32L0xx_HAL_Driver
76 * @brief CRC HAL module driver
80 #ifdef HAL_CRC_MODULE_ENABLED
82 /* Private typedef -----------------------------------------------------------*/
83 /* Private define ------------------------------------------------------------*/
84 /* Private macro -------------------------------------------------------------*/
85 /* Private variables ---------------------------------------------------------*/
86 /* Private function prototypes -----------------------------------------------*/
87 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
88 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
90 /* Exported functions --------------------------------------------------------*/
91 /** @addtogroup CRC_Exported_Functions
95 /** @addtogroup CRC_Exported_Functions_Group1
96 * @brief Initialization and Configuration functions.
99 ===============================================================================
100 ##### Initialization and de-initialization functions #####
101 ===============================================================================
103 This section provides functions allowing to:
105 (#) Initialize the CRC according to the specified parameters
106 in the CRC_InitTypeDef and create the associated handle
108 (#) DeInitialize the CRC peripheral
110 (#) Initialize the CRC MSP
112 (#) DeInitialize CRC MSP
119 * @brief Initializes the CRC according to the specified
120 * parameters in the CRC_InitTypeDef and creates the associated handle.
121 * @param hcrc: CRC handle
124 HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
126 /* Check the CRC handle allocation */
132 /* Check the parameters */
133 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
135 if(hcrc->State == HAL_CRC_STATE_RESET)
137 /* Allocate lock resource and initialize it */
138 hcrc->Lock = HAL_UNLOCKED;
140 /* Init the low level hardware */
141 HAL_CRC_MspInit(hcrc);
144 /* Change CRC peripheral state */
145 hcrc->State = HAL_CRC_STATE_BUSY;
147 /* check whether or not non-default generating polynomial has been
148 * picked up by user */
149 assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
150 if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
152 /* initialize IP with default generating polynomial */
153 WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
154 MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
158 /* initialize CRC IP with generating polynomial defined by user */
159 if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
165 /* check whether or not non-default CRC initial value has been
166 * picked up by user */
167 assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
168 if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
170 WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
174 WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
178 /* set input data inversion mode */
179 assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
180 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
182 /* set output data inversion mode */
183 assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
184 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
186 /* makes sure the input data format (bytes, halfwords or words stream)
187 * is properly specified by user */
188 assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
190 /* Change CRC peripheral state */
191 hcrc->State = HAL_CRC_STATE_READY;
193 /* Return function status */
198 * @brief DeInitializes the CRC peripheral.
199 * @param hcrc: CRC handle
202 HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
204 /* Check the CRC handle allocation */
210 /* Check the parameters */
211 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
213 /* Check the CRC peripheral state */
214 if(hcrc->State == HAL_CRC_STATE_BUSY)
219 /* Change CRC peripheral state */
220 hcrc->State = HAL_CRC_STATE_BUSY;
222 /* Reset CRC calculation unit */
223 __HAL_CRC_DR_RESET(hcrc);
225 /* DeInit the low level hardware */
226 HAL_CRC_MspDeInit(hcrc);
228 /* Change CRC peripheral state */
229 hcrc->State = HAL_CRC_STATE_RESET;
231 /* Process unlocked */
234 /* Return function status */
239 * @brief Initializes the CRC MSP.
240 * @param hcrc: CRC handle
243 __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
245 /* NOTE : This function should not be modified, when the callback is needed,
246 the HAL_CRC_MspInit can be implemented in the user file
251 * @brief DeInitializes the CRC MSP.
252 * @param hcrc: CRC handle
255 __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
257 /* NOTE : This function should not be modified, when the callback is needed,
258 the HAL_CRC_MspDeInit can be implemented in the user file
267 /** @addtogroup CRC_Exported_Functions_Group2
268 * @brief management functions.
271 ===============================================================================
272 ##### Peripheral Control functions #####
273 ===============================================================================
274 [..] This section provides functions allowing to:
276 (#) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
277 using combination of the previous CRC value and the new one.
281 (#) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
282 independently of the previous CRC value.
289 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
290 * starting with the previously computed CRC as initialization value.
291 * @param hcrc: CRC handle
292 * @param pBuffer: pointer to the input data buffer, exact input data format is
293 * provided by hcrc->InputDataFormat.
294 * @param BufferLength: input data buffer length
295 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
297 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
299 uint32_t index = 0; /* CRC input data buffer index */
300 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
305 /* Change CRC peripheral state */
306 hcrc->State = HAL_CRC_STATE_BUSY;
308 switch (hcrc->InputDataFormat)
310 case CRC_INPUTDATA_FORMAT_WORDS:
311 /* Enter Data to the CRC calculator */
312 for(index = 0; index < BufferLength; index++)
314 hcrc->Instance->DR = pBuffer[index];
316 temp = hcrc->Instance->DR;
319 case CRC_INPUTDATA_FORMAT_BYTES:
320 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
323 case CRC_INPUTDATA_FORMAT_HALFWORDS:
324 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
330 /* Change CRC peripheral state */
331 hcrc->State = HAL_CRC_STATE_READY;
333 /* Process unlocked */
336 /* Return the CRC computed value */
342 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
343 * starting with hcrc->Instance->INIT as initialization value.
344 * @param hcrc: CRC handle
345 * @param pBuffer: pointer to the input data buffer, exact input data format is
346 * provided by hcrc->InputDataFormat.
347 * @param BufferLength: input data buffer length
348 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
350 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
352 uint32_t index = 0; /* CRC input data buffer index */
353 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
358 /* Change CRC peripheral state */
359 hcrc->State = HAL_CRC_STATE_BUSY;
361 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
362 * written in hcrc->Instance->DR) */
363 __HAL_CRC_DR_RESET(hcrc);
365 switch (hcrc->InputDataFormat)
367 case CRC_INPUTDATA_FORMAT_WORDS:
368 /* Enter 32-bit input data to the CRC calculator */
369 for(index = 0; index < BufferLength; index++)
371 hcrc->Instance->DR = pBuffer[index];
373 temp = hcrc->Instance->DR;
376 case CRC_INPUTDATA_FORMAT_BYTES:
377 /* Specific 8-bit input data handling */
378 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
381 case CRC_INPUTDATA_FORMAT_HALFWORDS:
382 /* Specific 16-bit input data handling */
383 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
389 /* Change CRC peripheral state */
390 hcrc->State = HAL_CRC_STATE_READY;
392 /* Process unlocked */
395 /* Return the CRC computed value */
401 * @brief Enter 8-bit input data to the CRC calculator.
402 * Specific data handling to optimize processing time.
403 * @param hcrc: CRC handle
404 * @param pBuffer: pointer to the input data buffer
405 * @param BufferLength: input data buffer length
406 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
408 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
410 uint32_t i = 0; /* input data buffer index */
412 /* Processing time optimization: 4 bytes are entered in a row with a single word write,
413 * last bytes must be carefully fed to the CRC calculator to ensure a correct type
414 * handling by the IP */
415 for(i = 0; i < (BufferLength/4); i++)
417 hcrc->Instance->DR = (pBuffer[4*i]<<24) | (pBuffer[4*i+1]<<16) | (pBuffer[4*i+2]<<8) | pBuffer[4*i+3];
419 /* last bytes specific handling */
420 if ((BufferLength%4) != 0)
422 if (BufferLength%4 == 1)
424 *(uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i];
426 if (BufferLength%4 == 2)
428 *(uint16_t*) (&hcrc->Instance->DR) = (pBuffer[4*i]<<8) | pBuffer[4*i+1];
430 if (BufferLength%4 == 3)
432 *(uint16_t*) (&hcrc->Instance->DR) = (pBuffer[4*i]<<8) | pBuffer[4*i+1];
433 *(uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i+2];
437 /* Return the CRC computed value */
438 return hcrc->Instance->DR;
442 * @brief Enter 16-bit input data to the CRC calculator.
443 * Specific data handling to optimize processing time.
444 * @param hcrc: CRC handle
445 * @param pBuffer: pointer to the input data buffer
446 * @param BufferLength: input data buffer length
447 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
449 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
451 uint32_t i = 0; /* input data buffer index */
453 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
454 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
455 * a correct type handling by the IP */
456 for(i = 0; i < (BufferLength/2); i++)
458 hcrc->Instance->DR = (pBuffer[2*i]<<16) | pBuffer[2*i+1];
460 if ((BufferLength%2) != 0)
462 *(uint16_t*) (&hcrc->Instance->DR) = pBuffer[2*i];
465 /* Return the CRC computed value */
466 return hcrc->Instance->DR;
472 /** @addtogroup CRC_Exported_Functions_Group3
473 * @brief Peripheral State functions.
476 ===============================================================================
477 ##### Peripheral State functions #####
478 ===============================================================================
480 This subsection permits to get in run-time the status of the peripheral.
487 * @brief Returns the CRC state.
488 * @param hcrc: CRC handle
491 HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
504 #endif /* HAL_CRC_MODULE_ENABLED */
514 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/