Started refactoring output task and integrating new I/O into output
authorJianzhong Xu <a0869574@ti.com>
Wed, 10 Jan 2018 15:50:03 +0000 (10:50 -0500)
committerJianzhong Xu <a0869574@ti.com>
Wed, 10 Jan 2018 15:50:03 +0000 (10:50 -0500)
task. PCM loopback bypassing ARM working fine for HDMI in and analog out.

pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.c
pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.h
pasdk/test_dsp/framework/audioStreamInpProc.h
pasdk/test_dsp/framework/audioStreamInpProcNewIO.c
pasdk/test_dsp/framework/audioStreamOutProc.c
pasdk/test_dsp/framework/audioStreamOutProc.h
pasdk/test_dsp/framework/audioStreamOutProcNewIO.c
pasdk/test_dsp/framework/systemInit.c

index d7ff9850c092cf6f6d4d8c140cbab36aa6ffe6a6..96913f1559482a00ef075a748f78ec1fba5a695b 100644 (file)
@@ -537,4 +537,16 @@ Audk2g_STATUS mcaspRecfgWordWidth(Ptr hMcaspChan, uint16_t wordWidth)
     }
 } /* mcaspRecfgWordWidth */
 
+/*======================================================================================
+ *  This function checks if McASP Rx overruns or Tx underruns
+ *====================================================================================*/
+int mcaspCheckOverUnderRun(Ptr mcaspChanHandle)
+{
+    Mcasp_errCbStatus mcaspErrStat;
+
+    mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
+
+    return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
+}
+
 /* Nothing past this point */
index 709043f928fa7d59d7cca6c4950b696adc319c59..d42ab0ca4c28aecf33f15ad1330c81536f157fab 100644 (file)
@@ -123,5 +123,6 @@ Audk2g_STATUS mcaspTxReset(void);
 Audk2g_STATUS mcaspRxCreate(void);
 Audk2g_STATUS mcaspRxReset(void);
 Audk2g_STATUS mcaspRecfgWordWidth(Ptr hMcaspChan, uint16_t wordWidth);
+int mcaspCheckOverUnderRun(Ptr mcaspChanHandle);
 
 #endif /* _MCASP_CONFIG_H_ */
index a53c38602755d5349743d62e3f5fff7df8321bc1..4822d76aca800f7778954c9e4cc0a198cd53e039 100644 (file)
@@ -223,6 +223,15 @@ typedef struct PAF_AST_InpIO {
     bool           swapData;
 } PAF_AST_IoInp;
 
+// Decoder structure
+typedef struct asipDecProc_s {
+    Int state;
+    Int frame;
+    Int block;
+    Int sourceSelect;
+    Int sourceProgram;
+} asipDecProc_t;
+
 // Audio Stream Input Task (ASIT) configuration
 typedef struct PAF_ASIT_Config {
     Task_Handle taskHandle;     // ASIT handle
index 9c37ea115fac5da5181d418690179cf682a6e423..f46ffd1b074c6178ed6969d44d416acce986a41e 100644 (file)
@@ -39,6 +39,7 @@ All rights reserved.
 #include <xdc/runtime/Log.h>
 #include <ti/sysbios/BIOS.h>
 
+#include "procsdk_audio_typ.h"
 #include "audioStreamInpProc.h"
 #include "audioStreamProc_common.h"
 #include "asperr.h"
@@ -117,6 +118,7 @@ Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp);
 Int asipUpdateInputStatus(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(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp);
 void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno);
 
