TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_crc.c Source File

stm32l4xx_hal_crc.c

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