]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_dsp/sap/sap_mcasp.c
Fixed problem of input task being stuck when input stream stops:
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap_mcasp.c
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 // McASP implementations for SAP_PORT (d10 specific)
39 //
40 //
41 //
43 #include <stdio.h>
44 #include <xdc/std.h>
46 #include <sio2.h>
47 #include "sap_mcasp.h"
49 #define ENABLE_TRACE
50 #ifdef ENABLE_TRACE
51 #include <xdc/runtime/Log.h>
52 //#define TRACE_TERSE0(a)         Log_info0(a)
53 #endif
55 // Allow a developer to selectively enable tracing.
56 // For release, you might set the mask to 0, but I'd always leave it at 1.
57 #define CURRENT_TRACE_MASK      0x01   // terse only
59 #define TRACE_MASK_TERSE        0x01   // only flag errors and show init
60 #define TRACE_MASK_GENERAL      0x02   // half dozen lines per frame
61 #define TRACE_MASK_VERBOSE      0x04   // trace full operation
62 #define TRACE_MASK_DATA         0x08   // Show data
63 #define TRACE_MASK_TIME         0x10   // Timing related traces
65 #if (CURRENT_TRACE_MASK & TRACE_MASK_TERSE)
66     //#define TRACE_TERSE(a)          LOG_printf a
67     #define TRACE_TERSE0(a)         Log_info0(a)
68     #define TRACE_TERSE1(a,b)       Log_info1(a,b)
69     #define TRACE_TERSE2(a,b,c)     Log_info2(a,b,c)
70     #define TRACE_TERSE3(a,b,c,d)   Log_info3(a,b,c,d)
71     #define TRACE_TERSE4(a,b,c,d,e) Log_info4(a,b,c,d,e)
72 #else
73     //#define TRACE_TERSE(a)
74     #define TRACE_TERSE0(a)
75     #define TRACE_TERSE1(a,b)
76     #define TRACE_TERSE2(a,b,c)
77     #define TRACE_TERSE3(a,b,c,d)
78     #define TRACE_TERSE4(a,b,c,d,e)
79 #endif
81 #if (CURRENT_TRACE_MASK & TRACE_MASK_GENERAL)
82     //#define TRACE_GEN(a)            LOG_printf a
83     #define TRACE_GEN0(a)           Log_info0(a)
84     #define TRACE_GEN1(a,b)         Log_info1(a,b)
85     #define TRACE_GEN2(a,b,c)       Log_info2(a,b,c)
86     #define TRACE_GEN3(a,b,c,d)     Log_info3(a,b,c,d)
87     #define TRACE_GEN4(a,b,c,d,e)   Log_info4(a,b,c,d,e)
88 #else
89     //#define TRACE_GEN(a)
90     #define TRACE_GEN0(a)
91     #define TRACE_GEN1(a,b)
92     #define TRACE_GEN2(a,b,c)
93     #define TRACE_GEN3(a,b,c,d)
94     #define TRACE_GEN4(a,b,c,d,e)
95 #endif
97 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
98     #define TRACE_DATA(a) LOG_printf a
99 #else
100     #define TRACE_DATA(a)
101 #endif
103 #if (CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE)
104     #define TRACE_VERBOSE(a)        LOG_printf a
105     #define TRACE_VERBOSE0(a)           Log_info0(a)
106     #define TRACE_VERBOSE1(a,b)         Log_info1(a,b)
107     #define TRACE_VERBOSE2(a,b,c)       Log_info2(a,b,c)
108     #define TRACE_VERBOSE3(a,b,c,d)     Log_info3(a,b,c,d)
109     #define TRACE_VERBOSE4(a,b,c,d,e)   Log_info4(a,b,c,d,e)
111 #else
112     #define TRACE_VERBOSE(a)
113     #define TRACE_VERBOSE0(a)
114     #define TRACE_VERBOSE1(a,b)
115     #define TRACE_VERBOSE2(a,b,c)
116     #define TRACE_VERBOSE3(a,b,c,d)
117     #define TRACE_VERBOSE4(a,b,c,d,e)
118 #endif
119 // .............................................................................
120 // Resource Access Control
121 //
122 // The resources which must be controlled here are the McASP registers. There
123 // is layer context (sapMcaspDrv) but this essentially only holds the
124 // addresses of the resources. Further this is intitialized, i.e. written to
125 // only once, before the task scheduler begins and hence need not be controlled.
126 // Therefore we focus only on the McASP registers themselves.
127 // 
128 // There are two sources of switching which must be considered:
129 //        (A) Interrupts
130 //        (B) Tasks
131 //
132 // While SAP does not access McASP registers at ISR levels, other users may 
133 // access some of the registers for other functionality, e.g. GPIO, at any
134 // priority level. Therefore all accesses to these registers must be protected
135 // using HWI disable/enable blocks. Registers in this category are:
136 //        PDIR/PFUNC/PDOUT/PDIN
137 // 
138 // Within (B) there are two types of accesses which we must consider:
139 //        (i)  Modifications to non-direction specific registers not in (A)
140 //        (ii) Modifications to direction specific registers
141 // 
142 // Within this layer there are no accesses to registers of type (i). If there
143 // were then there are at least two choices for  appropriate access control.
144 //        . HWI disable/enable macros
145 //            This is effective but inefficient since it blocks all
146 //            processing regardless of its resource usage.
147 //            
148 //        . Raise the TSK priority > max priority of all tasks using SAP.
149 //            This assumes that no tasks using SAP run at TSK_MAXPRI.
150 //
151 // For (ii) there is no need to perform resource access control since these
152 // registers are *owned* by the device and hence the calling thread and not
153 // accessed by any other context. Registers in this category are:
154 //        AFSyCTL, ACLKyCTL, AHCLKyCTL, SRCTLz, yTDM, yGBLCTL, yINTCTL,
155 //        ySTAT, ySLOTCNT, yCLKCHK, yBUFz
156 // where y is X or R and z is between 1 and 15.
157 // 
158 // Of concern maybe the ASYNC bit in the ACLKXCTL since this is arguably a
159 // receive option in a transmit register. However, to date, this bit is only
160 // modified when the transmitter is configured not when the input is
161 // configured; which would be problematic.
162 // 
163 // Also we make no assumptions about the calling priority; e.g. we do not
164 // depend on the SAP layer to disable switching before making a call to this
165 // (SAP_MCASP) layer.
166 // .............................................................................
168 // max time to wait in SAP_MCASP_enableX functions (in mS)
169 #define REGISTER_SET_TIMEOUT 2.
171 // .............................................................................
172 // Function table
174 Int  SAP_MCASP_alloc    (DEV2_Handle device);
175 Int  SAP_MCASP_close    (DEV2_Handle device);
176 Int  SAP_MCASP_enable   (DEV2_Handle device);
177 Void SAP_MCASP_init     (Void);
178 Int  SAP_MCASP_open     (DEV2_Handle device);
179 Int  SAP_MCASP_reset    (DEV2_Handle device);
180 Int  SAP_MCASP_watchDog (DEV2_Handle device);
182 Int  SAP_MCASP_waitSet (MCASP_Handle hMcasp, Uint32 wrReg, Uint32 rdReg, Uint32 mask, Uint32 timeout);
183 //Int  SAP_MCASP_updateDITRam(DEV_Handle device );
185 SAP_MCASP_Fxns SAP_MCASP_FXNS = 
187     SAP_MCASP_alloc,
188     SAP_MCASP_close,
189     SAP_MCASP_enable,
190     SAP_MCASP_init,
191     SAP_MCASP_open,
192     SAP_MCASP_reset,
193     SAP_MCASP_watchDog,
194     SAP_MCASP_waitSet
195 };
197 SAP_MCASP_DriverObject sapMcaspDrv;
199 // -----------------------------------------------------------------------------
201 Void SAP_MCASP_init (Void)
203     volatile Uint32 *base;
204     volatile Uint32 *fifoBase;
205     volatile Uint32 *pSers;
206     int i, j;
208     TRACE_TERSE0("SAP_MCASP_init");
209     // open McASP ports via CSL. This CSL call, MCASP_open, does not require
210     // CSL_init which is important since this function is called before main
211     // and hence before any chance to call CSL_init.
212     for (i=0; i < _MCASP_PORT_CNT; i++) {
213         sapMcaspDrv.hPort[i] = MCASP_open (i, MCASP_OPEN);
214         base     = (volatile Uint32 *) sapMcaspDrv.hPort[i]->baseAddr;
215         fifoBase = base + _MCASP_FIFO_OFFSET;
216         //if (fifoBase[_MCASP_AFIFOREV_OFFSET] == 0x44311100)
217             sapMcaspDrv.fifoPresent[i] = 1;
218         //else
219           //  sapMcaspDrv.fifoPresent[i] = 0;
221         // zero out all serializers
222         pSers = &base[_MCASP_SRCTL0_OFFSET];
223         for (j=0; j<_MCASP_CHANNEL_CNT; j++)
224         {
225             Uint32 save = *pSers;
226             *pSers = 0;
227             pSers++;
228         }
229         base[_MCASP_PDIR_OFFSET] = 0;  // all input by default
230     }
232 } // SAP_MCASP_init
234 // -----------------------------------------------------------------------------
235 // TODO:
236 //     Add control for:
237 //        1. DLB
238 //        2. DIT
239 //        3. AMUTE?
241 Int SAP_MCASP_alloc (DEV2_Handle device)
243     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
244     const SAP_Params *pParams = pDevExt->pParams;
245     MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
246     volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
247     volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
248     Int i, oldMask, tdmMask;
250     //TRACE_TERSE1(("SAP_MCASP_alloc(0x%x)", device));
252     // validate mcasp number
253     if (pParams->sio.moduleNum >= _MCASP_PORT_CNT)
254         return DEV2_EINVAL;
256     // Could/should validate pin mask here.
257     // Check: McAsp0 has 16 pins.  McAsp1 has 10.  McAsp2 has 6.
258     // !!!! This code is DA10x specific !!!!!!!!!!
259     switch (pParams->sio.moduleNum)
260     {
261     case 0:
262         if (pParams->sap.pinMask & 0x00FF0000)
263         {
264                 //TRACE_TERSE1(("ERROR. McAsp0 has only 16 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
265             System_printf("ERROR. McAsp0 has only 16 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
266             System_abort("ABORT. McAsp0 has only 16 pins.");
267         }
268         break;
269     case 1:
270         if (pParams->sap.pinMask & 0x00FFFC00)
271         {
272                 //TRACE_TERSE1(("ERROR. McAsp1 has only 10 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
273                 System_printf("ERROR. McAsp1 has only 10 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
274                 System_abort("ABORT. McAsp1 has only 10 pins.");
275         }
276         break;
277     case 2:
278         if (pParams->sap.pinMask & 0x00FFFFC0)
279         {
280                 //TRACE_TERSE1(("ERROR. McAsp2 has only 6 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
281                 System_printf("ERROR. McAsp2 has only 6 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
282             System_abort("ABORT. McAsp2 has only 6 pins.");
283         }
284         break;
285     }
287     // lock context -- see class (A) above
288     oldMask = Hwi_disable ();
290     // use pinMask to configure MCASP vs. GPIO functionality
291     base[_MCASP_PFUNC_OFFSET] &= ~(pParams->sap.pinMask & 0xFE00FFFF);
293     // infer serializer config from pinMask and mode
294     //TRACE_TERSE2(("SAP_MCASP_alloc(): serializer: pinMask : 0x%x PDIR on entry: 0x%x.", pParams->sap.pinMask, base[_MCASP_PDIR_OFFSET]));
295     pDevExt->numSers = 0;
296     for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
297         if (pParams->sap.pinMask & (1 << i)) {
298             pDevExt->numSers += 1;
299             if (device->mode == DEV2_INPUT) {
300                 *pSers = MCASP_SRCTL_SRMOD_RCV;
301                 if (*pSers != MCASP_SRCTL_SRMOD_RCV) {
302                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: write to pSers failed: 0x%x.  *pSers: 0x%x", pSers, *pSers));
303                 }
304                 else {
305                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: pSers: 0x%x.  *pSers: 0x%x", pSers, *pSers));
306                 }
307                 base[_MCASP_PDIR_OFFSET] &= ~(1 << i);
308                 //TRACE_TERSE1(("SAP_MCASP_alloc(): serializer input: clear pin %d.", i));
309             }
310             else {
311                 *pSers = MCASP_SRCTL_SRMOD_XMT;
312                 if (*pSers != MCASP_SRCTL_SRMOD_XMT) {
313                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: write to pSers failed: 0x%x.  *pSers: 0x%x", pSers, *pSers));
314                 }
315                 else {
316                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: pSers: 0x%x.  *pSers: 0x%x", pSers, *pSers));
317                 }
318                 base[_MCASP_PDIR_OFFSET] |= (1 << i);
319                 //TRACE_TERSE1(( "SAP_MCASP_alloc(): serializer output: set pin %d.", i));
320             }
321         }
322         *pSers++;
323     }
324     //TRACE_TERSE3(("SAP_MCASP_alloc(): serializer PDIR: 0x%x, numSers %d, *pSers: 0x%x", base[_MCASP_PDIR_OFFSET], pDevExt->numSers, *pSers));
327     if (device->mode == DEV2_INPUT) {
328         MCASP_ConfigRcv *pRxConfig = (MCASP_ConfigRcv *)pParams->sio.pConfig;
330         // infer clock pin directions
331         if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKR_MASK)
332             if (pRxConfig->aclkrctl & _MCASP_ACLKRCTL_CLKRM_MASK)
333                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKR_MASK;
334             else
335                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKR_MASK;
336         if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKR_MASK)
337             if (pRxConfig->ahclkrctl & _MCASP_AHCLKRCTL_HCLKRM_MASK)
338                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKR_MASK;
339             else
340                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKR_MASK;
341         if (pParams->sap.pinMask & _MCASP_PFUNC_AFSR_MASK)
342             if (pRxConfig->afsrctl & _MCASP_AFSRCTL_FSRM_MASK)
343                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSR_MASK;
344             else
345                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSR_MASK;
347         //TRACE_TERSE1(( "SAP_MCASP_alloc(): rx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
348         MCASP_configRcv (hPort, pRxConfig);
349     }
350     else {
351         MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
353         // infer clock pin directions
354         if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKX_MASK)
355             if (pTxConfig->aclkxctl & _MCASP_ACLKXCTL_CLKXM_MASK)
356                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKX_MASK;
357             else
358                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKX_MASK;
359         if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKX_MASK)
360             if( pTxConfig->ahclkxctl & _MCASP_AHCLKXCTL_HCLKXM_MASK )
361                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKX_MASK;
362             else
363                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKX_MASK;
364         if (pParams->sap.pinMask & _MCASP_PFUNC_AFSX_MASK)
365             if( pTxConfig->afsxctl & _MCASP_AFSXCTL_FSXM_MASK )
366                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSX_MASK;
367             else
368                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSX_MASK;
370         if (pParams->sap.pinMask & _MCASP_PFUNC_AMUTE_MASK)
371                         base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AMUTE_MASK;
372         // HACK -- determine DIT need by FXWID
373         if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
374             base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_RMK (MCASP_DITCTL_VB_ZERO, MCASP_DITCTL_VA_ZERO, MCASP_DITCTL_DITEN_DIT);
375         else
376             base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_DEFAULT;
378         //TRACE_TERSE1(( "SAP_MCASP_alloc(): tx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
379         MCASP_configXmt (hPort, pTxConfig);
380     }
381     SAP_PORT_FTABLE_reset (device);
383     // unlock context
384     Hwi_restore (oldMask);
386     // determine number of TDM slots (32 max), if DIT must be 2, must be
387     // done after MCASP_config since the registers are referenced directly
388     if (device->mode == DEV2_OUTPUT) {
389         if ((base[_MCASP_AFSXCTL_OFFSET] & _MCASP_AFSXCTL_XMOD_MASK) ==
390             (MCASP_AFSXCTL_XMOD_OF(0x180) << _MCASP_AFSXCTL_XMOD_SHIFT) )
391             tdmMask = 0x3;
392         else
393             tdmMask = base[_MCASP_XTDM_OFFSET];
394     }
395     else
396         tdmMask = base[_MCASP_RTDM_OFFSET];
398     pDevExt->numSlots = 0;
399     for (i=0; i < 32; i++)
400         if (tdmMask & (1 << i))
401             pDevExt->numSlots +=1;
403     //Log_info2("Leaving SAP_MCASP_alloc: tdmMask: 0x%x.  numSlots: %d", tdmMask, pDevExt->numSlots);
404     return DEV2_OK;
405 } // SAP_MCASP_alloc
407 // -----------------------------------------------------------------------------
409 Int SAP_MCASP_close (DEV2_Handle device)
411     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
412     const SAP_Params *pParams = pDevExt->pParams;
413     MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
414     volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
415     volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
416     Int i;
418     //TRACE_TERSE1(( "SAP_MCASP_close(0x%x)", device));
420     for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
421         if (pParams->sap.pinMask & (1 << i))
422             *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
423         *pSers++;
424     }
426     return DEV2_OK;
427 } //SAP_MCASP_close
429 // -----------------------------------------------------------------------------
430 // Enable appropriate section of McASP. See McASP data sheet (Operation) for
431 // more info on the steps. 
433 Int SAP_MCASP_enable (DEV2_Handle device)
435     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
436     const SAP_Params *pParams = pDevExt->pParams;
437     Int mcaspNum = pParams->sio.moduleNum;
438     MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
439     volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
440     volatile Uint32 *fifoBase = base + _MCASP_FIFO_OFFSET;
441     int i, mask0, mask1, mask2, mask3, mask4;
442     Uint32 wrReg, rdReg;
443     Int result = 0;
445     //TRACE_TERSE1(( "SAP_MCASP_enable(0x%x)", device));
447     // STEP 1: Reset McASP to default values
448     // This was done in preceding function call. 
450     // STEP 2: Enable FIFO
451     // If present, for input and output. Set NUMEVT = NUMDMA to disable pacing
452     // so that the same DMA setup can be used with FIFO enabled or disbaled
453     if (sapMcaspDrv.fifoPresent[mcaspNum]) {
454         if (device->mode == DEV2_OUTPUT) {
455             fifoBase[_MCASP_WFIFOCTL_OFFSET] =
456                 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMEVT_SHIFT) |
457                 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMDMA_SHIFT); 
458             fifoBase[_MCASP_WFIFOCTL_OFFSET] |=
459                 (MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
461             //TRACE_TERSE1(( "SAP_MCASP_enable(): output fifos: numSers %d", pDevExt->numSers));
462         }
463         else {
464             fifoBase[_MCASP_RFIFOCTL_OFFSET] =
465                 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMEVT_SHIFT) |
466                 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMDMA_SHIFT); 
467             fifoBase[_MCASP_RFIFOCTL_OFFSET] |=
468                 (MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
469            // TRACE_TERSE1(( "SAP_MCASP_enable(): input fifos: numSers %d", pDevExt->numSers));
470         }
471     }
473     mask1 = 0;
474     rdReg = _MCASP_GBLCTL_OFFSET;
475     if (device->mode == DEV2_INPUT) {
476         wrReg = _MCASP_RGBLCTL_OFFSET;
477         mask0 = MCASP_FMKS (GBLCTL,RHCLKRST,ACTIVE);
478         if (base[_MCASP_ACLKRCTL_OFFSET] & _MCASP_ACLKRCTL_CLKRM_MASK)
479             mask1 = MCASP_FMKS (GBLCTL,RCLKRST,ACTIVE);
480         mask2 = MCASP_FMKS (GBLCTL,RSRCLR,ACTIVE);
481         mask3 = MCASP_FMKS (GBLCTL,RSMRST,ACTIVE);
482         mask4 = MCASP_FMKS (GBLCTL,RFRST,ACTIVE);
483     }
484     else {
485         wrReg = _MCASP_XGBLCTL_OFFSET;
486         mask0 = MCASP_FMKS (GBLCTL,XHCLKRST,ACTIVE);
487         if (base[_MCASP_ACLKXCTL_OFFSET] & _MCASP_ACLKXCTL_CLKXM_MASK)
488             mask1 = MCASP_FMKS (GBLCTL,XCLKRST,ACTIVE);
489         mask2 = MCASP_FMKS (GBLCTL,XSRCLR,ACTIVE);
490         mask3 = MCASP_FMKS (GBLCTL,XSMRST,ACTIVE);
491         mask4 = MCASP_FMKS (GBLCTL,XFRST,ACTIVE);
492     }
494     // STEP 4: Start high-frequency clocks
495     // According to McASP datasheet this step is necessary even if the high-
496     // frequency clocks are external.
497     if (mask0) {
498         //TRACE_TERSE1(( "SAP_MCASP_enable(): HF clock mask 0: 0x%x.  ", mask0));
499         result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask0, REGISTER_SET_TIMEOUT);
500         if (result)
501             return result;
502     }
504     // STEP 5: Enable bit clock generator if internally generated
505     if (mask1) {
506         //TRACE_TERSE1(( "SAP_MCASP_enable(): bit clock mask 1: 0x%x.  ", mask1));
507         result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask1, REGISTER_SET_TIMEOUT);
508         if (result)
509             return result;
510     }
512     // STEP 6: Setup DMA (this was done earlier -- out of order OK)
514     // STEP 7: Activate serializers
515     //TRACE_TERSE1(( "SAP_MCASP_enable(): serializers mask 2: 0x%x.  ", mask2));
516     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask2, REGISTER_SET_TIMEOUT);
517     if (result)
518         return result;
520     // STEP 8: Verify that all transmit buffers are serviced.
521     // This is guaranteed to succeed since by now we now that there is a clock
522     // and hence XDATA empty will be generated
524     if (device->mode == DEV2_OUTPUT)
525     {
526         volatile Uint32 *pSers;
527         volatile int timeout;
529         result = 0;
530         // configure serializers and associated pins
531         pSers =&base[_MCASP_SRCTL0_OFFSET];
532         for (i=0; i < _MCASP_CHANNEL_CNT; i++)
533         {
534             if (pDevExt->pParams->sap.pinMask & (1 << i))
535             {
536                 //Log_info3(( "SAP_MCASP_enable(): wait for serializer %d.  pSers: 0x%x, *pSers: 0x%x", i, pSers, *pSers));
537                 while ((*pSers & _MCASP_SRCTL_XRDY_MASK) != 0);
538             }
539             *pSers++;
540         }
541         if (result)
542         {
543           #ifdef ENABLE_TRACE
544                 TRACE_TERSE0(( "SAP_MCASP_enable(): Stopping trace on serializer error."));
545                 //Log_disable(&trace);
546           #endif
547             return result;
548         }
549     }
551     // STEP 9: Release state machine from reset
552     //TRACE_TERSE1(( "SAP_MCASP_enable(): reset state machine, mask 3: 0x%x.", mask3));
553     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask3, REGISTER_SET_TIMEOUT);
554     if (result)
555         return result;
557     // STEP 10: Release FS generators from reset
558     // This needs to be enabled even if external frame sync because counter
559     //   for frame sync errors is in frame sync generator.
560     //TRACE_TERSE1(( "SAP_MCASP_enable(): release FS generators, mask 4: 0x%x.", mask4));
561     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask4, REGISTER_SET_TIMEOUT);
563     //TRACE_TERSE1(( "SAP_MCASP_enable(): SAP_MCASP_enable(0x%x) complete.", device));
564     return result;
565 } //SAP_MCASP_enable
567 // -----------------------------------------------------------------------------
569 Int SAP_MCASP_open (DEV2_Handle device)
571     return DEV2_OK;
572 } // SAP_MCASP_open
574 // -----------------------------------------------------------------------------
576 Int SAP_MCASP_reset (DEV2_Handle device)
578     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
579     const SAP_Params *pParams = pDevExt->pParams;
580     Int mcaspNum = pParams->sio.moduleNum;
581     MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
582     int oldhclk, oldclk, newhclk, newclk;
583     volatile int * base = (volatile int *) hPort->baseAddr;
584     volatile Uint32 *fifoBase = (volatile Uint32 *) (base + _MCASP_FIFO_OFFSET);
587     if (device->mode == DEV2_INPUT)
588     {
589         //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) input device.", device));
590         // disable FIFO if present
591         Log_info1("SAP_MCASP_reset(0x%x) input device.", (xdc_IArg)device);
592         if (sapMcaspDrv.fifoPresent[mcaspNum])
593             fifoBase[_MCASP_RFIFOCTL_OFFSET] &=
594                 ~(MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
596         // set to internal clock source (see spru041d.pdf page 117)
597         oldhclk = base[_MCASP_AHCLKRCTL_OFFSET];
598         oldclk  = base[_MCASP_ACLKRCTL_OFFSET];
599         newhclk = (oldhclk & ~_MCASP_AHCLKRCTL_HCLKRM_MASK) | (MCASP_AHCLKRCTL_HCLKRM_INTERNAL << _MCASP_AHCLKRCTL_HCLKRM_SHIFT);
600         newclk  = (oldclk  & ~_MCASP_ACLKRCTL_CLKRM_MASK)   | (MCASP_ACLKRCTL_CLKRM_INTERNAL   << _MCASP_ACLKRCTL_CLKRM_SHIFT);
601         base[_MCASP_AHCLKRCTL_OFFSET] = newhclk;
602         base[_MCASP_ACLKRCTL_OFFSET]  = newclk;
604         // assert RHCLKRST,RCLKRST to force signals to pass through with divide by 1
605         base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RHCLKRST_MASK;
606         base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RCLKRST_MASK;
607         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RHCLKRST_MASK);
608         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RCLKRST_MASK);
610         // Reset all other transmitter functions 
611         base[_MCASP_RGBLCTL_OFFSET] = 0;
612         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSMRST_MASK);
613         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RFRST_MASK);
614         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSRCLR_MASK);
616         // clear status register by writing ones
617         //      don't write to the RTDMSLOT register since it is read only and
618         //      causes a simulator warning when written
619         base[_MCASP_RSTAT_OFFSET] = 0x1F7;
620         while (base[_MCASP_RSTAT_OFFSET] & _MCASP_RSTAT_RDATA_MASK);
622         // restore clock settings
623         base[_MCASP_AHCLKRCTL_OFFSET] = oldhclk;
624         base[_MCASP_ACLKRCTL_OFFSET]  = oldclk;
625     }
626     else 
627     {
628         //TRACE_TERSE1(("SAP_MCASP_reset(0x%x) output device.", device));
629         Log_info1("SAP_MCASP_reset(0x%x) output device.", (xdc_IArg)device);
630         // disable FIFO if present
631         if (sapMcaspDrv.fifoPresent[mcaspNum])
632             fifoBase[_MCASP_WFIFOCTL_OFFSET] &=
633                 ~(MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
635         {
636                 volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
637                 Int i;
639                 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
640                     if (pParams->sap.pinMask & (1 << i))
641                             *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
642                     *pSers++;
643                 }
644         }
645         // set to internal clock source (see spru041d.pdf page 117)
646         oldhclk = base[_MCASP_AHCLKXCTL_OFFSET];
647         oldclk  = base[_MCASP_ACLKXCTL_OFFSET];
648         newhclk = (oldhclk & ~_MCASP_AHCLKXCTL_HCLKXM_MASK) | (MCASP_AHCLKXCTL_HCLKXM_INTERNAL << _MCASP_AHCLKXCTL_HCLKXM_SHIFT);
649         newclk  = (oldclk  & ~_MCASP_ACLKXCTL_CLKXM_MASK)   | (MCASP_ACLKXCTL_CLKXM_INTERNAL   << _MCASP_ACLKXCTL_CLKXM_SHIFT);
650         base[_MCASP_AHCLKXCTL_OFFSET] = newhclk;
651         base[_MCASP_ACLKXCTL_OFFSET]  = newclk;
653         // assert XHCLKRST,XCLKRST to force signals to pass through with divide by 1
654         base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XHCLKRST_MASK;
655         base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XCLKRST_MASK;
656         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XHCLKRST_MASK);
657         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XCLKRST_MASK);
659         // Reset all other transmitter functions 
660         base[_MCASP_XGBLCTL_OFFSET] = 0;
661         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSMRST_MASK);
662         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XFRST_MASK);
663         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSRCLR_MASK);
665         // clear status register by writing ones
666         //      don't write to the RTDMSLOT register since it is read only and
667         //      causes a simulator warning when written
668         base[_MCASP_XSTAT_OFFSET] = 0x1F7;
669         while (base[_MCASP_XSTAT_OFFSET] & _MCASP_XSTAT_XDATA_MASK);
671         {
672             volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
673             Int i;
675             for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
676                 if (pParams->sap.pinMask & (1 << i))
677                     *pSers = MCASP_SRCTL_SRMOD_XMT;
678                 *pSers++;
679             }
680         }
681         // restore clock settings
682         base[_MCASP_AHCLKXCTL_OFFSET] = oldhclk;
683         base[_MCASP_ACLKXCTL_OFFSET]  = oldclk;
684     }
686     //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) complete.", device));
688     return DEV2_OK;
689 } // SAP_MCASP_reset
691 // -----------------------------------------------------------------------------
692 // Set and wait for settings to registers (e.g. GBLCTL) to take effect
693 // we nee such a timeout since if the clocks are not available then 
694 // the settings will never take affect which would lead to a lockup condition.
696 #define INT_MAX 0xFFFFFFFF // maximum value returned by Clock_getTicks
698 Int SAP_MCASP_waitSet (MCASP_Handle hMcasp, Uint32 wrReg, Uint32 rdReg, Uint32 mask, Uint32 timeout)
700     volatile Uint32 *base = (volatile Uint32 *)(hMcasp->baseAddr);
701     Uint32 timeStart, timeNow, elapsed, resMask;
703     //TRACE_TERSE3(("SAP_MCASP_waitSet(0x%x, 0x%x, 0x%x).", hMcasp, wrReg, rdReg));
705     // configure reserved mask to eliminate debug messages from simulator when
706     // writing to read only bits. Set default to all ones so that this function
707     // can be, although is not at this time, used by registers other than
708     // R/XGBCTL.
709     resMask = 0xFFFFFFFF;
710     if (wrReg == _MCASP_RGBLCTL_OFFSET) 
711         resMask = 0x1F;
712     else if (wrReg == _MCASP_XGBLCTL_OFFSET) 
713         resMask = 0x1F00;
715     // set register with mask value
716     base[wrReg] = (base[rdReg] | mask) & resMask;
718     timeStart = Clock_getTicks();
719     while (1) {
720                 if ((base[rdReg] & mask) == mask)
721                         break;
722                 timeNow = Clock_getTicks();
723                 elapsed = timeNow - timeStart;
725                 // check for wrap aound
726                 if (timeNow < timeStart)
727                         elapsed = INT_MAX - timeStart + timeNow;
729                  // return error if timeout reached;
730                  //note: tick period = 1 ms; so timeout in ms = nticks
731                 if (elapsed > timeout)
732                         return SIO2_ETIMEOUT;
733     }
735     return DEV2_OK;
736 } //SAP_MCASP_waitSet
738 int gMcASPWatchDogInCnt=0;
739 int gMcASPWatchDogOutCnt=0;
740 // -----------------------------------------------------------------------------
742 Int SAP_MCASP_watchDog (DEV2_Handle device)
744     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
745     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
746     int stat;
748     if (device->mode == DEV2_INPUT) {
749         stat = MCASP_RGETH (hPort, RSTAT);
750         if ((stat & _MCASP_RSTAT_ROVRN_MASK) ||
751             (stat & _MCASP_RSTAT_RDMAERR_MASK))
752         {
753                 gMcASPWatchDogInCnt++;
754             return DEV2_EBADIO;
755         }
756     }
757     else {
758         stat = MCASP_RGETH (hPort, XSTAT);
759         if ((stat & _MCASP_XSTAT_XUNDRN_MASK) ||
760             (stat & _MCASP_XSTAT_XDMAERR_MASK))
761         {
762                 gMcASPWatchDogOutCnt++;
763                 return DEV2_EBADIO;
764         }
765     }
766     
767     return DEV2_OK;
768 } // SAP_MCASP_watchDog
770 // -----------------------------------------------------------------------------