1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_hal_crc_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended CRC HAL module driver.
6   *          This file provides firmware functions to manage the extended
7   *          functionalities of the CRC peripheral.
8   *
9   ******************************************************************************
10   * @attention
11   *
12   * Copyright (c) 2016 STMicroelectronics.
13   * All rights reserved.
14   *
15   * This software is licensed under terms that can be found in the LICENSE file
16   * in the root directory of this software component.
17   * If no LICENSE file comes with this software, it is provided AS-IS.
18   *
19   ******************************************************************************
20   @verbatim
21 ================================================================================
22             ##### How to use this driver #####
23 ================================================================================
24     [..]
25          (+) Set user-defined generating polynomial through HAL_CRCEx_Polynomial_Set()
26          (+) Configure Input or Output data inversion
27 
28   @endverbatim
29   ******************************************************************************
30   */
31 
32 /* Includes ------------------------------------------------------------------*/
33 #include "stm32f0xx_hal.h"
34 
35 /** @addtogroup STM32F0xx_HAL_Driver
36   * @{
37   */
38 
39 /** @defgroup CRCEx CRCEx
40   * @brief CRC Extended HAL module driver
41   * @{
42   */
43 
44 #ifdef HAL_CRC_MODULE_ENABLED
45 
46 /* Private typedef -----------------------------------------------------------*/
47 /* Private define ------------------------------------------------------------*/
48 /* Private macro -------------------------------------------------------------*/
49 /* Private variables ---------------------------------------------------------*/
50 /* Private function prototypes -----------------------------------------------*/
51 /* Exported functions --------------------------------------------------------*/
52 
53 /** @defgroup CRCEx_Exported_Functions CRC Extended Exported Functions
54   * @{
55   */
56 
57 /** @defgroup CRCEx_Exported_Functions_Group1 Extended Initialization/de-initialization functions
58   * @brief    Extended Initialization and Configuration functions.
59   *
60 @verbatim
61  ===============================================================================
62             ##### Extended configuration functions #####
63  ===============================================================================
64     [..]  This section provides functions allowing to:
65       (+) Configure the generating polynomial
66       (+) Configure the input data inversion
67       (+) Configure the output data inversion
68 
69 @endverbatim
70   * @{
71   */
72 
73 
74 #if defined(CRC_POL_POL)
75 /**
76   * @brief  Initialize the CRC polynomial if different from default one.
77   * @param  hcrc CRC handle
78   * @param  Pol CRC generating polynomial (7, 8, 16 or 32-bit long).
79   *         This parameter is written in normal representation, e.g.
80   *         @arg for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65
81   *         @arg for a polynomial of degree 16, X^16 + X^12 + X^5 + 1 is written 0x1021
82   * @param  PolyLength CRC polynomial length.
83   *         This parameter can be one of the following values:
84   *          @arg @ref CRC_POLYLENGTH_7B  7-bit long CRC (generating polynomial of degree 7)
85   *          @arg @ref CRC_POLYLENGTH_8B  8-bit long CRC (generating polynomial of degree 8)
86   *          @arg @ref CRC_POLYLENGTH_16B 16-bit long CRC (generating polynomial of degree 16)
87   *          @arg @ref CRC_POLYLENGTH_32B 32-bit long CRC (generating polynomial of degree 32)
88   * @retval HAL status
89   */
HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef * hcrc,uint32_t Pol,uint32_t PolyLength)90 HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength)
91 {
92   HAL_StatusTypeDef status = HAL_OK;
93   uint32_t msb = 31U; /* polynomial degree is 32 at most, so msb is initialized to max value */
94 
95   /* Check the parameters */
96   assert_param(IS_CRC_POL_LENGTH(PolyLength));
97 
98   /* Ensure that the generating polynomial is odd */
99   if ((Pol & (uint32_t)(0x1U)) ==  0U)
100   {
101     status =  HAL_ERROR;
102   }
103   else
104   {
105     /* check polynomial definition vs polynomial size:
106      * polynomial length must be aligned with polynomial
107      * definition. HAL_ERROR is reported if Pol degree is
108      * larger than that indicated by PolyLength.
109      * Look for MSB position: msb will contain the degree of
110      *  the second to the largest polynomial member. E.g., for
111      *  X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */
112     while ((msb-- > 0U) && ((Pol & ((uint32_t)(0x1U) << (msb & 0x1FU))) == 0U))
113     {
114     }
115 
116     switch (PolyLength)
117     {
118 
119       case CRC_POLYLENGTH_7B:
120         if (msb >= HAL_CRC_LENGTH_7B)
121         {
122           status =   HAL_ERROR;
123         }
124         break;
125       case CRC_POLYLENGTH_8B:
126         if (msb >= HAL_CRC_LENGTH_8B)
127         {
128           status =   HAL_ERROR;
129         }
130         break;
131       case CRC_POLYLENGTH_16B:
132         if (msb >= HAL_CRC_LENGTH_16B)
133         {
134           status =   HAL_ERROR;
135         }
136         break;
137 
138       case CRC_POLYLENGTH_32B:
139         /* no polynomial definition vs. polynomial length issue possible */
140         break;
141       default:
142         status =  HAL_ERROR;
143         break;
144     }
145   }
146   if (status == HAL_OK)
147   {
148     /* set generating polynomial */
149     WRITE_REG(hcrc->Instance->POL, Pol);
150 
151     /* set generating polynomial size */
152     MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, PolyLength);
153   }
154   /* Return function status */
155   return status;
156 }
157 #endif /* CRC_POL_POL */
158 
159 /**
160   * @brief  Set the Reverse Input data mode.
161   * @param  hcrc CRC handle
162   * @param  InputReverseMode Input Data inversion mode.
163   *         This parameter can be one of the following values:
164   *          @arg @ref CRC_INPUTDATA_INVERSION_NONE     no change in bit order (default value)
165   *          @arg @ref CRC_INPUTDATA_INVERSION_BYTE     Byte-wise bit reversal
166   *          @arg @ref CRC_INPUTDATA_INVERSION_HALFWORD HalfWord-wise bit reversal
167   *          @arg @ref CRC_INPUTDATA_INVERSION_WORD     Word-wise bit reversal
168   * @retval HAL status
169   */
HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef * hcrc,uint32_t InputReverseMode)170 HAL_StatusTypeDef HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t InputReverseMode)
171 {
172   /* Check the parameters */
173   assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(InputReverseMode));
174 
175   /* Change CRC peripheral state */
176   hcrc->State = HAL_CRC_STATE_BUSY;
177 
178   /* set input data inversion mode */
179   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, InputReverseMode);
180   /* Change CRC peripheral state */
181   hcrc->State = HAL_CRC_STATE_READY;
182 
183   /* Return function status */
184   return HAL_OK;
185 }
186 
187 /**
188   * @brief  Set the Reverse Output data mode.
189   * @param  hcrc CRC handle
190   * @param  OutputReverseMode Output Data inversion mode.
191   *         This parameter can be one of the following values:
192   *          @arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion (default value)
193   *          @arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE  bit-level inversion (e.g. for a 8-bit CRC: 0xB5 becomes 0xAD)
194   * @retval HAL status
195   */
HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef * hcrc,uint32_t OutputReverseMode)196 HAL_StatusTypeDef HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t OutputReverseMode)
197 {
198   /* Check the parameters */
199   assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(OutputReverseMode));
200 
201   /* Change CRC peripheral state */
202   hcrc->State = HAL_CRC_STATE_BUSY;
203 
204   /* set output data inversion mode */
205   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, OutputReverseMode);
206 
207   /* Change CRC peripheral state */
208   hcrc->State = HAL_CRC_STATE_READY;
209 
210   /* Return function status */
211   return HAL_OK;
212 }
213 
214 
215 
216 
217 /**
218   * @}
219   */
220 
221 
222 /**
223   * @}
224   */
225 
226 
227 #endif /* HAL_CRC_MODULE_ENABLED */
228 /**
229   * @}
230   */
231 
232 /**
233   * @}
234   */
235