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
142 {
143 ASIP_SOURCE_DETECTION,
144 ASIP_DECODE,
145 ASIP_SWITCH_TO_PCM,
146 };
148 enum
149 {
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)
183 {
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
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
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)
319 {
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)
408 {
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)
455 {
456 pInp->swapData = SWAP_INPUT_DATA;
457 pInp->asipProcState = ASIP_SOURCE_DETECTION;
458 //pInp->switchHangOver = 0;
460 pDec->initDone = FALSE;
461 }
463 /*======================================================================================
464 * I/O physical layer prime operation required by McASP LLD
465 *====================================================================================*/
466 void asipIoPhyPrime(PAF_AST_IoInp *pInp)
467 {
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()
483 {
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)
492 {
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)
502 {
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 }
509 }
511 /*======================================================================================
512 * This function checks if McASP Rx for input overruns
513 *====================================================================================*/
514 int asipCheckMcaspRxOverrun(Ptr mcaspChanHandle)
515 {
516 Mcasp_errCbStatus mcaspErrStat;
518 mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
520 return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
521 }
523 /*======================================================================================
524 * This function restarts McASP LLD channel for input
525 *====================================================================================*/
526 void asipMcaspRxRestart(void)
527 {
528 mcaspRxReset();
529 mcaspRxCreate();
530 }
532 /*======================================================================================
533 * This function starts an I/O PHY transfer
534 *====================================================================================*/
535 void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
536 {
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 }
557 }
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)
567 {
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)
617 {
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;
693 }
696 void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp)
697 {
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);
722 }
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)
730 {
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)
842 {
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)
944 {
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;
972 }
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)
981 {
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)
1177 {
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;
1211 }
1213 Int rxDecodeBitStream(PAF_AST_IoInp *pInp)
1214 {
1215 return ASIP_NO_ERR;
1216 }
1219 Int rxDecodePlayZero(PAF_AST_IoInp *pInp)
1220 {
1221 return ASIP_NO_ERR;
1222 }
1223 #endif
1225 void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno)
1226 {
1228 }
1230 /* Nothing past this line */