1 /*
2  * Copyright 2017-2020, 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_SEMA4_H_
9 #define FSL_SEMA4_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup sema4
15  * @{
16  */
17 
18 /******************************************************************************
19  * Definitions
20  *****************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief SEMA4 driver version */
25 #define FSL_SEMA4_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
26 /*! @} */
27 
28 /*! @brief The number to reset all SEMA4 gates. */
29 #define SEMA4_GATE_NUM_RESET_ALL (64U)
30 
31 #if defined(SEMA4_GATE_COUNT)
32 
33 /*!
34  * @brief SEMA4 gate n register address.
35  */
36 #define SEMA4_GATEn(base, n) ((base)->GATE[(n)])
37 
38 #ifndef FSL_FEATURE_SEMA4_GATE_COUNT
39 #define FSL_FEATURE_SEMA4_GATE_COUNT SEMA4_GATE_COUNT
40 #endif
41 
42 #else
43 
44 /*!
45  * @brief SEMA4 gate n register address.
46  */
47 #define SEMA4_GATEn(base, n) (((volatile uint8_t *)(&((base)->Gate00)))[(n)])
48 
49 #endif
50 
51 /*******************************************************************************
52  * API
53  ******************************************************************************/
54 
55 #if defined(__cplusplus)
56 extern "C" {
57 #endif
58 
59 /*!
60  * @brief Initializes the SEMA4 module.
61  *
62  * This function initializes the SEMA4 module. It only enables the clock but does
63  * not reset the gates because the module might be used by other processors
64  * at the same time. To reset the gates, call either SEMA4_ResetGate or
65  * SEMA4_ResetAllGates function.
66  *
67  * @param base SEMA4 peripheral base address.
68  */
69 void SEMA4_Init(SEMA4_Type *base);
70 
71 /*!
72  * @brief De-initializes the SEMA4 module.
73  *
74  * This function de-initializes the SEMA4 module. It only disables the clock.
75  *
76  * @param base SEMA4 peripheral base address.
77  */
78 void SEMA4_Deinit(SEMA4_Type *base);
79 
80 /*!
81  * @brief Tries to lock the SEMA4 gate.
82  *
83  * This function tries to lock the specific SEMA4 gate. If the gate has been
84  * locked by another processor, this function returns an error code.
85  *
86  * @param base SEMA4 peripheral base address.
87  * @param gateNum  Gate number to lock.
88  * @param procNum  Current processor number.
89  *
90  * @retval kStatus_Success     Lock the sema4 gate successfully.
91  * @retval kStatus_Fail Sema4 gate has been locked by another processor.
92  */
93 status_t SEMA4_TryLock(SEMA4_Type *base, uint8_t gateNum, uint8_t procNum);
94 
95 /*!
96  * @brief Locks the SEMA4 gate.
97  *
98  * This function locks the specific SEMA4 gate. If the gate has been
99  * locked by other processors, this function waits until it is unlocked and then
100  * lock it.
101  *
102  * @param base SEMA4 peripheral base address.
103  * @param gateNum  Gate number to lock.
104  * @param procNum  Current processor number.
105  */
106 void SEMA4_Lock(SEMA4_Type *base, uint8_t gateNum, uint8_t procNum);
107 
108 /*!
109  * @brief Unlocks the SEMA4 gate.
110  *
111  * This function unlocks the specific SEMA4 gate. It only writes unlock value
112  * to the SEMA4 gate register. However, it does not check whether the SEMA4 gate is locked
113  * by the current processor or not. As a result, if the SEMA4 gate is not locked by the current
114  * processor, this function has no effect.
115  *
116  * @param base SEMA4 peripheral base address.
117  * @param gateNum  Gate number to unlock.
118  */
SEMA4_Unlock(SEMA4_Type * base,uint8_t gateNum)119 static inline void SEMA4_Unlock(SEMA4_Type *base, uint8_t gateNum)
120 {
121     assert(gateNum < (uint8_t)FSL_FEATURE_SEMA4_GATE_COUNT);
122 
123     SEMA4_GATEn(base, gateNum) = 0U;
124 }
125 
126 /*!
127  * @brief Gets the status of the SEMA4 gate.
128  *
129  * This function checks the lock status of a specific SEMA4 gate.
130  *
131  * @param base SEMA4 peripheral base address.
132  * @param gateNum  Gate number.
133  *
134  * @return Return -1 if the gate is unlocked, otherwise return the
135  * processor number which has locked the gate.
136  */
SEMA4_GetLockProc(SEMA4_Type * base,uint8_t gateNum)137 static inline int32_t SEMA4_GetLockProc(SEMA4_Type *base, uint8_t gateNum)
138 {
139     assert(gateNum < (uint8_t)FSL_FEATURE_SEMA4_GATE_COUNT);
140 
141     return (int32_t)(SEMA4_GATEn(base, gateNum)) - 1;
142 }
143 
144 /*!
145  * @brief Resets the SEMA4 gate to an unlocked status.
146  *
147  * This function resets a SEMA4 gate to an unlocked status.
148  *
149  * @param base SEMA4 peripheral base address.
150  * @param gateNum  Gate number.
151  *
152  * @retval kStatus_Success         SEMA4 gate is reset successfully.
153  * @retval kStatus_Fail Some other reset process is ongoing.
154  */
155 status_t SEMA4_ResetGate(SEMA4_Type *base, uint8_t gateNum);
156 
157 /*!
158  * @brief Resets all SEMA4 gates to an unlocked status.
159  *
160  * This function resets all SEMA4 gate to an unlocked status.
161  *
162  * @param base SEMA4 peripheral base address.
163  *
164  * @retval kStatus_Success         SEMA4 is reset successfully.
165  * @retval kStatus_Fail Some other reset process is ongoing.
166  */
SEMA4_ResetAllGates(SEMA4_Type * base)167 static inline status_t SEMA4_ResetAllGates(SEMA4_Type *base)
168 {
169     return SEMA4_ResetGate(base, SEMA4_GATE_NUM_RESET_ALL);
170 }
171 
172 /*!
173  * @brief Enable the gate notification interrupt.
174  *
175  * Gate notification provides such feature, when core tried to lock the gate
176  * and failed, it could get notification when the gate is idle.
177  *
178  * @param base SEMA4 peripheral base address.
179  * @param procNum  Current processor number.
180  * @param mask OR'ed value of the gate index, for example: (1<<0) | (1<<1) means
181  * gate 0 and gate 1.
182  */
SEMA4_EnableGateNotifyInterrupt(SEMA4_Type * base,uint8_t procNum,uint32_t mask)183 static inline void SEMA4_EnableGateNotifyInterrupt(SEMA4_Type *base, uint8_t procNum, uint32_t mask)
184 {
185     mask = __REV(__RBIT(mask));
186     base->CPINE[procNum].CPINE |= (uint16_t)mask;
187 }
188 
189 /*!
190  * @brief Disable the gate notification interrupt.
191  *
192  * Gate notification provides such feature, when core tried to lock the gate
193  * and failed, it could get notification when the gate is idle.
194  *
195  * @param base SEMA4 peripheral base address.
196  * @param procNum  Current processor number.
197  * @param mask OR'ed value of the gate index, for example: (1<<0) | (1<<1) means
198  * gate 0 and gate 1.
199  */
SEMA4_DisableGateNotifyInterrupt(SEMA4_Type * base,uint8_t procNum,uint32_t mask)200 static inline void SEMA4_DisableGateNotifyInterrupt(SEMA4_Type *base, uint8_t procNum, uint32_t mask)
201 {
202     mask = __REV(__RBIT(mask));
203     base->CPINE[procNum].CPINE &= (uint16_t)(~mask);
204 }
205 
206 /*!
207  * @brief Get the gate notification flags.
208  *
209  * Gate notification provides such feature, when core tried to lock the gate
210  * and failed, it could get notification when the gate is idle. The status flags
211  * are cleared automatically when the gate is locked by current core or locked
212  * again before the other core.
213  *
214  * @param base SEMA4 peripheral base address.
215  * @param procNum  Current processor number.
216  * @return OR'ed value of the gate index, for example: (1<<0) | (1<<1) means
217  * gate 0 and gate 1 flags are pending.
218  */
SEMA4_GetGateNotifyStatus(SEMA4_Type * base,uint8_t procNum)219 static inline uint32_t SEMA4_GetGateNotifyStatus(SEMA4_Type *base, uint8_t procNum)
220 {
221     return __REV(__RBIT(base->CPNTF[procNum].CPNTF));
222 }
223 
224 /*!
225  * @brief Resets the SEMA4 gate IRQ notification.
226  *
227  * This function resets a SEMA4 gate IRQ notification.
228  *
229  * @param base SEMA4 peripheral base address.
230  * @param gateNum  Gate number.
231  *
232  * @retval kStatus_Success Reset successfully.
233  * @retval kStatus_Fail    Some other reset process is ongoing.
234  */
235 status_t SEMA4_ResetGateNotify(SEMA4_Type *base, uint8_t gateNum);
236 
237 /*!
238  * @brief Resets all SEMA4 gates IRQ notification.
239  *
240  * This function resets all SEMA4 gate IRQ notifications.
241  *
242  * @param base SEMA4 peripheral base address.
243  *
244  * @retval kStatus_Success  Reset successfully.
245  * @retval kStatus_Fail     Some other reset process is ongoing.
246  */
SEMA4_ResetAllGateNotify(SEMA4_Type * base)247 static inline status_t SEMA4_ResetAllGateNotify(SEMA4_Type *base)
248 {
249     return SEMA4_ResetGateNotify(base, SEMA4_GATE_NUM_RESET_ALL);
250 }
251 
252 #if defined(__cplusplus)
253 }
254 #endif
255 
256 /*!
257  * @}
258  */
259 
260 #endif /* FSL_SEMA4_H_ */
261