1 /*
2 * Copyright 2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_itrc.h"
9
10 /*******************************************************************************
11 * Definitions
12 *******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.itrc_1"
17 #endif
18
19 #define b11 0x3UL
20 #define b10 0x2UL
21 #define b01 0x1UL
22
23 /* Value used to trigger SW Events */
24 #define SW_EVENT_VAL 0x5AA55AA5u
25
26 /*******************************************************************************
27 * Prototypes
28 ******************************************************************************/
29
30 /*******************************************************************************
31 * Code
32 ******************************************************************************/
33
34 /*!
35 * Weak implementation of ITRC IRQ, should be re-defined by user when using ITRC IRQ
36 */
ITRC_DriverIRQHandler(void)37 __WEAK void ITRC_DriverIRQHandler(void)
38 {
39 /* ITRC generates IRQ until corresponding bit in STATUS is cleared by calling
40 * ITRC_ClearStatus(ITRC,((uint32_t)kITRC_Irq)
41 */
42 }
43
44 /*!
45 * @brief Clear input ITRC status
46 *
47 * This function clears corresponding ITRC event in STATUS register.
48 *
49 * @param base ITRC peripheral base address
50 * @param word 32bit word represent corresponding event/action in STATUS register to be cleared
51 * (see ITRC_STATUS_INx)
52 * @return kStatus_Success if success, kStatus_InvalidArgument otherwise
53 */
ITRC_ClearInEventStatus(ITRC_Type * base,itrc_in_signals_t event)54 status_t ITRC_ClearInEventStatus(ITRC_Type *base, itrc_in_signals_t event)
55 {
56 /* If reserved/unused bits in STATUS register are set in 'event' parameter, return kStatus_InvalidArgument */
57 if (event < ITRC_INPUT_SIGNALS_NUM)
58 {
59 if (event < 16u)
60 {
61 const uint32_t shifted = (uint32_t)1U << event;
62 if ((shifted & ~(IN_STATUS0_EVENTS_MASK)) != 0u)
63 {
64 return kStatus_InvalidArgument;
65 }
66
67 base->STATUS0 = shifted;
68 }
69 else
70 {
71 const uint32_t shifted = (uint32_t)1U << (event - 16u);
72 if ((shifted & ~(IN_STATUS1_EVENTS_MASK)) != 0u)
73 {
74 return kStatus_InvalidArgument;
75 }
76
77 base->STATUS1 = shifted;
78 }
79 }
80 else
81 {
82 return kStatus_InvalidArgument;
83 }
84
85 return kStatus_Success;
86 }
87
88 /*!
89 * brief Clear output action ITRC status
90 *
91 * This function clears corresponding ITRC action in STATUS register.
92 *
93 * @param base ITRC peripheral base address
94 * @param word 32bit word represent corresponding event/action in STATUS register to be cleared
95 * (see OUTx_STATUS)
96 * @return kStatus_Success if success, kStatus_InvalidArgument otherwise
97 */
ITRC_ClearOutActionStatus(ITRC_Type * base,itrc_out_signals_t action)98 status_t ITRC_ClearOutActionStatus(ITRC_Type *base, itrc_out_signals_t action)
99 {
100 /* If reserved/unused bits in STATUS register are set in 'action' parameter, return kStatus_InvalidArgument */
101 const uint32_t shifted = (uint32_t)1U << action;
102 if ((shifted & ~(OUT_ACTIONS_MASK)) != 0u)
103 {
104 return kStatus_InvalidArgument;
105 }
106
107 base->STATUS0 = shifted;
108
109 return kStatus_Success;
110 }
111
112 /*!
113 * @brief Clear all ITRC status
114 *
115 * This clears all event and action status.
116 *
117 * @param base ITRC peripheral base address
118 * @return Status of the ITRC
119 */
ITRC_ClearAllStatus(ITRC_Type * base)120 status_t ITRC_ClearAllStatus(ITRC_Type *base)
121 {
122 base->STATUS0 = (IN_STATUS0_EVENTS_MASK | OUT_ACTIONS_MASK);
123 base->STATUS1 = IN_STATUS1_EVENTS_MASK;
124
125 return kStatus_Success;
126 }
127
128 /*!
129 * @brief Trigger ITRC SW Event 0
130 *
131 * This funciton set SW_EVENT0 register with value !=0 which triggers ITRC SW Event 0.
132 *
133 * @param base ITRC peripheral base address
134 */
ITRC_SetSWEvent0(ITRC_Type * base)135 void ITRC_SetSWEvent0(ITRC_Type *base)
136 {
137 base->SW_EVENT0 = SW_EVENT_VAL;
138 }
139
140 /*!
141 * @brief Trigger ITRC SW Event 1
142 *
143 * This funciton set SW_EVENT1 register with value !=0 which triggers ITRC SW Event 1.
144 *
145 * @param base ITRC peripheral base address
146 */
ITRC_SetSWEvent1(ITRC_Type * base)147 void ITRC_SetSWEvent1(ITRC_Type *base)
148 {
149 base->SW_EVENT1 = SW_EVENT_VAL;
150 }
151
152 /*!
153 * @brief Set ITRC Action to Event
154 *
155 * This function sets input Event signal to corresponding output Action response signal.
156 *
157 * @param base ITRC peripheral base address
158 * @param out ITRC OUT signal action
159 * @param in ITRC IN signal event
160 * @param lock if set locks INx_SEL configuration. This can be cleared only by PMC Core reset.
161 * @param enable if set input Event will be selected for output Action, otherwise disable (if not already locked).
162 * @return kStatus_Success if success, kStatus_InvalidArgument otherwise
163 */
ITRC_SetActionToEvent(ITRC_Type * base,itrc_out_signals_t out,itrc_in_signals_t in,itrc_lock_t lock,itrc_enable_t enable)164 status_t ITRC_SetActionToEvent(
165 ITRC_Type *base, itrc_out_signals_t out, itrc_in_signals_t in, itrc_lock_t lock, itrc_enable_t enable)
166 {
167 uint32_t sel0, sel1, index, select_AND_mask;
168
169 /* prepare values for INx_SEL0/1 bit-field according to secure techniques and register behavior
170 * +------------+------------+------------------+---------------------------+
171 * | INx_SEL0 | INx_SEL1 | Signal selected? | Writable field? |
172 * +------------+------------+------------------+---------------------------+
173 * | 10 | 10 | No | Yes (default after reset) |
174 * | 01 | 10 | Yes | Yes |
175 * | don't care | !="10" | Yes | No |
176 * | 00 or 11 | don't care | Yes | No |
177 * +------------+------------+------------------+---------------------------+
178 */
179 if ((lock == kITRC_Unlock) && (enable == kITRC_Disable))
180 {
181 sel0 = b10;
182 sel1 = b10;
183 }
184 else if ((lock == kITRC_Unlock) && (enable == kITRC_Enable))
185 {
186 sel0 = b01;
187 sel1 = b10;
188 }
189 else
190 {
191 sel0 = b11;
192 sel1 = b11;
193 }
194
195 /* Compute index for INx_SEL0/1 bit-field within OUTy_SEL0/1 registers */
196 index = 2UL * (uint32_t)in;
197
198 /* Eeach signal is encoded by two bits */
199 if (index > 2UL * ITRC_INPUT_SIGNALS_NUM)
200 {
201 return kStatus_InvalidArgument;
202 }
203
204 if (index < 32UL)
205 {
206 /* Prepare AND mask to set INx_SEL0 accordingly */
207 select_AND_mask = ~(b11 << index);
208
209 switch (out)
210 {
211 case kITRC_Irq:
212 base->OUT0_SEL0 = (base->OUT0_SEL0 & select_AND_mask) | (sel0 << index);
213 base->OUT0_SEL1 |= sel1 << index;
214 break;
215
216 case kITRC_ChipReset:
217 base->OUT1_SEL0 = (base->OUT1_SEL0 & select_AND_mask) | (sel0 << index);
218 base->OUT1_SEL1 |= sel1 << index;
219 break;
220
221 default:
222 /* This case shouldn't be reached. */
223 return kStatus_InvalidArgument;
224 }
225 }
226 else
227 {
228 index -= 32UL;
229 /* Prepare AND mask to set INx_SEL0 accordingly */
230 select_AND_mask = ~(b11 << index);
231
232 switch (out)
233 {
234 case kITRC_Irq:
235 base->OUT0_SEL0_EVENT16_31 = (base->OUT0_SEL0_EVENT16_31 & select_AND_mask) | (sel0 << index);
236 base->OUT0_SEL1_EVENT16_31 |= sel1 << index;
237 break;
238
239 case kITRC_ChipReset:
240 base->OUT1_SEL0_EVENT16_31 = (base->OUT1_SEL0_EVENT16_31 & select_AND_mask) | (sel0 << index);
241 base->OUT1_SEL1_EVENT16_31 |= sel1 << index;
242 break;
243
244 default:
245 /* This case shouldn't be reached. */
246 return kStatus_InvalidArgument;
247 }
248 }
249
250 return kStatus_Success;
251 }
252
253 /*!
254 * @brief Get ITRC input event status
255 *
256 * This function returns ITRC status corresponding to provided input event.
257 *
258 * @param base ITRC peripheral base address
259 * @param event represents input event in STATUS register to get
260 * (see ITRC_STATUS_INx)
261 * @return boolean TRUE if corresponding event occured
262 * FALSE otherwise
263 */
ITRC_GetInEventStatus(ITRC_Type * base,itrc_in_signals_t event)264 bool ITRC_GetInEventStatus(ITRC_Type *base, itrc_in_signals_t event)
265 {
266 if (event < 16UL)
267 {
268 return (base->STATUS0 & (1UL << event)) != 0UL;
269 }
270 else
271 {
272 return (base->STATUS1 & (1UL << (event - 16UL))) != 0UL;
273 }
274 }
275
276 /*!
277 * @brief Get ITRC output action status
278 *
279 * This function returns ITRC register output status.
280 *
281 * @param base ITRC peripheral base address
282 * @param action represents output action in STATUS register to get
283 * (see ITRC_STATUS_OUTx)
284 * @return boolean TRUE if corresponding action occured
285 * FALSE otherwise
286 */
ITRC_GetOutActionStatus(ITRC_Type * base,itrc_out_signals_t action)287 bool ITRC_GetOutActionStatus(ITRC_Type *base, itrc_out_signals_t action)
288 {
289 return ((base->STATUS0 & (1UL << action)) != 0UL);
290 }
291
292 /*!
293 * @brief Initialize ITRC
294 *
295 * This function initializes ITRC by enabling IRQ.
296 *
297 * @param base ITRC peripheral base address
298 * @return Status of the init operation
299 */
ITRC_Init(ITRC_Type * base)300 status_t ITRC_Init(ITRC_Type *base)
301 {
302 status_t status = IRQ_ClearPendingIRQ(ITRC_IRQn);
303
304 if ( status != kStatus_Success)
305 {
306 return status;
307 }
308 return EnableIRQ(ITRC_IRQn);
309 }
310
311 /*!
312 * @brief Deinitialize ITRC
313 *
314 * This function just disable ITRC IRQ.
315 *
316 * @param base ITRC peripheral base address
317 */
ITRC_Deinit(ITRC_Type * base)318 void ITRC_Deinit(ITRC_Type *base)
319 {
320 (void)DisableIRQ(ITRC_IRQn);
321 }
322