From: Frank Livingston Date: Fri, 16 Feb 2018 23:02:23 +0000 (-0600) Subject: Merge branch 'dev_pasdk_frank_pasdk516AsotRefactoring' into dev_pasdk_pasdk29Integration X-Git-Url: https://git.ti.com/gitweb?p=processor-sdk%2Fperformance-audio-sr.git;a=commitdiff_plain;h=454fde41e23f4de18f44877b72b92ea4792cb2cf;hp=dab0778018555672b318c9bd2c6f567691b2a2bd Merge branch 'dev_pasdk_frank_pasdk516AsotRefactoring' into dev_pasdk_pasdk29Integration --- diff --git a/pasdk/test_dsp/framework/audioStreamInpDec.c b/pasdk/test_dsp/framework/audioStreamInpDec.c index d2d2b4f2..cc48d809 100644 --- a/pasdk/test_dsp/framework/audioStreamInpDec.c +++ b/pasdk/test_dsp/framework/audioStreamInpDec.c @@ -52,36 +52,51 @@ All rights reserved. #include "ioPhy.h" #include "ioData.h" + +extern void asitPostInfoEvent(); // TODO: remove +extern void asitPostDecEvent(); // TODO: remove + enum { - INFO1, - INFO2, - DECODE, - QUIT + DEC_STATE_INFO_SND, + DEC_STATE_INFO_ACK_DECODE_SND, + DEC_STATE_DECODE_ACK, + DEC_STATE_QUIT }; -static Int decDecodeInit(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, - Int sourceSelect); -static Int decDecodeInfo(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, - PAF_ASIT_Config *pAsitCfg); -static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, - PAF_ASIT_Config *pAsitCfg, Int sourceSelect); +static Int decodeInit(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, + Int sourceSelect); + static Int decDecodeComplete(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg); -extern Int getFrameLengthSourceSel(const PAF_ASIT_Params *pP, Int8 sourceSelect); +static Int decErrorCheck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg, Int sourceSelect); +static Int decInfoSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg); +static Int decInfoAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg); +static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg); +static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg); +static Int decDecodeFinalTest(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg); +Int decCheckMajorAu(PAF_AST_Config *pAstCfg); + +Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf); +Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf); extern UInt32 gCbWrtAfErrCnt; - -Int asipDecodeInit( +Int decDecodeInit( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect) { Int errno; - errno = decDecodeInit(pP, pAsitCfg, sourceSelect); + errno = decodeInit(pP, pAsitCfg, sourceSelect); if(errno) { decDecodeComplete(pP, pAsitCfg); @@ -89,174 +104,251 @@ Int asipDecodeInit( return ASIP_ERR_DECODE_INIT; } + pAsitCfg->inpDec.majorAuFound = FALSE; + return ASIP_NO_ERR; } // ----------------------------------------------------------------------------- -// ASIT Processing Function - Decode Processing -// -// Name: asipDecodeProcessing -// Purpose: -// Return: Error number in standard form (0 on success). // ----------------------------------------------------------------------------- -Int asipDecodeProcessing( +Int decDecodeFsm( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, - Int sourceSelect) + Int sourceSelect, + UInt decMsg) { - PAF_AST_Config *pAstCfg; asipDecProc_t *pDec; - Int decError, retVal, getVal; /* error number */ - Int zMD, decProcDone; - Int8 tempVar8; + Int decErr, decDone; - pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration - zMD = pAstCfg->masterDec; pDec = &pAsitCfg->inpDec; - retVal = ASIP_NO_ERR; - - // Initialization for decode processing - if(!pDec->initDone) { - // Initialize decoder and send message to decoder - retVal = decDecodeInit(pP, pAsitCfg, pAsitCfg->pIoInp[zMD].sourceSelect); - if(retVal != ASIP_NO_ERR) { - decDecodeComplete(pP, pAsitCfg); - - return retVal; - } + TRACE_VERBOSE1("Entering decDecodeFsm with decMsg %d.", decMsg); - pDec->initDone = TRUE; + decErr = decErrorCheck(pP, pQ, pAsitCfg, sourceSelect); + if(decErr == DEC_ERR_ASPERR_ABORT) { + return decErr; } - - // Check if source has configured to NONE - tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), - GATEMP_INDEX_DEC); - if (tempVar8 == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) { - TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: sourceSelect == PAF_SOURCE_NONE"); - pAsitCfg->inpDec.state = QUIT; // skip processing, quit decoding - retVal = ASIP_ERR_DECODE_QUIT; + else if(decErr != DEC_NO_ERR) { + pDec->state = DEC_STATE_QUIT; } - - // Process commands (decode) - getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg); - if (getVal) { - retVal = ASIP_ERR_DECODE_COMMAND; - if (getVal == ASPERR_QUIT) { - TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: state = QUIT"); - - // Don't return if ASPERR_QUIT, but skip decode processing and quit - pAsitCfg->inpDec.state = QUIT; - } - else if (getVal == ASPERR_ABORT) { - TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: return getVal"); - - // Return here if ASPERR_ABORT - return retVal; - } - else { - /* ignore */; - } + else { + ; // No error } + // It is possible to go through the FSM multiple times: + // - Multiple messages may be received, INPDATA and DECACK. In this case, + // the FSM will process DECACK in state DEC_STATE_DECODE_ACK and then + // INPDATA in state DEC_STATE_INFO_SND. + // - DECACK is received after INPDATA. In this case, after DECACK is + // processed, we will spoof decMsg with INPDATA so that FSM will run + // again and process INPDATA in DEC_STATE_INFO_SND. do { - decProcDone = TRUE; - - switch(pAsitCfg->inpDec.state) + switch(pDec->state) { - case INFO1: - decError = decDecodeInfo(pP, pQ, pAsitCfg); - if (decError) { - //gAsipInfo1_PrimaryErrCnt++; - TRACE_TERSE1("INFO1: decError 0x%x after decodeInfo, primary timing", decError); - retVal = ASIP_ERR_DECODE_INFO1; + case DEC_STATE_INFO_SND: + if(decMsg != DEC_MSGMSK_INPDATA) { + // Only DEC_MSGMSK_INPDATA is expected in this state + decErr = DEC_ERR_WRONG_MSG; + } + else { + decMsg &= ~DEC_MSGMSK_INPDATA; // clear bit mask + + // Prepare and send INFO to decoder + decErr = decInfoSnd(pP, pQ, pAsitCfg); + if(decErr == DEC_NO_ERR) { + pDec->state = DEC_STATE_INFO_ACK_DECODE_SND; + TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_SND done."); } - else { - // Don't start decode until major access unit is found. - Int8 sourceDecode, sampleRate; + } + break; + + case DEC_STATE_INFO_ACK_DECODE_SND: + //if(decMsg != DEC_MSGMSK_INFOACK) { + // only DEC_MSGMSK_INFOACK is expected in this state + if((decMsg&DEC_MSGMSK_INFOACK) != DEC_MSGMSK_INFOACK) { + // During debugging, it is possible that INPDATA and INFOACK + // come at the same time (e.g. due to breaking point). + decErr = DEC_ERR_WRONG_MSG; + } + else { + decMsg &= ~DEC_MSGMSK_INFOACK; // clear the bit mask - sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), - GATEMP_INDEX_DEC); - sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), - GATEMP_INDEX_DEC); - if ( ( (sourceDecode == PAF_SOURCE_THD) || - (sourceDecode == PAF_SOURCE_DXP) || - (sourceDecode == PAF_SOURCE_DTSHD) ) && - ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) { - //gMajorAuMissed++; // debug - pAsitCfg->inpDec.frame++; - //pAsitCfg->inpDec.state = INFO1; // stay in this state + // Process the INFO acknowledgment from decoder + decErr = decInfoAck(pP, pQ, pAsitCfg); + if(decErr == DEC_NO_ERR) { + // Don't start decode until major access unit is found. + if(!pDec->majorAuFound) { + // Do we want to still check major AU after it is found? + // In old code, it was not checked again after it was found. + pDec->majorAuFound = decCheckMajorAu(pAsitCfg->pAstCfg); } - else { - decError = pP->fxns->decodeInfo1(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); - if(decError) { - retVal = ASIP_ERR_DECODE_INFO1; + + if(pDec->majorAuFound) { + // Major access unit is found. Send message to decoder to decode now. + decErr = decDecodeSnd(pP, pQ, pAsitCfg); + if(decErr == DEC_NO_ERR) { + pDec->state = DEC_STATE_DECODE_ACK; + + // Initialize decodeAckDelayed to FALSE - normally + // DECODE ACK comes after INPDATA. + pDec->decodeAckDelayed = FALSE; + + TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_DECODE_ACK."); } - else { - pAsitCfg->inpDec.state = DECODE; - decProcDone = FALSE; // go to DECODE state before return + } + else { + // No major access unit - go back to INFO. + pDec->frame++; + pDec->state = DEC_STATE_INFO_SND; + TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_INFO_SND."); + } + } + } + break; + + case DEC_STATE_DECODE_ACK: + // Two different messages may be received: DECACK (decode acknowledgment) + // or INPDATA (input data ready). + if(decMsg & DEC_MSGMSK_DECACK) { + decMsg &= ~DEC_MSGMSK_DECACK; + + // Process DECODE ACK from decoder + decErr = decDecodeAck(pP, pQ, pAsitCfg); + if(decErr == DEC_NO_ERR) { + // Decode finishes. Conduct final test. + decErr = decDecodeFinalTest(pP, pQ, pAsitCfg); + if(decErr == DEC_NO_ERR) { + pDec->frame++; + pDec->state = DEC_STATE_INFO_SND; + TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_DECODE_ACK done and going to DEC_STATE_INFO_SND."); + + // Check if DECACK comes late (after INPDATA) + if(pDec->decodeAckDelayed) { + pDec->decodeAckDelayed = FALSE; + + // Need to prepare and send INFO to decoder immediately. + // Becuase INPUT_DATA message is already received, + // we're just spoofing the message with INPDATA to + // run the FSM one more time. + decMsg |= DEC_MSGMSK_INPDATA; + + TRACE_VERBOSE0("decDecodeFsm: Info was delayed."); } } } - break; + } + else if(decMsg & DEC_MSGMSK_INPDATA) { + // If we're here, it means decode acknowledgment from decoder + // is delayed, i.e., a new frame of input data is ready before + // current frame decoding is finished. + decMsg &= ~DEC_MSGMSK_INPDATA; - case INFO2: - decError = decDecodeInfo(pP, pQ, pAsitCfg); - if (decError) { - //gAsipInfo1_PrimaryErrCnt++; - TRACE_TERSE1("INFO2: decError 0x%x after decodeInfo, primary timing", decError); - retVal = ASIP_ERR_DECODE_INFO2; - } - else { - pAsitCfg->inpDec.state = DECODE; - decProcDone = FALSE; // go to DECODE state before return - } - break; + // Do nothing but set a flag to postpone action. + pDec->decodeAckDelayed = TRUE; - case DECODE: - decError = decDecodeData(pP, pQ, pAsitCfg, sourceSelect); - if (decError) { - //gAsipDecodeErrCnt++; - TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE. decodeDecode err 0x%04x", decError); - retVal = ASIP_ERR_DECODE_DATA; - } - else { - decError = pP->fxns->decodeFinalTest(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); - if (decError) { - retVal = ASIP_ERR_DECODE_FINAL; - } - else { - pAsitCfg->inpDec.frame++; - pAsitCfg->inpDec.state = INFO2; - } - } - break; + TRACE_VERBOSE0("decDecodeFsm: receiving INPDATA in DEC_STATE_DECODE_ACK"); + } + else { + decErr = DEC_ERR_WRONG_MSG; + } + break; + + case DEC_STATE_QUIT: + //gAsipQuitCnt++; + TRACE_VERBOSE0("decDecodeFsm: state: DEC_STATE_QUIT"); + break; + + default: + break; + } /* switch */ + + // Loop through the FSM one more time if: + // - there are more real or spoofed messages to process, + // - and there is no error. + if((decMsg==0) || (decErr!=DEC_NO_ERR)) { + decDone = TRUE; + } + else { + decDone = FALSE; + } + } while(!decDone); - case QUIT: - //gAsipQuitCnt++; - Log_info0("TaskAsip: state=QUIT"); + // Error handling - complete decoding + if(decErr != DEC_NO_ERR) { + TRACE_VERBOSE1("decDecodeFsm: decErr %d, calling decDecodeComplete.", decErr); + decDecodeComplete(pP, pAsitCfg); + TRACE_VERBOSE0("decDecodeFsm: decDecodeComplete done."); + } - // Quit: - // - Set error number registers. - // - Exit state machine to "decode complete" processing. - TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: state: QUIT"); - break; + return decErr; +} /* decDecodeFsm */ - default: - break; - } /* switch */ +Int decErrorCheck(const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg, + Int sourceSelect +) +{ + Int retVal, getVal, zMD; + Int8 sourceConfig; - } while (!decProcDone); + retVal = DEC_NO_ERR; - if(retVal != ASIP_NO_ERR) { - decDecodeComplete(pP, pAsitCfg); + // Check if source has configured to NONE + zMD = pAsitCfg->pAstCfg->masterDec; + sourceConfig = sharedMemReadInt8(&(pAsitCfg->pAstCfg->xDec[zMD].decodeStatus.sourceSelect), + GATEMP_INDEX_DEC); + if (sourceConfig == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) { + TRACE_VERBOSE0("decDecodeFsm: sourceSelect == PAF_SOURCE_NONE"); + retVal = DEC_ERR_SOURCE_NONE; + } + + // Process commands (decode) + getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg); + if (getVal == ASPERR_QUIT) { + TRACE_VERBOSE0("decDecodeFsm. %d: state = QUIT"); + retVal = DEC_ERR_ASPERR_QUIT; + } + else if (getVal == ASPERR_ABORT) { + TRACE_VERBOSE0("decDecodeFsm. %d: return getVal"); + + // Return here if ASPERR_ABORT + retVal = DEC_ERR_ASPERR_ABORT; + } + else { + ; // No error } return retVal; -} /* asipDecodeProcessing */ +} /* decErrorCheck */ + + +Int decCheckMajorAu(PAF_AST_Config *pAstCfg) +{ + Int8 sourceDecode, sampleRate; + Int zMD; + + zMD = pAstCfg->masterDec; + + sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), + GATEMP_INDEX_DEC); + sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), + GATEMP_INDEX_DEC); + if ( ( (sourceDecode == PAF_SOURCE_THD) || + (sourceDecode == PAF_SOURCE_DXP) || + (sourceDecode == PAF_SOURCE_DTSHD) + ) + &&( sampleRate == PAF_SAMPLERATE_UNKNOWN) + ) { + return FALSE; + } + else { + return TRUE; + } +} /* decCheckMajorAu*/ // ----------------------------------------------------------------------------- @@ -272,7 +364,7 @@ Int asipDecodeProcessing( // * State information as per parent. // // ----------------------------------------------------------------------------- -static Int decDecodeInit( +static Int decodeInit( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect) @@ -287,8 +379,6 @@ static Int decDecodeInit( Int argIdx; Int8 tempVar8; char decMsgBuf[ASP_MSG_BUF_LEN]; - ioPhyCtl_t ioPhyCtl; - ioDataCtl_t ioDataCtl; pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration pInp = pAsitCfg->pIoInp; @@ -321,7 +411,6 @@ static Int decDecodeInit( if (pInp[zI].hIoPhy && tempVar8) { Uns gear; - Int frameLength; TRACE_VERBOSE1("AS%d: PAF_ASIT_decodeInit: initializing decode", as+zS); // write back Dec configuration @@ -390,7 +479,7 @@ static Int decDecodeInit( ioDataControl(pInp[zI].hIoData, &ioDataCtl); */ //JXTODO: do we need to update input status here again? - if (errno = asipUpdateInputStatus(pInp[zI].pRxParams, + if (errno = asitUpdateInputStatus(pInp[zI].pRxParams, &pAstCfg->xInp[zI].inpBufStatus, &pAstCfg->xInp[zI].inpBufConfig)) { return ASIP_ERR_INPUT_CFG; @@ -400,31 +489,139 @@ static Int decDecodeInit( pAsitCfg->inpDec.frame = 0; pAsitCfg->inpDec.block = 0; - pAsitCfg->inpDec.state = INFO1; + pAsitCfg->inpDec.state = DEC_STATE_INFO_SND; return ASIP_NO_ERR; } /* decDecodeInit */ + +Int decDecodeComplete( const PAF_ASIT_Params *pP, + PAF_ASIT_Config *pAsitCfg) +{ + PAF_AST_Config *pAstCfg; + Int as; /* Audio Stream Number (1, 2, etc.) */ + Int z; /* decode/encode counter */ + Int argIdx; + Int8 tempVar8; + char decMsgBuf[ASP_MSG_BUF_LEN]; + + pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration + as = pAstCfg->as; + (void)as; // clear compiler warning in case not used with tracing disabled + + for (z=DECODE1; z < DECODEN; z++) + { + tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), + GATEMP_INDEX_DEC); + if (pAsitCfg->pIoInp[z].hIoPhy && tempVar8) + { + TRACE_VERBOSE1("decDecodeComplete: AS%d: finalizing decode", as+z); + + // FL: send dec deactivate message to slave + argIdx = 0; // set decIdx + *(Int32 *)&decMsgBuf[argIdx] = z; + if(AspMsgSend(ASP_SLAVE_DEC_DEACTIVATE, ASP_MASTER_DEC_DEACTIVATE_DONE, + decMsgBuf, NULL) != ASP_MSG_NO_ERR) + { + TRACE_TERSE0("decodeComplete: error in sending DEC_DEACTIVATE message."); + SW_BREAKPOINT; + return DEC_ERR_COMPLETE_MSG; + } + } + else + { + TRACE_VERBOSE1("decDecodeComplete: AS%d: processing decode ", as+z); + } + } + + return DEC_NO_ERR; +} /* decDecodeComplete */ + + // ----------------------------------------------------------------------------- -// ASIT Decoding Function - Info Processing, Common +// Decoding Function - Frame-Final Processing // -// Name: PAF_ASIT_decodeInfo -// Purpose: Decoding Function for processing information in a manner that -// is common for both initial and subsequent frames of input data. +// Name: decDecodeFinalTest +// Purpose: Decoding Function for determining whether processing of the +// current frame is complete. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x -// Return: Error number in standard form (0 on success). -// Trace: Message Log "trace" in Debug Project Configuration reports: -// * State information as per parent. -// ----------------------------------------------------------------------------- +// Return: 0 if incomplete, and 1 if complete. +// Trace: None. +// + Int -decDecodeInfo( +decDecodeFinalTest( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg ) +{ + PAF_AST_Config *pAstCfg; + Int zMD; + Int sourceSelect; + Int sourceProgram; + Int8 tempVar8, temp2Var8; + + pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration + zMD = pAstCfg->masterDec; + + sourceSelect = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), + GATEMP_INDEX_DEC); + sourceProgram = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), + GATEMP_INDEX_DEC); + + if ((sourceSelect == PAF_SOURCE_NONE) || (sourceSelect == PAF_SOURCE_PASS)) + { + return DEC_ERR_DECODE_FINAL; + } + + // The following allows for Force modes to switch without command deferral. This might + // be better suited for inclusion in DIB_requestFrame, but for now will reside here. + if ((sourceSelect == PAF_SOURCE_SNG) || (sourceSelect > PAF_SOURCE_BITSTREAM)) + { + if (sourceSelect == PAF_SOURCE_DTSALL) + { + if (sourceProgram != PAF_SOURCE_DTS11 && + sourceProgram != PAF_SOURCE_DTS12 && + sourceProgram != PAF_SOURCE_DTS13 && + sourceProgram != PAF_SOURCE_DTS14 && + sourceProgram != PAF_SOURCE_DTS16 && + sourceProgram != PAF_SOURCE_DTSHD) + { + return DEC_ERR_DECODE_FINAL; + } + } + else if (sourceSelect == PAF_SOURCE_PCMAUTO) + { + if (sourceProgram != PAF_SOURCE_PCM) + { + return DEC_ERR_DECODE_FINAL; + } + } + else + { + tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), + GATEMP_INDEX_DEC); + temp2Var8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), + GATEMP_INDEX_DEC); + if (temp2Var8 != tempVar8) + { + return DEC_ERR_DECODE_FINAL; + } + } + } + + return DEC_NO_ERR; +} //decDecodeFinalTest + +Int decInfoSnd( + const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg +) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; @@ -432,19 +629,13 @@ decDecodeInfo( Int z; /* input/decode/stream counter */ Int errno; /* error number */ Int zD, zI, zS, zX; - Int zMD; - Int zMS; Int argIdx; Int8 tempVar8; - Int tempVar; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; - zMD = pAstCfg->masterDec; - zMS = pAstCfg->masterStr; - (void)zMS; (void)as; // clear compiler warning in case not used with tracing disabled // Set decode control: sample rate, emphasis for (z=INPUT1; z < INPUTN; z++) @@ -488,17 +679,6 @@ decDecodeInfo( } } /* end of for (z=INPUT1; z < INPUTN; z++) */ - // Wait for info input: (JX) all SIO_reclaim does is pend on data, and do sync scan or sync check, - // which is done in autoDetection routine now. - //if (pAstCfg->xInp[zMI].hRxSio) - // sioErr = SIO_reclaim(pAstCfg->xInp[zMI].hRxSio, (Ptr)&pAstCfg->xInp[zMI].pInpBuf, NULL); - -#if 0 // debug - // capture input buffer - capIb(pAstCfg->xInp[zMI].pInpBuf); - gCapIb_cnt++; -#endif - // Decode info for (z=DECODE1; z < DECODEN; z++) { @@ -512,11 +692,11 @@ decDecodeInfo( { TRACE_GEN2("PAF_ASIT_decodeInfo: AS%d: processing frame %d -- info", as+zS, pAsitCfg->inpDec.frame); - if (errno = asipUpdateInputStatus(pInp[zI].pRxParams, + if (errno = asitUpdateInputStatus(pInp[zI].pRxParams, &pAstCfg->xInp[zI].inpBufStatus, &pAstCfg->xInp[zI].inpBufConfig)) { - TRACE_TERSE1("return error errno 0x%x.", errno); - return errno; + TRACE_TERSE1("asitUpdateInputStatus return error errno 0x%x.", errno); + return DEC_ERR_INFO_SNDMSG; } #if 0 // debug @@ -534,13 +714,81 @@ decDecodeInfo( // send info message to slave argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; - if(AspMsgSend(ASP_SLAVE_DEC_INFO, ASP_MASTER_DEC_INFO_DONE, - decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR) + if(AspMsgSnd(ASP_SLAVE_DEC_INFO, decMsgBuf) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeInfo: error in sending DEC_INFO message "); SW_BREAKPOINT; // temporary return -1; // temporary } +/* else + { + argIdx = 0; // get decErrno + errno = *(Int32 *)&decMsgBuf[argIdx]; + } + + if (errno) { + TRACE_TERSE1("decInfoSndMSg return error errno 0x%x.", errno); + return DEC_ERR_INFO_SNDMSG; + } +*/ + } + } // z=DECODE1 to DECODEN + +////////////////////////////////////////////////////////////////////////////// + asitPostInfoEvent(); +////////////////////////////////////////////////////////////////////////////// + + return ASIP_NO_ERR; +} /* decInfoSnd() */ + + +Int decInfoAck( + const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg +) +{ + PAF_AST_Config *pAstCfg; + PAF_AST_IoInp *pInp; + Int as; /* Audio Stream Number (1, 2, etc.) */ + Int z; /* input/decode/stream counter */ + Int errno; /* error number */ + Int zI, zS; + Int zMD; + Int zMS; + Int argIdx; + Int8 tempVar8; + Int tempVar; + char decMsgBuf[ASP_MSG_BUF_LEN]; + + pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration + pInp = pAsitCfg->pIoInp; + as = pAstCfg->as; + zMD = pAstCfg->masterDec; + zMS = pAstCfg->masterStr; + (void)zMS; (void)as; // clear compiler warning in case not used with tracing disabled + + // Decode info + for (z=DECODE1; z < DECODEN; z++) + { + zI = pP->inputsFromDecodes[z]; + zS = pP->streamsFromDecodes[z]; + (void)zS; // clear compiler warning in case not used with tracing disabled + + tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), + GATEMP_INDEX_DEC); + if (pInp[zI].hIoPhy && tempVar8) + { + // FL: acknowledge info message from slave + argIdx = 0; // set decIdx + *(Int32 *)&decMsgBuf[argIdx] = z; + if(AspMsgAck(ASP_MASTER_DEC_INFO_DONE, + decMsgBuf) != ASP_MSG_NO_ERR) + { + TRACE_TERSE0("decodeInfo: error in receiving DEC_INFO message "); + SW_BREAKPOINT; // temporary + return -1; // temporary + } else { argIdx = 0; // get decErrno @@ -552,8 +800,8 @@ decDecodeInfo( Cache_wait(); if (errno) { - TRACE_TERSE1("return error errno 0x%x.", errno); - return errno; + TRACE_TERSE1("decInfoAck return error errno 0x%x.", errno); + return DEC_ERR_INFO_ACKMSG; } // increment decoded frame count @@ -598,36 +846,19 @@ decDecodeInfo( } return ASIP_NO_ERR; -} /* decDecodeInfo */ +} -// ----------------------------------------------------------------------------- -// ASIT Decoding Function - Decode Processing -// -// Name: PAF_ASIT_decodeDecode -// Purpose: Decoding Function for processing of input data by the -// Decode Algorithm. -// From: AST Parameter Function -> decodeProcessing -// Uses: See code. -// States: x -// Return: Error number in standard form (0 on success). -// Trace: Message Log "trace" in Debug Project Configuration reports: -// * State information as per parent. -// ----------------------------------------------------------------------------- -static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, - PAF_ASIT_Config *pAsitCfg, Int sourceSelect) +static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/stream counter */ - Int errno; /* error number */ Int argIdx; - Int cbErrno; - Int frameLength; + Int cbErrno, errno; char decMsgBuf[ASP_MSG_BUF_LEN]; - ioPhyCtl_t ioPhyCtl; - ioDataCtl_t ioDataCtl; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; @@ -662,8 +893,76 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, errno = 0; argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; - if(AspMsgSend(ASP_SLAVE_DEC_DECODE, ASP_MASTER_DEC_DECODE_DONE, - decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR) + if(AspMsgSnd(ASP_SLAVE_DEC_DECODE, decMsgBuf) != ASP_MSG_NO_ERR) + { + TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message "); + SW_BREAKPOINT; // temporary + return -1; // temporary + } +/* else + { + argIdx = 0; // get decErrno + errno = *(Int32 *)&decMsgBuf[argIdx]; + argIdx += sizeof(Int32); // get cbErrno + cbErrno = *(Int32 *)&decMsgBuf[argIdx]; + if (cbErrno != 0) + { + gCbWrtAfErrCnt++; + TRACE_TERSE1("CB write error=%d", cbErrno); + //SW_BREAKPOINT; // temporary + } + + if(errno) { + TRACE_TERSE1("decDecodeSnd return error errno 0x%x.", errno); + return DEC_ERR_DECODE_SNDMSG; + } + }*/ + + } // hIoPhy && decodeStatus.mode + else { + TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode ", as+zS, pAsitCfg->inpDec.block); + } + } // z=DECODE1 to DECODEN + +////////////////////////////////////////////////////////////////////////////// + asitPostDecEvent(); +////////////////////////////////////////////////////////////////////////////// + + return ASIP_NO_ERR; +} /* decDecodeSnd() */ + + +static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg) +{ + PAF_AST_Config *pAstCfg; + PAF_AST_IoInp *pInp; + Int as; /* Audio Stream Number (1, 2, etc.) */ + Int z; /* decode/stream counter */ + Int errno; /* error number */ + Int argIdx; + Int cbErrno; + char decMsgBuf[ASP_MSG_BUF_LEN]; + + pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration + pInp = pAsitCfg->pIoInp; + as = pAstCfg->as; + (void)as; // clear compiler warning in case not used with tracing disabled + + // Decode data + for (z=DECODE1; z < DECODEN; z++) + { + Int zI = pP->inputsFromDecodes[z]; + Int zS = pP->streamsFromDecodes[z]; + (void)zS; // clear compiler warning in case not used with tracing disabled + if ( pInp[zI].hIoPhy && pAstCfg->xDec[z].decodeStatus.mode ) + { + // FL: send decode message to slave + errno = 0; + argIdx = 0; // set decIdx + *(Int32 *)&decMsgBuf[argIdx] = z; + errno = AspMsgAck(ASP_MASTER_DEC_DECODE_DONE, decMsgBuf); + if(errno != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message "); SW_BREAKPOINT; // temporary @@ -687,21 +986,14 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); - if (errno) - { - TRACE_VERBOSE1("PAF_ASIT_decodeDecode: fxns->decode returns 0x%x", errno); - return errno; + if(errno) { + TRACE_TERSE1("decDecodeAck return error errno 0x%x.", errno); + return DEC_ERR_DECODE_ACKMSG; } #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA) as_traceChannels(pAsitCfg, z); #endif - - // Compute decoder frame length based on source selection - // This is unnecessary as sourceSelect won't change until input changes - //frameLength = getFrameLengthSourceSel(pP, sourceSelect); - //pAstCfg->xDec[z].decodeControl.frameLength = frameLength; - //pAstCfg->xDec[z].decodeInStruct.sampleCount = frameLength; } // hIoPhy && decodeStatus.mode else { TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode ", as+zS, pAsitCfg->inpDec.block); @@ -709,34 +1001,108 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, } // z=DECODE1 to DECODEN return ASIP_NO_ERR; +} /* decDecodeAck */ -} /* decDecodeData */ -Int decDecodeComplete( const PAF_ASIT_Params *pP, - PAF_ASIT_Config *pAsitCfg) +/************************************************************************************ + * ASP message sending function. Refer to aspMsg_master.h for detailed description. +************************************************************************************/ +Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf) { - int z, zMD, decError; - ALG_Handle alg[DECODEN_MAX]; + ASP_Msg* pAspMsg; /* Messaging */ + Int status; + + // allocate message + pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize); + if (pAspMsg == NULL) { + TRACE_TERSE0("MessageQ_alloc() failure."); + return (ASP_MSG_ERR_QUEUE_ALLOC); + } - zMD = pAsitCfg->pAstCfg->masterDec; + // set the return address in the message header and fill in message payload + MessageQ_setReplyQueue(hAspMsgMaster->masterQue, (MessageQ_Msg)pAspMsg); + pAspMsg->cmd = sndCmd; + pAspMsg->procId = hAspMsgMaster->masterProcId; + pAspMsg->messageId = hAspMsgMaster->messageId & ~(1<<31); + pAspMsg->expectResp = TRUE; - for (z=DECODE1; z < DECODEN; z++) - { - alg[z] = pAsitCfg->pAstCfg->xDec[z].decAlg[PAF_SOURCE_PCM]; + // copy the message provided by caller + if(sndMsgBuf != NULL) { + memcpy(pAspMsg->buf, sndMsgBuf, ASP_MSG_BUF_LEN*sizeof(char)); + } + + // send the message + TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); + status = MessageQ_put(hAspMsgMaster->slaveQue, (MessageQ_Msg)pAspMsg); + if (status != MessageQ_S_SUCCESS) { + TRACE_TERSE0("MessageQ_put() failure."); + MessageQ_free((MessageQ_Msg)pAspMsg); + return (ASP_MSG_ERR_QUEUE_PUT); + } + + status = MessageQ_free((MessageQ_Msg)pAspMsg); + if (status != MessageQ_S_SUCCESS) { + TRACE_TERSE0("MessageQ_free() failure."); + return (ASP_MSG_ERR_QUEUE_FREE); } - alg[zMD] = NULL; // decAlgMaster; // FL: alg[] init is on slave - // Call decodeComplete: 2nd argument is NOT used inside the function - decError = pP->fxns->decodeComplete(pP, NULL, pAsitCfg, alg, - pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); + // No error in messaging operation, even though there + // may be error in returned (acknowledgement) message. + return (ASP_MSG_NO_ERR); +} /* AspMsgSnd */ - if(decError) { - return ASIP_ERR_DECODE_COMPLETE; +/************************************************************************************ + * ASP message sending function. Refer to aspMsg_master.h for detailed description. +************************************************************************************/ +Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf) +{ + ASP_Msg* pAspMsg; /* Messaging */ + Int status; + + // allocate message + pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize); + if (pAspMsg == NULL) { + TRACE_TERSE0("MessageQ_alloc() failure."); + return (ASP_MSG_ERR_QUEUE_ALLOC); } - return ASIP_NO_ERR; -} /* decDecodeComplete */ + // wait for complete message from slave + status = MessageQ_get(hAspMsgMaster->masterQue, (MessageQ_Msg *)&pAspMsg, MessageQ_FOREVER); + if (status != MessageQ_S_SUCCESS) { + TRACE_TERSE0("MessageQ_get() failure."); + MessageQ_free((MessageQ_Msg)pAspMsg); + return (ASP_MSG_ERR_QUEUE_GET); + } + + // check if returned message is valid + if ((pAspMsg->procId != hAspMsgMaster->slaveProcId) || + (pAspMsg->cmd != ackCmd) || + (pAspMsg->messageId != (hAspMsgMaster->messageId | ((UInt32)1<<31)))) { + TRACE_TERSE3("ERROR: ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); + MessageQ_free((MessageQ_Msg)pAspMsg); + return(ASP_MSG_ERR_ACKNOWLEDGE); + } + + hAspMsgMaster->messageId = (hAspMsgMaster->messageId + 1) & ~(1<<31); + TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); + + // get the returned message + if(ackMsgBuf != NULL) { + memcpy(ackMsgBuf, pAspMsg->buf, ASP_MSG_BUF_LEN*sizeof(char)); + } + + // free the message + status = MessageQ_free((MessageQ_Msg)pAspMsg); + if (status != MessageQ_S_SUCCESS) { + TRACE_TERSE0("MessageQ_free() failure."); + return (ASP_MSG_ERR_QUEUE_FREE); + } + + // No error in messaging operation, even though there + // may be error in returned (acknowledgement) message. + return (ASP_MSG_NO_ERR); +} /* AspMsgAck */ #if 0 @@ -799,4 +1165,174 @@ Int asipDecodeProcessing( } /* asipDecodeProcessing */ #endif + +#if 0 +// ----------------------------------------------------------------------------- +// ASIT Processing Function - Decode Processing +// +// Name: asipDecodeProcessing +// Purpose: +// Return: Error number in standard form (0 on success). +// ----------------------------------------------------------------------------- +Int asipDecodeProcessing( + const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg, + Int sourceSelect) +{ + PAF_AST_Config *pAstCfg; + asipDecProc_t *pDec; + Int decError, retVal, getVal; /* error number */ + Int zMD, decDone; + Int8 tempVar8; + + pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration + zMD = pAstCfg->masterDec; + pDec = &pAsitCfg->inpDec; + + retVal = ASIP_NO_ERR; + + // Initialization for decode processing + if(!pDec->initDone) { + // Initialize decoder and send message to decoder + retVal = decDecodeInit(pP, pAsitCfg, pAsitCfg->pIoInp[zMD].sourceSelect); + if(retVal != ASIP_NO_ERR) { + decDecodeComplete(pP, pAsitCfg); + + return retVal; + } + + pDec->initDone = TRUE; + } + + // Check if source has configured to NONE + tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), + GATEMP_INDEX_DEC); + if (tempVar8 == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) { + TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: sourceSelect == PAF_SOURCE_NONE"); + pAsitCfg->inpDec.state = QUIT; // skip processing, quit decoding + retVal = ASIP_ERR_DECODE_QUIT; + } + + // Process commands (decode) + getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg); + if (getVal) { + retVal = ASIP_ERR_DECODE_COMMAND; + if (getVal == ASPERR_QUIT) { + TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: state = QUIT"); + + // Don't return if ASPERR_QUIT, but skip decode processing and quit + pAsitCfg->inpDec.state = QUIT; + } + else if (getVal == ASPERR_ABORT) { + TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: return getVal"); + + // Return here if ASPERR_ABORT + return retVal; + } + else { + /* ignore */; + } + } + + do { + decDone = TRUE; + + switch(pAsitCfg->inpDec.state) + { + case INFO1: + decError = decDecodeInfo(pP, pQ, pAsitCfg); + if (decError) { + //gAsipInfo1_PrimaryErrCnt++; + TRACE_TERSE1("INFO1: decError 0x%x after decodeInfo, primary timing", decError); + retVal = ASIP_ERR_DECODE_INFO1; + } + else { + // Don't start decode until major access unit is found. + Int8 sourceDecode, sampleRate; + + sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), + GATEMP_INDEX_DEC); + sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), + GATEMP_INDEX_DEC); + if ( ( (sourceDecode == PAF_SOURCE_THD) || + (sourceDecode == PAF_SOURCE_DXP) || + (sourceDecode == PAF_SOURCE_DTSHD) ) && + ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) { + //gMajorAuMissed++; // debug + pAsitCfg->inpDec.frame++; + //pAsitCfg->inpDec.state = INFO1; // stay in this state + } + else { + decError = pP->fxns->decodeInfo1(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); + if(decError) { + retVal = ASIP_ERR_DECODE_INFO1; + } + else { + pAsitCfg->inpDec.state = DECODE; + decDone = FALSE; // go to DECODE state before return + } + } + } + break; + + case INFO2: + decError = decDecodeInfo(pP, pQ, pAsitCfg); + if (decError) { + //gAsipInfo1_PrimaryErrCnt++; + TRACE_TERSE1("INFO2: decError 0x%x after decodeInfo, primary timing", decError); + retVal = ASIP_ERR_DECODE_INFO2; + } + else { + pAsitCfg->inpDec.state = DECODE; + decDone = FALSE; // go to DECODE state before return + } + break; + + case DECODE: + decError = decDecodeData(pP, pQ, pAsitCfg, sourceSelect); + if (decError) { + //gAsipDecodeErrCnt++; + TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE. decodeDecode err 0x%04x", decError); + retVal = ASIP_ERR_DECODE_DATA; + } + else { + decError = pP->fxns->decodeFinalTest(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); + if (decError) { + retVal = ASIP_ERR_DECODE_FINAL; + } + else { + pAsitCfg->inpDec.frame++; + pAsitCfg->inpDec.state = INFO2; + } + } + break; + + case QUIT: + //gAsipQuitCnt++; + Log_info0("TaskAsip: state=QUIT"); + + // Quit: + // - Set error number registers. + // - Exit state machine to "decode complete" processing. + TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: state: QUIT"); + break; + + default: + break; + + } /* switch */ + + } while (!decDone); + + if(retVal != ASIP_NO_ERR) { + decDecodeComplete(pP, pAsitCfg); + } + + return retVal; +} /* asipDecodeProcessing */ + +#endif + + /* Nothing past this line */ diff --git a/pasdk/test_dsp/framework/audioStreamInpProc.h b/pasdk/test_dsp/framework/audioStreamInpProc.h index fbe29465..a9b791c0 100644 --- a/pasdk/test_dsp/framework/audioStreamInpProc.h +++ b/pasdk/test_dsp/framework/audioStreamInpProc.h @@ -195,6 +195,11 @@ enum { enum { ASIT_NO_ERR, + ASIT_ERR_IOBUFF_INIT, + ASIT_ERR_IODATA_INIT, + ASIT_ERR_IOPYH_INIT, + ASIT_ERR_INPDATA_PROC, + ASIT_ERR_INPBUF_UNDERFLOW, ASIT_ERR_AUTO_DETECION, ASIT_ERR_NO_MATCHING_SOURCE, ASIT_ERR_SWITCH_TO_PCM, @@ -202,6 +207,7 @@ enum { ASIT_ERR_MCASP_CFG, ASIT_ERR_INPUT_CFG, ASIT_ERR_DECODE_INIT, + ASIT_ERR_DECODE, ASIT_ERR_DECODE_COMMAND, ASIT_ERR_DECODE_INFO1, ASIT_ERR_DECODE_INFO2, @@ -210,9 +216,26 @@ enum { ASIT_ERR_DECODE_COMPLETE, ASIT_ERR_DECODE_MSG, ASIT_ERR_DECODE_QUIT, + ASIP_ERR_DECODE_ABORT, + ASIT_ERR_EVENTS, ASIT_ERR_ABORT }; +enum { + DEC_NO_ERR, + DEC_ERR_SOURCE_NONE, + DEC_ERR_ASPERR_ABORT, + DEC_ERR_ASPERR_QUIT, + DEC_ERR_WRONG_MSG, + DEC_ERR_INFO_SNDMSG, + DEC_ERR_INFO_ACKMSG, + DEC_ERR_DECODE_SNDMSG, + DEC_ERR_DECODE_ACKMSG, + DEC_ERR_DECODE_FINAL, + DEC_ERR_COMPLETE_MSG +}; + + #define DEC_MSGMSK_INPDATA 0x1 #define DEC_MSGMSK_INFOACK 0x2 #define DEC_MSGMSK_DECACK 0x4 @@ -245,17 +268,18 @@ typedef struct PAF_AST_InpIO { //uint32_t numXferInterm; uint32_t numInputOverrun; uint32_t numUnderflow; - uint32_t numAsipRestart; - uint32_t numAsipDecodeQuit; + uint32_t numAsitRestart; + uint32_t numAsitDecodeQuit; uint32_t numFrameReceived; uint32_t numPcmFrameReceived; size_t phyXferSize; int_fast32_t pcmSwitchHangOver; uint_least16_t asipState; - uint_least16_t asipProcState; + //uint_least16_t asipProcState; bool buffReadComplete; bool swapData; + bool firstTimeInit; } PAF_AST_IoInp; // Decoder structure @@ -264,7 +288,9 @@ typedef struct asipDecProc_s { Int frame; Int block; + Int majorAuFound; Int initDone; + Int decodeAckDelayed; } asipDecProc_t; // Audio Stream Input Task (ASIT) configuration @@ -573,7 +599,7 @@ static inline Int sharedMemReadInt(volatile XDAS_Int32 *address, Int gateIdx) #endif } -Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus, +Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus, PAF_InpBufConfig *pInpBuf); /* Int asipDecodeInit( @@ -581,18 +607,28 @@ Int asipDecodeInit( PAF_ASIT_Config *pAsitCfg, Int sourceSelect); */ -Int asipDecodeProcessing( +/*Int asipDecodeProcessing( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, - Int sourceSelect); + Int sourceSelect);*/ +Int asitDecodeProcessing(const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg, + UInt asitEvents); -/* Int decDecodeInit( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect); -*/ + +Int decDecodeFsm( + const PAF_ASIT_Params *pP, + const PAF_ASIT_Patchs *pQ, + PAF_ASIT_Config *pAsitCfg, + Int sourceSelect, + UInt decMsg); + Int getFrameLengthSourceSel( const PAF_ASIT_Params *pP, Int8 sourceSelect); diff --git a/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c b/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c index 3afb532b..3db43196 100644 --- a/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c +++ b/pasdk/test_dsp/framework/audioStreamInpProcNewIO.c @@ -38,6 +38,8 @@ All rights reserved. */ #include #include +#include +#include #include "procsdk_audio_typ.h" #include "audioStreamInpProc.h" @@ -58,6 +60,8 @@ All rights reserved. #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 @@ -112,46 +116,64 @@ extern XDAS_Int32 D10_RxControl(const void *pD10RxParams, /* * 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); +Int asitSelectDevices(const PAF_ASIT_Patchs *pQ, 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; - -enum -{ - ASIP_SOURCE_DETECTION, - ASIP_DECODE, - ASIP_SWITCH_TO_PCM, +enum { + ASIT_RESET, + ASIT_SOURCE_DETECTION, + ASIT_PCM_TRANSITION, + ASIT_DECODE_PROCESSING }; -enum -{ - ASIP_INPUT_PREPARATION, - ASIP_INPUT_PROCESSING -}; +#define ASIT_EVTMSK_NONE 0x0 +#define ASIT_EVTMSK_INPDATA 0x1 +#define ASIT_EVTMSK_INFOACK 0x2 +#define ASIT_EVTMSK_DECACK 0x4 +#define ASIT_ALL_EVENTS ( ASIT_EVTMSK_INPDATA \ + + ASIT_EVTMSK_INFOACK \ + + ASIT_EVTMSK_DECACK ) +#define ASIT_DEC_EVENTS ( ASIT_EVTMSK_INPDATA \ + + ASIT_EVTMSK_INFOACK \ + + ASIT_EVTMSK_DECACK ) #define ASIP_DEBUG @@ -165,6 +187,9 @@ Int inputReadyForProcessing; #include "evmc66x_gpio_dbg.h" #endif +Event_Handle asitEvent; +Int eventsOn; + /* * ======== taskAsipFxn ======== * Audio Stream Input Processing task function @@ -192,13 +217,21 @@ int asipLoopCount1, asipLoopCount2; Int asipErrno; Int inputReadyForProcessing; #endif - - Int firstTimeInit = TRUE; + Int asitErr; + UInt events; +// Int eventsOn; + Error_Block eb; Log_info0("Enter taskAsipFxn()"); taskAsipFxnInit(pP, pQ); // initialization of input task + Error_init(&eb); // initialize error block + + asitEvent = Event_create(NULL, &eb); + if (asitEvent == NULL) { + System_abort("Event create failed"); + } // // Audio Stream Input Task Configuration (*pAsitCfg): // @@ -219,23 +252,33 @@ Int inputReadyForProcessing; 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; + pInp->asipState = ASIT_RESET; + pInp->firstTimeInit = TRUE; + pInp->numAsitRestart = 0; + + // 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(asitEvent, 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); @@ -243,76 +286,90 @@ Int inputReadyForProcessing; // 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); - - firstTimeInit = FALSE; - } - - // Initialize ASIP processing - asipProcInit(pInp, &pAsitCfg->inpDec); - - pInp->asipState = ASIP_INPUT_PROCESSING; + // 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; - case ASIP_INPUT_PROCESSING: - // Pending on I/O PHY transfer - asipPhyTransferPend(); - -#if 1 // (***) FL: shows timing of Input (Rx McASP EDMA) after decoding has started (autodet complete) - // (***) debug // 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); + 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); + } + else { + //Error checking & debug + asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA); } -#endif - - // 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); + break; - pInp->asipState = ASIP_INPUT_PREPARATION; + 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 ASIT_DECODE_PROCESSING: + if(events & ASIT_DEC_EVENTS) { + // 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) @@ -332,9 +389,10 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP, *asipErrno = 0; // Select source and initialize physical layer / HW interface - *asipErrno = asipSelectDevices(pQ, pInp); + *asipErrno = asitSelectDevices(pQ, 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 } @@ -349,7 +407,7 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP, } // 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) { @@ -389,7 +447,8 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP, *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; } @@ -399,34 +458,437 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP, // 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); + + // Check if bitstream or PCM is detected + 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 != Audk2g_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; + } + } + } + + // 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 ASIP_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 + asipDecProc_t *pDec; + ioDataAutoDetStat_t autoDetStatus; + Int zMD; + UInt decMsg; + + zMD = pAsitCfg->pAstCfg->masterDec; // pointer to AST common (shared) configuration + pInp = &pAsitCfg->pIoInp[zMD]; // pointer to input I/O components + 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 + 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 + 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 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) { + decMsg |= DEC_MSGMSK_INPDATA; + } + + if(asitEvents & ASIT_EVTMSK_INFOACK) { + decMsg |= DEC_MSGMSK_INFOACK; + } + + if(asitEvents & ASIT_EVTMSK_DECACK) { + decMsg |= DEC_MSGMSK_DECACK; + } + + 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; + + pInpIo->phyXferSize = INPUT_FRAME_SIZE_DEF; + + 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 + } - 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 - } + 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_IOPYH_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 + 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]; @@ -437,33 +899,60 @@ int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo) ioDataCfg.zeroRunTrigger = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger; if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) { - return (-1); // to remove magic number + 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 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 != Audk2g_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."); + } + + // 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; @@ -474,26 +963,43 @@ void asipIoPhyPrime(PAF_AST_IoInp *pInp) //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 */ + +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 != Audk2g_EOK) { + return ASIT_ERR_MCASP_CFG; + } + + // Start swapping data + pInp->swapData = TRUE; + } + + return ASIT_NO_ERR; +} /* asitRecfgPhyXfer */ /*====================================================================================== * McASP LLD call back function @@ -502,7 +1008,8 @@ void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet) { /* post semaphore */ if(mcasp_packet->arg == IOPHY_XFER_FINAL) { - Semaphore_post(asipSemRx); + //Semaphore_post(asipSemRx); + Event_post(asitEvent, ASIT_EVTMSK_INPDATA); } else { ; // intermediate packet due to buffer wrapping around } @@ -532,8 +1039,10 @@ void asipMcaspRxRestart(void) /*====================================================================================== * 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++; @@ -541,9 +1050,12 @@ void asipPhyTransferStart(PAF_AST_IoInp *pInpIo) asipMcaspRxRestart(); } 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 { @@ -563,7 +1075,7 @@ 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_IoInp *pInp) { Audk2g_STATUS status; @@ -583,7 +1095,7 @@ Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp) #endif if(status != Audk2g_EOK) { Log_info0("audk2g_AudioSelectClkSrc Failed!\n"); - return ASIP_ERR_D10_CFG; + return ASIT_ERR_D10_CFG; } audk2g_delay(50000); // Without delay between these 2 calls system aborts. @@ -591,7 +1103,7 @@ Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp) status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c if(status != Audk2g_EOK) { Log_info0("McASP Configuration Failed!\n"); - return ASIP_ERR_MCASP_CFG; + return ASIT_ERR_MCASP_CFG; } pInp->hMcaspChan = hMcaspRxChan; @@ -607,12 +1119,12 @@ Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp) #endif return 0; -} /* asipSelectDevices */ +} /* 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; @@ -693,7 +1205,11 @@ Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus, } -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; @@ -710,7 +1226,7 @@ void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp) 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; @@ -719,13 +1235,17 @@ void asipUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp) // 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; @@ -734,7 +1254,8 @@ Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp, // 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 || @@ -752,7 +1273,8 @@ Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp, } // 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 @@ -772,7 +1294,8 @@ Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp, // 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; @@ -814,10 +1337,10 @@ Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp, // 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, @@ -830,8 +1353,8 @@ Int asipDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp *pInp, 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 @@ -879,24 +1402,25 @@ Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, //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; @@ -934,237 +1458,13 @@ Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg, } //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) { - - // 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) -//{ - -//} - #ifndef IO_LOOPBACK_TEST #if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH @@ -1207,24 +1507,70 @@ Int rxDecodePcm(PAF_AST_IoInp *pInp) } - 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 - -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_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_VERBOSE0("ASIT error handling finished. Go to state ASIT_RESET."); + } + + if(asitErr == ASIT_ERR_EVENTS) { + pAsitCfg->pIoInp[0].asipState = ASIT_RESET; + pAsitCfg->pIoInp[0].numAsitRestart++; + TRACE_VERBOSE0("ASIT error handling: events error. Go to state ASIT_RESET."); + } + + return; +} /* asitErrorHandling */ + -void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno) +////////////////////////////////////////////////////////////////////////////// +void asitPostInfoEvent() { + Event_post(asitEvent, ASIT_EVTMSK_INFOACK); +} +void asitPostDecEvent() +{ + Event_post(asitEvent, ASIT_EVTMSK_DECACK); } +////////////////////////////////////////////////////////////////////////////// /* Nothing past this line */ diff --git a/pasdk/test_dsp/io/ioBuff.c b/pasdk/test_dsp/io/ioBuff.c index 6fc65815..0ade8152 100644 --- a/pasdk/test_dsp/io/ioBuff.c +++ b/pasdk/test_dsp/io/ioBuff.c @@ -81,7 +81,7 @@ int ioBuffInit (ioBuffHandle_t handle, const ioBuffParams_t *params) inst->sync = params->sync; // synchronous read or synchronous write inst->nom_delay = params->nominalDelay; // nominal delay for synchronous read/write - inst->rw_wrap_around = 0; + //inst->rw_wrap_around = 0; inst->status = BUFF_STATUS_NORMAL; inst->read_ptr = inst->read_complete_ptr = inst->base; inst->write_ptr = inst->write_complete_ptr = (void *)((uint_least32_t)inst->base + inst->nom_delay); @@ -104,11 +104,11 @@ int ioBuffGetReadPtrs(ioBuffHandle_t handle, size_t mem_size, if(inst->status != BUFF_STATUS_OVERFLOW) { /* check if buffer underflows */ - if( ( (!inst->rw_wrap_around) + if( ( ((uint_least32_t)inst->write_complete_ptr >= (uint_least32_t)inst->read_ptr) &&(((uint_least32_t)inst->write_complete_ptr - (uint_least32_t)inst->read_ptr) < mem_size) ) - ||( (inst->rw_wrap_around) + ||( ((uint_least32_t)inst->write_complete_ptr < (uint_least32_t)inst->read_ptr) &&(((uint_least32_t)inst->write_complete_ptr + inst->size - (uint_least32_t)inst->read_ptr) < mem_size) ) @@ -128,7 +128,7 @@ int ioBuffGetReadPtrs(ioBuffHandle_t handle, size_t mem_size, delay_adjust); if(inst->read_ptr < inst->base) { inst->read_ptr = (void *)((uint_least32_t)inst->read_ptr + inst->size); - inst->rw_wrap_around = 1; // set wrap around flag + //inst->rw_wrap_around = 1; // set wrap around flag } ret_val = IOBUFF_ERR_UNDERFLOW; @@ -210,11 +210,11 @@ int ioBuffGetWritePtrs(ioBuffHandle_t handle, size_t mem_size, /* check if buffer overflows or not */ if(inst->status != BUFF_STATUS_UNDERFLOW) { // this condition may need to be removed!!! - if( ( (!inst->rw_wrap_around) + if( ( ((uint_least32_t)inst->read_complete_ptr < (uint_least32_t)inst->write_ptr) &&(((uint_least32_t)inst->read_complete_ptr + inst->size - (uint_least32_t)inst->write_ptr) < mem_size) ) - ||( (inst->rw_wrap_around) + ||( ((uint_least32_t)inst->read_complete_ptr >= (uint_least32_t)inst->write_ptr) &&(((uint_least32_t)inst->read_complete_ptr - (uint_least32_t)inst->write_ptr) < mem_size) ) @@ -242,7 +242,8 @@ int ioBuffGetWritePtrs(ioBuffHandle_t handle, size_t mem_size, else { /* already in underflow and remain in underflow untill write pointer is ahead of read pointer */ - ret_val = IOBUFF_ERR_UNDERFLOW; + //ret_val = IOBUFF_ERR_UNDERFLOW; + ret_val = IOBUFF_NOERR; // underflow is not an error when getting write pointers } /* return 1 or 2 pointers depending buffer wraps around or not */ @@ -285,7 +286,7 @@ int ioBuffReadComplete(ioBuffHandle_t handle, void *read_begin, size_t read_size if(inst->read_complete_ptr >= inst->end) { inst->read_complete_ptr = (void *) ((uint_least32_t)inst->read_complete_ptr - inst->size); - inst->rw_wrap_around ^= 1; // toggle wrap around flag + //inst->rw_wrap_around ^= 1; // toggle wrap around flag } return (IOBUFF_NOERR); @@ -302,7 +303,7 @@ int ioBuffWriteComplete(ioBuffHandle_t handle, void *write_begin, size_t write_s if(inst->write_complete_ptr >= inst->end) { inst->write_complete_ptr = (void *)((uint_least32_t)inst->write_complete_ptr - inst->size); - inst->rw_wrap_around ^= 1; // toggle wrap around flag + //inst->rw_wrap_around ^= 1; // toggle wrap around flag } return (IOBUFF_NOERR); @@ -359,12 +360,12 @@ int ioBuffAdjustDelay(ioBuffHandle_t handle, size_t delay) if( (size_t)inst->write_complete_ptr >= ((size_t)inst->base+delay) ) { inst->read_ptr = inst->read_complete_ptr = (void *)((size_t)inst->write_complete_ptr - delay); - inst->rw_wrap_around = 0; + //inst->rw_wrap_around = 0; } else { temp = delay - ((size_t)inst->write_complete_ptr - (size_t)inst->base); inst->read_ptr = inst->read_complete_ptr = (void *)((size_t)inst->end - temp); - inst->rw_wrap_around = 1; + //inst->rw_wrap_around = 1; } inst->nom_delay = delay; diff --git a/pasdk/test_dsp/io/ioConfig.h b/pasdk/test_dsp/io/ioConfig.h index ca43abc4..27a67d12 100644 --- a/pasdk/test_dsp/io/ioConfig.h +++ b/pasdk/test_dsp/io/ioConfig.h @@ -68,16 +68,16 @@ // Define McASP transfer element size: number of bytes in one word #define WORD_SIZE_BITSTREAM 2 #define WORD_SIZE_PCM 4 -#define NUM_CYCLE_PER_FRAME 128 +#define NUM_CYCLE_PER_FRAME_DEF 1024 //128 // Input frame length: number of words to be transfered in 1 transfer of McASP LLD Rx // These numbers are according to existing SIO/DEV based I/O. #define INPUT_STRIDE (2*NUM_RX_SERIALIZER) #ifdef INPUT_HDMI_4xI2S -#define INPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME*INPUT_STRIDE) // 128 stereo/lane +#define INPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME_DEF*INPUT_STRIDE) // 128 stereo/lane #else //#define INPUT_FRAME_LENGTH (64*INPUT_STRIDE) // 64 stereo/lane -#define INPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME*INPUT_STRIDE) // 128 stereo/lane +#define INPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME_DEF*INPUT_STRIDE) // 128 stereo/lane #endif // Input frame size: number of bytes to be transfered in 1 transfer of McASP LLD Rx @@ -86,7 +86,7 @@ // Output frame length: number of words to be transfered in 1 transfer of McASP LLD Tx #define OUTPUT_STRIDE (2*NUM_TX_SERIALIZER) -#define OUTPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME*OUTPUT_STRIDE) // 128 stereo/lane +#define OUTPUT_FRAME_LENGTH (NUM_CYCLE_PER_FRAME_DEF*OUTPUT_STRIDE) // 128 stereo/lane // Output frame size: number of bytes to be transfered in 1 transfer of McASP LLD Tx #define OUTPUT_FRAME_SIZE (OUTPUT_FRAME_LENGTH * WORD_SIZE_PCM) diff --git a/pasdk/test_dsp/mib/mib.c b/pasdk/test_dsp/mib/mib.c index 82191d56..504cef8c 100644 --- a/pasdk/test_dsp/mib/mib.c +++ b/pasdk/test_dsp/mib/mib.c @@ -554,7 +554,7 @@ Int DIB_reclaim (DEV2_Handle device) // i.e. it is ok to adjust the input buffer pointers. // if successful then this sets // pSync = address of PA (for IEC) - status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig); + status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig); // DIB_initFrame if (status) { if (pBufConfig->pBufStatus->lastFrameMask & (1 << pDevExt->sourceProgram)) { pDevExt->deferredError = status; diff --git a/pasdk/test_dsp/sap/sap.c b/pasdk/test_dsp/sap/sap.c index 3ac2e5b1..1c2f5316 100644 --- a/pasdk/test_dsp/sap/sap.c +++ b/pasdk/test_dsp/sap/sap.c @@ -1221,7 +1221,7 @@ Void SAP_watchDog (Void) // do nothing if SAP_init not yet called if (!SAP_initialized) { - Log_info2("%s.%d: SAP_init not yet called.\n", (xdc_IArg)__FUNCTION__, __LINE__); + //Log_info2("%s.%d: SAP_init not yet called.\n", (xdc_IArg)__FUNCTION__, __LINE__); return; }