1 /*!
2  * @file        apm32f0xx_crs.c
3  *
4  * @brief       This file contains all the functions for the CRS peripheral
5  *
6  * @note        It's only for APM32F072 and APM32F091 devices
7  *
8  * @version     V1.0.3
9  *
10  * @date        2022-09-20
11  *
12  * @attention
13  *
14  *  Copyright (C) 2020-2022 Geehy Semiconductor
15  *
16  *  You may not use this file except in compliance with the
17  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
18  *
19  *  The program is only for reference, which is distributed in the hope
20  *  that it will be useful and instructional for customers to develop
21  *  their software. Unless required by applicable law or agreed to in
22  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
23  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
24  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
25  *  and limitations under the License.
26  */
27 
28 /* Includes */
29 #include "apm32f0xx_crs.h"
30 #include "apm32f0xx_rcm.h"
31 
32 /** @addtogroup APM32F0xx_StdPeriphDriver
33   @{
34 */
35 
36 /** @addtogroup CRS_Driver
37   @{
38 */
39 
40 /** @defgroup CRS_Macros Macros
41   @{
42 */
43 
44 /**@} end of group CRS_Macros */
45 
46 /** @defgroup CRS_Enumerations Enumerations
47   @{
48 */
49 
50 /**@} end of group CRS_Enumerations */
51 
52 /** @defgroup CRS_Structures Structures
53   @{
54 */
55 
56 /**@} end of group CRS_Structures */
57 
58 /** @defgroup CRS_Variables Variables
59   @{
60 */
61 
62 /**@} end of group CRS_Variables */
63 
64 /** @defgroup CRS_Functions Functions
65   @{
66 */
67 
68 /*!
69  * @brief    Resets the CRS peripheral registers to their default reset values.
70  *
71  * @param    None
72  *
73  * @retval   None
74  */
CRS_Reset(void)75 void CRS_Reset(void)
76 {
77     RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CRS);
78     RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CRS);
79 }
80 
81 /*!
82  * @brief    Adjusts the Internal High Speed 48 oscillator (HSI 48) calibration value.
83  *
84  * @param    calibrationVal: HSI48 oscillator smooth trimming value. It can be 0x0 to 0xF.
85  *
86  * @retval   None
87  */
CRS_AdjustHSI48CalibrationValue(uint8_t calibrationVal)88 void CRS_AdjustHSI48CalibrationValue(uint8_t calibrationVal)
89 {
90     CRS->CTRL_B.HSI48TRM = calibrationVal;
91 }
92 
93 /*!
94  * @brief    Enables the oscillator clock for frequency error counter.
95  *
96  * @param    None
97  *
98  * @retval   None
99  */
CRS_EnableFrequencyErrorCounter(void)100 void CRS_EnableFrequencyErrorCounter(void)
101 {
102     CRS->CTRL_B.CNTEN = SET;
103 }
104 
105 /*!
106  * @brief    Disables the oscillator clock for frequency error counter.
107  *
108  * @param    None
109  *
110  * @retval   None
111  */
CRS_DisableFrequencyErrorCounter(void)112 void CRS_DisableFrequencyErrorCounter(void)
113 {
114     CRS->CTRL_B.CNTEN = RESET;
115 }
116 
117 /*!
118  * @brief  Enables the automatic hardware adjustement of HSI48TRM bits.
119  *
120  * @param  None
121  *
122  * @retval None
123  */
CRS_EnableAutomaticCalibration(void)124 void CRS_EnableAutomaticCalibration(void)
125 {
126     CRS->CTRL_B.AUTOTRMEN = SET;
127 }
128 
129 /*!
130  * @brief    Disables the automatic hardware adjustement of HSI48TRM bits.
131  *
132  * @param    None
133  *
134  * @retval   None
135  */
CRS_DisableAutomaticCalibration(void)136 void CRS_DisableAutomaticCalibration(void)
137 {
138     CRS->CTRL_B.AUTOTRMEN = RESET;
139 }
140 
141 /*!
142  * @brief  Generate the software synchronization event.
143  *
144  * @param  None
145  *
146  * @retval None
147  */
CRS_GenerateSoftwareSynchronization(void)148 void CRS_GenerateSoftwareSynchronization(void)
149 {
150     CRS->CTRL_B.SWSGNR = SET;
151 }
152 
153 /*!
154  * @brief  Adjusts the Internal High Speed 48 oscillator (HSI 48) calibration value.
155  *
156  * @param  reloadVal: specifies the HSI calibration trimming value.
157  *                    This parameter must be a number between 0 and 0xFFFF.
158  *
159  * @retval None
160  */
CRS_FrequencyErrorCounterReloadValue(uint16_t reloadVal)161 void CRS_FrequencyErrorCounterReloadValue(uint16_t reloadVal)
162 {
163     CRS->CFG_B.RLDVAL = reloadVal;
164 }
165 
166 /**
167  * @brief   Configs the frequency error limit value.
168  *
169  * @param    errLimitVal: specifies the HSI calibration trimming value.
170  *
171  * @retval   None
172  */
CRS_ConfigFrequencyErrorLimit(uint8_t errLimitVal)173 void CRS_ConfigFrequencyErrorLimit(uint8_t errLimitVal)
174 {
175     CRS->CFG_B.FELMT = errLimitVal;
176 }
177 
178 /*!
179  * @brief    Configs SYNC divider.
180  *
181  * @param    div: defines the SYNC divider.
182  *                This parameter can be one of the following values:
183  *                  @arg CRS_SYNC_DIV1
184  *                  @arg CRS_SYNC_DIV2
185  *                  @arg CRS_SYNC_DIV4
186  *                  @arg CRS_SYNC_DIV8
187  *                  @arg CRS_SYNC_DIV16
188  *                  @arg CRS_SYNC_DIV32
189  *                  @arg CRS_SYNC_DIV64
190  *                  @arg CRS_SYNC_DIV128
191  *
192  * @retval   None
193  */
CRS_ConfigSynchronizationPrescaler(CRS_SYNC_DIV_T div)194 void CRS_ConfigSynchronizationPrescaler(CRS_SYNC_DIV_T div)
195 {
196     CRS->CFG_B.SYNCPSC = div;
197 }
198 
199 /*!
200  * @brief    Configs the SYNC signal source.
201  *
202  * @param    source: specifies the SYNC signal source.
203  *                   This parameter can be one of the following values:
204  *                     @arg CRS_SYNC_SOURCE_GPIO
205  *                     @arg CRS_SYNC_SOURCE_LSE
206  *                     @arg CRS_SYNC_SOURCE_USB
207  *
208  * @retval   None
209  */
CRS_ConfigSynchronizationSource(CRS_SYNC_SOURCE_T source)210 void CRS_ConfigSynchronizationSource(CRS_SYNC_SOURCE_T source)
211 {
212     CRS->CFG_B.SYNCSRCSEL = source;
213 }
214 
215 /*!
216  * @brief    Configs the SYNC polarity.
217  *
218  * @param    polarity: specifies SYNC polarity.
219  *                     This parameter can be one of the following values:
220  *                       @arg CRS_SYNC_POL_RISING
221  *                       @arg CRS_SYNC_POL_FALLING
222  *
223  * @retval   None
224  */
CRS_ConfigSynchronizationPolarity(CRS_SYNC_POL_T polarity)225 void CRS_ConfigSynchronizationPolarity(CRS_SYNC_POL_T polarity)
226 {
227     CRS->CFG_B.SYNCPOLSEL = polarity;
228 }
229 
230 /*!
231  * @brief    Returns the Relaod value.
232  *
233  * @param    None
234  *
235  * @retval   The reload value
236  */
CRS_ReadReloadValue(void)237 uint32_t CRS_ReadReloadValue(void)
238 {
239     return (uint32_t)CRS->CFG_B.RLDVAL;
240 }
241 
242 /*!
243  * @brief    Returns the HSI48 Calibration value.
244  *
245  * @param    None
246  *
247  * @retval   The reload value
248  */
CRS_ReadHSI48CalibrationValue(void)249 uint32_t CRS_ReadHSI48CalibrationValue(void)
250 {
251     return (uint32_t)CRS->CTRL_B.HSI48TRM;
252 }
253 
254 /*!
255  * @brief    Returns the frequency error capture.
256  *
257  * @param    None
258  *
259  * @retval   The frequency error capture value
260  */
CRS_ReadFrequencyErrorValue(void)261 uint32_t CRS_ReadFrequencyErrorValue(void)
262 {
263     return (uint32_t)CRS->INTSTS_B.FECPT;
264 }
265 
266 /*!
267  * @brief    Returns the frequency error direction.
268  *
269  * @param    None
270  *
271  * @retval   The frequency error direction.
272  *           The returned value can be one of the following values:
273  *              0: Up counting
274  *              1: Down counting
275  */
CRS_ReadFrequencyErrorDirection(void)276 uint32_t CRS_ReadFrequencyErrorDirection(void)
277 {
278     return (uint32_t)CRS->INTSTS_B.CNTDRCT;
279 }
280 
281 /*!
282  * @brief    Enables the specified CRS interrupts.
283  *
284  * @param    interrupt: specifies the RCC interrupt sources to be enabled or disabled.
285  *                      This parameter can be any combination of the following values:
286  *                          @arg CRS_INT_SYNCOK  : SYNC event OK interrupt
287  *                          @arg CRS_INT_SYNCWARN: SYNC warning interrupt
288  *                          @arg CRS_INT_ERR     : Synchronization or trimming error interrupt
289  *                          @arg CRS_INT_ESYNC   : Expected SYNC interrupt
290  *
291  * @retval   None
292  */
CRS_EnableInterrupt(CRS_INT_T interrupt)293 void CRS_EnableInterrupt(CRS_INT_T interrupt)
294 {
295     CRS->CTRL |= interrupt;
296 }
297 
298 /*!
299  * @brief    Disables the specified CRS interrupts.
300  *
301  * @param    interrupt: specifies the RCC interrupt sources to be enabled or disabled.
302  *                      This parameter can be any combination of the following values:
303  *                          @arg CRS_INT_SYNCOK  : SYNC event OK interrupt
304  *                          @arg CRS_INT_SYNCWARN: SYNC warning interrupt
305  *                          @arg CRS_INT_ERR     : Synchronization or trimming error interrupt
306  *                          @arg CRS_INT_ESYNC   : Expected SYNC interrupt
307  *
308  * @retval   None
309  */
CRS_DisableInterrupt(CRS_INT_T interrupt)310 void CRS_DisableInterrupt(CRS_INT_T interrupt)
311 {
312     CRS->CTRL &= ~interrupt;
313 }
314 
315 /*!
316  * @brief    Checks whether the specified CRS flag is set or not.
317  *
318  * @param    flag: specifies the flag to check.
319  *                 This parameter can be one of the following values:
320  *                     @arg CRS_FLAG_SYNCOK  : SYNC event OK flag
321  *                     @arg CRS_FLAG_SYNCWARN: SYNC warning flag
322  *                     @arg CRS_FLAG_ERR     : Synchronization or trimming error flag
323  *                     @arg CRS_FLAG_ESYNC   : Expected SYNC flag
324  *                     @arg CRS_FLAG_SYNCERR : SYNC error flag
325  *                     @arg CRS_FLAG_SYNCMISS: SYNC missed flag
326  *                     @arg CRS_FLAG_TRIMOVF : Trimming overflow or underflow falg
327  *
328  * @retval   The new state of CRS_FLAG (SET or RESET).
329  */
CRS_ReadStatusFlag(CRS_FLAG_T flag)330 uint8_t CRS_ReadStatusFlag(CRS_FLAG_T flag)
331 {
332     uint32_t status;
333     status = (uint32_t)(CRS->INTSTS & flag);
334 
335     if (status == flag)
336     {
337         return SET;
338     }
339 
340     return RESET;
341 }
342 
343 /*!
344  * @brief    Clears the CRS specified flag.
345  *
346  * @param    flag: specifies the flag to check.
347  *                 This parameter can be one of the following values:
348  *                     @arg CRS_FLAG_SYNCOK  : SYNC event OK flag
349  *                     @arg CRS_FLAG_SYNCWARN: SYNC warning flag
350  *                     @arg CRS_FLAG_ERR     : Synchronization or trimming error flag
351  *                     @arg CRS_FLAG_ESYNC   : Expected SYNC flag
352  *                     @arg CRS_FLAG_SYNCERR : SYNC error flag
353  *                     @arg CRS_FLAG_SYNCMISS: SYNC missed flag
354  *                     @arg CRS_FLAG_TRIMOVF : Trimming overflow or underflow falg
355  *
356  * @retval   None
357  */
CRS_ClearStatusFlag(CRS_FLAG_T flag)358 void CRS_ClearStatusFlag(CRS_FLAG_T flag)
359 {
360     if ((flag & 0x00000700) != 0)
361     {
362         CRS->INTCLR_B.ECLR = BIT_SET;
363     }
364 
365     CRS->INTCLR |= (uint32_t)flag;
366 }
367 
368 /*!
369  * @brief    Checks CRS interrupt flag.
370  *
371  * @param    flag: specifies the IT pending bit to check.
372  *                   This parameter can be one of the following values:
373  *                       @arg CRS_INT_SYNCOK  : SYNC event OK interrupt
374  *                       @arg CRS_INT_SYNCWARN: SYNC warning interrupt
375  *                       @arg CRS_INT_ERR     : Synchronization or trimming error interrupt
376  *                       @arg CRS_INT_ESYNC   : Expected SYNC interrupt
377  *                       @arg CRS_INT_SYNCERR : SYNC error
378  *                       @arg CRS_INT_SYNCMISS: SYNC missed
379  *                       @arg CRS_INT_TRIMOVF : Trimming overflow or underflow
380  *
381  * @retval   The new state of CRS_IT (SET or RESET).
382  */
CRS_ReadIntFlag(CRS_INT_T flag)383 uint8_t CRS_ReadIntFlag(CRS_INT_T flag)
384 {
385     if ((CRS->INTSTS & flag))
386     {
387         return SET;
388     }
389     else
390     {
391         return RESET;
392     }
393 }
394 
395 /*!
396  * @brief    Clears the CRS specified interrupt flag.
397  *
398  * @param    intFlag: specifies the IT pending bi to clear.
399  *                     This parameter can be one of the following values:
400  *                       @arg CRS_INT_SYNCOK  : SYNC event OK interrupt
401  *                       @arg CRS_INT_SYNCWARN: SYNC warning interrupt
402  *                       @arg CRS_INT_ERR     : Synchronization or trimming error interrupt
403  *                       @arg CRS_INT_ESYNC   : Expected SYNC interrupt
404  *                       @arg CRS_INT_SYNCERR : SYNC error
405  *                       @arg CRS_INT_SYNCMISS: SYNC missed
406  *                       @arg CRS_INT_TRIMOVF : Trimming overflow or underflow
407  *
408  * @retval   None
409  */
CRS_ClearIntFlag(CRS_INT_T intFlag)410 void CRS_ClearIntFlag(CRS_INT_T intFlag)
411 {
412     if ((intFlag & (uint32_t)0x700) != 0)
413     {
414         CRS->INTCLR |= CRS_INT_ERR;
415     }
416     else
417     {
418         CRS->INTCLR |= intFlag;
419     }
420 }
421 
422 /**@} end of group CRS_Functions */
423 /**@} end of group CRS_Driver*/
424 /**@} end of group APM32F0xx_StdPeriphDriver */
425