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