1 /*
2  * Copyright (c) 2015-2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       HwiP.h
34  *
35  *  @brief      Hardware Interrupt module for the RTOS Porting Interface
36  *
37  *  The ::HwiP_disable/::HwiP_restore APIs can be called recursively. The order
38  *  of the HwiP_restore calls, must be in reversed order. For example:
39  *  @code
40  *  uintptr_t key1, key2;
41  *  key1 = HwiP_disable();
42  *  key2 = HwiP_disable();
43  *  HwiP_restore(key2);
44  *  HwiP_restore(key1);
45  *  @endcode
46  *
47  *  ============================================================================
48  */
49 
50 #ifndef ti_dpl_HwiP__include
51 #define ti_dpl_HwiP__include
52 
53 #include <stdint.h>
54 #include <stdbool.h>
55 #include <stddef.h>
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60 
61 /*!
62  *  @brief    Number of bytes greater than or equal to the size of any RTOS
63  *            HwiP object.
64  *
65  *  nortos:   12
66  *  SysBIOS:  28
67  */
68 #define HwiP_STRUCT_SIZE   (28)
69 
70 /*!
71  *  @brief    HwiP structure.
72  *
73  *  Opaque structure that should be large enough to hold any of the RTOS
74  *  specific HwiP objects.
75  */
76 typedef union HwiP_Struct {
77     uint32_t dummy;  /*!< Align object */
78     char     data[HwiP_STRUCT_SIZE];
79 } HwiP_Struct;
80 
81 /*!
82  *  @brief    Opaque client reference to an instance of a HwiP
83  *
84  *  A HwiP_Handle returned from the ::HwiP_create represents that instance.
85  */
86 typedef  void *HwiP_Handle;
87 
88 /*!
89  *  @brief    Status codes for HwiP APIs
90  */
91 typedef enum {
92     HwiP_OK = 0,
93     HwiP_FAILURE = -1
94 } HwiP_Status;
95 
96 /*!
97  *  @brief  Prototype for the entry function for a hardware interrupt
98  */
99 typedef void (*HwiP_Fxn)(uintptr_t arg);
100 
101 /*!
102  *  @brief    Basic HwiP Parameters
103  *
104  *  Structure that contains the parameters passed into ::HwiP_create
105  *  when creating a HwiP instance. The ::HwiP_Params_init function should
106  *  be used to initialize the fields to default values before the application sets
107  *  the fields manually. The HwiP default parameters are noted in
108  *  HwiP_Params_init.
109  *
110  *  Parameter enableInt specifies if the interrupt should be enabled
111  *  upon creation of the HwiP object.  The default is true.
112  */
113 typedef struct {
114     uintptr_t  arg;       /*!< Argument passed into the Hwi function. */
115     uint32_t   priority;  /*!< Device specific priority. */
116     bool       enableInt; /*!< Enable interrupt on creation. */
117 } HwiP_Params;
118 
119 /*!
120  *  @brief    Interrupt number posted by SwiP
121  *
122  *  The SwiP module needs its scheduler to run at key points in SwiP
123  *  processing.  This is accomplished via an interrupt that is configured
124  *  at the lowest possible interrupt priority level and is plugged with
125  *  the SwiP scheduler.  This interrupt must be the *only* interrupt at
126  *  that lowest priority.  SwiP will post this interrupt whenever its
127  *  scheduler needs to run.
128  *
129  *  The default value for your device should suffice, but if a different
130  *  interrupt is needed to be used for SwiP scheduling then HwiP_swiPIntNum
131  *  can be assigned with this interrupt (early on, before HwiPs are created
132  *  and before any SwiP gets posted).
133  */
134 extern int HwiP_swiPIntNum;
135 
136 /*!
137  *  @brief  Function to construct a hardware interrupt object.
138  *
139  *  @param  hwiP   Pointer to HwiP_Struct object.
140  *  @param  interruptNum Interrupt Vector Id
141  *  @param  hwiFxn entry function of the hardware interrupt
142  *
143  *  @param  params    Pointer to the instance configuration parameters. NULL
144  *                    denotes to use the default parameters. The HwiP default
145  *                    parameters are noted in ::HwiP_Params_init.
146  *
147  *  @return A HwiP_Handle on success or a NULL on an error
148  */
149 extern HwiP_Handle HwiP_construct(HwiP_Struct *hwiP, int interruptNum,
150                                   HwiP_Fxn hwiFxn, HwiP_Params *params);
151 
152 /*!
153  *  @brief  Function to destruct a hardware interrupt object
154  *
155  *  @param  hwiP  Pointer to a HwiP_Struct object that was passed to
156  *                HwiP_construct().
157  *
158  *  @return
159  */
160 extern void HwiP_destruct(HwiP_Struct *hwiP);
161 
162 /*!
163  *  @brief  Function to clear a single interrupt
164  *
165  *  @param  interruptNum interrupt number to clear
166  */
167 extern void HwiP_clearInterrupt(int interruptNum);
168 
169 /*!
170  *  @brief  Function to create an interrupt on CortexM devices
171  *
172  *  @param  interruptNum Interrupt Vector Id
173  *
174  *  @param  hwiFxn entry function of the hardware interrupt
175  *
176  *  @param  params    Pointer to the instance configuration parameters. NULL
177  *                    denotes to use the default parameters. The HwiP default
178  *                    parameters are noted in ::HwiP_Params_init.
179  *
180  *  @return A HwiP_Handle on success or a NULL on an error
181  */
182 extern HwiP_Handle HwiP_create(int interruptNum, HwiP_Fxn hwiFxn,
183                                HwiP_Params *params);
184 
185 /*!
186  *  @brief  Function to delete an interrupt on CortexM devices
187  *
188  *  @param  handle returned from the HwiP_create call
189  *
190  *  @return
191  */
192 extern void HwiP_delete(HwiP_Handle handle);
193 
194 /*!
195  *  @brief  Function to disable interrupts to enter a critical region
196  *
197  *  This function can be called multiple times, but must unwound in the reverse
198  *  order. For example
199  *  @code
200  *  uintptr_t key1, key2;
201  *  key1 = HwiP_disable();
202  *  key2 = HwiP_disable();
203  *  HwiP_restore(key2);
204  *  HwiP_restore(key1);
205  *  @endcode
206  *
207  *  @return A key that must be passed to HwiP_restore to re-enable interrupts.
208  */
209 extern uintptr_t HwiP_disable(void);
210 
211 /*!
212  *  @brief  Function to enable interrupts
213  */
214 extern void HwiP_enable(void);
215 
216 /*!
217  *  @brief  Function to disable a single interrupt
218  *
219  *  @param  interruptNum interrupt number to disable
220  */
221 extern void HwiP_disableInterrupt(int interruptNum);
222 
223 /*!
224  *  @brief  Function to enable a single interrupt
225  *
226  *  @param  interruptNum interrupt number to enable
227  */
228 extern void HwiP_enableInterrupt(int interruptNum);
229 
230 /*!
231  *  @brief  Function  to return a status based on whether it is in an interrupt
232  *      context.
233  *
234  *  @return A status: indicating whether the function was called in an
235  *      ISR (true) or at thread level (false).
236  */
237 extern bool HwiP_inISR(void);
238 
239 /*!
240  *  @brief  Initialize params structure to default values.
241  *
242  *  The default parameters are:
243  *   - arg: 0
244  *   - priority: ~0
245  *   - enableInt: true
246  *
247  *  @param params  Pointer to the instance configuration parameters.
248  */
249 extern void HwiP_Params_init(HwiP_Params *params);
250 
251 /*!
252  *  @brief  Function to plug an interrupt vector
253  *
254  *  @param  interruptNum ID of interrupt to plug
255  *  @param  fxn ISR that services plugged interrupt
256  */
257 extern void HwiP_plug(int interruptNum, void *fxn);
258 
259 /*!
260  *  @brief  Function to generate an interrupt
261  *
262  *  @param  interruptNum ID of interrupt to generate
263  */
264 extern void HwiP_post(int interruptNum);
265 
266 /*!
267  *  @brief  Function to restore interrupts to exit a critical region
268  *
269  *  @param  key return from HwiP_disable
270  */
271 extern void HwiP_restore(uintptr_t key);
272 
273 /*!
274  *  @brief  Function to overwrite HwiP function and arg
275  *
276  *  @param  hwiP handle returned from the HwiP_create or construct call
277  *  @param  fxn  pointer to ISR function
278  *  @param  arg  argument to ISR function
279  */
280 extern void HwiP_setFunc(HwiP_Handle hwiP, HwiP_Fxn fxn, uintptr_t arg);
281 
282 /*!
283  *  @brief  Function to set the priority of a hardware interrupt
284  *
285  *  @param  interruptNum id of the interrupt to change
286  *  @param  priority new priority
287  */
288 extern void HwiP_setPriority(int interruptNum, uint32_t priority);
289 
290 #ifdef __cplusplus
291 }
292 #endif
293 
294 #endif /* ti_dpl_HwiP__include */
295