3db43196fd95135dd0c57e1df4c8330596d30a81
[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>
41 #include <xdc/runtime/Error.h>
42 #include <ti/sysbios/knl/Event.h>
44 #include "procsdk_audio_typ.h"
45 #include "audioStreamInpProc.h"
46 #include "audioStreamProc_common.h"
47 #include "aspMsg_common.h"
48 #include "aspMsg_master.h"
49 #include "asperr.h"
50 #include "common.h"
52 #include "audk2g.h"
53 #include "audk2g_audio.h"
54 #include "mcasp_cfg.h"
55 #include "ioConfig.h"    //TODO: remove this header
56 #include "ioBuff.h"
57 #include "ioPhy.h"
58 #include "ioData.h"
61 #define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
63 //#define DEBUG_SKIP_DECODING
65 #define SYNC_PC_MASK         0x1F
66 #define SYNC_SUBTYPE_MASK    0x700
67 #define SYNC_SUBTYPE_SHIFT   8
68 #define SYNC_SUBTYPE_DTSHD   0x11
69 #define SYNC_DDP             0x15
70 #define SYNC_THD             0x16
72 #define IEC_HEADER_LENGTH    4
74 #define INPUT_SWITCH_HANGOVER 8
76 //table needed until PAF_SOURCE is reordered to match IEC numbering
77 const SmUns IECpafSource[23] =
78 {
79     PAF_SOURCE_UNKNOWN,  // 0: IEC NULL Type
80     PAF_SOURCE_AC3,      // 1: Comments on 1-15 match IEC 61937 part 2.
81     PAF_SOURCE_UNKNOWN,  // 2: IEC reserved
82     PAF_SOURCE_UNKNOWN,  // 3: IEC pause
83     PAF_SOURCE_UNKNOWN,  // 4: MPEG 1 layer 1
84     PAF_SOURCE_MP3,      // 5: MPEG layer 2 or 3
85     PAF_SOURCE_UNKNOWN,  // 6: MPEG 2 data with extension
86     PAF_SOURCE_AAC,      // 7: MPEG-2 AAC ADTS
87     PAF_SOURCE_UNKNOWN,  // 8: MPEG 2 layer 1 low sampling frequency
88     PAF_SOURCE_UNKNOWN,  // 9: MPEG 2 layer 2 or 3 low sampling frequency
89     PAF_SOURCE_UNKNOWN,  // 10: reserved
90     PAF_SOURCE_DTS,      // 11: DTS type 1 (11 bit: 512 sample repeat period)
91     PAF_SOURCE_DTS12,    // 12: DTS type 2 (12 bit: 1024 sample repeat period)
92     PAF_SOURCE_DTS13,    // 13: DTS type 3 (13 bit: 2048 sample repeat period)
93     PAF_SOURCE_DTS14,    // 14: ATRAC
94     PAF_SOURCE_UNKNOWN,  // 15: ATRAC 2/3
95     PAF_SOURCE_THD,      // 16
96     PAF_SOURCE_DTSHD,    // 17
97     PAF_SOURCE_WMA9PRO,  // 18
98     PAF_SOURCE_UNKNOWN,  // 19
99     PAF_SOURCE_UNKNOWN,  // 20
100     PAF_SOURCE_DDP,      // 21
101     PAF_SOURCE_THD,      // 22
102 };
104 /*
105  * Functions defined in other files and to be put into proper header files
106  */
107 extern Void taskAsipFxnInit(const PAF_ASIT_Params *pP,const PAF_ASIT_Patchs *pQ);
110 // avoid including sap_d10.h, which would cause symbol redefinition
111 // warning (MCASP_PFUNC_XXX)
112 extern XDAS_Int32 D10_init();
113 extern XDAS_Int32 D10_RxControl(const void *pD10RxParams,
114                                 XDAS_Int32 code, XDAS_Int32 arg);
116 /*
117  * Functions only used in this file
118  */
119 int asitPrepareProcessing();
120 int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
121 void asitProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec);
122 void asitIoPhyPrime(PAF_AST_IoInp *pInpIo);
123 void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo);
124 void asitPhyTransferStart(PAF_AST_IoInp *pInpIo);
125 Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize);
126 Int asitSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp);
127 Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
128                           PAF_InpBufConfig *pInpBuf);
130 Int asitSourceDetection(const PAF_ASIT_Params *pP,
131                         const PAF_ASIT_Patchs *pQ,
132                         PAF_ASIT_Config       *pAsitCfg);
134 Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
135                      ioDataAutoDetStat_t *autoDetStatus);
136 Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
137                       PAF_AST_IoInp  *pInp, ioDataAutoDetStat_t *autoDetStatus);
138 Int asitBypassIoData(PAF_AST_IoInp *pInp);
139 Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg);
141 void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp);
142 Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats);
144 UInt asitEventsToDecMsg(UInt asitEvents);
145 void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr);
146 Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents);
148 void asitPostInfoEvent();
149 void asitPostDecEvent();
151 /*
152  * variables/structures to be put into proper global structures
153  */
154 extern PAF_ASIT_Config gPAF_ASIT_config;
155 extern const MdUns iecFrameLength[23];
156 extern Ptr hMcaspRxChan;
158 enum {
159     ASIT_RESET,
160     ASIT_SOURCE_DETECTION,
161     ASIT_PCM_TRANSITION,
162     ASIT_DECODE_PROCESSING
163 };
165 #define ASIT_EVTMSK_NONE        0x0
166 #define ASIT_EVTMSK_INPDATA     0x1
167 #define ASIT_EVTMSK_INFOACK     0x2
168 #define ASIT_EVTMSK_DECACK      0x4
170 #define ASIT_ALL_EVENTS (  ASIT_EVTMSK_INPDATA \
171                          + ASIT_EVTMSK_INFOACK \
172                          + ASIT_EVTMSK_DECACK )
174 #define ASIT_DEC_EVENTS (  ASIT_EVTMSK_INPDATA \
175                          + ASIT_EVTMSK_INFOACK \
176                          + ASIT_EVTMSK_DECACK )
178 #define ASIP_DEBUG
180 #ifdef ASIP_DEBUG
181 /* define the following as global variables for easy debugging */
182 int asipLoopCount1, asipLoopCount2;
183 Int asipErrno;
184 Int inputReadyForProcessing;
186 // FL: debug
187 #include "evmc66x_gpio_dbg.h"
188 #endif
190 Event_Handle asitEvent;
191 Int eventsOn;
193 /*
194  *  ======== taskAsipFxn ========
195  *  Audio Stream Input Processing task function
196  */
197 #ifndef PASDK_SIO_DEV
198 #ifndef IO_LOOPBACK_TEST
199 Void taskAsipFxn(                  // ASIP task function for new I/O
200 #else
201 Void taskAsipFxn_NewIO_Not_Used(   // not used for loopback test
202 #endif
203 #else
204 Void taskAsipFxn_NewIO_Not_USED(   // not used for SIO/DEV based I/O
205 #endif
206     const PAF_ASIT_Params *pP,
207         const PAF_ASIT_Patchs *pQ)
209     PAF_ASIT_Config *pAsitCfg;      /* ASIT configuration pointer */
210     PAF_AST_Config  *pAstCfg;       /* AST Common (shared) configuration pointer */
211     PAF_AST_IoInp *pInp;            /* Input I/O components */
212     Int as;                         /* Audio Stream Number (1, 2, etc.) */
213     Int z;                          /* input/encode/stream/decode/output counter */
214     Int zMI;
215 #ifndef ASIP_DEBUG
216 int asipLoopCount1, asipLoopCount2;
217 Int asipErrno;
218 Int inputReadyForProcessing;
219 #endif
220     Int asitErr;
221     UInt events;
222 //    Int eventsOn;
223     Error_Block  eb;
225     Log_info0("Enter taskAsipFxn()");
227     taskAsipFxnInit(pP, pQ);  // initialization of input task
228     
229     Error_init(&eb);          // initialize error block
231     asitEvent = Event_create(NULL, &eb);
232     if (asitEvent == NULL) {
233         System_abort("Event create failed");
234     }
235     //
236     // Audio Stream Input Task Configuration (*pAsitCfg):
237     //
238     pAsitCfg = &gPAF_ASIT_config;       // initialize pointer to task configuration
239     pAstCfg  = pAsitCfg->pAstCfg;       // pointer to AST common (shared) configuration
241     /* Set Audio Stream Number (1, 2, etc.) */
242     as = pAstCfg->as;
244     //
245     // Determine decoder and stream indices associated with the master input
246     //
247     zMI  = pP->zone.master;
248     pInp = &pAsitCfg->pIoInp[zMI];        // pointer to input I/O components
250     for (z=STREAM1; z < STREAMN; z++)
251     {
252         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
253     }
255     Log_info0("TaskAsip: Entering Main Loop.");
257     //
258     // Main processing loop
259     //
260     asipLoopCount1 = 0;
261     asipLoopCount2 = 0;
262     asitErr = ASIT_NO_ERR;
263     pInp->asipState = ASIT_RESET;
264     pInp->firstTimeInit = TRUE;
265     pInp->numAsitRestart = 0;
267     // The events_on flag will be removed if the RESTART state is changed to
268     // event-based scheduling instead of polling
269     eventsOn = FALSE;
271     for (;;)
272     {
273         asipLoopCount1++;
275         if(eventsOn) {
276             events = Event_pend(asitEvent, ASIT_EVTMSK_NONE, ASIT_ALL_EVENTS,
277                                 BIOS_WAIT_FOREVER);
278         }
279         switch (pInp->asipState)
280         {
281         case ASIT_RESET:    // No events pending in this state
282             // Indicate decoder no decoding yet
283             pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
285             // 5 system tick, or 5 msec. Should remove this later when implementing
286             // event based scheduling.
287             Task_sleep(5);
289             inputReadyForProcessing = asitPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
290             if (inputReadyForProcessing) {
291                 TRACE_VERBOSE0("TaskAsip: Input is ready. Initialize I/O components.");
292                 // Input is ready for processing, so we initialize the I/O components.
293                 // Note that the I/O components init. and I/O PHY prime are performed only
294                 // at the first time. This should be changed later - init. and prime
295                 // should be done whenever input interface has changed.
296                 asitErr = asitIoCompsInit(&pAstCfg->xInp[zMI], pInp);
298                 // Initialize ASIT processing
299                 asitProcInit(pInp, &pAsitCfg->inpDec);
300                 pInp->asipState = ASIT_SOURCE_DETECTION;
301                 eventsOn = TRUE;   // turn on events pending
302                 TRACE_VERBOSE0("TaskAsip: turn on events and go to source detection.");
303             }
304             break;
306         case ASIT_SOURCE_DETECTION:
307             // Source unknown - to detect & identify source
308             if(events == ASIT_EVTMSK_INPDATA) {  
309                 // Only this event is expected. If any other event, it's error.
310                 // Input data is ready - perform source detection.
311                 // New state will be decided inside the function
312                 asitErr = asitSourceDetection(pP, pQ, pAsitCfg);
313             }
314             else {
315                 //Error checking & debug
316                 asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
317             }
319             break;
321         case ASIT_PCM_TRANSITION:
322             // Source is PCM - transition to PCM decoding
323             if(events == ASIT_EVTMSK_INPDATA) {
324                 // Only this event is expected. If any other event, it's error.
325                 // Input data is ready - transition to PCM decoding
326                 // New state will be decided inside the function
327                 asitErr = asitPcmTransition(pAsitCfg);
328             }
329             else {
330                 //Error checking & debug
331                 asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
332             }
333             break;
335         case ASIT_DECODE_PROCESSING:
336             if(events & ASIT_DEC_EVENTS) {
337                 // Decode processing for either PCM or bitstream
338                 // New state will be decided inside the function
339                 asitErr = asitDecodeProcessing(pP, pQ, pAsitCfg, events);
340             }
341             else {
342                 //Error checking & debug
343                 asitErr = asitEvtErrCheck(events, ASIT_DEC_EVENTS);
344             }
345             break;
347         default:
348             break;
349         }
351         if(asitErr) {
352             asitErrorHandling(pAsitCfg, asitErr);
354             if(pInp->asipState == ASIT_RESET) {
355                 eventsOn = FALSE;
356             }
358             asitErr = ASIT_NO_ERR;
359         }
361     }  // for (;;)
363 }  /* taskAsipFxn */
366 /*===========================================================================
367  * ASIT Processing Preparation
368  * Output:
369  *        - return        TRUE (input is ready) or FALSE (input is not ready)
370  *        - *asipErrno    Error number
371 ============================================================================*/
372 Int asitPrepareProcessing(const PAF_ASIT_Params *pP,
373                           const PAF_ASIT_Patchs *pQ,
374                           PAF_ASIT_Config       *pC,
375                           Int                   *asipErrno)
377     Int as, zMS, zMI, zMD;
378     Int sourceConfig, mode;
379     PAF_AST_Config  *pAstCfg;
380     PAF_AST_IoInp *pInp;            /* I/O components for input */
382     pAstCfg  = pC->pAstCfg;         // pointer to AST common (shared) configuration
383     as  = pAstCfg->as;
384     zMI = pP->zone.master;
385     zMD = pAstCfg->masterDec;
386     zMS = pAstCfg->masterStr;
387     pInp = pC->pIoInp;              // pointer to input I/O components
389     *asipErrno = 0;
391     // Select source and initialize physical layer / HW interface
392     *asipErrno = asitSelectDevices(pQ, pInp);
393     if (*asipErrno) {
394         TRACE_TERSE2("asitSelectDevices returned asipErrno = 0x%04x at line %d. AS%d",
395                      *asipErrno, as+zMS);
396         return FALSE;    // Input is not ready for processing due to error
397     }
399     // If no master input selected then we don't know what may be at the input,
400     // so set to unknown and skip any remaining processing
401     if (!pInp[zMI].pRxParams) {
402         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
403                            (Int8)PAF_SOURCE_UNKNOWN, GATEMP_INDEX_DEC);
405         TRACE_VERBOSE1("TaskAsip: AS%d: No input selected...", as+zMS);
406         return FALSE;    // No error, but input is not ready for processing
407     }
409     // If here then we have a valid input so query its status
410     *asipErrno = asitUpdateInputStatus(pInp[zMI].pRxParams,
411                                    &pAstCfg->xInp[zMI].inpBufStatus,
412                                    &pAstCfg->xInp[zMI].inpBufConfig);
413     if(*asipErrno) {
414         TRACE_VERBOSE1("TaskAsip: updateInputStatus returns 0x%x", *asipErrno);
415         return FALSE;   // Input is not ready for processing due to error
416     }
418     // If master decoder is not enabled, or the input is unlocked, then do nothing
419     mode = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.mode),
420                                   GATEMP_INDEX_DEC);
421     if (!mode || !pAstCfg->xInp[zMI].inpBufStatus.lock)
422     {
423         TRACE_VERBOSE0("TaskAsip: Not locked, continue");
424         return FALSE;  // No error, but input is not ready for processing
425     }
427     // Check selected source: sourceSelect is set by another task, AIP or AFP
428     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
429                                           GATEMP_INDEX_DEC);
430     // If no source selected then do nothing
431     if(sourceConfig == PAF_SOURCE_NONE) {
432         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
433                            (Int8)PAF_SOURCE_NONE, GATEMP_INDEX_DEC);
434         TRACE_VERBOSE1("TaskAsip: AS%d: no source selected, continue", as+zMS);
435         return FALSE;  // No error, but input is not ready for processing
436     }
438     // If we want pass processing then proceed directly
439     if (sourceConfig == PAF_SOURCE_PASS)
440     {
441         TRACE_VERBOSE1("TaskAsip: AS%d: Pass processing ...", as+zMS);
442         sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
443                            (Int8)PAF_SOURCE_PASS, GATEMP_INDEX_DEC);
445         pP->fxns->sourceDecode(pP, pQ, pC, PAF_SOURCE_PASS);
446         if (pP->fxns->passProcessing) {
447             *asipErrno = pP->fxns->passProcessing(pP, pQ, pC, NULL);
448         }
449         else {
450             TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x",
451                          as+zMS, ASPERR_PASS);
452             *asipErrno = ASPERR_PASS;
453         }
455         TRACE_VERBOSE0("TaskAsip: continue");
456         return FALSE;  // Error or not, input is not ready for processing
457     }
459     // No error and input processing is ready
460     return TRUE;
461 } /* asitPrepareProcessing */
464 /*===========================================================================
465  * ASIT Source Detection:
466  *     ASIT processing for input source identification:
467  *     - mark I/O PHY transfer completion
468  *     - run auto-detection via I/O DATA in asitInputDataProcess
469  *     - mark I/O DATA read completion
470  *     - check auto-detection status and take corresponding actions if either
471  *       PCM or bitstream is identified:
472  *       - decide input source
473  *       - update I/O components
474  *       - reconfigure McASP LLD if it is PCM
475  *     - start next I/O PHY transfer
476 ============================================================================*/
477 Int asitSourceDetection(const PAF_ASIT_Params *pP,
478                         const PAF_ASIT_Patchs *pQ,
479                         PAF_ASIT_Config       *pAsitCfg)
481     PAF_AST_Config  *pAstCfg;
482     PAF_AST_IoInp *pInp;            /* I/O components for input */
483     Int zMD, mcaspErr, asitErr;
484     ioDataAutoDetStat_t autoDetStatus;
486     pAstCfg  = pAsitCfg->pAstCfg;         // pointer to AST common (shared) configuration
487     zMD = pAstCfg->masterDec;
488     pInp = &pAsitCfg->pIoInp[zMD];        // pointer to input I/O components
490     // Marks I/O PHY transfer and I/O BUFF write complete
491     asitPhyTransferComplete(pInp);
493     // Process input data - either searching SYNC for PCM or checking SYNC for bitstream
494     asitErr = asitInputDataProcess(pInp, &autoDetStatus);
495     if(asitErr != ASIT_NO_ERR) {
496         // Even though there is error, still need to start next transfer to
497         // maintain McASP transfer.
498         asitPhyTransferStart(pInp);
500         return asitErr;
501     }
503     // Mark input data read complete
504     ioDataReadComplete(pInp->hIoData);
506     // Check if bitstream or PCM is detected
507     if(   autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
508        || autoDetStatus.syncState == IODATA_SYNC_PCM) {
509         // Decide input source and inform decoder
510         asitErr = asitDecideSource(pAstCfg, pInp, &autoDetStatus);
511         if(asitErr != ASIT_NO_ERR) {
512             return asitErr;
513         }
514         else {
515             // Update I/O components and input buffer config
516             asitUpdateIoComps(pP, pAstCfg, pInp, &autoDetStatus);
518             // set to unknown so that we can ensure, for IOS purposes, that
519             // sourceDecode = NONE iff we are in this top level state machine
520             // and specifically not in decodeProcessing
521 #ifndef DEBUG_SKIP_DECODING
522             pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
523 #endif
525             if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
526                 // Input is bit stream: go to decoding
527                 pInp->asipState = ASIT_DECODE_PROCESSING;
528             }
529             else  {
530                 // Input is PCM: stop swapping data
531                 pInp->swapData = FALSE;
533                 // Reconfigure McASP LLD to transfer 32-bit unpacked data
534                 mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
535                 if(mcaspErr != Audk2g_EOK) {
536                     return ASIT_ERR_MCASP_CFG;
537                 }
539                 // Adjust I/O BUFF delay and read pointer - to make sure read pointers
540                 // always point to PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
541                 ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
543                 // Go to transition state to switch to PCM
544                 pInp->asipState = ASIT_PCM_TRANSITION;
545             }
546         }
547     }
549     // Start next transfer
550     asitPhyTransferStart(pInp);
552     return (ASIT_NO_ERR);
553 }  /* asitSourceDetection */
556 /*===========================================================================
557     //
558     // which will cause all 0's in one McASP LLD transfer. This will
559     // be detected as loss of SYNC by auto detection. To prevent that,
560     // skip I/O DATA process for hangover period so that this all 0's
561     // frame will not be seen by auto-detection. Also, playing out PCM
562     // needs to be skipped as well, to prevent from playing out garbage
563     // (16-bit packed data).
564  *
565  * ASIT Transition to PCM decoding.
566  *     When PCM is detected, McASP LLD will be reconfigured to transmit 32-bit
567  *     words, which will modify the RFMT register. This will cause all 0's in
568  *     one McASP LLD transfer, which would be detected as loss of SYNC by auto
569  *     detection (performed by I/O DATA). To prevent that, skip I/O DATA process
570  *     for hangover period so that this all-0's frame will not be seen by the
571  *     auto-detection.
572  *
573  *     In addition, playing out PCM should be skipped as well to prevent from
574  *     playing out the 16-bit packed data that's still in the input buffer.
575  *
576  *     This function does the following:
577  *     - mark I/O PHY transfer completion
578  *     - bypass I/O DATA
579  *     - start next I/O PHY transfer
580 ============================================================================*/
581 Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg)
583     Int asitErr;
584     PAF_AST_IoInp *pInp;                  // I/O components for input
585     Int zMD;
587     zMD = pAsitCfg->pAstCfg->masterDec;   // pointer to AST common (shared) configuration
588     pInp = &pAsitCfg->pIoInp[zMD];        // pointer to input I/O components
590     // Marks I/O PHY transfer and I/O BUFF write complete
591     asitPhyTransferComplete(pInp);
593     // Bypass I/O data processing due to McASP LLD work around
594     // (refer to comments inside the function)
595     asitErr = asitBypassIoData(pInp);
597     pInp->pcmSwitchHangOver--;
598     if(pInp->pcmSwitchHangOver == 0) {
599         pInp->asipState = ASIT_DECODE_PROCESSING;
600     }
601     else {
602         ; // stay in this state
603     }
605     // Start next transfer
606     asitPhyTransferStart(pInp);
608     return asitErr;
610 } /* asitPcmTransition */
612 /*============================================================================
613  * ASIT Bypass I/O DATA Processing
614  *     This function bypasses the I/O DATA processing. It maintains the read
615  *     operation of I/O BUFF by directly calling I/O BUFF APIs. When I/O DATA
616  *     is not bypassed, I/O BUFF read operation is invoked by I/O DATA.
617  *
618 ============================================================================*/
619 Int asitBypassIoData(PAF_AST_IoInp *pInp)
621     void *buff1, *buff2;
622     size_t size1, size2;
624     // Get read pointers (or sub-buffers) of the input buffer
625     if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
626                           &buff1, &size1, &buff2, &size2)
627         == IOBUFF_ERR_UNDERFLOW) {
628         pInp->numUnderflow += 1;
630         // Return since there is no enough data to process
631         return ASIT_ERR_INPBUF_UNDERFLOW;
632     }
634     ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
636     if(buff2 != NULL) {
637         ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
638     }
640     return ASIP_NO_ERR;
641 } /* asitBypassIoData */
644 /*============================================================================
645  * ASIT Decode Processing
646  *     This function performs the decode processing and does the following based
647  *     on the ASIT events:
648  *     - initialize the decode processing if it is the first time
649  *     - if there is ASIT INPUT DATA event (ASIT_EVTMSK_INPDATA):
650  *        - mark I/O PHY transfer completion
651  *        - run auto-detection via I/O DATA in asitInputDataProcess
652  *        - check auto-detection status and take corresponding actions if SYNC
653  *          is lost.
654  *        - start next I/O PHY transfer
655  *     - map ASIT events to decoding messages
656  *     - invoke decDecodeFsm() and pass the mapped decoding messages
657  *     - if there is ASIT DECODE ACK event (ASIT_EVTMSK_DECACK)
658  *        - mark I/O DATA read completion
659  *     - error handling
660 ============================================================================*/
661 Int asitDecodeProcessing(const PAF_ASIT_Params *pP,
662                          const PAF_ASIT_Patchs *pQ,
663                          PAF_ASIT_Config       *pAsitCfg,
664                          UInt asitEvents)
666     Int asitErr, decErr;
667     PAF_AST_IoInp *pInp;                  // I/O components for input
668     asipDecProc_t *pDec;
669     ioDataAutoDetStat_t autoDetStatus;
670     Int zMD;
671     UInt decMsg;
673     zMD = pAsitCfg->pAstCfg->masterDec;   // pointer to AST common (shared) configuration
674     pInp = &pAsitCfg->pIoInp[zMD];        // pointer to input I/O components
675     pDec = &pAsitCfg->inpDec;
677     // Initialization for decode processing when this function is called the first time
678 #ifndef DEBUG_SKIP_DECODING
679     if(!pDec->initDone) {
680         // Initialize decoder
681         decDecodeInit(pP, pAsitCfg, pInp->sourceSelect);
683         pDec->initDone = TRUE;
684     }
685 #endif
687     // Process input data if this is a data ready message
688     if(asitEvents & ASIT_EVTMSK_INPDATA) {
689         TRACE_TERSE0("asitDecodeProcessing: process input data.");
691         // Marks I/O PHY transfer and I/O BUFF write complete
692         asitPhyTransferComplete(pInp);
694         // Process input data - either search SYNC for PCM or check SYNC for bitstream
695         asitErr = asitInputDataProcess(pInp, &autoDetStatus);
697         if(asitErr == ASIT_NO_ERR) {
698             ioDataReadComplete(pInp->hIoData);
700             // Check if SYNC is maintained or lost (stream stops or format changes)
701             if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
702                 // SYNC lost: change I/O PHY transfer size to default for auto-detection
703                 //asitErr = asitRecfgPhyXfer(pInp, INPUT_FRAME_SIZE_DEF);
704                 //if(asitErr != ASIT_NO_ERR) {
705                 //    return asitErr;
706                 //}
708                 // Inform decoder to complete the decoding of previous frame - is this good?
709                 pInp->sourceSelect = PAF_SOURCE_NONE;
710                 pInp->numFrameReceived = 0;    // for debugging
711                 TRACE_TERSE0("asitDecodeProcessing: SYNC lost.");
713 #ifdef DEBUG_SKIP_DECODING
714                 asitErr = ASIT_ERR_DECODE_QUIT;
715 #endif
716             }
717             else {
718                 pInp->numFrameReceived += 1;    // for debugging
720                 // Communicate input stream information to decoder through input
721                 // buffer configuration
722                 asitUpdateInpBufConfig(pAsitCfg->pAstCfg, pInp);
724                 // Start next transfer
725                 asitPhyTransferStart(pInp);
726             }
728             // Start next transfer
729             //asitPhyTransferStart(pInp);
731 #ifdef DEBUG_SKIP_DECODING
732             return asitErr;
733 #endif
734         }
735         else if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
736             TRACE_TERSE0("asitDecodeProcessing: Input buffer underflows.");
738             // When input buffer underflows, it is not an error but decoding needs
739             // to be skipped as there is not enough data in the buffer.
740             asitPhyTransferStart(pInp);
742             return asitErr;
743         }
744         else {
745             // Inform decoder to complete the decoding of previous frame - is this good?
746             pInp->sourceSelect = PAF_SOURCE_NONE;
747             pInp->numFrameReceived = 0;    // for debugging
748             TRACE_TERSE1("asitDecodeProcessing: asitInputDataProcess error: %d", asitErr);
750 #ifdef DEBUG_SKIP_DECODING
751             return ASIT_ERR_DECODE_QUIT;
752 #endif
753         }
754     } /* ASIT_EVTMSK_INPDATA */
755 #ifdef DEBUG_SKIP_DECODING
756     else {
757         TRACE_TERSE0("asitDecodeProcessing: events error.");
758         return ASIT_ERR_EVENTS;
759     }
760 #endif
762 #ifndef DEBUG_SKIP_DECODING
763     // Map ASIT events to decode messages
764     decMsg = asitEventsToDecMsg(asitEvents);
766     // Pass messages (corresponding to events) to decode FSM
767     decErr = decDecodeFsm(pP, pQ, pAsitCfg, pInp->sourceSelect, decMsg);
769     // Mark I/O DATA read complete if decoder indicates decoding is done.
770     if((asitEvents & ASIT_EVTMSK_DECACK)) {  // DECACK -> decoding done
771         //ioDataReadComplete(pInp->hIoData);
772     }
774     if(decErr != DEC_NO_ERR) {
775         TRACE_VERBOSE0("TaskAsip: send DEC_EXIT message to slave decoder.");
777         // Send dec exit message to slave decoder
778         if( AspMsgSend(ASP_SLAVE_DEC_EXIT, ASP_MASTER_DEC_EXIT_DONE, NULL, NULL)
779             != ASP_MSG_NO_ERR) {
780             TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
781             SW_BREAKPOINT;
782         }
784         return ASIT_ERR_DECODE_QUIT;  // This is not necessarily an error
785     }
786     else {
787         return ASIT_NO_ERR;
788     }
789 #endif
790 }  /* asitDecodeProcessing */
793 /*============================================================================
794  * ASIT Input Data Processing:
795  *    - invoke ioDataProcess() to inspect input data for
796  *       - initial auto-detection,  or
797  *       - background scanning for PCM data, or
798  *       - SYNC check for bitstream
799  *    - return auto-detection status (SYNC detected, SYNC loss, etc)
800 ============================================================================*/
801 Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats)
803     Int ioDataErr, retVal;
804     ioDataCtl_t ioDataCtl;
806     // Perform auto-detection inside I/O DATA component
807     ioDataErr = ioDataProcess(pInp->hIoData);
809     if(ioDataErr == IODATA_NO_ERR) {
810         // Normal operation - check auto-detection status
811         ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
812         ioDataControl(pInp->hIoData, &ioDataCtl);
814         *pAutoDetStats = ioDataCtl.param.autoDetStats;
816         retVal = ASIT_NO_ERR;
817     }
818     else if(ioDataErr == IODATA_ERR_IOBUF_UNDERFLOW) {
819         // Input buffer underflows - there is no enough data to process.
820         // This is not error and no action is needed.
821         pInp->numUnderflow += 1; // debug
823         retVal = ASIT_ERR_INPBUF_UNDERFLOW;
824     }
825     else {
826         // Something is wrong: print error log and return
827         //printf("IODATA processing error!\n");
828         retVal = ASIT_ERR_INPDATA_PROC;
829     }
831     return retVal;
832 } /* asitInputDataProcess */
834 /*============================================================================
835  * Mapping ASIT Events to Decoding Messages
836 ============================================================================*/
837 UInt asitEventsToDecMsg(UInt asitEvents)
839     UInt decMsg = 0;
841     if(asitEvents & ASIT_EVTMSK_INPDATA) {
842         decMsg |= DEC_MSGMSK_INPDATA;
843     }
845     if(asitEvents & ASIT_EVTMSK_INFOACK) {
846         decMsg |= DEC_MSGMSK_INFOACK;
847     }
849     if(asitEvents & ASIT_EVTMSK_DECACK) {
850         decMsg |= DEC_MSGMSK_DECACK;
851     }
853     return decMsg;
854 } /* asitEventsToDecMsg */
856 /*===========================================================================
857  * Initialize I/O components for input processing
858 ============================================================================*/
859 int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
861     ioBuffParams_t ioBuffParams;
862     ioPhyParams_t  ioPhyParams;
863     ioDataParam_t  ioDataCfg;
864     ioPhyCtl_t     ioPhyCtl;
866     pInpIo->phyXferSize = INPUT_FRAME_SIZE_DEF;
868     if(pInpIo->firstTimeInit) {
869         TRACE_VERBOSE0("Initialize I/O BUFF and I/O PHY.");
870         ioBuffParams.base         = pInpBuf->inpBufConfig.base.pVoid;
871         ioBuffParams.size         = pInpBuf->inpBufConfig.allocation / STRIDE_WORST_CASE
872                                                                      * STRIDE_WORST_CASE;
873         ioBuffParams.sync         = IOBUFF_WRITE_SYNC;
874         ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
875         if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
876             return (ASIT_ERR_IOBUFF_INIT);   // to remove magic number
877         }
879         ioPhyParams.ioBuffHandle    = pInpIo->hIoBuff;
880         ioPhyParams.xferFrameSize   = pInpIo->phyXferSize;
881         ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
882         ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_WRITE;
883         if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
884             return (ASIT_ERR_IOPYH_INIT);   // to remove magic number
885         }
887         pInpIo->numPrimeXfers = NUM_PRIME_XFERS;
888     }
890     /* Reinitialize I/O DATA every time when ASIT restarts */
891     TRACE_VERBOSE0("Initialize I/O DATA.");
892     ioDataCfg.ioBuffHandle         = pInpIo->hIoBuff;
893     ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
894     ioDataCfg.frameLengthsIEC      = (uint_least16_t *)&iecFrameLength[0];
895     ioDataCfg.frameLengthPCM       = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
896     ioDataCfg.frameLengthDef       = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
897     ioDataCfg.ibMode               = pInpBuf->inpBufConfig.pBufStatus->mode;
898     ioDataCfg.zeroRunRestart       = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
899     ioDataCfg.zeroRunTrigger       = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
901     if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
902         return (ASIT_ERR_IODATA_INIT);   // to remove magic number
903     }
905     if(pInpIo->firstTimeInit) {
906         /* Initialize I/O BUFF and I/O PHY only when input interface changes. */
907         TRACE_VERBOSE0("Prime I/O PHY.");
909         // Start I/O physical layer by priming McASP LLD for input
910         asitIoPhyPrime(pInpIo);
912         pInpIo->firstTimeInit = FALSE;
913     }
914     else {
915         // Reconfigure I/O PHY transfer size
916         ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
917         ioPhyCtl.params.xferFrameSize = pInpIo->phyXferSize;
918         ioPhyControl(pInpIo->hIoPhy, &ioPhyCtl);
920         // If previous stream before reset was PCM, reconfigure McASP LLD to receive 16-bit packed bits
921         if(!pInpIo->swapData) {
922             Int mcaspErr;
923             mcaspErr = mcaspRecfgWordWidth(pInpIo->hMcaspChan, Mcasp_WordLength_16);
924             if(mcaspErr != Audk2g_EOK) {
925                 return ASIT_ERR_MCASP_CFG;
926             }
928             // Start swapping data
929             pInpIo->swapData = TRUE;
930             TRACE_VERBOSE0("Reconfigure McASP word length and start swapping data.");
931         }
933         // Start PHY transfer
934         TRACE_VERBOSE0("Start I/O PHY transfer.");
935         asitPhyTransferStart(pInpIo);
936     }
938     return 0;
939 } /* asitIoCompsInit */
941 /*======================================================================================
942  *  This function initializes ASIT processing
943  *====================================================================================*/
944 void asitProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec)
946     pInp->swapData = TRUE;
947     pInp->pcmSwitchHangOver = INPUT_SWITCH_HANGOVER;
948     pDec->initDone = FALSE;
949     pInp->numFrameReceived = 0;
952 /*======================================================================================
953  *  I/O physical layer prime operation required by McASP LLD
954  *====================================================================================*/
955 void asitIoPhyPrime(PAF_AST_IoInp *pInp)
957     Int32        count;
959     for(count = 0; count < pInp->numPrimeXfers; count++)
960     {
961         ioPhyXferSubmit(pInp->hIoPhy);
962 #ifdef ASIP_DEBUG
963         //pInp->numXferStart++;
964 #endif
965     }
966 } /* asitIoPhyPrime */
969 /*======================================================================================
970  *  This function marks the I/O PHY transfer as complete
971  *====================================================================================*/
972 void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo)
974     // Mark underlining I/O BUFF write complete and swap data if needed
975     ioPhyXferComplete(pInpIo->hIoPhy, pInpIo->swapData);
976 } /* asitPhyTransferComplete */
978 Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize)
980     ioPhyCtl_t ioPhyCtl;
981     Int mcaspErr;
983     ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
984     ioPhyCtl.params.xferFrameSize = xferSize;
985     ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
987     pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
989     if(!pInp->swapData) {
990         // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
991         mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
992         if(mcaspErr != Audk2g_EOK) {
993             return ASIT_ERR_MCASP_CFG;
994         }
996         // Start swapping data
997         pInp->swapData = TRUE;
998     }
1000     return ASIT_NO_ERR;
1002 } /* asitRecfgPhyXfer */
1004 /*======================================================================================
1005  *  McASP LLD call back function
1006  *====================================================================================*/
1007 void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
1009     /* post semaphore */
1010     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
1011         //Semaphore_post(asipSemRx);
1012         Event_post(asitEvent, ASIT_EVTMSK_INPDATA);
1013     } else {
1014         ;    // intermediate packet due to buffer wrapping around
1015     }
1018 /*======================================================================================
1019  *  This function checks if McASP Rx for input overruns
1020  *====================================================================================*/
1021 int asipCheckMcaspRxOverrun(Ptr mcaspChanHandle)
1023     Mcasp_errCbStatus mcaspErrStat;
1025     mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
1027     return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
1030 /*======================================================================================
1031  *  This function restarts McASP LLD channel for input
1032  *====================================================================================*/
1033 void asipMcaspRxRestart(void)
1035     mcaspRxReset();
1036     mcaspRxCreate();
1039 /*======================================================================================
1040  *  This function starts an I/O PHY transfer
1041  *====================================================================================*/
1042 void asitPhyTransferStart(PAF_AST_IoInp *pInpIo)
1044     Int ioPhyErr;
1046     if(asipCheckMcaspRxOverrun(pInpIo->hMcaspChan)) {
1047 #ifdef ASIP_DEBUG
1048         pInpIo->numInputOverrun++;
1049 #endif
1050         asipMcaspRxRestart();
1051     }
1052     else {
1053         ioPhyErr = ioPhyXferSubmit(pInpIo->hIoPhy);
1054         //if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
1055         if(ioPhyErr!=IOPHY_NOERR){
1056             printf("\n I/O PHY ioPhyXferSubmit fails with error %d!\n", ioPhyErr);
1057             // Input buffer overflows!
1058             //printf("\nInput buffer overflows!\n");
1059             exit(0);
1060         }
1061         else {
1062             // Input buffer operates normally
1063             ;
1064         }
1065 #ifdef ASIP_DEBUG
1066         //pInpIo->numXferStart++;
1067 #endif
1068     }
1071 Int d10Initialized = 0;
1072 //extern Audk2g_STATUS mcaspAudioConfig(void);
1073 extern void McaspDevice_init(void);
1075 /*======================================================================================
1076  *  This function initializes HW interface and selects the right device for input
1077  *====================================================================================*/
1078 Int asitSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp)
1080     Audk2g_STATUS status;
1082     //more configuration is needed to abstract out D10
1083     if(!d10Initialized) {
1084         /* Initialize McASP HW details */
1085         McaspDevice_init();
1087         D10_init();
1089 #ifdef INPUT_SPDIF
1090         // Input is DIR
1091         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
1092 #else
1093         // Input is HDMI
1094         status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
1095 #endif
1096         if(status != Audk2g_EOK) {
1097             Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
1098             return ASIT_ERR_D10_CFG;
1099         }
1100         audk2g_delay(50000); // Without delay between these 2 calls system aborts.
1102         /* Initialize McASP module */
1103         status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c
1104         if(status != Audk2g_EOK) {
1105             Log_info0("McASP Configuration Failed!\n");
1106             return ASIT_ERR_MCASP_CFG;
1107         }
1109         pInp->hMcaspChan = hMcaspRxChan;
1110         d10Initialized = 1;
1111     }
1113     /////////////// TODO: HW interface selection and initialization //////////////
1114     ////// to add what PAF_ASIT_selectDevices() does /////////
1115 #ifdef IO_HW_INTERFACE
1116     pInp->pRxParams = pQ->devinp->x[IO_HW_INTERFACE];
1117 #else
1118     pInp->pRxParams = NULL;
1119 #endif
1121     return 0;
1122 }  /* asitSelectDevices */
1124 /*======================================================================================
1125  *  This function updates input status
1126  *====================================================================================*/
1127 Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
1128                           PAF_InpBufConfig *pInpBuf)
1130     Int asipErrno;
1132     PAF_SIO_InputStatus inputStatus;
1134     // initialize all values to unknown so that device specific
1135     //   driver layer need only fill in those entries that it is aware of.
1136     //   This allows extensibility of the structure without requiring users
1137     //   to re-code.
1138     inputStatus.lock = 0;
1139     inputStatus.sampleRateData = PAF_SAMPLERATE_UNKNOWN;
1140     inputStatus.sampleRateMeasured = PAF_SAMPLERATE_UNKNOWN;
1141     inputStatus.nonaudio = PAF_IEC_AUDIOMODE_UNKNOWN;
1142     inputStatus.emphasis = PAF_IEC_PREEMPHASIS_UNKNOWN;
1144     //more configuration is needed to abstract out D10
1145     asipErrno = D10_RxControl(pRxParams,
1146                           (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS,
1147                           (Arg) &inputStatus);
1148     if (asipErrno) {
1149         return asipErrno;
1150     }
1151     pStatus->sampleRateData = inputStatus.sampleRateData;
1152     pStatus->sampleRateMeasured = inputStatus.sampleRateMeasured;
1153     pStatus->nonaudio = inputStatus.nonaudio;
1154     pStatus->emphasisData = inputStatus.emphasis;
1156     // if MSB of override clear then use as reported lock
1157     // if = 0x80 then use default [0x81]
1158     // if = 0x81 then use measured (from device)
1159     // others not defined or implemented
1160     if ((pStatus->lockOverride & (XDAS_Int8)0x80) == 0)
1161         pStatus->lock = pStatus->lockOverride;
1162     else if (pStatus->lockOverride == (XDAS_Int8)0x80)
1163         pStatus->lock = inputStatus.lock;
1164     else if (pStatus->lockOverride == (XDAS_Int8)0x81)
1165         pStatus->lock = inputStatus.lock;
1167     // if MSB of override clear then use it as sample rate for system,
1168     // if = 0x80 then use default [0x82]
1169     // if = 0x81 then use data
1170     // if = 0x82 then use measured
1171     // others not defined or implemented
1172     if ((pStatus->sampleRateOverride & (XDAS_Int8)0x80) == 0)
1173         pStatus->sampleRateStatus = pStatus->sampleRateOverride;
1174     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x80)
1175         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
1176     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x81)
1177         pStatus->sampleRateStatus = pStatus->sampleRateData;
1178     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x82)
1179         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
1181     // Update emphasis status:
1182     if ((pStatus->emphasisOverride & (XDAS_Int8)0x80) == 0) {
1183         if (pStatus->emphasisData == PAF_IEC_PREEMPHASIS_YES)
1184             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
1185         else
1186             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
1187     }
1188     else if (pStatus->emphasisOverride ==
1189              (XDAS_Int8 )(0x80+PAF_IEC_PREEMPHASIS_YES))
1190         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
1191     else /* IBEmphasisOverrideNo or other */
1192         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
1194     // Update precision control
1195     pInpBuf->precision = pStatus->precisionInput =
1196         pStatus->precisionOverride < 0
1197         ? pStatus->precisionDefault
1198         : pStatus->precisionOverride > 0
1199         ? pStatus->precisionOverride
1200         : pStatus->precisionDetect > 0
1201         ? pStatus->precisionDetect
1202         : pStatus->precisionDefault;
1204     return 0;
1208 /*==============================================================================
1209  * This function updates input buffer config based on frame information provided
1210  * by I/O DATA.
1211  ==============================================================================*/
1212 void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
1214     PAF_InpBufConfig *pBufConfig;
1215     ioDataCtl_t ioDataCtl;
1217     /* Get information for reading input data */
1218     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
1219     ioDataControl(pInp->hIoData, &ioDataCtl);
1221     if(ioDataCtl.param.dataReadInfo.frameSize != pInp->phyXferSize) {
1222         // Fatal error!
1223         TRACE_VERBOSE0("TaskAsip: error in updating I/O");
1224         SW_BREAKPOINT;
1225     }
1227     pBufConfig = &(pAstCfg->xInp[pAstCfg->masterDec].inpBufConfig);
1229     //JXTODO: do we need to gate here?
1230     //key = GateMP_enter(gateHandle);
1232     pBufConfig->base.pVoid   = ioDataCtl.param.dataReadInfo.buffBase;
1233     pBufConfig->sizeofBuffer = ioDataCtl.param.dataReadInfo.buffSize;
1234     pBufConfig->pntr.pSmInt  = ioDataCtl.param.dataReadInfo.startAddress;
1236     // Leave the gate
1237     //GateMP_leave(gateHandle, key);
1239     TRACE_TERSE2("Frame start address: 0x%x., preamble: 0x%x",
1240                  (UInt)ioDataCtl.param.dataReadInfo.startAddress,
1241                  *(UInt *)ioDataCtl.param.dataReadInfo.startAddress);
1244 /*==============================================================================
1245  * Decide source after SYNC is found, i.e. either bitstream preamble is detected
1246  * or it times out to PCM.
1247  ==============================================================================*/
1248 Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
1249                      ioDataAutoDetStat_t *autoDetStatus)
1251     Int sourceConfig, sourceSelect, sourceProgram;
1252     Int zMD;
1253     char asipMsgBuf[ASP_MSG_BUF_LEN];
1255     // Get the configured source
1256     zMD = pAstCfg->masterDec;
1257     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
1258                                           GATEMP_INDEX_DEC);
1260     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
1261         if (sourceConfig == PAF_SOURCE_DSD1 || sourceConfig == PAF_SOURCE_DSD2 ||
1262             sourceConfig == PAF_SOURCE_DSD3) {
1263             sourceProgram = sourceConfig;
1264         }
1265         else {
1266             sourceProgram = PAF_SOURCE_PCM;
1267         }
1268     }
1270     if(autoDetStatus->syncState == IODATA_SYNC_BITSTREAM) {
1271         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
1272         sourceProgram = IECpafSource[pc];
1273     }
1275     // write the decided source program to memory
1276     sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram,
1277                        GATEMP_INDEX_DEC);
1279     // now that we have some input classification, and possibly an outstanding
1280     // input frame, we determine whether or not to call decodeProcessing and with
1281     // what decAlg.
1282     sourceSelect = PAF_SOURCE_NONE;
1284     switch (sourceConfig)
1285     {
1286         // If autodetecting, decoding everything, and input is something
1287         // (i.e. bitstream or PCM) then decode.
1288         case PAF_SOURCE_AUTO:
1289             if (sourceProgram >= PAF_SOURCE_PCM)  {
1290                 sourceSelect = sourceProgram; // use whatever from autodet
1291             }
1292             break;
1294         // If autodetecting, decoding only PCM, and input is PCM then decode.
1295         case PAF_SOURCE_PCMAUTO:
1296             if (sourceProgram == PAF_SOURCE_PCM) {
1297                 // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
1298                 sourceSelect = sourceProgram;
1299             }
1300             break;
1302         // If autodetecting, decoding only bitstreams, and input is a bitstream then decode.
1303         case PAF_SOURCE_BITSTREAM:
1304             if (sourceProgram >= PAF_SOURCE_AC3) {
1305                 sourceSelect = sourceProgram;
1306             }
1307             break;
1309         // If autodetecting, decoding only DTS, and input is DTS then decode.
1310         case PAF_SOURCE_DTSALL:
1311             switch (sourceProgram)
1312             {
1313                 case PAF_SOURCE_DTS11:
1314                 case PAF_SOURCE_DTS12:
1315                 case PAF_SOURCE_DTS13:
1316                 case PAF_SOURCE_DTS14:
1317                 case PAF_SOURCE_DTS16:
1318                 case PAF_SOURCE_DTSHD:
1319                     sourceSelect = sourceProgram;
1320                     break;
1321             }
1322             break;
1324         // All others, e.g., force modes, fall through to here.
1325         // If user made specific selection then program must match select.
1326         // (NB: this compare relies on ordering of PAF_SOURCE)
1327         default:
1328             sourceSelect = sourceConfig;
1329             if ((sourceSelect >= PAF_SOURCE_PCM) && (sourceSelect <= PAF_SOURCE_N)) {
1330                 if (sourceProgram != sourceSelect) {
1331                     sourceSelect = PAF_SOURCE_NONE;
1332                 }
1333             }
1334             break;
1335     }
1337     // if we didn't find any matches then skip
1338     if (sourceSelect == PAF_SOURCE_NONE) {
1339         TRACE_VERBOSE0("TaskAsip: no matching source type, continue");
1340         return ASIT_ERR_NO_MATCHING_SOURCE;
1341     }
1343 #ifndef DEBUG_SKIP_DECODING
1344     // send source select message to slave
1345     *(Int32 *)&asipMsgBuf[0] = sourceSelect;
1346     if(AspMsgSend(ASP_SLAVE_DEC_SOURCE_SELECT, ASP_MASTER_DEC_SOURCE_SELECT_DONE,
1347                   asipMsgBuf, NULL) != ASP_MSG_NO_ERR) {
1348         TRACE_VERBOSE0("TaskAsip: error in sending SOURCE_SELECT message");
1349         SW_BREAKPOINT;
1350     }
1351 #endif
1353     pInp->sourceSelect  = sourceSelect;
1354     pInp->sourceProgram = sourceProgram;
1356     return ASIT_NO_ERR;
1357 } /* asitDecideSource */
1359 /*==============================================================================
1360  * After SYNC is found, i.e. either bitstream preamble is detected or it times
1361  * out to PCM, update input buffer config and I/o components accordingly.
1362  ==============================================================================*/
1363 Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
1364                       PAF_AST_IoInp  *pInp, ioDataAutoDetStat_t *autoDetStatus)
1366     Int sourceConfig;
1367     Int zMD, deliverZeros;
1368     int ioFrameLength, decFrameLength;
1369     PAF_InpBufConfig *pBufConfig;
1370     ioPhyCtl_t  ioPhyCtl;
1371     ioDataCtl_t ioDataCtl;
1373     zMD = pAstCfg->masterDec;
1374     pBufConfig = &pAstCfg->xInp[zMD].inpBufConfig;
1376     // Compute decoder frame length based on source selection
1377     decFrameLength = getFrameLengthSourceSel(pP, pInp->sourceSelect);
1379     pAstCfg->xDec[zMD].decodeControl.frameLength  = decFrameLength;
1380     pAstCfg->xDec[zMD].decodeInStruct.sampleCount = decFrameLength;
1381     pAstCfg->xDec[zMD].decodeControl.sampleRate   = PAF_SAMPLERATE_UNKNOWN;
1383     // Decide frame length for I/O DATA and I/O PHY
1384     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
1385         // For PCM, I/O frame length is decode frame length multiplied by stride
1386         ioFrameLength = decFrameLength * INPUT_STRIDE;
1388         pBufConfig->sizeofElement = WORD_SIZE_PCM;
1389         pBufConfig->frameLength   = pBufConfig->lengthofData = ioFrameLength;
1391         // Configure I/O DATA PCM frame length
1392         ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH;
1393         ioDataCtl.param.frameLengthPcm = ioFrameLength;
1394         ioDataControl(pInp->hIoData, &ioDataCtl);
1396         // Change I/O PHY transfer size to PCM frame size
1397         pInp->phyXferSize = ioFrameLength*(WORD_SIZE_PCM);
1399         // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
1400         // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
1401         // Adjust delay and don't mark input buffer as read complete
1402         //ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
1404         // Stop swapping data
1405         //pInp->swapData = FALSE;
1406     }
1407     else {
1408         // For bitstream, I/O frame length is the frame length of the bitstream
1409         uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
1410         ioFrameLength = iecFrameLength[pc];
1412 /*
1413         if(   (pc == 0x11) && (DTSHDSubType == 3)
1414            && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
1415             pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
1417         if (pc == 1)
1418             pDevExt->elementSize = 4288;
1419         else if (pc == 0x11) {
1420             pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
1421             pDevExt->lengthofData = pDevExt->frameLength;
1422         }
1423 */
1425         pBufConfig->sizeofElement = WORD_SIZE_BITSTREAM;
1426         pBufConfig->frameLength   = ioFrameLength;
1427         pBufConfig->lengthofData  = ioFrameLength - IEC_HEADER_LENGTH;
1429         // Change I/O PHY transfer size to bitstream frame size
1430         pInp->phyXferSize = ioFrameLength*WORD_SIZE_BITSTREAM;
1431     }
1433     pBufConfig->stride = INPUT_STRIDE;   // common for PCM and bitstream
1435     // Configure I/O PHY transfer size
1436     ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
1437     ioPhyCtl.params.xferFrameSize = pInp->phyXferSize;
1438     ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
1440     // Decide if zeros should be delivered based on the configured source
1441     sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
1442                                           GATEMP_INDEX_DEC);
1444     if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
1445         // Bitstream preamble is not found and it times out -> assume this is PCM
1446         deliverZeros = autoDetStatus->deliverZeros;
1447         if (sourceConfig == PAF_SOURCE_PCM || sourceConfig == PAF_SOURCE_DSD1 ||
1448             sourceConfig == PAF_SOURCE_DSD2 || sourceConfig == PAF_SOURCE_DSD3) {
1449             // set to one -- ensures that PCM decode calls made before data is
1450             // available will result in zero output.
1451             // (mostly needed for PA15 since, currently, all other frameworks
1452             // require a frame of data before the first decode call.
1453             deliverZeros = TRUE;  // override deliverZeros returned by ioDataControl
1454         }
1456         // update input buffer config structure
1457         pBufConfig->deliverZeros  = deliverZeros;
1458     }
1460     //JXTODO: decide what to do with hRxSio
1461     //temporary - does ARM use hRxSio or just check if it is not NULL?
1462     pAstCfg->xInp[zMD].hRxSio = pInp->hIoData;
1463     pAstCfg->xInp[zMD].pInpBuf = &(pAstCfg->xInp[zMD].inpBufConfig);
1465     return ASIT_NO_ERR;
1466 } /* asitUpdateIoComps */
1469 #ifndef IO_LOOPBACK_TEST
1470 #if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH
1471 U8 pcmbuf[OUTPUT_FRAME_SIZE];
1472 #else
1473 #error Input frame length is not equal to output frame length!
1474 #endif
1476 Int rxDecodePcm(PAF_AST_IoInp  *pInp)
1478     ioDataCtl_t ioDataCtl;
1479     void *buffBase;
1480     void *dataStartAddress;
1481     size_t buffSize, frameSize, size1, size2;
1483     /* Get information for reading input data */
1484     ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
1485     ioDataControl(pInp->hIoData, &ioDataCtl);
1487     buffBase = ioDataCtl.param.dataReadInfo.buffBase;
1488     buffSize = ioDataCtl.param.dataReadInfo.buffSize;
1489     dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
1490     frameSize        = ioDataCtl.param.dataReadInfo.frameSize;
1492     // Copy PCM data to output buffer
1493     if(((size_t)dataStartAddress+frameSize) <= ((size_t)buffBase+buffSize)) {
1494         // Input buffer doesn't wrap around
1495         Cache_inv(dataStartAddress, frameSize, Cache_Type_ALL, TRUE);
1496         memcpy((void *)&pcmbuf[0], dataStartAddress, frameSize);
1497     }
1498     else {
1499         // Input buffer wraps around
1500         size1 = (size_t)buffBase + buffSize - (size_t)dataStartAddress;
1501         size2 = frameSize - size1;
1502         Cache_inv(dataStartAddress, size1, Cache_Type_ALL, TRUE);
1503         memcpy((void *)&pcmbuf[0], dataStartAddress, size1);
1505         Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
1506         memcpy((void *)&pcmbuf[size1], buffBase, size2);
1507     }
1510     return ASIT_NO_ERR;
1514 Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
1516     return ASIT_NO_ERR;
1518 #endif
1520 Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents)
1522     TRACE_VERBOSE2("ASIT events error: actual events are: %d, expected events are: %d.",
1523                    actualEvents, expectedEvents);
1525     return ASIT_ERR_EVENTS;
1528 void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr)
1530     UInt events;
1532     if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
1533         TRACE_VERBOSE0("ASIT error handling: input buffer underflows. No actions needed.");
1534     }
1536     if(asitErr == ASIT_ERR_DECODE_QUIT) {
1537         TRACE_VERBOSE0("ASIT error handling: DECODE_QUIT - clear INPDATA event.");
1538 #if 0
1539         // Pend on INPTDATA event that should have been posted before decoding quits.
1540         events = Event_pend(asitEvent, ASIT_EVTMSK_NONE, ASIT_EVTMSK_INPDATA,
1541                             BIOS_WAIT_FOREVER);
1543         // Marks I/O PHY transfer and I/O BUFF write complete
1544         asitPhyTransferComplete(&pAsitCfg->pIoInp[0]);
1546         // Keep I/O BUFF read pointers going
1547         asitBypassIoData(&pAsitCfg->pIoInp[0]);
1548 #endif
1549         pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
1550         pAsitCfg->pIoInp[0].numAsitRestart++;
1551         TRACE_VERBOSE0("ASIT error handling finished. Go to state ASIT_RESET.");
1552     }
1554     if(asitErr == ASIT_ERR_EVENTS) {
1555         pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
1556         pAsitCfg->pIoInp[0].numAsitRestart++;
1557         TRACE_VERBOSE0("ASIT error handling: events error. Go to state ASIT_RESET.");
1558     }
1560     return;
1561 }  /* asitErrorHandling */
1564 //////////////////////////////////////////////////////////////////////////////
1565 void asitPostInfoEvent()
1567     Event_post(asitEvent, ASIT_EVTMSK_INFOACK);
1570 void asitPostDecEvent()
1572     Event_post(asitEvent, ASIT_EVTMSK_DECACK);
1574 //////////////////////////////////////////////////////////////////////////////
1576 /* Nothing past this line */