1 /*
2 * Copyright 2023 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_common.h"
9 #include "fsl_glikey.h"
10
11 /*******************************************************************************
12 * Definitions
13 *******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.glikey"
18 #endif
19
20 #define GLIKEY_SFR_LOCK 0x05u
21 #define GLIKEY_SFR_UNLOCK 0x0Au
22
23 /* Define to select between write to CTRL0_WR_0 or CTRL1_WR_1 */
24 #define WR_EN0 (0x0Fu)
25 #define WR_EN1 (0xF0u)
26
27 #define WR_EN0_VALUE_SHIFT (0u)
28 #define WR_EN1_VALUE_SHIFT (16u)
29
30 #define CTRL_SEL_CODEWORD_SHIFT (24u)
31
32 #define WR_0_INIT (0x2u)
33 #define WR_1_INIT (0x0u)
34
35 /*******************************************************************************
36 * Prototypes
37 ******************************************************************************/
38 static inline void Glikey_Internal_Set_WR_0(GLIKEY_Type *base, uint32_t value);
39 static inline void Glikey_Internal_Set_WR_1(GLIKEY_Type *base, uint32_t value);
40 /*******************************************************************************
41 * Code
42 ******************************************************************************/
43
44 /*!
45 * Weak implementation of GLIKEY IRQ, should be re-defined by user when using GLIKEY IRQ
46
47 __WEAK void GLIKEY0_DriverIRQHandler(void)
48 {
49 GLIKEY generates IRQ until corresponding bit in STATUS is cleared by calling
50 GLIKEY_ClearStatusFlags();
51 }
52 */
53
Glikey_Internal_Set_WR_0(GLIKEY_Type * base,uint32_t value)54 static inline void Glikey_Internal_Set_WR_0(GLIKEY_Type *base, uint32_t value)
55 {
56 uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
57
58 /* Clear WR_0 */
59 ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WR_EN_0_MASK);
60
61 /* Assign value */
62 ((GLIKEY_Type *)base)->CTRL_0 = ctrl0 | GLIKEY_CTRL_0_WR_EN_0(value);
63 }
64
Glikey_Internal_Set_WR_1(GLIKEY_Type * base,uint32_t value)65 static inline void Glikey_Internal_Set_WR_1(GLIKEY_Type *base, uint32_t value)
66 {
67 uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
68
69 /* Clear WR_1 */
70 ctrl1 = ctrl1 & (~GLIKEY_CTRL_1_WR_EN_1_MASK);
71
72 /* Assign value */
73 ((GLIKEY_Type *)base)->CTRL_1 = ctrl1 | GLIKEY_CTRL_1_WR_EN_1(value);
74 }
75
GLIKEY_GetStatus(GLIKEY_Type * base)76 uint32_t GLIKEY_GetStatus(GLIKEY_Type *base)
77 {
78 return ((GLIKEY_Type *)base)->STATUS;
79 }
80
GLIKEY_IsLocked(GLIKEY_Type * base)81 status_t GLIKEY_IsLocked(GLIKEY_Type *base)
82 {
83 status_t retCode = GLIKEY_CheckLock(base);
84 if (kStatus_GLIKEY_NotLocked == retCode)
85 {
86 return kStatus_GLIKEY_NotLocked;
87 }
88 else
89 {
90 return kStatus_GLIKEY_Locked;
91 }
92 }
93
GLIKEY_CheckLock(GLIKEY_Type * base)94 status_t GLIKEY_CheckLock(GLIKEY_Type *base)
95 {
96 uint32_t sfrLock = (((GLIKEY_Type *)base)->CTRL_1 & GLIKEY_CTRL_1_SFR_LOCK_MASK) >> GLIKEY_CTRL_1_SFR_LOCK_SHIFT;
97
98 if (GLIKEY_SFR_UNLOCK != sfrLock) /* Locked */
99 {
100 return kStatus_GLIKEY_LockedError;
101 }
102
103 return kStatus_GLIKEY_NotLocked;
104 }
105
106 #if defined(GLIKEY_VERSION_FSM_CONFIG)
GLIKEY_GetVersion(GLIKEY_Type * base,uint32_t * result)107 status_t GLIKEY_GetVersion(GLIKEY_Type *base, uint32_t *result)
108 {
109 *result = ((GLIKEY_Type *)base)->VERSION;
110
111 return kStatus_Success;
112 }
113 #endif /* GLIKEY_VERSION_FSM_CONFIG */
114
GLIKEY_SyncReset(GLIKEY_Type * base)115 status_t GLIKEY_SyncReset(GLIKEY_Type *base)
116 {
117 status_t retCode = GLIKEY_CheckLock(base);
118 if (kStatus_GLIKEY_NotLocked != retCode)
119 {
120 return retCode;
121 }
122
123 /* Set CTRL_0.SFT_RST = 1 */
124 ((GLIKEY_Type *)base)->CTRL_0 |= GLIKEY_CTRL_0_SFT_RST_MASK;
125
126 return kStatus_Success;
127 }
128
GLIKEY_SetIntEnable(GLIKEY_Type * base,uint32_t value)129 status_t GLIKEY_SetIntEnable(GLIKEY_Type *base, uint32_t value)
130 {
131 status_t retCode = GLIKEY_CheckLock(base);
132 if (kStatus_GLIKEY_NotLocked != retCode)
133 {
134 return retCode;
135 }
136
137 ((GLIKEY_Type *)base)->INTR_CTRL = GLIKEY_INTR_CTRL_INT_EN(value);
138
139 return kStatus_Success;
140 }
141
GLIKEY_GetIntEnable(GLIKEY_Type * base,uint32_t * value)142 status_t GLIKEY_GetIntEnable(GLIKEY_Type *base, uint32_t *value)
143 {
144 *value = ((GLIKEY_Type *)base)->INTR_CTRL & GLIKEY_INTR_CTRL_INT_EN_MASK;
145
146 return kStatus_Success;
147 }
148
GLIKEY_ClearIntStatus(GLIKEY_Type * base)149 status_t GLIKEY_ClearIntStatus(GLIKEY_Type *base)
150 {
151 status_t retCode = GLIKEY_CheckLock(base);
152 if (kStatus_GLIKEY_NotLocked != retCode)
153 {
154 return retCode;
155 }
156
157 ((GLIKEY_Type *)base)->INTR_CTRL |= GLIKEY_INTR_CTRL_INT_CLR_MASK;
158
159 return kStatus_Success;
160 }
161
GLIKEY_SetIntStatus(GLIKEY_Type * base)162 status_t GLIKEY_SetIntStatus(GLIKEY_Type *base)
163 {
164 status_t retCode = GLIKEY_CheckLock(base);
165 if (kStatus_GLIKEY_NotLocked != retCode)
166 {
167 return retCode;
168 }
169
170 ((GLIKEY_Type *)base)->INTR_CTRL |= GLIKEY_INTR_CTRL_INT_SET_MASK;
171
172 return kStatus_Success;
173 }
174
GLIKEY_Lock(GLIKEY_Type * base)175 status_t GLIKEY_Lock(GLIKEY_Type *base)
176 {
177 /* Check if SFR_LOCK is locked */
178 status_t retCode = GLIKEY_CheckLock(base);
179 if (kStatus_GLIKEY_NotLocked != retCode) /* Glikey is not locked -> lock */
180 {
181 uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
182 /* Clear SFR_LOCK */
183 ctrl1 = ctrl1 & (~GLIKEY_CTRL_1_SFR_LOCK_MASK);
184 /* Lock Gliekey */
185 ((GLIKEY_Type *)base)->CTRL_1 = ctrl1 | GLIKEY_CTRL_1_SFR_LOCK(GLIKEY_SFR_LOCK);
186 }
187
188 return kStatus_Success;
189 }
190
GLIKEY_IsIndexLocked(GLIKEY_Type * base,uint32_t index)191 status_t GLIKEY_IsIndexLocked(GLIKEY_Type *base, uint32_t index)
192 {
193 /* Set CTRL_1.READ_INDEX = index */
194 uint32_t ctr1Val = ((GLIKEY_Type *)base)->CTRL_1;
195 /* Clear READ_INDEX */
196 ctr1Val = ctr1Val & (~GLIKEY_CTRL_1_READ_INDEX_MASK);
197 /* Set index value */
198 ((GLIKEY_Type *)base)->CTRL_1 = ctr1Val | GLIKEY_CTRL_1_READ_INDEX(index);
199
200 /* Check ERROR_STATUS */
201 if (0u != (GLIKEY_GetStatus(base) & GLIKEY_STATUS_ERROR_STATUS_MASK))
202 {
203 return kStatus_Fail;
204 }
205
206 /* Check if STATUS.LOCK_STATUS is 0 */
207 if (0u == (GLIKEY_GetStatus(base) & GLIKEY_STATUS_LOCK_STATUS_MASK))
208 {
209 return kStatus_GLIKEY_NotLocked;
210 }
211 else
212 {
213 return kStatus_GLIKEY_Locked;
214 }
215 }
216
GLIKEY_LockIndex(GLIKEY_Type * base)217 status_t GLIKEY_LockIndex(GLIKEY_Type *base)
218 {
219 /* Check if Glikey SFR locked */
220 status_t retCode = GLIKEY_CheckLock(base);
221 if (kStatus_GLIKEY_NotLocked != retCode)
222 {
223 return retCode;
224 }
225
226 /* Check if FSM is in WR_EN state */
227 uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
228 if (GLIKEY_FSM_WR_EN == state)
229 {
230 /* Set WR_EN0 = b11 */
231 ((GLIKEY_Type *)base)->CTRL_0 |= GLIKEY_CTRL_0_WR_EN_0(0x3u);
232 return kStatus_GLIKEY_Locked;
233 }
234 else
235 {
236 return kStatus_GLIKEY_DisabledError;
237 }
238 }
239
GLIKEY_StartEnable(GLIKEY_Type * base,uint32_t index)240 status_t GLIKEY_StartEnable(GLIKEY_Type *base, uint32_t index)
241 {
242 /* Check if Glikey SFR locked */
243 status_t retCode = GLIKEY_CheckLock(base);
244 if (kStatus_GLIKEY_NotLocked != retCode)
245 {
246 return retCode;
247 }
248
249 /* Check if index is locked */
250 retCode = GLIKEY_IsIndexLocked(base, index);
251 if (kStatus_GLIKEY_NotLocked != retCode)
252 {
253 return retCode;
254 }
255
256 /* CTRL0 */
257 uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
258 /* Clear old index */
259 ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WRITE_INDEX_MASK);
260 /* Clear old CTRL0.WR_EN_0 */
261 ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WR_EN_0_MASK);
262 /* Set new index */
263 ctrl0 |= GLIKEY_CTRL_0_WRITE_INDEX(index);
264
265 /* Start the enable process by writting 0x01 to CTRL0.WR_EN_0 */
266 ctrl0 = ctrl0 | ((uint32_t)0x01u << GLIKEY_CTRL_0_WR_EN_0_SHIFT);
267
268 /* Write to CTRL0 (new index and WR_EN_0 = 0x01) */
269 ((GLIKEY_Type *)base)->CTRL_0 = ctrl0;
270
271 /* CTRL1 */
272 uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
273 /* Clear CTRL1.WR_EN_1 */
274 ctrl1 &= ~GLIKEY_CTRL_1_WR_EN_1_MASK;
275 ((GLIKEY_Type*)base)->CTRL_1 = ctrl1;
276
277 return kStatus_Success;
278 }
279
GLIKEY_ContinueEnable(GLIKEY_Type * base,uint32_t codeword)280 status_t GLIKEY_ContinueEnable(GLIKEY_Type *base, uint32_t codeword)
281 {
282 /* Check if Glikey SFR locked */
283 status_t retCode = GLIKEY_CheckLock(base);
284 if (kStatus_GLIKEY_NotLocked != retCode)
285 {
286 return retCode;
287 }
288
289 /* Set correctly we_en0 and wr_en1 according to codeword */
290 /* Select between CTRL0/CTRL1 */
291 if (WR_EN1 == (codeword >> CTRL_SEL_CODEWORD_SHIFT))
292 {
293 Glikey_Internal_Set_WR_1(base, codeword >> WR_EN1_VALUE_SHIFT);
294 }
295 else if (WR_EN0 == (codeword >> CTRL_SEL_CODEWORD_SHIFT))
296 {
297 Glikey_Internal_Set_WR_0(base, codeword >> WR_EN0_VALUE_SHIFT);
298 }
299 else
300 {
301 return kStatus_Fail;
302 }
303
304 if (0u != (GLIKEY_GetStatus(base) & GLIKEY_STATUS_ERROR_STATUS_MASK))
305 {
306 return kStatus_GLIKEY_DisabledError;
307 }
308
309 /* Validate codeword - check if XXYZ^UUVW == 0xFFFF */
310 if (0xFFFFu != (((codeword) ^ (codeword >> 16u)) & 0xFFFFu))
311 {
312 return kStatus_Fail;
313 }
314
315 return kStatus_Success;
316 }
317
GLIKEY_EndOperation(GLIKEY_Type * base)318 status_t GLIKEY_EndOperation(GLIKEY_Type *base)
319 {
320 /* Check if Glikey SFR locked */
321 status_t retCode = GLIKEY_CheckLock(base);
322 if (kStatus_GLIKEY_NotLocked != retCode)
323 {
324 return retCode;
325 }
326
327 // check state
328 uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
329
330 switch (state)
331 {
332 case GLIKEY_FSM_LOCKED:
333 {
334 /* If locked -> try to go to init with wr_en0 = WR_0_INIT (0x02); wr_en1 = WR_1_INIT (0x00) */
335 Glikey_Internal_Set_WR_0(base, WR_0_INIT);
336 Glikey_Internal_Set_WR_1(base, WR_1_INIT);
337
338 /* if still locked return locked - need to change index */
339 if (GLIKEY_FSM_LOCKED ==
340 (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT)
341 {
342 return kStatus_GLIKEY_Locked;
343 }
344
345 retCode = kStatus_Success;
346 break;
347 }
348
349 case GLIKEY_FSM_SSR_RESET:
350 case GLIKEY_FSM_WR_EN:
351 {
352 /* If FSM in RESET -> wr_en0 = WR_0_INIT; wr_en1 = WR_1_INIT */
353 /* If FSM in WR_EN -> wr_en0 = WR_0_INIT; wr_en1 = WR_1_INIT */
354 Glikey_Internal_Set_WR_0(base, WR_0_INIT);
355 Glikey_Internal_Set_WR_1(base, WR_1_INIT);
356
357 retCode = kStatus_Success;
358 break;
359 }
360
361 default:
362 /* Disabled error */
363 retCode = kStatus_GLIKEY_DisabledError;
364 break;
365 }
366
367 return retCode;
368 }
369
GLIKEY_ResetIndex(GLIKEY_Type * base,uint32_t index)370 status_t GLIKEY_ResetIndex(GLIKEY_Type *base, uint32_t index)
371 {
372 /* Check if Glikey SFR locked */
373 status_t retCode = GLIKEY_CheckLock(base);
374 if (kStatus_GLIKEY_NotLocked != retCode)
375 {
376 return retCode;
377 }
378
379 /* Check if index is locked */
380 retCode = GLIKEY_IsIndexLocked(base, index);
381 if (kStatus_GLIKEY_NotLocked != retCode)
382 {
383 return retCode;
384 }
385
386 /* Check if FSM is in INIT state */
387 uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
388 if (GLIKEY_FSM_INIT == state)
389 {
390 /* CTRL0.WRITE_INDEX = index */
391 uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
392 /* Clear index */
393 ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WRITE_INDEX_MASK);
394 /* Write new value */
395 ((GLIKEY_Type *)base)->CTRL_0 = ctrl0 | GLIKEY_CTRL_0_WRITE_INDEX(index);
396
397 return kStatus_Success;
398 }
399 else
400 {
401 return kStatus_GLIKEY_DisabledError;
402 }
403 }
404