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 <stddef.h>
22 #include "mxc_assert.h"
23 #include "mxc_pins.h"
24 #include "mxc_lock.h"
25 #include "mxc_delay.h"
26 #include "mxc_device.h"
27 #include "smon_reva.h"
28 
MXC_SMON_RevA_ExtSensorEnable(mxc_smon_reva_regs_t * smon,mxc_smon_reva_ext_cfg_t * cfg,uint32_t delay)29 int MXC_SMON_RevA_ExtSensorEnable(mxc_smon_reva_regs_t *smon, mxc_smon_reva_ext_cfg_t *cfg,
30                                   uint32_t delay)
31 {
32     int err;
33 
34     if (cfg == NULL) {
35         return E_NULL_PTR;
36     }
37 
38     if ((err = MXC_SMON_SetSensorFrequency((mxc_smon_ext_cfg_t *)cfg)) != E_NO_ERROR) {
39         return err;
40     }
41 
42     if ((err = MXC_SMON_SetErrorCount(cfg->errorCount)) != E_NO_ERROR) {
43         return err;
44     }
45 
46     //Enable external sensor
47     smon->extscn |= cfg->sensorNumber;
48 
49     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_EXTSENSOR, delay)) != E_NO_ERROR) {
50         return err;
51     }
52 
53     return err;
54 }
55 
MXC_SMON_RevA_SetSensorFrequency(mxc_smon_reva_regs_t * smon,mxc_smon_reva_ext_cfg_t * cfg)56 int MXC_SMON_RevA_SetSensorFrequency(mxc_smon_reva_regs_t *smon, mxc_smon_reva_ext_cfg_t *cfg)
57 {
58     int err;
59 
60     if (cfg == NULL) {
61         return E_NULL_PTR;
62     }
63 
64     smon->extscn |= (cfg->clockDivide | cfg->freqDivide);
65 
66     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_EXTSENSOR, 0)) != E_NO_ERROR) {
67         return err;
68     }
69 
70     return err;
71 }
72 
MXC_SMON_RevA_SetErrorCount(mxc_smon_reva_regs_t * smon,uint8_t errorCount)73 int MXC_SMON_RevA_SetErrorCount(mxc_smon_reva_regs_t *smon, uint8_t errorCount)
74 {
75     int err;
76 
77     if (errorCount > 31) {
78         return E_BAD_PARAM;
79     }
80 
81     smon->extscn &= ~MXC_F_SMON_REVA_EXTSCN_EXTCNT;
82     smon->extscn |= errorCount << MXC_F_SMON_REVA_EXTSCN_EXTCNT_POS;
83 
84     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_EXTSENSOR, 0)) != E_NO_ERROR) {
85         return err;
86     }
87 
88     return err;
89 }
90 
MXC_SMON_RevA_TempSensorEnable(mxc_smon_reva_regs_t * smon,mxc_smon_reva_temp_t threshold,uint32_t delay)91 int MXC_SMON_RevA_TempSensorEnable(mxc_smon_reva_regs_t *smon, mxc_smon_reva_temp_t threshold,
92                                    uint32_t delay)
93 {
94     int err;
95 
96     if ((err = MXC_SMON_SetTempThreshold((mxc_smon_temp_t)threshold)) != E_NO_ERROR) {
97         return err;
98     }
99 
100     smon->intscn |= MXC_F_SMON_REVA_INTSCN_TEMP_EN; //Enable Sensor
101 
102     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, delay)) != E_NO_ERROR) {
103         return err;
104     }
105 
106     return err;
107 }
108 
MXC_SMON_RevA_SetTempThreshold(mxc_smon_reva_regs_t * smon,mxc_smon_reva_temp_t threshold)109 int MXC_SMON_RevA_SetTempThreshold(mxc_smon_reva_regs_t *smon, mxc_smon_reva_temp_t threshold)
110 {
111     int err;
112 
113     if (threshold == SMON_REVA_TEMP_THRESHOLD_NEG_50) {
114         smon->intscn &= ~MXC_F_SMON_REVA_INTSCN_LOTEMP_SEL;
115     } else if (threshold == SMON_REVA_TEMP_THRESHOLD_NEG_30) {
116         smon->intscn |= MXC_F_SMON_REVA_INTSCN_LOTEMP_SEL;
117     } else {
118         return E_BAD_PARAM;
119     }
120 
121     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, 0)) != E_NO_ERROR) {
122         return err;
123     }
124 
125     return err;
126 }
127 
MXC_SMON_RevA_VoltageMonitorEnable(mxc_smon_reva_regs_t * smon,mxc_smon_reva_vtm_t threshold,uint32_t delay)128 int MXC_SMON_RevA_VoltageMonitorEnable(mxc_smon_reva_regs_t *smon, mxc_smon_reva_vtm_t threshold,
129                                        uint32_t delay)
130 {
131     int err;
132 
133     if ((err = MXC_SMON_SetVTMThreshold((mxc_smon_vtm_t)threshold)) != E_NO_ERROR) {
134         return err;
135     }
136 
137     smon->intscn |= MXC_F_SMON_REVA_INTSCN_VBAT_EN; //Enable Sensor
138 
139     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, delay)) != E_NO_ERROR) {
140         return err;
141     }
142 
143     return err;
144 }
145 
MXC_SMON_RevA_SetVTMThreshold(mxc_smon_reva_regs_t * smon,mxc_smon_reva_vtm_t threshold)146 int MXC_SMON_RevA_SetVTMThreshold(mxc_smon_reva_regs_t *smon, mxc_smon_reva_vtm_t threshold)
147 {
148     int err;
149 
150     if (threshold == SMON_REVA_VTM_THRESHOLD_1_6) {
151         smon->intscn &= ~(MXC_F_SMON_REVA_INTSCN_VCORELOEN | MXC_F_SMON_REVA_INTSCN_VCOREHIEN);
152     } else if (threshold == SMON_REVA_VTM_THRESHOLD_2_2) {
153         smon->intscn &= ~MXC_F_SMON_REVA_INTSCN_VCOREHIEN;
154         smon->intscn |= MXC_F_SMON_REVA_INTSCN_VCORELOEN;
155     } else if (threshold == SMON_REVA_VTM_THRESHOLD_2_8) {
156         smon->intscn |= (MXC_F_SMON_REVA_INTSCN_VCORELOEN | MXC_F_SMON_REVA_INTSCN_VCOREHIEN);
157     } else {
158         return E_BAD_PARAM;
159     }
160 
161     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, 0)) != E_NO_ERROR) {
162         return err;
163     }
164 
165     return err;
166 }
167 
MXC_SMON_RevA_ActiveDieShieldEnable(mxc_smon_reva_regs_t * smon,uint32_t delay)168 int MXC_SMON_RevA_ActiveDieShieldEnable(mxc_smon_reva_regs_t *smon, uint32_t delay)
169 {
170     int err;
171 
172     smon->intscn |= MXC_F_SMON_REVA_INTSCN_SHIELD_EN; //Enable Sensor
173 
174     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, delay)) != E_NO_ERROR) {
175         return err;
176     }
177 
178     return err;
179 }
180 
MXC_SMON_RevA_SelfDestructByteEnable(mxc_smon_reva_regs_t * smon,mxc_smon_reva_ext_cfg_t * cfg,uint32_t delay)181 int MXC_SMON_RevA_SelfDestructByteEnable(mxc_smon_reva_regs_t *smon, mxc_smon_reva_ext_cfg_t *cfg,
182                                          uint32_t delay)
183 {
184     int err;
185 
186     if (cfg == NULL) {
187         return E_NULL_PTR;
188     }
189 
190     smon->sdbe &= ~MXC_F_SMON_REVA_SDBE_SBDEN;
191 
192     smon->sdbe |= cfg->data << MXC_F_SMON_REVA_SDBE_DBYTE_POS;
193 
194     if ((err = MXC_SMON_ExtSensorEnable((mxc_smon_ext_cfg_t *)cfg, delay)) != E_NO_ERROR) {
195         return err;
196     }
197 
198     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, delay)) != E_NO_ERROR) {
199         return err;
200     }
201 
202     smon->sdbe |= MXC_F_SMON_REVA_SDBE_SBDEN;
203 
204     return err;
205 }
206 
MXC_SMON_RevA_EnablePUFTrimErase(mxc_smon_reva_regs_t * smon)207 void MXC_SMON_RevA_EnablePUFTrimErase(mxc_smon_reva_regs_t *smon)
208 {
209     smon->intscn |= MXC_F_SMON_REVA_INTSCN_PUF_TRIM_ERASE;
210 
211     MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, 0);
212 }
213 
MXC_SMON_RevA_DisablePUFTrimErase(mxc_smon_reva_regs_t * smon)214 void MXC_SMON_RevA_DisablePUFTrimErase(mxc_smon_reva_regs_t *smon)
215 {
216     smon->intscn &= ~MXC_F_SMON_REVA_INTSCN_PUF_TRIM_ERASE;
217 
218     MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, 0);
219 }
220 
MXC_SMON_RevA_DigitalFaultDetectorEnable(mxc_smon_reva_regs_t * smon,mxc_smon_reva_interrupt_mode_t interruptMode,mxc_smon_reva_lowpower_mode_t lowPowerMode,uint32_t delay)221 int MXC_SMON_RevA_DigitalFaultDetectorEnable(mxc_smon_reva_regs_t *smon,
222                                              mxc_smon_reva_interrupt_mode_t interruptMode,
223                                              mxc_smon_reva_lowpower_mode_t lowPowerMode,
224                                              uint32_t delay)
225 {
226     int err;
227 
228     if (interruptMode == SMON_REVA_DFD_INTERRUPT_NMI) {
229         smon->intscn &= ~MXC_F_SMON_REVA_INTSCN_DFD_STDBY;
230     } else if (interruptMode == SMON_REVA_DFD_INTERRUPT_PFW) {
231         smon->intscn |= MXC_F_SMON_REVA_INTSCN_DFD_STDBY;
232     } else {
233         return E_BAD_PARAM;
234     }
235 
236     if (lowPowerMode == SMON_REVA_DFD_LOWPOWER_ENABLE) {
237         smon->intscn &= ~MXC_F_SMON_REVA_INTSCN_DFD_NMI;
238     } else if (lowPowerMode == SMON_REVA_DFD_LOWPOWER_DISABLE) {
239         smon->intscn |= MXC_F_SMON_REVA_INTSCN_DFD_NMI;
240     } else {
241         return E_BAD_PARAM;
242     }
243 
244     smon->intscn |= MXC_F_SMON_REVA_INTSCN_DFD_EN; //Enable DFD
245 
246     if ((err = MXC_SMON_isBusy((mxc_smon_busy_t)SMON_REVA_INTSENSOR, delay)) != E_NO_ERROR) {
247         return err;
248     }
249 
250     return err;
251 }
252 
MXC_SMON_RevA_GetFlags(mxc_smon_reva_regs_t * smon)253 uint32_t MXC_SMON_RevA_GetFlags(mxc_smon_reva_regs_t *smon)
254 {
255     return smon->secalm;
256 }
257 
MXC_SMON_RevA_ClearFlags(mxc_smon_reva_regs_t * smon,uint32_t flags)258 void MXC_SMON_RevA_ClearFlags(mxc_smon_reva_regs_t *smon, uint32_t flags)
259 {
260     MXC_SMON_RevA_isBusy(smon, SMON_REVA_SECALARM, 0);
261     smon->secalm &= ~flags;
262     MXC_SMON_RevA_isBusy(smon, SMON_REVA_SECALARM, 0);
263 }
264 
MXC_SMON_RevA_ExtSensorLock(mxc_smon_reva_regs_t * smon)265 void MXC_SMON_RevA_ExtSensorLock(mxc_smon_reva_regs_t *smon)
266 {
267     smon->extscn |= MXC_F_SMON_REVA_EXTSCN_LOCK;
268 }
269 
MXC_SMON_RevA_IntSensorLock(mxc_smon_reva_regs_t * smon)270 void MXC_SMON_RevA_IntSensorLock(mxc_smon_reva_regs_t *smon)
271 {
272     smon->intscn |= MXC_F_SMON_REVA_INTSCN_LOCK;
273 }
274 
MXC_SMON_RevA_isBusy(mxc_smon_reva_regs_t * smon,mxc_smon_reva_busy_t reg,uint32_t delay)275 int MXC_SMON_RevA_isBusy(mxc_smon_reva_regs_t *smon, mxc_smon_reva_busy_t reg, uint32_t delay)
276 {
277     if (delay == 0) {
278         while (smon->secst & reg) {}
279 
280         return E_NO_ERROR;
281     }
282 
283     MXC_Delay(delay);
284 
285     if (smon->secst & reg) {
286         return E_BUSY;
287     }
288 
289     return E_NO_ERROR;
290 }
291