@@ -845,6 +847,13 @@ Int asipProcessing(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
 
         ioDataReadComplete(pInp->hIoData);
 
+        if(syncState == IODATA_SYNC_BITSTREAM || syncState == IODATA_SYNC_PCM) {
+            // Decide input source after SYNC is found, i.e. either
+            // bitstream preamble is detected or it times out to PCM.
+            //sourceSelect = asipDecideSource(pP, pAstCfg, &decProc);
+
+        }
+
         if(syncState == IODATA_SYNC_BITSTREAM) {
             // Change I/O PHY transfer size to be the same as the bitstream frame size
             int frameSize;
@@ -960,9 +969,56 @@ Int asipProcessing(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
     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
+U8 pcmbuf[OUTPUT_FRAME_SIZE];
+#else
+#error Input frame length is not equal to output frame length!
+#endif
+
 Int rxDecodePcm(PAF_AST_IoInp  *pInp)
 {
+    ioDataCtl_t ioDataCtl;
+    void *buffBase;
+    void *dataStartAddress;
+    size_t buffSize, frameSize, size1, size2;
+
+    /* Get information for reading input data */
+    ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
+    ioDataControl(pInp->hIoData, &ioDataCtl);
+
+    buffBase = ioDataCtl.param.dataReadInfo.buffBase;
+    buffSize = ioDataCtl.param.dataReadInfo.buffSize;
+    dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
+    frameSize        = ioDataCtl.param.dataReadInfo.frameSize;
+
+    // Copy PCM data to output buffer
+    if(((size_t)dataStartAddress+frameSize) <= ((size_t)buffBase+buffSize)) {
+        // Input buffer doesn't wrap around
+        Cache_inv(dataStartAddress, frameSize, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[0], dataStartAddress, frameSize);
+    }
+    else {
+        // Input buffer wraps around
+        size1 = (size_t)buffBase + buffSize - (size_t)dataStartAddress;
+        size2 = frameSize - size1;
+        Cache_inv(dataStartAddress, size1, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[0], dataStartAddress, size1);
+
+        Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[size1], buffBase, size2);
+    }
+
+
     return ASIP_NO_ERR;
 }
 
@@ -971,6 +1027,7 @@ Int rxDecodeBitStream(PAF_AST_IoInp  *pInp)
     return ASIP_NO_ERR;
 }
 
+
 Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
 {
     return ASIP_NO_ERR;
index d5538a6465cea7841121891978c76fd0f257396b..44040493f1fbc1d217e3cdf0a0448af0be6539c4 100644 (file)
@@ -197,13 +197,16 @@ static Int checkOutSio(
 );
 
 // Initialize Output Processing state function
-static Int PAF_ASOT_initOutProc(
+//static Int PAF_ASOT_initOutProc(
+// used by new OutProc.c, will be changed back to static once refactoring is done
+Int PAF_ASOT_initOutProc(
     const PAF_ASOT_Params *pP, 
     PAF_AST_Stream *xStr
 );
 
 // Initialize Output Processing state function
-static Int PAF_ASOT_initSyncDecReset(
+// used by new OutProc.c, will be changed back to static once refactoring is done
+Int PAF_ASOT_initSyncDecReset(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
@@ -219,7 +222,7 @@ static Int PAF_ASOT_outputReset(
 
 //   Purpose:   Init-Sync Dec Info1 state function.
 //              Performes Dec Info1 Init-Sync.
-static Int PAF_ASOT_initSyncDecInfo1(
+Int PAF_ASOT_initSyncDecInfo1(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
@@ -235,7 +238,7 @@ static Int PAF_ASOT_outputInfo1(
 
 //   Purpose:   Init-Sync Dec Decode1 state function.
 //              Performes Dec Decode1 Init-Sync.
-static Int PAF_ASOT_initSyncDecDecode1(
+Int PAF_ASOT_initSyncDecDecode1(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg
@@ -243,7 +246,7 @@ static Int PAF_ASOT_initSyncDecDecode1(
 
 //   Purpose:   Init-Sync Re-Sync state function.
 //              Peformed Init-Sync using stored Dec Reset/Info1 AFs.
-static Int PAF_ASOT_initSyncResync(
+Int PAF_ASOT_initSyncResync(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
@@ -430,7 +433,7 @@ Void taskAsopFxnInit(
 Void taskAsopFxn(
 #else
 #ifndef IO_LOOPBACK_TEST
-Void taskAsopFxn(   // still use this for new I/O before it is refactored.
+Void taskAsopFxn_NOt_Used(
 #else
 Void taskAsopFxn_Not_Used(
 #endif
@@ -3506,7 +3509,8 @@ static Void resetAfMetadata(
 }
 
 // Initialize Output Processing state function
-static Int PAF_ASOT_initOutProc(
+//static Int PAF_ASOT_initOutProc(
+Int PAF_ASOT_initOutProc(
     const PAF_ASOT_Params *pP, 
     PAF_AST_Stream *xStr
 )
@@ -3532,7 +3536,9 @@ static Int initSyncUpdateAf(
 
 //   Purpose:   Init-Sync Dec Reset state function.
 //              Performes Dec Reset Init-Sync.
-static Int PAF_ASOT_initSyncDecReset(
+//static Int PAF_ASOT_initSyncDecReset(
+// used by new OutProc.c, will be changed back to static once refactoring is done
+Int PAF_ASOT_initSyncDecReset(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
@@ -3645,7 +3651,7 @@ Int16 gOutFrameLen=PAF_ASOT_FRAMELENGTH; // output frame length (PCM samples)
 
 //   Purpose:   Init-Sync Dec Info1 state function.
 //              Performes Dec Info1 Init-Sync.
-static Int PAF_ASOT_initSyncDecInfo1(
+Int PAF_ASOT_initSyncDecInfo1(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
@@ -3772,7 +3778,8 @@ static Int PAF_ASOT_outputInfo1(
 
 //   Purpose:   Init-Sync Dec Decode1 state function.
 //              Performes Dec Decode1 Init-Sync.
-static Int PAF_ASOT_initSyncDecDecode1(
+//static Int PAF_ASOT_initSyncDecDecode1(
+Int PAF_ASOT_initSyncDecDecode1(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg
@@ -3810,7 +3817,7 @@ static Int PAF_ASOT_initSyncDecDecode1(
 
 //   Purpose:   Init-Sync Re-Sync state function.
 //              Peformed Init-Sync using stored Dec Reset/Info1 AFs.
-static Int PAF_ASOT_initSyncResync(
+Int PAF_ASOT_initSyncResync(
     const PAF_ASOT_Params *pP, 
     const PAF_ASOT_Patchs *pQ, 
     PAF_ASOT_Config *pAsotCfg,
index 5cb7a14421e40cd94e1fcf6f15ab0d75b9770c31..09871328dbd140f37544ee7bff77669f246a11c0 100644 (file)
@@ -195,6 +195,8 @@ typedef struct PAF_ASOT_Patchs {
 typedef struct PAF_AST_OutIO {
     ioPhyHandle_t        hIoPhy;     /* handle to I/O physical layer */
     ioBuffHandle_t       hIoBuff;    /* handle to I/O buffer management */
+    Ptr                  hMcaspChan; /* handle to McASP LLD channel for output */
+    uint32_t             phyXferSize;
 
     void     *mcaspTxBuf1;
     void     *mcaspTxBuf2;
index 205d64b93648636984b6eed8bd5587a79addfe20..cdf0bb2a8499ac1a511889d6c18b3ddd39a7edcf 100644 (file)
@@ -37,23 +37,113 @@ All rights reserved.
  *  ======== audioStreamOutProc.c ========
  */
 
+#include <xdc/runtime/Log.h>
+#include <ti/sysbios/BIOS.h>
+#include <stdio.h>
+
+#include "mcasp_cfg.h"
+#include "audioStreamProc_common.h"
 #include "audioStreamOutProc.h"
+
 #include "ioConfig.h"    //TODO: remove this header
 #include "ioBuff.h"
 #include "ioPhy.h"
 #include "ioData.h"
 
+extern Ptr hMcaspTxChan;
 extern Semaphore_Handle asopSemTx;
+extern PAF_ASOT_Config gPAF_ASOT_config;
+extern volatile UInt32 gCommandOutputTask_SYNC;
+extern volatile UInt32 gCommandOutputTask_ACK;
+extern Int d10Initialized;
+
+
+static Int asopSelectDevices(PAF_AST_IoOut *pOut);
+static int asopIoCompsInit(PAF_AST_OutBuf * pOutBuf, PAF_AST_IoOut * pOutIo);
+static void asopIoPhyPrime(PAF_AST_IoOut *pOut);
+static void asopPhyTransferStart(PAF_AST_IoOut *pOut);
+static Int asopDecodePcm(PAF_AST_IoOut *pOut);
+
+// Initialize Output Processing state function
+extern Int PAF_ASOT_initOutProc(
+    const PAF_ASOT_Params *pP,
+    PAF_AST_Stream *xStr);
+
+extern Int PAF_ASOT_initSyncDecReset(
+        const PAF_ASOT_Params *pP,
+        const PAF_ASOT_Patchs *pQ,
+        PAF_ASOT_Config *pAsotCfg,
+        PAF_AudioFrame *pDecResetAf);
+
+static Int checkOutSel(
+    const PAF_ASOT_Params *pP,
+    PAF_ASOT_Config *pAsotCfg,
+    Int *pOutSel);
+
+extern Int PAF_ASOT_initSyncDecDecode1(
+    const PAF_ASOT_Params *pP,
+    const PAF_ASOT_Patchs *pQ,
+    PAF_ASOT_Config *pAsotCfg);
+
+extern Int PAF_ASOT_initSyncDecInfo1(
+    const PAF_ASOT_Params *pP,
+    const PAF_ASOT_Patchs *pQ,
+    PAF_ASOT_Config *pAsotCfg,
+    PAF_AudioFrame *pDecInfo1Af);
+
+extern Int PAF_ASOT_initSyncResync(
+    const PAF_ASOT_Params *pP,
+    const PAF_ASOT_Patchs *pQ,
+    PAF_ASOT_Config *pAsotCfg,
+    PAF_AudioFrame *pDecResetAf,
+    PAF_AudioFrame *pDecInfo1Af);
 
 extern Void taskAsopFxnInit(const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ);
 
+//
+// Audio Stream Output Task definitions
+//
+
+// status codes
+// Output FSM
+#define ASOP_INITSYNC_NOTREADY      (  1 )  // ok, init-sync not ready
+#define ASOP_SOK                    (  0 )  // ok
+#define ASOP_FORWARD_ERR            ( -1 )  // forward (ASIT) error
+#define ASOP_ENCRESET_ERR           ( -2 )  // enc reset error
+#define ASOP_DECINFO1_ERR           ( -3 )  // dec info1 error
+// Decode Processing
+#define ASOP_DP_OUT_SIO_UPDATE      (  3 )  // new output selected
+#define ASOP_DP_CB_DRAINED          (  2 )  // circular buffer drained
+#define ASOP_DP_SOK                 (  0 )  // ok
+#define ASOP_DP_FORWARD_ERR         ( -1 )  // forward (ASIT) error
+#define ASOP_DP_DECINIT_ERR         ( -2 )  // decode init error
+#define ASOP_DP_DECSTREAM_ERR       ( -3 )  // decode stream error
+#define ASOP_DP_DECENC_ERR          ( -4 )  // decode encode error
+#define ASOP_DP_DECINFO2_ERR        ( -5 )  // decode encode error
+#define ASOP_DP_DECFINALTEST_ERR    ( -6 )  // decode final error
+
+// Global debug counters */
+extern UInt32 gAsopTxSioReclaimCnt      ;
+extern UInt32 gAsopInitOutProcCnt       ;
+extern UInt32 gAsopInitSyncDecResetCnt  ;
+extern UInt32 gAsopInitSyncDecInfo1Cnt  ;
+extern UInt32 gAsopInitSyncDecDecode1Cnt;
+extern UInt32 gAsopInitSyncResyncCnt    ;
+extern UInt32 gAsopOutProcCnt           ;
+extern UInt32 gAsopInitCnt              ;
+extern UInt32 gAsopStreamCnt            ;
+extern UInt32 gAsopEncodeCnt            ;
+extern UInt32 gAsopFinalCnt             ;
+extern UInt32 gAsopOutSioUpdateCnt      ;
+extern UInt32 gAsopQuitCnt              ;
+
 /*
  *  ======== taskAsopFxn ========
  *  Audio Stream Output Processing task function
  */
 #ifndef PASDK_SIO_DEV
 #ifndef IO_LOOPBACK_TEST
-Void taskAsopFxn_Not_Used(                 // ASOP task function for new I/O
+Void taskAsopFxn(                 // ASOP task function for new I/O
 #else
 Void taskAsopFxn_NewIO_Not_Used(  // not used for loopback test
 #endif
@@ -64,10 +154,417 @@ Void taskAsopFxn_NewIO_Not_Used(  // not used for SIO_DEV I/O
     const PAF_ASOT_Patchs *pQ
 )
 {
-//    Log_info0("Enter taskAsopFxn()");
+    PAF_ASOT_Config *pAsotCfg;      /* ASOT configuration pointer */
+    PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
+    Int as;                         /* Audio Stream Number (1, 2, etc.) */
+    Int z;                          /* input/encode/stream/decode/output counter */
+    Int zMS;
+    Int errno;                      // error number
+    Int8 procSleep;                 // whether to sleep: 0: No, 1: Yes
+    Int8 procOutDevSel;             // whether to perform output device selection: 0: No, 1:Yes
+    Int outSel;                     // whether output device selected
+    enum { INIT_OUT_PROC_STATE,
+           INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE,
+           INITSYNC_RESYNC_STATE,
+           OUT_PROC_STATE } state;
+    PAF_AudioFrame decResetAf;
+    PAF_AudioFrame decInfo1Af;
+    Int loopCount = 0;              // used to stop trace to see startup behavior.
+
+    Log_info0("Enter taskAsopFxn()");
 
     taskAsopFxnInit(pP, pQ);    // initialization of output task
 
+    //
+    // Audio Stream Output Task Configuration (*pAsotCfg):
+    //
+    pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
+    pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
+
+    /* Obtain Audio Stream Number (1, 2, etc.) */
+    as = pAstCfg->as;
+
+    zMS = pAstCfg->masterStr;
+
+    //
+    // Main processing loop
+    //
+    for (z=STREAM1; z < STREAMN; z++)
+    {
+        TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z);
+    }
+
+    errno = 0;                      // init error indicator -- no error
+    procSleep = 1;                  // init sleep flag -- sleep
+    procOutDevSel = 1;              // init device output selection flag -- perform output device selection
+    state = INIT_OUT_PROC_STATE;    // init state
+    for (;;)
+    {
+        loopCount++;
+        TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
+
+        //
+        // Check forward (ASIT) error here, TBD
+        //
+
+        // Even if we are not in error state, we check if writeDECCommandRestar issued or not
+        if (gCommandOutputTask_SYNC) {
+            TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Wait for the command deasserted");
+            gCommandOutputTask_ACK = 1;
+            while (gCommandOutputTask_SYNC) {
+                Task_sleep(1);
+            }
+            TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Startover the process");
+            procSleep = 1;                  // init sleep flag -- sleep
+            procOutDevSel = 1;              // init device output selection flag -- perform output device selection
+            state = INIT_OUT_PROC_STATE;    // init state -- starover
+            errno = ASOP_DP_FORWARD_ERR;    // Override the error -- for flushing SIO output device
+        }
+
+        // any error forces idling of output
+        if (errno)
+        {
+            for (z=OUTPUT1; z < OUTPUTN; z++)
+            {
+                if (pAstCfg->xOut[z].hTxSio)
+                {
+                    //SIO_idle(pAstCfg->xOut[z].hTxSio);  TO DO: implement proper error handling
+                }
+            }
+
+            TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
+            //ERRNO_RPRT(TaskAsop, errno);
+        }
+
+        if (procSleep == 1)
+        {
+            TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
+            Task_sleep(1);
+        }
+
+        if (procOutDevSel == 1)
+        {
+            // select output devices
+            TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
+            //errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
+            errno = asopSelectDevices(&pAsotCfg->pIoOut[0]);   // Do we need to do  for (z=OUTPUT1; z < OUTPUTN; z++)
+            if (errno)
+            {
+                TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
+
+                procSleep = 1;
+                procOutDevSel = 1;
+
+                continue;
+            }
+
+            // if no output selected skip remaining processing
+            errno = checkOutSel(pP, pAsotCfg, &outSel);
+            if (errno < 0)
+            {
+                TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
+
+                procSleep = 1;
+                procOutDevSel = 1;
+
+                continue;
+            }
+            else if (!outSel)
+            {
+                TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
+
+                procSleep = 1;
+                procOutDevSel = 1;
+
+                continue;
+            }
+        } /* if (procOutDevSel == 1) */
+
+        switch (state)
+        {
+            case INIT_OUT_PROC_STATE:
+                gAsopInitOutProcCnt++;
+                Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
+
+                //
+                // Output Processing initialization.
+                //
+                errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
+                if (errno < 0)
+                {
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else
+                {
+                    //state = INITSYNC_DEC_RESET_STATE;
+                    procSleep = 0;
+                    procOutDevSel = 0;
+                    for (z=OUTPUT1; z < OUTPUTN; z++)
+                    {
+                        asopIoCompsInit(&pAstCfg->xOut[z], &pAsotCfg->pIoOut[z]);
+                    }
+
+                    // Start I/O physical layer by priming McASP LLD for output
+                    asopIoPhyPrime(&pAsotCfg->pIoOut[0]);
+
+                    state = OUT_PROC_STATE;
+                }
+
+                break;
+
+            case OUT_PROC_STATE:
+                Semaphore_pend(asopSemTx, BIOS_WAIT_FOREVER);
+
+                ioPhyXferComplete(pAsotCfg->pIoOut[0].hIoPhy, FALSE);
+
+                asopDecodePcm(&pAsotCfg->pIoOut[0]);
+
+                asopPhyTransferStart(&pAsotCfg->pIoOut[0]);
+                break;
+
+#if 0
+            case INITSYNC_DEC_RESET_STATE:
+                gAsopInitSyncDecResetCnt++;
+                Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
+
+                //
+                // Dec Reset Init-Sync.
+                //
+
+                // Perform Dec Reset init-sync.
+                // Latch Dec Reset AF.
+                errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
+                if (errno < 0)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
+
+                    // sync error -- start over
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else if (errno == ASOP_INITSYNC_NOTREADY)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
+
+                    // sync not ready -- try again
+                    state = INITSYNC_DEC_RESET_STATE;
+                    errno=0; // FL: temp hack
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else // errno==0
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
+
+                    // sync'd -- move on
+                    state = INITSYNC_DEC_INFO1_STATE;
+                    procSleep = 0;
+                    procOutDevSel = 0;
+                }
+
+                break;
+
+            case INITSYNC_DEC_INFO1_STATE:
+                gAsopInitSyncDecInfo1Cnt++;
+                Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
+
+                //
+                // Dec Info1 Init-Sync.
+                //
+
+                // Perform Dec Info1 init-sync.
+                // Latch Dec Info1 AF.
+                errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
+                if (errno < 0)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
+
+                    // sync error -- start over
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else if (errno == ASOP_INITSYNC_NOTREADY)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
+
+                    // sync not ready -- try again
+                    state = INITSYNC_DEC_INFO1_STATE;
+                    errno=0; // FL: temp hack
+                    procSleep = 1;
+                    procOutDevSel = 0;
+                }
+                else // errno = 0
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
+
+                    // sync'd -- move on
+                    state = INITSYNC_DEC_DECODE1_STATE;
+                    procSleep = 0;
+                    procOutDevSel = 0;
+                }
+
+                break;
+
+            case INITSYNC_DEC_DECODE1_STATE:
+                gAsopInitSyncDecDecode1Cnt++;
+                Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
+
+                //
+                // Dec Info1 Init-Sync.
+                //
+
+                // Perform Dec Info1 init-sync.
+                // Latch Dec Info1 AF.
+                errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
+                if (errno < 0)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
+
+                    // sync error -- start over
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else if (errno == ASOP_INITSYNC_NOTREADY)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
+
+                    // sync not ready -- try again
+                    state = INITSYNC_DEC_DECODE1_STATE;
+                    errno=0; // FL: temp hack
+                    procSleep = 1;
+                    procOutDevSel = 0;
+                }
+                else // errno = 0
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
+
+                    // sync'd -- move on
+                    state = OUT_PROC_STATE;
+                    procSleep = 0;
+                    procOutDevSel = 0;
+                }
+
+                break;
+
+            case INITSYNC_RESYNC_STATE:
+                gAsopInitSyncResyncCnt++;
+                Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
+
+                //
+                // Re-Sync.
+                // Use stored AF info from init-sync.
+                // This is done in case of local error.
+                //
+
+                // Perform Dec Info1 init-sync.
+                errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf,
+                    &decInfo1Af);
+                if (errno < 0)
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
+
+                    // sync error -- start over
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+                else
+                {
+                    Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
+
+                    // re-sync'd -- move on
+                    state = OUT_PROC_STATE;
+                    procSleep = 0;
+                    procOutDevSel = 0;
+                }
+
+                break;
+
+            case OUT_PROC_STATE:
+                gAsopOutProcCnt++;
+                Log_info0("TaskAsop: state=OUT_PROC_STATE");
+
+                //
+                // Output Processing.
+                //
+
+                TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
+                errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
+                if (errno < 0)
+                {
+                    Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
+
+                    //
+                    // Output Processing exit, due to error
+                    //
+
+                    TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
+                    if (errno == ASOP_DP_FORWARD_ERR)
+                    {
+                        // forward (ASIT) error -- start over
+                        state = INIT_OUT_PROC_STATE;
+                        procSleep = 1;
+                        procOutDevSel = 1;
+                    }
+                    else
+                    {
+                        // local (ASOT) error
+                        state = INITSYNC_RESYNC_STATE;
+                        procSleep = 1;
+                        procOutDevSel = 0; // disallow device re-select if local error during output processing
+                    }
+                }
+                else if (errno > 0)
+                {
+                    Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
+
+                    //
+                    // Output Processing exit, not due to error
+                    //
+
+                    TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
+                    if (errno == ASOP_DP_OUT_SIO_UPDATE)
+                    {
+                        // skip re-sync
+                        // resume output processing after new output selected
+                        state = OUT_PROC_STATE;
+                        procSleep = 1;
+                        procOutDevSel = 1;
+                    }
+                }
+                else
+                {
+                    Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
+
+                    //
+                    // Output Processing exit, normal
+                    //
+
+                    TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
+
+                    // no error returned if CB drained
+                    // (i.e. CB drained is normal behavior)
+                    state = INIT_OUT_PROC_STATE;
+                    procSleep = 1;
+                    procOutDevSel = 1;
+                }
+
+                break;
+#endif
+            default: // unknown state
+                TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state);
+                break;
+        } // End of switch
+
+    } // End of main processing loop for (;;)
+
+
+
 } /* taskAsopFxn */
 
 
@@ -81,4 +578,146 @@ void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
     }
 }
 
+Int asopSelectDevices(PAF_AST_IoOut *pOut)
+{
+    if((pOut->hIoBuff == NULL) || (pOut->hIoPhy == NULL) || (!d10Initialized)) {
+        return -1;
+    }
+
+    pOut->hMcaspChan = hMcaspTxChan;
+
+    return 0;
+}
+
+/* Check if at least one output selected */
+static Int checkOutSel(
+    const PAF_ASOT_Params *pP,
+    PAF_ASOT_Config *pAsotCfg,
+    Int *pOutSel
+)
+{
+    PAF_AST_IoOut  *pOut;
+    Int outSel;
+    Int z;
+
+    pOut= pAsotCfg->pIoOut; // get pointer to AST common (shared) configuration
+
+    outSel = 0;
+    for (z=OUTPUT1; z < OUTPUTN; z++)
+    {
+        if (pOut[z].hIoPhy)
+        {
+            outSel = 1;
+            break;
+        }
+    }
+
+    *pOutSel = outSel;
+
+    return ASOP_SOK;
+}
+
+#define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
+
+/*===========================================================================
+ * Initialize I/O components for output processing
+============================================================================*/
+int asopIoCompsInit(PAF_AST_OutBuf * pOutBuf, PAF_AST_IoOut * pOutIo)
+{
+    // 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) {
+        return (-1);   // to remove magic number
+    }
+
+    ioPhyParams.ioBuffHandle    = pOutIo->hIoBuff;
+    ioPhyParams.xferFrameSize   = OUTPUT_FRAME_SIZE;
+    ioPhyParams.mcaspChanHandle = hMcaspTxChan;
+    ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_READ;
+    if(ioPhyInit(pOutIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+        return (-1);   // to remove magic number
+    }
+
+    pOutIo->phyXferSize = ioPhyParams.xferFrameSize;
+
+    return 0;
+} /* asipIoCompsInit */
+
+
+/*======================================================================================
+ *  I/O physical layer prime operation required by McASP LLD
+ *====================================================================================*/
+void asopIoPhyPrime(PAF_AST_IoOut *pOut)
+{
+    Int32        count;
+
+    pOut->numPrimeXfers = NUM_PRIME_XFERS;
+
+    for(count = 0; count < pOut->numPrimeXfers; count++)
+    {
+        ioPhyXferSubmit(pOut->hIoPhy);
+    }
+} /* asipIoPhyPrime */
+
+
+/*======================================================================================
+ *  This function starts an I/O PHY transfer for output
+ *====================================================================================*/
+void asopPhyTransferStart(PAF_AST_IoOut *pOut)
+{
+    if(mcaspCheckOverUnderRun(pOut->hMcaspChan)) {
+        mcaspTxReset();
+        mcaspTxCreate();
+        pOut->hMcaspChan = hMcaspTxChan;
+    }
+    else {
+        if(ioPhyXferSubmit(pOut->hIoPhy) == IOPHY_ERR_BUFF_UNDERFLOW) {
+            // Output buffer underflows!
+            printf("\nOutput buffer underflows!\n");
+            exit(0);
+        }
+        else {
+            // Output buffer operates normally
+            ;
+        }
+    }
+}
+
+extern U8 pcmbuf[OUTPUT_FRAME_SIZE];
+
+Int asopDecodePcm(PAF_AST_IoOut *pOut)
+{
+    void *buff1, *buff2;
+    size_t size1, size2;
+    int status;
+
+    status = ioBuffGetWritePtrs(pOut->hIoBuff, pOut->phyXferSize,
+                                &buff1, &size1, &buff2, &size2);
+    if (status == IOBUFF_ERR_OVERFLOW) {
+        /* skip processing since output buffer overflows */
+        return IOBUFF_ERR_OVERFLOW;   // to use a different error code
+    }
+
+    // Copy PCM data to output buffer to be transmitted by McASP
+    memcpy(buff1, &pcmbuf[0], size1);
+    Cache_wbInv(buff1, size1, Cache_Type_ALL,TRUE);
+
+    ioBuffWriteComplete(pOut->hIoBuff, buff1, size1);
+
+    if(buff2 != NULL) {
+      memcpy(buff2, &pcmbuf[size1], size2);
+      Cache_wbInv(buff2, size2, Cache_Type_ALL,TRUE);
+
+      ioBuffWriteComplete(pOut->hIoBuff, buff2, size2);
+    }
+
+    return 0;
+}
+
 /* Nothing past this line */
index b2c03518dae2c30b8a7f54f45332c095ac4320b2..9ccb0f5211831d9b95614ef090fcdbe61120278c 100644 (file)
@@ -68,7 +68,7 @@ All rights reserved.
 #define TASK_AFP_PRI        ( 2 )
 #define TASK_AIP_PRI        ( 3 )
 #define TASK_SSP_PRI        ( 1 )
-#define TASK_ASIP_PRI       ( 5 ) //( 4 )
+#define TASK_ASIP_PRI       ( 4 ) //( 4 )
 #define TASK_ASOP_PRI       ( 4 )
 
 #define SYS_INIT_SLEEP      ( 100 )