diff --git a/pasdk/test_dsp/framework/audioStreamOutIo.c b/pasdk/test_dsp/framework/audioStreamOutIo.c
index 6768889362bfeac37d6063a866749057ae7e4c95..a655af2675ac0b7681a8cceeee8678bdd57435fb 100644 (file)
#define DEC_OUTNUMBUF_MAP(X) \
pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
-#define STRIDE_WORST_CASE 32 // 4-byte (32-bit) word, 2 slots, 4 serializers
+//#define STRIDE_WORST_CASE 32 // 4-byte (32-bit) word, 2 slots, 4 serializers
extern Ptr hMcaspTxChan;
extern Int d10Initialized;
-// FL, New IO: this function is currently a stub
-// FL, New IO: need to McASP/EDMA configuration using SAP configuration from Output shortcut
// Select Output devices
-Int asopSelectDevices(void *pConfig, PAF_AST_IoOut *pOut)
+Int asopSelectDevices(
+ const PAF_SIO_Params *pOutCfg,
+ PAF_AST_IoOut *pOut
+)
{
- if((pOut->hIoBuff == NULL) || (pOut->hIoPhy == NULL) || (!d10Initialized)) {
- return -1;
- }
+ mcaspLLDconfig *pReqLldCfg;
+ Ptr mcaspChanHandle;
+ Int32 status;
+ Aud_STATUS audStatus;
+ UInt postedEvents;
- if(pOut->hMcaspChan == NULL) {
- Aud_STATUS status;
- mcaspLLDconfig * lldCfg;
- Ptr mcaspChanHandle;
+ if ((pOut->hIoBuff == NULL) || (pOut->hIoPhy == NULL) || (!d10Initialized))
+ {
+ return ASOP_IO_ERR_IO_UNINIT;
+ }
- lldCfg = (mcaspLLDconfig *)pConfig;
- status = mcasplldChanCreate(lldCfg, &mcaspChanHandle);
- if(status != Aud_EOK) {
- return -1;
+ // Deactivate currently active Output device
+ if (pOut->hMcaspChan != NULL)
+ {
+ // Reset channel
+ status = mcaspControlChan(pOut->hMcaspChan, MCASP_CHAN_RESET, NULL);
+ if (status != MCASP_COMPLETED)
+ {
+ Log_info0("asopSelectDevices(): McASP channel reset failed!\n");
+ return ASOP_IO_ERR_MCASP_CFG;
}
+
+ // Delete McASP LLD channel
+ status = mcaspDeleteChan(pOut->hMcaspChan);
+ if (status != MCASP_COMPLETED)
+ {
+ Log_info0("asopSelectDevices(): McASP channel deletion failed!\n");
+ return ASOP_IO_ERR_MCASP_CFG;
+ }
+
+ // Clear (drop) already posted Output data events
+ postedEvents = Event_getPostedEvents(gAsotEvtHandle);
+ while ((postedEvents & Evt_Id_AsotTxMcaspEdma) != 0)
+ {
+ Event_pend(gAsotEvtHandle, Event_Id_NONE, Evt_Id_AsotTxMcaspEdma, 0);
+ postedEvents = Event_getPostedEvents(gAsotEvtHandle);
+ }
+
+ pOut->hMcaspChan = NULL; // reset active McASP LLD handle
+ pOut->pLldCfg->hMcaspChan = NULL; // reset McASP LLD handle for active McASP LLD configuration
+ pOut->pLldCfg = NULL; // reset pointer to active McASP LLD configuration
+ }
- pOut->hMcaspChan = mcaspChanHandle;
+ // Activate requested device
+ if (pOutCfg != NULL)
+ {
+ //
+ // Device other than OutNone selected
+ //
+
+ pReqLldCfg = (mcaspLLDconfig *)pOutCfg->sio.pConfig;
+ if (pReqLldCfg->hMcaspChan == NULL)
+ {
+ // Create McASP LLD channel
+ mcaspChanHandle = NULL;
+ audStatus = mcasplldChanCreate(pReqLldCfg, &mcaspChanHandle);
+ if (audStatus != Aud_EOK)
+ {
+ Log_info0("asopSelectDevices(): McASP channel creation failed!\n");
+ return ASOP_IO_ERR_MCASP_CFG;
+ }
+
+ pReqLldCfg->hMcaspChan = mcaspChanHandle; // set McASP LLD handle for requested McASP LLD configuration
+ pOut->pLldCfg = pReqLldCfg; // set pointer to active McASP LLD configuration
+ pOut->hMcaspChan = pReqLldCfg->hMcaspChan; // set active McASP LLD handle
+
+ // configure stride according to selected McASP LLD configuration
+ pOut->stride = pReqLldCfg->mcaspChanParams->noOfSerRequested *
+ pReqLldCfg->mcaspChanParams->noOfChannels;
+
+ pOut->rateX = 1.; // intialize rateX
+ }
+ else
+ {
+ return ASOP_IO_ERR_INV_STATE;
+ }
+ }
+ else
+ {
+ //
+ // OutNone device selected
+ //
+
+ pOut->hMcaspChan = NULL; // reset active McASP LLD handle
+ pOut->pLldCfg = NULL; // reset pointer to active McASP LLD configuration
}
- return 0;
+ return ASOP_IO_SOK;
}
// Check if Output device SIO selection changed
if ((z < OUTPUT1) || (z >= OUTPUTN))
{
*pOutDevSelUpdate = FALSE;
- return -1;
+ return ASOP_IO_ERR_INV_PARAMS;
}
*pOutDevSelUpdate = (Bool)(pAstCfg->xOut[z].outBufStatus.sioSelect >= 0);
- return 0;
+ return ASOP_IO_SOK;
}
// Check if any Output device SIO selection changed
*pOutDevSelUpdate = outDevSelUpdate;
- return 0;
+ return ASOP_IO_SOK;
}
// -----------------------------------------------------------------------------
Int zMI;
Int zMS;
Int zE, zX;
+ // "proof of concept" for McASP LLD API
+ Uint32 divider;
+ Mcasp_HwSetupData mcaspSetup;
+ Int32 status;
pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
return ((getVal & 0xff) | ASPERR_RATE_CHECK);
}
#endif // FL, New IO
- // FL: ugly little experiment
- //*(volatile UInt32 *)0x23400B0 |= 7;
+ if (pOut->rateX != rateX)
+ {
+ UInt32 regVal;
+
+ //
+ // "Proof on concept" code for McASP LLD API to change bit clock divider.
+ //
+
+ // Initialize divider value.
+ // This works for AHCLKX input from HDMI & sample rate = 44.1,48,88.2,96,192 kHz.
+ divider = 2;
+
+ // Update divider based on calculated rateX
+ divider /= rateX;
+
+#if 0 // debug
+ // Experimental code: directly write CLKXDIV
+ regVal = *(volatile UInt32 *)0x23400B0; // read MCASP_ACLKXCTL
+ regVal &= ~0x1F; // mask off CLKXDIV bits
+ //regVal |= 7; // set CLKXDIV for 48 kHz
+ //regVal |= 3; // set CLKXDIV for 96 kHz
+ //regVal |= 1; // set CLKXDIV for 192 kHz
+ regVal |= (divider-1); // set CLKXDIV
+ *(volatile UInt32 *)0x23400B0 = regVal; // write MCASP_ACLKXCTL
+#endif
+
+#if 1
+ // get existing McASP HW setup
+ status = mcaspControlChan(pOut->hMcaspChan, Mcasp_IOCTL_CNTRL_GET_FORMAT_CHAN, &mcaspSetup);
+ if (status != MCASP_COMPLETED)
+ {
+ Log_info0("asopSetCheckRateX(): McASP get channel format failed!\n");
+ return ASOP_IO_ERR_MCASP_CFG;
+ }
+
+ // update CLKXDIV based on rateX
+ mcaspSetup.clk.clkSetupClk &= ~CSL_MCASP_ACLKXCTL_CLKXDIV_MASK;
+ mcaspSetup.clk.clkSetupClk |= (divider-1);
+
+ // update McASP HW setup
+ status = mcaspControlChan(pOut->hMcaspChan, Mcasp_IOCTL_CNTRL_SET_FORMAT_CHAN, &mcaspSetup);
+ if (status != MCASP_COMPLETED)
+ {
+ Log_info0("asopSetCheckRateX(): McASP set channel format failed!\n");
+ return ASOP_IO_ERR_MCASP_CFG;
+ }
+#endif
+
+ pOut->rateX = rateX;
+ }
}
}
- return 0;
+ return ASOP_IO_SOK;
} //asopSetCheckRateX
// -----------------------------------------------------------------------------
// Need to Revisit: Starting Clocks here seems logical & also manages the McASP without spurious underruns .
#if 0
// if device selected and valid then enable stat tracking if
- // required and start clocking
- if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
- {
- TRACE_VERBOSE0("PAF_ASOT_startOutput: start SIO clocks");
- errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
- if (errno)
- {
- TRACE_VERBOSE2("PAF_ASOT_startOutput: errme 0x%x, errno 0x%x", errme, errno);
- SIO_idle(pAstCfg->xOut[z].hTxSio);
- if (!errno)
- {
- errno = ASPERR_DEVOUT + errme;
- }
- }
- }
+ // required and start clocking
+ if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
+ {
+ TRACE_VERBOSE0("PAF_ASOT_startOutput: start SIO clocks");
+ errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
+ if (errno)
+ {
+ TRACE_VERBOSE2("PAF_ASOT_startOutput: errme 0x%x, errno 0x%x", errme, errno);
+ SIO_idle(pAstCfg->xOut[z].hTxSio);
+ if (!errno)
+ {
+ errno = ASPERR_DEVOUT + errme;
+ }
+ }
+ }
#endif
// Set sample count so that DOB knows how much data to send
#if 1 // FL, New IO: add similar thing to be figured out
// Update framework Phy transfer size
- pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * OUTPUT_STRIDE * WORD_SIZE_PCM;
- // Update IO Phy transfer size
+ pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * pOut[z].stride * WORD_SIZE_PCM;
+ // Update IO Phy transfer size
ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
ioPhyCtl.params.xferFrameSize = pOut[z].phyXferSize;
ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
// Update IO Buff delay to match Phy transfer size
ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
-#endif
+#endif
if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED)
{
}
}
- return 0;
+ return ASOP_IO_SOK;
} /* asopStartOutput */
// -----------------------------------------------------------------------------
PAF_AST_IoOut *pOut;
Int as; /* Audio Stream Number (1, 2, etc.) */
Int z; /* output counter */
- Int errno = 0, getVal;
+ Int errno, getVal;
Int zS, zX;
PAF_SIO_IALG_Obj *pObj;
PAF_SIO_IALG_Config *pAlgConfig;
as = pAstCfg->as;
(void)as; // clear compiler warning in case not used with tracing disabled
+ errno = ASOP_IO_SOK;
for (z=OUTPUT1; z < OUTPUTN; z++)
{
if (pOut[z].hIoPhy)
* Initialize I/O components for output processing
============================================================================*/
Int asopIoCompsInit(
- PAF_AST_OutBuf *pOutBuf,
- PAF_AST_IoOut *pOutIo
+ Int16 strAfSampleCount, // stream audio frame sample count
+ PAF_AST_OutBuf *pOutBuf, // pointer to Output Buffer
+ PAF_AST_IoOut *pOutIo // pointer to Output IO
)
{
- // Initialize I/O BUFF and I/O PHY components for output task
ioBuffParams_t ioBuffParams;
ioPhyParams_t ioPhyParams;
- ioBuffParams.base = pOutBuf->outBufConfig.base.pVoid;
- ioBuffParams.size = pOutBuf->outBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
- ioBuffParams.sync = IOBUff_READ_SYNC;
- ioBuffParams.nominalDelay = OUTPUT_FRAME_SIZE * (NUM_PRIME_XFERS+1);
- if(ioBuffInit(pOutIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR)
+ if (pOutIo->hMcaspChan != NULL)
{
- return -1; // to remove magic number
- }
+ // Initialize I/O BUFF and I/O PHY components for output task
+ ioBuffParams.base = pOutBuf->outBufConfig.base.pVoid;
+ // Set IO buffer size to multiple of audio frame sample count x stride x size of element.
+ // This ensures no split buffers will be allocated on Output buffer wrap.
+ ioBuffParams.size = pOutBuf->outBufConfig.allocation/(strAfSampleCount * pOutIo->stride * WORD_SIZE_PCM)*
+ (strAfSampleCount * pOutIo->stride * WORD_SIZE_PCM);
+ ioBuffParams.sync = IOBUff_READ_SYNC;
+ ioBuffParams.nominalDelay = strAfSampleCount * pOutIo->stride * WORD_SIZE_PCM * (NUM_PRIME_XFERS+1);
+ if (ioBuffInit(pOutIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR)
+ {
+ return ASOP_IO_ERR_IOBUFF_INIT; // to remove magic number
+ }
- ioPhyParams.ioBuffHandle = pOutIo->hIoBuff;
- ioPhyParams.xferFrameSize = OUTPUT_FRAME_SIZE;
- ioPhyParams.mcaspChanHandle = pOutIo->hMcaspChan;
- ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_READ;
- if(ioPhyInit(pOutIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR)
- {
- return -1; // to remove magic number
- }
+ ioPhyParams.ioBuffHandle = pOutIo->hIoBuff;
+ ioPhyParams.xferFrameSize = strAfSampleCount * pOutIo->stride * WORD_SIZE_PCM;
+ ioPhyParams.mcaspChanHandle = pOutIo->hMcaspChan;
+ ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_READ;
+ if (ioPhyInit(pOutIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR)
+ {
+ return ASOP_IO_ERR_IOPHY_INIT; // to remove magic number
+ }
- pOutIo->phyXferSize = ioPhyParams.xferFrameSize;
+ pOutIo->phyXferSize = ioPhyParams.xferFrameSize;
+
+ pOutIo->ioBuffBuf2AllocCnt = 0; // initialize buffer2 alloc count (indicates Output buffer wrap)
+ pOutIo->errIoBuffOvrCnt = 0; // initialize IO buff overflow count
+ pOutIo->errIoBuffUndCnt = 0; // initialize IO buff underflow count
+ }
- pOutIo->ioBuffBuf2AllocCnt = 0; // initialize buffer2 alloc count (indicates Output buffer wrap)
- pOutIo->errIoBuffOvrCnt = 0; // initialize IO buff overflow count
- pOutIo->errIoBuffUndCnt = 0; // initialize IO buff underflow count
-
- return 0;
+ return ASOP_IO_SOK;
} /* asopIoCompsInit */
/*======================================================================================
pOutBufCfg = &pOutBuf->outBufConfig;
hIoBuff = pOutIo->hIoBuff;
- pOutBufCfg->stride = OUTPUT_STRIDE;
+ pOutBufCfg->stride = pOutIo->stride;
pOutBufCfg->sizeofElement = WORD_SIZE_PCM;
pOutBufCfg->precision = 24;
ioBuffGetInfo(hIoBuff, &outBuffInfo);
- pOutBufCfg->base.pLgInt = outBuffInfo.base;
- pOutBufCfg->sizeofBuffer = outBuffInfo.size;
+ pOutBufCfg->base.pLgInt = outBuffInfo.base;
+ pOutBufCfg->sizeofBuffer = outBuffInfo.size;
+
+ pOutBuf->pOutBuf = &(pOutBuf->outBufConfig);
- pOutBuf->pOutBuf = &(pOutBuf->outBufConfig);
+ return ASOP_IO_SOK;
+}
+
+Int asopGetOutBufPtrs(
+ PAF_AST_IoOut *pOutIo,
+ size_t writeSize
+)
+{
+ void *buff1, *buff2;
+ size_t size1, size2;
+ Int status;
+
+ status = ioBuffGetWritePtrs(pOutIo->hIoBuff, writeSize,
+ &buff1, &size1, &buff2, &size2);
+ if (status == IOBUFF_ERR_OVERFLOW)
+ {
+ pOutIo->errIoBuffOvrCnt++;
+ //System_printf ("asopGetOutBufPtrs: output buff overflow\n"); // debug
+
+ // skip processing since output buffer overflows
+ return ASOP_IO_ERR_OUTBUF_OVERFLOW;
+ }
+ else if (status == IOBUFF_ERR_UNDERFLOW)
+ {
+ pOutIo->errIoBuffUndCnt++;
+ //System_printf ("asopGetOutBufPtrs: output buff underflow\n"); // debug
+
+ // already underflows and remain in underflow
+ }
- return 0;
+ if ((buff2 != NULL) || (size2 != 0))
+ {
+ // Two buffers allocated indicates split buffer allocation on buffer wrap.
+ pOutIo->ioBuffBuf2AllocCnt++; // increment count of allocated buffer2
+ }
+
+ // save buffer pointers & sizes for later write complete
+ pOutIo->buff1 = buff1;
+ pOutIo->size1 = size1;
+ pOutIo->buff2 = buff2;
+ pOutIo->size2 = size2;
+
+ return ASOP_IO_SOK;
}
+#if 0
// Update Output buffer configuration.
// This is needed for proper operation of PCM encoder.
Int asopUpdateOutBufConfig(
// FL, New IO: original code can change these values in every DOB issue
// Need to determine if this is required or not.
- pOutBufCfg->stride = OUTPUT_STRIDE;
+ pOutBufCfg->stride = pOutIo->stride;
pOutBufCfg->sizeofElement = WORD_SIZE_PCM;
pOutBufCfg->precision = 24;
//JXTODO: to replace hard coded write size
// Get write pointers of output memory pool
- total_write_size = pOutBufCfg->lengthofFrame * pOutBufCfg->stride * pOutBufCfg->sizeofElement;
+ total_write_size = pOutBufCfg->lengthofFrame * pOutBufCfg->stride * pOutBufCfg->sizeofElement;
status = ioBuffGetWritePtrs(hIoBuff, total_write_size,
&buff1, &size1, &buff2, &size2);
if (status == IOBUFF_ERR_OVERFLOW)
//System_printf ("asopUpdateOutBufConfig: output buff overflow\n"); // debug
// skip processing since output buffer overflows
- return -1;
+ return ASOP_IO_ERR_OUTBUF_OVERFLOW;
}
else if (status == IOBUFF_ERR_UNDERFLOW)
{
// already underflows and remain in underflow
}
-
+#if 0
// Update Output buffer pointer for Encoder
- pOutBufCfg->pntr.pLgInt = buff1;
+ pOutBufCfg->pntr.pLgInt = buff1;
if ((buff2 != NULL) || (size2 != 0))
{
// buff2 should always be NULL for Output & size2 should always be 0 for Output.
// Track this here.
pOutIo->ioBuffBuf2AllocCnt++; // debug
}
-
+#endif
// save buffer pointers & sizes for later write complete
pOutIo->buff1 = buff1;
pOutIo->size1 = size1;
pOutIo->buff2 = buff2;
pOutIo->size2 = size2;
- return 0;
+ return ASOP_IO_SOK;
}
+#endif
// Mark Output buffers write complete
Int asopMarkOutBuffsWriteComplete(
ioBuffWriteComplete(hIoBuff, buff2, size2);
}
- return 0;
+ return ASOP_IO_SOK;
}
/*======================================================================================