Started refactoring output task and integrating new I/O into output
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutProcNewIO.c
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 /*
37  *  ======== audioStreamOutProc.c ========
38  */
40 #include <xdc/runtime/Log.h>
41 #include <ti/sysbios/BIOS.h>
42 #include <stdio.h>
44 #include "mcasp_cfg.h"
45 #include "audioStreamProc_common.h"
46 #include "audioStreamOutProc.h"
48 #include "ioConfig.h"    //TODO: remove this header
49 #include "ioBuff.h"
50 #include "ioPhy.h"
51 #include "ioData.h"
53 extern Ptr hMcaspTxChan;
54 extern Semaphore_Handle asopSemTx;
55 extern PAF_ASOT_Config gPAF_ASOT_config;
56 extern volatile UInt32 gCommandOutputTask_SYNC;
57 extern volatile UInt32 gCommandOutputTask_ACK;
58 extern Int d10Initialized;
61 static Int asopSelectDevices(PAF_AST_IoOut *pOut);
62 static int asopIoCompsInit(PAF_AST_OutBuf * pOutBuf, PAF_AST_IoOut * pOutIo);
63 static void asopIoPhyPrime(PAF_AST_IoOut *pOut);
64 static void asopPhyTransferStart(PAF_AST_IoOut *pOut);
65 static Int asopDecodePcm(PAF_AST_IoOut *pOut);
67 // Initialize Output Processing state function
68 extern Int PAF_ASOT_initOutProc(
69     const PAF_ASOT_Params *pP,
70     PAF_AST_Stream *xStr);
72 extern Int PAF_ASOT_initSyncDecReset(
73         const PAF_ASOT_Params *pP,
74         const PAF_ASOT_Patchs *pQ,
75         PAF_ASOT_Config *pAsotCfg,
76         PAF_AudioFrame *pDecResetAf);
78 static Int checkOutSel(
79     const PAF_ASOT_Params *pP,
80     PAF_ASOT_Config *pAsotCfg,
81     Int *pOutSel);
83 extern Int PAF_ASOT_initSyncDecDecode1(
84     const PAF_ASOT_Params *pP,
85     const PAF_ASOT_Patchs *pQ,
86     PAF_ASOT_Config *pAsotCfg);
88 extern Int PAF_ASOT_initSyncDecInfo1(
89     const PAF_ASOT_Params *pP,
90     const PAF_ASOT_Patchs *pQ,
91     PAF_ASOT_Config *pAsotCfg,
92     PAF_AudioFrame *pDecInfo1Af);
94 extern Int PAF_ASOT_initSyncResync(
95     const PAF_ASOT_Params *pP,
96     const PAF_ASOT_Patchs *pQ,
97     PAF_ASOT_Config *pAsotCfg,
98     PAF_AudioFrame *pDecResetAf,
99     PAF_AudioFrame *pDecInfo1Af);
101 extern Void taskAsopFxnInit(const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ);
103 //
104 // Audio Stream Output Task definitions
105 //
107 // status codes
108 // Output FSM
109 #define ASOP_INITSYNC_NOTREADY      (  1 )  // ok, init-sync not ready
110 #define ASOP_SOK                    (  0 )  // ok
111 #define ASOP_FORWARD_ERR            ( -1 )  // forward (ASIT) error
112 #define ASOP_ENCRESET_ERR           ( -2 )  // enc reset error
113 #define ASOP_DECINFO1_ERR           ( -3 )  // dec info1 error
114 // Decode Processing
115 #define ASOP_DP_OUT_SIO_UPDATE      (  3 )  // new output selected
116 #define ASOP_DP_CB_DRAINED          (  2 )  // circular buffer drained
117 #define ASOP_DP_SOK                 (  0 )  // ok
118 #define ASOP_DP_FORWARD_ERR         ( -1 )  // forward (ASIT) error
119 #define ASOP_DP_DECINIT_ERR         ( -2 )  // decode init error
120 #define ASOP_DP_DECSTREAM_ERR       ( -3 )  // decode stream error
121 #define ASOP_DP_DECENC_ERR          ( -4 )  // decode encode error
122 #define ASOP_DP_DECINFO2_ERR        ( -5 )  // decode encode error
123 #define ASOP_DP_DECFINALTEST_ERR    ( -6 )  // decode final error
125 // Global debug counters */
126 extern UInt32 gAsopTxSioReclaimCnt      ;
127 extern UInt32 gAsopInitOutProcCnt       ;
128 extern UInt32 gAsopInitSyncDecResetCnt  ;
129 extern UInt32 gAsopInitSyncDecInfo1Cnt  ;
130 extern UInt32 gAsopInitSyncDecDecode1Cnt;
131 extern UInt32 gAsopInitSyncResyncCnt    ;
132 extern UInt32 gAsopOutProcCnt           ;
133 extern UInt32 gAsopInitCnt              ;
134 extern UInt32 gAsopStreamCnt            ;
135 extern UInt32 gAsopEncodeCnt            ;
136 extern UInt32 gAsopFinalCnt             ;
137 extern UInt32 gAsopOutSioUpdateCnt      ;
138 extern UInt32 gAsopQuitCnt              ;
140 /*
141  *  ======== taskAsopFxn ========
142  *  Audio Stream Output Processing task function
143  */
144 #ifndef PASDK_SIO_DEV
145 #ifndef IO_LOOPBACK_TEST
146 Void taskAsopFxn(                 // ASOP task function for new I/O
147 #else
148 Void taskAsopFxn_NewIO_Not_Used(  // not used for loopback test
149 #endif
150 #else
151 Void taskAsopFxn_NewIO_Not_Used(  // not used for SIO_DEV I/O
152 #endif
153     const PAF_ASOT_Params *pP,
154     const PAF_ASOT_Patchs *pQ
157     PAF_ASOT_Config *pAsotCfg;      /* ASOT configuration pointer */
158     PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
159     Int as;                         /* Audio Stream Number (1, 2, etc.) */
160     Int z;                          /* input/encode/stream/decode/output counter */
161     Int zMS;
162     Int errno;                      // error number
163     Int8 procSleep;                 // whether to sleep: 0: No, 1: Yes
164     Int8 procOutDevSel;             // whether to perform output device selection: 0: No, 1:Yes
165     Int outSel;                     // whether output device selected
166     enum { INIT_OUT_PROC_STATE,
167            INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE,
168            INITSYNC_RESYNC_STATE,
169            OUT_PROC_STATE } state;
170     PAF_AudioFrame decResetAf;
171     PAF_AudioFrame decInfo1Af;
172     Int loopCount = 0;              // used to stop trace to see startup behavior.
174     Log_info0("Enter taskAsopFxn()");
176     taskAsopFxnInit(pP, pQ);    // initialization of output task
178     //
179     // Audio Stream Output Task Configuration (*pAsotCfg):
180     //
181     pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
182     pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
184     /* Obtain Audio Stream Number (1, 2, etc.) */
185     as = pAstCfg->as;
187     zMS = pAstCfg->masterStr;
189     //
190     // Main processing loop
191     //
192     for (z=STREAM1; z < STREAMN; z++)
193     {
194         TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z);
195     }
197     errno = 0;                      // init error indicator -- no error
198     procSleep = 1;                  // init sleep flag -- sleep
199     procOutDevSel = 1;              // init device output selection flag -- perform output device selection
200     state = INIT_OUT_PROC_STATE;    // init state
201     for (;;)
202     {
203         loopCount++;
204         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
206         //
207         // Check forward (ASIT) error here, TBD
208         //
210         // Even if we are not in error state, we check if writeDECCommandRestar issued or not
211         if (gCommandOutputTask_SYNC) {
212             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Wait for the command deasserted");
213             gCommandOutputTask_ACK = 1;
214             while (gCommandOutputTask_SYNC) {
215                 Task_sleep(1);
216             }
217             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Startover the process");
218             procSleep = 1;                  // init sleep flag -- sleep
219             procOutDevSel = 1;              // init device output selection flag -- perform output device selection
220             state = INIT_OUT_PROC_STATE;    // init state -- starover
221             errno = ASOP_DP_FORWARD_ERR;    // Override the error -- for flushing SIO output device
222         }
224         // any error forces idling of output
225         if (errno)
226         {
227             for (z=OUTPUT1; z < OUTPUTN; z++)
228             {
229                 if (pAstCfg->xOut[z].hTxSio)
230                 {
231                     //SIO_idle(pAstCfg->xOut[z].hTxSio);  TO DO: implement proper error handling
232                 }
233             }
235             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
236             //ERRNO_RPRT(TaskAsop, errno);
237         }
239         if (procSleep == 1)
240         {
241             TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
242             Task_sleep(1);
243         }
245         if (procOutDevSel == 1)
246         {
247             // select output devices
248             TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
249             //errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
250             errno = asopSelectDevices(&pAsotCfg->pIoOut[0]);   // Do we need to do  for (z=OUTPUT1; z < OUTPUTN; z++)
251             if (errno)
252             {
253                 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
255                 procSleep = 1;
256                 procOutDevSel = 1;
258                 continue;
259             }
261             // if no output selected skip remaining processing
262             errno = checkOutSel(pP, pAsotCfg, &outSel);
263             if (errno < 0)
264             {
265                 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
267                 procSleep = 1;
268                 procOutDevSel = 1;
270                 continue;
271             }
272             else if (!outSel)
273             {
274                 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
276                 procSleep = 1;
277                 procOutDevSel = 1;
279                 continue;
280             }
281         } /* if (procOutDevSel == 1) */
283         switch (state)
284         {
285             case INIT_OUT_PROC_STATE:
286                 gAsopInitOutProcCnt++;
287                 Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
289                 //
290                 // Output Processing initialization.
291                 //
292                 errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
293                 if (errno < 0)
294                 {
295                     state = INIT_OUT_PROC_STATE;
296                     procSleep = 1;
297                     procOutDevSel = 1;
298                 }
299                 else
300                 {
301                     //state = INITSYNC_DEC_RESET_STATE;
302                     procSleep = 0;
303                     procOutDevSel = 0;
304                     for (z=OUTPUT1; z < OUTPUTN; z++)
305                     {
306                         asopIoCompsInit(&pAstCfg->xOut[z], &pAsotCfg->pIoOut[z]);
307                     }
309                     // Start I/O physical layer by priming McASP LLD for output
310                     asopIoPhyPrime(&pAsotCfg->pIoOut[0]);
312                     state = OUT_PROC_STATE;
313                 }
315                 break;
317             case OUT_PROC_STATE:
318                 Semaphore_pend(asopSemTx, BIOS_WAIT_FOREVER);
320                 ioPhyXferComplete(pAsotCfg->pIoOut[0].hIoPhy, FALSE);
322                 asopDecodePcm(&pAsotCfg->pIoOut[0]);
324                 asopPhyTransferStart(&pAsotCfg->pIoOut[0]);
325                 break;
327 #if 0
328             case INITSYNC_DEC_RESET_STATE:
329                 gAsopInitSyncDecResetCnt++;
330                 Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
332                 //
333                 // Dec Reset Init-Sync.
334                 //
336                 // Perform Dec Reset init-sync.
337                 // Latch Dec Reset AF.
338                 errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
339                 if (errno < 0)
340                 {
341                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
343                     // sync error -- start over
344                     state = INIT_OUT_PROC_STATE;
345                     procSleep = 1;
346                     procOutDevSel = 1;
347                 }
348                 else if (errno == ASOP_INITSYNC_NOTREADY)
349                 {
350                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
352                     // sync not ready -- try again
353                     state = INITSYNC_DEC_RESET_STATE;
354                     errno=0; // FL: temp hack
355                     procSleep = 1;
356                     procOutDevSel = 1;
357                 }
358                 else // errno==0
359                 {
360                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
362                     // sync'd -- move on
363                     state = INITSYNC_DEC_INFO1_STATE;
364                     procSleep = 0;
365                     procOutDevSel = 0;
366                 }
368                 break;
370             case INITSYNC_DEC_INFO1_STATE:
371                 gAsopInitSyncDecInfo1Cnt++;
372                 Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
374                 //
375                 // Dec Info1 Init-Sync.
376                 //
378                 // Perform Dec Info1 init-sync.
379                 // Latch Dec Info1 AF.
380                 errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
381                 if (errno < 0)
382                 {
383                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
385                     // sync error -- start over
386                     state = INIT_OUT_PROC_STATE;
387                     procSleep = 1;
388                     procOutDevSel = 1;
389                 }
390                 else if (errno == ASOP_INITSYNC_NOTREADY)
391                 {
392                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
394                     // sync not ready -- try again
395                     state = INITSYNC_DEC_INFO1_STATE;
396                     errno=0; // FL: temp hack
397                     procSleep = 1;
398                     procOutDevSel = 0;
399                 }
400                 else // errno = 0
401                 {
402                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
404                     // sync'd -- move on
405                     state = INITSYNC_DEC_DECODE1_STATE;
406                     procSleep = 0;
407                     procOutDevSel = 0;
408                 }
410                 break;
412             case INITSYNC_DEC_DECODE1_STATE:
413                 gAsopInitSyncDecDecode1Cnt++;
414                 Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
416                 //
417                 // Dec Info1 Init-Sync.
418                 //
420                 // Perform Dec Info1 init-sync.
421                 // Latch Dec Info1 AF.
422                 errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
423                 if (errno < 0)
424                 {
425                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
427                     // sync error -- start over
428                     state = INIT_OUT_PROC_STATE;
429                     procSleep = 1;
430                     procOutDevSel = 1;
431                 }
432                 else if (errno == ASOP_INITSYNC_NOTREADY)
433                 {
434                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
436                     // sync not ready -- try again
437                     state = INITSYNC_DEC_DECODE1_STATE;
438                     errno=0; // FL: temp hack
439                     procSleep = 1;
440                     procOutDevSel = 0;
441                 }
442                 else // errno = 0
443                 {
444                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
446                     // sync'd -- move on
447                     state = OUT_PROC_STATE;
448                     procSleep = 0;
449                     procOutDevSel = 0;
450                 }
452                 break;
454             case INITSYNC_RESYNC_STATE:
455                 gAsopInitSyncResyncCnt++;
456                 Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
458                 //
459                 // Re-Sync.
460                 // Use stored AF info from init-sync.
461                 // This is done in case of local error.
462                 //
464                 // Perform Dec Info1 init-sync.
465                 errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf,
466                     &decInfo1Af);
467                 if (errno < 0)
468                 {
469                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
471                     // sync error -- start over
472                     state = INIT_OUT_PROC_STATE;
473                     procSleep = 1;
474                     procOutDevSel = 1;
475                 }
476                 else
477                 {
478                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
480                     // re-sync'd -- move on
481                     state = OUT_PROC_STATE;
482                     procSleep = 0;
483                     procOutDevSel = 0;
484                 }
486                 break;
488             case OUT_PROC_STATE:
489                 gAsopOutProcCnt++;
490                 Log_info0("TaskAsop: state=OUT_PROC_STATE");
492                 //
493                 // Output Processing.
494                 //
496                 TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
497                 errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
498                 if (errno < 0)
499                 {
500                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
502                     //
503                     // Output Processing exit, due to error
504                     //
506                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
507                     if (errno == ASOP_DP_FORWARD_ERR)
508                     {
509                         // forward (ASIT) error -- start over
510                         state = INIT_OUT_PROC_STATE;
511                         procSleep = 1;
512                         procOutDevSel = 1;
513                     }
514                     else
515                     {
516                         // local (ASOT) error
517                         state = INITSYNC_RESYNC_STATE;
518                         procSleep = 1;
519                         procOutDevSel = 0; // disallow device re-select if local error during output processing
520                     }
521                 }
522                 else if (errno > 0)
523                 {
524                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
526                     //
527                     // Output Processing exit, not due to error
528                     //
530                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
531                     if (errno == ASOP_DP_OUT_SIO_UPDATE)
532                     {
533                         // skip re-sync
534                         // resume output processing after new output selected
535                         state = OUT_PROC_STATE;
536                         procSleep = 1;
537                         procOutDevSel = 1;
538                     }
539                 }
540                 else
541                 {
542                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
544                     //
545                     // Output Processing exit, normal
546                     //
548                     TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
550                     // no error returned if CB drained
551                     // (i.e. CB drained is normal behavior)
552                     state = INIT_OUT_PROC_STATE;
553                     procSleep = 1;
554                     procOutDevSel = 1;
555                 }
557                 break;
558 #endif
559             default: // unknown state
560                 TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state);
561                 break;
562         } // End of switch
564     } // End of main processing loop for (;;)
568 } /* taskAsopFxn */
571 void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
573     /* post semaphore */
574     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
575         Semaphore_post(asopSemTx);
576     } else {
577         ;    // intermediate packet due to buffer wrapping around
578     }
581 Int asopSelectDevices(PAF_AST_IoOut *pOut)
583     if((pOut->hIoBuff == NULL) || (pOut->hIoPhy == NULL) || (!d10Initialized)) {
584         return -1;
585     }
587     pOut->hMcaspChan = hMcaspTxChan;
589     return 0;
592 /* Check if at least one output selected */
593 static Int checkOutSel(
594     const PAF_ASOT_Params *pP,
595     PAF_ASOT_Config *pAsotCfg,
596     Int *pOutSel
599     PAF_AST_IoOut  *pOut;
600     Int outSel;
601     Int z;
603     pOut= pAsotCfg->pIoOut; // get pointer to AST common (shared) configuration
605     outSel = 0;
606     for (z=OUTPUT1; z < OUTPUTN; z++)
607     {
608         if (pOut[z].hIoPhy)
609         {
610             outSel = 1;
611             break;
612         }
613     }
615     *pOutSel = outSel;
617     return ASOP_SOK;
620 #define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
622 /*===========================================================================
623  * Initialize I/O components for output processing
624 ============================================================================*/
625 int asopIoCompsInit(PAF_AST_OutBuf * pOutBuf, PAF_AST_IoOut * pOutIo)
627     // Initialize I/O BUFF and I/O PHY components for output task
628     ioBuffParams_t ioBuffParams;
629     ioPhyParams_t  ioPhyParams;
631     ioBuffParams.base         = pOutBuf->outBufConfig.base.pVoid;
632     ioBuffParams.size         = pOutBuf->outBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
633     ioBuffParams.sync         = IOBUff_READ_SYNC;
634     ioBuffParams.nominalDelay = OUTPUT_FRAME_SIZE * (NUM_PRIME_XFERS+1);
635     if(ioBuffInit(pOutIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
636         return (-1);   // to remove magic number
637     }
639     ioPhyParams.ioBuffHandle    = pOutIo->hIoBuff;
640     ioPhyParams.xferFrameSize   = OUTPUT_FRAME_SIZE;
641     ioPhyParams.mcaspChanHandle = hMcaspTxChan;
642     ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_READ;
643     if(ioPhyInit(pOutIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
644         return (-1);   // to remove magic number
645     }
647     pOutIo->phyXferSize = ioPhyParams.xferFrameSize;
649     return 0;
650 } /* asipIoCompsInit */
653 /*======================================================================================
654  *  I/O physical layer prime operation required by McASP LLD
655  *====================================================================================*/
656 void asopIoPhyPrime(PAF_AST_IoOut *pOut)
658     Int32        count;
660     pOut->numPrimeXfers = NUM_PRIME_XFERS;
662     for(count = 0; count < pOut->numPrimeXfers; count++)
663     {
664         ioPhyXferSubmit(pOut->hIoPhy);
665     }
666 } /* asipIoPhyPrime */
669 /*======================================================================================
670  *  This function starts an I/O PHY transfer for output
671  *====================================================================================*/
672 void asopPhyTransferStart(PAF_AST_IoOut *pOut)
674     if(mcaspCheckOverUnderRun(pOut->hMcaspChan)) {
675         mcaspTxReset();
676         mcaspTxCreate();
677         pOut->hMcaspChan = hMcaspTxChan;
678     }
679     else {
680         if(ioPhyXferSubmit(pOut->hIoPhy) == IOPHY_ERR_BUFF_UNDERFLOW) {
681             // Output buffer underflows!
682             printf("\nOutput buffer underflows!\n");
683             exit(0);
684         }
685         else {
686             // Output buffer operates normally
687             ;
688         }
689     }
692 extern U8 pcmbuf[OUTPUT_FRAME_SIZE];
694 Int asopDecodePcm(PAF_AST_IoOut *pOut)
696     void *buff1, *buff2;
697     size_t size1, size2;
698     int status;
700     status = ioBuffGetWritePtrs(pOut->hIoBuff, pOut->phyXferSize,
701                                 &buff1, &size1, &buff2, &size2);
702     if (status == IOBUFF_ERR_OVERFLOW) {
703         /* skip processing since output buffer overflows */
704         return IOBUFF_ERR_OVERFLOW;   // to use a different error code
705     }
707     // Copy PCM data to output buffer to be transmitted by McASP
708     memcpy(buff1, &pcmbuf[0], size1);
709     Cache_wbInv(buff1, size1, Cache_Type_ALL,TRUE);
711     ioBuffWriteComplete(pOut->hIoBuff, buff1, size1);
713     if(buff2 != NULL) {
714       memcpy(buff2, &pcmbuf[size1], size2);
715       Cache_wbInv(buff2, size2, Cache_Type_ALL,TRUE);
717       ioBuffWriteComplete(pOut->hIoBuff, buff2, size2);
718     }
720     return 0;
723 /* Nothing past this line */