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