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