1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include "mxc_device.h"
25 #include "mxc_assert.h"
26 #include "mxc_lock.h"
27 #include "mxc_sys.h"
28 #include "mxc_delay.h"
29 #include "htmr_reva_regs.h"
30 #include "htmr.h"
31 #include "htmr_reva.h"
32 
33 /* **** Definitions **** */
34 #define HTMR_CTRL_RESET_DEFAULT (0x8000UL)
35 #define BUSY_TIMEOUT (10000) // Timeout counts for the Busy bit
36 #define ASYNC_MODE (MXC_F_HTMR_REVA_CTRL_ACRE & htmr->ctrl)
37 
38 #define MXC_HTMR_ALL_INT_FLAGS \
39     (MXC_F_HTMR_REVA_CTRL_RDY | MXC_F_HTMR_REVA_CTRL_ALDF | MXC_F_HTMR_REVA_CTRL_ALSF)
40 #define MXC_HTMR_ALL_INT_ENABLES \
41     (MXC_F_HTMR_REVA_CTRL_RDYE | MXC_F_HTMR_REVA_CTRL_ADE | MXC_F_HTMR_REVA_CTRL_ASE)
42 
43 /* ***** Functions ***** */
MXC_HTMR_RevA_Init(mxc_htmr_reva_regs_t * htmr,uint32_t sec,uint8_t ssec)44 int MXC_HTMR_RevA_Init(mxc_htmr_reva_regs_t *htmr, uint32_t sec, uint8_t ssec)
45 {
46     if (htmr == NULL) {
47         return E_NULL_PTR;
48     }
49 
50     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
51         return E_BUSY;
52     }
53 
54     htmr->ctrl = MXC_F_HTMR_REVA_CTRL_WE; //  Allow Writes
55 
56     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
57         return E_BUSY;
58     }
59 
60     htmr->ctrl = HTMR_CTRL_RESET_DEFAULT; // Start with a Clean Register
61 
62     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
63         return E_BUSY;
64     }
65 
66     htmr->ctrl |= MXC_F_HTMR_REVA_CTRL_WE; // Set Write Enable, allow writing to reg.
67 
68     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
69         return E_BUSY;
70     }
71 
72     htmr->ssec = ssec;
73 
74     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
75         return E_BUSY;
76     }
77 
78     htmr->sec = sec;
79 
80     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
81         return E_BUSY;
82     }
83 
84     // If the peripheral clock is twice the frequency of the clock driving HTMR
85     // we can enable Asynchronous read mode for htmr->sec and htmr->ssec registers
86     if (PeripheralClock > (2 * IBRO_FREQ)) {
87         htmr->ctrl |= MXC_F_HTMR_REVA_CTRL_ACRE;
88     }
89 
90     htmr->ctrl &= ~MXC_F_HTMR_REVA_CTRL_WE; // Prevent Writing...
91 
92     return E_SUCCESS;
93 }
94 
MXC_HTMR_RevA_Start(mxc_htmr_reva_regs_t * htmr)95 int MXC_HTMR_RevA_Start(mxc_htmr_reva_regs_t *htmr)
96 {
97     if (htmr == NULL) {
98         return E_NULL_PTR;
99     }
100 
101     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
102         return E_BUSY;
103     }
104 
105     htmr->ctrl |= MXC_F_HTMR_REVA_CTRL_WE; // Allow writing to registers
106 
107     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
108         return E_BUSY;
109     }
110 
111     // Can only write if WE=1 and BUSY=0
112     htmr->ctrl |= MXC_F_HTMR_REVA_CTRL_HTEN; // setting RTCE = 1
113 
114     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
115         return E_BUSY;
116     }
117 
118     htmr->ctrl &= ~MXC_F_HTMR_REVA_CTRL_WE; // Prevent Writing...
119 
120     return E_SUCCESS;
121 }
122 
MXC_HTMR_RevA_Stop(mxc_htmr_reva_regs_t * htmr)123 int MXC_HTMR_RevA_Stop(mxc_htmr_reva_regs_t *htmr)
124 {
125     if (htmr == NULL) {
126         return E_NULL_PTR;
127     }
128 
129     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
130         return E_BUSY;
131     }
132 
133     htmr->ctrl |= MXC_F_HTMR_REVA_CTRL_WE; // Allow writing to registers
134 
135     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
136         return E_BUSY;
137     }
138 
139     // Can only write if WE=1 and BUSY=0
140     htmr->ctrl &= ~MXC_F_HTMR_REVA_CTRL_HTEN; // setting RTCE = 0
141 
142     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
143         return E_BUSY;
144     }
145 
146     htmr->ctrl &= ~MXC_F_HTMR_REVA_CTRL_WE; // Prevent Writing...
147 
148     return E_SUCCESS;
149 }
150 
MXC_HTMR_RevA_GetShortCount(mxc_htmr_reva_regs_t * htmr)151 int MXC_HTMR_RevA_GetShortCount(mxc_htmr_reva_regs_t *htmr)
152 {
153     if (htmr == NULL) {
154         return E_NULL_PTR;
155     }
156 
157     // Don't bother calling CheckBusy() if we're in async mode
158     if (!ASYNC_MODE) {
159         if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
160             return E_BUSY;
161         }
162     }
163 
164     return htmr->ssec;
165 }
166 
MXC_HTMR_RevA_GetLongCount(mxc_htmr_reva_regs_t * htmr)167 int MXC_HTMR_RevA_GetLongCount(mxc_htmr_reva_regs_t *htmr)
168 {
169     if (htmr == NULL) {
170         return E_NULL_PTR;
171     }
172 
173     // Don't bother calling CheckBusy() if we're in async mode
174     if (!ASYNC_MODE) {
175         if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
176             return E_BUSY;
177         }
178     }
179 
180     return htmr->sec;
181 }
182 
MXC_HTMR_RevA_SetLongAlarm(mxc_htmr_reva_regs_t * htmr,uint32_t ras)183 int MXC_HTMR_RevA_SetLongAlarm(mxc_htmr_reva_regs_t *htmr, uint32_t ras)
184 {
185     // compare with maximum value
186     if (ras > 0xFFFFF) {
187         return E_BAD_PARAM;
188     }
189 
190     if (MXC_HTMR_DisableInt((mxc_htmr_regs_t *)htmr, MXC_F_HTMR_REVA_CTRL_ADE) == E_BUSY) {
191         return E_BUSY;
192     }
193 
194     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
195         return E_BUSY;
196     }
197 
198     htmr->ras = (ras << MXC_F_HTMR_REVA_RAS_RAS_POS) & MXC_F_HTMR_REVA_RAS_RAS;
199 
200     if (MXC_HTMR_EnableInt((mxc_htmr_regs_t *)htmr, MXC_F_HTMR_REVA_CTRL_ADE) == E_BUSY) {
201         return E_BUSY;
202     }
203 
204     return E_SUCCESS;
205 }
206 
MXC_HTMR_RevA_SetShortAlarm(mxc_htmr_reva_regs_t * htmr,uint32_t rssa)207 int MXC_HTMR_RevA_SetShortAlarm(mxc_htmr_reva_regs_t *htmr, uint32_t rssa)
208 {
209     if (MXC_HTMR_DisableInt((mxc_htmr_regs_t *)htmr, MXC_F_HTMR_REVA_CTRL_ASE) == E_BUSY) {
210         return E_BUSY;
211     }
212 
213     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
214         return E_BUSY;
215     }
216 
217     htmr->rssa = (rssa << MXC_F_HTMR_REVA_RSSA_RSSA_POS) & MXC_F_HTMR_REVA_RSSA_RSSA;
218 
219     if (MXC_HTMR_EnableInt((mxc_htmr_regs_t *)htmr, MXC_F_HTMR_REVA_CTRL_ASE) == E_BUSY) {
220         return E_BUSY;
221     }
222 
223     return E_SUCCESS;
224 }
225 
MXC_HTMR_RevA_CheckBusy(mxc_htmr_reva_regs_t * htmr)226 int MXC_HTMR_RevA_CheckBusy(mxc_htmr_reva_regs_t *htmr)
227 {
228     MXC_DelayAsync(MXC_DELAY_USEC(BUSY_TIMEOUT), NULL);
229 
230     while (htmr->ctrl & MXC_F_HTMR_CTRL_BUSY) {
231         MXC_DelayAbort();
232 
233         if (MXC_DelayCheck() != E_BUSY) {
234             return E_BUSY;
235         }
236     }
237 
238     return E_SUCCESS;
239 }
240 
MXC_HTMR_RevA_GetFlags(mxc_htmr_reva_regs_t * htmr)241 int MXC_HTMR_RevA_GetFlags(mxc_htmr_reva_regs_t *htmr)
242 {
243     if (htmr == NULL) {
244         return E_NULL_PTR;
245     }
246 
247     return htmr->ctrl & MXC_HTMR_ALL_INT_FLAGS;
248 }
249 
MXC_HTMR_RevA_ClearFlags(mxc_htmr_reva_regs_t * htmr,int flags)250 int MXC_HTMR_RevA_ClearFlags(mxc_htmr_reva_regs_t *htmr, int flags)
251 {
252     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
253         return E_BUSY;
254     }
255 
256     htmr->ctrl &= ~(flags & MXC_HTMR_ALL_INT_FLAGS);
257 
258     return E_SUCCESS;
259 }
260 
MXC_HTMR_RevA_EnableInt(mxc_htmr_reva_regs_t * htmr,uint32_t mask)261 int MXC_HTMR_RevA_EnableInt(mxc_htmr_reva_regs_t *htmr, uint32_t mask)
262 {
263     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
264         return E_BUSY;
265     }
266 
267     htmr->ctrl |= (mask & MXC_HTMR_ALL_INT_ENABLES); // Disable Long Interval Interrupt
268 
269     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
270         return E_BUSY;
271     }
272 
273     return E_SUCCESS;
274 }
275 
MXC_HTMR_RevA_DisableInt(mxc_htmr_reva_regs_t * htmr,uint32_t mask)276 int MXC_HTMR_RevA_DisableInt(mxc_htmr_reva_regs_t *htmr, uint32_t mask)
277 {
278     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
279         return E_BUSY;
280     }
281 
282     htmr->ctrl &= ~(mask & MXC_HTMR_ALL_INT_ENABLES); // Disable Long Interval Interrupt
283 
284     if (MXC_HTMR_CheckBusy((mxc_htmr_regs_t *)htmr)) {
285         return E_BUSY;
286     }
287 
288     return E_SUCCESS;
289 }
290