]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blobdiff - pasdk/test_dsp/framework/audioStreamOutIo.c
PASDK-577:Add McASP LLD ch reset before McASP LLD ch delete
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutIo.c
index b367aba5610b6ae61afe1a6bdc533b79302e1844..9562fed315c93cb63067ceb924c3a1dca2053584 100644 (file)
@@ -58,37 +58,84 @@ All rights reserved.
 #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;
+    Aud_STATUS status;
 
-    if(pOut->hMcaspChan == NULL) {
-        Audk2g_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 != Audk2g_EOK) {
-            return -1;
+    // Deactivate currently active Output device
+    if (pOut->hMcaspChan != NULL)
+    {
+        
+        // check McASP LLD control API
+        mcaspControlChan(pOut->hMcaspChan, MCASP_CHAN_RESET, NULL);
+        // Delete McASP LLD channel
+        status = mcaspDeleteChan(pOut->hMcaspChan);
+        if (status != Aud_EOK)
+        {
+            Log_info0("asopSelectDevices(): McASP channel deletion failed!\n");
+            return ASOP_IO_ERR_MCASP_CFG;
         }
+        
+        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
+    }
+
+    // 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;
+            status = mcasplldChanCreate(pReqLldCfg, &mcaspChanHandle);
+            if (status != Aud_EOK) {
+                Log_info0("asopSelectDevices(): McASP channel creation failed!\n");
+                return ASOP_IO_ERR_MCASP_CFG;
+            }
 
-        pOut->hMcaspChan = mcaspChanHandle;
-        pOut->stride = lldCfg->mcaspChanParams->noOfSerRequested * lldCfg->mcaspChanParams->noOfChannels;
+            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;
+        }
+    }
+    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
@@ -106,12 +153,12 @@ Int checkOutDevSioSelUpdate(
     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
@@ -139,7 +186,7 @@ Int checkAnyOutDevSioSelUpdate(
     
     *pOutDevSelUpdate = outDevSelUpdate;
 
-    return 0;
+    return ASOP_IO_SOK;
 }
 
 // -----------------------------------------------------------------------------
@@ -243,10 +290,12 @@ Int asopSetCheckRateX(
                 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
             }
 #endif // FL, New IO
+            // FL: ugly little experiment
+            //*(volatile UInt32 *)0x23400B0 |= 7;
         }
     }
 
-    return 0;
+    return ASOP_IO_SOK;
 } //asopSetCheckRateX
 
 // -----------------------------------------------------------------------------
@@ -306,21 +355,21 @@ Int asopStartOutput(
 // 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
@@ -330,13 +379,13 @@ Int asopStartOutput(
 #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 * pOut[z].stride * WORD_SIZE_PCM;
-            // Update IO Phy transfer size            
+            // 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)
             {
@@ -386,7 +435,7 @@ Int asopStartOutput(
         }
     }
 
-    return 0;
+    return ASOP_IO_SOK;
 } /* asopStartOutput */
 
 // -----------------------------------------------------------------------------
@@ -412,7 +461,7 @@ Int asopStopOutput(
     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;
@@ -422,6 +471,7 @@ Int asopStopOutput(
     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) 
@@ -520,39 +570,46 @@ Int asopStopOutput(
  * 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 = NUM_CYCLE_PER_OUTPUT_FRAME_DEF * pOutIo->stride * WORD_SIZE_PCM * (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   = NUM_CYCLE_PER_FRAME_DEF * pOutIo->stride * WORD_SIZE_PCM;
-    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 */
 
 /*======================================================================================
@@ -601,12 +658,12 @@ Int asopInitOutBufConfig(
     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 0;
+    return ASOP_IO_SOK;
 }
 
 Int asopGetOutBufPtrs(
@@ -626,7 +683,7 @@ Int asopGetOutBufPtrs(
         //System_printf ("asopGetOutBufPtrs: 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)
     {
@@ -635,6 +692,12 @@ Int asopGetOutBufPtrs(
 
         // already underflows and remain in underflow
     }
+    
+    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;
@@ -642,7 +705,7 @@ Int asopGetOutBufPtrs(
     pOutIo->buff2 = buff2;
     pOutIo->size2 = size2;
 
-    return 0;
+    return ASOP_IO_SOK;
 }
 
 #if 0
@@ -671,7 +734,7 @@ Int asopUpdateOutBufConfig(
     
     //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) 
@@ -680,7 +743,7 @@ Int asopUpdateOutBufConfig(
         //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) 
     {
@@ -691,7 +754,7 @@ Int asopUpdateOutBufConfig(
     }
 #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.
@@ -705,7 +768,7 @@ Int asopUpdateOutBufConfig(
     pOutIo->buff2 = buff2;
     pOutIo->size2 = size2;
     
-    return 0;
+    return ASOP_IO_SOK;
 }
 #endif
 
@@ -734,7 +797,7 @@ Int asopMarkOutBuffsWriteComplete(
         ioBuffWriteComplete(hIoBuff, buff2, size2);
     }
     
-    return 0;
+    return ASOP_IO_SOK;
 }
 
 /*======================================================================================