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