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"
17 #endif
18
19 #define b11 0x3UL
20 #define b10 0x2u
21 #define b01 0x1u
22
23 #define OUT_SEL_0_COUNT (16u)
24 #define OUT_SEL_1_COUNT (32u)
25 #define OUT_SEL_2_COUNT (48u)
26
27 /* Value used to trigger SW Events */
28 #define SW_EVENT_VAL 0x5AA55AA5u
29
30 /*******************************************************************************
31 * Prototypes
32 ******************************************************************************/
33
34 /*******************************************************************************
35 * Code
36 ******************************************************************************/
37
38 /*!
39 * Weak implementation of ITRC IRQ, should be re-defined by user when using ITRC IRQ
40 */
ITRC0_DriverIRQHandler(void)41 __WEAK void ITRC0_DriverIRQHandler(void)
42 {
43 /* ITRC generates IRQ until corresponding bit in STATUS is cleared by calling
44 * ITRC_ClearStatus(ITRC,((uint32_t)kITRC_Irq)
45 */
46 }
47
48 /*!
49 * brief Clear ITRC status
50 *
51 * This function clears corresponding ITRC event or action in STATUS register.
52 *
53 * param base ITRC peripheral base address
54 * param word 32bit word represent corresponding event/action in STATUS register to be cleared (see
55 * ITRC_STATUS_INx/OUTx_STATUS)
56 * return kStatus_Success if success, kStatus_InvalidArgument otherwise
57 */
ITRC_ClearStatus(ITRC_Type * base,uint32_t word)58 status_t ITRC_ClearStatus(ITRC_Type *base, uint32_t word)
59 {
60 /* If reserved/unused bits in STATUS register are set in 'word' parameter, return kStatus_InvalidArgument */
61 if ((word & ~(IN_0_15_EVENTS_MASK | OUT_ACTIONS_MASK)) != 0u)
62 {
63 return kStatus_InvalidArgument;
64 }
65
66 base->STATUS |= word;
67
68 return kStatus_Success;
69 }
70
71 /*!
72 * brief Get ITRC Status
73 *
74 * This function returns ITRC STATUS1 register value.
75 *
76 * param base ITRC peripheral base address
77 * return Value of ITRC STATUS register
78 */
ITRC_GetStatus(ITRC_Type * base)79 uint32_t ITRC_GetStatus(ITRC_Type *base)
80 {
81 return base->STATUS;
82 }
83
84 #if defined(ITRC_STATUS1_IN16_STATUS_MASK)
85 /*!
86 * brief Clear ITRC status 1
87 *
88 * This function clears corresponding ITRC event or action in STATUS1 register.
89 *
90 * param base ITRC peripheral base address
91 * param word 32bit word represent corresponding event/action in STATUS1 register to be cleared (see
92 * ITRC_STATUS_INx/OUTx_STATUS)
93 * return kStatus_Success if success, kStatus_InvalidArgument otherwise
94 */
ITRC_ClearStatus1(ITRC_Type * base,uint32_t word)95 status_t ITRC_ClearStatus1(ITRC_Type *base, uint32_t word)
96 {
97 /* If reserved/unused bits in STATUS register are set in 'word' parameter, return kStatus_InvalidArgument */
98 if ((word & ~(IN_16_47_EVENTS_MASK)) != 0u)
99 {
100 return kStatus_InvalidArgument;
101 }
102
103 base->STATUS1 |= word;
104
105 return kStatus_Success;
106 }
107
108 /*!
109 * brief Get ITRC Status 1
110 *
111 * This function returns ITRC STATUS1 register value.
112 *
113 * param base ITRC peripheral base address
114 * return Value of ITRC STATUS1 register
115 */
ITRC_GetStatus1(ITRC_Type * base)116 uint32_t ITRC_GetStatus1(ITRC_Type *base)
117 {
118 return base->STATUS1;
119 }
120
121 #endif /* defined(ITRC_STATUS1_IN16_STATUS_MASK) */
122
123 /*!
124 * brief Clear all ITRC status
125 *
126 * This clears all event and action in STATUS and STATUS1 registers.
127 *
128 * param base ITRC peripheral base address
129 * return kStatus_Success
130 */
ITRC_ClearAllStatus(ITRC_Type * base)131 status_t ITRC_ClearAllStatus(ITRC_Type *base)
132 {
133 base->STATUS |= (IN_0_15_EVENTS_MASK | OUT_ACTIONS_MASK);
134 #if defined(ITRC_STATUS1_IN16_STATUS_MASK)
135 base->STATUS1 |= (IN_16_47_EVENTS_MASK);
136 #endif /* defined(ITRC_STATUS1_IN16_STATUS_MASK) */
137
138 return kStatus_Success;
139 }
140
141 /*!
142 * brief Trigger ITRC SW Event 0
143 *
144 * This funciton set SW_EVENT0 register with value !=0 which triggers ITRC SW Event 0.
145 *
146 * param base ITRC peripheral base address
147 */
ITRC_SetSWEvent0(ITRC_Type * base)148 void ITRC_SetSWEvent0(ITRC_Type *base)
149 {
150 base->SW_EVENT0 = SW_EVENT_VAL;
151 }
152
153 /*!
154 * brief Trigger ITRC SW Event 1
155 *
156 * This funciton set SW_EVENT1 register with value !=0 which triggers ITRC SW Event 1.
157 *
158 * param base ITRC peripheral base address
159 */
ITRC_SetSWEvent1(ITRC_Type * base)160 void ITRC_SetSWEvent1(ITRC_Type *base)
161 {
162 base->SW_EVENT1 = SW_EVENT_VAL;
163 }
164
165 /*!
166 * brief Set ITRC Action to Event
167 *
168 * This function sets input Event signal to corresponding output Action response signal.
169 *
170 * param base ITRC peripheral base address
171 * param out ITRC OUT signal action
172 * param in ITRC IN signal event
173 * param lock if set locks INx_SEL configuration. This can be cleared only by PMC Core reset.
174 * param enable if set input Event will be selected for output Action, otherwise disable (if not already locked).
175 * return kStatus_Success if success, kStatus_InvalidArgument otherwise
176 */
ITRC_SetActionToEvent(ITRC_Type * base,itrc_out_signals_t out,itrc_input_signals_t in,itrc_lock_t lock,itrc_enable_t enable)177 status_t ITRC_SetActionToEvent(
178 ITRC_Type *base, itrc_out_signals_t out, itrc_input_signals_t in, itrc_lock_t lock, itrc_enable_t enable)
179 {
180 uint32_t sel0, sel1, index, select_AND_mask;
181
182 /* prepare values for INx_SEL0/1 bit-field according to secure techniques and register behavior
183 * +------------+------------+------------------+---------------------------+
184 * | INx_SEL0 | INx_SEL1 | Signal selected? | Writable field? |
185 * +------------+------------+------------------+---------------------------+
186 * | 10 | 10 | No | Yes (default after reset) |
187 * | 01 | 10 | Yes | Yes |
188 * | don't care | !="10" | Yes | No |
189 * | 00 or 11 | don't care | Yes | No |
190 * +------------+------------+------------------+---------------------------+
191 */
192 if ((lock == kITRC_Unlock) && (enable == kITRC_Disable))
193 {
194 sel0 = b10;
195 sel1 = b10;
196 }
197 else if ((lock == kITRC_Unlock) && (enable == kITRC_Enable))
198 {
199 sel0 = b01;
200 sel1 = b10;
201 }
202 else
203 {
204 sel0 = b11;
205 sel1 = b11;
206 }
207
208 /* Compute index for INx_SEL0/1 bit-field within OUTy_SEL0/1 registers */
209 if ((uint32_t)in < OUT_SEL_0_COUNT)
210 {
211 index = 2u * (uint32_t)in;
212 }
213 else if (OUT_SEL_0_COUNT <= (uint32_t)in && (uint32_t)in < OUT_SEL_1_COUNT)
214 {
215 index = 2u * ((uint32_t)in - OUT_SEL_0_COUNT);
216 }
217 else if (OUT_SEL_1_COUNT <= (uint32_t)in && (uint32_t)in < OUT_SEL_2_COUNT)
218 {
219 index = 2u * ((uint32_t)in - OUT_SEL_1_COUNT);
220 }
221 else
222 {
223 return kStatus_InvalidArgument;
224 }
225
226 /* Prepare AND mask to set INx_SEL0 accordingly */
227 select_AND_mask = ~(uint32_t)(b11 << index);
228
229 /* Configure OUT action for IN event */
230 for (uint8_t i = (uint8_t)kITRC_Irq; i < ITRC_OUT_COUNT; i++)
231 {
232 /* Loop over all OUT actions, set only requested one */
233 if (i == (uint8_t)out)
234 {
235 if ((uint32_t)in < OUT_SEL_0_COUNT)
236 {
237 base->OUT_SEL[i][0] = (base->OUT_SEL[i][0] & select_AND_mask) | (sel0 << index);
238 base->OUT_SEL[i][1] |= sel1 << index;
239 break;
240 }
241 #if defined(ITRC_OUTX_SEL_1_OUTX_SELY_OUT_SEL_1_COUNT)
242 else if (OUT_SEL_0_COUNT <= (uint32_t)in && (uint32_t)in < OUT_SEL_1_COUNT)
243 {
244 base->OUT_SEL_1[i][0] = (base->OUT_SEL[i][0] & select_AND_mask) | (sel0 << index);
245 base->OUT_SEL_1[i][1] |= sel1 << index;
246 break;
247 }
248 #endif /* defined(OUT_SEL_1) */
249 #if defined(ITRC_OUTX_SEL_2_OUTX_SELY_OUT_SEL_2_COUNT)
250 else if (OUT_SEL_1_COUNT <= (uint32_t)in && (uint32_t)in < OUT_SEL_2_COUNT)
251 {
252 base->OUT_SEL_2[i][0] = (base->OUT_SEL[i][0] & select_AND_mask) | (sel0 << index);
253 base->OUT_SEL_2[i][1] |= sel1 << index;
254 break;
255 }
256 else
257 {
258 /* All the cases have been listed above, this branch should not be reached. */
259 return kStatus_InvalidArgument;
260 }
261 #endif /* defined(OUT_SEL_2) */
262 }
263 }
264
265 return kStatus_Success;
266 }
267
268 /*!
269 * brief Initialize ITRC
270 *
271 * This function initializes ITRC by enabling IRQ.
272 *
273 * param base ITRC peripheral base address
274 * return Status of the init operation
275 */
ITRC_Init(ITRC_Type * base)276 status_t ITRC_Init(ITRC_Type *base)
277 {
278 NVIC_EnableIRQ(ITRC0_IRQn);
279
280 return kStatus_Success;
281 }
282
283 /*!
284 * brief Deinitialize ITRC
285 *
286 * This function just disable ITRC IRQ.
287 *
288 * param base ITRC peripheral base address
289 */
ITRC_Deinit(ITRC_Type * base)290 void ITRC_Deinit(ITRC_Type *base)
291 {
292 NVIC_DisableIRQ(ITRC0_IRQn);
293 }
294