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