]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_dsp/sap/sap.c
Merge branch 'dev_pasdk_govind' into dev_pasdk_frank
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap.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 //
38 // SIO driver implementation for audio I/O using McASP.
39 //
40 //
41 //
43 #ifndef SAP_CACHE_SUPPORT
44   // if you rebuild dap.c in your project without this defined, 
45   // the result is quite hard to find:  Occasional glitches in the sound.
46   #define SAP_CACHE_SUPPORT  // typically defined in the project
47 #endif
49 #ifdef SAP_CACHE_SUPPORT
50 #include <ti/sysbios/hal/Cache.h>
51 #endif
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <string.h> //memset
57 #include <xdc/std.h>
59 #include "sap.h"
61 #include <ti/sdo/edma3/drv/edma3_drv.h>
62 #include <ti/sdo/edma3/drv/src/edma3.h>
63 #include <ti/sdo/edma3/rm/edma3_rm.h>
64 #include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h>
66 #include <ti/csl/cslr_device.h>
68 #define EDMA_HINV NULL
70 #ifdef SAP_PORT_MCASP
71 #include "sap_mcasp.h"
72 #else
73 #error "No port defined"
74 #endif
76 #include <pafsio.h>
78 // This works to set a breakpoint
79 #define SW_BREAKPOINT       asm( " SWBP 0" );
80 /* Software Breakpoint to Code Composer */
81 // SW_BREAKPOINT;
83 // global allocated in bios_edma3_drv_sample_init.c
84 extern EDMA3_DRV_Handle hEdma0;
85 extern EDMA3_DRV_Handle hEdma1;
87 int gStartError;
88 int gIsrCnt;
89 int gIsrElseCnt;
90 int gIsrErrCnt;
91 int gIsrRunCnt;
92 int gIsrNotRunCnt;
93 int gisrOutput;
95 typedef xdc_Short MdInt;
97 void swapHdmi(Ptr, int);
99 #define TEST_MULTICHANNEL
102 #ifdef TEST_MULTICHANNEL
103 #define SAP_UNDER_LEN 4
104 //#define SAP_UNDER_LEN 1024 // GJ: experiment
105 #else
106 #define SAP_UNDER_LEN 1024
107 #endif
108 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
109 int sap_OVER = 0;     // used for overrun
110 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
112         unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
113         unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
114         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
116         Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
117         Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
119         Log_info5("PARAM0x19a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[0], ptrPARAM0x19[1], ptrPARAM0x19[2], ptrPARAM0x19[3]);
120         Log_info5("PARAM0x19b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[4], ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
121     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
123 // .............................................................................
124 // notes:
125 //  . add control function to PORT table
126 //  . how to handle DMA/PORT specifics in parameter entries
127 //      can assume numSers = numChans is general and can be applied by DMA
128 //      same for wordSize?
129 //  . why are two idle stages needed (seems like 1 is enough)?
131 // .............................................................................
132 // only one global variable, not static so that DMA and port functions
133 // can access. We cant just store the address in devExt since the ISR has
134 // no context.
136 SAP_DriverObject sapDrv;
138 // needed since SAP_watchDog is called before SAP_init
139 Int SAP_initialized = 0;
141 //Int  SAP_close(DEV2_Handle);
142 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
143 Int  SAP_idle(DEV2_Handle, Bool);
144 Int  SAP_issue(DEV2_Handle);
145 Int  SAP_open(DEV2_Handle, String);
146 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
147 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
148 Int  SAP_reclaim(DEV2_Handle);
149 Int  SAP_shutdown(DEV2_Handle);
150 Int  SAP_start(DEV2_Handle);
151 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
152 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, unsigned int addr, unsigned int size);
153 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
155 // .............................................................................
157 // .............................................................................
159 SAP_DMA_Fxns SAP_EDMA_FXNS =
161         SAP_EDMA_setupParam,
162         SAP_EDMA_setupXfer,
163 };
166 SAP_Fxns SAP_FXNS =
168     NULL, //SAP_close, -- remove for IROM since not using
169     SAP_ctrl,
170     SAP_idle,
171     SAP_issue,
172     SAP_open,
173     NULL, //SAP_ready, -- remove for IROM since not using
174     SAP_reclaim,
175     SAP_shutdown,
176     SAP_start,
177     SAP_config,
179 #ifdef SAP_PORT_MCASP
180     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
181 #endif
182 #ifdef SAP_DMA_EDMA
183     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
184 #endif
185 };
187 // -----------------------------------------------------------------------------
188 // This function is not in the driver function table.
189 // Must be pointed at in GUI config tool.
190 //
191 Void SAP_init (Void)
193     DEV2_Device  *entry;
194     SAP_Fxns    *pFxns;
196     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
198     // find function table pointer (used by SAP_XX_FTABLE_init macros)
199     DEV2_match(SAP_NAME, &entry);
200     if (entry == NULL) {
201         Log_error1 ("SAP", SIO2_ENODEV);
202         return;
203     }
204     pFxns = (SAP_Fxns *) entry->fxns;
206     //SAP_DMA_FTABLE_init ();
207     SAP_PORT_FTABLE_init ();
209     sapDrv.numDevices = 0;
210     SAP_initialized = 1;
212     return;
213 } // SAP_init
215 // -----------------------------------------------------------------------------
217 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
219     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
220     const SAP_Params *pParams;
221     Int result = SIO2_OK;
222     EDMA3_DRV_Handle    hEdma;
223     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
225     switch (code) {
227 /* .......................................................................... */
229         case PAF_SIO_CONTROL_MUTE:
230         case PAF_SIO_CONTROL_UNMUTE:
231             pParams = pDevExt->pParams;
232             if (pParams == NULL)
233                 return SIO2_OK;
235             if (pParams->sio.control != NULL)
236                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
237             break;
239 /* .......................................................................... */
241         case PAF_SIO_CONTROL_OPEN:
242             if (pDevExt->runState)
243                 return SIO2_EBUSY;
245             if (!( pParams = (const SAP_Params *) arg ))
246                 return SIO2_OK;
248             if (result = SAP_FTABLE_config (device, pParams))
249                 return result;
251             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
252                 return result;
254             break;
256 /* .......................................................................... */
258         case PAF_SIO_CONTROL_CLOSE:
259             if (pDevExt->runState)
260                 return SIO2_EBUSY;
262             if (pDevExt->pParams == NULL)
263                                 return SIO2_EINVAL;
265             pParams = pDevExt->pParams;
267                         if (pParams->sio.moduleNum == 0)
268                                 hEdma = hEdma0;
269                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
270                                 hEdma = hEdma1;
271             if (pDevExt->activeEdma != EDMA_HINV) {
272                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
273                             pDevExt->activeEdma = EDMA_HINV;
274                         }
276             if (!(pParams = pDevExt->pParams))
277                 return SIO2_OK;
279             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
280                 return result;
282             result = SAP_PORT_FTABLE_close (device);
283             if (result)
284                 return result;
286             pDevExt->pParams = NULL;
287             break;
289 /* .......................................................................... */
291         case PAF_SIO_CONTROL_GET_WORDSIZE:
292                 if (!arg)
293                                 return SIO2_EINVAL;
294                         *((int *) arg) = pDevExt->edmaWordSize;
295             break;
297         case PAF_SIO_CONTROL_SET_WORDSIZE:
298             // defer to DMA processing
299                 // currently only supported for input
300                         if (device->mode != DEV2_INPUT)
301                                 return SIO2_EINVAL;
303                         // can't be running
304                         if (pDevExt->runState)
305                                 return SIO2_EBUSY;
307                         // driver only supports 2 or 4 bytes
308                    if ((arg != 2) && (arg != 4))
309                                 return SIO2_EINVAL;
311                         // return success for unconfigured devices?
312                         if (!pDevExt->pParams)
313                                 return SIO2_OK;
315                         // ask platform if size is supported
316                         pParams = pDevExt->pParams;
317                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
318                                 return result;
320                         pDevExt->edmaWordSize = arg;
321                         break;
323         case PAF_SIO_CONTROL_GET_PRECISION:
324             if (arg == 0)
325                 return SIO2_EINVAL;
327             pParams = pDevExt->pParams;
328             if (pParams == NULL)
329                 return( SIO2_EINVAL );
331             *((int *) arg) = pParams->sio.precision;
332             break;
334         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
335             if (arg == 0)
336                 return SIO2_EINVAL;
338             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
339             break;
341         case PAF_SIO_CONTROL_SET_RATEX:
342             pParams = pDevExt->pParams;
343             if (pParams == NULL)
344                 return SIO2_OK ;
346             if (pParams->sio.control == NULL)
347                 return SIO2_EINVAL;
349             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
350             break;
352 /* .......................................................................... */
354         case PAF_SIO_CONTROL_IDLE:
355             pParams = pDevExt->pParams;
356             if (pParams == NULL)
357                 return SIO2_OK ;
359             if (pParams->sio.control == NULL)
360                 return SIO2_EINVAL;
362             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
363             break;
365         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
366             // 1. Here we are intentionally not using SIO_Idle() and
367             //    leaving the Tx clock running. We need this to avoid DAC noise,
368             //    as well as provide a DIT clock when using digital output.
369             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
370                 return SIO2_EINVAL;
372             pParams = pDevExt->pParams;
374             if (pParams->sio.moduleNum == 0)
375                 hEdma = hEdma0;
376             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
377                                 hEdma = hEdma1;
379             result = SAP_FTABLE_shutdown (device);
380             if (result)
381                 return result;
383             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
384             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
386 #if 1
387             //DJDBG, if below enableTransfer() is commented, input side continuous working.
388      if (pDevExt->activeEdma != EDMA_HINV) {
389                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
390             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
391             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
392      }
393 #endif
394             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
396             break;
398 /* .......................................................................... */
400         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
401             // needs to be attached
402             pParams = pDevExt->pParams;
403             if (pParams == NULL)
404                 return SIO2_OK;
406             if (pParams->sio.control == NULL)
407                 return SIO2_EINVAL;
409             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
410             break;
412         case PAF_SIO_CONTROL_WATCHDOG:
413             pParams = pDevExt->pParams;
414             if (pParams == NULL)
415                 return SIO2_OK;
416             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
417                 return result;
418             break;
419             
420 /* .......................................................................... */
422         // Timing stats specific to DMA engine
423         case PAF_SIO_CONTROL_ENABLE_STATS:
424         case PAF_SIO_CONTROL_DISABLE_STATS:
425         case PAF_SIO_CONTROL_GET_STATS:
426         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
427         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
428             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
429             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
430             break;
432 /* .......................................................................... */
434         case PAF_SIO_CONTROL_SET_DITSTATUS:
435             if(device->mode == DEV2_OUTPUT)
436             {
437                 const SAP_Params *pParams = pDevExt->pParams;
438                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
439                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
440                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
441                 int encSelect = *((int *) arg);
443                 // HACK -- determine DIT need by FXWID
444                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
445                 {
446                     if ( (encSelect == 0x13) ||
447                          (encSelect == 0xa)  || 
448                          (encSelect == 0x6)) // DTE, DDE, MPE 
449                     {
450                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
451                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
452                     }
453                     else
454                     {
455                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
456                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
457                     }
458                 }
460                 pParams = pDevExt->pParams;
461                 if (pParams == NULL)
462                     return SIO2_OK;
464                 if (pParams->sio.control != NULL)
465                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
466             }
467             break;
469 /* .......................................................................... */
471     }
473     return result;
474 } // SAP_ctrl
476 // -----------------------------------------------------------------------------
478 Int SAP_idle (DEV2_Handle device, Bool flush)
480     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
481     Int result = SIO2_OK;
482     EDMA3_DRV_Handle hEdma;
484     // do nothing if already idled or unattached
485     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
486         return result;
488         if (pDevExt->pParams->sio.moduleNum == 0)
489                 hEdma = hEdma0;
490         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
491                 hEdma = hEdma1;
493     // reset serial port -- stop generating sync events
494     result = SAP_PORT_FTABLE_reset (device);
495     if (result)
496     {
497         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
498         return result;
499     }
501     pDevExt->shutDown = 0; // force shutdown to run
502     result = SAP_FTABLE_shutdown (device);
503     if (result)
504     {
505         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
506         return result;
507     }
509     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
511     // disable interrupts and EDMA servicing
512    if (pDevExt->activeEdma != EDMA_HINV)
513            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
515     pDevExt->numQueued = 0;
517     // signal stopped
518     pDevExt->runState = 0;
520     // reset errorState
521     pDevExt->errorState = PAF_SIO_ERROR_NONE;
522     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
524     // place call to physical device
525     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
526         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
528     return result;
529 } // SAP_idle
531 // -----------------------------------------------------------------------------
533 Int SAP_start (DEV2_Handle device)
535     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
536     DEV2_Frame *pFrame;
537     int result;
538     EDMA3_DRV_Handle hEdma;
540     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
542     // signal we have started
543     //    we change the state here since we have already moved a frame from the 
544     //    todevice queue to the xferQue. If an error occurs during one of the 
545     //    following resets/enables then we need to have runState !=0 in order
546     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
547     //    do not (and are now required not to) depend on runState being 0.
548     //pDevExt->runState = 1;
549     // Assume todevice queue is not empty -- how else could we be here?
550     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
552     // inidicate this xfer did not use param entry - just the active one
553     pFrame->misc = NULL;
554     if (pDevExt->pParams->sio.moduleNum == 0)
555         hEdma = hEdma0;
556     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
557                 hEdma = hEdma1;
559     // non-atomic functions since not running yet.
560     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
562     // initialize count
563     pDevExt->numQueued = 1;
565     result = SAP_PORT_FTABLE_reset (device);
566     if (result)
567     {
568         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
569         return result;
570     }
572     // enable DMA processing
574     // config active xfer for this buffer
575     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
577     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
578       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
579         // signal we have started -- this must come before last enable to prevent a race
580         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
581         // and completes before any further instructions in this thread are executed.
582         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
583         // will be serviced and generate an interrupt even before the McASP is enabled.
584         pDevExt->runState = 1;
585         pDevExt->shutDown = 0;
586         //Log_info0 ("SAP_start runState=1 & ENABLE TRANSFERS");
587         // enable interrupts and event servicing for this channel
588         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
590     // enable peripheral
591     result = SAP_PORT_FTABLE_enable (device);
593     if (result)
594     {
595         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
596         return result;
597     }
599     return SIO2_OK;
600 } // SAP_start
602 int gDmaParamsarray[17][3];
603 int gDmaParamsidx=0;
604 // -----------------------------------------------------------------------------
606 Int SAP_issue (DEV2_Handle device)
608     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
609     DEV2_Frame *pFrame;
610     Int result;
611     SAP_EDMA_Param *pParam;
612     XDAS_UInt32 parentEdma;
614     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
616     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
617     {
618         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
619             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
620         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
621                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
622         return SIO2_EBADIO;
623     }
625     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
626         {
627                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
628             return SIO2_EBADIO;
629         }
631     // if not yet running then configure active xfer and start
632     if (pDevExt->runState == 0)
633         return (SAP_FTABLE_start(device));
635     // .........................................................................
636     // here if running
638     // disable device interrupts
639     // TODO: is there an API to just disable the IER bit for this tcc?
640     unsigned int key = Hwi_disable ();
641        /* determine parent EDMA
642           if no xfers in queue and we are running then must be in the
643           error state so link to active channel otherwise link to last
644           transfer queued.
645        */
647        /* here we assume after Tx SIO_idle or overrun, the user
648           will issue, at least, back-to-back issue requests so
649           there should be no problem here.
650        */
651        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
652            parentEdma = pDevExt->activeEdma;
653        else {
654            // if here then xferQue has more than one element so ok to use tail
655            // last scheduled transfer must be queue->prev
656            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
657            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
658        }
660     // get frame and parameter table to use; ints off => non-atomic OK
661     //     dont need to check for empty queues since were here then todevice
662     //     must have a frame placed there by the SIO_issue layer.
663     //     paramQue must be valid since it is accessed the same as todevice.
664     //     (indirectly -- isr places used items onto paramQue and fromdevice que
665     //      at the same time)
666     // set misc argument to pParam so get enqueue later
667     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
668     pFrame = Queue_dequeue (device->todevice);
669     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
671    /* if (pFrame->addr == NULL)
672                 SW_BREAKPOINT; */
673     if (pParam->hEdmaParam == NULL)
674         Log_info0("SAP_issue: hEdma value is NULL");
675     // set misc argument to pParam so get enqueue later
676     pFrame->misc = (Arg) pParam;
678     // place on holder queue, ints off => non-atomic OK
679     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
680     if (pFrame->addr) {
681                 if (device->mode == DEV2_INPUT)
682                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
683                 else
684                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
685         }
687     // increment count
688     pDevExt->numQueued += 1;
690     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
691     //Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
692     //                __LINE__, pParam->hEdma, parentEdma, pDevExt->errorEdma);
694     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
695         {
696         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
697                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
698                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
699         } */
701         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
702                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
704         pDevExt->shutDown = 0;
706     // special case enables when not yet started
707     if (pDevExt->runState == 0) {
708         result = SAP_FTABLE_start (device);
709         if (result) {
710             //SAP_DMA_FTABLE_unlock (device);
711                   Hwi_enable ();
712             return result;
713         }
714     }
715     Hwi_restore (key); //DJDBG
717     return result;
718 } // SAP_issue
720 // -----------------------------------------------------------------------------
722 void swapHdmi(Ptr Input, int size)
725         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
726         MdInt *p1, *p2;
727         int i=0;
729         for (i=0; i< size; i+=16)
730         {
731                         p1 = (MdInt *)&Input[i];
732                         p2 = p1;
734                         L0 = *p1++;
735                         L1 = *p1++;
736                         L2 = *p1++;
737                         L3 = *p1++;
738                         R0 = *p1++;
739                         R1 = *p1++;
740                         R2 = *p1++;
741                         R3 = *p1++;
743                         *p2++ = L0;
744                         *p2++ = R0;
745                         *p2++ = L1;
746                         *p2++ = R1;
747                         *p2++ = L2;
748                         *p2++ = R2;
749                         *p2++ = L3;
750                         *p2++ = R3;
752         }
754         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (MdInt *)Input, p1, p2);
756         /**p2++ = 0xF872;
757         *p2++ = 0x4E1F;
758         *p2++ = 0x0016;
759         *p2++ = 0xEFF0;
760         *p2++ = 0x079E;
761         *p2++ = 0x0003;
762         *p2++ = 0x8401;
763         *p2++ = 0x0101; */
765         return;
768 Int SAP_reclaim (DEV2_Handle device)
770     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
771     Int result, i, oldMask;
772 #ifdef SAP_CACHE_SUPPORT
773     DEV2_Frame *pFrame;
774 #endif
776     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
778     // must be running and  error free 
779     if ((!pDevExt->runState) || (pDevExt->errorState))
780     {
781         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
782         return SIO2_EBADIO;
783     }
785     // idle if necessary
786         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
787             DEV2_idle (device, 1);
788             return SIO2_EBADIO;
789         }
791        // Log_info0("SAP_reclaim: Before SEM Pend");
793     // wait for ISR to signal block completion
794     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
795     if (!Semaphore_pend(pDevExt->sync, device->timeout))
796     {
797         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
798         return SIO2_ETIMEOUT;
799     }
800     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
802     // return error (owner must idle)
803     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
804     {
805         DEV2_idle (device, 1);
806         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
807         return PAF_SIO_ERROR_FATAL;
808     }
810 #ifdef SAP_CACHE_SUPPORT
811     // invalidate CACHE region if input -- use clean since
812     //    Dont clean if was for fill.
813     // since pend returned we know that head of fromdevice is valid
814     pFrame = Queue_head (device->fromdevice);
815     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
816     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
817     {
818         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
819         {
820             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
821             Cache_wait();
822                 //note: size here is in # of bytes, so incrementing by 4X32b words ( or 8X16b)
823                         //for(i=0; i<(pFrame->size)/(4*4); i+=16)
824                         //{
825                 oldMask = Hwi_disable ();
826                                 swapHdmi(pFrame->addr, pFrame->size);
827                                 Hwi_restore(oldMask);
829                         Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
830                         Cache_wait();
831                         //}
832         }
833     }
835 #endif
836     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
837         SW_BREAKPOINT; */
839     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
840     return SIO2_OK;
841 } // SAP_reclaim
844 // -----------------------------------------------------------------------------
846 Int SAP_open (DEV2_Handle device, String name)
848     SAP_DeviceExtension   *pDevExt;
849     DEV2_Device            *entry;
850     Int                    oldMask, result;
851     Error_Block                         eb;
852     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
854     // check SIO mode 
855     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
856         return SIO2_EMODE;
858     // allocate memory for device extension
859     device->object = NULL;
860     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
861     if (pDevExt == NULL)
862     {
863         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
864         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
865         asm( " SWBP 0" );  // SW Breakpoint
866         return SIO2_EALLOC;
867     }
868     device->object = (Ptr)pDevExt;
870     // inits
871     pDevExt->device = device;
872     pDevExt->sync = NULL;
873     pDevExt->pParams = NULL;
874     pDevExt->runState = 0;  // not yet started
875     pDevExt->errorState = PAF_SIO_ERROR_NONE;
876     pDevExt->shutDown = 1;
877     pDevExt->numQueued = 0;
878     pDevExt->activeEdma = EDMA_HINV;
879     pDevExt->errorEdma = EDMA_HINV;
880     pDevExt->firstTCC = 0;
881     pDevExt->optLevel = 0;
882     pDevExt->numParamSetup = 0;
883     pDevExt->numEdmaParams = 4;
885     // use dev match to fetch function table pointer for SAP
886     DEV2_match(SAP_NAME, &entry);
887     if (entry == NULL) {
888         Log_error1("SAP", SIO2_ENODEV);
889         return SIO2_ENODEV;
890     }
891     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
893     // create semaphore for device
894     pDevExt->sync = Semaphore_create (0, NULL, NULL);
895     if (pDevExt->sync == NULL)
896     {
897         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
898         return SIO2_EALLOC;
899     }
901     // queue inits
902     Queue_construct (&pDevExt->xferQue, NULL);
903     Queue_construct (&pDevExt->paramQue, NULL);
905     // update driver global (need to protect context)
906     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
907     {
908         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
909             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
910         SW_BREAKPOINT;
911     }
912     oldMask = Hwi_disable ();
913     sapDrv.device[sapDrv.numDevices] = device;
914     pDevExt->deviceNum = sapDrv.numDevices++;
915     Hwi_restore (oldMask);
917     // PORT init
918     result = SAP_PORT_FTABLE_open (device);
919     if (result)
920     {
921         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
922         return result;
923     }
925     return result;
926 } // SAP_open
928 // -----------------------------------------------------------------------------
930 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
932     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
933     Int                  result, Que_num, i;
934     EDMA3_DRV_Result     edmaResult;
935     Uint32                                      reqTcc;
936     EDMA3_DRV_Handle    hEdma;
937     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
939     // cannot configure if transfer started
940     if (pDevExt->runState == 1)
941         return SIO2_EBADIO;
943     // save pointer to config structure in device extension. here so that
944     //   forthcoming functions can use/modify config structure.
945     pDevExt->pParams = pParams;
946     pDevExt->edmaWordSize = pParams->sio.wordSize;
948     // allocate Port resources.
949     //    This must come before DMA configuration
950     result = SAP_PORT_FTABLE_alloc (device);
951     if (result)
952     {
953         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
954         return result;
955     }
957     // .............................................................................
958     // EDMA configuration
960     // DA10x McASP0 Specific
961     if (pParams->sio.moduleNum == 0)
962     {
963         hEdma = hEdma0;
964         if (device->mode == DEV2_INPUT)
965         {
966                 Que_num = 0;
967                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
968         }
969         else
970         {
971                 Que_num = 1;
972                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
973         }
974     }
975     // DA10x McASP1 Specific
976     else if (pParams->sio.moduleNum == 1)
977     {
978         hEdma = hEdma1;
979         if (device->mode == DEV2_INPUT)
980                 {
981                 Que_num = 0;
982                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
983                 }
984                 else
985                 {
986                         Que_num = 1;
987                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
988                 }
989     }
990     // DA10x McASP2 Specific
991     else if (pParams->sio.moduleNum == 2)
992     {
993         hEdma = hEdma1;
994         if (device->mode == DEV2_INPUT)
995                 {
996                         Que_num = 0;
997                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
998                 }
999                 else
1000                 {
1001                         Que_num = 1;
1002                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1003                 }
1004     }
1007     for (i=0; i < pDevExt->numEdmaParams; i++) {
1009         reqTcc = EDMA3_DRV_TCC_ANY;
1010         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1011         edmaResult = EDMA3_DRV_requestChannel (
1012                 hEdma,
1013             &pDevExt->edmaParams[i].hEdmaParam,
1014             &reqTcc,
1015             (EDMA3_RM_EventQueue) Que_num,
1016             SAP_isrCallback,
1017             (void *) device);
1019         if (edmaResult != EDMA3_DRV_SOK)
1020             return SIO2_EALLOC;
1022         //not running => can use non-atomic functions
1023         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1025     }
1027     reqTcc = EDMA3_DRV_TCC_ANY;
1028         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1029         edmaResult = EDMA3_DRV_requestChannel (
1030             hEdma,
1031             &pDevExt->errorEdma,
1032             &reqTcc,
1033             (EDMA3_RM_EventQueue)Que_num,
1034             SAP_isrCallback,
1035             (void *) device);
1036         if (edmaResult != EDMA3_DRV_SOK)
1037             return SIO2_EALLOC;
1039         // allocate edma channel -- also disable and clear the interrupt
1042         pDevExt->firstTCC = pDevExt->activeEdma ;
1043         edmaResult = EDMA3_DRV_requestChannel (
1044                 hEdma,
1045                 &pDevExt->activeEdma,
1046                 &pDevExt->firstTCC,
1047                 (EDMA3_RM_EventQueue) 0,
1048                 SAP_isrCallback,
1049                 (void *) device);
1050         if (edmaResult != EDMA3_DRV_SOK)
1051                     {
1052                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1053                         return SIO2_EALLOC;
1054                     }
1056         // Configure error transfer
1057         //   make cnt same as # of channels in order to maintain alignment
1058         //   and the error transfer small so that we never have to wait
1059         //   long for it to complete and trigger a linked transfer. This is
1060         //   important for establishing output timing when we are idling with
1061         //   clocks still running. Is fine for Rx as well.
1062         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1064         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1066     return SIO2_OK;
1067 } // SAP_config
1069 // -----------------------------------------------------------------------------
1071 Int SAP_shutdown (DEV2_Handle device)
1073     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1074     SIO2_Handle stream = (SIO2_Handle) device;
1075     DEV2_Frame *pFrame;
1076     Int result,i;
1077     EDMA3_DRV_Handle hEdma;
1078     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1080     if (pDevExt->shutDown)
1081         return SIO2_EBADIO;
1083     if (pDevExt->pParams == NULL)
1084         return SIO2_EINVAL;
1086     if (pDevExt->pParams->sio.moduleNum == 0)
1087         hEdma = hEdma0;
1088     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1089         hEdma = hEdma1;
1090     if (pDevExt->activeEdma != EDMA_HINV)
1091         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1093     // reset queues
1094     while (!Queue_empty(device->todevice)) {
1095        // place oustanding requests onto holding queue
1096        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1097        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1098     }
1100     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1101         // pull frame from holding queue and place on user queue
1102         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1103         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1104     }
1107     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1108         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1110     // not running => can use non-atomic functions
1111     for (i=0; i < pDevExt->numEdmaParams; i++)
1112         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1114     // reset counter
1115     pDevExt->numQueued = 0;
1117     // make sure active is linked to error
1118         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1120     // think this is better (from SIO_idle for standard model )
1121     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1122     while (!Queue_empty(device->fromdevice)) {
1123         /* place oustanding requests onto holding queue */
1124         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1125         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1126     }
1127     Semaphore_reset (pDevExt->sync, 0);
1128     
1129     pDevExt->shutDown = 1;
1130     pDevExt->numParamSetup = 0;
1131     
1132     /*result = SAP_DMA_FTABLE_unlock (device);
1133     if (result)
1134     {
1135         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1136         return result;
1137     } */
1139     return SIO2_OK;
1140 } // SAP_shutdown
1142 // -----------------------------------------------------------------------------
1143 int gSapWatchDogThrottle = 0; //DJDBG
1144 Void SAP_watchDog (Void)
1146     DEV2_Handle device;
1147     SAP_DeviceExtension *pDevExt;
1148     int i, oldMask, result;
1150     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1152     // do nothing if SAP_init not yet called
1153     if (!SAP_initialized)
1154     {
1155         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1156         return;
1157     }
1159     // protect context
1160     Task_disable (); // needed since we may call SEM_post
1161     oldMask = Hwi_disable ();
1163     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1165     for (i=0; i < sapDrv.numDevices; i++) {
1166         device  = sapDrv.device[i];
1168         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1170         pDevExt = (SAP_DeviceExtension *) device->object;
1172         // do nothing if not running
1173         if (!pDevExt->runState)
1174             continue;
1176         // call board specific watchdog
1177         // TODO: handle return value
1178         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1179         
1180         // if port layer returns error then must need to clean up
1181         result = SAP_PORT_FTABLE_watchDog (device);
1182         if (result) {
1183             // set errorState which will force owner thread
1184             //   to clean up via SIO_idle()
1185             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1186             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1187            /* if(gSapWatchDogThrottle == 0) //DJDBG
1188             {
1189                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1190             }
1191             gSapWatchDogThrottle ++;
1192             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1193             // if outstanding pend then post to free owner thead
1194             if (!Semaphore_pend(pDevExt->sync, 0))
1195                 Semaphore_post (pDevExt->sync);
1196         }
1197     }
1199     // renable interrupts and task manager.
1200     // If we posted to the semaphore then the TSK_enable call will lead to
1201     // an immediate task switch to the associated audio thread.
1202     Hwi_restore (oldMask);
1203     Task_enable ();
1205 } // SAP_watchDog
1207 // -----------------------------------------------------------------------------
1208 // Assumes that EDMA3 dispatcher handles TCC clearing.
1210 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1212     DEV2_Handle                 device;
1213     SAP_DeviceExtension       *pDevExt;
1214     DEV2_Frame                 *pFrame;
1215     unsigned int               opt;
1216     EDMA3_DRV_Handle                    hEdma;
1218     // could be here after Tx idle/overrun and this is the interrupt
1219     // for the last occuring error transfer so there is no transfer
1220     // to release, we just clear the int and exit.
1222     device = (DEV2_Handle) context;
1223     pDevExt = (SAP_DeviceExtension *)(device->object);
1224     if (pDevExt->pParams == NULL)
1225         return SIO2_EINVAL;
1227     if (pDevExt->pParams->sio.moduleNum == 0)
1228         hEdma = hEdma0;
1229     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1230         hEdma = hEdma1;
1232     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1233         // if here then an interrupt occured due to errorEdma or valid
1234         // transfer, we assume the xfer is long enough so it will not complete
1235         // before we are finished here.
1237         // if last transfer was valid then complete it
1238         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1240             // pull frame from holding queue
1241             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1243             // if used param entry then return it to queue
1244             if (pFrame->misc != NULL)
1245             {
1246                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1247                 if (device->mode == 1)
1248                         gisrOutput+=100;
1249             }
1251             // decrement count
1252             pDevExt->numQueued -= 1;
1253             gIsrCnt++;
1254             if (device->mode == 1)
1255                 gisrOutput++;
1257             // place frame onto user queue and signal user thread
1258             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1260             Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1261             // signal user thread
1262             Semaphore_post (pDevExt->sync);
1263 #if 0
1264             if(gIsrCnt > 10) { //DJDBG
1265                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1267             }
1268 #endif
1269         }
1270         else
1271                 gIsrElseCnt++;
1273         // determine if currently transferring buffer is valid based on interrupt enable bit
1274         // only valid transfers will generate interrupts
1275         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1277         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1278         {
1279                 gIsrErrCnt++;
1280                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1281         }
1283     } // runState
1284     else
1285     {
1286                 if (pDevExt->runState != 1)
1287                         gIsrRunCnt++;
1288                 else
1289                         gIsrNotRunCnt++;
1290     }
1292     return;
1293 } //SAP_isrCallback
1295 // -----------------------------------------------------------------------------
1297 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1299     EDMA3_DRV_Handle            hEdma;
1300     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1301 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1303         if (pDevExt->pParams == NULL)
1304                 return SIO2_EINVAL;
1306             if (pDevExt->pParams->sio.moduleNum == 0)
1307                 hEdma = hEdma0;
1308             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1309                 hEdma = hEdma1;
1311     // TODO: shouldn't this just be tcc interrupt disable?
1312     // at least until linkage phase...
1313     unsigned int key = Hwi_disable (); //DJDBG
1315     if(targetEdma == NULL)
1316     {
1317         Log_info0("targetEdma is NULL");
1318     }
1319     // configure transfer
1320     if(pFrame->addr == NULL) //DJDBG
1321     {
1322         Log_info0("pFrame has NULL address?");
1323     }
1324     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, pFrame->addr, pFrame->size);
1326     if (parentEdma != EDMA_HINV)
1327         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1330     Hwi_restore (key); //DJDBG
1332     return SIO2_OK;
1333 } // SAP_setupXfer
1335 // -----------------------------------------------------------------------------
1336 // Configure EDMA3 parameter entry
1338 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, unsigned int addr, unsigned int size)
1340     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1341     EDMA3_DRV_Handle            hEdma;
1342     EDMA3_DRV_PaRAMRegs  edmaConfig;
1344     if (pDevExt->pParams == NULL)
1345                 return SIO2_EINVAL;
1347         if (pDevExt->pParams->sio.moduleNum == 0)
1348                 hEdma = hEdma0;
1349         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1350                 hEdma = hEdma1;
1351     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1352     volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1354    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1356     // Init opt parameter to 0 which, without being overriden, configures as:
1357     //    A synchronized transfer (no FIFO mode on src or dst)
1358     //    no chaining or intermediate interrupts
1359     //    param is not static
1360     //    normal completion
1361     //    don't generate an interrupt (overriden below for regular xfers)
1362     edmaConfig.opt = 0;
1364     // not transferring blocks so c index is 0
1365     edmaConfig.destCIdx = 0;
1366     edmaConfig.srcCIdx = 0;
1368     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1369     if (device->mode == DEV2_OUTPUT) {
1370       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1371       edmaConfig.opt |= 2;
1372     }
1373     else {
1374         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1375         //edmaConfig.opt |= 1;
1376     }
1378     // if regular transfer then enable interrupt with tcc code
1379     if (targetEdma != pDevExt->errorEdma) {
1380         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1381         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1382         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1383     }
1386     edmaConfig.aCnt = 4;
1387         edmaConfig.bCnt = pDevExt->numSers;
1388         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1389     edmaConfig.bCntReload = edmaConfig.bCnt;
1392     // handle direction specific requirements
1393     if (device->mode == DEV2_INPUT) {
1394         edmaConfig.srcBIdx  = 0;
1395                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1397         if (addr) {
1398             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1399             edmaConfig.destAddr = addr;
1400             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1401             if(pDevExt->edmaWordSize == 2)
1402                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);        // GJ: Account for additional 2-bytes.
1403         }
1404         else {
1405                 //if(pDevExt->edmaWordSize == 2)
1406                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1407             edmaConfig.destBIdx = 0;
1408             edmaConfig.destAddr = (unsigned int) &sap_OVER;
1409         }
1410     }
1411     else {
1412         edmaConfig.destBIdx = 0;
1413         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1415         if (addr) {
1416             edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1417             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1418             edmaConfig.srcAddr  = addr;
1419             Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1420         }
1421         else {
1422             edmaConfig.srcBIdx  = 0;
1423             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1424 #if 1
1425             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1426             edmaConfig.cCnt = 512; //DJDBG, if underrun have frame of silence
1427 #endif
1428         }
1429     }
1430     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1431     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1433     //Log_info3("SAP: Inside SAP_EDMA_setupParam with targetEdma = 0x%x linked to childEdma = 0x%x & dest-addr: 0x%x", targetEdma, childEdma, edmaConfig.destAddr);
1435     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1437     // link child xfer
1438     if (childEdma != EDMA_HINV)
1439         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1441     return SIO2_OK;
1442 } //SAP_setupParam