Updates for PASDK-53
[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 gIsrInputCnt;
89 int gIsrOutputCnt;
90 int gIsrElseCnt;
91 int gIsrInErrCnt;
92 int gIsrOutErrCnt;
93 int gIsrRunCnt;
94 int gIsrNotRunCnt;
95 int gisrOutput;
96 int gSAPResetIn;
97 int gSAPResetOut;
99 typedef xdc_Short MdInt;
101 void swapHdmi(Ptr, int);
103 //#define TEST_MULTICHANNEL
106 #ifdef TEST_MULTICHANNEL
107 #define SAP_UNDER_LEN 16
108 //#define SAP_UNDER_LEN 1024 // GJ: experiment
109 #else
110 #define SAP_UNDER_LEN 1024
111 #endif
112 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
113 int sap_OVER = 0;     // used for overrun
115 #ifdef DEBUG
116 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
118         unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
119         unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
120         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
122         Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
123         Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
125         Log_info5("PARAM0x19a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[0], ptrPARAM0x19[1], ptrPARAM0x19[2], ptrPARAM0x19[3]);
126         Log_info5("PARAM0x19b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[4], ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
127     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
129 #endif
130 // .............................................................................
131 // notes:
132 //  . add control function to PORT table
133 //  . how to handle DMA/PORT specifics in parameter entries
134 //      can assume numSers = numChans is general and can be applied by DMA
135 //      same for wordSize?
136 //  . why are two idle stages needed (seems like 1 is enough)?
138 // .............................................................................
139 // only one global variable, not static so that DMA and port functions
140 // can access. We cant just store the address in devExt since the ISR has
141 // no context.
143 SAP_DriverObject sapDrv;
145 // needed since SAP_watchDog is called before SAP_init
146 Int SAP_initialized = 0;
148 //Int  SAP_close(DEV2_Handle);
149 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
150 Int  SAP_idle(DEV2_Handle, Bool);
151 Int  SAP_issue(DEV2_Handle);
152 Int  SAP_open(DEV2_Handle, String);
153 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
154 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
155 Int  SAP_reclaim(DEV2_Handle);
156 Int  SAP_shutdown(DEV2_Handle);
157 Int  SAP_start(DEV2_Handle);
158 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
159 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
160 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
162 // .............................................................................
164 // .............................................................................
166 SAP_DMA_Fxns SAP_EDMA_FXNS =
168         SAP_EDMA_setupParam,
169         SAP_EDMA_setupXfer,
170 };
173 SAP_Fxns SAP_FXNS =
175     NULL, //SAP_close, -- remove for IROM since not using
176     SAP_ctrl,
177     SAP_idle,
178     SAP_issue,
179     SAP_open,
180     NULL, //SAP_ready, -- remove for IROM since not using
181     SAP_reclaim,
182     SAP_shutdown,
183     SAP_start,
184     SAP_config,
186 #ifdef SAP_PORT_MCASP
187     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
188 #endif
189 #ifdef SAP_DMA_EDMA
190     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
191 #endif
192 };
194 // -----------------------------------------------------------------------------
195 // This function is not in the driver function table.
196 // Must be pointed at in GUI config tool.
197 //
198 Void SAP_init (Void)
200     DEV2_Device  *entry;
201     SAP_Fxns    *pFxns;
203     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
205     // find function table pointer (used by SAP_XX_FTABLE_init macros)
206     DEV2_match(SAP_NAME, &entry);
207     if (entry == NULL) {
208         Log_error1 ("SAP", SIO2_ENODEV);
209         return;
210     }
211     pFxns = (SAP_Fxns *) entry->fxns;
213     //SAP_DMA_FTABLE_init ();
214     SAP_PORT_FTABLE_init ();
216     sapDrv.numDevices = 0;
217     SAP_initialized = 1;
219     return;
220 } // SAP_init
222 // -----------------------------------------------------------------------------
224 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
226     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
227     const SAP_Params *pParams;
228     Int result = SIO2_OK;
229     EDMA3_DRV_Handle    hEdma;
230     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
232     switch (code) {
234 /* .......................................................................... */
236         case PAF_SIO_CONTROL_MUTE:
237         case PAF_SIO_CONTROL_UNMUTE:
238             pParams = pDevExt->pParams;
239             if (pParams == NULL)
240                 return SIO2_OK;
242             if (pParams->sio.control != NULL)
243                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
244             break;
246 /* .......................................................................... */
248         case PAF_SIO_CONTROL_OPEN:
249             if (pDevExt->runState)
250                 return SIO2_EBUSY;
252             if (!( pParams = (const SAP_Params *) arg ))
253                 return SIO2_OK;
255             if (result = SAP_FTABLE_config (device, pParams))
256                 return result;
258             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
259                 return result;
261             break;
263 /* .......................................................................... */
265         case PAF_SIO_CONTROL_CLOSE:
266             if (pDevExt->runState)
267                 return SIO2_EBUSY;
269             if (pDevExt->pParams == NULL)
270                                 return SIO2_EINVAL;
272             pParams = pDevExt->pParams;
274                         if (pParams->sio.moduleNum == 0)
275                                 hEdma = hEdma0;
276                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
277                                 hEdma = hEdma1;
278             if (pDevExt->activeEdma != EDMA_HINV) {
279                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
280                             pDevExt->activeEdma = EDMA_HINV;
281                         }
283             if (!(pParams = pDevExt->pParams))
284                 return SIO2_OK;
286             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
287                 return result;
289             result = SAP_PORT_FTABLE_close (device);
290             if (result)
291                 return result;
293             pDevExt->pParams = NULL;
294             break;
296 /* .......................................................................... */
298         case PAF_SIO_CONTROL_GET_WORDSIZE:
299                 if (!arg)
300                                 return SIO2_EINVAL;
301                         *((int *) arg) = pDevExt->edmaWordSize;
302             break;
304         case PAF_SIO_CONTROL_SET_WORDSIZE:
305             // defer to DMA processing
306                 // currently only supported for input
307                         if (device->mode != DEV2_INPUT)
308                                 return SIO2_EINVAL;
310                         // can't be running
311                         if (pDevExt->runState)
312                                 return SIO2_EBUSY;
314                         // driver only supports 2 or 4 bytes
315                    if ((arg != 2) && (arg != 4))
316                                 return SIO2_EINVAL;
318                         // return success for unconfigured devices?
319                         if (!pDevExt->pParams)
320                                 return SIO2_OK;
322                         // ask platform if size is supported
323                         pParams = pDevExt->pParams;
324                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
325                                 return result;
327                         pDevExt->edmaWordSize = arg;
328                         break;
330         case PAF_SIO_CONTROL_GET_PRECISION:
331             if (arg == 0)
332                 return SIO2_EINVAL;
334             pParams = pDevExt->pParams;
335             if (pParams == NULL)
336                 return( SIO2_EINVAL );
338             *((int *) arg) = pParams->sio.precision;
339             break;
341         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
342             if (arg == 0)
343                 return SIO2_EINVAL;
345             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
346             break;
348         case PAF_SIO_CONTROL_SET_RATEX:
349             pParams = pDevExt->pParams;
350             if (pParams == NULL)
351                 return SIO2_OK ;
353             if (pParams->sio.control == NULL)
354                 return SIO2_EINVAL;
356             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
357             break;
359 /* .......................................................................... */
361         case PAF_SIO_CONTROL_IDLE:
362             pParams = pDevExt->pParams;
363             if (pParams == NULL)
364                 return SIO2_OK ;
366             if (pParams->sio.control == NULL)
367                 return SIO2_EINVAL;
369             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
370             break;
372         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
373             // 1. Here we are intentionally not using SIO_Idle() and
374             //    leaving the Tx clock running. We need this to avoid DAC noise,
375             //    as well as provide a DIT clock when using digital output.
376             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
377                 return SIO2_EINVAL;
379             pParams = pDevExt->pParams;
381             if (pParams->sio.moduleNum == 0)
382                 hEdma = hEdma0;
383             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
384                                 hEdma = hEdma1;
386             result = SAP_FTABLE_shutdown (device);
387             if (result)
388                 return result;
390             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
391             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
393 #if 1
394             //DJDBG, if below enableTransfer() is commented, input side continuous working.
395      if (pDevExt->activeEdma != EDMA_HINV) {
396                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
397             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
398             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
399      }
400 #endif
401             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
403             break;
405 /* .......................................................................... */
407         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
408             // needs to be attached
409             pParams = pDevExt->pParams;
410             if (pParams == NULL)
411                 return SIO2_OK;
413             if (pParams->sio.control == NULL)
414                 return SIO2_EINVAL;
416             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
417             break;
419         case PAF_SIO_CONTROL_WATCHDOG:
420             pParams = pDevExt->pParams;
421             if (pParams == NULL)
422                 return SIO2_OK;
423             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
424                 return result;
425             break;
426             
427 /* .......................................................................... */
429         // Timing stats specific to DMA engine
430         case PAF_SIO_CONTROL_ENABLE_STATS:
431         case PAF_SIO_CONTROL_DISABLE_STATS:
432         case PAF_SIO_CONTROL_GET_STATS:
433         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
434         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
435             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
436             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
437             break;
439 /* .......................................................................... */
441         case PAF_SIO_CONTROL_SET_DITSTATUS:
442             if(device->mode == DEV2_OUTPUT)
443             {
444                 const SAP_Params *pParams = pDevExt->pParams;
445                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
446                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
447                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
448                 int encSelect = *((int *) arg);
450                 // HACK -- determine DIT need by FXWID
451                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
452                 {
453                     if ( (encSelect == 0x13) ||
454                          (encSelect == 0xa)  || 
455                          (encSelect == 0x6)) // DTE, DDE, MPE 
456                     {
457                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
458                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
459                     }
460                     else
461                     {
462                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
463                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
464                     }
465                 }
467                 pParams = pDevExt->pParams;
468                 if (pParams == NULL)
469                     return SIO2_OK;
471                 if (pParams->sio.control != NULL)
472                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
473             }
474             break;
476 /* .......................................................................... */
478     }
480     return result;
481 } // SAP_ctrl
483 int gSAPIdleShutdownIn=0;
484 int gSAPIdleShutdownOut=0;
486 // -----------------------------------------------------------------------------
488 Int SAP_idle (DEV2_Handle device, Bool flush)
490     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
491     Int result = SIO2_OK;
492     EDMA3_DRV_Handle hEdma;
494     // do nothing if already idled or unattached
495     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
496         return result;
498         if (pDevExt->pParams->sio.moduleNum == 0)
499                 hEdma = hEdma0;
500         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
501                 hEdma = hEdma1;
503     // reset serial port -- stop generating sync events
504     result = SAP_PORT_FTABLE_reset (device);
505     if(device->mode == DEV2_OUTPUT)
506         gSAPResetOut++;
507     else
508         gSAPResetIn++;
509     if (result)
510     {
511         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
512         return result;
513     }
515     pDevExt->shutDown = 0; // force shutdown to run
516     result = SAP_FTABLE_shutdown (device);
517     if(device->mode == DEV2_OUTPUT)
518         gSAPIdleShutdownOut++;
519     else
520         gSAPIdleShutdownIn++;
522     if (result)
523     {
524         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
525         return result;
526     }
528     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
530     // disable interrupts and EDMA servicing
531    if (pDevExt->activeEdma != EDMA_HINV)
532            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
534     pDevExt->numQueued = 0;
536     // signal stopped
537     pDevExt->runState = 0;
539     // reset errorState
540     pDevExt->errorState = PAF_SIO_ERROR_NONE;
541     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
543     // place call to physical device
544     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
545         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
547     return result;
548 } // SAP_idle
550 // -----------------------------------------------------------------------------
552 Int SAP_start (DEV2_Handle device)
554     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
555     DEV2_Frame *pFrame;
556     int result;
557     EDMA3_DRV_Handle hEdma;
559     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
561     // signal we have started
562     //    we change the state here since we have already moved a frame from the 
563     //    todevice queue to the xferQue. If an error occurs during one of the 
564     //    following resets/enables then we need to have runState !=0 in order
565     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
566     //    do not (and are now required not to) depend on runState being 0.
567     //pDevExt->runState = 1;
568     // Assume todevice queue is not empty -- how else could we be here?
569     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
571     // inidicate this xfer did not use param entry - just the active one
572     pFrame->misc = NULL;
573     if (pDevExt->pParams->sio.moduleNum == 0)
574         hEdma = hEdma0;
575     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
576                 hEdma = hEdma1;
578     // non-atomic functions since not running yet.
579     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
581     // initialize count
582     pDevExt->numQueued = 1;
584     result = SAP_PORT_FTABLE_reset (device);
585     if (result)
586     {
587         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
588         return result;
589     }
591     // enable DMA processing
593     // config active xfer for this buffer
594     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
596     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
597       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
598         // signal we have started -- this must come before last enable to prevent a race
599         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
600         // and completes before any further instructions in this thread are executed.
601         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
602         // will be serviced and generate an interrupt even before the McASP is enabled.
603         pDevExt->runState = 1;
604         pDevExt->shutDown = 0;
605         //Log_info0 ("SAP_start runState=1 & ENABLE TRANSFERS");
606         // enable interrupts and event servicing for this channel
607         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
609     // enable peripheral
610     result = SAP_PORT_FTABLE_enable (device);
612     if (result)
613     {
614         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
615         return result;
616     }
618     return SIO2_OK;
619 } // SAP_start
621 int gDmaParamsarray[17][3];
622 int gDmaParamsidx=0, gSAPSpecialCase=0;
623 // -----------------------------------------------------------------------------
625 Int SAP_issue (DEV2_Handle device)
627     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
628     DEV2_Frame *pFrame;
629     Int result;
630     SAP_EDMA_Param *pParam;
631     XDAS_UInt32 parentEdma;
633     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
635     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
636     {
637         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
638             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
639         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
640                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
641         return SIO2_EBADIO;
642     }
644     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
645         {
646                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
647             return SIO2_EBADIO;
648         }
650     // if not yet running then configure active xfer and start
651     if (pDevExt->runState == 0)
652         return (SAP_FTABLE_start(device));
654     // .........................................................................
655     // here if running
657     // disable device interrupts
658     // TODO: is there an API to just disable the IER bit for this tcc?
659     unsigned int key = Hwi_disable ();
660        /* determine parent EDMA
661           if no xfers in queue and we are running then must be in the
662           error state so link to active channel otherwise link to last
663           transfer queued.
664        */
666        /* here we assume after Tx SIO_idle or overrun, the user
667           will issue, at least, back-to-back issue requests so
668           there should be no problem here.
669        */
670        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
671            parentEdma = pDevExt->activeEdma;
672        else {
673            // if here then xferQue has more than one element so ok to use tail
674            // last scheduled transfer must be queue->prev
675            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
676            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
677        }
679     // get frame and parameter table to use; ints off => non-atomic OK
680     //     dont need to check for empty queues since were here then todevice
681     //     must have a frame placed there by the SIO_issue layer.
682     //     paramQue must be valid since it is accessed the same as todevice.
683     //     (indirectly -- isr places used items onto paramQue and fromdevice que
684     //      at the same time)
685     // set misc argument to pParam so get enqueue later
686     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
687     pFrame = Queue_dequeue (device->todevice);
688     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
690     if (pParam->hEdmaParam == NULL)
691         Log_info0("SAP_issue: hEdma value is NULL");
692     // set misc argument to pParam so get enqueue later
693     pFrame->misc = (Arg) pParam;
695     // place on holder queue, ints off => non-atomic OK
696     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
697     if (pFrame->addr) {
698                 if (device->mode == DEV2_INPUT)
699                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
700                 else
701                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
702         }
704     // increment count
705     pDevExt->numQueued += 1;
707     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
708     //Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
709     //                __LINE__, pParam->hEdma, parentEdma, pDevExt->errorEdma);
711     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
712         {
713         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
714                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
715                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
716         } */
718         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
719                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
721         pDevExt->shutDown = 0;
723     // special case enables when not yet started
724     if (pDevExt->runState == 0) {
725         gSAPSpecialCase++;
726         result = SAP_FTABLE_start (device);
727         if (result) {
728             //SAP_DMA_FTABLE_unlock (device);
729                   Hwi_restore (key);
730             return result;
731         }
732     }
733     Hwi_restore (key); //DJDBG
735     return result;
736 } // SAP_issue
738 // -----------------------------------------------------------------------------
740 void swapHdmi(Ptr Input, int size)
743         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
744         MdInt *p1, *p2;
745         int i=0;
747         for (i=0; i< size; i+=16)
748         {
749                         p1 = (MdInt *)&Input[i];
750                         p2 = p1;
752                         L0 = *p1++;
753                         L1 = *p1++;
754                         L2 = *p1++;
755                         L3 = *p1++;
756                         R0 = *p1++;
757                         R1 = *p1++;
758                         R2 = *p1++;
759                         R3 = *p1++;
761                         *p2++ = L0;
762                         *p2++ = R0;
763                         *p2++ = L1;
764                         *p2++ = R1;
765                         *p2++ = L2;
766                         *p2++ = R2;
767                         *p2++ = L3;
768                         *p2++ = R3;
770         }
772         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, p1, p2);
774         return;
777 Int SAP_reclaim (DEV2_Handle device)
779     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
780 #ifdef SAP_CACHE_SUPPORT
781     DEV2_Frame *pFrame;
782 #endif
784     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
786     // must be running and  error free 
787     if ((!pDevExt->runState) || (pDevExt->errorState))
788     {
789         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
790         return SIO2_EBADIO;
791     }
793     // idle if necessary
794         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
795             DEV2_idle (device, 1);
796             return SIO2_EBADIO;
797         }
799        // Log_info0("SAP_reclaim: Before SEM Pend");
801     // wait for ISR to signal block completion
802     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
803     if (!Semaphore_pend(pDevExt->sync, device->timeout))
804     {
805         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
806         return SIO2_ETIMEOUT;
807     }
808     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
810     // return error (owner must idle)
811     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
812     {
813         DEV2_idle (device, 1);
814         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
815         return PAF_SIO_ERROR_FATAL;
816     }
818 #ifdef SAP_CACHE_SUPPORT
819     // invalidate CACHE region if input -- use clean since
820     //    Dont clean if was for fill.
821     // since pend returned we know that head of fromdevice is valid
822     pFrame = Queue_head (device->fromdevice);
823     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
824     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
825     {
826         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
827         {
828             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
829             Cache_wait();
831             // max HWI disable duration ~1ms observed
832             //unsigned int key = Hwi_disable();                                 // GJ: Revisit, along with other context protections here.
833             swapHdmi(pFrame->addr, pFrame->size);
834             //Hwi_restore(key);
835         }
836     }
838 #endif
839     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
840         SW_BREAKPOINT; */
842     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
843     return SIO2_OK;
844 } // SAP_reclaim
847 // -----------------------------------------------------------------------------
849 Int SAP_open (DEV2_Handle device, String name)
851     SAP_DeviceExtension   *pDevExt;
852     DEV2_Device            *entry;
853     Int                    oldMask, result;
854     Error_Block                         eb;
855     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
857     // check SIO mode 
858     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
859         return SIO2_EMODE;
861     // allocate memory for device extension
862     device->object = NULL;
863     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
864     if (pDevExt == NULL)
865     {
866         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
867         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
868         asm( " SWBP 0" );  // SW Breakpoint
869         return SIO2_EALLOC;
870     }
871     device->object = (Ptr)pDevExt;
873     // inits
874     pDevExt->device = device;
875     pDevExt->sync = NULL;
876     pDevExt->pParams = NULL;
877     pDevExt->runState = 0;  // not yet started
878     pDevExt->errorState = PAF_SIO_ERROR_NONE;
879     pDevExt->shutDown = 1;
880     pDevExt->numQueued = 0;
881     pDevExt->activeEdma = EDMA_HINV;
882     pDevExt->errorEdma = EDMA_HINV;
883     pDevExt->firstTCC = 0;
884     pDevExt->optLevel = 0;
885     pDevExt->numParamSetup = 0;
886     pDevExt->numEdmaParams = 4;
888     // use dev match to fetch function table pointer for SAP
889     DEV2_match(SAP_NAME, &entry);
890     if (entry == NULL) {
891         Log_error1("SAP", SIO2_ENODEV);
892         return SIO2_ENODEV;
893     }
894     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
896     // create semaphore for device
897     pDevExt->sync = Semaphore_create (0, NULL, NULL);
898     if (pDevExt->sync == NULL)
899     {
900         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
901         return SIO2_EALLOC;
902     }
904     // queue inits
905     Queue_construct (&pDevExt->xferQue, NULL);
906     Queue_construct (&pDevExt->paramQue, NULL);
908     // update driver global (need to protect context)
909     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
910     {
911         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
912             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
913         SW_BREAKPOINT;
914     }
915     oldMask = Hwi_disable ();
916     sapDrv.device[sapDrv.numDevices] = device;
917     pDevExt->deviceNum = sapDrv.numDevices++;
918     Hwi_restore (oldMask);
920     // PORT init
921     result = SAP_PORT_FTABLE_open (device);
922     if (result)
923     {
924         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
925         return result;
926     }
928     return result;
929 } // SAP_open
931 // -----------------------------------------------------------------------------
933 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
935     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
936     Int                  result, Que_num, i;
937     EDMA3_DRV_Result     edmaResult;
938     Uint32                                      reqTcc;
939     EDMA3_DRV_Handle    hEdma;
940     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
942     // cannot configure if transfer started
943     if (pDevExt->runState == 1)
944         return SIO2_EBADIO;
946     // save pointer to config structure in device extension. here so that
947     //   forthcoming functions can use/modify config structure.
948     pDevExt->pParams = pParams;
949     pDevExt->edmaWordSize = pParams->sio.wordSize;
951     // allocate Port resources.
952     //    This must come before DMA configuration
953     result = SAP_PORT_FTABLE_alloc (device);
954     if (result)
955     {
956         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
957         return result;
958     }
960     // .............................................................................
961     // EDMA configuration
963     // DA10x McASP0 Specific
964     if (pParams->sio.moduleNum == 0)
965     {
966         hEdma = hEdma0;
967         if (device->mode == DEV2_INPUT)
968         {
969                 Que_num = 0;
970                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
971         }
972         else
973         {
974                 Que_num = 1;
975                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
976         }
977     }
978     // DA10x McASP1 Specific
979     else if (pParams->sio.moduleNum == 1)
980     {
981         hEdma = hEdma1;
982         if (device->mode == DEV2_INPUT)
983                 {
984                 Que_num = 0;
985                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
986                 }
987                 else
988                 {
989                         Que_num = 1;
990                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
991                 }
992     }
993     // DA10x McASP2 Specific
994     else if (pParams->sio.moduleNum == 2)
995     {
996         hEdma = hEdma1;
997         if (device->mode == DEV2_INPUT)
998                 {
999                         Que_num = 0;
1000                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1001                 }
1002                 else
1003                 {
1004                         Que_num = 1;
1005                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1006                 }
1007     }
1010     for (i=0; i < pDevExt->numEdmaParams; i++) {
1012         reqTcc = EDMA3_DRV_TCC_ANY;
1013         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1014         edmaResult = EDMA3_DRV_requestChannel (
1015                 hEdma,
1016             &pDevExt->edmaParams[i].hEdmaParam,
1017             &reqTcc,
1018             (EDMA3_RM_EventQueue) Que_num,
1019             SAP_isrCallback,
1020             (void *) device);
1022         if (edmaResult != EDMA3_DRV_SOK)
1023             return SIO2_EALLOC;
1025         //not running => can use non-atomic functions
1026         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1028     }
1030     reqTcc = EDMA3_DRV_TCC_ANY;
1031         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1032         edmaResult = EDMA3_DRV_requestChannel (
1033             hEdma,
1034             &pDevExt->errorEdma,
1035             &reqTcc,
1036             (EDMA3_RM_EventQueue)Que_num,
1037             SAP_isrCallback,
1038             (void *) device);
1039         if (edmaResult != EDMA3_DRV_SOK)
1040             return SIO2_EALLOC;
1042         // allocate edma channel -- also disable and clear the interrupt
1045         pDevExt->firstTCC = pDevExt->activeEdma ;
1046         edmaResult = EDMA3_DRV_requestChannel (
1047                 hEdma,
1048                 &pDevExt->activeEdma,
1049                 &pDevExt->firstTCC,
1050                 (EDMA3_RM_EventQueue) 0,
1051                 SAP_isrCallback,
1052                 (void *) device);
1053         if (edmaResult != EDMA3_DRV_SOK)
1054                     {
1055                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1056                         return SIO2_EALLOC;
1057                     }
1059         // Configure error transfer
1060         //   make cnt same as # of channels in order to maintain alignment
1061         //   and the error transfer small so that we never have to wait
1062         //   long for it to complete and trigger a linked transfer. This is
1063         //   important for establishing output timing when we are idling with
1064         //   clocks still running. Is fine for Rx as well.
1065         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1067         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1069     return SIO2_OK;
1070 } // SAP_config
1072 // -----------------------------------------------------------------------------
1074 Int SAP_shutdown (DEV2_Handle device)
1076     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1077     SIO2_Handle stream = (SIO2_Handle) device;
1078     DEV2_Frame *pFrame;
1079     Int i;
1080     EDMA3_DRV_Handle hEdma;
1081     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1083     if (pDevExt->shutDown)
1084         return SIO2_EBADIO;
1086     if (pDevExt->pParams == NULL)
1087         return SIO2_EINVAL;
1089     if (pDevExt->pParams->sio.moduleNum == 0)
1090         hEdma = hEdma0;
1091     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1092         hEdma = hEdma1;
1093     if (pDevExt->activeEdma != EDMA_HINV)
1094         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1096     // reset queues
1097     while (!Queue_empty(device->todevice)) {
1098        // place oustanding requests onto holding queue
1099        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1100        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1101     }
1103     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1104         // pull frame from holding queue and place on user queue
1105         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1106         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1107     }
1110     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1111         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1113     // not running => can use non-atomic functions
1114     for (i=0; i < pDevExt->numEdmaParams; i++)
1115         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1117     // reset counter
1118     pDevExt->numQueued = 0;
1120     // make sure active is linked to error
1121         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1123     // think this is better (from SIO_idle for standard model )
1124     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1125     while (!Queue_empty(device->fromdevice)) {
1126         /* place oustanding requests onto holding queue */
1127         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1128         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1129     }
1130     Semaphore_reset (pDevExt->sync, 0);
1131     
1132     pDevExt->shutDown = 1;
1133     pDevExt->numParamSetup = 0;
1134     
1135     /*result = SAP_DMA_FTABLE_unlock (device);
1136     if (result)
1137     {
1138         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1139         return result;
1140     } */
1142     return SIO2_OK;
1143 } // SAP_shutdown
1145 // -----------------------------------------------------------------------------
1146 int gSapWatchDogThrottle = 0; //DJDBG
1147 int gSapWatchDogIn =0;
1148 int gSapWatchDogOut = 0;
1149 int gSapWatchDogInSemPost = 0;
1150 int gSapWatchDogOutSemPost = 0;
1152 Void SAP_watchDog (Void)
1154     DEV2_Handle device;
1155     SAP_DeviceExtension *pDevExt;
1156     int i, oldMask, result;
1158     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1160     // do nothing if SAP_init not yet called
1161     if (!SAP_initialized)
1162     {
1163         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1164         return;
1165     }
1167     // GJ: Revisit, along with other context protections here.
1168     // GJ: Is this architecture ok?
1169     // protect context
1170     Task_disable (); // needed since we may call SEM_post
1171     // Hwi_disable commented since it used to affect other interrupts
1172     // max HWI disable duration ~4ms observed
1173     //oldMask = Hwi_disable ();
1176     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1178     for (i=0; i < sapDrv.numDevices; i++) {
1179         device  = sapDrv.device[i];
1181         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1183         pDevExt = (SAP_DeviceExtension *) device->object;
1185         // do nothing if not running
1186         if (!pDevExt->runState)
1187             continue;
1189         // call board specific watchdog
1190         // TODO: handle return value
1191         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1192         
1193         // if port layer returns error then must need to clean up
1194         result = SAP_PORT_FTABLE_watchDog (device);
1195         if (result) {
1196             // set errorState which will force owner thread
1197             //   to clean up via SIO_idle()
1198             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1199             if(device->mode == DEV2_INPUT)
1200                 gSapWatchDogIn++;
1201             else
1202                 gSapWatchDogOut++;
1204             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1205            /* if(gSapWatchDogThrottle == 0) //DJDBG
1206             {
1207                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1208             }
1209             gSapWatchDogThrottle ++;
1210             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1211             // if outstanding pend then post to free owner thead
1212             if (!Semaphore_pend(pDevExt->sync, 0))
1213             {
1214                 if(device->mode == DEV2_INPUT)
1215                         gSapWatchDogInSemPost++;
1216                 else
1217                         gSapWatchDogOutSemPost++;
1218                 Semaphore_post (pDevExt->sync);
1219             }
1220         }
1221     }
1224     // renable interrupts and task manager.
1225     // If we posted to the semaphore then the TSK_enable call will lead to
1226     // an immediate task switch to the associated audio thread.
1227     //Hwi_restore (oldMask);
1228     Task_enable ();
1230 } // SAP_watchDog
1232 // -----------------------------------------------------------------------------
1233 // Assumes that EDMA3 dispatcher handles TCC clearing.
1235 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1237     DEV2_Handle                 device;
1238     SAP_DeviceExtension       *pDevExt;
1239     DEV2_Frame                 *pFrame;
1240     unsigned int               opt;
1241     EDMA3_DRV_Handle                    hEdma;
1243     // could be here after Tx idle/overrun and this is the interrupt
1244     // for the last occuring error transfer so there is no transfer
1245     // to release, we just clear the int and exit.
1247     device = (DEV2_Handle) context;
1248     pDevExt = (SAP_DeviceExtension *)(device->object);
1249     //if (pDevExt->pParams == NULL)
1250         //return SIO2_EINVAL;
1252     if (pDevExt->pParams->sio.moduleNum == 0)
1253         hEdma = hEdma0;
1254     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1255         hEdma = hEdma1;
1257     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1258         // if here then an interrupt occured due to errorEdma or valid
1259         // transfer, we assume the xfer is long enough so it will not complete
1260         // before we are finished here.
1262         // if last transfer was valid then complete it
1263         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1265             // pull frame from holding queue
1266             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1268             // if used param entry then return it to queue
1269             if (pFrame->misc != NULL)
1270             {
1271                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1272                 if (device->mode == 1)
1273                         gisrOutput+=100;
1274             }
1276             // decrement count
1277             pDevExt->numQueued -= 1;
1278             //gIsrCnt++;
1279             if (device->mode == 1)
1280                 gIsrOutputCnt++;
1281             else
1282                 gIsrInputCnt++;
1283             // place frame onto user queue and signal user thread
1284             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1286             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1287             // signal user thread
1288             Semaphore_post (pDevExt->sync);
1289 #if 0
1290             if(gIsrCnt > 10) { //DJDBG
1291                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1293             }
1294 #endif
1295         }
1296         else
1297                 gIsrElseCnt++;
1299         // determine if currently transferring buffer is valid based on interrupt enable bit
1300         // only valid transfers will generate interrupts
1301         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1303         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1304         {
1305                 if (device->mode == 1)
1306                         gIsrOutErrCnt++;
1307                 else
1308                         gIsrInErrCnt++;
1309                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1310         }
1312     } // runState
1313     else
1314     {
1315                 if (pDevExt->runState != 1)
1316                         gIsrRunCnt++;
1317                 else
1318                         gIsrNotRunCnt++;
1319     }
1321     return;
1322 } //SAP_isrCallback
1324 // -----------------------------------------------------------------------------
1326 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1328     EDMA3_DRV_Handle            hEdma;
1329     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1330 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1332         if (pDevExt->pParams == NULL)
1333                 return SIO2_EINVAL;
1335             if (pDevExt->pParams->sio.moduleNum == 0)
1336                 hEdma = hEdma0;
1337             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1338                 hEdma = hEdma1;
1340     // TODO: shouldn't this just be tcc interrupt disable?
1341     // at least until linkage phase...
1342     unsigned int key = Hwi_disable (); //DJDBG
1344     if(targetEdma == NULL)
1345     {
1346         Log_info0("targetEdma is NULL");
1347     }
1348     // configure transfer
1349     if(pFrame->addr == NULL) //DJDBG
1350     {
1351         Log_info0("pFrame has NULL address?");
1352     }
1353     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1355     if (parentEdma != EDMA_HINV)
1356         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1359     Hwi_restore (key); //DJDBG
1361     return SIO2_OK;
1362 } // SAP_setupXfer
1364 // -----------------------------------------------------------------------------
1365 // Configure EDMA3 parameter entry
1367 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1369     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1370     EDMA3_DRV_Handle            hEdma;
1371     EDMA3_DRV_PaRAMRegs  edmaConfig;
1373     if (pDevExt->pParams == NULL)
1374                 return SIO2_EINVAL;
1376         if (pDevExt->pParams->sio.moduleNum == 0)
1377                 hEdma = hEdma0;
1378         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1379                 hEdma = hEdma1;
1380     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1381    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1383    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1385     // Init opt parameter to 0 which, without being overriden, configures as:
1386     //    A synchronized transfer (no FIFO mode on src or dst)
1387     //    no chaining or intermediate interrupts
1388     //    param is not static
1389     //    normal completion
1390     //    don't generate an interrupt (overriden below for regular xfers)
1391     edmaConfig.opt = 0;
1393     // not transferring blocks so c index is 0
1394     edmaConfig.destCIdx = 0;
1395     edmaConfig.srcCIdx = 0;
1397     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1398     if (device->mode == DEV2_OUTPUT) {
1399       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1400       edmaConfig.opt |= 2;
1401     }
1402     else {
1403         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1404         //edmaConfig.opt |= 1;
1405     }
1407     // if regular transfer then enable interrupt with tcc code
1408     if (targetEdma != pDevExt->errorEdma) {
1409         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1410         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1411         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1412     }
1415     edmaConfig.aCnt = 4;
1416         edmaConfig.bCnt = pDevExt->numSers;
1417         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1418     edmaConfig.bCntReload = edmaConfig.bCnt;
1421     // handle direction specific requirements
1422     if (device->mode == DEV2_INPUT) {
1423         edmaConfig.srcBIdx  = 0;
1424                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1426         if (addr) {
1427             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1428             edmaConfig.destAddr = addr;
1429             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1430             if(pDevExt->edmaWordSize == 2)
1431                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1432         }
1433         else {
1434                 //if(pDevExt->edmaWordSize == 2)
1435                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1436             edmaConfig.destBIdx = 0;
1437             edmaConfig.destAddr = (unsigned int) &sap_OVER;
1438         }
1439     }
1440     else {
1441         edmaConfig.destBIdx = 0;
1442         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1444         if (addr) {
1445             edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1446             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1447             edmaConfig.srcAddr  = addr;
1448             //Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1449         }
1450         else {
1451             edmaConfig.srcBIdx  = 0;
1452             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1453 #if 1
1454             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1455             edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1456 #endif
1457         }
1458     }
1459     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1460     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1462     //Log_info3("SAP: Inside SAP_EDMA_setupParam with targetEdma = 0x%x linked to childEdma = 0x%x & dest-addr: 0x%x", targetEdma, childEdma, edmaConfig.destAddr);
1464     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1466     // link child xfer
1467     if (childEdma != EDMA_HINV)
1468         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1470     return SIO2_OK;
1471 } //SAP_setupParam