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