Add debug counters
[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 4
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
114 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
116         unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
117         unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
118         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
120         Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
121         Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
123         Log_info5("PARAM0x19a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[0], ptrPARAM0x19[1], ptrPARAM0x19[2], ptrPARAM0x19[3]);
124         Log_info5("PARAM0x19b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x19[4], ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
125     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
127 // .............................................................................
128 // notes:
129 //  . add control function to PORT table
130 //  . how to handle DMA/PORT specifics in parameter entries
131 //      can assume numSers = numChans is general and can be applied by DMA
132 //      same for wordSize?
133 //  . why are two idle stages needed (seems like 1 is enough)?
135 // .............................................................................
136 // only one global variable, not static so that DMA and port functions
137 // can access. We cant just store the address in devExt since the ISR has
138 // no context.
140 SAP_DriverObject sapDrv;
142 // needed since SAP_watchDog is called before SAP_init
143 Int SAP_initialized = 0;
145 //Int  SAP_close(DEV2_Handle);
146 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
147 Int  SAP_idle(DEV2_Handle, Bool);
148 Int  SAP_issue(DEV2_Handle);
149 Int  SAP_open(DEV2_Handle, String);
150 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
151 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
152 Int  SAP_reclaim(DEV2_Handle);
153 Int  SAP_shutdown(DEV2_Handle);
154 Int  SAP_start(DEV2_Handle);
155 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
156 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, unsigned int addr, unsigned int size);
157 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
159 // .............................................................................
161 // .............................................................................
163 SAP_DMA_Fxns SAP_EDMA_FXNS =
165         SAP_EDMA_setupParam,
166         SAP_EDMA_setupXfer,
167 };
170 SAP_Fxns SAP_FXNS =
172     NULL, //SAP_close, -- remove for IROM since not using
173     SAP_ctrl,
174     SAP_idle,
175     SAP_issue,
176     SAP_open,
177     NULL, //SAP_ready, -- remove for IROM since not using
178     SAP_reclaim,
179     SAP_shutdown,
180     SAP_start,
181     SAP_config,
183 #ifdef SAP_PORT_MCASP
184     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
185 #endif
186 #ifdef SAP_DMA_EDMA
187     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
188 #endif
189 };
191 // -----------------------------------------------------------------------------
192 // This function is not in the driver function table.
193 // Must be pointed at in GUI config tool.
194 //
195 Void SAP_init (Void)
197     DEV2_Device  *entry;
198     SAP_Fxns    *pFxns;
200     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
202     // find function table pointer (used by SAP_XX_FTABLE_init macros)
203     DEV2_match(SAP_NAME, &entry);
204     if (entry == NULL) {
205         Log_error1 ("SAP", SIO2_ENODEV);
206         return;
207     }
208     pFxns = (SAP_Fxns *) entry->fxns;
210     //SAP_DMA_FTABLE_init ();
211     SAP_PORT_FTABLE_init ();
213     sapDrv.numDevices = 0;
214     SAP_initialized = 1;
216     return;
217 } // SAP_init
219 // -----------------------------------------------------------------------------
221 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
223     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
224     const SAP_Params *pParams;
225     Int result = SIO2_OK;
226     EDMA3_DRV_Handle    hEdma;
227     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
229     switch (code) {
231 /* .......................................................................... */
233         case PAF_SIO_CONTROL_MUTE:
234         case PAF_SIO_CONTROL_UNMUTE:
235             pParams = pDevExt->pParams;
236             if (pParams == NULL)
237                 return SIO2_OK;
239             if (pParams->sio.control != NULL)
240                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
241             break;
243 /* .......................................................................... */
245         case PAF_SIO_CONTROL_OPEN:
246             if (pDevExt->runState)
247                 return SIO2_EBUSY;
249             if (!( pParams = (const SAP_Params *) arg ))
250                 return SIO2_OK;
252             if (result = SAP_FTABLE_config (device, pParams))
253                 return result;
255             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
256                 return result;
258             break;
260 /* .......................................................................... */
262         case PAF_SIO_CONTROL_CLOSE:
263             if (pDevExt->runState)
264                 return SIO2_EBUSY;
266             if (pDevExt->pParams == NULL)
267                                 return SIO2_EINVAL;
269             pParams = pDevExt->pParams;
271                         if (pParams->sio.moduleNum == 0)
272                                 hEdma = hEdma0;
273                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
274                                 hEdma = hEdma1;
275             if (pDevExt->activeEdma != EDMA_HINV) {
276                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
277                             pDevExt->activeEdma = EDMA_HINV;
278                         }
280             if (!(pParams = pDevExt->pParams))
281                 return SIO2_OK;
283             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
284                 return result;
286             result = SAP_PORT_FTABLE_close (device);
287             if (result)
288                 return result;
290             pDevExt->pParams = NULL;
291             break;
293 /* .......................................................................... */
295         case PAF_SIO_CONTROL_GET_WORDSIZE:
296                 if (!arg)
297                                 return SIO2_EINVAL;
298                         *((int *) arg) = pDevExt->edmaWordSize;
299             break;
301         case PAF_SIO_CONTROL_SET_WORDSIZE:
302             // defer to DMA processing
303                 // currently only supported for input
304                         if (device->mode != DEV2_INPUT)
305                                 return SIO2_EINVAL;
307                         // can't be running
308                         if (pDevExt->runState)
309                                 return SIO2_EBUSY;
311                         // driver only supports 2 or 4 bytes
312                    if ((arg != 2) && (arg != 4))
313                                 return SIO2_EINVAL;
315                         // return success for unconfigured devices?
316                         if (!pDevExt->pParams)
317                                 return SIO2_OK;
319                         // ask platform if size is supported
320                         pParams = pDevExt->pParams;
321                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
322                                 return result;
324                         pDevExt->edmaWordSize = arg;
325                         break;
327         case PAF_SIO_CONTROL_GET_PRECISION:
328             if (arg == 0)
329                 return SIO2_EINVAL;
331             pParams = pDevExt->pParams;
332             if (pParams == NULL)
333                 return( SIO2_EINVAL );
335             *((int *) arg) = pParams->sio.precision;
336             break;
338         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
339             if (arg == 0)
340                 return SIO2_EINVAL;
342             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
343             break;
345         case PAF_SIO_CONTROL_SET_RATEX:
346             pParams = pDevExt->pParams;
347             if (pParams == NULL)
348                 return SIO2_OK ;
350             if (pParams->sio.control == NULL)
351                 return SIO2_EINVAL;
353             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
354             break;
356 /* .......................................................................... */
358         case PAF_SIO_CONTROL_IDLE:
359             pParams = pDevExt->pParams;
360             if (pParams == NULL)
361                 return SIO2_OK ;
363             if (pParams->sio.control == NULL)
364                 return SIO2_EINVAL;
366             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
367             break;
369         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
370             // 1. Here we are intentionally not using SIO_Idle() and
371             //    leaving the Tx clock running. We need this to avoid DAC noise,
372             //    as well as provide a DIT clock when using digital output.
373             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
374                 return SIO2_EINVAL;
376             pParams = pDevExt->pParams;
378             if (pParams->sio.moduleNum == 0)
379                 hEdma = hEdma0;
380             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
381                                 hEdma = hEdma1;
383             result = SAP_FTABLE_shutdown (device);
384             if (result)
385                 return result;
387             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
388             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
390 #if 1
391             //DJDBG, if below enableTransfer() is commented, input side continuous working.
392      if (pDevExt->activeEdma != EDMA_HINV) {
393                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
394             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
395             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
396      }
397 #endif
398             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
400             break;
402 /* .......................................................................... */
404         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
405             // needs to be attached
406             pParams = pDevExt->pParams;
407             if (pParams == NULL)
408                 return SIO2_OK;
410             if (pParams->sio.control == NULL)
411                 return SIO2_EINVAL;
413             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
414             break;
416         case PAF_SIO_CONTROL_WATCHDOG:
417             pParams = pDevExt->pParams;
418             if (pParams == NULL)
419                 return SIO2_OK;
420             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
421                 return result;
422             break;
423             
424 /* .......................................................................... */
426         // Timing stats specific to DMA engine
427         case PAF_SIO_CONTROL_ENABLE_STATS:
428         case PAF_SIO_CONTROL_DISABLE_STATS:
429         case PAF_SIO_CONTROL_GET_STATS:
430         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
431         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
432             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
433             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
434             break;
436 /* .......................................................................... */
438         case PAF_SIO_CONTROL_SET_DITSTATUS:
439             if(device->mode == DEV2_OUTPUT)
440             {
441                 const SAP_Params *pParams = pDevExt->pParams;
442                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
443                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
444                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
445                 int encSelect = *((int *) arg);
447                 // HACK -- determine DIT need by FXWID
448                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
449                 {
450                     if ( (encSelect == 0x13) ||
451                          (encSelect == 0xa)  || 
452                          (encSelect == 0x6)) // DTE, DDE, MPE 
453                     {
454                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
455                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
456                     }
457                     else
458                     {
459                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
460                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
461                     }
462                 }
464                 pParams = pDevExt->pParams;
465                 if (pParams == NULL)
466                     return SIO2_OK;
468                 if (pParams->sio.control != NULL)
469                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
470             }
471             break;
473 /* .......................................................................... */
475     }
477     return result;
478 } // SAP_ctrl
480 int gSAPIdleShutdownIn=0;
481 int gSAPIdleShutdownOut=0;
483 // -----------------------------------------------------------------------------
485 Int SAP_idle (DEV2_Handle device, Bool flush)
487     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
488     Int result = SIO2_OK;
489     EDMA3_DRV_Handle hEdma;
491     // do nothing if already idled or unattached
492     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
493         return result;
495         if (pDevExt->pParams->sio.moduleNum == 0)
496                 hEdma = hEdma0;
497         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
498                 hEdma = hEdma1;
500     // reset serial port -- stop generating sync events
501     result = SAP_PORT_FTABLE_reset (device);
502     if(device->mode == DEV2_OUTPUT)
503         gSAPResetOut++;
504     else
505         gSAPResetIn++;
506     if (result)
507     {
508         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
509         return result;
510     }
512     pDevExt->shutDown = 0; // force shutdown to run
513     result = SAP_FTABLE_shutdown (device);
514     if(device->mode == DEV2_OUTPUT)
515         gSAPIdleShutdownOut++;
516     else
517         gSAPIdleShutdownIn++;
519     if (result)
520     {
521         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
522         return result;
523     }
525     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
527     // disable interrupts and EDMA servicing
528    if (pDevExt->activeEdma != EDMA_HINV)
529            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
531     pDevExt->numQueued = 0;
533     // signal stopped
534     pDevExt->runState = 0;
536     // reset errorState
537     pDevExt->errorState = PAF_SIO_ERROR_NONE;
538     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
540     // place call to physical device
541     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
542         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
544     return result;
545 } // SAP_idle
547 // -----------------------------------------------------------------------------
549 Int SAP_start (DEV2_Handle device)
551     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
552     DEV2_Frame *pFrame;
553     int result;
554     EDMA3_DRV_Handle hEdma;
556     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
558     // signal we have started
559     //    we change the state here since we have already moved a frame from the 
560     //    todevice queue to the xferQue. If an error occurs during one of the 
561     //    following resets/enables then we need to have runState !=0 in order
562     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
563     //    do not (and are now required not to) depend on runState being 0.
564     //pDevExt->runState = 1;
565     // Assume todevice queue is not empty -- how else could we be here?
566     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
568     // inidicate this xfer did not use param entry - just the active one
569     pFrame->misc = NULL;
570     if (pDevExt->pParams->sio.moduleNum == 0)
571         hEdma = hEdma0;
572     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
573                 hEdma = hEdma1;
575     // non-atomic functions since not running yet.
576     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
578     // initialize count
579     pDevExt->numQueued = 1;
581     result = SAP_PORT_FTABLE_reset (device);
582     if (result)
583     {
584         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
585         return result;
586     }
588     // enable DMA processing
590     // config active xfer for this buffer
591     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
593     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
594       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
595         // signal we have started -- this must come before last enable to prevent a race
596         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
597         // and completes before any further instructions in this thread are executed.
598         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
599         // will be serviced and generate an interrupt even before the McASP is enabled.
600         pDevExt->runState = 1;
601         pDevExt->shutDown = 0;
602         //Log_info0 ("SAP_start runState=1 & ENABLE TRANSFERS");
603         // enable interrupts and event servicing for this channel
604         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
606     // enable peripheral
607     result = SAP_PORT_FTABLE_enable (device);
609     if (result)
610     {
611         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
612         return result;
613     }
615     return SIO2_OK;
616 } // SAP_start
618 int gDmaParamsarray[17][3];
619 int gDmaParamsidx=0;
620 // -----------------------------------------------------------------------------
622 Int SAP_issue (DEV2_Handle device)
624     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
625     DEV2_Frame *pFrame;
626     Int result;
627     SAP_EDMA_Param *pParam;
628     XDAS_UInt32 parentEdma;
630     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
632     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
633     {
634         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
635             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
636         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
637                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
638         return SIO2_EBADIO;
639     }
641     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
642         {
643                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
644             return SIO2_EBADIO;
645         }
647     // if not yet running then configure active xfer and start
648     if (pDevExt->runState == 0)
649         return (SAP_FTABLE_start(device));
651     // .........................................................................
652     // here if running
654     // disable device interrupts
655     // TODO: is there an API to just disable the IER bit for this tcc?
656     unsigned int key = Hwi_disable ();
657        /* determine parent EDMA
658           if no xfers in queue and we are running then must be in the
659           error state so link to active channel otherwise link to last
660           transfer queued.
661        */
663        /* here we assume after Tx SIO_idle or overrun, the user
664           will issue, at least, back-to-back issue requests so
665           there should be no problem here.
666        */
667        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
668            parentEdma = pDevExt->activeEdma;
669        else {
670            // if here then xferQue has more than one element so ok to use tail
671            // last scheduled transfer must be queue->prev
672            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
673            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
674        }
676     // get frame and parameter table to use; ints off => non-atomic OK
677     //     dont need to check for empty queues since were here then todevice
678     //     must have a frame placed there by the SIO_issue layer.
679     //     paramQue must be valid since it is accessed the same as todevice.
680     //     (indirectly -- isr places used items onto paramQue and fromdevice que
681     //      at the same time)
682     // set misc argument to pParam so get enqueue later
683     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
684     pFrame = Queue_dequeue (device->todevice);
685     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
687    /* if (pFrame->addr == NULL)
688                 SW_BREAKPOINT; */
689     if (pParam->hEdmaParam == NULL)
690         Log_info0("SAP_issue: hEdma value is NULL");
691     // set misc argument to pParam so get enqueue later
692     pFrame->misc = (Arg) pParam;
694     // place on holder queue, ints off => non-atomic OK
695     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
696     if (pFrame->addr) {
697                 if (device->mode == DEV2_INPUT)
698                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
699                 else
700                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
701         }
703     // increment count
704     pDevExt->numQueued += 1;
706     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
707     //Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
708     //                __LINE__, pParam->hEdma, parentEdma, pDevExt->errorEdma);
710     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
711         {
712         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
713                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
714                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
715         } */
717         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
718                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
720         pDevExt->shutDown = 0;
722     // special case enables when not yet started
723     if (pDevExt->runState == 0) {
724         result = SAP_FTABLE_start (device);
725         if (result) {
726             //SAP_DMA_FTABLE_unlock (device);
727                   Hwi_enable ();
728             return result;
729         }
730     }
731     Hwi_restore (key); //DJDBG
733     return result;
734 } // SAP_issue
736 // -----------------------------------------------------------------------------
738 void swapHdmi(Ptr Input, int size)
741         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
742         MdInt *p1, *p2;
743         int i=0;
745         for (i=0; i< size; i+=16)
746         {
747                         p1 = (MdInt *)&Input[i];
748                         p2 = p1;
750                         L0 = *p1++;
751                         L1 = *p1++;
752                         L2 = *p1++;
753                         L3 = *p1++;
754                         R0 = *p1++;
755                         R1 = *p1++;
756                         R2 = *p1++;
757                         R3 = *p1++;
759                         *p2++ = L0;
760                         *p2++ = R0;
761                         *p2++ = L1;
762                         *p2++ = R1;
763                         *p2++ = L2;
764                         *p2++ = R2;
765                         *p2++ = L3;
766                         *p2++ = R3;
768         }
770         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (MdInt *)Input, p1, p2);
772         /**p2++ = 0xF872;
773         *p2++ = 0x4E1F;
774         *p2++ = 0x0016;
775         *p2++ = 0xEFF0;
776         *p2++ = 0x079E;
777         *p2++ = 0x0003;
778         *p2++ = 0x8401;
779         *p2++ = 0x0101; */
781         return;
784 Int SAP_reclaim (DEV2_Handle device)
786     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
787     Int result, i, oldMask;
788 #ifdef SAP_CACHE_SUPPORT
789     DEV2_Frame *pFrame;
790 #endif
792     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
794     // must be running and  error free 
795     if ((!pDevExt->runState) || (pDevExt->errorState))
796     {
797         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
798         return SIO2_EBADIO;
799     }
801     // idle if necessary
802         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
803             DEV2_idle (device, 1);
804             return SIO2_EBADIO;
805         }
807        // Log_info0("SAP_reclaim: Before SEM Pend");
809     // wait for ISR to signal block completion
810     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
811     if (!Semaphore_pend(pDevExt->sync, device->timeout))
812     {
813         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
814         return SIO2_ETIMEOUT;
815     }
816     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
818     // return error (owner must idle)
819     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
820     {
821         DEV2_idle (device, 1);
822         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
823         return PAF_SIO_ERROR_FATAL;
824     }
826 #ifdef SAP_CACHE_SUPPORT
827     // invalidate CACHE region if input -- use clean since
828     //    Dont clean if was for fill.
829     // since pend returned we know that head of fromdevice is valid
830     pFrame = Queue_head (device->fromdevice);
831     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
832     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
833     {
834         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
835         {
836             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
837             Cache_wait();
838                 //note: size here is in # of bytes, so incrementing by 4X32b words ( or 8X16b)
839                         //for(i=0; i<(pFrame->size)/(4*4); i+=16)
840                         //{
841                 // Hwi_disable commented since it used to affect other interrupts
842                 // max HWI disable duration ~1ms observed
843                     //oldMask = Hwi_disable ();
844                                 swapHdmi(pFrame->addr, pFrame->size);
845                                 //Hwi_restore(oldMask);
847                         Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
848                         Cache_wait();
849                         //}
850         }
851     }
853 #endif
854     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
855         SW_BREAKPOINT; */
857     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
858     return SIO2_OK;
859 } // SAP_reclaim
862 // -----------------------------------------------------------------------------
864 Int SAP_open (DEV2_Handle device, String name)
866     SAP_DeviceExtension   *pDevExt;
867     DEV2_Device            *entry;
868     Int                    oldMask, result;
869     Error_Block                         eb;
870     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
872     // check SIO mode 
873     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
874         return SIO2_EMODE;
876     // allocate memory for device extension
877     device->object = NULL;
878     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
879     if (pDevExt == NULL)
880     {
881         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
882         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
883         asm( " SWBP 0" );  // SW Breakpoint
884         return SIO2_EALLOC;
885     }
886     device->object = (Ptr)pDevExt;
888     // inits
889     pDevExt->device = device;
890     pDevExt->sync = NULL;
891     pDevExt->pParams = NULL;
892     pDevExt->runState = 0;  // not yet started
893     pDevExt->errorState = PAF_SIO_ERROR_NONE;
894     pDevExt->shutDown = 1;
895     pDevExt->numQueued = 0;
896     pDevExt->activeEdma = EDMA_HINV;
897     pDevExt->errorEdma = EDMA_HINV;
898     pDevExt->firstTCC = 0;
899     pDevExt->optLevel = 0;
900     pDevExt->numParamSetup = 0;
901     pDevExt->numEdmaParams = 4;
903     // use dev match to fetch function table pointer for SAP
904     DEV2_match(SAP_NAME, &entry);
905     if (entry == NULL) {
906         Log_error1("SAP", SIO2_ENODEV);
907         return SIO2_ENODEV;
908     }
909     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
911     // create semaphore for device
912     pDevExt->sync = Semaphore_create (0, NULL, NULL);
913     if (pDevExt->sync == NULL)
914     {
915         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
916         return SIO2_EALLOC;
917     }
919     // queue inits
920     Queue_construct (&pDevExt->xferQue, NULL);
921     Queue_construct (&pDevExt->paramQue, NULL);
923     // update driver global (need to protect context)
924     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
925     {
926         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
927             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
928         SW_BREAKPOINT;
929     }
930     oldMask = Hwi_disable ();
931     sapDrv.device[sapDrv.numDevices] = device;
932     pDevExt->deviceNum = sapDrv.numDevices++;
933     Hwi_restore (oldMask);
935     // PORT init
936     result = SAP_PORT_FTABLE_open (device);
937     if (result)
938     {
939         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
940         return result;
941     }
943     return result;
944 } // SAP_open
946 // -----------------------------------------------------------------------------
948 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
950     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
951     Int                  result, Que_num, i;
952     EDMA3_DRV_Result     edmaResult;
953     Uint32                                      reqTcc;
954     EDMA3_DRV_Handle    hEdma;
955     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
957     // cannot configure if transfer started
958     if (pDevExt->runState == 1)
959         return SIO2_EBADIO;
961     // save pointer to config structure in device extension. here so that
962     //   forthcoming functions can use/modify config structure.
963     pDevExt->pParams = pParams;
964     pDevExt->edmaWordSize = pParams->sio.wordSize;
966     // allocate Port resources.
967     //    This must come before DMA configuration
968     result = SAP_PORT_FTABLE_alloc (device);
969     if (result)
970     {
971         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
972         return result;
973     }
975     // .............................................................................
976     // EDMA configuration
978     // DA10x McASP0 Specific
979     if (pParams->sio.moduleNum == 0)
980     {
981         hEdma = hEdma0;
982         if (device->mode == DEV2_INPUT)
983         {
984                 Que_num = 0;
985                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
986         }
987         else
988         {
989                 Que_num = 1;
990                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
991         }
992     }
993     // DA10x McASP1 Specific
994     else if (pParams->sio.moduleNum == 1)
995     {
996         hEdma = hEdma1;
997         if (device->mode == DEV2_INPUT)
998                 {
999                 Que_num = 0;
1000                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1001                 }
1002                 else
1003                 {
1004                         Que_num = 1;
1005                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1006                 }
1007     }
1008     // DA10x McASP2 Specific
1009     else if (pParams->sio.moduleNum == 2)
1010     {
1011         hEdma = hEdma1;
1012         if (device->mode == DEV2_INPUT)
1013                 {
1014                         Que_num = 0;
1015                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1016                 }
1017                 else
1018                 {
1019                         Que_num = 1;
1020                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1021                 }
1022     }
1025     for (i=0; i < pDevExt->numEdmaParams; i++) {
1027         reqTcc = EDMA3_DRV_TCC_ANY;
1028         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1029         edmaResult = EDMA3_DRV_requestChannel (
1030                 hEdma,
1031             &pDevExt->edmaParams[i].hEdmaParam,
1032             &reqTcc,
1033             (EDMA3_RM_EventQueue) Que_num,
1034             SAP_isrCallback,
1035             (void *) device);
1037         if (edmaResult != EDMA3_DRV_SOK)
1038             return SIO2_EALLOC;
1040         //not running => can use non-atomic functions
1041         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1043     }
1045     reqTcc = EDMA3_DRV_TCC_ANY;
1046         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1047         edmaResult = EDMA3_DRV_requestChannel (
1048             hEdma,
1049             &pDevExt->errorEdma,
1050             &reqTcc,
1051             (EDMA3_RM_EventQueue)Que_num,
1052             SAP_isrCallback,
1053             (void *) device);
1054         if (edmaResult != EDMA3_DRV_SOK)
1055             return SIO2_EALLOC;
1057         // allocate edma channel -- also disable and clear the interrupt
1060         pDevExt->firstTCC = pDevExt->activeEdma ;
1061         edmaResult = EDMA3_DRV_requestChannel (
1062                 hEdma,
1063                 &pDevExt->activeEdma,
1064                 &pDevExt->firstTCC,
1065                 (EDMA3_RM_EventQueue) 0,
1066                 SAP_isrCallback,
1067                 (void *) device);
1068         if (edmaResult != EDMA3_DRV_SOK)
1069                     {
1070                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1071                         return SIO2_EALLOC;
1072                     }
1074         // Configure error transfer
1075         //   make cnt same as # of channels in order to maintain alignment
1076         //   and the error transfer small so that we never have to wait
1077         //   long for it to complete and trigger a linked transfer. This is
1078         //   important for establishing output timing when we are idling with
1079         //   clocks still running. Is fine for Rx as well.
1080         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1082         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1084     return SIO2_OK;
1085 } // SAP_config
1087 // -----------------------------------------------------------------------------
1089 Int SAP_shutdown (DEV2_Handle device)
1091     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1092     SIO2_Handle stream = (SIO2_Handle) device;
1093     DEV2_Frame *pFrame;
1094     Int result,i;
1095     EDMA3_DRV_Handle hEdma;
1096     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1098     if (pDevExt->shutDown)
1099         return SIO2_EBADIO;
1101     if (pDevExt->pParams == NULL)
1102         return SIO2_EINVAL;
1104     if (pDevExt->pParams->sio.moduleNum == 0)
1105         hEdma = hEdma0;
1106     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1107         hEdma = hEdma1;
1108     if (pDevExt->activeEdma != EDMA_HINV)
1109         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1111     // reset queues
1112     while (!Queue_empty(device->todevice)) {
1113        // place oustanding requests onto holding queue
1114        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1115        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1116     }
1118     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1119         // pull frame from holding queue and place on user queue
1120         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1121         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1122     }
1125     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1126         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1128     // not running => can use non-atomic functions
1129     for (i=0; i < pDevExt->numEdmaParams; i++)
1130         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1132     // reset counter
1133     pDevExt->numQueued = 0;
1135     // make sure active is linked to error
1136         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1138     // think this is better (from SIO_idle for standard model )
1139     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1140     while (!Queue_empty(device->fromdevice)) {
1141         /* place oustanding requests onto holding queue */
1142         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1143         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1144     }
1145     Semaphore_reset (pDevExt->sync, 0);
1146     
1147     pDevExt->shutDown = 1;
1148     pDevExt->numParamSetup = 0;
1149     
1150     /*result = SAP_DMA_FTABLE_unlock (device);
1151     if (result)
1152     {
1153         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1154         return result;
1155     } */
1157     return SIO2_OK;
1158 } // SAP_shutdown
1160 // -----------------------------------------------------------------------------
1161 int gSapWatchDogThrottle = 0; //DJDBG
1162 Void SAP_watchDog (Void)
1164     DEV2_Handle device;
1165     SAP_DeviceExtension *pDevExt;
1166     int i, oldMask, result;
1168     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1170     // do nothing if SAP_init not yet called
1171     if (!SAP_initialized)
1172     {
1173         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1174         return;
1175     }
1177     // protect context
1178     Task_disable (); // needed since we may call SEM_post
1179     // Hwi_disable commented since it used to affect other interrupts
1180     // max HWI disable duration ~4ms observed
1181     //oldMask = Hwi_disable ();
1183     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1185     for (i=0; i < sapDrv.numDevices; i++) {
1186         device  = sapDrv.device[i];
1188         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1190         pDevExt = (SAP_DeviceExtension *) device->object;
1192         // do nothing if not running
1193         if (!pDevExt->runState)
1194             continue;
1196         // call board specific watchdog
1197         // TODO: handle return value
1198         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1199         
1200         // if port layer returns error then must need to clean up
1201         result = SAP_PORT_FTABLE_watchDog (device);
1202         if (result) {
1203             // set errorState which will force owner thread
1204             //   to clean up via SIO_idle()
1205             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1206             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1207            /* if(gSapWatchDogThrottle == 0) //DJDBG
1208             {
1209                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1210             }
1211             gSapWatchDogThrottle ++;
1212             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1213             // if outstanding pend then post to free owner thead
1214             if (!Semaphore_pend(pDevExt->sync, 0))
1215                 Semaphore_post (pDevExt->sync);
1216         }
1217     }
1219     // renable interrupts and task manager.
1220     // If we posted to the semaphore then the TSK_enable call will lead to
1221     // an immediate task switch to the associated audio thread.
1222     //Hwi_restore (oldMask);
1223     Task_enable ();
1225 } // SAP_watchDog
1227 // -----------------------------------------------------------------------------
1228 // Assumes that EDMA3 dispatcher handles TCC clearing.
1230 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1232     DEV2_Handle                 device;
1233     SAP_DeviceExtension       *pDevExt;
1234     DEV2_Frame                 *pFrame;
1235     unsigned int               opt;
1236     EDMA3_DRV_Handle                    hEdma;
1238     // could be here after Tx idle/overrun and this is the interrupt
1239     // for the last occuring error transfer so there is no transfer
1240     // to release, we just clear the int and exit.
1242     device = (DEV2_Handle) context;
1243     pDevExt = (SAP_DeviceExtension *)(device->object);
1244     if (pDevExt->pParams == NULL)
1245         return SIO2_EINVAL;
1247     if (pDevExt->pParams->sio.moduleNum == 0)
1248         hEdma = hEdma0;
1249     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1250         hEdma = hEdma1;
1252     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1253         // if here then an interrupt occured due to errorEdma or valid
1254         // transfer, we assume the xfer is long enough so it will not complete
1255         // before we are finished here.
1257         // if last transfer was valid then complete it
1258         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1260             // pull frame from holding queue
1261             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1263             // if used param entry then return it to queue
1264             if (pFrame->misc != NULL)
1265             {
1266                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1267                 if (device->mode == 1)
1268                         gisrOutput+=100;
1269             }
1271             // decrement count
1272             pDevExt->numQueued -= 1;
1273             //gIsrCnt++;
1274             if (device->mode == 1)
1275                 gisrOutput++;
1277             // place frame onto user queue and signal user thread
1278             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1280             Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1281             // signal user thread
1282             Semaphore_post (pDevExt->sync);
1283 #if 0
1284             if(gIsrCnt > 10) { //DJDBG
1285                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1287             }
1288 #endif
1289         }
1290         else
1291                 gIsrElseCnt++;
1293         // determine if currently transferring buffer is valid based on interrupt enable bit
1294         // only valid transfers will generate interrupts
1295         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1297         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1298         {
1299                 if (device->mode == 1)
1300                         gIsrOutErrCnt++;
1301                 else
1302                         gIsrInErrCnt++;
1303                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1304         }
1306     } // runState
1307     else
1308     {
1309                 if (pDevExt->runState != 1)
1310                         gIsrRunCnt++;
1311                 else
1312                         gIsrNotRunCnt++;
1313     }
1315     return;
1316 } //SAP_isrCallback
1318 // -----------------------------------------------------------------------------
1320 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1322     EDMA3_DRV_Handle            hEdma;
1323     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1324 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1326         if (pDevExt->pParams == NULL)
1327                 return SIO2_EINVAL;
1329             if (pDevExt->pParams->sio.moduleNum == 0)
1330                 hEdma = hEdma0;
1331             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1332                 hEdma = hEdma1;
1334     // TODO: shouldn't this just be tcc interrupt disable?
1335     // at least until linkage phase...
1336     unsigned int key = Hwi_disable (); //DJDBG
1338     if(targetEdma == NULL)
1339     {
1340         Log_info0("targetEdma is NULL");
1341     }
1342     // configure transfer
1343     if(pFrame->addr == NULL) //DJDBG
1344     {
1345         Log_info0("pFrame has NULL address?");
1346     }
1347     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, pFrame->addr, pFrame->size);
1349     if (parentEdma != EDMA_HINV)
1350         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1353     Hwi_restore (key); //DJDBG
1355     return SIO2_OK;
1356 } // SAP_setupXfer
1358 // -----------------------------------------------------------------------------
1359 // Configure EDMA3 parameter entry
1361 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, unsigned int addr, unsigned int size)
1363     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1364     EDMA3_DRV_Handle            hEdma;
1365     EDMA3_DRV_PaRAMRegs  edmaConfig;
1367     if (pDevExt->pParams == NULL)
1368                 return SIO2_EINVAL;
1370         if (pDevExt->pParams->sio.moduleNum == 0)
1371                 hEdma = hEdma0;
1372         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1373                 hEdma = hEdma1;
1374     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1375     volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1377    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1379     // Init opt parameter to 0 which, without being overriden, configures as:
1380     //    A synchronized transfer (no FIFO mode on src or dst)
1381     //    no chaining or intermediate interrupts
1382     //    param is not static
1383     //    normal completion
1384     //    don't generate an interrupt (overriden below for regular xfers)
1385     edmaConfig.opt = 0;
1387     // not transferring blocks so c index is 0
1388     edmaConfig.destCIdx = 0;
1389     edmaConfig.srcCIdx = 0;
1391     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1392     if (device->mode == DEV2_OUTPUT) {
1393       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1394       edmaConfig.opt |= 2;
1395     }
1396     else {
1397         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1398         //edmaConfig.opt |= 1;
1399     }
1401     // if regular transfer then enable interrupt with tcc code
1402     if (targetEdma != pDevExt->errorEdma) {
1403         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1404         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1405         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1406     }
1409     edmaConfig.aCnt = 4;
1410         edmaConfig.bCnt = pDevExt->numSers;
1411         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1412     edmaConfig.bCntReload = edmaConfig.bCnt;
1415     // handle direction specific requirements
1416     if (device->mode == DEV2_INPUT) {
1417         edmaConfig.srcBIdx  = 0;
1418                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1420         if (addr) {
1421             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1422             edmaConfig.destAddr = addr;
1423             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1424             if(pDevExt->edmaWordSize == 2)
1425                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);        // GJ: Account for additional 2-bytes.
1426         }
1427         else {
1428                 //if(pDevExt->edmaWordSize == 2)
1429                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1430             edmaConfig.destBIdx = 0;
1431             edmaConfig.destAddr = (unsigned int) &sap_OVER;
1432         }
1433     }
1434     else {
1435         edmaConfig.destBIdx = 0;
1436         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1438         if (addr) {
1439             edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1440             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1441             edmaConfig.srcAddr  = addr;
1442             Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1443         }
1444         else {
1445             edmaConfig.srcBIdx  = 0;
1446             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1447 #if 1
1448             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1449             edmaConfig.cCnt = 512; //DJDBG, if underrun have frame of silence
1450 #endif
1451         }
1452     }
1453     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1454     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1456     //Log_info3("SAP: Inside SAP_EDMA_setupParam with targetEdma = 0x%x linked to childEdma = 0x%x & dest-addr: 0x%x", targetEdma, childEdma, edmaConfig.destAddr);
1458     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1460     // link child xfer
1461     if (childEdma != EDMA_HINV)
1462         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1464     return SIO2_OK;
1465 } //SAP_setupParam