source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_crc.c

Last change on this file was 6, checked in by f.jahn, 3 months ago
File size: 17.2 KB
Line 
1/**
2  ******************************************************************************
3  * @file    stm32g0xx_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 (peripheral default or non-default one)
20             (++) specify initialization value (peripheral 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) 2018 STMicroelectronics.
35  * All rights reserved.</center></h2>
36  *
37  * This software component is licensed by ST under BSD 3-Clause license,
38  * the "License"; You may not use this file except in compliance with the
39  * License. You may obtain a copy of the License at:
40  *                        opensource.org/licenses/BSD-3-Clause
41  *
42  ******************************************************************************
43  */
44
45/* Includes ------------------------------------------------------------------*/
46#include "stm32g0xx_hal.h"
47
48/** @addtogroup STM32G0xx_HAL_Driver
49  * @{
50  */
51
52/** @defgroup CRC CRC
53  * @brief CRC HAL module driver.
54  * @{
55  */
56
57#ifdef HAL_CRC_MODULE_ENABLED
58
59/* Private typedef -----------------------------------------------------------*/
60/* Private define ------------------------------------------------------------*/
61/* Private macro -------------------------------------------------------------*/
62/* Private variables ---------------------------------------------------------*/
63/* Private function prototypes -----------------------------------------------*/
64/** @defgroup CRC_Private_Functions CRC Private Functions
65 * @{
66 */
67static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
68static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
69/**
70  * @}
71  */
72
73/* Exported functions --------------------------------------------------------*/
74
75/** @defgroup CRC_Exported_Functions CRC Exported Functions
76  * @{
77  */
78
79/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
80 *  @brief    Initialization and Configuration functions.
81 *
82@verbatim
83 ===============================================================================
84            ##### Initialization and de-initialization functions #####
85 ===============================================================================
86    [..]  This section provides functions allowing to:
87      (+) Initialize the CRC according to the specified parameters
88          in the CRC_InitTypeDef and create the associated handle
89      (+) DeInitialize the CRC peripheral
90      (+) Initialize the CRC MSP (MCU Specific Package)
91      (+) DeInitialize the CRC MSP
92
93@endverbatim
94  * @{
95  */
96
97/**
98  * @brief  Initialize the CRC according to the specified
99  *         parameters in the CRC_InitTypeDef and create the associated handle.
100  * @param  hcrc CRC handle
101  * @retval HAL status
102  */
103HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
104{
105  /* Check the CRC handle allocation */
106  if (hcrc == NULL)
107  {
108    return HAL_ERROR;
109  }
110
111  /* Check the parameters */
112  assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
113
114  if (hcrc->State == HAL_CRC_STATE_RESET)
115  {
116    /* Allocate lock resource and initialize it */
117    hcrc->Lock = HAL_UNLOCKED;
118    /* Init the low level hardware */
119    HAL_CRC_MspInit(hcrc);
120  }
121
122  hcrc->State = HAL_CRC_STATE_BUSY;
123
124  /* check whether or not non-default generating polynomial has been
125   * picked up by user */
126  assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
127  if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
128  {
129    /* initialize peripheral with default generating polynomial */
130    WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
131    MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
132  }
133  else
134  {
135    /* initialize CRC peripheral with generating polynomial defined by user */
136    if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
137    {
138      return HAL_ERROR;
139    }
140  }
141
142  /* check whether or not non-default CRC initial value has been
143   * picked up by user */
144  assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
145  if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
146  {
147    WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
148  }
149  else
150  {
151    WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
152  }
153
154
155  /* set input data inversion mode */
156  assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
157  MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
158
159  /* set output data inversion mode */
160  assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
161  MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
162
163  /* makes sure the input data format (bytes, halfwords or words stream)
164   * is properly specified by user */
165  assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
166
167  /* Change CRC peripheral state */
168  hcrc->State = HAL_CRC_STATE_READY;
169
170  /* Return function status */
171  return HAL_OK;
172}
173
174/**
175  * @brief  DeInitialize the CRC peripheral.
176  * @param  hcrc CRC handle
177  * @retval HAL status
178  */
179HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
180{
181  /* Check the CRC handle allocation */
182  if (hcrc == NULL)
183  {
184    return HAL_ERROR;
185  }
186
187  /* Check the parameters */
188  assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
189
190  /* Check the CRC peripheral state */
191  if (hcrc->State == HAL_CRC_STATE_BUSY)
192  {
193    return HAL_BUSY;
194  }
195
196  /* Change CRC peripheral state */
197  hcrc->State = HAL_CRC_STATE_BUSY;
198
199  /* Reset CRC calculation unit */
200  __HAL_CRC_DR_RESET(hcrc);
201
202  /* Reset IDR register content */
203  CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
204
205  /* DeInit the low level hardware */
206  HAL_CRC_MspDeInit(hcrc);
207
208  /* Change CRC peripheral state */
209  hcrc->State = HAL_CRC_STATE_RESET;
210
211  /* Process unlocked */
212  __HAL_UNLOCK(hcrc);
213
214  /* Return function status */
215  return HAL_OK;
216}
217
218/**
219  * @brief  Initializes the CRC MSP.
220  * @param  hcrc CRC handle
221  * @retval None
222  */
223__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
224{
225  /* Prevent unused argument(s) compilation warning */
226  UNUSED(hcrc);
227
228  /* NOTE : This function should not be modified, when the callback is needed,
229            the HAL_CRC_MspInit can be implemented in the user file
230   */
231}
232
233/**
234  * @brief  DeInitialize the CRC MSP.
235  * @param  hcrc CRC handle
236  * @retval None
237  */
238__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
239{
240  /* Prevent unused argument(s) compilation warning */
241  UNUSED(hcrc);
242
243  /* NOTE : This function should not be modified, when the callback is needed,
244            the HAL_CRC_MspDeInit can be implemented in the user file
245   */
246}
247
248/**
249  * @}
250  */
251
252/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
253 *  @brief    management functions.
254 *
255@verbatim
256 ===============================================================================
257                      ##### Peripheral Control functions #####
258 ===============================================================================
259    [..]  This section provides functions allowing to:
260      (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
261          using combination of the previous CRC value and the new one.
262
263       [..]  or
264
265      (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
266          independently of the previous CRC value.
267
268@endverbatim
269  * @{
270  */
271
272/**
273  * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
274  *         starting with the previously computed CRC as initialization value.
275  * @param  hcrc CRC handle
276  * @param  pBuffer pointer to the input data buffer, exact input data format is
277  *         provided by hcrc->InputDataFormat.
278  * @param  BufferLength input data buffer length (number of bytes if pBuffer
279  *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
280  *         number of words if pBuffer type is * uint32_t).
281  * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
282  *        Input buffer pointers with other types simply need to be cast in uint32_t
283  *        and the API will internally adjust its input data processing based on the
284  *        handle field hcrc->InputDataFormat.
285  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
286  */
287uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
288{
289  uint32_t index;      /* CRC input data buffer index */
290  uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
291
292  /* Change CRC peripheral state */
293  hcrc->State = HAL_CRC_STATE_BUSY;
294
295  switch (hcrc->InputDataFormat)
296  {
297    case CRC_INPUTDATA_FORMAT_WORDS:
298      /* Enter Data to the CRC calculator */
299      for (index = 0U; index < BufferLength; index++)
300      {
301        hcrc->Instance->DR = pBuffer[index];
302      }
303      temp = hcrc->Instance->DR;
304      break;
305
306    case CRC_INPUTDATA_FORMAT_BYTES:
307      temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
308      break;
309
310    case CRC_INPUTDATA_FORMAT_HALFWORDS:
311      temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength);    /* Derogation MisraC2012 R.11.5 */
312      break;
313    default:
314      break;
315  }
316
317  /* Change CRC peripheral state */
318  hcrc->State = HAL_CRC_STATE_READY;
319
320  /* Return the CRC computed value */
321  return temp;
322}
323
324/**
325  * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
326  *         starting with hcrc->Instance->INIT as initialization value.
327  * @param  hcrc CRC handle
328  * @param  pBuffer pointer to the input data buffer, exact input data format is
329  *         provided by hcrc->InputDataFormat.
330  * @param  BufferLength input data buffer length (number of bytes if pBuffer
331  *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
332  *         number of words if pBuffer type is * uint32_t).
333  * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
334  *        Input buffer pointers with other types simply need to be cast in uint32_t
335  *        and the API will internally adjust its input data processing based on the
336  *        handle field hcrc->InputDataFormat.
337  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
338  */
339uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
340{
341  uint32_t index;      /* CRC input data buffer index */
342  uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
343
344  /* Change CRC peripheral state */
345  hcrc->State = HAL_CRC_STATE_BUSY;
346
347  /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
348  *  written in hcrc->Instance->DR) */
349  __HAL_CRC_DR_RESET(hcrc);
350
351  switch (hcrc->InputDataFormat)
352  {
353    case CRC_INPUTDATA_FORMAT_WORDS:
354      /* Enter 32-bit input data to the CRC calculator */
355      for (index = 0U; index < BufferLength; index++)
356      {
357        hcrc->Instance->DR = pBuffer[index];
358      }
359      temp = hcrc->Instance->DR;
360      break;
361
362    case CRC_INPUTDATA_FORMAT_BYTES:
363      /* Specific 8-bit input data handling  */
364      temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
365      break;
366
367    case CRC_INPUTDATA_FORMAT_HALFWORDS:
368      /* Specific 16-bit input data handling  */
369      temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength);    /* Derogation MisraC2012 R.11.5 */
370      break;
371
372    default:
373      break;
374  }
375
376  /* Change CRC peripheral state */
377  hcrc->State = HAL_CRC_STATE_READY;
378
379  /* Return the CRC computed value */
380  return temp;
381}
382
383/**
384  * @}
385  */
386
387/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
388 *  @brief    Peripheral State functions.
389 *
390@verbatim
391 ===============================================================================
392                      ##### Peripheral State functions #####
393 ===============================================================================
394    [..]
395    This subsection permits to get in run-time the status of the peripheral.
396
397@endverbatim
398  * @{
399  */
400
401/**
402  * @brief  Return the CRC handle state.
403  * @param  hcrc CRC handle
404  * @retval HAL state
405  */
406HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
407{
408  /* Return CRC handle state */
409  return hcrc->State;
410}
411
412/**
413  * @}
414  */
415
416/**
417  * @}
418  */
419
420/** @addtogroup CRC_Private_Functions
421 * @{
422 */
423
424/**
425  * @brief  Enter 8-bit input data to the CRC calculator.
426  *         Specific data handling to optimize processing time.
427  * @param  hcrc CRC handle
428  * @param  pBuffer pointer to the input data buffer
429  * @param  BufferLength input data buffer length
430  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
431  */
432static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
433{
434  uint32_t i; /* input data buffer index */
435  uint16_t data;
436  __IO uint16_t *pReg;
437
438  /* Processing time optimization: 4 bytes are entered in a row with a single word write,
439   * last bytes must be carefully fed to the CRC calculator to ensure a correct type
440   * handling by the peripheral */
441  for (i = 0U; i < (BufferLength / 4U); i++)
442  {
443    hcrc->Instance->DR = ((uint32_t)pBuffer[4U * i] << 24U) | \
444                         ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | \
445                         ((uint32_t)pBuffer[(4U * i) + 2U] << 8U)  | \
446                         (uint32_t)pBuffer[(4U * i) + 3U];
447  }
448  /* last bytes specific handling */
449  if ((BufferLength % 4U) != 0U)
450  {
451    if ((BufferLength % 4U) == 1U)
452    {
453      *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i];         /* Derogation MisraC2012 R.11.5 */
454    }
455    if ((BufferLength % 4U) == 2U)
456    {
457      data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
458      pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
459      *pReg = data;
460    }
461    if ((BufferLength % 4U) == 3U)
462    {
463      data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
464      pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
465      *pReg = data;
466
467      *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i) + 2U];  /* Derogation MisraC2012 R.11.5 */
468    }
469  }
470
471  /* Return the CRC computed value */
472  return hcrc->Instance->DR;
473}
474
475/**
476  * @brief  Enter 16-bit input data to the CRC calculator.
477  *         Specific data handling to optimize processing time.
478  * @param  hcrc CRC handle
479  * @param  pBuffer pointer to the input data buffer
480  * @param  BufferLength input data buffer length
481  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
482  */
483static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
484{
485  uint32_t i;  /* input data buffer index */
486  __IO uint16_t *pReg;
487
488  /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
489   * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
490   * a correct type handling by the peripheral */
491  for (i = 0U; i < (BufferLength / 2U); i++)
492  {
493    hcrc->Instance->DR = ((uint32_t)pBuffer[2U * i] << 16U) | (uint32_t)pBuffer[(2U * i) + 1U];
494  }
495  if ((BufferLength % 2U) != 0U)
496  {
497    pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                 /* Derogation MisraC2012 R.11.5 */
498    *pReg = pBuffer[2U * i];
499  }
500
501  /* Return the CRC computed value */
502  return hcrc->Instance->DR;
503}
504
505/**
506  * @}
507  */
508
509#endif /* HAL_CRC_MODULE_ENABLED */
510/**
511  * @}
512  */
513
514/**
515  * @}
516  */
517
518/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.