13276593c2736e3f72b51b904e21d4902e65285e
[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 <ti/sysbios/knl/Event.h>
43 #include <stdio.h>
45 #include "mcasp_cfg.h"
46 #include "audioStreamProc_common.h"
47 #include "audioStreamOutProc.h"
49 #include "ioConfig.h"    //TODO: remove this header
50 #include "ioBuff.h"
51 #include "ioPhy.h"
52 #include "ioData.h"
54 extern Ptr hMcaspTxChan;
55 extern Semaphore_Handle asopSemTx;
56 extern PAF_ASOT_Config gPAF_ASOT_config;
57 extern volatile UInt32 gCommandOutputTask_SYNC;
58 extern volatile UInt32 gCommandOutputTask_ACK;
59 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 // Output FSM states 
126 enum 
127
128     INIT_OUT_PROC_STATE,
129     INITSYNC_DEC_RESET_STATE, 
130     INITSYNC_DEC_INFO1_STATE, 
131     INITSYNC_DEC_DECODE1_STATE,
132     INITSYNC_RESYNC_STATE,
133     OUT_PROC_STATE 
134 };
136 // Global debug counters */
137 extern UInt32 gAsopTxSioReclaimCnt      ;
138 extern UInt32 gAsopInitOutProcCnt       ;
139 extern UInt32 gAsopInitSyncDecResetCnt  ;
140 extern UInt32 gAsopInitSyncDecInfo1Cnt  ;
141 extern UInt32 gAsopInitSyncDecDecode1Cnt;
142 extern UInt32 gAsopInitSyncResyncCnt    ;
143 extern UInt32 gAsopOutProcCnt           ;
144 extern UInt32 gAsopInitCnt              ;
145 extern UInt32 gAsopStreamCnt            ;
146 extern UInt32 gAsopEncodeCnt            ;
147 extern UInt32 gAsopFinalCnt             ;
148 extern UInt32 gAsopOutSioUpdateCnt      ;
149 extern UInt32 gAsopQuitCnt              ;
151 #define ASOP_DEBUG
152 #ifdef ASOP_DEBUG
153 Int asopLoopCount;
154 #endif
157 /*
158  *  ======== taskAsopFxn ========
159  *  Audio Stream Output Processing task function
160  */
161 #ifndef PASDK_SIO_DEV
162 #ifndef IO_LOOPBACK_TEST
163 Void taskAsopFxn(                 // ASOP task function for new I/O
164 #else
165 Void taskAsopFxn_NewIO_Not_Used(  // not used for loopback test
166 #endif
167 #else
168 Void taskAsopFxn_NewIO_Not_Used(  // not used for SIO_DEV I/O
169 #endif
170     const PAF_ASOT_Params *pP,
171     const PAF_ASOT_Patchs *pQ
174     PAF_ASOT_Config *pAsotCfg;      // ASOT configuration pointer
175     PAF_AST_Config *pAstCfg;        // Common (shared) configuration pointer
176     Int as;                         // Audio Stream Number (1, 2, etc.)
177     Int z;                          // input/encode/stream/decode/output counter
178     Int zMS;
179     Int errno;                      // error number
180     Int8 procSleep;                 // whether to sleep: 0: No, 1: Yes
181     Int8 procOutDevSel;             // whether to perform output device selection: 0: No, 1:Yes
182     Int outSel;                     // whether output device selected
183     PAF_AudioFrame decResetAf;
184     PAF_AudioFrame decInfo1Af;
185 #ifndef ASOP_DEBUG
186     Int asopLoopCount;              // debug, ASOT loop counter
187 #endif    
189     Log_info0("Enter taskAsopFxn()");
191     taskAsopFxnInit(pP, pQ);    // initialization of output task
192     
193     //
194     // Audio Stream Output Task Configuration (*pAsotCfg):
195     //
196     pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
197     pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
199     /* Obtain Audio Stream Number (1, 2, etc.) */
200     as = pAstCfg->as;
202     zMS = pAstCfg->masterStr;
204     //
205     // Main processing loop
206     //
207     for (z=STREAM1; z < STREAMN; z++)
208     {
209         TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z);
210     }
212     errno = 0;                              // init error indicator -- no error
213     procSleep = 1;                          // init sleep flag -- sleep
214     procOutDevSel = 1;                      // init device output selection flag -- perform output device selection
215     pAsotCfg->state = INIT_OUT_PROC_STATE;  // init state
216     asopLoopCount = 0;                      // loop counter
217     for (;;)
218     {
219         asopLoopCount++;
220         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", asopLoopCount, errno);
222         //
223         // Check forward (ASIT) error here, TBD
224         //
226         // Even if we are not in error state, we check if writeDECCommandRestar issued or not
227         if (gCommandOutputTask_SYNC) {
228             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Wait for the command deasserted");
229             gCommandOutputTask_ACK = 1;
230             while (gCommandOutputTask_SYNC) {
231                 //Task_sleep(1);
232                 Event_pend(asotEvt, Event_Id_NONE, Evt_Id_AsotWakeTimer, BIOS_WAIT_FOREVER);
233             }
234             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Startover the process");
235             procSleep = 1;                          // init sleep flag -- sleep
236             procOutDevSel = 1;                      // init device output selection flag -- perform output device selection
237             pAsotCfg->state = INIT_OUT_PROC_STATE;  // init state -- start over
238             errno = ASOP_DP_FORWARD_ERR;            // Override the error -- for flushing SIO output device
239         }
241         // any error forces idling of output
242         if (errno)
243         {
244             for (z=OUTPUT1; z < OUTPUTN; z++)
245             {
246                 if (pAstCfg->xOut[z].hTxSio)
247                 {
248                     //SIO_idle(pAstCfg->xOut[z].hTxSio);  TO DO: implement proper error handling
249                 }
250             }
252             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", asopLoopCount);
253             //ERRNO_RPRT(TaskAsop, errno);
254         }
256         if (procSleep == 1)
257         {
258             TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
259             //Task_sleep(1);
260             Event_pend(asotEvt, Event_Id_NONE, Evt_Id_AsotWakeTimer, BIOS_WAIT_FOREVER);
261         }
263         if (procOutDevSel == 1)
264         {
265             // select output devices
266             TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
267             //errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
268             errno = asopSelectDevices(&pAsotCfg->pIoOut[0]);   // Do we need to do  for (z=OUTPUT1; z < OUTPUTN; z++)
269             if (errno)
270             {
271                 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
273                 procSleep = 1;
274                 procOutDevSel = 1;
276                 continue;
277             }
279             // if no output selected skip remaining processing
280             errno = checkOutSel(pP, pAsotCfg, &outSel);
281             if (errno < 0)
282             {
283                 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
285                 procSleep = 1;
286                 procOutDevSel = 1;
288                 continue;
289             }
290             else if (!outSel)
291             {
292                 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
294                 procSleep = 1;
295                 procOutDevSel = 1;
297                 continue;
298             }
299         } /* if (procOutDevSel == 1) */
301         switch (pAsotCfg->state)
302         {
303             case INIT_OUT_PROC_STATE:
304                 gAsopInitOutProcCnt++;
305                 Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
307                 //
308                 // Output Processing initialization.
309                 //
310                 errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
311                 if (errno < 0)
312                 {
313                     pAsotCfg->state = INIT_OUT_PROC_STATE;
314                     procSleep = 1;
315                     procOutDevSel = 1;
316                 }
317                 else
318                 {
319                     //pAsotCfg->state = INITSYNC_DEC_RESET_STATE;
320                     procSleep = 0;
321                     procOutDevSel = 0;
322                     for (z=OUTPUT1; z < OUTPUTN; z++)
323                     {
324                         asopIoCompsInit(&pAstCfg->xOut[z], &pAsotCfg->pIoOut[z]);
325                     }
327                     // Start I/O physical layer by priming McASP LLD for output
328                     asopIoPhyPrime(&pAsotCfg->pIoOut[0]);
330                     pAsotCfg->state = OUT_PROC_STATE;
331                 }
333                 break;
335             case OUT_PROC_STATE:
336                 //Semaphore_pend(asopSemTx, BIOS_WAIT_FOREVER);
337                 Event_pend(asotEvt, Event_Id_NONE, Evt_Id_AsotTxMcaspEdma, BIOS_WAIT_FOREVER);
338                 
339                 ioPhyXferComplete(pAsotCfg->pIoOut[0].hIoPhy, FALSE);
341                 asopDecodePcm(&pAsotCfg->pIoOut[0]);
343                 asopPhyTransferStart(&pAsotCfg->pIoOut[0]);
344                 break;
346 #if 0
347             case INITSYNC_DEC_RESET_STATE:
348                 gAsopInitSyncDecResetCnt++;
349                 Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
351                 //
352                 // Dec Reset Init-Sync.
353                 //
355                 // Perform Dec Reset init-sync.
356                 // Latch Dec Reset AF.
357                 errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
358                 if (errno < 0)
359                 {
360                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
362                     // sync error -- start over
363                     pAsotCfg->state = INIT_OUT_PROC_STATE;
364                     procSleep = 1;
365                     procOutDevSel = 1;
366                 }
367                 else if (errno == ASOP_INITSYNC_NOTREADY)
368                 {
369                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
371                     // sync not ready -- try again
372                     pAsotCfg->state = INITSYNC_DEC_RESET_STATE;
373                     errno=0; // FL: temp hack
374                     procSleep = 1;
375                     procOutDevSel = 1;
376                 }
377                 else // errno==0
378                 {
379                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
381                     // sync'd -- move on
382                     pAsotCfg->state = INITSYNC_DEC_INFO1_STATE;
383                     procSleep = 0;
384                     procOutDevSel = 0;
385                 }
387                 break;
389             case INITSYNC_DEC_INFO1_STATE:
390                 gAsopInitSyncDecInfo1Cnt++;
391                 Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
393                 //
394                 // Dec Info1 Init-Sync.
395                 //
397                 // Perform Dec Info1 init-sync.
398                 // Latch Dec Info1 AF.
399                 errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
400                 if (errno < 0)
401                 {
402                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
404                     // sync error -- start over
405                     pAsotCfg->state = INIT_OUT_PROC_STATE;
406                     procSleep = 1;
407                     procOutDevSel = 1;
408                 }
409                 else if (errno == ASOP_INITSYNC_NOTREADY)
410                 {
411                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
413                     // sync not ready -- try again
414                     pAsotCfg->state = INITSYNC_DEC_INFO1_STATE;
415                     errno=0; // FL: temp hack
416                     procSleep = 1;
417                     procOutDevSel = 0;
418                 }
419                 else // errno = 0
420                 {
421                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
423                     // sync'd -- move on
424                     pAsotCfg->state = INITSYNC_DEC_DECODE1_STATE;
425                     procSleep = 0;
426                     procOutDevSel = 0;
427                 }
429                 break;
431             case INITSYNC_DEC_DECODE1_STATE:
432                 gAsopInitSyncDecDecode1Cnt++;
433                 Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
435                 //
436                 // Dec Info1 Init-Sync.
437                 //
439                 // Perform Dec Info1 init-sync.
440                 // Latch Dec Info1 AF.
441                 errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
442                 if (errno < 0)
443                 {
444                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
446                     // sync error -- start over
447                     pAsotCfg->state = INIT_OUT_PROC_STATE;
448                     procSleep = 1;
449                     procOutDevSel = 1;
450                 }
451                 else if (errno == ASOP_INITSYNC_NOTREADY)
452                 {
453                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
455                     // sync not ready -- try again
456                     pAsotCfg->state = INITSYNC_DEC_DECODE1_STATE;
457                     errno=0; // FL: temp hack
458                     procSleep = 1;
459                     procOutDevSel = 0;
460                 }
461                 else // errno = 0
462                 {
463                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
465                     // sync'd -- move on
466                     pAsotCfg->state = OUT_PROC_STATE;
467                     procSleep = 0;
468                     procOutDevSel = 0;
469                 }
471                 break;
473             case INITSYNC_RESYNC_STATE:
474                 gAsopInitSyncResyncCnt++;
475                 Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
477                 //
478                 // Re-Sync.
479                 // Use stored AF info from init-sync.
480                 // This is done in case of local error.
481                 //
483                 // Perform Dec Info1 init-sync.
484                 errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf,
485                     &decInfo1Af);
486                 if (errno < 0)
487                 {
488                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
490                     // sync error -- start over
491                     pAsotCfg->state = INIT_OUT_PROC_STATE;
492                     procSleep = 1;
493                     procOutDevSel = 1;
494                 }
495                 else
496                 {
497                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
499                     // re-sync'd -- move on
500                     pAsotCfg->state = OUT_PROC_STATE;
501                     procSleep = 0;
502                     procOutDevSel = 0;
503                 }
505                 break;
507             case OUT_PROC_STATE:
508                 gAsopOutProcCnt++;
509                 Log_info0("TaskAsop: state=OUT_PROC_STATE");
511                 //
512                 // Output Processing.
513                 //
515                 TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
516                 errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
517                 if (errno < 0)
518                 {
519                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
521                     //
522                     // Output Processing exit, due to error
523                     //
525                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
526                     if (errno == ASOP_DP_FORWARD_ERR)
527                     {
528                         // forward (ASIT) error -- start over
529                         pAsotCfg->state = INIT_OUT_PROC_STATE;
530                         procSleep = 1;
531                         procOutDevSel = 1;
532                     }
533                     else
534                     {
535                         // local (ASOT) error
536                         pAsotCfg->state = INITSYNC_RESYNC_STATE;
537                         procSleep = 1;
538                         procOutDevSel = 0; // disallow device re-select if local error during output processing
539                     }
540                 }
541                 else if (errno > 0)
542                 {
543                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
545                     //
546                     // Output Processing exit, not due to error
547                     //
549                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
550                     if (errno == ASOP_DP_OUT_SIO_UPDATE)
551                     {
552                         // skip re-sync
553                         // resume output processing after new output selected
554                         pAsotCfg->state = OUT_PROC_STATE;
555                         procSleep = 1;
556                         procOutDevSel = 1;
557                     }
558                 }
559                 else
560                 {
561                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
563                     //
564                     // Output Processing exit, normal
565                     //
567                     TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
569                     // no error returned if CB drained
570                     // (i.e. CB drained is normal behavior)
571                     pAsotCfg->state = INIT_OUT_PROC_STATE;
572                     procSleep = 1;
573                     procOutDevSel = 1;
574                 }
576                 break;
577 #endif
578             default: // unknown state
579                 TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, pAsotCfg->state);
580                 break;
581         } // End of switch
583     } // End of main processing loop for (;;)
587 } /* taskAsopFxn */
589 // ASOT wake timer (clock) function
590 Void clkAsotFxn(Void)
592     Event_post(asotEvt, Evt_Id_AsotWakeTimer);
595 void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
597     /* post semaphore */
598     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
599         //Semaphore_post(asopSemTx);
600         Event_post(asotEvt, Evt_Id_AsotTxMcaspEdma);
601     } else {
602         ;    // intermediate packet due to buffer wrapping around
603     }
606 Int asopSelectDevices(PAF_AST_IoOut *pOut)
608     if((pOut->hIoBuff == NULL) || (pOut->hIoPhy == NULL) || (!d10Initialized)) {
609         return -1;
610     }
612     pOut->hMcaspChan = hMcaspTxChan;
614     return 0;
617 /* Check if at least one output selected */
618 static Int checkOutSel(
619     const PAF_ASOT_Params *pP,
620     PAF_ASOT_Config *pAsotCfg,
621     Int *pOutSel
624     PAF_AST_IoOut  *pOut;
625     Int outSel;
626     Int z;
628     pOut= pAsotCfg->pIoOut; // get pointer to AST common (shared) configuration
630     outSel = 0;
631     for (z=OUTPUT1; z < OUTPUTN; z++)
632     {
633         if (pOut[z].hIoPhy)
634         {
635             outSel = 1;
636             break;
637         }
638     }
640     *pOutSel = outSel;
642     return ASOP_SOK;
645 #define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
647 /*===========================================================================
648  * Initialize I/O components for output processing
649 ============================================================================*/
650 int asopIoCompsInit(PAF_AST_OutBuf * pOutBuf, PAF_AST_IoOut * pOutIo)
652     // Initialize I/O BUFF and I/O PHY components for output task
653     ioBuffParams_t ioBuffParams;
654     ioPhyParams_t  ioPhyParams;
656     ioBuffParams.base         = pOutBuf->outBufConfig.base.pVoid;
657     ioBuffParams.size         = pOutBuf->outBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
658     ioBuffParams.sync         = IOBUff_READ_SYNC;
659     ioBuffParams.nominalDelay = OUTPUT_FRAME_SIZE * (NUM_PRIME_XFERS+1);
660     if(ioBuffInit(pOutIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
661         return (-1);   // to remove magic number
662     }
664     ioPhyParams.ioBuffHandle    = pOutIo->hIoBuff;
665     ioPhyParams.xferFrameSize   = OUTPUT_FRAME_SIZE;
666     ioPhyParams.mcaspChanHandle = hMcaspTxChan;
667     ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_READ;
668     if(ioPhyInit(pOutIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
669         return (-1);   // to remove magic number
670     }
672     pOutIo->phyXferSize = ioPhyParams.xferFrameSize;
674     return 0;
675 } /* asopIoCompsInit */
678 /*======================================================================================
679  *  I/O physical layer prime operation required by McASP LLD
680  *====================================================================================*/
681 void asopIoPhyPrime(PAF_AST_IoOut *pOut)
683     Int32        count;
685     pOut->numPrimeXfers = NUM_PRIME_XFERS;
687     for(count = 0; count < pOut->numPrimeXfers; count++)
688     {
689         ioPhyXferSubmit(pOut->hIoPhy);
690     }
691 } /* asipIoPhyPrime */
694 /*======================================================================================
695  *  This function starts an I/O PHY transfer for output
696  *====================================================================================*/
697 void asopPhyTransferStart(PAF_AST_IoOut *pOut)
699     if(mcaspCheckOverUnderRun(pOut->hMcaspChan)) {
700         mcaspTxReset();
701         mcaspTxCreate();
702         pOut->hMcaspChan = hMcaspTxChan;
703     }
704     else {
705         if(ioPhyXferSubmit(pOut->hIoPhy) == IOPHY_ERR_BUFF_UNDERFLOW) {
706             // Output buffer underflows!
707             printf("\nOutput buffer underflows!\n");
708             exit(0);
709         }
710         else {
711             // Output buffer operates normally
712             ;
713         }
714     }
717 extern U8 pcmbuf[OUTPUT_FRAME_SIZE];
719 Int asopDecodePcm(PAF_AST_IoOut *pOut)
721     void *buff1, *buff2;
722     size_t size1, size2;
723     int status;
725     status = ioBuffGetWritePtrs(pOut->hIoBuff, pOut->phyXferSize,
726                                 &buff1, &size1, &buff2, &size2);
727     if (status == IOBUFF_ERR_OVERFLOW) {
728         /* skip processing since output buffer overflows */
729         return IOBUFF_ERR_OVERFLOW;   // to use a different error code
730     }
732     // Copy PCM data to output buffer to be transmitted by McASP
733     memcpy(buff1, &pcmbuf[0], size1);
734     Cache_wbInv(buff1, size1, Cache_Type_ALL,TRUE);
736     ioBuffWriteComplete(pOut->hIoBuff, buff1, size1);
738     if(buff2 != NULL) {
739       memcpy(buff2, &pcmbuf[size1], size2);
740       Cache_wbInv(buff2, size2, Cache_Type_ALL,TRUE);
742       ioBuffWriteComplete(pOut->hIoBuff, buff2, size2);
743     }
745     return 0;
748 /* Nothing past this line */