2 ******************************************************************************
3 * @file stm32f7xx_hal_crc.c
4 * @author MCD Application Team
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
15 ===============================================================================
16 ##### CRC How to use this driver #####
17 ===============================================================================
20 (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
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
28 (#) Use HAL_CRC_Accumulate() function to compute the CRC value of the
29 input data buffer starting with the previously computed CRC as
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
37 ******************************************************************************
40 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
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.
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.
64 ******************************************************************************
67 /* Includes ------------------------------------------------------------------*/
68 #include "stm32f7xx_hal.h"
70 /** @addtogroup STM32F7xx_HAL_Driver
75 * @brief CRC HAL module driver.
79 #ifdef HAL_CRC_MODULE_ENABLED
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 --------------------------------------------------------*/
90 /** @defgroup CRC_Exported_Functions CRC Exported Functions
94 /** @defgroup HAL_CRC_Group1 Initialization/de-initialization functions
95 * @brief Initialization and Configuration functions.
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
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
118 HAL_StatusTypeDef
HAL_CRC_Init(CRC_HandleTypeDef
*hcrc
)
120 /* Check the CRC handle allocation */
126 /* Check the parameters */
127 assert_param(IS_CRC_ALL_INSTANCE(hcrc
->Instance
));
129 if(hcrc
->State
== HAL_CRC_STATE_RESET
)
131 /* Allocate lock resource and initialize it */
132 hcrc
->Lock
= HAL_UNLOCKED
;
133 /* Init the low level hardware */
134 HAL_CRC_MspInit(hcrc
);
137 /* Change CRC peripheral state */
138 hcrc
->State
= HAL_CRC_STATE_BUSY
;
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
)
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
);
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
)
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
)
163 WRITE_REG(hcrc
->Instance
->INIT
, DEFAULT_CRC_INITVALUE
);
167 WRITE_REG(hcrc
->Instance
->INIT
, hcrc
->Init
.InitValue
);
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
);
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
);
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
));
183 /* Change CRC peripheral state */
184 hcrc
->State
= HAL_CRC_STATE_READY
;
186 /* Return function status */
191 * @brief DeInitialize the CRC peripheral.
192 * @param hcrc: CRC handle
195 HAL_StatusTypeDef
HAL_CRC_DeInit(CRC_HandleTypeDef
*hcrc
)
197 /* Check the CRC handle allocation */
203 /* Check the parameters */
204 assert_param(IS_CRC_ALL_INSTANCE(hcrc
->Instance
));
206 /* Check the CRC peripheral state */
207 if(hcrc
->State
== HAL_CRC_STATE_BUSY
)
212 /* Change CRC peripheral state */
213 hcrc
->State
= HAL_CRC_STATE_BUSY
;
215 /* Reset CRC calculation unit */
216 __HAL_CRC_DR_RESET(hcrc
);
218 /* Reset IDR register content */
219 CLEAR_BIT(hcrc
->Instance
->IDR
, CRC_IDR_IDR
);
221 /* DeInit the low level hardware */
222 HAL_CRC_MspDeInit(hcrc
);
224 /* Change CRC peripheral state */
225 hcrc
->State
= HAL_CRC_STATE_RESET
;
227 /* Process unlocked */
230 /* Return function status */
235 * @brief Initialize the CRC MSP.
236 * @param hcrc: CRC handle
239 __weak
void HAL_CRC_MspInit(CRC_HandleTypeDef
*hcrc
)
241 /* Prevent unused argument(s) compilation warning */
244 /* NOTE : This function should not be modified, when the callback is needed,
245 the HAL_CRC_MspInit can be implemented in the user file
250 * @brief DeInitialize the CRC MSP.
251 * @param hcrc: CRC handle
254 __weak
void HAL_CRC_MspDeInit(CRC_HandleTypeDef
*hcrc
)
256 /* Prevent unused argument(s) compilation warning */
259 /* NOTE : This function should not be modified, when the callback is needed,
260 the HAL_CRC_MspDeInit can be implemented in the user file
268 /** @defgroup HAL_CRC_Group2 Peripheral Control functions
269 * @brief Peripheral Control functions
272 ==============================================================================
273 ##### Peripheral Control functions #####
274 ==============================================================================
275 [..] 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 (number of bytes if pBuffer
295 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
296 * number of words if pBuffer type is * uint32_t).
297 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
298 * Input buffer pointers with other types simply need to be cast in uint32_t
299 * and the API will internally adjust its input data processing based on the
300 * handle field hcrc->InputDataFormat.
301 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
303 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef
*hcrc
, uint32_t pBuffer
[], uint32_t BufferLength
)
305 uint32_t index
= 0; /* CRC input data buffer index */
306 uint32_t temp
= 0; /* CRC output (read from hcrc->Instance->DR register) */
311 /* Change CRC peripheral state */
312 hcrc
->State
= HAL_CRC_STATE_BUSY
;
314 switch (hcrc
->InputDataFormat
)
316 case CRC_INPUTDATA_FORMAT_WORDS
:
317 /* Enter Data to the CRC calculator */
318 for(index
= 0; index
< BufferLength
; index
++)
320 hcrc
->Instance
->DR
= pBuffer
[index
];
322 temp
= hcrc
->Instance
->DR
;
325 case CRC_INPUTDATA_FORMAT_BYTES
:
326 temp
= CRC_Handle_8(hcrc
, (uint8_t*)pBuffer
, BufferLength
);
329 case CRC_INPUTDATA_FORMAT_HALFWORDS
:
330 temp
= CRC_Handle_16(hcrc
, (uint16_t*)pBuffer
, BufferLength
);
336 /* Change CRC peripheral state */
337 hcrc
->State
= HAL_CRC_STATE_READY
;
339 /* Process unlocked */
342 /* Return the CRC computed value */
347 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
348 * starting with hcrc->Instance->INIT as initialization value.
349 * @param hcrc: CRC handle
350 * @param pBuffer: pointer to the input data buffer, exact input data format is
351 * provided by hcrc->InputDataFormat.
352 * @param BufferLength: input data buffer length (number of bytes if pBuffer
353 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
354 * number of words if pBuffer type is * uint32_t).
355 * @note By default, the API expects a uint32_t pointer as input buffer parameter.
356 * Input buffer pointers with other types simply need to be cast in uint32_t
357 * and the API will internally adjust its input data processing based on the
358 * handle field hcrc->InputDataFormat.
359 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
361 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef
*hcrc
, uint32_t pBuffer
[], uint32_t BufferLength
)
363 uint32_t index
= 0; /* CRC input data buffer index */
364 uint32_t temp
= 0; /* CRC output (read from hcrc->Instance->DR register) */
369 /* Change CRC peripheral state */
370 hcrc
->State
= HAL_CRC_STATE_BUSY
;
372 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
373 * written in hcrc->Instance->DR) */
374 __HAL_CRC_DR_RESET(hcrc
);
376 switch (hcrc
->InputDataFormat
)
378 case CRC_INPUTDATA_FORMAT_WORDS
:
379 /* Enter 32-bit input data to the CRC calculator */
380 for(index
= 0; index
< BufferLength
; index
++)
382 hcrc
->Instance
->DR
= pBuffer
[index
];
384 temp
= hcrc
->Instance
->DR
;
387 case CRC_INPUTDATA_FORMAT_BYTES
:
388 /* Specific 8-bit input data handling */
389 temp
= CRC_Handle_8(hcrc
, (uint8_t*)pBuffer
, BufferLength
);
392 case CRC_INPUTDATA_FORMAT_HALFWORDS
:
393 /* Specific 16-bit input data handling */
394 temp
= CRC_Handle_16(hcrc
, (uint16_t*)pBuffer
, BufferLength
);
400 /* Change CRC peripheral state */
401 hcrc
->State
= HAL_CRC_STATE_READY
;
403 /* Process unlocked */
406 /* Return the CRC computed value */
411 * @brief Enter 8-bit input data to the CRC calculator.
412 * Specific data handling to optimize processing time.
413 * @param hcrc: CRC handle
414 * @param pBuffer: pointer to the input data buffer
415 * @param BufferLength: input data buffer length
416 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
418 static uint32_t CRC_Handle_8(CRC_HandleTypeDef
*hcrc
, uint8_t pBuffer
[], uint32_t BufferLength
)
420 uint32_t i
= 0; /* input data buffer index */
422 /* Processing time optimization: 4 bytes are entered in a row with a single word write,
423 * last bytes must be carefully fed to the CRC calculator to ensure a correct type
424 * handling by the IP */
425 for(i
= 0; i
< (BufferLength
/4); i
++)
427 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]));
429 /* last bytes specific handling */
430 if((BufferLength
%4) != 0)
432 if(BufferLength
%4 == 1)
434 *(__IO
uint8_t*) (&hcrc
->Instance
->DR
) = pBuffer
[4*i
];
436 if(BufferLength
%4 == 2)
438 *(__IO
uint16_t*) (&hcrc
->Instance
->DR
) = (uint16_t)((uint16_t)((uint16_t)(pBuffer
[4*i
])<<8) | (uint16_t)(pBuffer
[4*i
+1]));
440 if(BufferLength
%4 == 3)
442 *(__IO
uint16_t*) (&hcrc
->Instance
->DR
) = (uint16_t)((uint16_t)((uint16_t)(pBuffer
[4*i
])<<8) | (uint16_t)(pBuffer
[4*i
+1]));
443 *(__IO
uint8_t*) (&hcrc
->Instance
->DR
) = pBuffer
[4*i
+2];
447 /* Return the CRC computed value */
448 return hcrc
->Instance
->DR
;
452 * @brief Enter 16-bit input data to the CRC calculator.
453 * Specific data handling to optimize processing time.
454 * @param hcrc: CRC handle
455 * @param pBuffer: pointer to the input data buffer
456 * @param BufferLength: input data buffer length
457 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
459 static uint32_t CRC_Handle_16(CRC_HandleTypeDef
*hcrc
, uint16_t pBuffer
[], uint32_t BufferLength
)
461 uint32_t i
= 0; /* input data buffer index */
463 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
464 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
465 * a correct type handling by the IP */
466 for(i
= 0; i
< (BufferLength
/2); i
++)
468 hcrc
->Instance
->DR
= (((uint32_t)(pBuffer
[2*i
])<<16) | (uint32_t)(pBuffer
[2*i
+1]));
470 if((BufferLength
%2) != 0)
472 *(__IO
uint16_t*) (&hcrc
->Instance
->DR
) = pBuffer
[2*i
];
475 /* Return the CRC computed value */
476 return hcrc
->Instance
->DR
;
483 /** @defgroup HAL_CRC_Group3 Peripheral State functions
484 * @brief Peripheral State functions.
487 ==============================================================================
488 ##### Peripheral State functions #####
489 ==============================================================================
491 This subsection permits to get in run-time the status of the peripheral
499 * @brief Return the CRC state.
500 * @param hcrc: CRC handle
503 HAL_CRC_StateTypeDef
HAL_CRC_GetState(CRC_HandleTypeDef
*hcrc
)
516 #endif /* HAL_CRC_MODULE_ENABLED */
525 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/