QuakeGod
2022-09-29 e1f35018c4dec304b00f50d9dbe12204fd57a623
提交 | 用户 | age
bfc108 1 /**
Q 2   ******************************************************************************
3   * @file    stm32f0xx_hal_crc.c
4   * @author  MCD Application Team
5   * @brief   CRC HAL module driver.
6   *          This file provides firmware functions to manage the following 
7   *          functionalities of the Cyclic Redundancy Check (CRC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions 
10   *           + Peripheral State functions
11   *         
12   @verbatim
13  ===============================================================================
14                      ##### How to use this driver #####
15  ===============================================================================
16     [..]
17          (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
18          (+) Initialize CRC calculator
19              (++)specify generating polynomial (IP default or non-default one)
20              (++)specify initialization value (IP default or non-default one)
21              (++)specify input data format
22              (++)specify input or output data inversion mode if any
23          (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the 
24              input data buffer starting with the previously computed CRC as 
25              initialization value
26          (+) Use HAL_CRC_Calculate() function to compute the CRC value of the 
27              input data buffer starting with the defined initialization value 
28              (default or non-default) to initiate CRC calculation
29
30   @endverbatim
31   ******************************************************************************
32   * @attention
33   *
34   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
35   *
36   * Redistribution and use in source and binary forms, with or without modification,
37   * are permitted provided that the following conditions are met:
38   *   1. Redistributions of source code must retain the above copyright notice,
39   *      this list of conditions and the following disclaimer.
40   *   2. Redistributions in binary form must reproduce the above copyright notice,
41   *      this list of conditions and the following disclaimer in the documentation
42   *      and/or other materials provided with the distribution.
43   *   3. Neither the name of STMicroelectronics nor the names of its contributors
44   *      may be used to endorse or promote products derived from this software
45   *      without specific prior written permission.
46   *
47   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
51   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57   *
58   ******************************************************************************
59   */
60
61 /* Includes ------------------------------------------------------------------*/
62 #include "stm32f0xx_hal.h"
63
64 /** @addtogroup STM32F0xx_HAL_Driver
65   * @{
66   */
67
68 /** @defgroup CRC CRC
69   * @brief CRC HAL module driver.
70   * @{
71   */
72
73 #ifdef HAL_CRC_MODULE_ENABLED
74
75 /* Private typedef -----------------------------------------------------------*/
76 /* Private define ------------------------------------------------------------*/
77 /* Private macro -------------------------------------------------------------*/
78 /* Private variables ---------------------------------------------------------*/
79 /* Private function prototypes -----------------------------------------------*/
80 /** @defgroup CRC_Private_Functions CRC Private Functions
81   * @{
82   */
83 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
84 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
85 /**
86   * @}
87   */
88
89 /* Exported functions --------------------------------------------------------*/
90
91 /** @defgroup CRC_Exported_Functions CRC Exported Functions
92   * @{
93   */
94
95 /** @defgroup CRC_Exported_Functions_Group1 Initialization/de-initialization functions
96  *  @brief    Initialization and Configuration functions. 
97  *
98 @verbatim    
99  ===============================================================================
100             ##### Initialization and de-initialization functions #####
101  ===============================================================================
102     [..]  This section provides functions allowing to:
103       (+) Initialize the CRC according to the specified parameters 
104           in the CRC_InitTypeDef and create the associated handle
105       (+) DeInitialize the CRC peripheral
106       (+) Initialize the CRC MSP (MCU Specific Package)
107       (+) DeInitialize the CRC MSP
108  
109 @endverbatim
110   * @{
111   */
112
113 /**
114   * @brief  Initialize the CRC according to the specified
115   *         parameters in the CRC_InitTypeDef and initialize the associated handle.
116   * @param  hcrc CRC handle
117   * @retval HAL status
118   */
119 HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
120 {
121   /* Check the CRC handle allocation */
122   if(hcrc == NULL)
123   {
124     return HAL_ERROR;
125   }
126   
127   /* Check the parameters */
128   assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
129
130   if(hcrc->State == HAL_CRC_STATE_RESET)
131   {   
132     /* Allocate lock resource and initialize it */
133     hcrc->Lock = HAL_UNLOCKED;
134
135     /* Init the low level hardware */
136     HAL_CRC_MspInit(hcrc);
137   }
138   
139   hcrc->State = HAL_CRC_STATE_BUSY; 
140   
141   /* Extended initialization: if programmable polynomial feature is 
142      applicable to device, set default or non-default generating 
143      polynomial according to hcrc->Init parameters.
144      If feature is non-applicable to device in use, HAL_CRCEx_Init straight 
145      away reports HAL_OK. */
146   if (HAL_CRCEx_Init(hcrc) != HAL_OK)
147   {
148     return HAL_ERROR;
149   }
150   
151   /* check whether or not non-default CRC initial value has been 
152    * picked up by user */
153   assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
154   if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
155   {
156     WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);  
157   }
158   else
159   {
160     WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
161   }
162   
163
164   /* set input data inversion mode */
165   assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode)); 
166   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode); 
167   
168   /* set output data inversion mode */
169   assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode)); 
170   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);  
171   
172   /* makes sure the input data format (bytes, halfwords or words stream)
173    * is properly specified by user */
174   assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
175
176   /* Change CRC peripheral state */
177   hcrc->State = HAL_CRC_STATE_READY;
178   
179   /* Return function status */
180   return HAL_OK;
181 }
182
183 /**
184   * @brief  DeInitialize the CRC peripheral. 
185   * @param  hcrc CRC handle
186   * @retval HAL status
187   */
188 HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
189
190   /* Check the CRC handle allocation */
191   if(hcrc == NULL)
192   {
193     return HAL_ERROR;
194   }
195   
196   /* Check the parameters */
197   assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
198   
199   /* Check the CRC peripheral state */
200   if(hcrc->State == HAL_CRC_STATE_BUSY)
201   {
202     return HAL_BUSY;
203   }
204   
205   /* Change CRC peripheral state */
206   hcrc->State = HAL_CRC_STATE_BUSY;
207   
208   /* Reset CRC calculation unit */
209   __HAL_CRC_DR_RESET(hcrc);
210   
211   /* Reset IDR register content */
212   CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR) ;
213
214   /* DeInit the low level hardware */
215   HAL_CRC_MspDeInit(hcrc);
216
217   /* Change CRC peripheral state */
218   hcrc->State = HAL_CRC_STATE_RESET;
219
220   /* Process unlocked */
221   __HAL_UNLOCK(hcrc);
222
223   /* Return function status */
224   return HAL_OK;
225 }
226
227 /**
228   * @brief  Initializes the CRC MSP.
229   * @param  hcrc CRC handle
230   * @retval None
231   */
232 __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
233 {
234   /* Prevent unused argument(s) compilation warning */
235   UNUSED(hcrc);
236
237   /* NOTE : This function should not be modified, when the callback is needed,
238             the HAL_CRC_MspInit can be implemented in the user file
239    */
240 }
241
242 /**
243   * @brief  DeInitialize the CRC MSP.
244   * @param  hcrc CRC handle
245   * @retval None
246   */
247 __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
248 {
249   /* Prevent unused argument(s) compilation warning */
250   UNUSED(hcrc);
251
252   /* NOTE : This function should not be modified, when the callback is needed,
253             the HAL_CRC_MspDeInit can be implemented in the user file
254    */
255 }
256
257 /**
258   * @}
259   */
260
261 /** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions 
262  *  @brief    management functions. 
263  *
264 @verbatim   
265  ===============================================================================
266                       ##### Peripheral Control functions #####
267  ===============================================================================  
268     [..]  This section provides functions allowing to:
269       (+) compute the 7U, 8U, 16 or 32-bit CRC value of an 8U, 16 or 32-bit data buffer
270           using the combination of the previous CRC value and the new one
271           
272        [..]  or
273           
274       (+) compute the 7U, 8U, 16 or 32-bit CRC value of an 8U, 16 or 32-bit data buffer
275           independently of the previous CRC value.
276
277 @endverbatim
278   * @{
279   */
280
281 /**                  
282   * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
283   *         starting with the previously computed CRC as initialization value.
284   * @param  hcrc CRC handle
285   * @param  pBuffer pointer to the input data buffer, exact input data format is
286   *         provided by hcrc->InputDataFormat.  
287   * @param  BufferLength input data buffer length (number of bytes if pBuffer
288   *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
289   *         number of words if pBuffer type is * uint32_t).
290   * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
291   *        Input buffer pointers with other types simply need to be cast in uint32_t
292   *        and the API will internally adjust its input data processing based on the
293   *        handle field hcrc->InputDataFormat.
294   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
295   */
296 uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
297 {
298   uint32_t index = 0U; /* CRC input data buffer index */
299   uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
300   
301   /* Process locked */
302   __HAL_LOCK(hcrc); 
303     
304   /* Change CRC peripheral state */  
305   hcrc->State = HAL_CRC_STATE_BUSY;
306   
307   switch (hcrc->InputDataFormat)
308   {
309     case CRC_INPUTDATA_FORMAT_WORDS:  
310       /* Enter Data to the CRC calculator */
311       for(index = 0U; index < BufferLength; index++)
312       {
313         hcrc->Instance->DR = pBuffer[index];
314       }
315       temp = hcrc->Instance->DR;
316       break;
317       
318     case CRC_INPUTDATA_FORMAT_BYTES: 
319       temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
320       break;
321       
322     case CRC_INPUTDATA_FORMAT_HALFWORDS: 
323       temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
324       break;
325       
326     default:
327       break;          
328   }
329   
330   /* Change CRC peripheral state */    
331   hcrc->State = HAL_CRC_STATE_READY; 
332   
333   /* Process unlocked */
334   __HAL_UNLOCK(hcrc);
335   
336   /* Return the CRC computed value */ 
337   return temp;
338 }
339
340
341 /**                  
342   * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
343   *         starting with hcrc->Instance->INIT as initialization value.
344   * @param  hcrc CRC handle
345   * @param  pBuffer pointer to the input data buffer, exact input data format is
346   *         provided by hcrc->InputDataFormat.  
347   * @param  BufferLength input data buffer length (number of bytes if pBuffer
348   *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
349   *         number of words if pBuffer type is * uint32_t).
350   * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
351   *        Input buffer pointers with other types simply need to be cast in uint32_t
352   *        and the API will internally adjust its input data processing based on the
353   *        handle field hcrc->InputDataFormat. 
354   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
355   */  
356 uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
357 {
358   uint32_t index = 0U; /* CRC input data buffer index */
359   uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
360     
361   /* Process locked */
362   __HAL_LOCK(hcrc); 
363   
364   /* Change CRC peripheral state */  
365   hcrc->State = HAL_CRC_STATE_BUSY;
366   
367   /* Reset CRC Calculation Unit (hcrc->Instance->INIT is 
368   *  written in hcrc->Instance->DR) */
369   __HAL_CRC_DR_RESET(hcrc);
370   
371   switch (hcrc->InputDataFormat)
372   {
373     case CRC_INPUTDATA_FORMAT_WORDS:  
374       /* Enter 32-bit input data to the CRC calculator */
375       for(index = 0U; index < BufferLength; index++)
376       {
377         hcrc->Instance->DR = pBuffer[index];
378       }
379       temp = hcrc->Instance->DR;
380       break;
381       
382     case CRC_INPUTDATA_FORMAT_BYTES: 
383       /* Specific 8-bit input data handling  */
384       temp = CRC_Handle_8(hcrc, (uint8_t*)pBuffer, BufferLength);
385       break;
386       
387     case CRC_INPUTDATA_FORMAT_HALFWORDS: 
388       /* Specific 16-bit input data handling  */
389       temp = CRC_Handle_16(hcrc, (uint16_t*)pBuffer, BufferLength);
390       break;
391       
392     default:
393       break;         
394   }
395
396   /* Change CRC peripheral state */    
397   hcrc->State = HAL_CRC_STATE_READY; 
398   
399   /* Process unlocked */
400   __HAL_UNLOCK(hcrc);
401   
402   /* Return the CRC computed value */ 
403   return temp;
404 }
405   
406 /**
407   * @}
408   */
409
410 /** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions 
411  *  @brief    Peripheral State functions. 
412  *
413 @verbatim   
414  ===============================================================================
415                       ##### Peripheral State functions #####
416  ===============================================================================  
417     [..]
418     This subsection permits to get in run-time the status of the peripheral.
419
420 @endverbatim
421   * @{
422   */
423
424 /**
425   * @brief  Return the CRC handle state.
426   * @param  hcrc CRC handle
427   * @retval HAL state
428   */
429 HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
430 {
431   /* Return CRC handle state */
432   return hcrc->State;
433 }
434
435 /**
436   * @}
437   */
438
439 /**
440   * @}
441   */
442
443 /** @defgroup CRC_Private_Functions CRC Private Functions
444   * @{
445   */
446
447 /**             
448   * @brief  Enter 8-bit input data to the CRC calculator.
449   *         Specific data handling to optimize processing time.  
450   * @param  hcrc CRC handle
451   * @param  pBuffer pointer to the input data buffer
452   * @param  BufferLength input data buffer length
453   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
454   */
455 static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
456 {
457   uint32_t i = 0U; /* input data buffer index */
458   
459    /* Processing time optimization: 4 bytes are entered in a row with a single word write,
460     * last bytes must be carefully fed to the CRC calculator to ensure a correct type
461     * handling by the IP */
462    for(i = 0U; i < (BufferLength/4U); i++)
463    {
464       hcrc->Instance->DR = ((uint32_t)pBuffer[4U*i]<<24U) | ((uint32_t)pBuffer[4U*i+1]<<16U) | ((uint32_t)pBuffer[4U*i+2]<<8U) | (uint32_t)pBuffer[4U*i+3];      
465    }
466    /* last bytes specific handling */
467    if ((BufferLength%4U) != 0U)
468    {
469      if  (BufferLength%4U == 1U)
470      {
471        *(uint8_t volatile*) (&hcrc->Instance->DR) = pBuffer[4*i];
472      }
473      if  (BufferLength%4U == 2U)
474      {
475        *(uint16_t volatile*) (&hcrc->Instance->DR) = ((uint32_t)pBuffer[4*i]<<8) | (uint32_t)pBuffer[4*i+1];
476      }
477      if  (BufferLength%4U == 3U)
478      {
479        *(uint16_t volatile*) (&hcrc->Instance->DR) = ((uint32_t)pBuffer[4*i]<<8) | (uint32_t)pBuffer[4*i+1];
480        *(uint8_t volatile*) (&hcrc->Instance->DR) = pBuffer[4*i+2];       
481      }
482    }
483   
484   /* Return the CRC computed value */ 
485   return hcrc->Instance->DR;
486 }
487
488
489
490 /**             
491   * @brief  Enter 16-bit input data to the CRC calculator.
492   *         Specific data handling to optimize processing time.  
493   * @param  hcrc CRC handle
494   * @param  pBuffer pointer to the input data buffer
495   * @param  BufferLength input data buffer length
496   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
497   */  
498 static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
499 {
500   uint32_t i = 0U;  /* input data buffer index */
501   
502   /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
503    * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure 
504    * a correct type handling by the IP */
505   for(i = 0U; i < (BufferLength/2U); i++)
506   {
507     hcrc->Instance->DR = ((uint32_t)pBuffer[2U*i]<<16U) | (uint32_t)pBuffer[2U*i+1];     
508   }
509   if ((BufferLength%2U) != 0U)
510   {
511        *(uint16_t volatile*) (&hcrc->Instance->DR) = pBuffer[2*i]; 
512   }
513    
514   /* Return the CRC computed value */ 
515   return hcrc->Instance->DR;
516 }
517
518 /**
519   * @}
520   */
521   
522 #endif /* HAL_CRC_MODULE_ENABLED */
523 /**
524   * @}
525   */
526
527 /**
528   * @}
529   */
530
531 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/