]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_dsp/sap/sample_cs.c
Update test_arm and test_dsp projects for new locations of IPC and PDK eng
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sample_cs.c
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 /*
37  * sample_cs.c
38  *
39  * Sample functions showing the implementation of critical section entry/exit
40  * routines and various semaphore related routines (all BIOS6 depenedent).
41  * These implementations MUST be provided by the user / application, using the
42  * EDMA3 driver, for its correct functioning.
43  */
45 #include <ti/sysbios/family/c64p/EventCombiner.h>
46 #include <ti/sysbios/hal/Cache.h>
47 #include <ti/sysbios/hal/Hwi.h>
48 #include <ti/sysbios/knl/Task.h>
49 #include <ti/sysbios/knl/Semaphore.h>
51 #include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h>
52 #include <ti/sdo/edma3/drv/edma3_drv.h>
54 extern unsigned int ccXferCompInt[][EDMA3_MAX_REGIONS];
55 extern unsigned int ccErrorInt[];
56 extern unsigned int tcErrorInt[][EDMA3_MAX_TC];
58 /**
59  * Shadow Region on which the executable is running. Its value is
60  * populated with the DSP Instance Number here in this case.
61  */
62 extern unsigned int region_id;
64 /**
65  * \brief   EDMA3 OS Protect Entry
66  *
67  *      This function saves the current state of protection in 'intState'
68  *      variable passed by caller, if the protection level is
69  *      EDMA3_OS_PROTECT_INTERRUPT. It then applies the requested level of
70  *      protection.
71  *      For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
72  *      EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
73  *      and the requested interrupt is disabled.
74  *      For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, '*intState' specifies the
75  *      Transfer Controller number whose interrupt needs to be disabled.
76  *
77  * \param   level is numeric identifier of the desired degree of protection.
78  * \param   intState is memory location where current state of protection is
79  *      saved for future use while restoring it via edma3OsProtectExit() (Only
80  *      for EDMA3_OS_PROTECT_INTERRUPT protection level).
81  * \return  None
82  */
83 void edma3OsProtectEntry (unsigned int edma3InstanceId,
84                                                         int level, unsigned int *intState)
85     {
86     if (((level == EDMA3_OS_PROTECT_INTERRUPT)
87         || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
88         && (intState == NULL))
89         {
90         return;
91         }
92     else
93         {
94         switch (level)
95             {
96             /* Disable all (global) interrupts */
97             case EDMA3_OS_PROTECT_INTERRUPT :
98                 *intState = Hwi_disable();
99                 break;
101             /* Disable scheduler */
102             case EDMA3_OS_PROTECT_SCHEDULER :
103                                         Task_disable();
104                 break;
106             /* Disable EDMA3 transfer completion interrupt only */
107             case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
108                 EventCombiner_disableEvent(ccXferCompInt[edma3InstanceId][region_id]);
109                 break;
111             /* Disable EDMA3 CC error interrupt only */
112             case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
113                 EventCombiner_disableEvent(ccErrorInt[edma3InstanceId]);
114                 break;
116             /* Disable EDMA3 TC error interrupt only */
117             case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
118                 switch (*intState)
119                     {
120                     case 0:
121                     case 1:
122                     case 2:
123                     case 3:
124                     case 4:
125                     case 5:
126                     case 6:
127                     case 7:
128                         /* Fall through... */
129                         /* Disable the corresponding interrupt */
130                         EventCombiner_disableEvent(tcErrorInt[edma3InstanceId][*intState]);
131                         break;
133                      default:
134                         break;
135                     }
137                 break;
139             default:
140                 break;
141             }
142         }
143     }
146 /**
147  * \brief   EDMA3 OS Protect Exit
148  *
149  *      This function undoes the protection enforced to original state
150  *      as is specified by the variable 'intState' passed, if the protection
151  *      level is EDMA3_OS_PROTECT_INTERRUPT.
152  *      For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
153  *      EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
154  *      and the requested interrupt is enabled.
155  *      For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, 'intState' specifies the
156  *      Transfer Controller number whose interrupt needs to be enabled.
157  * \param   level is numeric identifier of the desired degree of protection.
158  * \param   intState is original state of protection at time when the
159  *      corresponding edma3OsProtectEntry() was called (Only
160  *      for EDMA3_OS_PROTECT_INTERRUPT protection level).
161  * \return  None
162  */
163 void edma3OsProtectExit (unsigned int edma3InstanceId,
164                         int level, unsigned int intState)
165     {
166     switch (level)
167         {
168         /* Enable all (global) interrupts */
169         case EDMA3_OS_PROTECT_INTERRUPT :
170             Hwi_restore(intState);
171             break;
173         /* Enable scheduler */
174         case EDMA3_OS_PROTECT_SCHEDULER :
175             Task_enable();
176             break;
178         /* Enable EDMA3 transfer completion interrupt only */
179         case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
180             EventCombiner_enableEvent(ccXferCompInt[edma3InstanceId][region_id]);
181             break;
183         /* Enable EDMA3 CC error interrupt only */
184         case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
185             EventCombiner_enableEvent(ccErrorInt[edma3InstanceId]);
186             break;
188         /* Enable EDMA3 TC error interrupt only */
189         case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
190             switch (intState)
191                 {
192                 case 0:
193                 case 1:
194                 case 2:
195                 case 3:
196                 case 4:
197                 case 5:
198                 case 6:
199                 case 7:
200                     /* Fall through... */
201                     /* Enable the corresponding interrupt */
202                     EventCombiner_enableEvent(tcErrorInt[edma3InstanceId][intState]);
203                     break;
205                  default:
206                     break;
207                 }
209             break;
211         default:
212             break;
213         }
214     }
217 /**
218  *  \brief   EDMA3 Cache Invalidate
219  *
220  *  This function invalidates the D cache.
221  *
222  *  \param  mem_start_ptr [IN]      Starting address of memory.
223  *                                  Please note that this should be
224  *                                  aligned according to the cache line size.
225  *  \param  num_bytes [IN]          length of buffer
226  *  \return  EDMA3_DRV_SOK if success, else error code in case of error
227  *          or non-alignment of buffers.
228  *
229  * Note: This function is required if the buffer is in DDR.
230  * For other cases, where buffer is NOT in DDR, user
231  * may or may not require the below implementation and
232  * should modify it according to her need.
233  */
234 EDMA3_DRV_Result Edma3_CacheInvalidate(unsigned int mem_start_ptr,
235                            unsigned int    num_bytes)
236     {
237     EDMA3_DRV_Result cacheInvResult = EDMA3_DRV_SOK;
239     /* Verify whether the start address is cache aligned or not */
240     if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u))    !=    0)
241         {
242 #ifdef EDMA3_DRV_DEBUG
243         EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
244                             EDMA3_CACHE_LINE_SIZE_IN_BYTES);
245 #endif
246         cacheInvResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
247         }
248     else
249         {
250                 Cache_inv((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
251         }
253     return cacheInvResult;
258 /**
259  * \brief   EDMA3 Cache Flush
260  *
261  *  This function flushes (cleans) the Cache
262  *
263  *  \param  mem_start_ptr [IN]      Starting address of memory.
264  *                                  Please note that this should be
265  *                                  aligned according to the cache line size.
266  *  \param  num_bytes [IN]          length of buffer
267  *  \return  EDMA3_DRV_SOK if success, else error code in case of error
268  *          or non-alignment of buffers.
269  *
270  * Note: This function is required if the buffer is in DDR.
271  * For other cases, where buffer is NOT in DDR, user
272  * may or may not require the below implementation and
273  * should modify it according to her need.
274  */
275 EDMA3_DRV_Result Edma3_CacheFlush(unsigned int mem_start_ptr,
276                       unsigned int num_bytes)
277     {
278     EDMA3_DRV_Result cacheFlushResult = EDMA3_DRV_SOK;
280     /* Verify whether the start address is cache aligned or not */
281     if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u))    !=    0)
282         {
283 #ifdef EDMA3_DRV_DEBUG
284         EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
285                             EDMA3_CACHE_LINE_SIZE_IN_BYTES);
286 #endif
287         cacheFlushResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
288         }
289     else
290         {
291                 Cache_wb((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
292         }
294     return cacheFlushResult;
298 /**
299   * Counting Semaphore related functions (OS dependent) should be
300   * called/implemented by the application. A handle to the semaphore
301   * is required while opening the driver/resource manager instance.
302   */
304 /**
305  * \brief   EDMA3 OS Semaphore Create
306  *
307  *      This function creates a counting semaphore with specified
308  *      attributes and initial value. It should be used to create a semaphore
309  *      with initial value as '1'. The semaphore is then passed by the user
310  *      to the EDMA3 driver/RM for proper sharing of resources.
311  * \param   initVal [IN] is initial value for semaphore
312  * \param   semParams [IN] is the semaphore attributes.
313  * \param   hSem [OUT] is location to recieve the handle to just created
314  *      semaphore
315  * \return  EDMA3_DRV_SOK if succesful, else a suitable error code.
316  */
317 EDMA3_DRV_Result edma3OsSemCreate(int initVal,
318                                                         const Semaphore_Params *semParams,
319                                 EDMA3_OS_Sem_Handle *hSem)
320     {
321     EDMA3_DRV_Result semCreateResult = EDMA3_DRV_SOK;
323     if(NULL == hSem)
324         {
325         semCreateResult = EDMA3_DRV_E_INVALID_PARAM;
326         }
327     else
328         {
329         *hSem = (EDMA3_OS_Sem_Handle)Semaphore_create(initVal, semParams, NULL);
330         if ( (*hSem) == NULL )
331             {
332             semCreateResult = EDMA3_DRV_E_SEMAPHORE;
333             }
334         }
336     return semCreateResult;
337     }
340 /**
341  * \brief   EDMA3 OS Semaphore Delete
342  *
343  *      This function deletes or removes the specified semaphore
344  *      from the system. Associated dynamically allocated memory
345  *      if any is also freed up.
346  * \param   hSem [IN] handle to the semaphore to be deleted
347  * \return  EDMA3_DRV_SOK if succesful else a suitable error code
348  */
349 EDMA3_DRV_Result edma3OsSemDelete(EDMA3_OS_Sem_Handle hSem)
350     {
351     EDMA3_DRV_Result semDeleteResult = EDMA3_DRV_SOK;
353     if(NULL == hSem)
354         {
355         semDeleteResult = EDMA3_DRV_E_INVALID_PARAM;
356         }
357     else
358         {
359                 Semaphore_delete((Semaphore_Handle *)&hSem);
360         }
362     return semDeleteResult;
363     }
366 /**
367  * \brief   EDMA3 OS Semaphore Take
368  *
369  *      This function takes a semaphore token if available.
370  *      If a semaphore is unavailable, it blocks currently
371  *      running thread in wait (for specified duration) for
372  *      a free semaphore.
373  * \param   hSem [IN] is the handle of the specified semaphore
374  * \param   mSecTimeout [IN] is wait time in milliseconds
375  * \return  EDMA3_DRV_Result if successful else a suitable error code
376  */
377 EDMA3_DRV_Result edma3OsSemTake(EDMA3_OS_Sem_Handle hSem, int mSecTimeout)
378     {
379     EDMA3_DRV_Result semTakeResult = EDMA3_DRV_SOK;
380     unsigned short semPendResult;
382     if(NULL == hSem)
383         {
384         semTakeResult = EDMA3_DRV_E_INVALID_PARAM;
385         }
386     else
387         {
388         semPendResult = Semaphore_pend(hSem, mSecTimeout);
389         if (semPendResult == FALSE)
390             {
391             semTakeResult = EDMA3_DRV_E_SEMAPHORE;
392             }
393         }
395     return semTakeResult;
396     }
399 /**
400  * \brief   EDMA3 OS Semaphore Give
401  *
402  *      This function gives or relinquishes an already
403  *      acquired semaphore token
404  * \param   hSem [IN] is the handle of the specified semaphore
405  * \return  EDMA3_DRV_Result if successful else a suitable error code
406  */
407 EDMA3_DRV_Result edma3OsSemGive(EDMA3_OS_Sem_Handle hSem)
408     {
409     EDMA3_DRV_Result semGiveResult = EDMA3_DRV_SOK;
411     if(NULL == hSem)
412         {
413         semGiveResult = EDMA3_DRV_E_INVALID_PARAM;
414         }
415     else
416         {
417                 Semaphore_post(hSem);
418         }
420     return semGiveResult;
421     }
423 /* End of File */