1 /*
2  * Copyright 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_INTM_H_
9 #define FSL_INTM_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup intm
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief INTM driver version. */
25 #define FSL_INTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
26 /*! @} */
27 
28 /*! @brief Interrupt monitors. */
29 typedef enum _intm_monitor
30 {
31     kINTM_Monitor1 = 0U,
32     kINTM_Monitor2,
33     kINTM_Monitor3,
34     kINTM_Monitor4
35 } intm_monitor_t;
36 
37 /*! @brief INTM  interrupt source configuration structure. */
38 typedef struct _intm_monitor_config
39 {
40     uint32_t maxtimer;   /*!< Set the maximum timer */
41     IRQn_Type irqnumber; /*!< Select the interrupt request number to monitor. */
42 } intm_monitor_config_t;
43 
44 /*! @brief INTM configuration structure. */
45 typedef struct _intm_config
46 {
47     intm_monitor_config_t intm[FSL_FEATURE_INTM_MONITOR_COUNT]; /*! Interrupt source monitor config.*/
48     bool enable; /*!< enables the cycle count timer on a monitored interrupt request for comparison to the latency
49                     register. */
50 } intm_config_t;
51 
52 /*******************************************************************************
53  * API
54  ******************************************************************************/
55 /*!
56  * @brief  Fill in the INTM config struct with the default settings
57  *
58  * The default values are:
59  * @code
60  *     config[0].irqnumber = NotAvail_IRQn;
61  *     config[0].maxtimer = 1000U;
62  *     config[1].irqnumber = NotAvail_IRQn;
63  *     config[1].maxtimer = 1000U;
64  *     config[2].irqnumber = NotAvail_IRQn;
65  *     config[2].maxtimer = 1000U;
66  *     config[3].irqnumber = NotAvail_IRQn;
67  *     config[3].maxtimer = 1000U;
68  *     config->enable = false;
69  * @endcode
70  * @param config Pointer to user's INTM config structure.
71  */
72 void INTM_GetDefaultConfig(intm_config_t *config);
73 
74 /*!
75  * @brief Ungates the INTM clock and configures the peripheral for basic operation.
76  *
77  * @note This API should be called at the beginning of the application using the INTM driver.
78  *
79  * @param base      INTM peripheral base address
80  * @param config    Pointer to user's INTM config structure.
81  */
82 void INTM_Init(INTM_Type *base, const intm_config_t *config);
83 
84 /*!
85  * @brief Disables the INTM module.
86  *
87  * @param base INTM peripheral base address
88  */
89 void INTM_Deinit(INTM_Type *base);
90 
91 /*!
92  * @brief Enable the cycle count timer mode.
93  *
94  * Monitor mode enables the cycle count timer on a monitored interrupt request for comparison to the latency register.
95  *
96  * @param base INTM peripheral base address.
97  * @param enable Enable the cycle count or not.
98  */
INTM_EnableCycleCount(INTM_Type * base,bool enable)99 static inline void INTM_EnableCycleCount(INTM_Type *base, bool enable)
100 {
101     if (enable)
102     {
103         base->INTM_MM |= INTM_INTM_MM_MM_MASK;
104     }
105     else
106     {
107         base->INTM_MM &= ~INTM_INTM_MM_MM_MASK;
108     }
109 }
110 
111 /*!
112  * @brief Interrupt Acknowledge.
113  *
114  * Call this function in ISR to acknowledge interrupt.
115  *
116  * @param base INTM peripheral base address.
117  * @param irq Handle interrupt number.
118  */
INTM_AckIrq(INTM_Type * base,IRQn_Type irq)119 static inline void INTM_AckIrq(INTM_Type *base, IRQn_Type irq)
120 {
121     assert(((uint32_t)irq) < (uint32_t)NUMBER_OF_INT_VECTORS);
122 
123     base->INTM_IACK = (uint32_t)irq;
124 }
125 
126 /*!
127  * @brief Interrupt Request Select.
128  *
129  * This function is used to set the interrupt request number to monitor or check.
130  *
131  * @param base INTM peripheral base address.
132  * @param intms Programmable interrupt monitors.
133  * @param irq  Interrupt request number to monitor.
134  *
135  * @return Select the interrupt request number to monitor.
136  */
INTM_SetInterruptRequestNumber(INTM_Type * base,intm_monitor_t intms,IRQn_Type irq)137 static inline void INTM_SetInterruptRequestNumber(INTM_Type *base, intm_monitor_t intms, IRQn_Type irq)
138 {
139     assert(((uint32_t)irq) < (uint32_t)NUMBER_OF_INT_VECTORS);
140 
141     base->MON[intms].INTM_IRQSEL = INTM_MON_INTM_IRQSEL_IRQ(irq);
142 }
143 
144 /*!
145  * @brief Set the maximum count time.
146  *
147  * This function is to set the maximum time from interrupt generation to confirmation.
148  *
149  * @param base INTM peripheral base address.
150  * @param intms Programmable interrupt monitors.
151  * @param count Timer maximum count.
152  */
INTM_SetMaxTime(INTM_Type * base,intm_monitor_t intms,uint32_t count)153 static inline void INTM_SetMaxTime(INTM_Type *base, intm_monitor_t intms, uint32_t count)
154 {
155     assert((count < 0xFFFFFDU) && (count > 0U));
156 
157     base->MON[intms].INTM_LATENCY = INTM_MON_INTM_LATENCY_LAT(count);
158 }
159 
160 /*!
161  * @brief Clear the timer period in units of count.
162  *
163  * This function is used to clear the INTM_TIMERa register.
164  *
165  * @param base INTM peripheral base address.
166  * @param intms Programmable interrupt monitors.
167  */
INTM_ClearTimeCount(INTM_Type * base,intm_monitor_t intms)168 static inline void INTM_ClearTimeCount(INTM_Type *base, intm_monitor_t intms)
169 {
170     base->MON[intms].INTM_TIMER &= ~INTM_MON_INTM_TIMER_TIMER_MASK;
171 }
172 
173 /*!
174  * @brief Gets the timer period in units of count.
175  *
176  * This function is used to get the number of INTM clock cycles from interrupt request to confirmation interrupt
177  * processing. If this number exceeds the set maximum time, will be an error signal.
178  *
179  * @param base INTM peripheral base address.
180  * @param intms Programmable interrupt monitors.
181  */
INTM_GetTimeCount(INTM_Type * base,intm_monitor_t intms)182 static inline uint32_t INTM_GetTimeCount(INTM_Type *base, intm_monitor_t intms)
183 {
184     return base->MON[intms].INTM_TIMER;
185 }
186 
187 /*!
188  * @brief Interrupt monitor status.
189  *
190  * This function indicates whether the INTM_TIMERa value has exceeded the INTM_LATENCYa value.
191  * If any interrupt source in INTM_TIMERa exceeds the programmed delay value, the monitor state
192  * can be cleared by calling the INTM_ClearTimeCount() API to clear the corresponding INTM_TIMERa register.
193  *
194  * @param base INTM peripheral base address.
195  * @param intms Programmable interrupt monitors.
196  *
197  * @return Whether INTM_TIMER value has exceeded INTM_LATENCY value.
198  *         false:INTM_TIMER value has not exceeded the INTM_LATENCY value;
199  *         true:INTM_TIMER value has exceeded the INTM_LATENCY value.
200  */
INTM_GetStatusFlags(INTM_Type * base,intm_monitor_t intms)201 static inline bool INTM_GetStatusFlags(INTM_Type *base, intm_monitor_t intms)
202 {
203     return ((base->MON[intms].INTM_STATUS & INTM_MON_INTM_STATUS_STATUS_MASK) != 0U);
204 }
205 
206 /*! @} */
207 #endif /* FSL_INTM_H_*/
208