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