Subversion Repositories ScreenTimer

Rev

Details | Last modification | View Log | RSS feed

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