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)
115 {
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
126 }
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 =
164 {
165 SAP_EDMA_setupParam,
166 SAP_EDMA_setupXfer,
167 };
170 SAP_Fxns SAP_FXNS =
171 {
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)
196 {
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)
222 {
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;
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)
486 {
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)
550 {
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)
623 {
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)
739 {
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;
782 }
784 Int SAP_reclaim (DEV2_Handle device)
785 {
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)
865 {
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)
949 {
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)
1090 {
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);
1147 pDevExt->shutDown = 1;
1148 pDevExt->numParamSetup = 0;
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)
1163 {
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);
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)
1231 {
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)
1321 {
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)
1362 {
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