[keystone-rtos/edma3_lld.git] / packages / ti / sdo / edma3 / drv / sample / src / bios6_edma3_drv_sample_cs.c
1 /*******************************************************************************
2 **+--------------------------------------------------------------------------+**
3 **| **** |**
4 **| **** |**
5 **| ******o*** |**
6 **| ********_///_**** |**
7 **| ***** /_//_/ **** |**
8 **| ** ** (__/ **** |**
9 **| ********* |**
10 **| **** |**
11 **| *** |**
12 **| |**
13 **| Copyright (c) 1998-2006 Texas Instruments Incorporated |**
14 **| ALL RIGHTS RESERVED |**
15 **| |**
16 **| Permission is hereby granted to licensees of Texas Instruments |**
17 **| Incorporated (TI) products to use this computer program for the sole |**
18 **| purpose of implementing a licensee product based on TI products. |**
19 **| No other rights to reproduce, use, or disseminate this computer |**
20 **| program, whether in part or in whole, are granted. |**
21 **| |**
22 **| TI makes no representation or warranties with respect to the |**
23 **| performance of this computer program, and specifically disclaims |**
24 **| any responsibility for any damages, special or consequential, |**
25 **| connected with the use of this program. |**
26 **| |**
27 **+--------------------------------------------------------------------------+**
28 *******************************************************************************/
30 /** \file bios6_edma3_drv_sample_cs.c
32 \brief Sample functions showing the implementation of Critical section
33 entry/exit routines and various semaphore related routines (all BIOS6
34 depenedent). These implementations MUST be provided by the user /
35 application, using the EDMA3 driver, for its correct functioning.
37 (C) Copyright 2006, Texas Instruments, Inc
39 \version 1.0 Anuj Aggarwal - Created
41 */
43 #include <ti/sysbios/family/c64p/EventCombiner.h>
44 #include <ti/sysbios/hal/Cache.h>
45 #include <ti/sysbios/hal/Hwi.h>
46 #include <ti/sysbios/knl/Task.h>
47 #include <ti/sysbios/ipc/Semaphore.h>
49 #include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h>
51 /**
52 * \brief EDMA3 OS Protect Entry
53 *
54 * This function saves the current state of protection in 'intState'
55 * variable passed by caller, if the protection level is
56 * EDMA3_OS_PROTECT_INTERRUPT. It then applies the requested level of
57 * protection.
58 * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
59 * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
60 * and the requested interrupt is disabled.
61 * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, '*intState' specifies the
62 * Transfer Controller number whose interrupt needs to be disabled.
63 *
64 * \param level is numeric identifier of the desired degree of protection.
65 * \param intState is memory location where current state of protection is
66 * saved for future use while restoring it via edma3OsProtectExit() (Only
67 * for EDMA3_OS_PROTECT_INTERRUPT protection level).
68 * \return None
69 */
70 void edma3OsProtectEntry (int level, unsigned int *intState)
71 {
72 if (((level == EDMA3_OS_PROTECT_INTERRUPT)
73 || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
74 && (intState == NULL))
75 {
76 return;
77 }
78 else
79 {
80 switch (level)
81 {
82 /* Disable all (global) interrupts */
83 case EDMA3_OS_PROTECT_INTERRUPT :
84 *intState = Hwi_disable();
85 break;
87 /* Disable scheduler */
88 case EDMA3_OS_PROTECT_SCHEDULER :
89 Task_disable();
90 break;
92 /* Disable EDMA3 transfer completion interrupt only */
93 case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
94 EventCombiner_disableEvent(ccXferCompInt);
95 break;
97 /* Disable EDMA3 CC error interrupt only */
98 case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
99 EventCombiner_disableEvent(ccErrorInt);
100 break;
102 /* Disable EDMA3 TC error interrupt only */
103 case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
104 switch (*intState)
105 {
106 case 0:
107 case 1:
108 case 2:
109 case 3:
110 case 4:
111 case 5:
112 case 6:
113 case 7:
114 /* Fall through... */
115 /* Disable the corresponding interrupt */
116 EventCombiner_disableEvent(tcErrorInt[*intState]);
117 break;
119 default:
120 break;
121 }
123 break;
125 default:
126 break;
127 }
128 }
129 }
132 /**
133 * \brief EDMA3 OS Protect Exit
134 *
135 * This function undoes the protection enforced to original state
136 * as is specified by the variable 'intState' passed, if the protection
137 * level is EDMA3_OS_PROTECT_INTERRUPT.
138 * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
139 * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
140 * and the requested interrupt is enabled.
141 * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, 'intState' specifies the
142 * Transfer Controller number whose interrupt needs to be enabled.
143 * \param level is numeric identifier of the desired degree of protection.
144 * \param intState is original state of protection at time when the
145 * corresponding edma3OsProtectEntry() was called (Only
146 * for EDMA3_OS_PROTECT_INTERRUPT protection level).
147 * \return None
148 */
149 void edma3OsProtectExit (int level, unsigned int intState)
150 {
151 switch (level)
152 {
153 /* Enable all (global) interrupts */
154 case EDMA3_OS_PROTECT_INTERRUPT :
155 Hwi_restore(intState);
156 break;
158 /* Enable scheduler */
159 case EDMA3_OS_PROTECT_SCHEDULER :
160 Task_enable();
161 break;
163 /* Enable EDMA3 transfer completion interrupt only */
164 case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
165 EventCombiner_enableEvent(ccXferCompInt);
166 break;
168 /* Enable EDMA3 CC error interrupt only */
169 case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
170 EventCombiner_enableEvent(ccErrorInt);
171 break;
173 /* Enable EDMA3 TC error interrupt only */
174 case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
175 switch (intState)
176 {
177 case 0:
178 case 1:
179 case 2:
180 case 3:
181 case 4:
182 case 5:
183 case 6:
184 case 7:
185 /* Fall through... */
186 /* Enable the corresponding interrupt */
187 EventCombiner_enableEvent(tcErrorInt[intState]);
188 break;
190 default:
191 break;
192 }
194 break;
196 default:
197 break;
198 }
199 }
202 /**
203 * \brief EDMA3 Cache Invalidate
204 *
205 * This function invalidates the D cache.
206 *
207 * \param mem_start_ptr [IN] Starting address of memory.
208 * Please note that this should be
209 * aligned according to the cache line size.
210 * \param num_bytes [IN] length of buffer
211 * \return EDMA3_DRV_SOK if success, else error code in case of error
212 * or non-alignment of buffers.
213 *
214 * Note: This function is required if the buffer is in DDR.
215 * For other cases, where buffer is NOT in DDR, user
216 * may or may not require the below implementation and
217 * should modify it according to her need.
218 */
219 EDMA3_DRV_Result Edma3_CacheInvalidate(unsigned int mem_start_ptr,
220 unsigned int num_bytes)
221 {
222 EDMA3_DRV_Result cacheInvResult = EDMA3_DRV_SOK;
224 /* Verify whether the start address is cache aligned or not */
225 if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u)) != 0)
226 {
227 #ifdef EDMA3_DRV_DEBUG
228 EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
229 EDMA3_CACHE_LINE_SIZE_IN_BYTES);
230 #endif
231 cacheInvResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
232 }
233 else
234 {
235 Cache_inv((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
236 }
238 return cacheInvResult;
239 }
243 /**
244 * \brief EDMA3 Cache Flush
245 *
246 * This function flushes (cleans) the Cache
247 *
248 * \param mem_start_ptr [IN] Starting address of memory.
249 * Please note that this should be
250 * aligned according to the cache line size.
251 * \param num_bytes [IN] length of buffer
252 * \return EDMA3_DRV_SOK if success, else error code in case of error
253 * or non-alignment of buffers.
254 *
255 * Note: This function is required if the buffer is in DDR.
256 * For other cases, where buffer is NOT in DDR, user
257 * may or may not require the below implementation and
258 * should modify it according to her need.
259 */
260 EDMA3_DRV_Result Edma3_CacheFlush(unsigned int mem_start_ptr,
261 unsigned int num_bytes)
262 {
263 EDMA3_DRV_Result cacheFlushResult = EDMA3_DRV_SOK;
265 /* Verify whether the start address is cache aligned or not */
266 if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u)) != 0)
267 {
268 #ifdef EDMA3_DRV_DEBUG
269 EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
270 EDMA3_CACHE_LINE_SIZE_IN_BYTES);
271 #endif
272 cacheFlushResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
273 }
274 else
275 {
276 Cache_wb((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
277 }
279 return cacheFlushResult;
280 }
283 /**
284 * Counting Semaphore related functions (OS dependent) should be
285 * called/implemented by the application. A handle to the semaphore
286 * is required while opening the driver/resource manager instance.
287 */
289 /**
290 * \brief EDMA3 OS Semaphore Create
291 *
292 * This function creates a counting semaphore with specified
293 * attributes and initial value. It should be used to create a semaphore
294 * with initial value as '1'. The semaphore is then passed by the user
295 * to the EDMA3 driver/RM for proper sharing of resources.
296 * \param initVal [IN] is initial value for semaphore
297 * \param semParams [IN] is the semaphore attributes.
298 * \param hSem [OUT] is location to recieve the handle to just created
299 * semaphore
300 * \return EDMA3_DRV_SOK if succesful, else a suitable error code.
301 */
302 EDMA3_DRV_Result edma3OsSemCreate(int initVal,
303 const Semaphore_Params *semParams,
304 EDMA3_OS_Sem_Handle *hSem)
305 {
306 EDMA3_DRV_Result semCreateResult = EDMA3_DRV_SOK;
308 if(NULL == hSem)
309 {
310 semCreateResult = EDMA3_DRV_E_INVALID_PARAM;
311 }
312 else
313 {
314 *hSem = (EDMA3_OS_Sem_Handle)Semaphore_create(initVal, semParams, NULL);
315 if ( (*hSem) == NULL )
316 {
317 semCreateResult = EDMA3_DRV_E_SEMAPHORE;
318 }
319 }
321 return semCreateResult;
322 }
325 /**
326 * \brief EDMA3 OS Semaphore Delete
327 *
328 * This function deletes or removes the specified semaphore
329 * from the system. Associated dynamically allocated memory
330 * if any is also freed up.
331 * \param hSem [IN] handle to the semaphore to be deleted
332 * \return EDMA3_DRV_SOK if succesful else a suitable error code
333 */
334 EDMA3_DRV_Result edma3OsSemDelete(EDMA3_OS_Sem_Handle hSem)
335 {
336 EDMA3_DRV_Result semDeleteResult = EDMA3_DRV_SOK;
338 if(NULL == hSem)
339 {
340 semDeleteResult = EDMA3_DRV_E_INVALID_PARAM;
341 }
342 else
343 {
344 Semaphore_delete((Semaphore_Handle *)&hSem);
345 }
347 return semDeleteResult;
348 }
351 /**
352 * \brief EDMA3 OS Semaphore Take
353 *
354 * This function takes a semaphore token if available.
355 * If a semaphore is unavailable, it blocks currently
356 * running thread in wait (for specified duration) for
357 * a free semaphore.
358 * \param hSem [IN] is the handle of the specified semaphore
359 * \param mSecTimeout [IN] is wait time in milliseconds
360 * \return EDMA3_DRV_Result if successful else a suitable error code
361 */
362 EDMA3_DRV_Result edma3OsSemTake(EDMA3_OS_Sem_Handle hSem, int mSecTimeout)
363 {
364 EDMA3_DRV_Result semTakeResult = EDMA3_DRV_SOK;
365 unsigned short semPendResult;
367 if(NULL == hSem)
368 {
369 semTakeResult = EDMA3_DRV_E_INVALID_PARAM;
370 }
371 else
372 {
373 semPendResult = Semaphore_pend(hSem, mSecTimeout);
374 if (semPendResult == FALSE)
375 {
376 semTakeResult = EDMA3_DRV_E_SEMAPHORE;
377 }
378 }
380 return semTakeResult;
381 }
384 /**
385 * \brief EDMA3 OS Semaphore Give
386 *
387 * This function gives or relinquishes an already
388 * acquired semaphore token
389 * \param hSem [IN] is the handle of the specified semaphore
390 * \return EDMA3_DRV_Result if successful else a suitable error code
391 */
392 EDMA3_DRV_Result edma3OsSemGive(EDMA3_OS_Sem_Handle hSem)
393 {
394 EDMA3_DRV_Result semGiveResult = EDMA3_DRV_SOK;
396 if(NULL == hSem)
397 {
398 semGiveResult = EDMA3_DRV_E_INVALID_PARAM;
399 }
400 else
401 {
402 Semaphore_post(hSem);
403 }
405 return semGiveResult;
406 }