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 uint32_t ccXferCompInt[EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
49 extern uint32_t ccErrorInt[EDMA3_MAX_EDMA3_INSTANCES];
50 extern uint32_t tcErrorInt[EDMA3_MAX_EDMA3_INSTANCES][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 uint32_t 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 (uint32_t edma3InstanceId,
78 int32_t level, uint32_t *intState)
79 {
80 if (((level == EDMA3_OS_PROTECT_INTERRUPT)
81 || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
82 && (intState == NULL))
83 {
84 /* Nothing to be done here */
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 return;
138 }
141 /**
142 * \brief EDMA3 OS Protect Exit
143 *
144 * This function undoes the protection enforced to original state
145 * as is specified by the variable 'intState' passed, if the protection
146 * level is EDMA3_OS_PROTECT_INTERRUPT.
147 * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
148 * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
149 * and the requested interrupt is enabled.
150 * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, 'intState' specifies the
151 * Transfer Controller number whose interrupt needs to be enabled.
152 * \param level is numeric identifier of the desired degree of protection.
153 * \param intState is original state of protection at time when the
154 * corresponding edma3OsProtectEntry() was called (Only
155 * for EDMA3_OS_PROTECT_INTERRUPT protection level).
156 * \return None
157 */
158 void edma3OsProtectExit (uint32_t edma3InstanceId,
159 int32_t level, uint32_t intState)
160 {
161 switch (level)
162 {
163 /* Enable all (global) interrupts */
164 case EDMA3_OS_PROTECT_INTERRUPT :
165 Hwi_restore(intState);
166 break;
168 /* Enable scheduler */
169 case EDMA3_OS_PROTECT_SCHEDULER :
170 Task_enable();
171 break;
173 /* Enable EDMA3 transfer completion interrupt only */
174 case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
175 Hwi_enableInterrupt(ccXferCompInt[edma3InstanceId][region_id]);
176 break;
178 /* Enable EDMA3 CC error interrupt only */
179 case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
180 Hwi_enableInterrupt(ccErrorInt[edma3InstanceId]);
181 break;
183 /* Enable EDMA3 TC error interrupt only */
184 case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
185 switch (intState)
186 {
187 case 0:
188 case 1:
189 case 2:
190 case 3:
191 case 4:
192 case 5:
193 case 6:
194 case 7:
195 /* Fall through... */
196 /* Enable the corresponding interrupt */
197 Hwi_enableInterrupt(tcErrorInt[edma3InstanceId][intState]);
198 break;
200 default:
201 break;
202 }
204 break;
206 default:
207 break;
208 }
209 }
212 /**
213 * Counting Semaphore related functions (OS dependent) should be
214 * called/implemented by the application. A handle to the semaphore
215 * is required while opening the resource manager instance.
216 */
218 /**
219 * \brief EDMA3 OS Semaphore Create
220 *
221 * This function creates a counting semaphore with specified
222 * attributes and initial value. It should be used to create a semaphore
223 * with initial value as '1'. The semaphore is then passed by the user
224 * to the EDMA3 RM for proper sharing of resources.
225 * \param initVal [IN] is initial value for semaphore
226 * \param semParams [IN] is the semaphore attributes.
227 * \param hSem [OUT] is location to recieve the handle to just created
228 * semaphore
229 * \return EDMA3_RM_SOK if succesful, else a suitable error code.
230 */
231 EDMA3_RM_Result edma3OsSemCreate(int32_t initVal,
232 const Semaphore_Params *semParams,
233 EDMA3_OS_Sem_Handle *hSem)
234 {
235 EDMA3_RM_Result semCreateResult = EDMA3_RM_SOK;
237 if(NULL == hSem)
238 {
239 semCreateResult = EDMA3_RM_E_INVALID_PARAM;
240 }
241 else
242 {
243 *hSem = (EDMA3_OS_Sem_Handle)Semaphore_create(initVal, semParams, NULL);
244 if ( (*hSem) == NULL )
245 {
246 semCreateResult = EDMA3_RM_E_SEMAPHORE;
247 }
248 }
250 return semCreateResult;
251 }
254 /**
255 * \brief EDMA3 OS Semaphore Delete
256 *
257 * This function deletes or removes the specified semaphore
258 * from the system. Associated dynamically allocated memory
259 * if any is also freed up.
260 * \param hSem [IN] handle to the semaphore to be deleted
261 * \return EDMA3_RM_SOK if succesful else a suitable error code
262 */
263 EDMA3_RM_Result edma3OsSemDelete(EDMA3_OS_Sem_Handle hSem)
264 {
265 EDMA3_RM_Result semDeleteResult = EDMA3_RM_SOK;
267 if(NULL == hSem)
268 {
269 semDeleteResult = EDMA3_RM_E_INVALID_PARAM;
270 }
271 else
272 {
273 Semaphore_delete((Semaphore_Handle *)&hSem);
274 }
276 return semDeleteResult;
277 }
280 /**
281 * \brief EDMA3 OS Semaphore Take
282 *
283 * This function takes a semaphore token if available.
284 * If a semaphore is unavailable, it blocks currently
285 * running thread in wait (for specified duration) for
286 * a free semaphore.
287 * \param hSem [IN] is the handle of the specified semaphore
288 * \param mSecTimeout [IN] is wait time in milliseconds
289 * \return EDMA3_RM_Result if successful else a suitable error code
290 */
291 EDMA3_Result edma3OsSemTake(EDMA3_OS_Sem_Handle hSem, int32_t mSecTimeout)
292 {
293 EDMA3_Result semTakeResult = EDMA3_RM_SOK;
295 if(NULL == hSem)
296 {
297 semTakeResult = EDMA3_RM_E_INVALID_PARAM;
298 }
299 else
300 {
301 if ((Semaphore_pend((Semaphore_Handle)hSem, (uint32_t)mSecTimeout)) == FALSE)
302 {
303 semTakeResult = EDMA3_RM_E_SEMAPHORE;
304 }
305 }
307 return semTakeResult;
308 }
311 /**
312 * \brief EDMA3 OS Semaphore Give
313 *
314 * This function gives or relinquishes an already
315 * acquired semaphore token
316 * \param hSem [IN] is the handle of the specified semaphore
317 * \return EDMA3_Result if successful else a suitable error code
318 */
319 EDMA3_Result edma3OsSemGive(EDMA3_OS_Sem_Handle hSem)
320 {
321 EDMA3_Result semGiveResult = EDMA3_RM_SOK;
323 if(NULL == hSem)
324 {
325 semGiveResult = EDMA3_RM_E_INVALID_PARAM;
326 }
327 else
328 {
329 Semaphore_post((Semaphore_Handle)hSem);
330 }
332 return semGiveResult;
333 }
335 /* End of File */