3afb532b2621401c4e757f293791bfe528f29b3e
[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;
164 // FL: debug
165 #include "evmc66x_gpio_dbg.h"
166 #endif
168 /*
169  *  ======== taskAsipFxn ========
170  *  Audio Stream Input Processing task function
171  */
172 #ifndef PASDK_SIO_DEV
173 #ifndef IO_LOOPBACK_TEST
174 Void taskAsipFxn(                  // ASIP task function for new I/O
175 #else
176 Void taskAsipFxn_NewIO_Not_Used(   // not used for loopback test
177 #endif
178 #else
179 Void taskAsipFxn_NewIO_Not_USED(   // not used for SIO/DEV based I/O
180 #endif
181     const PAF_ASIT_Params *pP,
182         const PAF_ASIT_Patchs *pQ)
184     PAF_ASIT_Config *pAsitCfg;      /* ASIT configuration pointer */
185     PAF_AST_Config  *pAstCfg;       /* AST Common (shared) configuration pointer */
186     PAF_AST_IoInp *pInp;            /* Input I/O components */
187     Int as;                         /* Audio Stream Number (1, 2, etc.) */
188     Int z;                          /* input/encode/stream/decode/output counter */
189     Int zMI;
190 #ifndef ASIP_DEBUG
191 int asipLoopCount1, asipLoopCount2;
192 Int asipErrno;
193 Int inputReadyForProcessing;
194 #endif
196     Int firstTimeInit = TRUE;
198     Log_info0("Enter taskAsipFxn()");
200     taskAsipFxnInit(pP, pQ);  // initialization of input task
201     
202     //
203     // Audio Stream Input Task Configuration (*pAsitCfg):
204     //
205     pAsitCfg = &gPAF_ASIT_config;       // initialize pointer to task configuration
206     pAstCfg  = pAsitCfg->pAstCfg;       // pointer to AST common (shared) configuration
208     /* Set Audio Stream Number (1, 2, etc.) */
209     as = pAstCfg->as;
211     //
212     // Determine decoder and stream indices associated with the master input
213     //
214     zMI  = pP->zone.master;
215     pInp = &pAsitCfg->pIoInp[zMI];        // pointer to input I/O components
217     for (z=STREAM1; z < STREAMN; z++)
218     {
219         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
220     }
222     TRACE_TERSE0("TaskAsip: Entering Main Loop.");
224     //
225     // Main processing loop
226     //
227     asipLoopCount1 = 0;
228     asipLoopCount2 = 0;
229     asipErrno = 0;
230     pInp->asipState = ASIP_INPUT_PREPARATION;
232     for (;;)
233     {
234         asipLoopCount1++;
236         switch (pInp->asipState)
237         {
238         case ASIP_INPUT_PREPARATION:
239             // Indicate decoder no decoding yet
240             pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
242             // 5 system tick, or 5 msec. Should remove this later when implementing
243             // event based scheduling.
244             Task_sleep(5);
246             inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
247             if (inputReadyForProcessing) {
248                 // Input is ready for processing, so we initialize the I/O components.
249                 // Note that the I/O components init. and I/O PHY prime are performed only at the
250                 // first time. This should be changed later - init. and prime should be done whenever
251                 // input interface has changed.
252                 if(firstTimeInit) {
253                     asipIoCompsInit(&pAstCfg->xInp[zMI], pInp);
255                     // Start I/O physical layer by priming McASP LLD for input
256                     asipIoPhyPrime(pInp);
258                     firstTimeInit = FALSE;
259                 }
261                 // Initialize ASIP processing
262                 asipProcInit(pInp, &pAsitCfg->inpDec);
264                 pInp->asipState = ASIP_INPUT_PROCESSING;
265             }
266             break;
268         case ASIP_INPUT_PROCESSING:
269             // Pending on I/O PHY transfer
270             asipPhyTransferPend();
272 #if 1 // (***) FL: shows timing of Input (Rx McASP EDMA) after decoding has started (autodet complete)
273             // (***) debug // B5
274             {
275                 static Uint8 toggleState = 0;
276                 if (toggleState == 0)
277                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
278                 else
279                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
280                 toggleState = ~(toggleState);
281             }
282 #endif            
283             
284             // Marks I/O PHY transfer and I/O BUFF write complete
285             asipPhyTransferComplete(pInp);
287             // Main function to process input data
288             asipErrno = asipProcessing(pP, pQ, pAsitCfg);
290             // Start next transfer
291             asipPhyTransferStart(pInp);
293             if(asipErrno) {
294                 asipErrorHandling(pAstCfg, asipErrno);
296                 pInp->asipState = ASIP_INPUT_PREPARATION;
297             }
299             break;
301         default:
302             break;
303         }
304     }  // for (;;)
306 }  /* taskAsipFxn */
309 /*===========================================================================
310  * ASIP processing preparation
311  * Output:
312  *        - return        TRUE (input is ready) or FALSE (input is not ready)
313  *        - *asipErrno        Error number
314 ============================================================================*/
315 Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
316                           const PAF_ASIT_Patchs *pQ,
317                           PAF_ASIT_Config       *pC,
318                           Int                   *asipErrno)
320     Int as, zMS, zMI, zMD;
321     Int sourceConfig, mode;
322     PAF_AST_Config  *pAstCfg;
323     PAF_AST_IoInp *pInp;            /* I/O components for input */
325     pAstCfg  = pC->pAstCfg;         // pointer to AST common (shared) configuration
326     as  = pAstCfg->as;
327     zMI = pP->zone.master;
328     zMD = pAstCfg->masterDec;
329     zMS = pAstCfg->masterStr;
330     pInp = pC->pIoInp;              // pointer to input I/O components
332     *asipErrno = 0;
334     // Select source and initialize physical layer / HW interface
335     *asipErrno = asipSelectDevices(pQ, pInp);
336     if (*asipErrno) {
337         TRACE_TERSE2("TaskAsip: selectDevices returned asipErrno = 0x%04x at line %d. AS%d", *asipErrno, as+zMS);
338         return FALSE;    // Input is not ready for processing due to error
339     }
341     // If no master input selected then we don't know what may be at the input,
342     // so set to unknown and skip any remaining processing
343     if (!pInp[zMI].pRxParams) {
344         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
345                            (Int8)PAF_SOURCE_UNKNOWN, GATEMP_INDEX_DEC);
347         TRACE_VERBOSE1("TaskAsip: AS%d: No input selected...", as+zMS);
348         return FALSE;    // No error, but input is not ready for processing
349     }
351     // If here then we have a valid input so query its status
352     *asipErrno = asipUpdateInputStatus(pInp[zMI].pRxParams,
353                                    &pAstCfg->xInp[zMI].inpBufStatus,
354                                    &pAstCfg->xInp[zMI].inpBufConfig);
355     if(*asipErrno) {
356         TRACE_VERBOSE1("TaskAsip: updateInputStatus returns 0x%x", *asipErrno);
357         return FALSE;   // Input is not ready for processing due to error
358     }
360     // If master decoder is not enabled, or the input is unlocked, then do nothing
361     mode = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.mode),
362                                   GATEMP_INDEX_DEC);
363     if (!mode || !pAstCfg->xInp[zMI].inpBufStatus.lock)
364     {
365         TRACE_VERBOSE0("TaskAsip: Not locked, continue");
366         return FALSE;  // No error, but input is not ready for processing
367     }
369     // Check selected source: sourceSelect is set by another task, AIP or AFP
370     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
371                                           GATEMP_INDEX_DEC);
372     // If no source selected then do nothing
373     if(sourceConfig == PAF_SOURCE_NONE) {
374         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
375                            (Int8)PAF_SOURCE_NONE, GATEMP_INDEX_DEC);
376         TRACE_VERBOSE1("TaskAsip: AS%d: no source selected, continue", as+zMS);
377         return FALSE;  // No error, but input is not ready for processing
378     }
380     // If we want pass processing then proceed directly
381     if (sourceConfig == PAF_SOURCE_PASS)
382     {
383         TRACE_VERBOSE1("TaskAsip: AS%d: Pass processing ...", as+zMS);
384         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
385                            (Int8)PAF_SOURCE_PASS, GATEMP_INDEX_DEC);
387         pP->fxns->sourceDecode(pP, pQ, pC, PAF_SOURCE_PASS);
388         if (pP->fxns->passProcessing) {
389             *asipErrno = pP->fxns->passProcessing(pP, pQ, pC, NULL);
390         }
391         else {
392             TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x", as+zMS, ASPERR_PASS);
393             *asipErrno = ASPERR_PASS;
394         }
396         TRACE_VERBOSE0("TaskAsip: continue");
397         return FALSE;  // Error or not, input is not ready for processing
398     }
400     // No error and input processing is ready
401     return TRUE;
402 } /* asipPrepareProcessing */
404 /*===========================================================================
405  * Initialize I/O components for input processing
406 ============================================================================*/
407 int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
409     // Initialize I/O BUFF and I/O PHY components for input task
410     ioBuffParams_t ioBuffParams;
411     ioPhyParams_t  ioPhyParams;
412     ioDataParam_t  ioDataCfg;
414     ioBuffParams.base         = pInpBuf->inpBufConfig.base.pVoid;
415     ioBuffParams.size         = pInpBuf->inpBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
416     ioBuffParams.sync         = IOBUFF_WRITE_SYNC;
417     ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
418     if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
419         return (-1);   // to remove magic number
420     }
422     ioPhyParams.ioBuffHandle    = pInpIo->hIoBuff;
423     ioPhyParams.xferFrameSize   = INPUT_FRAME_SIZE_DEF;
424     ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
425     ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_WRITE;
426     if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
427         return (-1);   // to remove magic number
428     }
430     ioDataCfg.ioBuffHandle         = pInpIo->hIoBuff;
431     ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
432     ioDataCfg.frameLengthsIEC      = (uint_least16_t *)&iecFrameLength[0];
433     ioDataCfg.frameLengthPCM       = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
434     ioDataCfg.frameLengthDef       = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
435     ioDataCfg.ibMode               = pInpBuf->inpBufConfig.pBufStatus->mode;
436     ioDataCfg.zeroRunRestart       = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
437     ioDataCfg.zeroRunTrigger       = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
439     if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
440         return (-1);   // to remove magic number
441     }
443     pInpIo->numPrimeXfers  = NUM_PRIME_XFERS;
444     pInpIo->phyXferSize    = ioPhyParams.xferFrameSize;
445     //pInpIo->switchHangOver = 0;
446     pInpIo->preSyncState   = IODATA_SYNC_NONE;
448     return 0;
449 } /* asipIoCompsInit */
451 /*======================================================================================
452  *  This function initializes ASIP processing
453  *====================================================================================*/
454 void asipProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec)
456     pInp->swapData = SWAP_INPUT_DATA;
457     pInp->asipProcState = ASIP_SOURCE_DETECTION;
458     //pInp->switchHangOver = 0;
460     pDec->initDone = FALSE;
463 /*======================================================================================
464  *  I/O physical layer prime operation required by McASP LLD
465  *====================================================================================*/
466 void asipIoPhyPrime(PAF_AST_IoInp *pInp)
468     Int32        count;
470     for(count = 0; count < pInp->numPrimeXfers; count++)
471     {
472         ioPhyXferSubmit(pInp->hIoPhy);
473 #ifdef ASIP_DEBUG
474         //pInp->numXferStart++;
475 #endif
476     }
477 } /* asipIoPhyPrime */
479 /*======================================================================================
480  *  This function pends on I/O PHY transfer for the input task
481  *====================================================================================*/
482 void asipPhyTransferPend()
484     // asipSemRx needs to be placed into some data structure
485     Semaphore_pend(asipSemRx, BIOS_WAIT_FOREVER);
486 } /* asipPhyTransferPend */
488 /*======================================================================================
489  *  This function marks the I/O PHY transfer as complete
490  *====================================================================================*/
491 void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo)
493     // Mark underlining I/O BUFF write complete and swap data if needed
494     ioPhyXferComplete(pInpIo->hIoPhy, pInpIo->swapData);
495 } /* asipPhyTransferComplete */
498 /*======================================================================================
499  *  McASP LLD call back function
500  *====================================================================================*/
501 void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
503     /* post semaphore */
504     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
505         Semaphore_post(asipSemRx);
506     } else {
507         ;    // intermediate packet due to buffer wrapping around
508     }
511 /*======================================================================================
512  *  This function checks if McASP Rx for input overruns
513  *====================================================================================*/
514 int asipCheckMcaspRxOverrun(Ptr mcaspChanHandle)
516     Mcasp_errCbStatus mcaspErrStat;
518     mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
520     return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
523 /*======================================================================================
524  *  This function restarts McASP LLD channel for input
525  *====================================================================================*/
526 void asipMcaspRxRestart(void)
528     mcaspRxReset();
529     mcaspRxCreate();
532 /*======================================================================================
533  *  This function starts an I/O PHY transfer
534  *====================================================================================*/
535 void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
537     if(asipCheckMcaspRxOverrun(pInpIo->hMcaspChan)) {
538 #ifdef ASIP_DEBUG
539         pInpIo->numInputOverrun++;
540 #endif
541         asipMcaspRxRestart();
542     }
543     else {
544         if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
545             // Input buffer overflows!
546             printf("\nInput buffer overflows!\n");
547             exit(0);
548         }
549         else {
550             // Input buffer operates normally
551             ;
552         }
553 #ifdef ASIP_DEBUG
554         //pInpIo->numXferStart++;
555 #endif
556     }
559 Int d10Initialized = 0;
560 //extern Audk2g_STATUS mcaspAudioConfig(void);
561 extern void McaspDevice_init(void);
563 /*======================================================================================
564  *  This function initializes HW interface and selects the right device for input
565  *====================================================================================*/
566 Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp)
568     Audk2g_STATUS status;
570     //more configuration is needed to abstract out D10
571     if(!d10Initialized) {
572         /* Initialize McASP HW details */
573         McaspDevice_init();
575         D10_init();
577 #ifdef INPUT_SPDIF
578         // Input is DIR
579         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
580 #else
581         // Input is HDMI
582         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
583 #endif
584         if(status != Audk2g_EOK) {
585             Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
586             return ASIP_ERR_D10_CFG;
587         }
588         audk2g_delay(50000); // Without delay between these 2 calls system aborts.
590         /* Initialize McASP module */
591         status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c
592         if(status != Audk2g_EOK) {
593             Log_info0("McASP Configuration Failed!\n");
594             return ASIP_ERR_MCASP_CFG;
595         }
597         pInp->hMcaspChan = hMcaspRxChan;
598         d10Initialized = 1;
599     }
601     /////////////// TODO: HW interface selection and initialization //////////////
602     ////// to add what PAF_ASIT_selectDevices() does /////////
603 #ifdef IO_HW_INTERFACE
604     pInp->pRxParams = pQ->devinp->x[IO_HW_INTERFACE];
605 #else
606     pInp->pRxParams = NULL;
607 #endif
609     return 0;
610 }  /* asipSelectDevices */
612 /*======================================================================================
613  *  This function updates input status
614  *====================================================================================*/
615 Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
616                           PAF_InpBufConfig *pInpBuf)
618     Int asipErrno;
620     PAF_SIO_InputStatus inputStatus;
622     // initialize all values to unknown so that device specific
623     //   driver layer need only fill in those entries that it is aware of.
624     //   This allows extensibility of the structure without requiring users
625     //   to re-code.
626     inputStatus.lock = 0;
627     inputStatus.sampleRateData = PAF_SAMPLERATE_UNKNOWN;
628     inputStatus.sampleRateMeasured = PAF_SAMPLERATE_UNKNOWN;
629     inputStatus.nonaudio = PAF_IEC_AUDIOMODE_UNKNOWN;
630     inputStatus.emphasis = PAF_IEC_PREEMPHASIS_UNKNOWN;
632     //more configuration is needed to abstract out D10
633     asipErrno = D10_RxControl(pRxParams,
634                           (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS,
635                           (Arg) &inputStatus);
636     if (asipErrno) {
637         return asipErrno;
638     }
639     pStatus->sampleRateData = inputStatus.sampleRateData;
640     pStatus->sampleRateMeasured = inputStatus.sampleRateMeasured;
641     pStatus->nonaudio = inputStatus.nonaudio;
642     pStatus->emphasisData = inputStatus.emphasis;
644     // if MSB of override clear then use as reported lock
645     // if = 0x80 then use default [0x81]
646     // if = 0x81 then use measured (from device)
647     // others not defined or implemented
648     if ((pStatus->lockOverride & (XDAS_Int8)0x80) == 0)
649         pStatus->lock = pStatus->lockOverride;
650     else if (pStatus->lockOverride == (XDAS_Int8)0x80)
651         pStatus->lock = inputStatus.lock;
652     else if (pStatus->lockOverride == (XDAS_Int8)0x81)
653         pStatus->lock = inputStatus.lock;
655     // if MSB of override clear then use it as sample rate for system,
656     // if = 0x80 then use default [0x82]
657     // if = 0x81 then use data
658     // if = 0x82 then use measured
659     // others not defined or implemented
660     if ((pStatus->sampleRateOverride & (XDAS_Int8)0x80) == 0)
661         pStatus->sampleRateStatus = pStatus->sampleRateOverride;
662     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x80)
663         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
664     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x81)
665         pStatus->sampleRateStatus = pStatus->sampleRateData;
666     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x82)
667         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
669     // Update emphasis status:
670     if ((pStatus->emphasisOverride & (XDAS_Int8)0x80) == 0) {
671         if (pStatus->emphasisData == PAF_IEC_PREEMPHASIS_YES)
672             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
673         else
674             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
675     }
676     else if (pStatus->emphasisOverride ==
677              (XDAS_Int8 )(0x80+PAF_IEC_PREEMPHASIS_YES))
678         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
679     else /* IBEmphasisOverrideNo or other */
680         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
682     // Update precision control
683     pInpBuf->precision = pStatus->precisionInput =
684         pStatus->precisionOverride < 0
685         ? pStatus->precisionDefault
686         : pStatus->precisionOverride > 0
687         ? pStatus->precisionOverride
688         : pStatus->precisionDetect > 0
689         ? pStatus->precisionDetect
690         : pStatus->precisionDefault;
692     return 0;
696 void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
698     PAF_InpBufConfig *pBufConfig;
699     ioDataCtl_t ioDataCtl;
701     /* Get information for reading input data */
702     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
703     ioDataControl(pInp->hIoData, &ioDataCtl);
705     if(ioDataCtl.param.dataReadInfo.frameSize != pInp->phyXferSize) {
706         // Fatal error!
707         TRACE_VERBOSE0("TaskAsip: error in updating I/O");
708         SW_BREAKPOINT;
709     }
711     pBufConfig = &(pAstCfg->xInp[pAstCfg->masterDec].inpBufConfig);
713     //JXTODO: do we need to gate here? - No, since ARM won't read until it receives message
714     //key = GateMP_enter(gateHandle);
716     pBufConfig->base.pVoid   = ioDataCtl.param.dataReadInfo.buffBase;
717     pBufConfig->sizeofBuffer = ioDataCtl.param.dataReadInfo.buffSize;
718     pBufConfig->pntr.pSmInt  = ioDataCtl.param.dataReadInfo.startAddress;
720     // Leave the gate
721     //GateMP_leave(gateHandle, key);
724 /*==============================================================================
725  * Decide source after SYNC is found, i.e. either bitstream preamble is detected
726  * or it times out to PCM.
727  ==============================================================================*/
728 Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
729                      ioDataAutoDetStat_t *autoDetStatus)
731     Int sourceConfig, sourceSelect, sourceProgram;
732     Int zMD;
733     char asipMsgBuf[ASP_MSG_BUF_LEN];
735     // Get the configured source
736     zMD = pAstCfg->masterDec;
737     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC);
739     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
740         if (sourceConfig == PAF_SOURCE_DSD1 || sourceConfig == PAF_SOURCE_DSD2 ||
741             sourceConfig == PAF_SOURCE_DSD3) {
742             sourceProgram = sourceConfig;
743         }
744         else {
745             sourceProgram = PAF_SOURCE_PCM;
746         }
747     }
749     if(autoDetStatus->syncState == IODATA_SYNC_BITSTREAM) {
750         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
751         sourceProgram = IECpafSource[pc];
752     }
754     // write the decided source program to memory
755     sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram, GATEMP_INDEX_DEC);
757     // now that we have some input classification, and possibly an outstanding
758     // input frame, we determine whether or not to call decodeProcessing and with
759     // what decAlg.
760     sourceSelect = PAF_SOURCE_NONE;
762     switch (sourceConfig)
763     {
764         // If autodetecting, decoding everything, and input is something
765         // (i.e. bitstream or PCM) then decode.
766         case PAF_SOURCE_AUTO:
767             if (sourceProgram >= PAF_SOURCE_PCM)  {
768                 sourceSelect = sourceProgram; // use whatever from autodet
769             }
770             break;
772         // If autodetecting, decoding only PCM, and input is PCM then decode.
773         case PAF_SOURCE_PCMAUTO:
774             if (sourceProgram == PAF_SOURCE_PCM) {
775                 sourceSelect = sourceProgram;  // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
776             }
777             break;
779         // If autodetecting, decoding only bitstreams, and input is a bitstream then decode.
780         case PAF_SOURCE_BITSTREAM:
781             if (sourceProgram >= PAF_SOURCE_AC3) {
782                 sourceSelect = sourceProgram;
783             }
784             break;
786         // If autodetecting, decoding only DTS, and input is DTS then decode.
787         case PAF_SOURCE_DTSALL:
788             switch (sourceProgram)
789             {
790                 case PAF_SOURCE_DTS11:
791                 case PAF_SOURCE_DTS12:
792                 case PAF_SOURCE_DTS13:
793                 case PAF_SOURCE_DTS14:
794                 case PAF_SOURCE_DTS16:
795                 case PAF_SOURCE_DTSHD:
796                     sourceSelect = sourceProgram;
797                     break;
798             }
799             break;
801         // All others, e.g., force modes, fall through to here.
802         // If user made specific selection then program must match select.
803         // (NB: this compare relies on ordering of PAF_SOURCE)
804         default:
805             sourceSelect = sourceConfig;
806             if ((sourceSelect >= PAF_SOURCE_PCM) && (sourceSelect <= PAF_SOURCE_N)) {
807                 if (sourceProgram != sourceSelect) {
808                     sourceSelect = PAF_SOURCE_NONE;
809                 }
810             }
811             break;
812     }
814     // if we didn't find any matches then skip
815     if (sourceSelect == PAF_SOURCE_NONE) {
816         TRACE_VERBOSE0("TaskAsip: no matching source type, continue");
817         return ASIP_ERR_NO_MATCHING_SOURCE;
818     }
820 #ifndef PCM_LOOPBACK_TEST
821     // send source select message to slave
822     *(Int32 *)&asipMsgBuf[0] = sourceSelect;
823     if(AspMsgSend(ASP_SLAVE_DEC_SOURCE_SELECT, ASP_MASTER_DEC_SOURCE_SELECT_DONE,
824                   asipMsgBuf, NULL) != ASP_MSG_NO_ERR) {
825         TRACE_VERBOSE0("TaskAsip: error in sending SOURCE_SELECT message");
826         SW_BREAKPOINT;
827     }
828 #endif
830     pInp->sourceSelect  = sourceSelect;
831     pInp->sourceProgram = sourceProgram;
833     return ASIP_NO_ERR;
834 } /* asipDecideSource */
836 /*==============================================================================
837  * After SYNC is found, i.e. either bitstream preamble is detected or it times
838  * out to PCM, update input buffer config and I/o components accordingly.
839  ==============================================================================*/
840 Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
841                       PAF_AST_IoInp  *pInp, ioDataAutoDetStat_t *autoDetStatus)
843     Int sourceConfig;
844     Int zMD, deliverZeros;
845     int ioFrameLength, decFrameLength;
846     PAF_InpBufConfig *pBufConfig;
847     ioPhyCtl_t  ioPhyCtl;
848     ioDataCtl_t ioDataCtl;
850     zMD = pAstCfg->masterDec;
851     pBufConfig = &pAstCfg->xInp[zMD].inpBufConfig;
853     // Compute decoder frame length based on source selection
854     decFrameLength = getFrameLengthSourceSel(pP, pInp->sourceSelect);
856     pAstCfg->xDec[zMD].decodeControl.frameLength  = decFrameLength;
857     pAstCfg->xDec[zMD].decodeInStruct.sampleCount = decFrameLength;
858     pAstCfg->xDec[zMD].decodeControl.sampleRate   = PAF_SAMPLERATE_UNKNOWN;
860     // Decide frame length for I/O DATA and I/O PHY
861     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
862         // For PCM, I/O frame length is decode frame length multiplied by stride
863         ioFrameLength = decFrameLength * INPUT_STRIDE;
865         pBufConfig->sizeofElement = WORD_SIZE_PCM;
866         pBufConfig->frameLength   = pBufConfig->lengthofData = ioFrameLength;
868         // Configure I/O DATA PCM frame length
869         ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH;
870         ioDataCtl.param.frameLengthPcm = ioFrameLength;
871         ioDataControl(pInp->hIoData, &ioDataCtl);
873         // Change I/O PHY transfer size to PCM frame size
874         pInp->phyXferSize = ioFrameLength*(WORD_SIZE_PCM);
876         // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
877         // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
878         // Adjust delay and don't mark input buffer as read complete
879         //ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
881         // Stop swapping data
882         pInp->swapData = FALSE;
883     }
884     else {
885         // For bitstream, I/O frame length is the frame length of the bitstream
886         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
887         ioFrameLength = iecFrameLength[pc];
889         /*
890                 if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
891                     pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
893                 if (pc == 1)
894                     pDevExt->elementSize = 4288;
895                 else if (pc == 0x11) {
896                     pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
897                     pDevExt->lengthofData = pDevExt->frameLength;
898                 }
899         */
901         pBufConfig->sizeofElement = WORD_SIZE_BITSTREAM;
902         pBufConfig->frameLength   = ioFrameLength;
903         pBufConfig->lengthofData  = ioFrameLength - IEC_HEADER_LENGTH;
905         // Change I/O PHY transfer size to bitstream frame size
906         pInp->phyXferSize = ioFrameLength*WORD_SIZE_BITSTREAM;
907     }
909     pBufConfig->stride = INPUT_STRIDE;   // common for PCM and bitstream
911     // Configure I/O PHY transfer size
912     ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
913     ioPhyCtl.params.xferFrameSize = pInp->phyXferSize;
914     ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
916     // Decide if zeros should be delivered based on the configured source
917     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
918                                           GATEMP_INDEX_DEC);
920     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
921         // Bitstream preamble is not found and it times out -> assume this is PCM
922         deliverZeros = autoDetStatus->deliverZeros;
923         if (sourceConfig == PAF_SOURCE_PCM || sourceConfig == PAF_SOURCE_DSD1 ||
924             sourceConfig == PAF_SOURCE_DSD2 || sourceConfig == PAF_SOURCE_DSD3) {
925             // set to one -- ensures that PCM decode calls made before data is
926             // available will result in zero output.
927             // (mostly needed for PA15 since, currently, all other frameworks
928             // require a frame of data before the first decode call.
929             deliverZeros = TRUE;  // override deliverZeros returned by ioDataControl
930         }
932         // update input buffer config structure
933         pBufConfig->deliverZeros  = deliverZeros;
934     }
936     //JXTODO: decide what to do with hRxSio
937     pAstCfg->xInp[zMD].hRxSio = pInp->hIoData; //temporary - does ARM use hRxSio or just check if it is not NULL?
938     pAstCfg->xInp[zMD].pInpBuf = &(pAstCfg->xInp[zMD].inpBufConfig);
940     return ASIP_NO_ERR;
941 } /* asitUpdateIoComps */
943 Int asipBypassIoData(PAF_AST_IoInp *pInp)
945     // When switching to PCM, McASP RFMT register will be modified,
946     // which will cause all 0's in one McASP LLD transfer. This will
947     // be detected as loss of SYNC by auto detection. To prevent that,
948     // skip I/O DATA process for hangover period so that this all 0's
949     // frame will not be seen by auto-detection. Also, playing out PCM
950     // needs to be skipped as well, to prevent from playing out garbage
951     // (16-bit packed data).
952     void *buff1, *buff2;
953     size_t size1, size2;
955     // Get read pointers (or sub-buffers) of the input buffer
956     if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
957                           &buff1, &size1, &buff2, &size2)
958         == IOBUFF_ERR_UNDERFLOW) {
959         pInp->numUnderflow += 1;
961         // Return since there is no enough data to process
962         return ASIP_NO_ERR;
963     }
965     ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
967     if(buff2 != NULL) {
968         ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
969     }
971     return ASIP_NO_ERR;
974 /*=============================================================================
975  *  Main function of ASIP processing
976  *============================================================================*/
977 Int asipProcessing(const PAF_ASIT_Params *pP,
978                    const PAF_ASIT_Patchs *pQ,
979                    PAF_ASIT_Config *pAsitCfg)
982     PAF_AST_Config  *pAstCfg;
983     int ioDataStatus, asipStatus, zMI;
984     ioDataAutoDetStat_t autoDetStatus;
985     Audk2g_STATUS mcaspStatus;
986     ioDataCtl_t ioDataCtl;
987     ioPhyCtl_t  ioPhyCtl;
988     PAF_AST_IoInp *pInp;            /* Input I/O components */
990     pAstCfg = pAsitCfg->pAstCfg;
991     zMI  = pAstCfg->masterDec;
992     pInp = &pAsitCfg->pIoInp[zMI]; // pointer to input I/O components
994     if(pInp->asipProcState == ASIP_SWITCH_TO_PCM) {
995         // Bypass I/O data processing due to McASP LLD work around
996         // (refer to comments inside the function)
997         asipStatus = asipBypassIoData(pInp);
998         if(asipStatus != ASIP_NO_ERR) {
999             return asipStatus;
1000         }
1001     }
1002     else {
1003         // Perform auto-detection when not switching
1004         ioDataStatus = ioDataProcess(pInp->hIoData);
1005         if(ioDataStatus == IODATA_ERR_IOBUF_UNDERFLOW) {
1006             // Input buffer underflows - no action is needed
1007             pInp->numUnderflow += 1;
1009             // Return since there is no enough data to process
1010             return ASIP_NO_ERR;
1011         }
1012         else if(ioDataStatus != IODATA_NO_ERR) {
1013             // Something is wrong: print error log and return
1014             //printf("IODATA processing error!\n");
1015             return ASIP_ERR_AUTO_DETECION;
1016         }
1017         else {
1018             // Normal operation - check auto-detection status
1019             ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
1020             ioDataControl(pInp->hIoData, &ioDataCtl);
1022             autoDetStatus = ioDataCtl.param.autoDetStats;
1023         }
1024     }
1026     switch(pInp->asipProcState)
1027     {
1028     case ASIP_SOURCE_DETECTION:
1029         // zero out the output buffer
1030         rxDecodePlayZero(pInp);
1032         // Mark I/O DATA read complete as auto-detection finishes reading input data now.
1033         ioDataReadComplete(pInp->hIoData);
1035         if(   autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
1036            || autoDetStatus.syncState == IODATA_SYNC_PCM) {
1037             // Decide input source and inform decoder
1038             asipStatus = asipDecideSource(pAstCfg, pInp, &autoDetStatus);
1039             if(asipStatus != ASIP_NO_ERR) {
1040                 return asipStatus;
1041             }
1042             else {
1043                 // Update I/O components and input buffer config
1044                 asitUpdateIoComps(pP, pAstCfg, pInp, &autoDetStatus);
1046                 // set to unknown so that we can ensure, for IOS purposes, that sourceDecode = NONE
1047                 // iff we are in this top level state machine and specifically not in decodeProcessing
1048 #ifndef PCM_LOOPBACK_TEST
1049                 pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
1050 #endif
1052                 if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
1053                     // Input is bit stream: go to decoding
1054                     pInp->asipProcState = ASIP_DECODE;
1055                     //pInp->numFrameReceived = 1;
1056                 }
1057                 else  {
1058                     // Input is PCM: stop swapping data
1059                     pInp->swapData = FALSE;
1061                     // Reconfigure McASP LLD to transfer 32-bit unpacked data
1062                     mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
1063                     if(mcaspStatus != Audk2g_EOK) {
1064                         return ASIP_ERR_MCASP_CFG;
1065                     }
1067                     // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
1068                     // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
1069                     ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
1071                     // Go to transition state to switch to PCM
1072                     pInp->asipProcState = ASIP_SWITCH_TO_PCM;
1073                     pInp->pcmSwitchHangOver = INPUT_SWITCH_HANGOVER;
1074                     //pInp->numPcmFrameReceived = 0;
1075                 }
1076             }
1078             pInp->numFrameReceived = 0;
1079             pInp->preSyncState = autoDetStatus.syncState;
1080         }
1081         else {
1082             // Source is still unknown - take no action
1083             ;
1084         }
1085         break;
1087     case ASIP_SWITCH_TO_PCM:
1088         // zero out the output buffer
1089         rxDecodePlayZero(pInp);
1091         pInp->pcmSwitchHangOver--;
1092         if(pInp->pcmSwitchHangOver == 0) {
1093             pInp->asipProcState = ASIP_DECODE;
1094         }
1095         break;
1097     case ASIP_DECODE:
1098         if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
1099             // SYNC lost: change I/O PHY transfer size to default for auto-detection
1100             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
1101             ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
1102             ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
1103             pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
1105             if(pInp->preSyncState == IODATA_SYNC_PCM) {
1106                 // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
1107                 mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
1108                 if(mcaspStatus != Audk2g_EOK) {
1109                     return ASIP_ERR_MCASP_CFG;
1110                 }
1112                 // Start swapping data
1113                 pInp->swapData = TRUE;
1114             }
1116             // Inform decoder to complete decoding previous frame
1117             pInp->sourceSelect = PAF_SOURCE_NONE;
1119             pInp->numFrameReceived = 0;
1120             pInp->asipProcState  = ASIP_SOURCE_DETECTION;
1121         }
1122         else {
1123             pInp->numFrameReceived += 1;    // for debugging
1125             // Communicate input stream information to decoder through input buffer configuration
1126             asipUpdateInpBufConfig(pAstCfg, pInp);
1127         }
1129 #ifndef PCM_LOOPBACK_TEST
1130         asipStatus = asipDecodeProcessing(pP, pQ, pAsitCfg, pInp->sourceSelect);
1131         if(asipStatus != ASIP_NO_ERR) {
1133             // send dec exit message to slave
1134             if( AspMsgSend(ASP_SLAVE_DEC_EXIT, ASP_MASTER_DEC_EXIT_DONE, NULL, NULL)
1135                 != ASP_MSG_NO_ERR)
1136             {
1137                 TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
1138                 SW_BREAKPOINT;
1139             }
1141             return asipStatus;
1142         }
1143 #else
1144         if(autoDetStatus.syncState == IODATA_SYNC_PCM) {
1145             rxDecodePcm(pInp);     // for PCM loopback testing
1146         }
1147 #endif
1148         // Mark I/O DATA read complete as decoder finishes reading input now.
1149         ioDataReadComplete(pInp->hIoData);
1151         break;
1153     default:
1154         break;
1155     }
1157     return 0;
1158 } /* asipProcessing */
1160 /*======================================================================================
1161  *  This function decides the input source based on auto-detection information.
1162  *====================================================================================*/
1163 //Int asipDecideSource(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, asipDecProc_t *pDec)
1164 //{
1166 //}
1169 #ifndef IO_LOOPBACK_TEST
1170 #if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH
1171 U8 pcmbuf[OUTPUT_FRAME_SIZE];
1172 #else
1173 #error Input frame length is not equal to output frame length!
1174 #endif
1176 Int rxDecodePcm(PAF_AST_IoInp  *pInp)
1178     ioDataCtl_t ioDataCtl;
1179     void *buffBase;
1180     void *dataStartAddress;
1181     size_t buffSize, frameSize, size1, size2;
1183     /* Get information for reading input data */
1184     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
1185     ioDataControl(pInp->hIoData, &ioDataCtl);
1187     buffBase = ioDataCtl.param.dataReadInfo.buffBase;
1188     buffSize = ioDataCtl.param.dataReadInfo.buffSize;
1189     dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
1190     frameSize        = ioDataCtl.param.dataReadInfo.frameSize;
1192     // Copy PCM data to output buffer
1193     if(((size_t)dataStartAddress+frameSize) <= ((size_t)buffBase+buffSize)) {
1194         // Input buffer doesn't wrap around
1195         Cache_inv(dataStartAddress, frameSize, Cache_Type_ALL, TRUE);
1196         memcpy((void *)&pcmbuf[0], dataStartAddress, frameSize);
1197     }
1198     else {
1199         // Input buffer wraps around
1200         size1 = (size_t)buffBase + buffSize - (size_t)dataStartAddress;
1201         size2 = frameSize - size1;
1202         Cache_inv(dataStartAddress, size1, Cache_Type_ALL, TRUE);
1203         memcpy((void *)&pcmbuf[0], dataStartAddress, size1);
1205         Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
1206         memcpy((void *)&pcmbuf[size1], buffBase, size2);
1207     }
1210     return ASIP_NO_ERR;
1213 Int rxDecodeBitStream(PAF_AST_IoInp  *pInp)
1215     return ASIP_NO_ERR;
1219 Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
1221     return ASIP_NO_ERR;
1223 #endif
1225 void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno)
1230 /* Nothing past this line */