diff --git a/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c b/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c
index 7113d92622ac95d9f84e51e347843d042a369a92..61518a499f85d0e00e1da6e970f70e6149913858 100644 (file)
*/
#include <xdc/runtime/Log.h>
#include <ti/sysbios/BIOS.h>
+#include <xdc/runtime/Error.h>
+#include <ti/sysbios/knl/Event.h>
#include "procsdk_audio_typ.h"
#include "audioStreamInpProc.h"
#include "asperr.h"
#include "common.h"
-#include "audk2g.h"
-#include "audk2g_audio.h"
+#include "aud.h"
+#include "aud_audio.h"
#include "mcasp_cfg.h"
#include "ioConfig.h" //TODO: remove this header
#include "ioBuff.h"
#define STRIDE_WORST_CASE 32 // 4-byte (32-bit) word, 2 slots, 4 serializers
+//#define DEBUG_SKIP_DECODING
+
#define SYNC_PC_MASK 0x1F
#define SYNC_SUBTYPE_MASK 0x700
#define SYNC_SUBTYPE_SHIFT 8
@@ -105,53 +109,73 @@ extern Void taskAsipFxnInit(const PAF_ASIT_Params *pP,const PAF_ASIT_Patchs *pQ)
// avoid including sap_d10.h, which would cause symbol redefinition
// warning (MCASP_PFUNC_XXX)
-extern XDAS_Int32 D10_init();
+//extern XDAS_Int32 D10_init(void * pD10Params);
+extern XDAS_Int32 D10_initClkMux(void *pD10Params);
extern XDAS_Int32 D10_RxControl(const void *pD10RxParams,
XDAS_Int32 code, XDAS_Int32 arg);
/*
* Functions only used in this file
*/
-int asipPrepareProcessing();
-int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
-void asipProcInit(PAF_AST_IoInp *pInp, asipDecProc_t *pDec);
-void asipIoPhyPrime(PAF_AST_IoInp *pInpIo);
-void asipPhyTransferPend(void);
-void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo);
-void asipPhyTransferStart(PAF_AST_IoInp *pInpIo);
-Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp);
-Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
+int asitPrepareProcessing();
+int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
+void asitProcInit(PAF_AST_IoInp *pInp, asipDecProc_t *pDec);
+void asitIoPhyPrime(PAF_AST_IoInp *pInpIo);
+void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo);
+void asitPhyTransferStart(PAF_AST_IoInp *pInpIo);
+Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize);
+
+// Select Input devices
+Int asitSelectDevices(
+ const PAF_ASIT_Patchs *pQ,
+ PAF_AST_Config *pAstCfg,
+ PAF_AST_IoInp *pInp
+);
+
+Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
PAF_InpBufConfig *pInpBuf);
-//Int asipDecideSource(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, asipDecProc_t *pDec);
-Int asipProcessing(const PAF_ASIT_Params *pP,
- const PAF_ASIT_Patchs *pQ,
- PAF_ASIT_Config *pAsitCfg);
-void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno);
+Int asitSourceDetection(const PAF_ASIT_Params *pP,
+ const PAF_ASIT_Patchs *pQ,
+ PAF_ASIT_Config *pAsitCfg);
+
+Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp,
+ ioDataAutoDetStat_t *autoDetStatus);
+Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
+ PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *autoDetStatus);
+Int asitBypassIoData(PAF_AST_IoInp *pInp);
+Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg);
+
+void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp);
+Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats);
+
+UInt asitEventsToDecMsg(UInt asitEvents);
+void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr);
+Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents);
+
+void asitPostInfoEvent();
+void asitPostDecEvent();
/*
* variables/structures to be put into proper global structures
*/
-extern Semaphore_Handle asipSemRx;
extern PAF_ASIT_Config gPAF_ASIT_config;
extern const MdUns iecFrameLength[23];
extern Ptr hMcaspRxChan;
+// temp for simulation
+//#define ASIT_ALL_EVENTS ( ASIT_EVTMSK_INPDATA \
+// + ASIT_EVTMSK_INFOACK \
+// + ASIT_EVTMSK_DECACK )
+#define ASIT_ALL_EVENTS ( ASIT_EVTMSK_INPDATA \
+ + ASIT_EVTMSK_RXACK )
-enum
-{
- ASIP_SOURCE_DETECTION,
- ASIP_DECODE,
- ASIP_SWITCH_TO_PCM,
-};
-
-enum
-{
- ASIP_INPUT_PREPARATION,
- ASIP_INPUT_PROCESSING
-};
-
-
+// temp for simulation
+//#define ASIT_DEC_EVENTS ( ASIT_EVTMSK_INPDATA \
+// + ASIT_EVTMSK_INFOACK \
+// + ASIT_EVTMSK_DECACK )
+#define ASIT_DEC_EVENTS ( ASIT_EVTMSK_INPDATA \
+ + ASIT_EVTMSK_RXACK )
#define ASIP_DEBUG
int asipLoopCount1, asipLoopCount2;
Int asipErrno;
Int inputReadyForProcessing;
+
+// debug
+#include "evmc66x_gpio_dbg.h"
#endif
+Event_Handle gAsitEvtHandle; // ASIT event handle
+Int eventsOn; // flag indicating whether to process events
+
+SyncEvent_Handle gAsitSyncEvtHandle; // ASIT Sync event handle
+
/*
* ======== taskAsipFxn ========
* Audio Stream Input Processing task function
Int asipErrno;
Int inputReadyForProcessing;
#endif
-
- Int firstTimeInit = TRUE;
+ Int asitErr;
+ UInt events;
+// Int eventsOn;
+// Error_Block eb;
Log_info0("Enter taskAsipFxn()");
TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
}
- TRACE_TERSE0("TaskAsip: Entering Main Loop.");
+ Log_info0("TaskAsip: Entering Main Loop.");
//
// Main processing loop
//
asipLoopCount1 = 0;
asipLoopCount2 = 0;
- asipErrno = 0;
- pInp->asipState = ASIP_INPUT_PREPARATION;
+ asitErr = ASIT_NO_ERR;
+
+ // The events_on flag will be removed if the RESTART state is changed to
+ // event-based scheduling instead of polling
+ eventsOn = FALSE;
for (;;)
{
asipLoopCount1++;
+ if(eventsOn) {
+ events = Event_pend(gAsitEvtHandle, ASIT_EVTMSK_NONE, ASIT_ALL_EVENTS,
+ BIOS_WAIT_FOREVER);
+ }
switch (pInp->asipState)
{
- case ASIP_INPUT_PREPARATION:
+ case ASIT_RESET: // No events pending in this state
// Indicate decoder no decoding yet
pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
// event based scheduling.
Task_sleep(5);
- inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
+ inputReadyForProcessing = asitPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
if (inputReadyForProcessing) {
+ TRACE_VERBOSE0("TaskAsip: Input is ready. Initialize I/O components.");
// Input is ready for processing, so we initialize the I/O components.
- // Note that the I/O components init. and I/O PHY prime are performed only at the
- // first time. This should be changed later - init. and prime should be done whenever
- // input interface has changed.
- if(firstTimeInit) {
- asipIoCompsInit(&pAstCfg->xInp[zMI], pInp);
-
- // Start I/O physical layer by priming McASP LLD for input
- asipIoPhyPrime(pInp);
+ // Note that the I/O components init. and I/O PHY prime are performed only
+ // at the first time. This should be changed later - init. and prime
+ // should be done whenever input interface has changed.
+ asitErr = asitIoCompsInit(&pAstCfg->xInp[zMI], pInp);
+
+ // Initialize ASIT processing
+ asitProcInit(pInp, &pAsitCfg->inpDec);
+ pInp->asipState = ASIT_SOURCE_DETECTION;
+ eventsOn = TRUE; // turn on events pending
+ TRACE_VERBOSE0("TaskAsip: turn on events and go to source detection.");
+ }
+ break;
- firstTimeInit = FALSE;
+ case ASIT_SOURCE_DETECTION:
+ // Source unknown - to detect & identify source
+ if(events == ASIT_EVTMSK_INPDATA) {
+ // Only this event is expected. If any other event, it's error.
+ // Input data is ready - perform source detection.
+ // New state will be decided inside the function
+ asitErr = asitSourceDetection(pP, pQ, pAsitCfg);
+
+ if(asitErr == ASIT_AUTODET_TIME_OUT) {
+ // Should restart if new interface is selected.
+ TRACE_VERBOSE0("TaskAsip: auto-detection time out.");
}
+ }
+ else {
+ //Error checking & debug
+ asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
+ }
- // Initialize ASIP processing
- asipProcInit(pInp, &pAsitCfg->inpDec);
+ break;
- pInp->asipState = ASIP_INPUT_PROCESSING;
+ case ASIT_PCM_TRANSITION:
+ // Source is PCM - transition to PCM decoding
+ if(events == ASIT_EVTMSK_INPDATA) {
+ // Only this event is expected. If any other event, it's error.
+ // Input data is ready - transition to PCM decoding
+ // New state will be decided inside the function
+ asitErr = asitPcmTransition(pAsitCfg);
+ }
+ else {
+ //Error checking & debug
+ asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
}
break;
- case ASIP_INPUT_PROCESSING:
- // Pending on I/O PHY transfer
- asipPhyTransferPend();
-
- // Marks I/O PHY transfer and I/O BUFF write complete
- asipPhyTransferComplete(pInp);
-
- // Main function to process input data
- asipErrno = asipProcessing(pP, pQ, pAsitCfg);
-
- // Start next transfer
- asipPhyTransferStart(pInp);
-
- if(asipErrno) {
- asipErrorHandling(pAstCfg, asipErrno);
-
- pInp->asipState = ASIP_INPUT_PREPARATION;
+ case ASIT_DECODE_PROCESSING:
+ if(events & ASIT_DEC_EVENTS) {
+
+#if 1 // debug
+ if (events & ASIT_EVTMSK_INPDATA)
+ {
+ // shows timing of Input (Rx McASP EDMA)
+ // ADC B5
+ {
+ static Uint8 toggleState = 0;
+ if (toggleState == 0)
+ GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
+ else
+ GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
+ toggleState = ~(toggleState);
+ }
+ }
+#endif
+
+ // Decode processing for either PCM or bitstream
+ // New state will be decided inside the function
+ asitErr = asitDecodeProcessing(pP, pQ, pAsitCfg, events);
+ }
+ else {
+ //Error checking & debug
+ asitErr = asitEvtErrCheck(events, ASIT_DEC_EVENTS);
}
-
break;
default:
break;
}
+
+ if(asitErr) {
+ asitErrorHandling(pAsitCfg, asitErr);
+
+ if(pInp->asipState == ASIT_RESET) {
+ eventsOn = FALSE;
+ }
+
+ asitErr = ASIT_NO_ERR;
+ }
+
} // for (;;)
} /* taskAsipFxn */
/*===========================================================================
- * ASIP processing preparation
+ * ASIT Processing Preparation
* Output:
* - return TRUE (input is ready) or FALSE (input is not ready)
- * - *asipErrno Error number
+ * - *asipErrno Error number
============================================================================*/
-Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
+Int asitPrepareProcessing(const PAF_ASIT_Params *pP,
const PAF_ASIT_Patchs *pQ,
PAF_ASIT_Config *pC,
Int *asipErrno)
*asipErrno = 0;
// Select source and initialize physical layer / HW interface
- *asipErrno = asipSelectDevices(pQ, pInp);
+ *asipErrno = asitSelectDevices(pQ, pAstCfg, pInp);
if (*asipErrno) {
- TRACE_TERSE2("TaskAsip: selectDevices returned asipErrno = 0x%04x at line %d. AS%d", *asipErrno, as+zMS);
+ TRACE_TERSE2("asitSelectDevices returned asipErrno = 0x%04x at line %d. AS%d",
+ *asipErrno, as+zMS);
return FALSE; // Input is not ready for processing due to error
}
}
// If here then we have a valid input so query its status
- *asipErrno = asipUpdateInputStatus(pInp[zMI].pRxParams,
+ *asipErrno = asitUpdateInputStatus(pInp[zMI].pRxParams,
&pAstCfg->xInp[zMI].inpBufStatus,
&pAstCfg->xInp[zMI].inpBufConfig);
if(*asipErrno) {
*asipErrno = pP->fxns->passProcessing(pP, pQ, pC, NULL);
}
else {
- TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x", as+zMS, ASPERR_PASS);
+ TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x",
+ as+zMS, ASPERR_PASS);
*asipErrno = ASPERR_PASS;
}
// No error and input processing is ready
return TRUE;
-} /* asipPrepareProcessing */
+} /* asitPrepareProcessing */
+
+
+/*===========================================================================
+ * ASIT Source Detection:
+ * ASIT processing for input source identification:
+ * - mark I/O PHY transfer completion
+ * - run auto-detection via I/O DATA in asitInputDataProcess
+ * - mark I/O DATA read completion
+ * - check auto-detection status and take corresponding actions if either
+ * PCM or bitstream is identified:
+ * - decide input source
+ * - update I/O components
+ * - reconfigure McASP LLD if it is PCM
+ * - start next I/O PHY transfer
+============================================================================*/
+Int asitSourceDetection(const PAF_ASIT_Params *pP,
+ const PAF_ASIT_Patchs *pQ,
+ PAF_ASIT_Config *pAsitCfg)
+{
+ PAF_AST_Config *pAstCfg;
+ PAF_AST_IoInp *pInp; // I/O components for input
+ Int zMD, mcaspErr, asitErr;
+ ioDataAutoDetStat_t autoDetStatus;
+
+ pAstCfg = pAsitCfg->pAstCfg; // pointer to AST common (shared) configuration
+ zMD = pAstCfg->masterDec;
+ pInp = &pAsitCfg->pIoInp[zMD]; // pointer to input I/O components
+
+ // Marks I/O PHY transfer and I/O BUFF write complete
+ asitPhyTransferComplete(pInp);
+
+ // Process input data - either searching SYNC for PCM or checking SYNC for bitstream
+ asitErr = asitInputDataProcess(pInp, &autoDetStatus);
+ if(asitErr != ASIT_NO_ERR) {
+ // Even though there is error, still need to start next transfer to
+ // maintain McASP transfer.
+ asitPhyTransferStart(pInp);
+
+ return asitErr;
+ }
+
+ // Mark input data read complete
+ ioDataReadComplete(pInp->hIoData);
+
+ if(autoDetStatus.syncTimeOut) {
+ return ASIT_AUTODET_TIME_OUT;
+ }
+ // Check if bitstream or PCM is detected
+ else if( autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
+ || autoDetStatus.syncState == IODATA_SYNC_PCM) {
+ // Decide input source and inform decoder
+ asitErr = asitDecideSource(pAstCfg, pInp, &autoDetStatus);
+ if(asitErr != ASIT_NO_ERR) {
+ return asitErr;
+ }
+ else {
+ // Update I/O components and input buffer config
+ asitUpdateIoComps(pP, pAstCfg, pInp, &autoDetStatus);
+
+ // set to unknown so that we can ensure, for IOS purposes, that
+ // sourceDecode = NONE iff we are in this top level state machine
+ // and specifically not in decodeProcessing
+#ifndef DEBUG_SKIP_DECODING
+ pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
+#endif
+
+ if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
+ // Input is bit stream: go to decoding
+ pInp->asipState = ASIT_DECODE_PROCESSING;
+ }
+ else {
+ // Input is PCM: stop swapping data
+ pInp->swapData = FALSE;
+
+ // Reconfigure McASP LLD to transfer 32-bit unpacked data
+ mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
+ if(mcaspErr != Aud_EOK) {
+ return ASIT_ERR_MCASP_CFG;
+ }
+
+ // Adjust I/O BUFF delay and read pointer - to make sure read pointers
+ // always point to PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
+ ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
+
+ // Go to transition state to switch to PCM
+ pInp->asipState = ASIT_PCM_TRANSITION;
+ }
+ }
+ }
+ else {
+ // SYNC search ongoing, no action is needed
+ }
+
+ // Start next transfer
+ asitPhyTransferStart(pInp);
+
+ return (ASIT_NO_ERR);
+} /* asitSourceDetection */
+
+
+/*===========================================================================
+ //
+ // which will cause all 0's in one McASP LLD transfer. This will
+ // be detected as loss of SYNC by auto detection. To prevent that,
+ // skip I/O DATA process for hangover period so that this all 0's
+ // frame will not be seen by auto-detection. Also, playing out PCM
+ // needs to be skipped as well, to prevent from playing out garbage
+ // (16-bit packed data).
+ *
+ * ASIT Transition to PCM decoding.
+ * When PCM is detected, McASP LLD will be reconfigured to transmit 32-bit
+ * words, which will modify the RFMT register. This will cause all 0's in
+ * one McASP LLD transfer, which would be detected as loss of SYNC by auto
+ * detection (performed by I/O DATA). To prevent that, skip I/O DATA process
+ * for hangover period so that this all-0's frame will not be seen by the
+ * auto-detection.
+ *
+ * In addition, playing out PCM should be skipped as well to prevent from
+ * playing out the 16-bit packed data that's still in the input buffer.
+ *
+ * This function does the following:
+ * - mark I/O PHY transfer completion
+ * - bypass I/O DATA
+ * - start next I/O PHY transfer
+============================================================================*/
+Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg)
+{
+ Int asitErr;
+ PAF_AST_IoInp *pInp; // I/O components for input
+ Int zMD;
+
+ zMD = pAsitCfg->pAstCfg->masterDec; // pointer to AST common (shared) configuration
+ pInp = &pAsitCfg->pIoInp[zMD]; // pointer to input I/O components
+
+ // Marks I/O PHY transfer and I/O BUFF write complete
+ asitPhyTransferComplete(pInp);
+
+ // Bypass I/O data processing due to McASP LLD work around
+ // (refer to comments inside the function)
+ asitErr = asitBypassIoData(pInp);
+
+ pInp->pcmSwitchHangOver--;
+ if(pInp->pcmSwitchHangOver == 0) {
+ pInp->asipState = ASIT_DECODE_PROCESSING;
+ }
+ else {
+ ; // stay in this state
+ }
+
+ // Start next transfer
+ asitPhyTransferStart(pInp);
+
+ return asitErr;
+
+} /* asitPcmTransition */
+
+/*============================================================================
+ * ASIT Bypass I/O DATA Processing
+ * This function bypasses the I/O DATA processing. It maintains the read
+ * operation of I/O BUFF by directly calling I/O BUFF APIs. When I/O DATA
+ * is not bypassed, I/O BUFF read operation is invoked by I/O DATA.
+ *
+============================================================================*/
+Int asitBypassIoData(PAF_AST_IoInp *pInp)
+{
+ void *buff1, *buff2;
+ size_t size1, size2;
+
+ // Get read pointers (or sub-buffers) of the input buffer
+ if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
+ &buff1, &size1, &buff2, &size2)
+ == IOBUFF_ERR_UNDERFLOW) {
+ pInp->numUnderflow += 1;
+
+ // Return since there is no enough data to process
+ return ASIT_ERR_INPBUF_UNDERFLOW;
+ }
+
+ ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
+
+ if(buff2 != NULL) {
+ ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
+ }
+
+ return ASIT_NO_ERR;
+} /* asitBypassIoData */
+
+
+/*============================================================================
+ * ASIT Decode Processing
+ * This function performs the decode processing and does the following based
+ * on the ASIT events:
+ * - initialize the decode processing if it is the first time
+ * - if there is ASIT INPUT DATA event (ASIT_EVTMSK_INPDATA):
+ * - mark I/O PHY transfer completion
+ * - run auto-detection via I/O DATA in asitInputDataProcess
+ * - check auto-detection status and take corresponding actions if SYNC
+ * is lost.
+ * - start next I/O PHY transfer
+ * - map ASIT events to decoding messages
+ * - invoke decDecodeFsm() and pass the mapped decoding messages
+ * - if there is ASIT DECODE ACK event (ASIT_EVTMSK_DECACK)
+ * - mark I/O DATA read completion
+ * - error handling
+============================================================================*/
+Int asitDecodeProcessing(const PAF_ASIT_Params *pP,
+ const PAF_ASIT_Patchs *pQ,
+ PAF_ASIT_Config *pAsitCfg,
+ UInt asitEvents)
+{
+ Int asitErr, decErr;
+ PAF_AST_IoInp *pInp; // I/O components for input
+ AspMsgMaster_Handle hAspMsgMaster; // ASIT message master handle
+ asipDecProc_t *pDec;
+ ioDataAutoDetStat_t autoDetStatus;
+ Int zMD;
+ UInt decMsg;
+ Int status;
+
+ zMD = pAsitCfg->pAstCfg->masterDec; // pointer to AST common (shared) configuration
+ pInp = &pAsitCfg->pIoInp[zMD]; // pointer to input I/O components
+ hAspMsgMaster = pAsitCfg->hAspMsgMaster; // get ASIT message master handle
+ pDec = &pAsitCfg->inpDec;
+
+ // Initialization for decode processing when this function is called the first time
+#ifndef DEBUG_SKIP_DECODING
+ if(!pDec->initDone) {
+ // Initialize decoder
+ decDecodeInit(pP, pAsitCfg, pInp->sourceSelect);
+
+ pDec->initDone = TRUE;
+ }
+#endif
+
+ // Process input data if this is a data ready message
+ if(asitEvents & ASIT_EVTMSK_INPDATA) {
+ TRACE_TERSE0("asitDecodeProcessing: process input data.");
+
+ // Marks I/O PHY transfer and I/O BUFF write complete
+ asitPhyTransferComplete(pInp);
+
+ // Process input data - either search SYNC for PCM or check SYNC for bitstream
+ asitErr = asitInputDataProcess(pInp, &autoDetStatus);
+
+ if(asitErr == ASIT_NO_ERR) {
+ ioDataReadComplete(pInp->hIoData);
+
+ // Check if SYNC is maintained or lost (stream stops or format changes)
+ if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
+ // SYNC lost: change I/O PHY transfer size to default for auto-detection
+ //asitErr = asitRecfgPhyXfer(pInp, INPUT_FRAME_SIZE_DEF);
+ //if(asitErr != ASIT_NO_ERR) {
+ // return asitErr;
+ //}
+
+ // Inform decoder to complete the decoding of previous frame - is this good?
+ pInp->sourceSelect = PAF_SOURCE_NONE;
+ pInp->numFrameReceived = 0; // for debugging
+ TRACE_TERSE0("asitDecodeProcessing: SYNC lost.");
+
+#ifdef DEBUG_SKIP_DECODING
+ asitErr = ASIT_ERR_DECODE_QUIT;
+#endif
+ }
+ else {
+ pInp->numFrameReceived += 1; // for debugging
+
+ // Communicate input stream information to decoder through input
+ // buffer configuration -- this was moved inside decDecodeFsm
+ //asitUpdateInpBufConfig(pAsitCfg->pAstCfg, pInp);
+
+ // Start next transfer
+ asitPhyTransferStart(pInp);
+ }
+
+ // Start next transfer
+ //asitPhyTransferStart(pInp);
+
+#ifdef DEBUG_SKIP_DECODING
+ return asitErr;
+#endif
+ }
+ else if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
+ TRACE_TERSE0("asitDecodeProcessing: Input buffer underflows.");
+
+ // When input buffer underflows, it is not an error but decoding needs
+ // to be skipped as there is not enough data in the buffer.
+ asitPhyTransferStart(pInp);
+
+ return asitErr;
+ }
+ else {
+ // Inform decoder to complete the decoding of previous frame - is this good?
+ pInp->sourceSelect = PAF_SOURCE_NONE;
+ pInp->numFrameReceived = 0; // for debugging
+ TRACE_TERSE1("asitDecodeProcessing: asitInputDataProcess error: %d", asitErr);
+
+#ifdef DEBUG_SKIP_DECODING
+ return ASIT_ERR_DECODE_QUIT;
+#endif
+ }
+ } /* ASIT_EVTMSK_INPDATA */
+#ifdef DEBUG_SKIP_DECODING
+ else {
+ TRACE_TERSE0("asitDecodeProcessing: events error.");
+ return ASIT_ERR_EVENTS;
+ }
+#endif
+
+#ifndef DEBUG_SKIP_DECODING
+ // Map ASIT events to decode messages
+ decMsg = asitEventsToDecMsg(asitEvents);
+
+ // Pass messages (corresponding to events) to decode FSM
+ decErr = decDecodeFsm(pP, pQ, pAsitCfg, pInp->sourceSelect, decMsg);
+
+ // Mark I/O DATA read complete if decoder indicates decoding is done.
+ if((asitEvents & ASIT_EVTMSK_DECACK)) { // DECACK -> decoding done
+ //ioDataReadComplete(pInp->hIoData);
+ }
+
+ if(decErr != DEC_NO_ERR) {
+ TRACE_VERBOSE0("TaskAsip: send DEC_EXIT message to slave decoder.");
+
+ // Send dec exit message to slave decoder
+ status = AspMsgSnd(hAspMsgMaster, ASP_SLAVE_DEC_EXIT, NULL);
+ if (status != ASP_MSG_NO_ERR)
+ {
+ TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
+ SW_BREAKPOINT;
+ }
+ status = AspMsgRcvAck(hAspMsgMaster, ASP_MASTER_DEC_EXIT_DONE, NULL, TRUE);
+ if (status != ASP_MSG_NO_ERR)
+ {
+ TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
+ SW_BREAKPOINT;
+ }
+
+ return ASIT_ERR_DECODE_QUIT; // This is not necessarily an error
+ }
+ else {
+ return ASIT_NO_ERR;
+ }
+#endif
+} /* asitDecodeProcessing */
+
+
+/*============================================================================
+ * ASIT Input Data Processing:
+ * - invoke ioDataProcess() to inspect input data for
+ * - initial auto-detection, or
+ * - background scanning for PCM data, or
+ * - SYNC check for bitstream
+ * - return auto-detection status (SYNC detected, SYNC loss, etc)
+============================================================================*/
+Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats)
+{
+ Int ioDataErr, retVal;
+ ioDataCtl_t ioDataCtl;
+
+ // Perform auto-detection inside I/O DATA component
+ ioDataErr = ioDataProcess(pInp->hIoData);
+
+ if(ioDataErr == IODATA_NO_ERR) {
+ // Normal operation - check auto-detection status
+ ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
+ ioDataControl(pInp->hIoData, &ioDataCtl);
+
+ *pAutoDetStats = ioDataCtl.param.autoDetStats;
+
+ retVal = ASIT_NO_ERR;
+ }
+ else if(ioDataErr == IODATA_ERR_IOBUF_UNDERFLOW) {
+ // Input buffer underflows - there is no enough data to process.
+ // This is not error and no action is needed.
+ pInp->numUnderflow += 1; // debug
+
+ retVal = ASIT_ERR_INPBUF_UNDERFLOW;
+ }
+ else {
+ // Something is wrong: print error log and return
+ //printf("IODATA processing error!\n");
+ retVal = ASIT_ERR_INPDATA_PROC;
+ }
+
+ return retVal;
+} /* asitInputDataProcess */
+
+/*============================================================================
+ * Mapping ASIT Events to Decoding Messages
+============================================================================*/
+UInt asitEventsToDecMsg(UInt asitEvents)
+{
+ UInt decMsg = 0;
+
+ if (asitEvents & ASIT_EVTMSK_INPDATA) {
+ // Input data event
+ decMsg |= DEC_MSGMSK_INPDATA;
+ }
+
+ // temp, simulation
+ //if(asitEvents & ASIT_EVTMSK_INFOACK) {
+ // decMsg |= DEC_MSGMSK_INFOACK;
+ //}
+
+ // temp, simulation
+ //if(asitEvents & ASIT_EVTMSK_DECACK) {
+ // decMsg |= DEC_MSGMSK_DECACK;
+ //}
+
+ if (asitEvents & ASIT_EVTMSK_RXACK)
+ {
+ // Receive acknowledge message event
+ decMsg |= DEC_MSGMSK_RXACK;
+ }
+
+ return decMsg;
+} /* asitEventsToDecMsg */
/*===========================================================================
* Initialize I/O components for input processing
============================================================================*/
-int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
+int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
{
- // Initialize I/O BUFF and I/O PHY components for input task
ioBuffParams_t ioBuffParams;
ioPhyParams_t ioPhyParams;
ioDataParam_t ioDataCfg;
+ ioPhyCtl_t ioPhyCtl;
- ioBuffParams.base = pInpBuf->inpBufConfig.base.pVoid;
- ioBuffParams.size = pInpBuf->inpBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
- ioBuffParams.sync = IOBUFF_WRITE_SYNC;
- ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
- if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
- return (-1); // to remove magic number
- }
+ if (pInpIo->hMcaspChan != NULL)
+ {
+ //pInpIo->phyXferSize = INPUT_FRAME_SIZE_DEF;
+ pInpIo->phyXferSize = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF * WORD_SIZE_BITSTREAM;
+
+ if (pInpIo->firstTimeInit) {
+ TRACE_VERBOSE0("Initialize I/O BUFF and I/O PHY.");
+ ioBuffParams.base = pInpBuf->inpBufConfig.base.pVoid;
+ ioBuffParams.size = pInpBuf->inpBufConfig.allocation / STRIDE_WORST_CASE
+ * STRIDE_WORST_CASE;
+ ioBuffParams.sync = IOBUFF_WRITE_SYNC;
+ ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
+ if (ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
+ return (ASIT_ERR_IOBUFF_INIT); // to remove magic number
+ }
- ioPhyParams.ioBuffHandle = pInpIo->hIoBuff;
- ioPhyParams.xferFrameSize = INPUT_FRAME_SIZE_DEF;
- ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
- ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_WRITE;
- if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
- return (-1); // to remove magic number
- }
+ ioPhyParams.ioBuffHandle = pInpIo->hIoBuff;
+ ioPhyParams.xferFrameSize = pInpIo->phyXferSize;
+ ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
+ ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_WRITE;
+ if (ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+ return (ASIT_ERR_IOPHY_INIT); // to remove magic number
+ }
- ioDataCfg.ioBuffHandle = pInpIo->hIoBuff;
- ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
- ioDataCfg.frameLengthsIEC = (uint_least16_t *)&iecFrameLength[0];
- ioDataCfg.frameLengthPCM = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
- ioDataCfg.frameLengthDef = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
- ioDataCfg.ibMode = pInpBuf->inpBufConfig.pBufStatus->mode;
- ioDataCfg.zeroRunRestart = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
- ioDataCfg.zeroRunTrigger = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
-
- if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
- return (-1); // to remove magic number
- }
+ pInpIo->numPrimeXfers = NUM_PRIME_XFERS;
+ }
+
+ /* Reinitialize I/O DATA every time when ASIT restarts */
+ TRACE_VERBOSE0("Initialize I/O DATA.");
+ ioDataCfg.ioBuffHandle = pInpIo->hIoBuff;
+ ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
+ ioDataCfg.frameLengthsIEC = (uint_least16_t *)&iecFrameLength[0];
+ ioDataCfg.frameLengthPCM = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF;
+ ioDataCfg.frameLengthDef = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF;
+ ioDataCfg.ibMode = pInpBuf->inpBufConfig.pBufStatus->mode;
+ ioDataCfg.zeroRunRestart = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
+ ioDataCfg.zeroRunTrigger = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
+
+ if (ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
+ return (ASIT_ERR_IODATA_INIT); // to remove magic number
+ }
+
+ if (pInpIo->firstTimeInit) {
+ /* Initialize I/O BUFF and I/O PHY only when input interface changes. */
+ TRACE_VERBOSE0("Prime I/O PHY.");
+
+ // Start I/O physical layer by priming McASP LLD for input
+ asitIoPhyPrime(pInpIo);
+
+ pInpIo->firstTimeInit = FALSE;
+ }
+ else {
+ // Reconfigure I/O PHY transfer size
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = pInpIo->phyXferSize;
+ ioPhyControl(pInpIo->hIoPhy, &ioPhyCtl);
+ #if 0
+ // If previous stream before reset was PCM, reconfigure McASP LLD to receive 16-bit packed bits
+ if (!pInpIo->swapData) {
+ Int mcaspErr;
+ mcaspErr = mcaspRecfgWordWidth(pInpIo->hMcaspChan, Mcasp_WordLength_16);
+ if(mcaspErr != Aud_EOK) {
+ return ASIT_ERR_MCASP_CFG;
+ }
- pInpIo->numPrimeXfers = NUM_PRIME_XFERS;
- pInpIo->phyXferSize = ioPhyParams.xferFrameSize;
- //pInpIo->switchHangOver = 0;
- pInpIo->preSyncState = IODATA_SYNC_NONE;
+ // Start swapping data
+ pInpIo->swapData = TRUE;
+ TRACE_VERBOSE0("Reconfigure McASP word length and start swapping data.");
+ }
+ #endif
+ // Start PHY transfer
+ TRACE_VERBOSE0("Start I/O PHY transfer.");
+ asitPhyTransferStart(pInpIo);
+ }
+ }
return 0;
-} /* asipIoCompsInit */
+} /* asitIoCompsInit */
/*======================================================================================
- * This function initializes ASIP processing
+ * This function initializes ASIT processing
*====================================================================================*/
-void asipProcInit(PAF_AST_IoInp *pInp, asipDecProc_t *pDec)
+void asitProcInit(PAF_AST_IoInp *pInp, asipDecProc_t *pDec)
{
- pInp->swapData = SWAP_INPUT_DATA;
- pInp->asipProcState = ASIP_SOURCE_DETECTION;
- //pInp->switchHangOver = 0;
-
+// pInp->swapData = TRUE;
+ pInp->pcmSwitchHangOver = INPUT_SWITCH_HANGOVER;
pDec->initDone = FALSE;
+ pInp->numFrameReceived = 0;
}
/*======================================================================================
* I/O physical layer prime operation required by McASP LLD
*====================================================================================*/
-void asipIoPhyPrime(PAF_AST_IoInp *pInp)
+void asitIoPhyPrime(PAF_AST_IoInp *pInp)
{
Int32 count;
//pInp->numXferStart++;
#endif
}
-} /* asipIoPhyPrime */
+} /* asitIoPhyPrime */
-/*======================================================================================
- * This function pends on I/O PHY transfer for the input task
- *====================================================================================*/
-void asipPhyTransferPend()
-{
- // asipSemRx needs to be placed into some data structure
- Semaphore_pend(asipSemRx, BIOS_WAIT_FOREVER);
-} /* asipPhyTransferPend */
/*======================================================================================
* This function marks the I/O PHY transfer as complete
*====================================================================================*/
-void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo)
+void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo)
{
// Mark underlining I/O BUFF write complete and swap data if needed
ioPhyXferComplete(pInpIo->hIoPhy, pInpIo->swapData);
-} /* asipPhyTransferComplete */
+} /* asitPhyTransferComplete */
+#if 0
+Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize)
+{
+ ioPhyCtl_t ioPhyCtl;
+ Int mcaspErr;
+
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = xferSize;
+ ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
+
+ pInp->phyXferSize = ioPhyCtl.params.xferFrameSize;
+
+ if(!pInp->swapData) {
+ // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
+ mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
+ if(mcaspErr != Aud_EOK) {
+ return ASIT_ERR_MCASP_CFG;
+ }
+
+ // Start swapping data
+ pInp->swapData = TRUE;
+ }
+
+ return ASIT_NO_ERR;
+
+} /* asitRecfgPhyXfer */
+#endif
/*======================================================================================
* McASP LLD call back function
{
/* post semaphore */
if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
- Semaphore_post(asipSemRx);
+ //Semaphore_post(asipSemRx);
+ Event_post(gAsitEvtHandle, ASIT_EVTMSK_INPDATA);
} else {
; // intermediate packet due to buffer wrapping around
}
return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
}
+#if 0
/*======================================================================================
* This function restarts McASP LLD channel for input
*====================================================================================*/
-void asipMcaspRxRestart(void)
+void asipMcaspRxRestart(PAF_AST_IoInp *pInpIo)
{
mcaspRxReset();
mcaspRxCreate();
}
+#endif
/*======================================================================================
* This function starts an I/O PHY transfer
*====================================================================================*/
-void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
+void asitPhyTransferStart(PAF_AST_IoInp *pInpIo)
{
+ Int ioPhyErr;
+
if(asipCheckMcaspRxOverrun(pInpIo->hMcaspChan)) {
#ifdef ASIP_DEBUG
pInpIo->numInputOverrun++;
#endif
- asipMcaspRxRestart();
+ //asipMcaspRxRestart(pInpIo);
+ System_abort("\nMcASP for input overruns! %d!\n");
}
else {
- if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
+ ioPhyErr = ioPhyXferSubmit(pInpIo->hIoPhy);
+ //if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
+ if(ioPhyErr!=IOPHY_NOERR){
+ printf("\n I/O PHY ioPhyXferSubmit fails with error %d!\n", ioPhyErr);
// Input buffer overflows!
- printf("\nInput buffer overflows!\n");
+ //printf("\nInput buffer overflows!\n");
exit(0);
}
else {
}
Int d10Initialized = 0;
-//extern Audk2g_STATUS mcaspAudioConfig(void);
-extern void McaspDevice_init(void);
+//extern Aud_STATUS mcaspAudioConfig(void);
+//extern void McaspDevice_init(void);
/*======================================================================================
* This function initializes HW interface and selects the right device for input
*====================================================================================*/
-Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp)
+Int asitSelectDevices(
+ const PAF_ASIT_Patchs *pQ,
+ PAF_AST_Config *pAstCfg,
+ PAF_AST_IoInp *pInp
+)
{
- Audk2g_STATUS status;
-
- //more configuration is needed to abstract out D10
- if(!d10Initialized) {
- /* Initialize McASP HW details */
- McaspDevice_init();
-
- D10_init();
+ Aud_STATUS status;
+ const PAF_SIO_Params *pInPrms;
+ mcaspLLDconfig *pLldCfg;
+ mcaspLLDconfig *pReqLldCfg;
+ Ptr mcaspChanHandle;
+ Int zMD;
+ Int interface;
+ const PAF_SIO_Params *pD10Params;
-#ifdef INPUT_SPDIF
- // Input is DIR
- status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
-#else
- // Input is HDMI
- status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
-#endif
- if(status != Audk2g_EOK) {
- Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
- return ASIP_ERR_D10_CFG;
+ zMD = pAstCfg->masterDec;
+
+ interface = pAstCfg->xInp[zMD].inpBufStatus.sioSelect; // obtain SIO select for input
+
+ if (interface >= 0)
+ {
+ // Positive value for interface: new Input SIO update request has been received via alpha command.
+ // Negative value for interface: no new Input SIO update request has been received,
+ // previous requests have been processed.
+
+ // check for valid index into device array
+ if (interface >= pQ->devinp->n) // DEVINP_N
+ {
+ interface = 0; // treat as device InNone
}
- audk2g_delay(50000); // Without delay between these 2 calls system aborts.
-
- /* Initialize McASP module */
- status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c
- if(status != Audk2g_EOK) {
- Log_info0("McASP Configuration Failed!\n");
- return ASIP_ERR_MCASP_CFG;
+
+ //
+ // Deactivate currently active interface
+ //
+ if (pInp->hMcaspChan != NULL) // non-NULL McASP LLD channel handle indicates there's an active interface
+ {
+ d10Initialized = 0; // indicate no Input selected
+
+ // check McASP LLD control API
+ mcaspControlChan(pInp->hMcaspChan, MCASP_CHAN_RESET, NULL); // Rx reset channel
+ //mcaspControlChan(pInp->hMcaspChan, MCASP_DEVICE_RESET, NULL); // Reset Tx/Rx channel
+
+ // Delete McASP LLD channel
+ status = mcaspDeleteChan(pInp->hMcaspChan);
+ if (status != Aud_EOK)
+ {
+ Log_info0("asitSelectDevices(): McASP channel deletion failed!\n");
+ return ASIP_ERR_MCASP_CFG;
+ }
+
+ pInp->hMcaspChan = NULL; // reset active McASP LLD handle
+ if (pInp->pRxParams != NULL) // sanity check, pInp->pRxParams should be non NULL if pInp->hMcaspChan is non NULL
+ {
+ pInPrms = (const PAF_SIO_Params *)pInp->pRxParams;
+ pLldCfg = (mcaspLLDconfig *)pInPrms->sio.pConfig; // get pointer to active McASP LLD configuration
+ pLldCfg->hMcaspChan = NULL; // reset McASP LLD handle for active McASP LLD configuration
+ pInp->pRxParams = NULL; // reset pointer to active D10 parameters
+ }
+ else
+ {
+ // This is a programming error
+ SW_BREAKPOINT; // debug
+ }
}
- pInp->hMcaspChan = hMcaspRxChan;
- d10Initialized = 1;
+ //
+ // Activate requested interface
+ //
+ pD10Params = (const PAF_SIO_Params *)pQ->devinp->x[interface]; // get D10 parameters for selected interface
+ if (pD10Params != NULL)
+ {
+ //
+ // Requested device is other than InNone
+ //
+
+ // Initialize Tx clock mux
+ D10_initClkMux((void *)pD10Params);
+
+ pReqLldCfg = (mcaspLLDconfig *)pD10Params->sio.pConfig;
+ if (pReqLldCfg->hMcaspChan == NULL)
+ {
+ // Create McASP LLD channel
+ mcaspChanHandle = NULL;
+ status = mcasplldChanCreate(pReqLldCfg, &mcaspChanHandle);
+ if (status != Aud_EOK)
+ {
+ Log_info0("asitSelectDevices(): McASP channel creation failed!\n");
+ return ASIP_ERR_MCASP_CFG;
+ }
+
+ pReqLldCfg->hMcaspChan = mcaspChanHandle; // set McASP LLD handle for requested McASP LLD configuration
+ pInp->pRxParams = (const void *)pD10Params; // set pointer to active D10 parameters
+ pInp->hMcaspChan = pReqLldCfg->hMcaspChan; // set active McASP LLD handle
+
+ // configure stride according to selected McASP LLD configuration
+ pInp->stride = pReqLldCfg->mcaspChanParams->noOfSerRequested *
+ pReqLldCfg->mcaspChanParams->noOfChannels;
+
+ pInp->firstTimeInit = TRUE; // set flag for IO Phy & Buff initialization
+
+ d10Initialized = 1; // indicate Input selected
+ }
+ }
+ else
+ {
+ //
+ // Requested device is InNone
+ //
+ pInp->hMcaspChan = NULL; // reset active McASP LLD handle
+ pInp->pRxParams = NULL; // reset pointer to active D10 parameters
+ }
+
+ // indicate SIO update request processed
+ pAstCfg->xInp[zMD].inpBufStatus.sioSelect = interface | 0x80;
}
- /////////////// TODO: HW interface selection and initialization //////////////
- ////// to add what PAF_ASIT_selectDevices() does /////////
-#ifdef IO_HW_INTERFACE
- pInp->pRxParams = pQ->devinp->x[IO_HW_INTERFACE];
-#else
- pInp->pRxParams = NULL;
-#endif
+ if (pInp->hMcaspChan != NULL) // non NULL indicates there's an active interface
+ {
+ if (pInp->pRxParams != NULL) // sanity check, this should be non NULL if pInp->hMcaspChan is non NULL
+ {
+ pInPrms = (const PAF_SIO_Params *)pInp->pRxParams;
+ pLldCfg = (mcaspLLDconfig *)pInPrms->sio.pConfig; // get currently active McASP LLD configuration
+ if (pLldCfg != NULL) // sanity check, this should be non NULL if pInp->hMcaspChan is non NULL
+ {
+ // Configure McASP to receive 16/32-bit data according to default configuration
+ mcaspRecfgWordWidth(pInp->hMcaspChan, pLldCfg->mcaspChanParams->wordWidth);
+
+ // Set flag to swap HDMI data if it is 4xI2S and word length is 16
+ if ((pLldCfg->mcaspChanParams->wordWidth == Mcasp_WordLength_16) &&
+ (pLldCfg->mcaspChanParams->noOfSerRequested == 4))
+ {
+ pInp->swapData = TRUE;
+ }
+ else
+ {
+ pInp->swapData = FALSE;
+ }
+ }
+ else
+ {
+ // This is a programming error
+ SW_BREAKPOINT; // debug
+ }
- return 0;
-} /* asipSelectDevices */
+ }
+ else
+ {
+ // This is a programming error
+ SW_BREAKPOINT; // debug
+ }
+ }
+
+ return ASIP_NO_ERR;
+} /* asitSelectDevices */
/*======================================================================================
* This function updates input status
*====================================================================================*/
-Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
+Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
PAF_InpBufConfig *pInpBuf)
{
Int asipErrno;
}
-void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp)
+/*==============================================================================
+ * This function updates input buffer config based on frame information provided
+ * by I/O DATA.
+ ==============================================================================*/
+void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp)
{
PAF_InpBufConfig *pBufConfig;
ioDataCtl_t ioDataCtl;
pBufConfig = &(pAstCfg->xInp[pAstCfg->masterDec].inpBufConfig);
- //JXTODO: do we need to gate here? - No, since ARM won't read until it receives message
+ //JXTODO: do we need to gate here?
//key = GateMP_enter(gateHandle);
pBufConfig->base.pVoid = ioDataCtl.param.dataReadInfo.buffBase;
// Leave the gate
//GateMP_leave(gateHandle, key);
+
+ TRACE_TERSE2("Frame start address: 0x%x., preamble: 0x%x",
+ (UInt)ioDataCtl.param.dataReadInfo.startAddress,
+ *(UInt *)ioDataCtl.param.dataReadInfo.startAddress);
}
/*==============================================================================
* Decide source after SYNC is found, i.e. either bitstream preamble is detected
* or it times out to PCM.
==============================================================================*/
-Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp,
+Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp,
ioDataAutoDetStat_t *autoDetStatus)
{
Int sourceConfig, sourceSelect, sourceProgram;
Int zMD;
char asipMsgBuf[ASP_MSG_BUF_LEN];
+ Int status;
// Get the configured source
zMD = pAstCfg->masterDec;
- sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC);
+ sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+ GATEMP_INDEX_DEC);
if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
if (sourceConfig == PAF_SOURCE_DSD1 || sourceConfig == PAF_SOURCE_DSD2 ||
}
// write the decided source program to memory
- sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram, GATEMP_INDEX_DEC);
+ sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram,
+ GATEMP_INDEX_DEC);
// now that we have some input classification, and possibly an outstanding
// input frame, we determine whether or not to call decodeProcessing and with
// If autodetecting, decoding only PCM, and input is PCM then decode.
case PAF_SOURCE_PCMAUTO:
if (sourceProgram == PAF_SOURCE_PCM) {
- sourceSelect = sourceProgram; // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
+ // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
+ sourceSelect = sourceProgram;
}
break;
// if we didn't find any matches then skip
if (sourceSelect == PAF_SOURCE_NONE) {
TRACE_VERBOSE0("TaskAsip: no matching source type, continue");
- return ASIP_ERR_NO_MATCHING_SOURCE;
+ return ASIT_ERR_NO_MATCHING_SOURCE;
}
-#ifndef PCM_LOOPBACK_TEST
+#ifndef DEBUG_SKIP_DECODING
// send source select message to slave
*(Int32 *)&asipMsgBuf[0] = sourceSelect;
- if(AspMsgSend(ASP_SLAVE_DEC_SOURCE_SELECT, ASP_MASTER_DEC_SOURCE_SELECT_DONE,
- asipMsgBuf, NULL) != ASP_MSG_NO_ERR) {
+ status = AspMsgSnd(gPAF_ASIT_config.hAspMsgMaster, ASP_SLAVE_DEC_SOURCE_SELECT, asipMsgBuf);
+ if (status != ASP_MSG_NO_ERR)
+ {
TRACE_VERBOSE0("TaskAsip: error in sending SOURCE_SELECT message");
SW_BREAKPOINT;
}
+ status = AspMsgRcvAck(gPAF_ASIT_config.hAspMsgMaster, ASP_MASTER_DEC_SOURCE_SELECT_DONE, NULL, TRUE);
+ if (status != ASP_MSG_NO_ERR)
+ {
+ TRACE_VERBOSE0("TaskAsip: error in receiving SOURCE_SELECT ack message");
+ SW_BREAKPOINT;
+ }
#endif
pInp->sourceSelect = sourceSelect;
pInp->sourceProgram = sourceProgram;
- return ASIP_NO_ERR;
-} /* asipDecideSource */
+ return ASIT_NO_ERR;
+} /* asitDecideSource */
/*==============================================================================
* After SYNC is found, i.e. either bitstream preamble is detected or it times
// Decide frame length for I/O DATA and I/O PHY
if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
// For PCM, I/O frame length is decode frame length multiplied by stride
- ioFrameLength = decFrameLength * INPUT_STRIDE;
+ ioFrameLength = decFrameLength * pInp->stride;
pBufConfig->sizeofElement = WORD_SIZE_PCM;
pBufConfig->frameLength = pBufConfig->lengthofData = ioFrameLength;
//ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
// Stop swapping data
- pInp->swapData = FALSE;
+ //pInp->swapData = FALSE;
}
else {
// For bitstream, I/O frame length is the frame length of the bitstream
uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
ioFrameLength = iecFrameLength[pc];
- /*
- if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
- pDevExt->sourceProgram = PAF_SOURCE_DXP; // LBR is 23
-
- if (pc == 1)
- pDevExt->elementSize = 4288;
- else if (pc == 0x11) {
- pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
- pDevExt->lengthofData = pDevExt->frameLength;
- }
- */
+/*
+ if( (pc == 0x11) && (DTSHDSubType == 3)
+ && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
+ pDevExt->sourceProgram = PAF_SOURCE_DXP; // LBR is 23
+
+ if (pc == 1)
+ pDevExt->elementSize = 4288;
+ else if (pc == 0x11) {
+ pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
+ pDevExt->lengthofData = pDevExt->frameLength;
+ }
+*/
pBufConfig->sizeofElement = WORD_SIZE_BITSTREAM;
pBufConfig->frameLength = ioFrameLength;
pInp->phyXferSize = ioFrameLength*WORD_SIZE_BITSTREAM;
}
- pBufConfig->stride = INPUT_STRIDE; // common for PCM and bitstream
+ pBufConfig->stride = pInp->stride; // common for PCM and bitstream
// Configure I/O PHY transfer size
ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
}
//JXTODO: decide what to do with hRxSio
- pAstCfg->xInp[zMD].hRxSio = pInp->hIoData; //temporary - does ARM use hRxSio or just check if it is not NULL?
+ //temporary - does ARM use hRxSio or just check if it is not NULL?
+ pAstCfg->xInp[zMD].hRxSio = pInp->hIoData;
pAstCfg->xInp[zMD].pInpBuf = &(pAstCfg->xInp[zMD].inpBufConfig);
- return ASIP_NO_ERR;
+ return ASIT_NO_ERR;
} /* asitUpdateIoComps */
-Int asipBypassIoData(PAF_AST_IoInp *pInp)
-{
- // When switching to PCM, McASP RFMT register will be modified,
- // which will cause all 0's in one McASP LLD transfer. This will
- // be detected as loss of SYNC by auto detection. To prevent that,
- // skip I/O DATA process for hangover period so that this all 0's
- // frame will not be seen by auto-detection. Also, playing out PCM
- // needs to be skipped as well, to prevent from playing out garbage
- // (16-bit packed data).
- void *buff1, *buff2;
- size_t size1, size2;
-
- // Get read pointers (or sub-buffers) of the input buffer
- if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
- &buff1, &size1, &buff2, &size2)
- == IOBUFF_ERR_UNDERFLOW) {
- pInp->numUnderflow += 1;
-
- // Return since there is no enough data to process
- return ASIP_NO_ERR;
- }
-
- ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
-
- if(buff2 != NULL) {
- ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
- }
-
- return ASIP_NO_ERR;
-}
-
-/*=============================================================================
- * Main function of ASIP processing
- *============================================================================*/
-Int asipProcessing(const PAF_ASIT_Params *pP,
- const PAF_ASIT_Patchs *pQ,
- PAF_ASIT_Config *pAsitCfg)
-
-{
- PAF_AST_Config *pAstCfg;
- int ioDataStatus, asipStatus, zMI;
- ioDataAutoDetStat_t autoDetStatus;
- Audk2g_STATUS mcaspStatus;
- ioDataCtl_t ioDataCtl;
- ioPhyCtl_t ioPhyCtl;
- PAF_AST_IoInp *pInp; /* Input I/O components */
-
- pAstCfg = pAsitCfg->pAstCfg;
- zMI = pAstCfg->masterDec;
- pInp = &pAsitCfg->pIoInp[zMI]; // pointer to input I/O components
-
- if(pInp->asipProcState == ASIP_SWITCH_TO_PCM) {
- // Bypass I/O data processing due to McASP LLD work around
- // (refer to comments inside the function)
- asipStatus = asipBypassIoData(pInp);
- if(asipStatus != ASIP_NO_ERR) {
- return asipStatus;
- }
- }
- else {
- // Perform auto-detection when not switching
- ioDataStatus = ioDataProcess(pInp->hIoData);
- if(ioDataStatus == IODATA_ERR_IOBUF_UNDERFLOW) {
- // Input buffer underflows - no action is needed
- pInp->numUnderflow += 1;
-
- // Return since there is no enough data to process
- return ASIP_NO_ERR;
- }
- else if(ioDataStatus != IODATA_NO_ERR) {
- // Something is wrong: print error log and return
- //printf("IODATA processing error!\n");
- return ASIP_ERR_AUTO_DETECION;
- }
- else {
- // Normal operation - check auto-detection status
- ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
- ioDataControl(pInp->hIoData, &ioDataCtl);
-
- autoDetStatus = ioDataCtl.param.autoDetStats;
- }
- }
-
- switch(pInp->asipProcState)
- {
- case ASIP_SOURCE_DETECTION:
- // zero out the output buffer
- rxDecodePlayZero(pInp);
-
- // Mark I/O DATA read complete as auto-detection finishes reading input data now.
- ioDataReadComplete(pInp->hIoData);
-
- if( autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
- || autoDetStatus.syncState == IODATA_SYNC_PCM) {
- // Decide input source and inform decoder
- asipStatus = asipDecideSource(pAstCfg, pInp, &autoDetStatus);
- if(asipStatus != ASIP_NO_ERR) {
- return asipStatus;
- }
- else {
- // Update I/O components and input buffer config
- asitUpdateIoComps(pP, pAstCfg, pInp, &autoDetStatus);
-
- // set to unknown so that we can ensure, for IOS purposes, that sourceDecode = NONE
- // iff we are in this top level state machine and specifically not in decodeProcessing
-#ifndef PCM_LOOPBACK_TEST
- pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
-#endif
-
- if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
- // Input is bit stream: go to decoding
- pInp->asipProcState = ASIP_DECODE;
- //pInp->numFrameReceived = 1;
- }
- else {
- // Input is PCM: stop swapping data
- pInp->swapData = FALSE;
-
- // Reconfigure McASP LLD to transfer 32-bit unpacked data
- mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
- if(mcaspStatus != Audk2g_EOK) {
- return ASIP_ERR_MCASP_CFG;
- }
-
- // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
- // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
- ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
-
- // Go to transition state to switch to PCM
- pInp->asipProcState = ASIP_SWITCH_TO_PCM;
- pInp->pcmSwitchHangOver = INPUT_SWITCH_HANGOVER;
- //pInp->numPcmFrameReceived = 0;
- }
- }
-
- pInp->numFrameReceived = 0;
- pInp->preSyncState = autoDetStatus.syncState;
- }
- else {
- // Source is still unknown - take no action
- ;
- }
- break;
-
- case ASIP_SWITCH_TO_PCM:
- // zero out the output buffer
- rxDecodePlayZero(pInp);
-
- pInp->pcmSwitchHangOver--;
- if(pInp->pcmSwitchHangOver == 0) {
- pInp->asipProcState = ASIP_DECODE;
- }
- break;
-
- case ASIP_DECODE:
- if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
- // SYNC lost: change I/O PHY transfer size to default for auto-detection
- ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
- ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
- ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
- pInp->phyXferSize = ioPhyCtl.params.xferFrameSize;
-
- if(pInp->preSyncState == IODATA_SYNC_PCM) {
- // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
- mcaspStatus = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
- if(mcaspStatus != Audk2g_EOK) {
- return ASIP_ERR_MCASP_CFG;
- }
-
- // Start swapping data
- pInp->swapData = TRUE;
- }
-
- // Inform decoder to complete decoding previous frame
- pInp->sourceSelect = PAF_SOURCE_NONE;
-
- pInp->numFrameReceived = 0;
- pInp->asipProcState = ASIP_SOURCE_DETECTION;
- }
- else {
- pInp->numFrameReceived += 1; // for debugging
-
- // Communicate input stream information to decoder through input buffer configuration
- asipUpdateInpBufConfig(pAstCfg, pInp);
- }
-
-#ifndef PCM_LOOPBACK_TEST
- asipStatus = asipDecodeProcessing(pP, pQ, pAsitCfg, pInp->sourceSelect);
- if(asipStatus != ASIP_NO_ERR) {
-
- // FL: send dec exit message to slave
- if( AspMsgSend(ASP_SLAVE_DEC_EXIT, ASP_MASTER_DEC_EXIT_DONE, NULL, NULL)
- != ASP_MSG_NO_ERR)
- {
- TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
- SW_BREAKPOINT;
- }
-
- return asipStatus;
- }
-#else
- if(autoDetStatus.syncState == IODATA_SYNC_PCM) {
- rxDecodePcm(pInp); // for PCM loopback testing
- }
-#endif
- // Mark I/O DATA read complete as decoder finishes reading input now.
- ioDataReadComplete(pInp->hIoData);
-
- break;
-
- default:
- break;
- }
-
- return 0;
-} /* asipProcessing */
-
-/*======================================================================================
- * This function decides the input source based on auto-detection information.
- *====================================================================================*/
-//Int asipDecideSource(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, asipDecProc_t *pDec)
-//{
-
-//}
-
-
+#if 0
#ifndef IO_LOOPBACK_TEST
#if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH
U8 pcmbuf[OUTPUT_FRAME_SIZE];
}
- return ASIP_NO_ERR;
+ return ASIT_NO_ERR;
}
-Int rxDecodeBitStream(PAF_AST_IoInp *pInp)
+
+Int rxDecodePlayZero(PAF_AST_IoInp *pInp)
{
- return ASIP_NO_ERR;
+ return ASIT_NO_ERR;
}
+#endif
+#endif
-Int rxDecodePlayZero(PAF_AST_IoInp *pInp)
+Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents)
{
- return ASIP_NO_ERR;
+ TRACE_VERBOSE2("ASIT events error: actual events are: %d, expected events are: %d.",
+ actualEvents, expectedEvents);
+
+ return ASIT_ERR_EVENTS;
}
+
+void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr)
+{
+ //UInt events;
+
+ if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
+ TRACE_VERBOSE0("ASIT error handling: input buffer underflows. No actions needed.");
+ }
+
+ if(asitErr == ASIT_AUTODET_TIME_OUT) {
+ pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+ pAsitCfg->pIoInp[0].numAsitRestart++;
+ TRACE_VERBOSE1("ASIT error %d handling finished. Go to state ASIT_RESET.", asitErr);
+ }
+
+ if(asitErr == ASIT_ERR_DECODE_QUIT) {
+ TRACE_VERBOSE0("ASIT error handling: DECODE_QUIT - clear INPDATA event.");
+#if 0
+ // Pend on INPTDATA event that should have been posted before decoding quits.
+ events = Event_pend(asitEvent, ASIT_EVTMSK_NONE, ASIT_EVTMSK_INPDATA,
+ BIOS_WAIT_FOREVER);
+
+ // Marks I/O PHY transfer and I/O BUFF write complete
+ asitPhyTransferComplete(&pAsitCfg->pIoInp[0]);
+
+ // Keep I/O BUFF read pointers going
+ asitBypassIoData(&pAsitCfg->pIoInp[0]);
#endif
+ pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+ pAsitCfg->pIoInp[0].numAsitRestart++;
+ TRACE_VERBOSE1("ASIT error %d handling finished. Go to state ASIT_RESET.", asitErr);
+ }
-void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno)
+ if(asitErr == ASIT_ERR_EVENTS) {
+ pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+ pAsitCfg->pIoInp[0].numAsitRestart++;
+ TRACE_VERBOSE1("ASIT error %d handling: events error. Go to state ASIT_RESET.", asitErr);
+ }
+
+ return;
+} /* asitErrorHandling */
+
+
+//////////////////////////////////////////////////////////////////////////////
+void asitPostInfoEvent()
{
+ Event_post(gAsitEvtHandle, ASIT_EVTMSK_INFOACK);
+}
+void asitPostDecEvent()
+{
+ Event_post(gAsitEvtHandle, ASIT_EVTMSK_DECACK);
}
+//////////////////////////////////////////////////////////////////////////////
/* Nothing past this line */