Fixed problem of input task being stuck when input stream stops:
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamInpProcNewIO.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  *  ======== audioStreamInpProcNewIo.c ========
38  */
39 #include <xdc/runtime/Log.h>
40 #include <ti/sysbios/BIOS.h>
42 #include "procsdk_audio_typ.h"
43 #include "audioStreamInpProc.h"
44 #include "audioStreamProc_common.h"
45 #include "aspMsg_common.h"
46 #include "aspMsg_master.h"
47 #include "asperr.h"
48 #include "common.h"
50 #include "audk2g.h"
51 #include "audk2g_audio.h"
52 #include "mcasp_cfg.h"
53 #include "ioConfig.h"    //TODO: remove this header
54 #include "ioBuff.h"
55 #include "ioPhy.h"
56 #include "ioData.h"
59 #define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
61 #define SYNC_PC_MASK         0x1F
62 #define SYNC_SUBTYPE_MASK    0x700
63 #define SYNC_SUBTYPE_SHIFT   8
64 #define SYNC_SUBTYPE_DTSHD   0x11
65 #define SYNC_DDP             0x15
66 #define SYNC_THD             0x16
68 #define IEC_HEADER_LENGTH    4
70 #define INPUT_SWITCH_HANGOVER 8
72 //table needed until PAF_SOURCE is reordered to match IEC numbering
73 const SmUns IECpafSource[23] =
74 {
75     PAF_SOURCE_UNKNOWN,  // 0: IEC NULL Type
76     PAF_SOURCE_AC3,      // 1: Comments on 1-15 match IEC 61937 part 2.
77     PAF_SOURCE_UNKNOWN,  // 2: IEC reserved
78     PAF_SOURCE_UNKNOWN,  // 3: IEC pause
79     PAF_SOURCE_UNKNOWN,  // 4: MPEG 1 layer 1
80     PAF_SOURCE_MP3,      // 5: MPEG layer 2 or 3
81     PAF_SOURCE_UNKNOWN,  // 6: MPEG 2 data with extension
82     PAF_SOURCE_AAC,      // 7: MPEG-2 AAC ADTS
83     PAF_SOURCE_UNKNOWN,  // 8: MPEG 2 layer 1 low sampling frequency
84     PAF_SOURCE_UNKNOWN,  // 9: MPEG 2 layer 2 or 3 low sampling frequency
85     PAF_SOURCE_UNKNOWN,  // 10: reserved
86     PAF_SOURCE_DTS,      // 11: DTS type 1 (11 bit: 512 sample repeat period)
87     PAF_SOURCE_DTS12,    // 12: DTS type 2 (12 bit: 1024 sample repeat period)
88     PAF_SOURCE_DTS13,    // 13: DTS type 3 (13 bit: 2048 sample repeat period)
89     PAF_SOURCE_DTS14,    // 14: ATRAC
90     PAF_SOURCE_UNKNOWN,  // 15: ATRAC 2/3
91     PAF_SOURCE_THD,      // 16
92     PAF_SOURCE_DTSHD,    // 17
93     PAF_SOURCE_WMA9PRO,  // 18
94     PAF_SOURCE_UNKNOWN,  // 19
95     PAF_SOURCE_UNKNOWN,  // 20
96     PAF_SOURCE_DDP,      // 21
97     PAF_SOURCE_THD,      // 22
98 };
100 /*
101  * Functions defined in other files and to be put into proper header files
102  */
103 extern Void taskAsipFxnInit(const PAF_ASIT_Params *pP,const PAF_ASIT_Patchs *pQ);
106 // avoid including sap_d10.h, which would cause symbol redefinition
107 // warning (MCASP_PFUNC_XXX)
108 extern XDAS_Int32 D10_init();
109 extern XDAS_Int32 D10_RxControl(const void *pD10RxParams,
110                                 XDAS_Int32 code, XDAS_Int32 arg);
112 /*
113  * Functions only used in this file
114  */
115 int asipPrepareProcessing();
116 int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
117 void asipProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec);
118 void asipIoPhyPrime(PAF_AST_IoInp *pInpIo);
119 void asipPhyTransferPend(void);
120 void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo);
121 void asipPhyTransferStart(PAF_AST_IoInp *pInpIo);
122 Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp);
123 Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
124                           PAF_InpBufConfig *pInpBuf);
126 //Int asipDecideSource(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, asipDecProc_t *pDec);
127 Int asipProcessing(const PAF_ASIT_Params *pP,
128                    const PAF_ASIT_Patchs *pQ,
129                    PAF_ASIT_Config *pAsitCfg);
130 void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno);
132 /*
133  * variables/structures to be put into proper global structures
134  */
135 extern Semaphore_Handle asipSemRx;
136 extern PAF_ASIT_Config gPAF_ASIT_config;
137 extern const MdUns iecFrameLength[23];
138 extern Ptr hMcaspRxChan;
141 enum
143     ASIP_SOURCE_DETECTION,
144     ASIP_DECODE,
145     ASIP_SWITCH_TO_PCM,
146 };
148 enum
150     ASIP_INPUT_PREPARATION,
151     ASIP_INPUT_PROCESSING
152 };
156 #define ASIP_DEBUG
158 #ifdef ASIP_DEBUG
159 /* define the following as global variables for easy debugging */
160 int asipLoopCount1, asipLoopCount2;
161 Int asipErrno;
162 Int inputReadyForProcessing;
163 #endif
165 /*
166  *  ======== taskAsipFxn ========
167  *  Audio Stream Input Processing task function
168  */
169 #ifndef PASDK_SIO_DEV
170 #ifndef IO_LOOPBACK_TEST
171 Void taskAsipFxn(                  // ASIP task function for new I/O
172 #else
173 Void taskAsipFxn_NewIO_Not_Used(   // not used for loopback test
174 #endif
175 #else
176 Void taskAsipFxn_NewIO_Not_USED(   // not used for SIO/DEV based I/O
177 #endif
178     const PAF_ASIT_Params *pP,
179         const PAF_ASIT_Patchs *pQ)
181     PAF_ASIT_Config *pAsitCfg;      /* ASIT configuration pointer */
182     PAF_AST_Config  *pAstCfg;       /* AST Common (shared) configuration pointer */
183     PAF_AST_IoInp *pInp;            /* Input I/O components */
184     Int as;                         /* Audio Stream Number (1, 2, etc.) */
185     Int z;                          /* input/encode/stream/decode/output counter */
186     Int zMI;
187 #ifndef ASIP_DEBUG
188 int asipLoopCount1, asipLoopCount2;
189 Int asipErrno;
190 Int inputReadyForProcessing;
191 #endif
193     Int firstTimeInit = TRUE;
195     Log_info0("Enter taskAsipFxn()");
197     taskAsipFxnInit(pP, pQ);  // initialization of input task
198     
199     //
200     // Audio Stream Input Task Configuration (*pAsitCfg):
201     //
202     pAsitCfg = &gPAF_ASIT_config;       // initialize pointer to task configuration
203     pAstCfg  = pAsitCfg->pAstCfg;       // pointer to AST common (shared) configuration
205     /* Set Audio Stream Number (1, 2, etc.) */
206     as = pAstCfg->as;
208     //
209     // Determine decoder and stream indices associated with the master input
210     //
211     zMI  = pP->zone.master;
212     pInp = &pAsitCfg->pIoInp[zMI];        // pointer to input I/O components
214     for (z=STREAM1; z < STREAMN; z++)
215     {
216         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
217     }
219     TRACE_TERSE0("TaskAsip: Entering Main Loop.");
221     //
222     // Main processing loop
223     //
224     asipLoopCount1 = 0;
225     asipLoopCount2 = 0;
226     asipErrno = 0;
227     pInp->asipState = ASIP_INPUT_PREPARATION;
229     for (;;)
230     {
231         asipLoopCount1++;
233         switch (pInp->asipState)
234         {
235         case ASIP_INPUT_PREPARATION:
236             // Indicate decoder no decoding yet
237             pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
239             // 5 system tick, or 5 msec. Should remove this later when implementing
240             // event based scheduling.
241             Task_sleep(5);
243             inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
244             if (inputReadyForProcessing) {
245                 // Input is ready for processing, so we initialize the I/O components.
246                 // Note that the I/O components init. and I/O PHY prime are performed only at the
247                 // first time. This should be changed later - init. and prime should be done whenever
248                 // input interface has changed.
249                 if(firstTimeInit) {
250                     asipIoCompsInit(&pAstCfg->xInp[zMI], pInp);
252                     // Start I/O physical layer by priming McASP LLD for input
253                     asipIoPhyPrime(pInp);
255                     firstTimeInit = FALSE;
256                 }
258                 // Initialize ASIP processing
259                 asipProcInit(pInp, &pAsitCfg->inpDec);
261                 pInp->asipState = ASIP_INPUT_PROCESSING;
262             }
263             break;
265         case ASIP_INPUT_PROCESSING:
266             // Pending on I/O PHY transfer
267             asipPhyTransferPend();
269             // Marks I/O PHY transfer and I/O BUFF write complete
270             asipPhyTransferComplete(pInp);
272             // Main function to process input data
273             asipErrno = asipProcessing(pP, pQ, pAsitCfg);
275             // Start next transfer
276             asipPhyTransferStart(pInp);
278             if(asipErrno) {
279                 asipErrorHandling(pAstCfg, asipErrno);
281                 pInp->asipState = ASIP_INPUT_PREPARATION;
282             }
284             break;
286         default:
287             break;
288         }
289     }  // for (;;)
291 }  /* taskAsipFxn */
294 /*===========================================================================
295  * ASIP processing preparation
296  * Output:
297  *        - return        TRUE (input is ready) or FALSE (input is not ready)
298  *        - *asipErrno        Error number
299 ============================================================================*/
300 Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
301                           const PAF_ASIT_Patchs *pQ,
302                           PAF_ASIT_Config       *pC,
303                           Int                   *asipErrno)
305     Int as, zMS, zMI, zMD;
306     Int sourceConfig, mode;
307     PAF_AST_Config  *pAstCfg;
308     PAF_AST_IoInp *pInp;            /* I/O components for input */
310     pAstCfg  = pC->pAstCfg;         // pointer to AST common (shared) configuration
311     as  = pAstCfg->as;
312     zMI = pP->zone.master;
313     zMD = pAstCfg->masterDec;
314     zMS = pAstCfg->masterStr;
315     pInp = pC->pIoInp;              // pointer to input I/O components
317     *asipErrno = 0;
319     // Select source and initialize physical layer / HW interface
320     *asipErrno = asipSelectDevices(pQ, pInp);
321     if (*asipErrno) {
322         TRACE_TERSE2("TaskAsip: selectDevices returned asipErrno = 0x%04x at line %d. AS%d", *asipErrno, as+zMS);
323         return FALSE;    // Input is not ready for processing due to error
324     }
326     // If no master input selected then we don't know what may be at the input,
327     // so set to unknown and skip any remaining processing
328     if (!pInp[zMI].pRxParams) {
329         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
330                            (Int8)PAF_SOURCE_UNKNOWN, GATEMP_INDEX_DEC);
332         TRACE_VERBOSE1("TaskAsip: AS%d: No input selected...", as+zMS);
333         return FALSE;    // No error, but input is not ready for processing
334     }
336     // If here then we have a valid input so query its status
337     *asipErrno = asipUpdateInputStatus(pInp[zMI].pRxParams,
338                                    &pAstCfg->xInp[zMI].inpBufStatus,
339                                    &pAstCfg->xInp[zMI].inpBufConfig);
340     if(*asipErrno) {
341         TRACE_VERBOSE1("TaskAsip: updateInputStatus returns 0x%x", *asipErrno);
342         return FALSE;   // Input is not ready for processing due to error
343     }
345     // If master decoder is not enabled, or the input is unlocked, then do nothing
346     mode = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.mode),
347                                   GATEMP_INDEX_DEC);
348     if (!mode || !pAstCfg->xInp[zMI].inpBufStatus.lock)
349     {
350         TRACE_VERBOSE0("TaskAsip: Not locked, continue");
351         return FALSE;  // No error, but input is not ready for processing
352     }
354     // Check selected source: sourceSelect is set by another task, AIP or AFP
355     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
356                                           GATEMP_INDEX_DEC);
357     // If no source selected then do nothing
358     if(sourceConfig == PAF_SOURCE_NONE) {
359         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
360                            (Int8)PAF_SOURCE_NONE, GATEMP_INDEX_DEC);
361         TRACE_VERBOSE1("TaskAsip: AS%d: no source selected, continue", as+zMS);
362         return FALSE;  // No error, but input is not ready for processing
363     }
365     // If we want pass processing then proceed directly
366     if (sourceConfig == PAF_SOURCE_PASS)
367     {
368         TRACE_VERBOSE1("TaskAsip: AS%d: Pass processing ...", as+zMS);
369         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
370                            (Int8)PAF_SOURCE_PASS, GATEMP_INDEX_DEC);
372         pP->fxns->sourceDecode(pP, pQ, pC, PAF_SOURCE_PASS);
373         if (pP->fxns->passProcessing) {
374             *asipErrno = pP->fxns->passProcessing(pP, pQ, pC, NULL);
375         }
376         else {
377             TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x", as+zMS, ASPERR_PASS);
378             *asipErrno = ASPERR_PASS;
379         }
381         TRACE_VERBOSE0("TaskAsip: continue");
382         return FALSE;  // Error or not, input is not ready for processing
383     }
385     // No error and input processing is ready
386     return TRUE;
387 } /* asipPrepareProcessing */
389 /*===========================================================================
390  * Initialize I/O components for input processing
391 ============================================================================*/
392 int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
394     // Initialize I/O BUFF and I/O PHY components for input task
395     ioBuffParams_t ioBuffParams;
396     ioPhyParams_t  ioPhyParams;
397     ioDataParam_t  ioDataCfg;
399     ioBuffParams.base         = pInpBuf->inpBufConfig.base.pVoid;
400     ioBuffParams.size         = pInpBuf->inpBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
401     ioBuffParams.sync         = IOBUFF_WRITE_SYNC;
402     ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
403     if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
404         return (-1);   // to remove magic number
405     }
407     ioPhyParams.ioBuffHandle    = pInpIo->hIoBuff;
408     ioPhyParams.xferFrameSize   = INPUT_FRAME_SIZE_DEF;
409     ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
410     ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_WRITE;
411     if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
412         return (-1);   // to remove magic number
413     }
415     ioDataCfg.ioBuffHandle         = pInpIo->hIoBuff;
416     ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
417     ioDataCfg.frameLengthsIEC      = (uint_least16_t *)&iecFrameLength[0];
418     ioDataCfg.frameLengthPCM       = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
419     ioDataCfg.frameLengthDef       = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
420     ioDataCfg.ibMode               = pInpBuf->inpBufConfig.pBufStatus->mode;
421     ioDataCfg.zeroRunRestart       = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
422     ioDataCfg.zeroRunTrigger       = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
424     if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
425         return (-1);   // to remove magic number
426     }
428     pInpIo->numPrimeXfers  = NUM_PRIME_XFERS;
429     pInpIo->phyXferSize    = ioPhyParams.xferFrameSize;
430     //pInpIo->switchHangOver = 0;
431     pInpIo->preSyncState   = IODATA_SYNC_NONE;
433     return 0;
434 } /* asipIoCompsInit */
436 /*======================================================================================
437  *  This function initializes ASIP processing
438  *====================================================================================*/
439 void asipProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec)
441     pInp->swapData = SWAP_INPUT_DATA;
442     pInp->asipProcState = ASIP_SOURCE_DETECTION;
443     //pInp->switchHangOver = 0;
445     pDec->initDone = FALSE;
448 /*======================================================================================
449  *  I/O physical layer prime operation required by McASP LLD
450  *====================================================================================*/
451 void asipIoPhyPrime(PAF_AST_IoInp *pInp)
453     Int32        count;
455     for(count = 0; count < pInp->numPrimeXfers; count++)
456     {
457         ioPhyXferSubmit(pInp->hIoPhy);
458 #ifdef ASIP_DEBUG
459         //pInp->numXferStart++;
460 #endif
461     }
462 } /* asipIoPhyPrime */
464 /*======================================================================================
465  *  This function pends on I/O PHY transfer for the input task
466  *====================================================================================*/
467 void asipPhyTransferPend()
469     // asipSemRx needs to be placed into some data structure
470     Semaphore_pend(asipSemRx, BIOS_WAIT_FOREVER);
471 } /* asipPhyTransferPend */
473 /*======================================================================================
474  *  This function marks the I/O PHY transfer as complete
475  *====================================================================================*/
476 void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo)
478     // Mark underlining I/O BUFF write complete and swap data if needed
479     ioPhyXferComplete(pInpIo->hIoPhy, pInpIo->swapData);
480 } /* asipPhyTransferComplete */
483 /*======================================================================================
484  *  McASP LLD call back function
485  *====================================================================================*/
486 void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
488     /* post semaphore */
489     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
490         Semaphore_post(asipSemRx);
491     } else {
492         ;    // intermediate packet due to buffer wrapping around
493     }
496 /*======================================================================================
497  *  This function checks if McASP Rx for input overruns
498  *====================================================================================*/
499 int asipCheckMcaspRxOverrun(Ptr mcaspChanHandle)
501     Mcasp_errCbStatus mcaspErrStat;
503     mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
505     return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
508 /*======================================================================================
509  *  This function restarts McASP LLD channel for input
510  *====================================================================================*/
511 void asipMcaspRxRestart(void)
513     mcaspRxReset();
514     mcaspRxCreate();
517 /*======================================================================================
518  *  This function starts an I/O PHY transfer
519  *====================================================================================*/
520 void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
522     if(asipCheckMcaspRxOverrun(pInpIo->hMcaspChan)) {
523 #ifdef ASIP_DEBUG
524         pInpIo->numInputOverrun++;
525 #endif
526         asipMcaspRxRestart();
527     }
528     else {
529         if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
530             // Input buffer overflows!
531             printf("\nInput buffer overflows!\n");
532             exit(0);
533         }
534         else {
535             // Input buffer operates normally
536             ;
537         }
538 #ifdef ASIP_DEBUG
539         //pInpIo->numXferStart++;
540 #endif
541     }
544 Int d10Initialized = 0;
545 //extern Audk2g_STATUS mcaspAudioConfig(void);
546 extern void McaspDevice_init(void);
548 /*======================================================================================
549  *  This function initializes HW interface and selects the right device for input
550  *====================================================================================*/
551 Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp)
553     Audk2g_STATUS status;
555     //more configuration is needed to abstract out D10
556     if(!d10Initialized) {
557         /* Initialize McASP HW details */
558         McaspDevice_init();
560         D10_init();
562 #ifdef INPUT_SPDIF
563         // Input is DIR
564         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
565 #else
566         // Input is HDMI
567         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
568 #endif
569         if(status != Audk2g_EOK) {
570             Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
571             return ASIP_ERR_D10_CFG;
572         }
573         audk2g_delay(50000); // Without delay between these 2 calls system aborts.
575         /* Initialize McASP module */
576         status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c
577         if(status != Audk2g_EOK) {
578             Log_info0("McASP Configuration Failed!\n");
579             return ASIP_ERR_MCASP_CFG;
580         }
582         pInp->hMcaspChan = hMcaspRxChan;
583         d10Initialized = 1;
584     }
586     /////////////// TODO: HW interface selection and initialization //////////////
587     ////// to add what PAF_ASIT_selectDevices() does /////////
588 #ifdef IO_HW_INTERFACE
589     pInp->pRxParams = pQ->devinp->x[IO_HW_INTERFACE];
590 #else
591     pInp->pRxParams = NULL;
592 #endif
594     return 0;
595 }  /* asipSelectDevices */
597 /*======================================================================================
598  *  This function updates input status
599  *====================================================================================*/
600 Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
601                           PAF_InpBufConfig *pInpBuf)
603     Int asipErrno;
605     PAF_SIO_InputStatus inputStatus;
607     // initialize all values to unknown so that device specific
608     //   driver layer need only fill in those entries that it is aware of.
609     //   This allows extensibility of the structure without requiring users
610     //   to re-code.
611     inputStatus.lock = 0;
612     inputStatus.sampleRateData = PAF_SAMPLERATE_UNKNOWN;
613     inputStatus.sampleRateMeasured = PAF_SAMPLERATE_UNKNOWN;
614     inputStatus.nonaudio = PAF_IEC_AUDIOMODE_UNKNOWN;
615     inputStatus.emphasis = PAF_IEC_PREEMPHASIS_UNKNOWN;
617     //more configuration is needed to abstract out D10
618     asipErrno = D10_RxControl(pRxParams,
619                           (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS,
620                           (Arg) &inputStatus);
621     if (asipErrno) {
622         return asipErrno;
623     }
624     pStatus->sampleRateData = inputStatus.sampleRateData;
625     pStatus->sampleRateMeasured = inputStatus.sampleRateMeasured;
626     pStatus->nonaudio = inputStatus.nonaudio;
627     pStatus->emphasisData = inputStatus.emphasis;
629     // if MSB of override clear then use as reported lock
630     // if = 0x80 then use default [0x81]
631     // if = 0x81 then use measured (from device)
632     // others not defined or implemented
633     if ((pStatus->lockOverride & (XDAS_Int8)0x80) == 0)
634         pStatus->lock = pStatus->lockOverride;
635     else if (pStatus->lockOverride == (XDAS_Int8)0x80)
636         pStatus->lock = inputStatus.lock;
637     else if (pStatus->lockOverride == (XDAS_Int8)0x81)
638         pStatus->lock = inputStatus.lock;
640     // if MSB of override clear then use it as sample rate for system,
641     // if = 0x80 then use default [0x82]
642     // if = 0x81 then use data
643     // if = 0x82 then use measured
644     // others not defined or implemented
645     if ((pStatus->sampleRateOverride & (XDAS_Int8)0x80) == 0)
646         pStatus->sampleRateStatus = pStatus->sampleRateOverride;
647     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x80)
648         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
649     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x81)
650         pStatus->sampleRateStatus = pStatus->sampleRateData;
651     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x82)
652         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
654     // Update emphasis status:
655     if ((pStatus->emphasisOverride & (XDAS_Int8)0x80) == 0) {
656         if (pStatus->emphasisData == PAF_IEC_PREEMPHASIS_YES)
657             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
658         else
659             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
660     }
661     else if (pStatus->emphasisOverride ==
662              (XDAS_Int8 )(0x80+PAF_IEC_PREEMPHASIS_YES))
663         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
664     else /* IBEmphasisOverrideNo or other */
665         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
667     // Update precision control
668     pInpBuf->precision = pStatus->precisionInput =
669         pStatus->precisionOverride < 0
670         ? pStatus->precisionDefault
671         : pStatus->precisionOverride > 0
672         ? pStatus->precisionOverride
673         : pStatus->precisionDetect > 0
674         ? pStatus->precisionDetect
675         : pStatus->precisionDefault;
677     return 0;
680 /*==============================================================================
681  * After SYNC is found, i.e. either bitstream preamble is detected or it times
682  * out to PCM, update input buffer config and I/o components accordingly.
683  ==============================================================================*/
684 Int asipUpdateIoComps(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
685                       ioDataAutoDetStat_t *autoDetStatus)
687     Int sourceConfig;
688     Int zMD, deliverZeros;
689     int frameLength;
690     PAF_InpBufConfig *pBufConfig;
691     Audk2g_STATUS mcaspStatus;
692     ioPhyCtl_t  ioPhyCtl;
694     zMD = pAstCfg->masterDec;
695     pBufConfig = &pAstCfg->xInp[zMD].inpBufConfig;
697     // Get the configured source
698     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
699                                           GATEMP_INDEX_DEC);
701     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
702         // Bitstream preamble is not found and it times out -> assume this is PCM
703         deliverZeros = autoDetStatus->deliverZeros;
704         if (sourceConfig == PAF_SOURCE_PCM || sourceConfig == PAF_SOURCE_DSD1 ||
705             sourceConfig == PAF_SOURCE_DSD2 || sourceConfig == PAF_SOURCE_DSD3) {
706             // set to one -- ensures that PCM decode calls made before data is
707             // available will result in zero output.
708             // (mostly needed for PA15 since, currently, all other frameworks
709             // require a frame of data before the first decode call.
710             deliverZeros = TRUE;  // override deliverZeros returned by ioDataControl
711         }
713         // update input buffer config structure
714         pBufConfig->deliverZeros  = deliverZeros;
715         pBufConfig->sizeofElement = WORD_SIZE_PCM;
716         pBufConfig->frameLength   = pBufConfig->lengthofData = INPUT_FRAME_LENGTH;
718         // reconfigure McASP LLD to transfer 32-bit unpacked data
719         //mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
720         //if(mcaspStatus != Audk2g_EOK) {
721         //    return ASIP_ERR_MCASP_CFG;
722         //}
724         // Change I/O PHY transfer size to PCM frame size
725         pInp->phyXferSize = (INPUT_FRAME_LENGTH)*(WORD_SIZE_PCM);
727         // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
728         // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
729         // Adjust delay and don't mark input buffer as read complete
730         ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
732         // Stop swapping data
733         pInp->swapData = FALSE;
735     } /* IODATA_SYNC_PCM */
737     if(autoDetStatus->syncState == IODATA_SYNC_BITSTREAM) {
738         // Change I/O PHY transfer size to be the same as the bitstream frame size
739         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
740         frameLength = iecFrameLength[pc];
742         // update input buffer config structure
743         pBufConfig->sizeofElement = WORD_SIZE_BITSTREAM;
744         pBufConfig->frameLength   = frameLength;
745         pBufConfig->lengthofData  = frameLength - IEC_HEADER_LENGTH;
747 /*
748         if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
749             pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
750 */
752 /*        if (pc == 1)
753             pDevExt->elementSize = 4288;
754         else if (pc == 0x11) {
755             pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
756             pDevExt->lengthofData = pDevExt->frameLength;
757         }
758 */
760         // Change I/O PHY transfer size to bitstream frame size
761         pInp->phyXferSize = frameLength*WORD_SIZE_BITSTREAM;
762     }
764     pBufConfig->stride = INPUT_STRIDE;   // common for PCM and bitstream
766     //JXTODO: decide what to do with hRxSio
767     pAstCfg->xInp[zMD].hRxSio = pInp->hIoData; //temporary - does ARM use hRxSio or just check if it is not NULL?
768     pAstCfg->xInp[zMD].pInpBuf = &(pAstCfg->xInp[zMD].inpBufConfig);
770     // Update I/O PHY transfer size accordingly
771     ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
772     ioPhyCtl.params.xferFrameSize = pInp->phyXferSize;
773     ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
775     return ASIP_NO_ERR;
776 } /* asipUpdateIoComps */
778 void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
780     PAF_InpBufConfig *pBufConfig;
781     ioDataCtl_t ioDataCtl;
783     /* Get information for reading input data */
784     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
785     ioDataControl(pInp->hIoData, &ioDataCtl);
787     if(ioDataCtl.param.dataReadInfo.frameSize != pInp->phyXferSize) {
788         // Fatal error!
789         TRACE_VERBOSE0("TaskAsip: error in updating I/O");
790         SW_BREAKPOINT;
791     }
793     pBufConfig = &(pAstCfg->xInp[pAstCfg->masterDec].inpBufConfig);
795     //JXTODO: do we need to gate here? - No, since ARM won't read until it receives message
796     //key = GateMP_enter(gateHandle);
798     pBufConfig->base.pVoid   = ioDataCtl.param.dataReadInfo.buffBase;
799     pBufConfig->sizeofBuffer = ioDataCtl.param.dataReadInfo.buffSize;
800     pBufConfig->pntr.pSmInt  = ioDataCtl.param.dataReadInfo.startAddress;
802     // Leave the gate
803     //GateMP_leave(gateHandle, key);
806 /*==============================================================================
807  * Decide source after SYNC is found, i.e. either bitstream preamble is detected
808  * or it times out to PCM.
809  ==============================================================================*/
810 Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
811                      ioDataAutoDetStat_t *autoDetStatus)
813     Int sourceConfig, sourceSelect, sourceProgram;
814     Int zMD;
815     char asipMsgBuf[ASP_MSG_BUF_LEN];
817     // Get the configured source
818     zMD = pAstCfg->masterDec;
819     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC);
821     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
822         if (sourceConfig == PAF_SOURCE_DSD1 || sourceConfig == PAF_SOURCE_DSD2 ||
823             sourceConfig == PAF_SOURCE_DSD3) {
824             sourceProgram = sourceConfig;
825         }
826         else {
827             sourceProgram = PAF_SOURCE_PCM;
828         }
829     }
831     if(autoDetStatus->syncState == IODATA_SYNC_BITSTREAM) {
832         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
833         sourceProgram = IECpafSource[pc];
834     }
836     // write the decided source program to memory
837     sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram, GATEMP_INDEX_DEC);
839     // now that we have some input classification, and possibly an outstanding
840     // input frame, we determine whether or not to call decodeProcessing and with
841     // what decAlg.
842     sourceSelect = PAF_SOURCE_NONE;
844     switch (sourceConfig)
845     {
846         // If autodetecting, decoding everything, and input is something
847         // (i.e. bitstream or PCM) then decode.
848         case PAF_SOURCE_AUTO:
849             if (sourceProgram >= PAF_SOURCE_PCM)  {
850                 sourceSelect = sourceProgram; // use whatever from autodet
851             }
852             break;
854         // If autodetecting, decoding only PCM, and input is PCM then decode.
855         case PAF_SOURCE_PCMAUTO:
856             if (sourceProgram == PAF_SOURCE_PCM) {
857                 sourceSelect = sourceProgram;  // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
858             }
859             break;
861         // If autodetecting, decoding only bitstreams, and input is a bitstream then decode.
862         case PAF_SOURCE_BITSTREAM:
863             if (sourceProgram >= PAF_SOURCE_AC3) {
864                 sourceSelect = sourceProgram;
865             }
866             break;
868         // If autodetecting, decoding only DTS, and input is DTS then decode.
869         case PAF_SOURCE_DTSALL:
870             switch (sourceProgram)
871             {
872                 case PAF_SOURCE_DTS11:
873                 case PAF_SOURCE_DTS12:
874                 case PAF_SOURCE_DTS13:
875                 case PAF_SOURCE_DTS14:
876                 case PAF_SOURCE_DTS16:
877                 case PAF_SOURCE_DTSHD:
878                     sourceSelect = sourceProgram;
879                     break;
880             }
881             break;
883         // All others, e.g., force modes, fall through to here.
884         // If user made specific selection then program must match select.
885         // (NB: this compare relies on ordering of PAF_SOURCE)
886         default:
887             sourceSelect = sourceConfig;
888             if ((sourceSelect >= PAF_SOURCE_PCM) && (sourceSelect <= PAF_SOURCE_N)) {
889                 if (sourceProgram != sourceSelect) {
890                     sourceSelect = PAF_SOURCE_NONE;
891                 }
892             }
893             break;
894     }
896     // if we didn't find any matches then skip
897     if (sourceSelect == PAF_SOURCE_NONE) {
898         TRACE_VERBOSE0("TaskAsip: no matching source type, continue");
899         return ASIP_ERR_NO_MATCHING_SOURCE;
900     }
902 #ifndef PCM_LOOPBACK_TEST
903     // send source select message to slave
904     *(Int32 *)&asipMsgBuf[0] = sourceSelect;
905     if(AspMsgSend(ASP_SLAVE_DEC_SOURCE_SELECT, ASP_MASTER_DEC_SOURCE_SELECT_DONE,
906                   asipMsgBuf, NULL) != ASP_MSG_NO_ERR) {
907         TRACE_VERBOSE0("TaskAsip: error in sending SOURCE_SELECT message");
908         SW_BREAKPOINT;
909     }
910 #endif
912     pInp->sourceSelect  = sourceSelect;
913     pInp->sourceProgram = sourceProgram;
915     return ASIP_NO_ERR;
916 } /* asipDecideSource */
919 Int asipBypassIoData(PAF_AST_IoInp *pInp)
921     // When switching to PCM, McASP RFMT register will be modified,
922     // which will cause all 0's in one McASP LLD transfer. This will
923     // be detected as loss of SYNC by auto detection. To prevent that,
924     // skip I/O DATA process for hangover period so that this all 0's
925     // frame will not be seen by auto-detection. Also, playing out PCM
926     // needs to be skipped as well, to prevent from playing out garbage
927     // (16-bit packed data).
928     void *buff1, *buff2;
929     size_t size1, size2;
931     // Get read pointers (or sub-buffers) of the input buffer
932     if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
933                           &buff1, &size1, &buff2, &size2)
934         == IOBUFF_ERR_UNDERFLOW) {
935         //printf("Input buffer underflows during switch hangover!\n");
936         return ASIP_ERR_SWITCH_TO_PCM;
937     }
939     ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
941     if(buff2 != NULL) {
942         ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
943     }
945     return ASIP_NO_ERR;
948 /*=============================================================================
949  *  Main function of ASIP processing
950  *============================================================================*/
951 Int asipProcessing(const PAF_ASIT_Params *pP,
952                    const PAF_ASIT_Patchs *pQ,
953                    PAF_ASIT_Config *pAsitCfg)
956     PAF_AST_Config  *pAstCfg;
957     int ioDataStatus, asipStatus, zMI;
958     ioDataAutoDetStat_t autoDetStatus;
959     Audk2g_STATUS mcaspStatus;
960     ioDataCtl_t ioDataCtl;
961     ioPhyCtl_t  ioPhyCtl;
962     PAF_AST_IoInp *pInp;            /* Input I/O components */
964     pAstCfg = pAsitCfg->pAstCfg;
965     zMI  = pAstCfg->masterDec;
966     pInp = &pAsitCfg->pIoInp[zMI]; // pointer to input I/O components
968     if(pInp->asipProcState == ASIP_SWITCH_TO_PCM) {
969         // Bypass I/O data processing due to McASP LLD work around
970         // (refer to comments inside the function)
971         asipStatus = asipBypassIoData(pInp);
972         if(asipStatus != ASIP_NO_ERR) {
973             return asipStatus;
974         }
975     }
976     else {
977         // Perform auto-detection when not switching
978         ioDataStatus = ioDataProcess(pInp->hIoData);
979         if(ioDataStatus == IODATA_ERR_IOBUF_UNDERFLOW) {
980             // Input buffer underflows - no action is needed
981             pInp->numUnderflow += 1;
983             // Return since there is no enough data to process
984             return ASIP_NO_ERR;
985         }
986         else if(ioDataStatus != IODATA_NO_ERR) {
987             // Something is wrong: print error log and return
988             //printf("IODATA processing error!\n");
989             return ASIP_ERR_AUTO_DETECION;
990         }
991         else {
992             // Normal operation - check auto-detection status
993             ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
994             ioDataControl(pInp->hIoData, &ioDataCtl);
996             autoDetStatus = ioDataCtl.param.autoDetStats;
997         }
998     }
1000     switch(pInp->asipProcState)
1001     {
1002     case ASIP_SOURCE_DETECTION:
1003         // zero out the output buffer
1004         rxDecodePlayZero(pInp);
1006         if(   autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
1007            || autoDetStatus.syncState == IODATA_SYNC_PCM) {
1008             // Update I/O components and input buffer config
1009             asipUpdateIoComps(pAstCfg, pInp, &autoDetStatus);
1011             // Decide input source and inform decoder
1012             asipStatus = asipDecideSource(pAstCfg, pInp, &autoDetStatus);
1013             if(asipStatus != ASIP_NO_ERR) {
1014                 return asipStatus;
1015             }
1016             else {
1017                 // set to unknown so that we can ensure, for IOS purposes, that sourceDecode = NONE
1018                 // iff we are in this top level state machine and specifically not in decodeProcessing
1019 #ifndef PCM_LOOPBACK_TEST
1020                 pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
1021 #endif
1023                 if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
1024                     // Input is bit stream: go to decoding
1025                     pInp->asipProcState = ASIP_DECODE;
1026                     //pInp->numFrameReceived = 1;
1027                 }
1028                 else  {
1029                     // Input is PCM: stop swapping data
1030                     pInp->swapData = FALSE;
1032                     // Reconfigure McASP LLD to transfer 32-bit unpacked data
1033                     mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
1034                     if(mcaspStatus != Audk2g_EOK) {
1035                         return ASIP_ERR_MCASP_CFG;
1036                     }
1038                     // Go to transition state to switch to PCM
1039                     pInp->asipProcState = ASIP_SWITCH_TO_PCM;
1040                     pInp->switchHangOver = INPUT_SWITCH_HANGOVER;
1041                     //pInp->numPcmFrameReceived = 0;
1042                 }
1043             }
1045             pInp->numFrameReceived = 0;
1046             pInp->preSyncState = autoDetStatus.syncState;
1047         }
1048         else {
1049             // Source is still unknown - take no action
1050             ;
1051         }
1052         break;
1054     case ASIP_SWITCH_TO_PCM:
1055         // zero out the output buffer
1056         rxDecodePlayZero(pInp);
1058         pInp->switchHangOver--;
1059         if(pInp->switchHangOver == 0) {
1060             pInp->asipProcState = ASIP_DECODE;
1061         }
1062         break;
1064     case ASIP_DECODE:
1065         if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
1066             // SYNC lost: change I/O PHY transfer size to default for auto-detection
1067             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
1068             ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
1069             ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
1070             pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
1072             if(pInp->preSyncState == IODATA_SYNC_PCM) {
1073                 // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
1074                 mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
1075                 if(mcaspStatus != Audk2g_EOK) {
1076                     return ASIP_ERR_MCASP_CFG;
1077                 }
1079                 // Start swapping data
1080                 pInp->swapData = TRUE;
1081             }
1083             // Inform decoder to complete decoding previous frame
1084             pInp->sourceSelect = PAF_SOURCE_NONE;
1086             pInp->numFrameReceived = 0;
1087             pInp->asipProcState  = ASIP_SOURCE_DETECTION;
1088         }
1089         else {
1090             pInp->numFrameReceived += 1;    // for debugging
1092             // Communicate input stream information to decoder through input buffer configuration
1093             asipUpdateInpBufConfig(pAstCfg, pInp);
1094         }
1096 #ifndef PCM_LOOPBACK_TEST
1097         asipStatus = asipDecodeProcessing(pP, pQ, pAsitCfg, pInp->sourceSelect);
1098         if(asipStatus != ASIP_NO_ERR) {
1100             // FL: send dec exit message to slave
1101             if( AspMsgSend(ASP_SLAVE_DEC_EXIT, ASP_MASTER_DEC_EXIT_DONE, NULL, NULL)
1102                 != ASP_MSG_NO_ERR)
1103             {
1104                 TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
1105                 SW_BREAKPOINT;
1106             }
1108             return asipStatus;
1109         }
1110 #else
1111         if(autoDetStatus.syncState == IODATA_SYNC_PCM) {
1112             rxDecodePcm(pInp);     // for PCM loopback testing
1113         }
1114 #endif
1115         break;
1117     default:
1118         break;
1119     }
1121     if(pInp->asipProcState != ASIP_SWITCH_TO_PCM) {
1122         ioDataReadComplete(pInp->hIoData);
1123     }
1125     return 0;
1126 } /* asipProcessing */
1128 /*======================================================================================
1129  *  This function decides the input source based on auto-detection information.
1130  *====================================================================================*/
1131 //Int asipDecideSource(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, asipDecProc_t *pDec)
1132 //{
1134 //}
1137 #ifndef IO_LOOPBACK_TEST
1138 #if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH
1139 U8 pcmbuf[OUTPUT_FRAME_SIZE];
1140 #else
1141 #error Input frame length is not equal to output frame length!
1142 #endif
1144 Int rxDecodePcm(PAF_AST_IoInp  *pInp)
1146     ioDataCtl_t ioDataCtl;
1147     void *buffBase;
1148     void *dataStartAddress;
1149     size_t buffSize, frameSize, size1, size2;
1151     /* Get information for reading input data */
1152     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
1153     ioDataControl(pInp->hIoData, &ioDataCtl);
1155     buffBase = ioDataCtl.param.dataReadInfo.buffBase;
1156     buffSize = ioDataCtl.param.dataReadInfo.buffSize;
1157     dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
1158     frameSize        = ioDataCtl.param.dataReadInfo.frameSize;
1160     // Copy PCM data to output buffer
1161     if(((size_t)dataStartAddress+frameSize) <= ((size_t)buffBase+buffSize)) {
1162         // Input buffer doesn't wrap around
1163         Cache_inv(dataStartAddress, frameSize, Cache_Type_ALL, TRUE);
1164         memcpy((void *)&pcmbuf[0], dataStartAddress, frameSize);
1165     }
1166     else {
1167         // Input buffer wraps around
1168         size1 = (size_t)buffBase + buffSize - (size_t)dataStartAddress;
1169         size2 = frameSize - size1;
1170         Cache_inv(dataStartAddress, size1, Cache_Type_ALL, TRUE);
1171         memcpy((void *)&pcmbuf[0], dataStartAddress, size1);
1173         Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
1174         memcpy((void *)&pcmbuf[size1], buffBase, size2);
1175     }
1178     return ASIP_NO_ERR;
1181 Int rxDecodeBitStream(PAF_AST_IoInp  *pInp)
1183     return ASIP_NO_ERR;
1187 Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
1189     return ASIP_NO_ERR;
1191 #endif
1193 void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno)
1198 /* Nothing past this line */