2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_crc.c
\r
4 * @author MCD Application Team
\r
6 * @date 06-March-2015
\r
7 * @brief CRC HAL module driver.
\r
8 * This file provides firmware functions to manage the following
\r
9 * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
\r
10 * + Initialization and de-initialization functions
\r
11 * + Peripheral Control functions
\r
12 * + Peripheral State functions
\r
15 ===============================================================================
\r
16 ##### CRC How to use this driver #####
\r
17 ===============================================================================
\r
20 (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
\r
22 (#) Initialize CRC calculator
\r
23 (++) specify generating polynomial (IP default or non-default one)
\r
24 (++) specify initialization value (IP default or non-default one)
\r
25 (++) specify input data format
\r
26 (++) specify input or output data inversion mode if any
\r
28 (#) Use HAL_CRC_Accumulate() function to compute the CRC value of the
\r
29 input data buffer starting with the previously computed CRC as
\r
30 initialization value
\r
32 (#) Use HAL_CRC_Calculate() function to compute the CRC value of the
\r
33 input data buffer starting with the defined initialization value
\r
34 (default or non-default) to initiate CRC calculation
\r
37 ******************************************************************************
\r
40 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
42 * Redistribution and use in source and binary forms, with or without modification,
\r
43 * are permitted provided that the following conditions are met:
\r
44 * 1. Redistributions of source code must retain the above copyright notice,
\r
45 * this list of conditions and the following disclaimer.
\r
46 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
47 * this list of conditions and the following disclaimer in the documentation
\r
48 * and/or other materials provided with the distribution.
\r
49 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
50 * may be used to endorse or promote products derived from this software
\r
51 * without specific prior written permission.
\r
53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
54 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
56 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
59 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
60 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
61 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
64 ******************************************************************************
\r
67 /* Includes ------------------------------------------------------------------*/
\r
68 #include "stm32f7xx_hal.h"
\r
70 /** @addtogroup STM32F7xx_HAL_Driver
\r
74 /** @defgroup CRC CRC
\r
75 * @brief CRC HAL module driver.
\r
79 #ifdef HAL_CRC_MODULE_ENABLED
\r
81 /* Private typedef -----------------------------------------------------------*/
\r
82 /* Private define ------------------------------------------------------------*/
\r
83 /* Private macro -------------------------------------------------------------*/
\r
84 /* Private variables ---------------------------------------------------------*/
\r
85 /* Private function prototypes -----------------------------------------------*/
\r
86 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
\r
87 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
\r
88 /* Exported functions --------------------------------------------------------*/
\r
90 /** @defgroup CRC_Exported_Functions
\r
94 /** @defgroup HAL_CRC_Group1 Initialization/de-initialization functions
\r
95 * @brief Initialization and Configuration functions.
\r
98 ===============================================================================
\r
99 ##### Initialization and de-initialization functions #####
\r
100 ===============================================================================
\r
101 [..] This section provides functions allowing to:
\r
102 (+) Initialize the CRC according to the specified parameters
\r
103 in the CRC_InitTypeDef and create the associated handle
\r
104 (+) DeInitialize the CRC peripheral
\r
105 (+) Initialize the CRC MSP
\r
106 (+) DeInitialize CRC MSP
\r
113 * @brief Initializes the CRC according to the specified
\r
114 * parameters in the CRC_InitTypeDef and creates the associated handle.
\r
115 * @param hcrc: CRC handle
\r
116 * @retval HAL status
\r
118 HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
\r
120 /* Check the CRC handle allocation */
\r
126 /* Check the parameters */
\r
127 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
\r
129 if(hcrc->State == HAL_CRC_STATE_RESET)
\r
131 /* Init the low level hardware */
\r
132 HAL_CRC_MspInit(hcrc);
\r
135 /* Change CRC peripheral state */
\r
136 hcrc->State = HAL_CRC_STATE_BUSY;
\r
138 /* check whether or not non-default generating polynomial has been
\r
139 * picked up by user */
\r
140 assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
\r
141 if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
\r
143 /* initialize IP with default generating polynomial */
\r
144 WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
\r
145 MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
\r
149 /* initialize CRC IP with generating polynomial defined by user */
\r
150 if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
\r
156 /* check whether or not non-default CRC initial value has been
\r
157 * picked up by user */
\r
158 assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
\r
159 if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
\r
161 WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
\r
165 WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
\r
169 /* set input data inversion mode */
\r
170 assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
\r
171 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
\r
173 /* set output data inversion mode */
\r
174 assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
\r
175 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
\r
177 /* makes sure the input data format (bytes, halfwords or words stream)
\r
178 * is properly specified by user */
\r
179 assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
\r
181 /* Change CRC peripheral state */
\r
182 hcrc->State = HAL_CRC_STATE_READY;
\r
184 /* Return function status */
\r
189 * @brief DeInitializes the CRC peripheral.
\r
190 * @param hcrc: CRC handle
\r
191 * @retval HAL status
\r
193 HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
\r
195 /* Check the CRC handle allocation */
\r
201 /* Check the parameters */
\r
202 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
\r
204 /* Check the CRC peripheral state */
\r
205 if(hcrc->State == HAL_CRC_STATE_BUSY)
\r
210 /* Change CRC peripheral state */
\r
211 hcrc->State = HAL_CRC_STATE_BUSY;
\r
213 /* Reset CRC calculation unit */
\r
214 __HAL_CRC_DR_RESET(hcrc);
\r
216 /* DeInit the low level hardware */
\r
217 HAL_CRC_MspDeInit(hcrc);
\r
219 /* Change CRC peripheral state */
\r
220 hcrc->State = HAL_CRC_STATE_RESET;
\r
222 /* Process unlocked */
\r
223 __HAL_UNLOCK(hcrc);
\r
225 /* Return function status */
\r
230 * @brief Initializes the CRC MSP.
\r
231 * @param hcrc: CRC handle
\r
234 __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
\r
236 /* NOTE : This function should not be modified, when the callback is needed,
\r
237 the HAL_CRC_MspInit can be implemented in the user file
\r
242 * @brief DeInitializes the CRC MSP.
\r
243 * @param hcrc: CRC handle
\r
246 __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
\r
248 /* NOTE : This function should not be modified, when the callback is needed,
\r
249 the HAL_CRC_MspDeInit can be implemented in the user file
\r
257 /** @defgroup HAL_CRC_Group2 Peripheral Control functions
\r
258 * @brief Peripheral Control functions
\r
261 ==============================================================================
\r
262 ##### Peripheral Control functions #####
\r
263 ==============================================================================
\r
264 [..] This section provides functions allowing to:
\r
265 (+) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
\r
266 using combination of the previous CRC value and the new one.
\r
270 (+) Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
\r
271 independently of the previous CRC value.
\r
278 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
\r
279 * starting with the previously computed CRC as initialization value.
\r
280 * @param hcrc: CRC handle
\r
281 * @param pBuffer: pointer to the input data buffer, exact input data format is
\r
282 * provided by hcrc->InputDataFormat.
\r
283 * @param BufferLength: input data buffer length
\r
284 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
\r
286 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
\r
288 uint32_t index = 0; /* CRC input data buffer index */
\r
289 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
\r
291 /* Process locked */
\r
294 /* Change CRC peripheral state */
\r
295 hcrc->State = HAL_CRC_STATE_BUSY;
\r
297 switch (hcrc->InputDataFormat)
\r
299 case CRC_INPUTDATA_FORMAT_WORDS:
\r
300 /* Enter Data to the CRC calculator */
\r
301 for(index = 0; index < BufferLength; index++)
\r
303 hcrc->Instance->DR = pBuffer[index];
\r
305 temp = hcrc->Instance->DR;
\r
308 case CRC_INPUTDATA_FORMAT_BYTES:
\r
309 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
\r
312 case CRC_INPUTDATA_FORMAT_HALFWORDS:
\r
313 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
\r
319 /* Change CRC peripheral state */
\r
320 hcrc->State = HAL_CRC_STATE_READY;
\r
322 /* Process unlocked */
\r
323 __HAL_UNLOCK(hcrc);
\r
325 /* Return the CRC computed value */
\r
331 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
\r
332 * starting with hcrc->Instance->INIT as initialization value.
\r
333 * @param hcrc: CRC handle
\r
334 * @param pBuffer: pointer to the input data buffer, exact input data format is
\r
335 * provided by hcrc->InputDataFormat.
\r
336 * @param BufferLength: input data buffer length
\r
337 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
\r
339 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
\r
341 uint32_t index = 0; /* CRC input data buffer index */
\r
342 uint32_t temp = 0; /* CRC output (read from hcrc->Instance->DR register) */
\r
344 /* Process locked */
\r
347 /* Change CRC peripheral state */
\r
348 hcrc->State = HAL_CRC_STATE_BUSY;
\r
350 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
\r
351 * written in hcrc->Instance->DR) */
\r
352 __HAL_CRC_DR_RESET(hcrc);
\r
354 switch (hcrc->InputDataFormat)
\r
356 case CRC_INPUTDATA_FORMAT_WORDS:
\r
357 /* Enter 32-bit input data to the CRC calculator */
\r
358 for(index = 0; index < BufferLength; index++)
\r
360 hcrc->Instance->DR = pBuffer[index];
\r
362 temp = hcrc->Instance->DR;
\r
365 case CRC_INPUTDATA_FORMAT_BYTES:
\r
366 /* Specific 8-bit input data handling */
\r
367 temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
\r
370 case CRC_INPUTDATA_FORMAT_HALFWORDS:
\r
371 /* Specific 16-bit input data handling */
\r
372 temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
\r
378 /* Change CRC peripheral state */
\r
379 hcrc->State = HAL_CRC_STATE_READY;
\r
381 /* Process unlocked */
\r
382 __HAL_UNLOCK(hcrc);
\r
384 /* Return the CRC computed value */
\r
391 * @brief Enter 8-bit input data to the CRC calculator.
\r
392 * Specific data handling to optimize processing time.
\r
393 * @param hcrc: CRC handle
\r
394 * @param pBuffer: pointer to the input data buffer
\r
395 * @param BufferLength: input data buffer length
\r
396 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
\r
398 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
\r
400 uint32_t i = 0; /* input data buffer index */
\r
402 /* Processing time optimization: 4 bytes are entered in a row with a single word write,
\r
403 * last bytes must be carefully fed to the CRC calculator to ensure a correct type
\r
404 * handling by the IP */
\r
405 for(i = 0; i < (BufferLength/4); i++)
\r
407 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]));
\r
409 /* last bytes specific handling */
\r
410 if ((BufferLength%4) != 0)
\r
412 if (BufferLength%4 == 1)
\r
414 *(__IO uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i];
\r
416 if (BufferLength%4 == 2)
\r
418 *(__IO uint16_t*) (&hcrc->Instance->DR) = (uint16_t)(((uint32_t)(pBuffer[4*i])<<8) | (uint32_t)(pBuffer[4*i+1]));
\r
420 if (BufferLength%4 == 3)
\r
422 *(__IO uint16_t*) (&hcrc->Instance->DR) = (uint16_t)(((uint32_t)(pBuffer[4*i])<<8) | (uint32_t)(pBuffer[4*i+1]));
\r
423 *(__IO uint8_t*) (&hcrc->Instance->DR) = pBuffer[4*i+2];
\r
427 /* Return the CRC computed value */
\r
428 return hcrc->Instance->DR;
\r
434 * @brief Enter 16-bit input data to the CRC calculator.
\r
435 * Specific data handling to optimize processing time.
\r
436 * @param hcrc: CRC handle
\r
437 * @param pBuffer: pointer to the input data buffer
\r
438 * @param BufferLength: input data buffer length
\r
439 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
\r
441 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
\r
443 uint32_t i = 0; /* input data buffer index */
\r
445 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
\r
446 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
\r
447 * a correct type handling by the IP */
\r
448 for(i = 0; i < (BufferLength/2); i++)
\r
450 hcrc->Instance->DR = (((uint32_t)(pBuffer[2*i])<<16) | (uint32_t)(pBuffer[2*i+1]));
\r
452 if ((BufferLength%2) != 0)
\r
454 *(__IO uint16_t*) (&hcrc->Instance->DR) = pBuffer[2*i];
\r
457 /* Return the CRC computed value */
\r
458 return hcrc->Instance->DR;
\r
465 /** @defgroup HAL_CRC_Group3 Peripheral State functions
\r
466 * @brief Peripheral State functions.
\r
469 ==============================================================================
\r
470 ##### Peripheral State functions #####
\r
471 ==============================================================================
\r
473 This subsection permits to get in run-time the status of the peripheral
\r
481 * @brief Returns the CRC state.
\r
482 * @param hcrc: CRC handle
\r
483 * @retval HAL state
\r
485 HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
\r
487 return hcrc->State;
\r
498 #endif /* HAL_CRC_MODULE_ENABLED */
\r
507 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r