1 /*
2  * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-02-09     CDT          first version
9  */
10 
11 #include <board.h>
12 #include <drv_wktm.h>
13 
14 #if defined(RT_USING_PM)
15 
16 #if defined(BSP_USING_PM)
17 
18 // #define DRV_DEBUG
19 #define LOG_TAG                         "drv_wktm"
20 #include <drv_log.h>
21 
22 #define CMPVAL_MAX                      (0xFFFUL)
23 
24 #if defined(BSP_USING_WKTM_XTAL32)
25     #define PWC_WKT_CLK_SRC             (PWC_WKT_CLK_SRC_XTAL32)
26     #define PWC_WKT_COUNT_FRQ           (32768UL)
27 #elif defined(BSP_USING_WKTM_64HZ)
28     #define PWC_WKT_CLK_SRC             (PWC_WKT_CLK_SRC_64HZ)
29     #define PWC_WKT_COUNT_FRQ           (64U)
30 #else
31     #if defined(HC32F4A0) || defined(HC32F4A8)
32         #define PWC_WKT_CLK_SRC         (PWC_WKT_CLK_SRC_RTCLRC)
33     #elif defined(HC32F460) || defined(HC32F448) || defined(HC32F472)
34         #define PWC_WKT_CLK_SRC         (PWC_WKT_CLK_SRC_LRC)
35     #endif
36     #define PWC_WKT_COUNT_FRQ           (32768UL)
37 #endif
38 
39 /**
40  * This function get timeout count value of WKTM
41  * @param  None
42  * @return the count value
43  */
hc32_wktm_get_timeout_tick(void)44 rt_uint32_t hc32_wktm_get_timeout_tick(void)
45 {
46     return (RT_TICK_PER_SECOND * PWC_WKT_GetCompareValue() / PWC_WKT_COUNT_FRQ);
47 }
48 
49 /**
50  * This function get the max value that WKTM can count
51  * @param  None
52  * @return the max count
53  */
hc32_wktm_get_tick_max(void)54 rt_uint32_t hc32_wktm_get_tick_max(void)
55 {
56     return (CMPVAL_MAX);
57 }
58 
59 /**
60  * This function start WKTM with reload value
61  * @param reload The value that Comparison value of the Counter
62  * @return RT_EOK
63  */
hc32_wktm_start(rt_uint32_t reload)64 rt_err_t hc32_wktm_start(rt_uint32_t reload)
65 {
66     /* 64HZ must use XTAL32 and run RTC */
67 #if defined(BSP_USING_WKTM_64HZ)
68 #if defined(BSP_RTC_USING_XTAL32)
69     if (DISABLE == RTC_GetCounterState())
70     {
71         /* #error "Please start the RTC!" */
72         RT_ASSERT(0);
73     }
74 #else
75 #error "Please enable XTAL32 and start the RTC!"
76 #endif
77 #endif
78     if (reload > CMPVAL_MAX || !reload)
79     {
80         return -RT_ERROR;
81     }
82     PWC_WKT_SetCompareValue(reload);
83     PWC_WKT_Cmd(ENABLE);
84 
85     return RT_EOK;
86 }
87 
88 /**
89  * @brief  This function stop WKTM
90  * @param  None
91  * @retval None
92  */
hc32_wktm_stop(void)93 void hc32_wktm_stop(void)
94 {
95     PWC_WKT_Cmd(DISABLE);
96 }
97 
98 /**
99  * This function get the count clock of WKTM
100  * @param  None
101  * @return the count clock frequency in Hz
102  */
hc32_wktm_get_countfreq(void)103 rt_uint32_t hc32_wktm_get_countfreq(void)
104 {
105     return PWC_WKT_COUNT_FRQ;
106 }
107 
108 /**
109  * @brief  This function initialize the wktm
110  * @param  None
111  * @retval type code
112  */
rt_hw_wktm_init(void)113 int rt_hw_wktm_init(void)
114 {
115     rt_err_t ret = RT_EOK;
116 
117     /* Disable WKTM in advance */
118     PWC_WKT_Cmd(DISABLE);
119     /* WKTM init */
120     PWC_WKT_Config(PWC_WKT_CLK_SRC, CMPVAL_MAX);
121 
122 #if defined(HC32F4A0) || defined(HC32F4A8)
123     /* F4A0 if select RTCLRC clock need open the LRCEN by RTC->CR3 register */
124 #if (PWC_WKT_CLK_SRC == PWC_WKT_CLK_SRC_RTCLRC)
125     MODIFY_REG8(CM_RTC->CR3, RTC_CR3_LRCEN, 0x01U << RTC_CR3_LRCEN_POS);
126 #endif
127 #endif
128 
129     return ret;
130 }
131 
132 INIT_DEVICE_EXPORT(rt_hw_wktm_init);
133 
134 #endif
135 
136 #endif  /* RT_USING_PM */
137