STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_crc.c 00004 * @author MCD Application Team 00005 * @brief CRC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Cyclic Redundancy Check (CRC) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + Peripheral Control functions 00010 * + Peripheral State functions 00011 * 00012 ****************************************************************************** 00013 * @attention 00014 * 00015 * Copyright (c) 2017 STMicroelectronics. 00016 * All rights reserved. 00017 * 00018 * This software is licensed under terms that can be found in the LICENSE file 00019 * in the root directory of this software component. 00020 * If no LICENSE file comes with this software, it is provided AS-IS. 00021 * 00022 ****************************************************************************** 00023 @verbatim 00024 =============================================================================== 00025 ##### How to use this driver ##### 00026 =============================================================================== 00027 [..] 00028 (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE(); 00029 (+) Initialize CRC calculator 00030 (++) specify generating polynomial (peripheral default or non-default one) 00031 (++) specify initialization value (peripheral default or non-default one) 00032 (++) specify input data format 00033 (++) specify input or output data inversion mode if any 00034 (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the 00035 input data buffer starting with the previously computed CRC as 00036 initialization value 00037 (+) Use HAL_CRC_Calculate() function to compute the CRC value of the 00038 input data buffer starting with the defined initialization value 00039 (default or non-default) to initiate CRC calculation 00040 00041 @endverbatim 00042 ****************************************************************************** 00043 */ 00044 00045 /* Includes ------------------------------------------------------------------*/ 00046 #include "stm32l4xx_hal.h" 00047 00048 /** @addtogroup STM32L4xx_HAL_Driver 00049 * @{ 00050 */ 00051 00052 /** @defgroup CRC CRC 00053 * @brief CRC HAL module driver. 00054 * @{ 00055 */ 00056 00057 #ifdef HAL_CRC_MODULE_ENABLED 00058 00059 /* Private typedef -----------------------------------------------------------*/ 00060 /* Private define ------------------------------------------------------------*/ 00061 /* Private macro -------------------------------------------------------------*/ 00062 /* Private variables ---------------------------------------------------------*/ 00063 /* Private function prototypes -----------------------------------------------*/ 00064 /** @defgroup CRC_Private_Functions CRC Private Functions 00065 * @{ 00066 */ 00067 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength); 00068 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength); 00069 /** 00070 * @} 00071 */ 00072 00073 /* Exported functions --------------------------------------------------------*/ 00074 00075 /** @defgroup CRC_Exported_Functions CRC Exported Functions 00076 * @{ 00077 */ 00078 00079 /** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions 00080 * @brief Initialization and Configuration functions. 00081 * 00082 @verbatim 00083 =============================================================================== 00084 ##### Initialization and de-initialization functions ##### 00085 =============================================================================== 00086 [..] This section provides functions allowing to: 00087 (+) Initialize the CRC according to the specified parameters 00088 in the CRC_InitTypeDef and create the associated handle 00089 (+) DeInitialize the CRC peripheral 00090 (+) Initialize the CRC MSP (MCU Specific Package) 00091 (+) DeInitialize the CRC MSP 00092 00093 @endverbatim 00094 * @{ 00095 */ 00096 00097 /** 00098 * @brief Initialize the CRC according to the specified 00099 * parameters in the CRC_InitTypeDef and create the associated handle. 00100 * @param hcrc CRC handle 00101 * @retval HAL status 00102 */ 00103 HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc) 00104 { 00105 /* Check the CRC handle allocation */ 00106 if (hcrc == NULL) 00107 { 00108 return HAL_ERROR; 00109 } 00110 00111 /* Check the parameters */ 00112 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); 00113 00114 if (hcrc->State == HAL_CRC_STATE_RESET) 00115 { 00116 /* Allocate lock resource and initialize it */ 00117 hcrc->Lock = HAL_UNLOCKED; 00118 /* Init the low level hardware */ 00119 HAL_CRC_MspInit(hcrc); 00120 } 00121 00122 hcrc->State = HAL_CRC_STATE_BUSY; 00123 00124 /* check whether or not non-default generating polynomial has been 00125 * picked up by user */ 00126 assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse)); 00127 if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE) 00128 { 00129 /* initialize peripheral with default generating polynomial */ 00130 WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY); 00131 MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B); 00132 } 00133 else 00134 { 00135 /* initialize CRC peripheral with generating polynomial defined by user */ 00136 if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK) 00137 { 00138 return HAL_ERROR; 00139 } 00140 } 00141 00142 /* check whether or not non-default CRC initial value has been 00143 * picked up by user */ 00144 assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse)); 00145 if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE) 00146 { 00147 WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE); 00148 } 00149 else 00150 { 00151 WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue); 00152 } 00153 00154 00155 /* set input data inversion mode */ 00156 assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode)); 00157 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode); 00158 00159 /* set output data inversion mode */ 00160 assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode)); 00161 MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode); 00162 00163 /* makes sure the input data format (bytes, halfwords or words stream) 00164 * is properly specified by user */ 00165 assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat)); 00166 00167 /* Change CRC peripheral state */ 00168 hcrc->State = HAL_CRC_STATE_READY; 00169 00170 /* Return function status */ 00171 return HAL_OK; 00172 } 00173 00174 /** 00175 * @brief DeInitialize the CRC peripheral. 00176 * @param hcrc CRC handle 00177 * @retval HAL status 00178 */ 00179 HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc) 00180 { 00181 /* Check the CRC handle allocation */ 00182 if (hcrc == NULL) 00183 { 00184 return HAL_ERROR; 00185 } 00186 00187 /* Check the parameters */ 00188 assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); 00189 00190 /* Check the CRC peripheral state */ 00191 if (hcrc->State == HAL_CRC_STATE_BUSY) 00192 { 00193 return HAL_BUSY; 00194 } 00195 00196 /* Change CRC peripheral state */ 00197 hcrc->State = HAL_CRC_STATE_BUSY; 00198 00199 /* Reset CRC calculation unit */ 00200 __HAL_CRC_DR_RESET(hcrc); 00201 00202 /* Reset IDR register content */ 00203 CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR); 00204 00205 /* DeInit the low level hardware */ 00206 HAL_CRC_MspDeInit(hcrc); 00207 00208 /* Change CRC peripheral state */ 00209 hcrc->State = HAL_CRC_STATE_RESET; 00210 00211 /* Process unlocked */ 00212 __HAL_UNLOCK(hcrc); 00213 00214 /* Return function status */ 00215 return HAL_OK; 00216 } 00217 00218 /** 00219 * @brief Initializes the CRC MSP. 00220 * @param hcrc CRC handle 00221 * @retval None 00222 */ 00223 __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc) 00224 { 00225 /* Prevent unused argument(s) compilation warning */ 00226 UNUSED(hcrc); 00227 00228 /* NOTE : This function should not be modified, when the callback is needed, 00229 the HAL_CRC_MspInit can be implemented in the user file 00230 */ 00231 } 00232 00233 /** 00234 * @brief DeInitialize the CRC MSP. 00235 * @param hcrc CRC handle 00236 * @retval None 00237 */ 00238 __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc) 00239 { 00240 /* Prevent unused argument(s) compilation warning */ 00241 UNUSED(hcrc); 00242 00243 /* NOTE : This function should not be modified, when the callback is needed, 00244 the HAL_CRC_MspDeInit can be implemented in the user file 00245 */ 00246 } 00247 00248 /** 00249 * @} 00250 */ 00251 00252 /** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions 00253 * @brief management functions. 00254 * 00255 @verbatim 00256 =============================================================================== 00257 ##### Peripheral Control functions ##### 00258 =============================================================================== 00259 [..] This section provides functions allowing to: 00260 (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer 00261 using combination of the previous CRC value and the new one. 00262 00263 [..] or 00264 00265 (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer 00266 independently of the previous CRC value. 00267 00268 @endverbatim 00269 * @{ 00270 */ 00271 00272 /** 00273 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer 00274 * starting with the previously computed CRC as initialization value. 00275 * @param hcrc CRC handle 00276 * @param pBuffer pointer to the input data buffer, exact input data format is 00277 * provided by hcrc->InputDataFormat. 00278 * @param BufferLength input data buffer length (number of bytes if pBuffer 00279 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t, 00280 * number of words if pBuffer type is * uint32_t). 00281 * @note By default, the API expects a uint32_t pointer as input buffer parameter. 00282 * Input buffer pointers with other types simply need to be cast in uint32_t 00283 * and the API will internally adjust its input data processing based on the 00284 * handle field hcrc->InputDataFormat. 00285 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) 00286 */ 00287 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) 00288 { 00289 uint32_t index; /* CRC input data buffer index */ 00290 uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */ 00291 00292 /* Change CRC peripheral state */ 00293 hcrc->State = HAL_CRC_STATE_BUSY; 00294 00295 switch (hcrc->InputDataFormat) 00296 { 00297 case CRC_INPUTDATA_FORMAT_WORDS: 00298 /* Enter Data to the CRC calculator */ 00299 for (index = 0U; index < BufferLength; index++) 00300 { 00301 hcrc->Instance->DR = pBuffer[index]; 00302 } 00303 temp = hcrc->Instance->DR; 00304 break; 00305 00306 case CRC_INPUTDATA_FORMAT_BYTES: 00307 temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength); 00308 break; 00309 00310 case CRC_INPUTDATA_FORMAT_HALFWORDS: 00311 temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */ 00312 break; 00313 default: 00314 break; 00315 } 00316 00317 /* Change CRC peripheral state */ 00318 hcrc->State = HAL_CRC_STATE_READY; 00319 00320 /* Return the CRC computed value */ 00321 return temp; 00322 } 00323 00324 /** 00325 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer 00326 * starting with hcrc->Instance->INIT as initialization value. 00327 * @param hcrc CRC handle 00328 * @param pBuffer pointer to the input data buffer, exact input data format is 00329 * provided by hcrc->InputDataFormat. 00330 * @param BufferLength input data buffer length (number of bytes if pBuffer 00331 * type is * uint8_t, number of half-words if pBuffer type is * uint16_t, 00332 * number of words if pBuffer type is * uint32_t). 00333 * @note By default, the API expects a uint32_t pointer as input buffer parameter. 00334 * Input buffer pointers with other types simply need to be cast in uint32_t 00335 * and the API will internally adjust its input data processing based on the 00336 * handle field hcrc->InputDataFormat. 00337 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) 00338 */ 00339 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) 00340 { 00341 uint32_t index; /* CRC input data buffer index */ 00342 uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */ 00343 00344 /* Change CRC peripheral state */ 00345 hcrc->State = HAL_CRC_STATE_BUSY; 00346 00347 /* Reset CRC Calculation Unit (hcrc->Instance->INIT is 00348 * written in hcrc->Instance->DR) */ 00349 __HAL_CRC_DR_RESET(hcrc); 00350 00351 switch (hcrc->InputDataFormat) 00352 { 00353 case CRC_INPUTDATA_FORMAT_WORDS: 00354 /* Enter 32-bit input data to the CRC calculator */ 00355 for (index = 0U; index < BufferLength; index++) 00356 { 00357 hcrc->Instance->DR = pBuffer[index]; 00358 } 00359 temp = hcrc->Instance->DR; 00360 break; 00361 00362 case CRC_INPUTDATA_FORMAT_BYTES: 00363 /* Specific 8-bit input data handling */ 00364 temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength); 00365 break; 00366 00367 case CRC_INPUTDATA_FORMAT_HALFWORDS: 00368 /* Specific 16-bit input data handling */ 00369 temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */ 00370 break; 00371 00372 default: 00373 break; 00374 } 00375 00376 /* Change CRC peripheral state */ 00377 hcrc->State = HAL_CRC_STATE_READY; 00378 00379 /* Return the CRC computed value */ 00380 return temp; 00381 } 00382 00383 /** 00384 * @} 00385 */ 00386 00387 /** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions 00388 * @brief Peripheral State functions. 00389 * 00390 @verbatim 00391 =============================================================================== 00392 ##### Peripheral State functions ##### 00393 =============================================================================== 00394 [..] 00395 This subsection permits to get in run-time the status of the peripheral. 00396 00397 @endverbatim 00398 * @{ 00399 */ 00400 00401 /** 00402 * @brief Return the CRC handle state. 00403 * @param hcrc CRC handle 00404 * @retval HAL state 00405 */ 00406 HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc) 00407 { 00408 /* Return CRC handle state */ 00409 return hcrc->State; 00410 } 00411 00412 /** 00413 * @} 00414 */ 00415 00416 /** 00417 * @} 00418 */ 00419 00420 /** @addtogroup CRC_Private_Functions 00421 * @{ 00422 */ 00423 00424 /** 00425 * @brief Enter 8-bit input data to the CRC calculator. 00426 * Specific data handling to optimize processing time. 00427 * @param hcrc CRC handle 00428 * @param pBuffer pointer to the input data buffer 00429 * @param BufferLength input data buffer length 00430 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) 00431 */ 00432 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength) 00433 { 00434 uint32_t i; /* input data buffer index */ 00435 uint16_t data; 00436 __IO uint16_t *pReg; 00437 00438 /* Processing time optimization: 4 bytes are entered in a row with a single word write, 00439 * last bytes must be carefully fed to the CRC calculator to ensure a correct type 00440 * handling by the peripheral */ 00441 for (i = 0U; i < (BufferLength / 4U); i++) 00442 { 00443 hcrc->Instance->DR = ((uint32_t)pBuffer[4U * i] << 24U) | \ 00444 ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | \ 00445 ((uint32_t)pBuffer[(4U * i) + 2U] << 8U) | \ 00446 (uint32_t)pBuffer[(4U * i) + 3U]; 00447 } 00448 /* last bytes specific handling */ 00449 if ((BufferLength % 4U) != 0U) 00450 { 00451 if ((BufferLength % 4U) == 1U) 00452 { 00453 *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i]; /* Derogation MisraC2012 R.11.5 */ 00454 } 00455 if ((BufferLength % 4U) == 2U) 00456 { 00457 data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]; 00458 pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ 00459 *pReg = data; 00460 } 00461 if ((BufferLength % 4U) == 3U) 00462 { 00463 data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]; 00464 pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ 00465 *pReg = data; 00466 00467 *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i) + 2U]; /* Derogation MisraC2012 R.11.5 */ 00468 } 00469 } 00470 00471 /* Return the CRC computed value */ 00472 return hcrc->Instance->DR; 00473 } 00474 00475 /** 00476 * @brief Enter 16-bit input data to the CRC calculator. 00477 * Specific data handling to optimize processing time. 00478 * @param hcrc CRC handle 00479 * @param pBuffer pointer to the input data buffer 00480 * @param BufferLength input data buffer length 00481 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) 00482 */ 00483 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength) 00484 { 00485 uint32_t i; /* input data buffer index */ 00486 __IO uint16_t *pReg; 00487 00488 /* Processing time optimization: 2 HalfWords are entered in a row with a single word write, 00489 * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure 00490 * a correct type handling by the peripheral */ 00491 for (i = 0U; i < (BufferLength / 2U); i++) 00492 { 00493 hcrc->Instance->DR = ((uint32_t)pBuffer[2U * i] << 16U) | (uint32_t)pBuffer[(2U * i) + 1U]; 00494 } 00495 if ((BufferLength % 2U) != 0U) 00496 { 00497 pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ 00498 *pReg = pBuffer[2U * i]; 00499 } 00500 00501 /* Return the CRC computed value */ 00502 return hcrc->Instance->DR; 00503 } 00504 00505 /** 00506 * @} 00507 */ 00508 00509 #endif /* HAL_CRC_MODULE_ENABLED */ 00510 /** 00511 * @} 00512 */ 00513 00514 /** 00515 * @} 00516 */