2 /*
3 Copyright (c) 2017, 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 #include "sap_mcasp.h"
71 #include <pafsio.h>
73 // This works to set a breakpoint
74 #define SW_BREAKPOINT asm( " SWBP 0" );
75 /* Software Breakpoint to Code Composer */
76 // SW_BREAKPOINT;
78 // global allocated in bios_edma3_drv_sample_init.c
79 extern EDMA3_DRV_Handle hEdma0;
80 extern EDMA3_DRV_Handle hEdma1;
82 int gStartError;
83 int gIsrInputCnt;
84 int gIsrOutputCnt;
85 int gIsrElseCnt;
86 int gIsrInErrCnt;
87 int gIsrOutErrCnt;
88 int gIsrRunCnt;
89 int gIsrNotRunCnt;
90 int gisrOutput;
91 int gSAPResetIn;
92 int gSAPResetOut;
94 typedef xdc_Short MdInt;
96 void swapHdmi(Ptr, int);
98 #define SAP_UNDER_LEN 8
100 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
101 int sap_OVER_1LANE = 0; // used for overrun
102 int sap_OVER_4LANE[4] = {0,0,0,0}; // used for overrun
104 #ifdef DEBUG
105 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
106 {
107 //unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
108 //unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
109 unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
110 unsigned int *ptrPARAM0x41 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
111 unsigned int *ptrPARAM0x42 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
112 unsigned int *ptrPARAM0x43 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
113 unsigned int *ptrPARAM0x44 = (unsigned int *)0x02704910; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
115 //Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
116 //Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
118 Log_info5("PARAM0x19a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x19[0] & 0x200000) >> 21), ((ptrPARAM0x19[0] & 0x100000) >> 20), ((ptrPARAM0x19[0] & 0x3F000) >> 12), ((ptrPARAM0x19[0] & 0x800) >> 11));
119 Log_info5("PARAM0x19b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x, SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x19[1], ptrPARAM0x19[2], ptrPARAM0x19[3], ptrPARAM0x19[4]);
120 Log_info4("PARAM0x19b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
122 Log_info5("PARAM0x41a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x41[0] & 0x200000) >> 21), ((ptrPARAM0x41[0] & 0x100000) >> 20), ((ptrPARAM0x41[0] & 0x3F000) >> 12), ((ptrPARAM0x41[0] & 0x800) >> 11));
123 Log_info5("PARAM0x41b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x, SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x41[1], ptrPARAM0x41[2], ptrPARAM0x41[3], ptrPARAM0x41[4]);
124 Log_info4("PARAM0x41b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x41[5], ptrPARAM0x41[6], ptrPARAM0x41[7]);
126 Log_info5("PARAM0x42a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x42[0] & 0x200000) >> 21), ((ptrPARAM0x42[0] & 0x100000) >> 20), ((ptrPARAM0x42[0] & 0x3F000) >> 12), ((ptrPARAM0x42[0] & 0x800) >> 11));
127 Log_info5("PARAM0x42b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x, SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x42[1], ptrPARAM0x42[2], ptrPARAM0x42[3], ptrPARAM0x42[4]);
128 Log_info4("PARAM0x42b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x42[5], ptrPARAM0x42[6], ptrPARAM0x42[7]);
130 Log_info5("PARAM0x43a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x43[0] & 0x200000) >> 21), ((ptrPARAM0x43[0] & 0x100000) >> 20), ((ptrPARAM0x43[0] & 0x3F000) >> 12), ((ptrPARAM0x43[0] & 0x800) >> 11));
131 Log_info5("PARAM0x43b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x, SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x43[1], ptrPARAM0x43[2], ptrPARAM0x43[3], ptrPARAM0x43[4]);
132 Log_info4("PARAM0x43b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x43[5], ptrPARAM0x43[6], ptrPARAM0x43[7]);
134 Log_info5("PARAM0x44a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x44[0] & 0x200000) >> 21), ((ptrPARAM0x44[0] & 0x100000) >> 20), ((ptrPARAM0x44[0] & 0x3F000) >> 12), ((ptrPARAM0x44[0] & 0x800) >> 11));
135 Log_info5("PARAM0x44b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x, SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x44[1], ptrPARAM0x44[2], ptrPARAM0x44[3], ptrPARAM0x44[4]);
136 Log_info4("PARAM0x44b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x44[5], ptrPARAM0x44[6], ptrPARAM0x44[7]);
137 //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
138 }
139 #endif
140 // .............................................................................
141 // notes:
142 // . add control function to PORT table
143 // . how to handle DMA/PORT specifics in parameter entries
144 // can assume numSers = numChans is general and can be applied by DMA
145 // same for wordSize?
146 // . why are two idle stages needed (seems like 1 is enough)?
148 // .............................................................................
149 // only one global variable, not static so that DMA and port functions
150 // can access. We cant just store the address in devExt since the ISR has
151 // no context.
153 SAP_DriverObject sapDrv;
155 // needed since SAP_watchDog is called before SAP_init
156 Int SAP_initialized = 0;
158 //Int SAP_close(DEV2_Handle);
159 Int SAP_ctrl(DEV2_Handle, Uns, Arg);
160 Int SAP_idle(DEV2_Handle, Bool);
161 Int SAP_issue(DEV2_Handle);
162 Int SAP_open(DEV2_Handle, String);
163 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
164 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
165 Int SAP_reclaim(DEV2_Handle);
166 Int SAP_shutdown(DEV2_Handle);
167 Int SAP_start(DEV2_Handle);
168 Int SAP_config(DEV2_Handle device, const SAP_Params *pParams);
169 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
170 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
172 // .............................................................................
174 // .............................................................................
176 SAP_DMA_Fxns SAP_EDMA_FXNS =
177 {
178 SAP_EDMA_setupParam,
179 SAP_EDMA_setupXfer,
180 };
183 SAP_Fxns SAP_FXNS =
184 {
185 NULL, //SAP_close, -- remove for IROM since not using
186 SAP_ctrl,
187 SAP_idle,
188 SAP_issue,
189 SAP_open,
190 NULL, //SAP_ready, -- remove for IROM since not using
191 SAP_reclaim,
192 SAP_shutdown,
193 SAP_start,
194 SAP_config,
196 #ifdef SAP_PORT_MCASP
197 (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
198 #endif
199 #ifdef SAP_DMA_EDMA
200 (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
201 #endif
202 };
204 // -----------------------------------------------------------------------------
205 // This function is not in the driver function table.
206 // Must be pointed at in GUI config tool.
207 //
208 Void SAP_init (Void)
209 {
210 DEV2_Device *entry;
211 SAP_Fxns *pFxns;
213 //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
215 // find function table pointer (used by SAP_XX_FTABLE_init macros)
216 DEV2_match(SAP_NAME, &entry);
217 if (entry == NULL) {
218 Log_error1 ("SAP", SIO2_ENODEV);
219 return;
220 }
221 pFxns = (SAP_Fxns *) entry->fxns;
223 //SAP_DMA_FTABLE_init ();
224 SAP_PORT_FTABLE_init ();
226 sapDrv.numDevices = 0;
227 SAP_initialized = 1;
229 return;
230 } // SAP_init
232 // -----------------------------------------------------------------------------
234 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
235 {
236 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
237 const SAP_Params *pParams;
238 Int result = SIO2_OK;
239 EDMA3_DRV_Handle hEdma;
240 //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
242 switch (code) {
244 /* .......................................................................... */
246 case PAF_SIO_CONTROL_MUTE:
247 case PAF_SIO_CONTROL_UNMUTE:
248 pParams = pDevExt->pParams;
249 if (pParams == NULL)
250 return SIO2_OK;
252 if (pParams->sio.control != NULL)
253 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
254 break;
256 /* .......................................................................... */
258 case PAF_SIO_CONTROL_OPEN:
259 if (pDevExt->runState)
260 return SIO2_EBUSY;
262 if (!( pParams = (const SAP_Params *) arg ))
263 return SIO2_OK;
265 if (result = SAP_FTABLE_config (device, pParams))
266 return result;
268 if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
269 return result;
271 break;
273 /* .......................................................................... */
275 case PAF_SIO_CONTROL_CLOSE:
276 if (pDevExt->runState)
277 return SIO2_EBUSY;
279 if (pDevExt->pParams == NULL)
280 return SIO2_EINVAL;
282 pParams = pDevExt->pParams;
284 if (pParams->sio.moduleNum == 0)
285 hEdma = hEdma0;
286 else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
287 hEdma = hEdma1;
288 if (pDevExt->activeEdma != EDMA_HINV) {
289 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
290 pDevExt->activeEdma = EDMA_HINV;
291 }
293 if (!(pParams = pDevExt->pParams))
294 return SIO2_OK;
296 if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
297 return result;
299 result = SAP_PORT_FTABLE_close (device);
300 if (result)
301 return result;
303 pDevExt->pParams = NULL;
304 break;
306 /* .......................................................................... */
308 case PAF_SIO_CONTROL_GET_WORDSIZE:
309 if (!arg)
310 return SIO2_EINVAL;
311 *((int *) arg) = pDevExt->edmaWordSize;
312 break;
314 case PAF_SIO_CONTROL_SET_WORDSIZE:
315 // defer to DMA processing
316 // currently only supported for input
317 if (device->mode != DEV2_INPUT)
318 return SIO2_EINVAL;
320 // can't be running
321 if (pDevExt->runState)
322 return SIO2_EBUSY;
324 // driver only supports 2 or 4 bytes
325 if ((arg != 2) && (arg != 4))
326 return SIO2_EINVAL;
328 // return success for unconfigured devices?
329 if (!pDevExt->pParams)
330 return SIO2_OK;
332 // ask platform if size is supported
333 pParams = pDevExt->pParams;
334 if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
335 return result;
337 pDevExt->edmaWordSize = arg;
338 break;
340 case PAF_SIO_CONTROL_GET_PRECISION:
341 if (arg == 0)
342 return SIO2_EINVAL;
344 pParams = pDevExt->pParams;
345 if (pParams == NULL)
346 return( SIO2_EINVAL );
348 *((int *) arg) = pParams->sio.precision;
349 break;
351 case PAF_SIO_CONTROL_GET_NUMCHANNELS:
352 if (arg == 0)
353 return SIO2_EINVAL;
355 *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
356 break;
358 case PAF_SIO_CONTROL_SET_RATEX:
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_SET_RATEX, arg);
367 break;
369 /* .......................................................................... */
371 case PAF_SIO_CONTROL_IDLE:
372 pParams = pDevExt->pParams;
373 if (pParams == NULL)
374 return SIO2_OK ;
376 if (pParams->sio.control == NULL)
377 return SIO2_EINVAL;
379 result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
380 break;
382 case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
383 // 1. Here we are intentionally not using SIO_Idle() and
384 // leaving the Tx clock running. We need this to avoid DAC noise,
385 // as well as provide a DIT clock when using digital output.
386 if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
387 return SIO2_EINVAL;
389 pParams = pDevExt->pParams;
391 if (pParams->sio.moduleNum == 0)
392 hEdma = hEdma0;
393 else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
394 hEdma = hEdma1;
396 result = SAP_FTABLE_shutdown (device);
397 if (result)
398 return result;
400 Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
401 pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
403 #if 1
404 //DJDBG, if below enableTransfer() is commented, input side continuous working.
405 if (pDevExt->activeEdma != EDMA_HINV) {
406 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
407 //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
408 EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
409 }
410 #endif
411 //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
413 break;
415 /* .......................................................................... */
417 case PAF_SIO_CONTROL_GET_INPUT_STATUS:
418 // needs to be attached
419 pParams = pDevExt->pParams;
420 if (pParams == NULL)
421 return SIO2_OK;
423 if (pParams->sio.control == NULL)
424 return SIO2_EINVAL;
426 result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
427 break;
429 case PAF_SIO_CONTROL_WATCHDOG:
430 pParams = pDevExt->pParams;
431 if (pParams == NULL)
432 return SIO2_OK;
433 if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
434 return result;
435 break;
437 /* .......................................................................... */
439 // Timing stats specific to DMA engine
440 case PAF_SIO_CONTROL_ENABLE_STATS:
441 case PAF_SIO_CONTROL_DISABLE_STATS:
442 case PAF_SIO_CONTROL_GET_STATS:
443 case PAF_SIO_CONTROL_GET_NUM_EVENTS:
444 case PAF_SIO_CONTROL_GET_NUM_REMAINING:
445 //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
446 // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x. result 0x%x.", device, code, result));
447 break;
449 /* .......................................................................... */
451 case PAF_SIO_CONTROL_SET_DITSTATUS:
452 if(device->mode == DEV2_OUTPUT)
453 {
454 const SAP_Params *pParams = pDevExt->pParams;
455 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
456 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
457 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
458 int encSelect = *((int *) arg);
460 // HACK -- determine DIT need by FXWID
461 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
462 {
463 if ( (encSelect == 0x13) ||
464 (encSelect == 0xa) ||
465 (encSelect == 0x6)) // DTE, DDE, MPE
466 {
467 base[_MCASP_DITCSRA0_OFFSET] |= 2;
468 base[_MCASP_DITCSRB0_OFFSET] |= 2;
469 }
470 else
471 {
472 base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
473 base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
474 }
475 }
477 pParams = pDevExt->pParams;
478 if (pParams == NULL)
479 return SIO2_OK;
481 if (pParams->sio.control != NULL)
482 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
483 }
484 break;
486 /* .......................................................................... */
488 }
490 return result;
491 } // SAP_ctrl
493 int gSAPIdleShutdownIn=0;
494 int gSAPIdleShutdownOut=0;
496 // -----------------------------------------------------------------------------
498 Int SAP_idle (DEV2_Handle device, Bool flush)
499 {
500 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
501 Int result = SIO2_OK;
502 EDMA3_DRV_Handle hEdma;
504 // do nothing if already idled or unattached
505 if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
506 return result;
508 if (pDevExt->pParams->sio.moduleNum == 0)
509 hEdma = hEdma0;
510 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
511 hEdma = hEdma1;
513 // reset serial port -- stop generating sync events
514 result = SAP_PORT_FTABLE_reset (device);
515 if(device->mode == DEV2_OUTPUT)
516 gSAPResetOut++;
517 else
518 gSAPResetIn++;
519 if (result)
520 {
521 //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
522 return result;
523 }
525 pDevExt->shutDown = 0; // force shutdown to run
526 result = SAP_FTABLE_shutdown (device);
527 if(device->mode == DEV2_OUTPUT)
528 gSAPIdleShutdownOut++;
529 else
530 gSAPIdleShutdownIn++;
532 if (result)
533 {
534 //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
535 return result;
536 }
538 Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
540 // disable interrupts and EDMA servicing
541 if (pDevExt->activeEdma != EDMA_HINV)
542 EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
544 pDevExt->numQueued = 0;
546 // signal stopped
547 pDevExt->runState = 0;
549 // reset errorState
550 pDevExt->errorState = PAF_SIO_ERROR_NONE;
551 //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
553 // place call to physical device
554 if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
555 result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
557 return result;
558 } // SAP_idle
560 // -----------------------------------------------------------------------------
562 Int SAP_start (DEV2_Handle device)
563 {
564 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
565 DEV2_Frame *pFrame;
566 int result;
567 EDMA3_DRV_Handle hEdma;
569 //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
571 // signal we have started
572 // we change the state here since we have already moved a frame from the
573 // todevice queue to the xferQue. If an error occurs during one of the
574 // following resets/enables then we need to have runState !=0 in order
575 // for SAP_idle to properly cleanup. Moreover, the following resets/enables
576 // do not (and are now required not to) depend on runState being 0.
577 //pDevExt->runState = 1;
578 // Assume todevice queue is not empty -- how else could we be here?
579 pFrame = (DEV2_Frame *) Queue_get (device->todevice);
581 // inidicate this xfer did not use param entry - just the active one
582 pFrame->misc = NULL;
583 if (pDevExt->pParams->sio.moduleNum == 0)
584 hEdma = hEdma0;
585 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
586 hEdma = hEdma1;
588 // non-atomic functions since not running yet.
589 Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
591 // initialize count
592 pDevExt->numQueued = 1;
594 result = SAP_PORT_FTABLE_reset (device);
595 if (result)
596 {
597 //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
598 return result;
599 }
601 // enable DMA processing
603 // config active xfer for this buffer
604 result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
606 //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
607 // __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
608 // signal we have started -- this must come before last enable to prevent a race
609 // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
610 // and completes before any further instructions in this thread are executed.
611 // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
612 // will be serviced and generate an interrupt even before the McASP is enabled.
613 pDevExt->runState = 1;
614 pDevExt->shutDown = 0;
615 Log_info1 ("SAP: %d, SAP_start runState=1 & ENABLE TRANSFERS", __LINE__);
616 // enable interrupts and event servicing for this channel
617 EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
619 // enable peripheral
620 result = SAP_PORT_FTABLE_enable (device);
622 if (result)
623 {
624 //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
625 return result;
626 }
628 return SIO2_OK;
629 } // SAP_start
631 int gDmaParamsarray[17][3];
632 int gDmaParamsidx=0, gSAPSpecialCase=0;
633 // -----------------------------------------------------------------------------
635 Int SAP_issue (DEV2_Handle device)
636 {
637 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
638 DEV2_Frame *pFrame;
639 Int result;
640 SAP_EDMA_Param *pParam;
641 XDAS_UInt32 parentEdma;
643 //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
645 if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
646 {
647 /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
648 __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
649 Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
650 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
651 return SIO2_EBADIO;
652 }
654 if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
655 {
656 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
657 return SIO2_EBADIO;
658 }
660 // if not yet running then configure active xfer and start
661 if (pDevExt->runState == 0)
662 return (SAP_FTABLE_start(device));
664 // .........................................................................
665 // here if running
667 // disable device interrupts
668 // TODO: is there an API to just disable the IER bit for this tcc?
669 unsigned int key = Hwi_disable ();
670 /* determine parent EDMA
671 if no xfers in queue and we are running then must be in the
672 error state so link to active channel otherwise link to last
673 transfer queued.
674 */
676 /* here we assume after Tx SIO_idle or overrun, the user
677 will issue, at least, back-to-back issue requests so
678 there should be no problem here.
679 */
680 if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
681 parentEdma = pDevExt->activeEdma;
682 else {
683 // if here then xferQue has more than one element so ok to use tail
684 // last scheduled transfer must be queue->prev
685 DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
686 parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
687 }
689 // get frame and parameter table to use; ints off => non-atomic OK
690 // dont need to check for empty queues since were here then todevice
691 // must have a frame placed there by the SIO_issue layer.
692 // paramQue must be valid since it is accessed the same as todevice.
693 // (indirectly -- isr places used items onto paramQue and fromdevice que
694 // at the same time)
695 // set misc argument to pParam so get enqueue later
696 //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
697 pFrame = Queue_dequeue (device->todevice);
698 pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
700 if (pParam->hEdmaParam == NULL)
701 Log_info0("SAP_issue: hEdma value is NULL");
702 // set misc argument to pParam so get enqueue later
703 pFrame->misc = (Arg) pParam;
705 // place on holder queue, ints off => non-atomic OK
706 Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
707 if (pFrame->addr) {
708 if (device->mode == DEV2_INPUT)
709 Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
710 else
711 Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
712 }
714 // increment count
715 pDevExt->numQueued += 1;
717 result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
718 Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
719 __LINE__, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma);
721 /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
722 {
723 gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
724 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
725 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
726 } */
728 if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
729 pDevExt->errorState = PAF_SIO_ERROR_NONE;
731 pDevExt->shutDown = 0;
733 // special case enables when not yet started
734 if (pDevExt->runState == 0) {
735 gSAPSpecialCase++;
736 result = SAP_FTABLE_start (device);
737 if (result) {
738 //SAP_DMA_FTABLE_unlock (device);
739 Hwi_restore (key);
740 return result;
741 }
742 }
743 Hwi_restore (key); //DJDBG
745 return result;
746 } // SAP_issue
748 // -----------------------------------------------------------------------------
750 void swapHdmi(Ptr Input, int size)
751 {
753 MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
754 MdInt *p1, *p2;
755 int i=0;
757 for (i=0; i< size; i+=16)
758 {
759 p1 = (MdInt *)&Input[i];
760 p2 = p1;
762 L0 = *p1++;
763 L1 = *p1++;
764 L2 = *p1++;
765 L3 = *p1++;
766 R0 = *p1++;
767 R1 = *p1++;
768 R2 = *p1++;
769 R3 = *p1++;
771 *p2++ = L0;
772 *p2++ = R0;
773 *p2++ = L1;
774 *p2++ = R1;
775 *p2++ = L2;
776 *p2++ = R2;
777 *p2++ = L3;
778 *p2++ = R3;
780 }
782 Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, p1, p2);
784 return;
785 }
787 Int SAP_reclaim (DEV2_Handle device)
788 {
789 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
790 #ifdef SAP_CACHE_SUPPORT
791 DEV2_Frame *pFrame;
792 #endif
794 //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
796 // must be running and error free
797 if ((!pDevExt->runState) || (pDevExt->errorState))
798 {
799 //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
800 return SIO2_EBADIO;
801 }
803 // idle if necessary
804 if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
805 Log_info1("SAP_reclaim: PAF_SIO_ERROR_FATAL, Before Idle for device 0x%x ", device->mode);
806 DEV2_idle (device, 1);
807 return SIO2_EBADIO;
808 }
810 // Log_info0("SAP_reclaim: Before SEM Pend");
812 // wait for ISR to signal block completion
813 //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
814 if (!Semaphore_pend(pDevExt->sync, device->timeout))
815 {
816 Log_info0("SAP_reclaim, SYS_ETIMEOUT");
817 return SIO2_ETIMEOUT;
818 }
819 //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
821 #if 0
822 // return error (owner must idle)
823 if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
824 {
825 DEV2_idle (device, 1);
826 //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
827 return PAF_SIO_ERROR_FATAL;
828 }
829 #endif
831 #ifdef SAP_CACHE_SUPPORT
832 // invalidate CACHE region if input -- use clean since
833 // Dont clean if was for fill.
834 // since pend returned we know that head of fromdevice is valid
835 pFrame = Queue_head (device->fromdevice);
836 Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
837 if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
838 {
839 if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
840 {
841 Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
842 Cache_wait();
844 // max HWI disable duration ~1ms observed
845 //unsigned int key = Hwi_disable (); // GJ: Revisit, along with other context protections here.
846 swapHdmi(pFrame->addr, pFrame->size);
847 //Hwi_restore(key);
849 Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
850 Cache_wait();
851 }
852 }
854 #endif
855 /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
856 SW_BREAKPOINT; */
858 Log_info1("SAP_reclaim: Exiting with SIO2_OK for device 0x%x ", device->mode);
859 //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
860 return SIO2_OK;
861 } // SAP_reclaim
864 // -----------------------------------------------------------------------------
866 Int SAP_open (DEV2_Handle device, String name)
867 {
868 SAP_DeviceExtension *pDevExt;
869 DEV2_Device *entry;
870 Int oldMask, result;
871 Error_Block eb;
872 //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
874 // check SIO mode
875 if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
876 return SIO2_EMODE;
878 // allocate memory for device extension
879 device->object = NULL;
880 pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
881 if (pDevExt == NULL)
882 {
883 printf("%s.%d: MEM_alloc failed.\n", __FUNCTION__, __LINE__);
884 //TRACE_TERSE((&TR_MOD, "%s.%d: MEM_alloc failed.\n", __FUNCTION__, __LINE__));
885 asm( " SWBP 0" ); // SW Breakpoint
886 return SIO2_EALLOC;
887 }
888 device->object = (Ptr)pDevExt;
890 // inits
891 pDevExt->device = device;
892 pDevExt->sync = NULL;
893 pDevExt->pParams = NULL;
894 pDevExt->runState = 0; // not yet started
895 pDevExt->errorState = PAF_SIO_ERROR_NONE;
896 pDevExt->shutDown = 1;
897 pDevExt->numQueued = 0;
898 pDevExt->activeEdma = EDMA_HINV;
899 pDevExt->errorEdma = EDMA_HINV;
900 pDevExt->firstTCC = 0;
901 pDevExt->optLevel = 0;
902 pDevExt->numParamSetup = 0;
903 pDevExt->numEdmaParams = 4;
905 // use dev match to fetch function table pointer for SAP
906 DEV2_match(SAP_NAME, &entry);
907 if (entry == NULL) {
908 Log_error1("SAP", SIO2_ENODEV);
909 return SIO2_ENODEV;
910 }
911 pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
913 // create semaphore for device
914 pDevExt->sync = Semaphore_create (0, NULL, NULL);
915 if (pDevExt->sync == NULL)
916 {
917 //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
918 return SIO2_EALLOC;
919 }
921 // queue inits
922 Queue_construct (&pDevExt->xferQue, NULL);
923 Queue_construct (&pDevExt->paramQue, NULL);
925 // update driver global (need to protect context)
926 if (sapDrv.numDevices >= MAX_SAP_DEVICES)
927 {
928 /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
929 __FUNCTION__, __LINE__, dapDrv.numDevices));*/
930 SW_BREAKPOINT;
931 }
932 oldMask = Hwi_disable ();
933 sapDrv.device[sapDrv.numDevices] = device;
934 pDevExt->deviceNum = sapDrv.numDevices++;
935 Hwi_restore (oldMask);
937 // PORT init
938 result = SAP_PORT_FTABLE_open (device);
939 if (result)
940 {
941 //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
942 return result;
943 }
945 return result;
946 } // SAP_open
948 // -----------------------------------------------------------------------------
950 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
951 {
952 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
953 Int result, Que_num, i;
954 EDMA3_DRV_Result edmaResult;
955 Uint32 reqTcc;
956 EDMA3_DRV_Handle hEdma;
957 Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
959 // cannot configure if transfer started
960 if (pDevExt->runState == 1)
961 return SIO2_EBADIO;
963 // save pointer to config structure in device extension. here so that
964 // forthcoming functions can use/modify config structure.
965 pDevExt->pParams = pParams;
966 pDevExt->edmaWordSize = pParams->sio.wordSize;
968 // allocate Port resources.
969 // This must come before DMA configuration
970 result = SAP_PORT_FTABLE_alloc (device);
971 if (result)
972 {
973 Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
974 return result;
975 }
977 // .............................................................................
978 // EDMA configuration
980 // DA10x McASP0 Specific
981 if (pParams->sio.moduleNum == 0)
982 {
983 hEdma = hEdma0;
984 if (device->mode == DEV2_INPUT)
985 {
986 Que_num = 0;
987 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
988 }
989 else
990 {
991 Que_num = 1;
992 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
993 }
994 }
995 // DA10x McASP1 Specific
996 else if (pParams->sio.moduleNum == 1)
997 {
998 hEdma = hEdma1;
999 if (device->mode == DEV2_INPUT)
1000 {
1001 Que_num = 0;
1002 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1003 }
1004 else
1005 {
1006 Que_num = 1;
1007 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1008 }
1009 }
1010 // DA10x McASP2 Specific
1011 else if (pParams->sio.moduleNum == 2)
1012 {
1013 hEdma = hEdma1;
1014 if (device->mode == DEV2_INPUT)
1015 {
1016 Que_num = 0;
1017 pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1018 }
1019 else
1020 {
1021 Que_num = 1;
1022 pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1023 }
1024 }
1027 for (i=0; i < pDevExt->numEdmaParams; i++) {
1029 reqTcc = EDMA3_DRV_TCC_ANY;
1030 pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1031 edmaResult = EDMA3_DRV_requestChannel (
1032 hEdma,
1033 &pDevExt->edmaParams[i].hEdmaParam,
1034 &reqTcc,
1035 (EDMA3_RM_EventQueue) Que_num,
1036 SAP_isrCallback,
1037 (void *) device);
1039 if (edmaResult != EDMA3_DRV_SOK)
1040 return SIO2_EALLOC;
1042 //not running => can use non-atomic functions
1043 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1045 }
1047 reqTcc = EDMA3_DRV_TCC_ANY;
1048 pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1049 edmaResult = EDMA3_DRV_requestChannel (
1050 hEdma,
1051 &pDevExt->errorEdma,
1052 &reqTcc,
1053 (EDMA3_RM_EventQueue)Que_num,
1054 SAP_isrCallback,
1055 (void *) device);
1056 if (edmaResult != EDMA3_DRV_SOK)
1057 return SIO2_EALLOC;
1059 // allocate edma channel -- also disable and clear the interrupt
1062 pDevExt->firstTCC = pDevExt->activeEdma ;
1063 edmaResult = EDMA3_DRV_requestChannel (
1064 hEdma,
1065 &pDevExt->activeEdma,
1066 &pDevExt->firstTCC,
1067 (EDMA3_RM_EventQueue) 0,
1068 SAP_isrCallback,
1069 (void *) device);
1070 if (edmaResult != EDMA3_DRV_SOK)
1071 {
1072 Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1073 return SIO2_EALLOC;
1074 }
1076 // Configure error transfer
1077 // make cnt same as # of channels in order to maintain alignment
1078 // and the error transfer small so that we never have to wait
1079 // long for it to complete and trigger a linked transfer. This is
1080 // important for establishing output timing when we are idling with
1081 // clocks still running. Is fine for Rx as well.
1082 result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1084 Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1086 return SIO2_OK;
1087 } // SAP_config
1089 // -----------------------------------------------------------------------------
1091 Int SAP_shutdown (DEV2_Handle device)
1092 {
1093 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1094 SIO2_Handle stream = (SIO2_Handle) device;
1095 DEV2_Frame *pFrame;
1096 Int i;
1097 EDMA3_DRV_Handle hEdma;
1098 //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1100 if (pDevExt->shutDown)
1101 return SIO2_EBADIO;
1103 if (pDevExt->pParams == NULL)
1104 return SIO2_EINVAL;
1106 if (pDevExt->pParams->sio.moduleNum == 0)
1107 hEdma = hEdma0;
1108 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1109 hEdma = hEdma1;
1110 if (pDevExt->activeEdma != EDMA_HINV)
1111 EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1113 // reset queues
1114 while (!Queue_empty(device->todevice)) {
1115 // place oustanding requests onto holding queue
1116 pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1117 Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1118 }
1120 while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1121 // pull frame from holding queue and place on user queue
1122 pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1123 Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1124 }
1127 while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1128 Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1130 // not running => can use non-atomic functions
1131 for (i=0; i < pDevExt->numEdmaParams; i++)
1132 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1134 // reset counter
1135 pDevExt->numQueued = 0;
1137 //DJDBG_SAP_EDMA_dumpParams(1);
1138 // make sure active is linked to error
1139 EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1141 // think this is better (from SIO_idle for standard model )
1142 // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1143 while (!Queue_empty(device->fromdevice)) {
1144 /* place oustanding requests onto holding queue */
1145 pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1146 Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1147 }
1148 Semaphore_reset (pDevExt->sync, 0);
1150 pDevExt->shutDown = 1;
1151 pDevExt->numParamSetup = 0;
1153 /*result = SAP_DMA_FTABLE_unlock (device);
1154 if (result)
1155 {
1156 //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1157 return result;
1158 } */
1160 return SIO2_OK;
1161 } // SAP_shutdown
1163 // -----------------------------------------------------------------------------
1164 int gSapWatchDogThrottle = 0; //DJDBG
1165 int gSapWatchDogIn =0;
1166 int gSapWatchDogOut = 0;
1167 int gSapWatchDogInSemPost = 0;
1168 int gSapWatchDogOutSemPost = 0;
1170 Void SAP_watchDog (Void)
1171 {
1172 DEV2_Handle device;
1173 SAP_DeviceExtension *pDevExt;
1174 int i, oldMask, result;
1176 //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1178 // do nothing if SAP_init not yet called
1179 if (!SAP_initialized)
1180 {
1181 Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1182 return;
1183 }
1185 // protect context
1186 Task_disable (); // needed since we may call SEM_post
1187 //oldMask = Hwi_disable ();
1190 //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1192 for (i=0; i < sapDrv.numDevices; i++) {
1193 device = sapDrv.device[i];
1195 //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1197 pDevExt = (SAP_DeviceExtension *) device->object;
1199 // do nothing if not running
1200 if (!pDevExt->runState)
1201 continue;
1203 // call board specific watchdog
1204 // TODO: handle return value
1205 SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1207 // if port layer returns error then must need to clean up
1208 result = SAP_PORT_FTABLE_watchDog (device);
1209 if (result) {
1210 // set errorState which will force owner thread
1211 // to clean up via SIO_idle()
1212 pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1213 if(device->mode == DEV2_INPUT)
1214 gSapWatchDogIn++;
1215 else
1216 gSapWatchDogOut++;
1218 //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1219 /* if(gSapWatchDogThrottle == 0) //DJDBG
1220 {
1221 Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1222 }
1223 gSapWatchDogThrottle ++;
1224 if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1225 // if outstanding pend then post to free owner thead
1226 if (!Semaphore_pend(pDevExt->sync, 0))
1227 {
1228 if(device->mode == DEV2_INPUT)
1229 gSapWatchDogInSemPost++;
1230 else
1231 gSapWatchDogOutSemPost++;
1232 Semaphore_post (pDevExt->sync);
1233 }
1234 }
1235 }
1238 // renable interrupts and task manager.
1239 // If we posted to the semaphore then the TSK_enable call will lead to
1240 // an immediate task switch to the associated audio thread.
1241 //Hwi_restore (oldMask);
1242 Task_enable ();
1244 } // SAP_watchDog
1246 // -----------------------------------------------------------------------------
1247 // Assumes that EDMA3 dispatcher handles TCC clearing.
1249 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1250 {
1251 DEV2_Handle device;
1252 SAP_DeviceExtension *pDevExt;
1253 DEV2_Frame *pFrame;
1254 unsigned int opt;
1255 EDMA3_DRV_Handle hEdma;
1257 // could be here after Tx idle/overrun and this is the interrupt
1258 // for the last occuring error transfer so there is no transfer
1259 // to release, we just clear the int and exit.
1261 device = (DEV2_Handle) context;
1262 pDevExt = (SAP_DeviceExtension *)(device->object);
1263 //if (pDevExt->pParams == NULL)
1264 //return SIO2_EINVAL;
1266 if (pDevExt->pParams->sio.moduleNum == 0)
1267 hEdma = hEdma0;
1268 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1269 hEdma = hEdma1;
1271 if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1272 // if here then an interrupt occured due to errorEdma or valid
1273 // transfer, we assume the xfer is long enough so it will not complete
1274 // before we are finished here.
1276 // if last transfer was valid then complete it
1277 if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1279 // pull frame from holding queue
1280 pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1282 // if used param entry then return it to queue
1283 if (pFrame->misc != NULL)
1284 {
1285 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1286 if (device->mode == 1)
1287 gisrOutput+=100;
1288 }
1290 // decrement count
1291 pDevExt->numQueued -= 1;
1292 //gIsrCnt++;
1293 if (device->mode == 1)
1294 gIsrOutputCnt++;
1295 else
1296 gIsrInputCnt++;
1297 // place frame onto user queue and signal user thread
1298 Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1300 //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1301 // signal user thread
1302 Semaphore_post (pDevExt->sync);
1303 #if 0
1304 if(gIsrCnt > 10) { //DJDBG
1305 Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1307 }
1308 #endif
1309 }
1310 else
1311 gIsrElseCnt++;
1313 // determine if currently transferring buffer is valid based on interrupt enable bit
1314 // only valid transfers will generate interrupts
1315 EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1317 if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1318 {
1319 if (device->mode == 1)
1320 gIsrOutErrCnt++;
1321 else
1322 gIsrInErrCnt++;
1323 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1324 }
1326 } // runState
1327 else
1328 {
1329 if (pDevExt->runState != 1)
1330 gIsrRunCnt++;
1331 else
1332 gIsrNotRunCnt++;
1333 }
1335 return;
1336 } //SAP_isrCallback
1338 // -----------------------------------------------------------------------------
1340 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1341 {
1342 EDMA3_DRV_Handle hEdma;
1343 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1344 // int mcbspNum = pDevExt->pParams->sio.moduleNum;
1346 if (pDevExt->pParams == NULL)
1347 return SIO2_EINVAL;
1349 if (pDevExt->pParams->sio.moduleNum == 0)
1350 hEdma = hEdma0;
1351 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1352 hEdma = hEdma1;
1354 // TODO: shouldn't this just be tcc interrupt disable?
1355 // at least until linkage phase...
1356 unsigned int key = Hwi_disable (); //DJDBG
1358 if(targetEdma == NULL)
1359 {
1360 Log_info0("targetEdma is NULL");
1361 }
1362 // configure transfer
1363 if(pFrame->addr == NULL) //DJDBG
1364 {
1365 Log_info0("pFrame has NULL address?");
1366 }
1367 SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1369 if (parentEdma != EDMA_HINV)
1370 EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1373 Hwi_restore (key); //DJDBG
1375 return SIO2_OK;
1376 } // SAP_setupXfer
1378 // -----------------------------------------------------------------------------
1379 // Configure EDMA3 parameter entry
1381 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1382 {
1383 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1384 EDMA3_DRV_Handle hEdma;
1385 EDMA3_DRV_PaRAMRegs edmaConfig;
1387 if (pDevExt->pParams == NULL)
1388 return SIO2_EINVAL;
1390 if (pDevExt->pParams->sio.moduleNum == 0)
1391 hEdma = hEdma0;
1392 else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1393 hEdma = hEdma1;
1394 MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1395 // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1397 //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1399 // Init opt parameter to 0 which, without being overriden, configures as:
1400 // A synchronized transfer (no FIFO mode on src or dst)
1401 // no chaining or intermediate interrupts
1402 // param is not static
1403 // normal completion
1404 // don't generate an interrupt (overriden below for regular xfers)
1405 edmaConfig.opt = 0;
1407 // not transferring blocks so c index is 0
1408 edmaConfig.destCIdx = 0;
1409 edmaConfig.srcCIdx = 0;
1411 edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1412 if (device->mode == DEV2_OUTPUT) {
1413 //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1414 edmaConfig.opt |= 2;
1415 }
1416 else {
1417 //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1418 edmaConfig.opt |= 1;
1419 }
1421 // if regular transfer then enable interrupt with tcc code
1422 if (targetEdma != pDevExt->errorEdma) {
1423 edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1424 edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1425 edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1426 }
1429 edmaConfig.aCnt = 4;
1430 edmaConfig.bCnt = pDevExt->numSers;
1431 edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1432 edmaConfig.bCntReload = edmaConfig.bCnt;
1435 // handle direction specific requirements
1436 if (device->mode == DEV2_INPUT) {
1437 edmaConfig.srcBIdx = 0;
1438 edmaConfig.srcAddr = (unsigned int) (hPort->rbufAddr);
1440 if (addr) {
1441 edmaConfig.destBIdx = pDevExt->edmaWordSize;
1442 edmaConfig.destAddr = addr;
1443 edmaConfig.destCIdx = pDevExt->edmaWordSize * pDevExt->numSers ;
1444 if(pDevExt->edmaWordSize == 2)
1445 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1446 }
1447 else {
1448 //if(pDevExt->edmaWordSize == 2)
1449 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1450 edmaConfig.destBIdx = 0;
1451 edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1452 edmaConfig.cCnt = 1;
1453 }
1454 }
1455 else {
1456 edmaConfig.destBIdx = 0;
1457 edmaConfig.srcBIdx = pDevExt->edmaWordSize;
1458 edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1459 if (addr) {
1460 edmaConfig.srcCIdx = pDevExt->edmaWordSize * pDevExt->numSers ;
1461 edmaConfig.srcAddr = addr;
1462 //Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1463 }
1464 else {
1465 edmaConfig.srcBIdx = 0;
1466 edmaConfig.srcAddr = (unsigned int) &sap_UNDER[0];
1467 #if 1
1468 //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1469 edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1470 #endif
1471 }
1472 }
1473 edmaConfig.srcAddr = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1474 edmaConfig.destAddr = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1476 Log_info5("SAP: Inside SAP_EDMA_setupParam with size=0x%x, targetEdma = 0x%x, CCNT = %d with dest-addr: 0x%x and OPT=0x%x", size, targetEdma, edmaConfig.cCnt, edmaConfig.destAddr, edmaConfig.opt);
1477 Log_info5("SAP: Inside SAP_EDMA_setupParam with aCnt=0x%x, bCnt = 0x%x, destBIdx = 0x%x destCIdx: 0x%x and bCntReload=0x%x", edmaConfig.aCnt, edmaConfig.bCnt, edmaConfig.destBIdx, edmaConfig.destCIdx, edmaConfig.bCntReload);
1479 EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1481 // link child xfer
1482 if (childEdma != EDMA_HINV)
1483 EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1485 return SIO2_OK;
1486 } //SAP_setupParam