4646e7644bb6b8d12232eb403798ed565a6d34b1
[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;
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;
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     }