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