1 /*
2  * Copyright (c) 2017-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       SwiP.h
34  *
35  *  @brief      Software Interrupt module for the RTOS Porting Interface
36  *
37  *  ============================================================================
38  */
39 
40 #ifndef ti_dpl_SwiP__include
41 #define ti_dpl_SwiP__include
42 
43 #include <stdint.h>
44 #include <stdbool.h>
45 #include <stddef.h>
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 /*!
52  *  @brief    Number of bytes greater than or equal to the size of any RTOS
53  *            SwiP object.
54  *
55  *  nortos:   40
56  *  SysBIOS:  52
57  */
58 #define SwiP_STRUCT_SIZE   (52)
59 
60 /*!
61  *  @brief    SemaphoreP structure.
62  *
63  *  Opaque structure that should be large enough to hold any of the
64  *  RTOS specific SwiP objects.
65  */
66 typedef union SwiP_Struct {
67     uint32_t dummy;  /*!< Align object */
68     char     data[SwiP_STRUCT_SIZE];
69 } SwiP_Struct;
70 
71 /*!
72  *  @brief    Opaque client reference to an instance of a SwiP
73  *
74  *  A SwiP_Handle returned from the ::SwiP_create represents that instance.
75  */
76 typedef  void *SwiP_Handle;
77 
78 /*!
79  *  @brief    Status codes for SwiP APIs
80  *  TODO: See if we need more error codes.
81  */
82 typedef enum {
83     SwiP_OK = 0,
84     SwiP_FAILURE = -1
85 } SwiP_Status;
86 
87 /*!
88  *  @brief  Prototype for the entry function for a hardware interrupt
89  */
90 typedef void (*SwiP_Fxn)(uintptr_t arg0, uintptr_t arg1);
91 
92 /*!
93  *  @brief    Basic SwiP Parameters
94  *
95  *  Structure that contains the parameters passed into ::SwiP_create
96  *  and ::SwiP_construct when creating or constructing a SwiP instance.
97  *  The ::SwiP_Params_init function should be used to initialize the
98  *  fields to default values before the application sets the fields
99  *  manually. The SwiP default parameters are noted in ::SwiP_Params_init.
100  *
101  *  Each SwiP object has a "trigger" used either to determine whether to
102  *  post the SwiP or as a value that can be evaluated within the SwiP's
103  *  function.
104  *
105  *  The SwiP_andn and SwiP_dec functions post the SwiP
106  *  if the trigger value transitions to 0. The SwiP_or and
107  *  SwiP_inc functions also modify the trigger value. SwiP_or
108  *  sets bits, and SwiP_andn clears bits.
109  */
110 typedef struct {
111     uintptr_t  arg0;      /*!< Argument passed into the SwiP function. */
112     uintptr_t  arg1;      /*!< Argument passed into the SwiP function. */
113     uint32_t   priority;  /*!< priority, 0 is min, 1, 2, ..., ~0 for max */
114     uint32_t   trigger;   /*!< Initial SwiP trigger value. */
115 } SwiP_Params;
116 
117 /*!
118  *  @brief  Function to construct a software interrupt object.
119  *
120  *  @param  swiP   Pointer to SwiP_Struct object.
121  *  @param  swiFxn entry function of the software interrupt
122  *
123  *  @param  params    Pointer to the instance configuration parameters. NULL
124  *                    denotes to use the default parameters. The SwiP default
125  *                    parameters are noted in ::SwiP_Params_init.
126  *
127  *  @return A SwiP_Handle on success or a NULL on an error
128  */
129 extern SwiP_Handle SwiP_construct(SwiP_Struct *swiP, SwiP_Fxn swiFxn,
130                                SwiP_Params *params);
131 
132 /*!
133  *  @brief  Function to destruct a software interrupt object
134  *
135  *  @param  swiP  Pointer to a SwiP_Struct object that was passed to
136  *                SwiP_construct().
137  *
138  *  @return
139  */
140 extern void SwiP_destruct(SwiP_Struct *swiP);
141 
142 /*!
143  *  @brief  Initialize params structure to default values.
144  *
145  *  The default parameters are:
146  *   - name: NULL
147  *
148  *  @param params  Pointer to the instance configuration parameters.
149  */
150 extern void SwiP_Params_init(SwiP_Params *params);
151 
152 /*!
153  *  @brief  Function to create a software interrupt object.
154  *
155  *  @param  swiFxn entry function of the software interrupt
156  *
157  *  @param  params    Pointer to the instance configuration parameters. NULL
158  *                    denotes to use the default parameters. The SwiP default
159  *                    parameters are noted in ::SwiP_Params_init.
160  *
161  *  @return A SwiP_Handle on success or a NULL on an error
162  */
163 extern SwiP_Handle SwiP_create(SwiP_Fxn swiFxn,
164                                SwiP_Params *params);
165 
166 /*!
167  *  @brief  Function to delete a software interrupt object
168  *
169  *  @param  handle returned from the SwiP_create call
170  *
171  */
172 extern void SwiP_delete(SwiP_Handle handle);
173 
174 /*!
175  *  @brief  Function to disable software interrupts
176  *
177  *  This function can be called multiple times, but must unwound in the reverse
178  *  order. For example
179  *  @code
180  *  uintptr_t key1, key2;
181  *  key1 = SwiP_disable();
182  *  key2 = SwiP_disable();
183  *  SwiP_restore(key2);
184  *  SwiP_restore(key1);
185  *  @endcode
186  *
187  *  @return A key that must be passed to SwiP_restore to re-enable interrupts.
188  */
189 extern uintptr_t SwiP_disable(void);
190 
191 /*!
192  *  @brief  Function to get the trigger value of the currently running SwiP.
193  *
194  */
195 extern uint32_t SwiP_getTrigger();
196 
197 /*!
198  *  @brief  Clear bits in SwiP's trigger. Post SwiP if trigger becomes 0.
199  *
200  *  @param  handle returned from the SwiP_create or SwiP_construct call
201  *  @param  mask   inverse value to be ANDed
202  */
203 extern void SwiP_andn(SwiP_Handle handle, uint32_t mask);
204 
205 /*!
206  *  @brief  Decrement SwiP's trigger value. Post SwiP if trigger becomes 0.
207  *
208  *  @param  handle returned from the SwiP_create or SwiP_construct call
209  */
210 extern void SwiP_dec(SwiP_Handle handle);
211 
212 /*!
213  *  @brief  Increment the SwiP's trigger value and post the SwiP.
214  *
215  *  @param  handle returned from the SwiP_create or SwiP_construct call
216  */
217 extern void SwiP_inc(SwiP_Handle handle);
218 
219 /*!
220  *  @brief  Function  to return a status based on whether it is in a
221  *      software interrupt context.
222  *
223  *  @return A status: indicating whether the function was called in a
224  *      software interrupt routine (true) or not (false).
225  */
226 extern bool SwiP_inISR(void);
227 
228 /*!
229  *  @brief  Or the mask with the SwiP's trigger value and post the SwiP.
230  *
231  *  @param  handle returned from the SwiP_create or SwiP_construct call
232  *  @param  mask   value to be ORed
233  */
234 extern void SwiP_or(SwiP_Handle handle, uint32_t mask);
235 
236 /*!
237  *  @brief  Unconditionally post a software interrupt.
238  *
239  *  @param  handle returned from the SwiP_create or SwiP_construct call
240  */
241 extern void SwiP_post(SwiP_Handle handle);
242 
243 /*!
244  *  @brief  Function to restore software interrupts
245  *
246  *  @param  key return from SwiP_disable
247  */
248 extern void SwiP_restore(uintptr_t key);
249 
250 /*!
251  *  @brief  Function to set the priority of a software interrupt
252  *
253  *  @param  handle returned from the SwiP_create or SwiP_construct call
254  *  @param  priority new priority
255  */
256 extern void SwiP_setPriority(SwiP_Handle handle, uint32_t priority);
257 
258 #ifdef __cplusplus
259 }
260 #endif
261 
262 #endif /* ti_dpl_SwiP__include */
263