1 /*\r
2 * sample_cs.c\r
3 *\r
4 * Sample functions showing the implementation of critical section entry/exit\r
5 * routines and various semaphore related routines (all OS depenedent). These\r
6 * implementations MUST be provided by the user / application, using the EDMA3\r
7 * Resource Manager, for its correct functioning.\r
8 *\r
9 * Copyright (C) 2009-2017 Texas Instruments Incorporated - http://www.ti.com/\r
10 *\r
11 *\r
12 * Redistribution and use in source and binary forms, with or without\r
13 * modification, are permitted provided that the following conditions\r
14 * are met:\r
15 *\r
16 * Redistributions of source code must retain the above copyright\r
17 * notice, this list of conditions and the following disclaimer.\r
18 *\r
19 * Redistributions in binary form must reproduce the above copyright\r
20 * notice, this list of conditions and the following disclaimer in the\r
21 * documentation and/or other materials provided with the\r
22 * distribution.\r
23 *\r
24 * Neither the name of Texas Instruments Incorporated nor the names of\r
25 * its contributors may be used to endorse or promote products derived\r
26 * from this software without specific prior written permission.\r
27 *\r
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
39 *\r
40 */\r
41 \r
42 #include <ti/sysbios/family/c64p/EventCombiner.h>\r
43 #include <ti/sysbios/hal/Hwi.h>\r
44 #include <ti/sysbios/knl/Task.h>\r
45 #include <ti/sysbios/knl/Semaphore.h>\r
46 \r
47 #include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h>\r
48 \r
49 extern uint32_t tcErrorInt[EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_TC];\r
50 extern void enableXferCompInterrupt(uint32_t edma3Id);\r
51 extern void disableXferCompInterrupt(uint32_t edma3Id);\r
52 extern void enableErrorInterrupt(uint32_t edma3Id);\r
53 extern void disableErrorInterrupt(uint32_t edma3Id);\r
54 \r
55 /**\r
56 * Shadow Region on which the executable is running. Its value is\r
57 * populated with the DSP Instance Number here in this case.\r
58 */\r
59 extern uint32_t region_id;\r
60 \r
61 /**\r
62 * \brief EDMA3 OS Protect Entry\r
63 *\r
64 * This function saves the current state of protection in 'intState'\r
65 * variable passed by caller, if the protection level is\r
66 * EDMA3_OS_PROTECT_INTERRUPT. It then applies the requested level of\r
67 * protection.\r
68 * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and\r
69 * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,\r
70 * and the requested interrupt is disabled.\r
71 * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, '*intState' specifies the\r
72 * Transfer Controller number whose interrupt needs to be disabled.\r
73 *\r
74 * \param level is numeric identifier of the desired degree of protection.\r
75 * \param intState is memory location where current state of protection is\r
76 * saved for future use while restoring it via edma3OsProtectExit() (Only\r
77 * for EDMA3_OS_PROTECT_INTERRUPT protection level).\r
78 * \return None\r
79 */\r
80 void edma3OsProtectEntry (uint32_t edma3InstanceId,\r
81 int32_t level, uint32_t *intState)\r
82 {\r
83 if (((level == EDMA3_OS_PROTECT_INTERRUPT)\r
84 || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))\r
85 && (intState == NULL))\r
86 {\r
87 /* Nothing to be done here */\r
88 }\r
89 else\r
90 {\r
91 switch (level)\r
92 {\r
93 /* Disable all (global) interrupts */\r
94 case EDMA3_OS_PROTECT_INTERRUPT :\r
95 *intState = Hwi_disable();\r
96 break;\r
97 \r
98 /* Disable scheduler */\r
99 case EDMA3_OS_PROTECT_SCHEDULER :\r
100 Task_disable();\r
101 break;\r
102 \r
103 /* Disable EDMA3 transfer completion interrupt only */\r
104 case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :\r
105 disableXferCompInterrupt(edma3InstanceId);\r
106 break;\r
107 \r
108 /* Disable EDMA3 CC error interrupt only */\r
109 case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :\r
110 disableErrorInterrupt(edma3InstanceId);\r
111 break;\r
112 \r
113 /* Disable EDMA3 TC error interrupt only */\r
114 case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :\r
115 switch (*intState)\r
116 {\r
117 case 0:\r
118 case 1:\r
119 case 2:\r
120 case 3:\r
121 case 4:\r
122 case 5:\r
123 case 6:\r
124 case 7:\r
125 /* Fall through... */\r
126 /* Disable the corresponding interrupt */\r
127 EventCombiner_disableEvent(tcErrorInt[edma3InstanceId][*intState]);\r
128 break;\r
129 \r
130 default:\r
131 break;\r
132 }\r
133 \r
134 break;\r
135 \r
136 default:\r
137 break;\r
138 }\r
139 }\r
140 return;\r
141 }\r
142 \r
143 \r
144 /**\r
145 * \brief EDMA3 OS Protect Exit\r
146 *\r
147 * This function undoes the protection enforced to original state\r
148 * as is specified by the variable 'intState' passed, if the protection\r
149 * level is EDMA3_OS_PROTECT_INTERRUPT.\r
150 * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and\r
151 * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,\r
152 * and the requested interrupt is enabled.\r
153 * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, 'intState' specifies the\r
154 * Transfer Controller number whose interrupt needs to be enabled.\r
155 * \param level is numeric identifier of the desired degree of protection.\r
156 * \param intState is original state of protection at time when the\r
157 * corresponding edma3OsProtectEntry() was called (Only\r
158 * for EDMA3_OS_PROTECT_INTERRUPT protection level).\r
159 * \return None\r
160 */\r
161 void edma3OsProtectExit (uint32_t edma3InstanceId,\r
162 int32_t level, uint32_t intState)\r
163 {\r
164 switch (level)\r
165 {\r
166 /* Enable all (global) interrupts */\r
167 case EDMA3_OS_PROTECT_INTERRUPT :\r
168 Hwi_restore(intState);\r
169 break;\r
170 \r
171 /* Enable scheduler */\r
172 case EDMA3_OS_PROTECT_SCHEDULER :\r
173 Task_enable();\r
174 break;\r
175 \r
176 /* Enable EDMA3 transfer completion interrupt only */\r
177 case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :\r
178 enableXferCompInterrupt(edma3InstanceId);\r
179 break;\r
180 \r
181 /* Enable EDMA3 CC error interrupt only */\r
182 case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :\r
183 enableErrorInterrupt(edma3InstanceId);\r
184 break;\r
185 \r
186 /* Enable EDMA3 TC error interrupt only */\r
187 case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :\r
188 switch ((int32_t)intState)\r
189 {\r
190 case 0:\r
191 case 1:\r
192 case 2:\r
193 case 3:\r
194 case 4:\r
195 case 5:\r
196 case 6:\r
197 case 7:\r
198 /* Fall through... */\r
199 /* Enable the corresponding interrupt */\r
200 EventCombiner_enableEvent(tcErrorInt[edma3InstanceId][intState]);\r
201 break;\r
202 \r
203 default:\r
204 break;\r
205 }\r
206 \r
207 break;\r
208 \r
209 default:\r
210 break;\r
211 }\r
212 }\r
213 \r
214 \r
215 /**\r
216 * Counting Semaphore related functions (OS dependent) should be\r
217 * called/implemented by the application. A handle to the semaphore\r
218 * is required while opening the resource manager instance.\r
219 */\r
220 \r
221 /**\r
222 * \brief EDMA3 OS Semaphore Create\r
223 *\r
224 * This function creates a counting semaphore with specified\r
225 * attributes and initial value. It should be used to create a semaphore\r
226 * with initial value as '1'. The semaphore is then passed by the user\r
227 * to the EDMA3 RM for proper sharing of resources.\r
228 * \param initVal [IN] is initial value for semaphore\r
229 * \param semParams [IN] is the semaphore attributes.\r
230 * \param hSem [OUT] is location to recieve the handle to just created\r
231 * semaphore\r
232 * \return EDMA3_RM_SOK if succesful, else a suitable error code.\r
233 */\r
234 EDMA3_RM_Result edma3OsSemCreate(int32_t initVal,\r
235 const Semaphore_Params *semParams,\r
236 EDMA3_OS_Sem_Handle *hSem)\r
237 {\r
238 EDMA3_RM_Result semCreateResult = EDMA3_RM_SOK;\r
239 \r
240 if(NULL == hSem)\r
241 {\r
242 semCreateResult = EDMA3_RM_E_INVALID_PARAM;\r
243 }\r
244 else\r
245 {\r
246 *hSem = (EDMA3_OS_Sem_Handle)Semaphore_create(initVal, semParams, NULL);\r
247 if ( (*hSem) == NULL )\r
248 {\r
249 semCreateResult = EDMA3_RM_E_SEMAPHORE;\r
250 }\r
251 }\r
252 \r
253 return semCreateResult;\r
254 }\r
255 \r
256 \r
257 /**\r
258 * \brief EDMA3 OS Semaphore Delete\r
259 *\r
260 * This function deletes or removes the specified semaphore\r
261 * from the system. Associated dynamically allocated memory\r
262 * if any is also freed up.\r
263 * \param hSem [IN] handle to the semaphore to be deleted\r
264 * \return EDMA3_RM_SOK if succesful else a suitable error code\r
265 */\r
266 EDMA3_RM_Result edma3OsSemDelete(EDMA3_OS_Sem_Handle hSem)\r
267 {\r
268 EDMA3_RM_Result semDeleteResult = EDMA3_RM_SOK;\r
269 \r
270 if(NULL == hSem)\r
271 {\r
272 semDeleteResult = EDMA3_RM_E_INVALID_PARAM;\r
273 }\r
274 else\r
275 {\r
276 Semaphore_delete(hSem);\r
277 }\r
278 \r
279 return semDeleteResult;\r
280 }\r
281 \r
282 \r
283 /**\r
284 * \brief EDMA3 OS Semaphore Take\r
285 *\r
286 * This function takes a semaphore token if available.\r
287 * If a semaphore is unavailable, it blocks currently\r
288 * running thread in wait (for specified duration) for\r
289 * a free semaphore.\r
290 * \param hSem [IN] is the handle of the specified semaphore\r
291 * \param mSecTimeout [IN] is wait time in milliseconds\r
292 * \return EDMA3_Result if successful else a suitable error code\r
293 */\r
294 EDMA3_Result edma3OsSemTake(EDMA3_OS_Sem_Handle hSem, int32_t mSecTimeout)\r
295 {\r
296 EDMA3_Result semTakeResult = EDMA3_RM_SOK;\r
297 \r
298 if(NULL == hSem)\r
299 {\r
300 semTakeResult = EDMA3_RM_E_INVALID_PARAM;\r
301 }\r
302 else\r
303 {\r
304 if((Semaphore_pend(hSem, (uint32_t)mSecTimeout)) == FALSE)\r
305 {\r
306 semTakeResult = EDMA3_RM_E_SEMAPHORE;\r
307 }\r
308 }\r
309 \r
310 return semTakeResult;\r
311 }\r
312 \r
313 \r
314 /**\r
315 * \brief EDMA3 OS Semaphore Give\r
316 *\r
317 * This function gives or relinquishes an already\r
318 * acquired semaphore token\r
319 * \param hSem [IN] is the handle of the specified semaphore\r
320 * \return EDMA3_Result if successful else a suitable error code\r
321 */\r
322 EDMA3_Result edma3OsSemGive(EDMA3_OS_Sem_Handle hSem)\r
323 {\r
324 EDMA3_Result semGiveResult = EDMA3_RM_SOK;\r
325 \r
326 if(NULL == hSem)\r
327 {\r
328 semGiveResult = EDMA3_RM_E_INVALID_PARAM;\r
329 }\r
330 else\r
331 {\r
332 Semaphore_post(hSem);\r
333 }\r
334 \r
335 return semGiveResult;\r
336 }\r
337 \r
338 /* End of File */\r
339 \r