1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_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) 2022 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 "stm32c0xx_hal.h"
34 
35 /** @addtogroup STM32C0xx_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 /**
75   * @brief  Initialize the CRC polynomial if different from default one.
76   * @param  hcrc CRC handle
77   * @param  Pol CRC generating polynomial (7, 8, 16 or 32-bit long).
78   *         This parameter is written in normal representation, e.g.
79   *         @arg for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65
80   *         @arg for a polynomial of degree 16, X^16 + X^12 + X^5 + 1 is written 0x1021
81   * @param  PolyLength CRC polynomial length.
82   *         This parameter can be one of the following values:
83   *          @arg @ref CRC_POLYLENGTH_7B  7-bit long CRC (generating polynomial of degree 7)
84   *          @arg @ref CRC_POLYLENGTH_8B  8-bit long CRC (generating polynomial of degree 8)
85   *          @arg @ref CRC_POLYLENGTH_16B 16-bit long CRC (generating polynomial of degree 16)
86   *          @arg @ref CRC_POLYLENGTH_32B 32-bit long CRC (generating polynomial of degree 32)
87   * @retval HAL status
88   */
HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef * hcrc,uint32_t Pol,uint32_t PolyLength)89 HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength)
90 {
91   HAL_StatusTypeDef status = HAL_OK;
92   uint32_t msb = 31U; /* polynomial degree is 32 at most, so msb is initialized to max value */
93 
94   /* Check the parameters */
95   assert_param(IS_CRC_POL_LENGTH(PolyLength));
96 
97   /* Ensure that the generating polynomial is odd */
98   if ((Pol & (uint32_t)(0x1U)) ==  0U)
99   {
100     status =  HAL_ERROR;
101   }
102   else
103   {
104     /* check polynomial definition vs polynomial size:
105      * polynomial length must be aligned with polynomial
106      * definition. HAL_ERROR is reported if Pol degree is
107      * larger than that indicated by PolyLength.
108      * Look for MSB position: msb will contain the degree of
109      *  the second to the largest polynomial member. E.g., for
110      *  X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */
111     while ((msb-- > 0U) && ((Pol & ((uint32_t)(0x1U) << (msb & 0x1FU))) == 0U))
112     {
113     }
114 
115     switch (PolyLength)
116     {
117 
118       case CRC_POLYLENGTH_7B:
119         if (msb >= HAL_CRC_LENGTH_7B)
120         {
121           status =   HAL_ERROR;
122         }
123         break;
124       case CRC_POLYLENGTH_8B:
125         if (msb >= HAL_CRC_LENGTH_8B)
126         {
127           status =   HAL_ERROR;
128         }
129         break;
130       case CRC_POLYLENGTH_16B:
131         if (msb >= HAL_CRC_LENGTH_16B)
132         {
133           status =   HAL_ERROR;
134         }
135         break;
136 
137       case CRC_POLYLENGTH_32B:
138         /* no polynomial definition vs. polynomial length issue possible */
139         break;
140       default:
141         status =  HAL_ERROR;
142         break;
143     }
144   }
145   if (status == HAL_OK)
146   {
147     /* set generating polynomial */
148     WRITE_REG(hcrc->Instance->POL, Pol);
149 
150     /* set generating polynomial size */
151     MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, PolyLength);
152   }
153   /* Return function status */
154   return status;
155 }
156 
157 /**
158   * @brief  Set the Reverse Input data mode.
159   * @param  hcrc CRC handle
160   * @param  InputReverseMode Input Data inversion mode.
161   *         This parameter can be one of the following values:
162   *          @arg @ref CRC_INPUTDATA_INVERSION_NONE     no change in bit order (default value)
163   *          @arg @ref CRC_INPUTDATA_INVERSION_BYTE     Byte-wise bit reversal
164   *          @arg @ref CRC_INPUTDATA_INVERSION_HALFWORD HalfWord-wise bit reversal
165   *          @arg @ref CRC_INPUTDATA_INVERSION_WORD     Word-wise bit reversal
166   * @retval HAL status
167   */
HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef * hcrc,uint32_t InputReverseMode)168 HAL_StatusTypeDef HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t InputReverseMode)
169 {
170   /* Check the parameters */
171   assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(InputReverseMode));
172 
173   /* Change CRC peripheral state */
174   hcrc->State = HAL_CRC_STATE_BUSY;
175 
176   /* set input data inversion mode */
177   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, InputReverseMode);
178   /* Change CRC peripheral state */
179   hcrc->State = HAL_CRC_STATE_READY;
180 
181   /* Return function status */
182   return HAL_OK;
183 }
184 
185 /**
186   * @brief  Set the Reverse Output data mode.
187   * @param  hcrc CRC handle
188   * @param  OutputReverseMode Output Data inversion mode.
189   *         This parameter can be one of the following values:
190   *          @arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion (default value)
191   *          @arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE  bit-level inversion (e.g. for a 8-bit CRC: 0xB5 becomes 0xAD)
192   * @retval HAL status
193   */
HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef * hcrc,uint32_t OutputReverseMode)194 HAL_StatusTypeDef HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t OutputReverseMode)
195 {
196   /* Check the parameters */
197   assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(OutputReverseMode));
198 
199   /* Change CRC peripheral state */
200   hcrc->State = HAL_CRC_STATE_BUSY;
201 
202   /* set output data inversion mode */
203   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, OutputReverseMode);
204 
205   /* Change CRC peripheral state */
206   hcrc->State = HAL_CRC_STATE_READY;
207 
208   /* Return function status */
209   return HAL_OK;
210 }
211 
212 
213 
214 
215 /**
216   * @}
217   */
218 
219 
220 /**
221   * @}
222   */
223 
224 
225 #endif /* HAL_CRC_MODULE_ENABLED */
226 /**
227   * @}
228   */
229 
230 /**
231   * @}
232   */
233