summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: aa43fe6)
raw | patch | inline | side by side (parent: aa43fe6)
author | Jianzhong Xu <a0869574@ti.com> | |
Fri, 15 Dec 2017 21:02:51 +0000 (16:02 -0500) | ||
committer | Jianzhong Xu <a0869574@ti.com> | |
Fri, 15 Dec 2017 21:02:51 +0000 (16:02 -0500) |
initPhaseMalloc. Added McASP LLD to application\itopo\evmk2g.
Standalone test works fine. PASDK functionality stays unchanged.
Standalone test works fine. PASDK functionality stays unchanged.
23 files changed:
index 00d64ecaf620fd4aa0d372cebc72b6b12d4748b4..0ec0ad6e592cf8e416ae9ad8db1ef8554ac8ac9d 100644 (file)
--- a/pasdk/test_dsp/.cproject
+++ b/pasdk/test_dsp/.cproject
<stringMacro name="USB_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
<stringMacro name="UART_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
<stringMacro name="QMSS_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
- <stringMacro name="PDK_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti/pdk_k2g_1_0_6/packages"/>
+ <stringMacro name="PDK_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti/pdk_k2g_1_0_7/packages"/>
<stringMacro name="SRIO_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
<stringMacro name="SA_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
<stringMacro name="PRUSS_INSTALL_PATH" type="VALUE_PATH_DIR" value="C:/ti"/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/csl""/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/addon/audk2g/include""/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/board""/>
+ <listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/drv/mcasp""/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}""/>
+ <listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/test_dsp/io""/>
<listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/test_dsp/sap""/>
<listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/test_dsp/mib""/>
<listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/test_dsp/mob""/>
<listOptionValue builtIn="false" value=""libc.a""/>
<listOptionValue builtIn="false" value="ti.addon.audk2g.ae66"/>
<listOptionValue builtIn="false" value="ti.board.ae66"/>
+ <listOptionValue builtIn="false" value="ti.drv.mcasp.ae66"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_8.1.linkerID.SEARCH_PATH.1285174236" name="Add <dir> to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.C6000_8.1.linkerID.SEARCH_PATH" valueType="libPaths">
<listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/lib""/>
<listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/addon/audk2g/lib/k2g/c66/release""/>
<listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/board/lib/evmK2G/c66/release""/>
+ <listOptionValue builtIn="false" value=""${PDK_INSTALL_PATH}/ti/drv/mcasp/lib/k2g/c66/release""/>
<listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/paf/pa/build/c66x/release""/>
<listOptionValue builtIn="false" value=""${PROC_AUDIO_SDK_ROOT}/pasdk/paf/pa/util/da10x_misc/c66x/release""/>
<listOptionValue builtIn="false" value=""${TI_MAS_DSPLIB_C66X_INSTALL_DIR}/packages/ti/dsplib/lib""/>
diff --git a/pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.c b/pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.c
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+ * Copyright (c) 2015, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file mcasp_config.c
+ *
+ * \brief Configures McASP module
+ *
+ */
+
+#include "mcasp_cfg.h"
+#include "ioConfig.h"
+
+#define AUDIO_DAC0_TEST
+
+/* McASP device handles */
+Ptr hMcaspDevTx;
+Ptr hMcaspDevRx;
+
+/* McASP channel handles */
+Ptr hMcaspTxChan;
+Ptr hMcaspRxChan;
+Ptr hMcaspRxChan2;
+
+/* McASP channel parameters */
+Mcasp_Params mcaspTxParams;
+Mcasp_Params mcaspRxParams;
+
+/* McASP Callback function argument */
+//uint32_t txChanMode;
+//uint32_t rxChanMode;
+
+/* Error flag */
+uint32_t gblErrFlag = 0;
+Error_Block eb;
+
+void GblErr(Mcasp_errCbStatus arg);
+
+/* External function declarations */
+extern void McaspDevice_init(void);
+extern signed char* getGlobalAddr(signed char* addr);
+
+#ifdef IO_LOOPBACK_TEST
+extern void mcaspAppCallbackRx(void* arg, MCASP_Packet *mcasp_packet);
+extern void mcaspAppCallbackTx(void* arg, MCASP_Packet *mcasp_packet);
+#else
+void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
+{
+ // to be moved to and defined in asip processing
+}
+void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
+{
+ // to be moved to and defined in asop processing
+}
+#endif
+
+/* McASP HW setup for receive */
+Mcasp_HwSetupData mcaspRcvSetup = {
+ MCASP_DIR_RMASK, /* .rmask: 0xFFFFFFFF */
+ MCASP_DIR_RFMT, /* .rfmt: 0x000180F0 */
+ MCASP_DIR_AFSRCTL, /* .afsrctl: 0x00000111 */
+ MCASP_DIR_RTDM, /* .rtdm: 0x00000003 */
+ MCASP_DIR_RINTCTL, /* .rintctl: 0x00000000 */
+ MCASP_DIR_RSTAT, /* .rstat: 0x000001FF */
+ MCASP_DIR_REVTCTL, /* .revtctl */
+ {
+ MCASP_DIR_ACLKRCTL, /* .aclkrctl: 0x00000080 */
+ MCASP_DIR_AHCLKRCTL, /* .ahclkrctl: 0x00000000 */
+ MCASP_DIR_RCLKCHK /* .rclkchk: 0x00000000 */
+ }
+};
+
+/* McASP HW setup for transmit */
+Mcasp_HwSetupData mcaspXmtSetup = {
+ /* .xmask = */ 0xFFFFFFFF, /* 16 bits are to be used */
+ /* .xfmt = */ 0x000180F0, /*
+ * 0 bit delay from framesync
+ * MSB first
+ * No extra bit padding
+ * Padding bit (ignore)
+ * slot Size is 32
+ * Reads from DMA port
+ * NO rotation
+ */
+ /* .afsxctl = */ 0x00000112, /* I2S mode - 2 slot TDM
+ * Frame sync is one word
+ * Rising edge is start of frame
+ * Internally generated frame sync
+ */
+ /* .xtdm = */ 0x00000003, /* slot 1 and 2 are active (I2S) */
+ /* .xintctl = */ 0x00000000, /* sync error,overrun error,clK error */
+ /* .xstat = */ 0x000001FF, /* reset any existing status bits */
+ /* .xevtctl = */ 0x00000000, /* DMA request is enabled or disabled */
+ {
+ /* .aclkxctl = */ 0X000000E1,
+ /* .ahclkxctl = */ 0x00004000 ,
+ /* .xclkchk = */ 0x00000000
+ },
+
+};
+
+#ifdef INPUT_SPDIF
+/* McAsp channel parameters for receive - DIR */
+Mcasp_ChanParams mcaspRxChanParam =
+{
+ 0x0001, /* Number of serializers */
+ {Mcasp_SerializerNum_5}, /* Serializer index */
+ &mcaspRcvSetup,
+ TRUE,
+ Mcasp_OpMode_TDM, /* Mode (TDM/DIT) */
+ Mcasp_WordLength_32,
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_1SER_MULTISLOT_INTERLEAVED,
+ TRUE,
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked */
+ Mcasp_WordBitsSelect_MSB /* wordBitsSelect */
+};
+#endif
+
+/* McASP LLD channel parameters for HDMI input:
+ * When slot size of McASP is configured to 32-bit, HDMI data always come to 16 MSBs of the slot
+ * and the 16 LSBs are filled with 0's. This is the nature of HDMI and I2S.
+ * For PCM data, we want all 32 bits in the slot to be transferred to the input buffer:
+ * - wordWidth = Mcasp_WordLength_32
+ * - isDataPacked = 1,
+ * - wordBitsSelect having no effect since wordWidth = slot size
+ * For bit stream, we want only 16 MSBs in the slot to be transferred to the input buffer:
+ * - wordWidth = Mcasp_WordLength_16
+ * - isDataPacked = 1,
+ * - wordBitsSelect = Mcasp_WordBitsSelect_MSB
+ */
+#ifdef INPUT_HDMI_4xI2S
+/* McAsp channel parameters for receive - HDMI 4XI2S layout */
+Mcasp_ChanParams mcaspRxChanParam =
+{
+ 0x0004, /* number of serializers */
+ {Mcasp_SerializerNum_12,
+ Mcasp_SerializerNum_13,
+ Mcasp_SerializerNum_14,
+ Mcasp_SerializerNum_15 }, /* serializer index */
+ &mcaspRcvSetup,
+ TRUE,
+ Mcasp_OpMode_TDM, /* Mode (TDM/DIT) */
+#ifdef INPUT_PCM_ONLY
+ Mcasp_WordLength_32, /* 32-bit word length, whole slot (size=32) to be transfered */
+#else
+ Mcasp_WordLength_16, /* 16-bit word length, MSB or LSB of slot to be transfered, depending on wordBitsSelect */
+#endif
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
+ TRUE, /* enableHwFifo */
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked, only transfer the selected bits of slot, based on wordWidth and wordBitsSelect */
+ Mcasp_WordBitsSelect_MSB /* wordBitsSelect, only matters if wordWidth < slot size */
+};
+#endif
+
+#ifdef INPUT_HDMI_STEREO
+/* McAsp channel parameters for receive - HDMI 1XI2S layout */
+Mcasp_ChanParams mcaspRxChanParam =
+{
+ 0x0001, /* Number of serializers */
+ {Mcasp_SerializerNum_12}, /* Serializer index */
+ &mcaspRcvSetup,
+ TRUE,
+ Mcasp_OpMode_TDM, /* Mode (TDM/DIT) */
+ Mcasp_WordLength_32,
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_1SER_MULTISLOT_INTERLEAVED,
+ TRUE, /* enableHwFifo */
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked */
+ Mcasp_WordBitsSelect_MSB /* wordBitsSelect */
+};
+#endif
+
+/* McAsp channel parameters for transmit - DAC0 */
+#ifndef TX_MCASP_USE_MULT_SER
+Mcasp_ChanParams mcaspTx0ChanParam =
+{
+ 0x0001, /* number of serializers */
+ {Mcasp_SerializerNum_0}, /* serializer index for DAC0 */
+ &mcaspXmtSetup,
+ TRUE,
+ Mcasp_OpMode_TDM,
+ Mcasp_WordLength_32, /* word width */
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_1SER_MULTISLOT_INTERLEAVED,
+ TRUE,
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked */
+ Mcasp_WordBitsSelect_LSB /* wordBitsSelect */
+};
+#else
+Mcasp_ChanParams mcaspTx0ChanParam =
+{
+ 0x0004, /* number of serializers */
+ {Mcasp_SerializerNum_0,
+ Mcasp_SerializerNum_1,
+ Mcasp_SerializerNum_2,
+ Mcasp_SerializerNum_3 }, /* serializer index for DAC0 */
+ &mcaspXmtSetup,
+ TRUE,
+ Mcasp_OpMode_TDM,
+ Mcasp_WordLength_32, /* word width */
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
+ TRUE,
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked */
+ Mcasp_WordBitsSelect_LSB /* wordBitsSelect */
+};
+#endif
+
+/* McAsp channel parameters for transmit - DAC1 */
+Mcasp_ChanParams mcaspTx1ChanParam =
+{
+ 0x0001, /* number of serializers */
+ {Mcasp_SerializerNum_4}, /* serializer index for DAC0 */
+ &mcaspXmtSetup,
+ TRUE,
+ Mcasp_OpMode_TDM,
+ Mcasp_WordLength_32, /* word width */
+ NULL,
+ 0,
+ NULL,
+ GblErr,
+ 2, /* number of TDM channels */
+ Mcasp_BufferFormat_1SER_MULTISLOT_INTERLEAVED,
+ TRUE,
+ 1, /* hwFifoEventDMARatio */
+ TRUE, /* isDataPacked */
+ Mcasp_WordBitsSelect_LSB /* wordBitsSelect */
+};
+
+/* Handle to eDMA */
+extern EDMA3_DRV_Handle hEdma0;
+extern EDMA3_DRV_Handle hEdma1;
+
+/**
+ * \brief Function called by McASP driver in case of error
+ *
+ * \return None
+ */
+void GblErr(Mcasp_errCbStatus arg)
+{
+ gblErrFlag = 1;
+}
+
+
+/* DAC default configuration parameters */
+DacConfig DAC_Cfg =
+{
+ AUDK2G_DAC_AMUTE_CTRL_DAC_DISABLE_CMD, /* Amute event */
+ 0, /* Amute control */
+ AUDK2G_DAC_SAMPLING_MODE_AUTO, /* Sampling mode */
+ AUDK2G_DAC_DATA_FORMAT_I2S, /* Data format */
+ 0, /* Soft mute control */
+ AUDK2G_DAC_ATTENUATION_WIDE_RANGE, /* Attenuation mode */
+ AUDK2G_DAC_DEEMP_DISABLE, /* De-emph control */
+ 100 /* Volume */
+};
+
+/**
+ * \brief Configures audio DAC module
+ *
+ * \return none
+ */
+void configAudioDAC(void)
+{
+ Audk2g_STATUS status;
+
+ audk2g_delay(10000);
+
+ /* Initialize Audio DAC module */
+ status = audioDacConfig(AUDK2G_DAC_DEVICE_ALL, &DAC_Cfg);
+ if(status != Audk2g_EOK)
+ {
+ //platform_write("Audio DAC Configuration Failed!\n");
+ //testRet(1);
+ }
+}
+
+/**
+ * \brief Configures McASP module and creates the channel
+ * for audio Tx and Rx
+ *
+ * \return Audk2g_EOK on Success or error code
+ */
+Audk2g_STATUS mcaspAudioConfig(void)
+{
+ Int status;
+
+ hMcaspDevTx = NULL;
+ hMcaspDevRx = NULL;
+ hMcaspTxChan = NULL;
+ hMcaspRxChan = NULL;
+
+ /* Initialize McASP Tx and Rx parameters */
+ mcaspTxParams = Mcasp_PARAMS;
+ mcaspRxParams = Mcasp_PARAMS;
+
+ mcaspTxParams.mcaspHwSetup.tx.clk.clkSetupClk = 0x23; // not used
+ mcaspTxParams.mcaspHwSetup.rx.clk.clkSetupClk = 0x23; // not used
+ mcaspRxParams.mcaspHwSetup.rx.clk.clkSetupClk = 0x23;
+ mcaspRxParams.mcaspHwSetup.tx.clk.clkSetupClk = 0x63; // Asynchronous. Separate clock and frame sync used by transmit and receive sections.
+
+#ifndef INPUT_SPDIF
+ mcaspRxParams.mcaspHwSetup.glb.pdir |= 0x2000000; //Special case, since for HDMI input - mcasp0 is both Rx & Tx
+ mcaspRxParams.mcaspHwSetup.glb.amute = 0x2; // this to ensure one doesn't overwrite the other (rx/tx)
+ mcaspTxParams.mcaspHwSetup.glb.pdir |= 0x2000000; //Set Amute pin as output for Tx channel
+ mcaspTxParams.mcaspHwSetup.glb.amute = 0x2;
+#else
+ mcaspTxParams.mcaspHwSetup.glb.pdir |= 0x2000000; //Set Amute pin as output for Tx channel
+ mcaspTxParams.mcaspHwSetup.glb.amute = 0x2;
+#endif
+
+ /* Set the HW interrupt number */
+ //mcaspTxParams.hwiNumber = 8;
+ //mcaspRxParams.hwiNumber = 8;
+
+ /* Initialize eDMA handle */
+#ifdef INPUT_SPDIF
+ mcaspRxChanParam.edmaHandle = hEdma1;
+#else
+ mcaspRxChanParam.edmaHandle = hEdma0;
+#endif
+
+ mcaspTx0ChanParam.edmaHandle = hEdma0;
+ mcaspTx1ChanParam.edmaHandle = hEdma0;
+
+#ifdef INPUT_SPDIF
+ /* Bind McASP0 for Tx */
+ status = mcaspBindDev(&hMcaspDevTx, CSL_MCASP_0, &mcaspTxParams);
+ if((status != MCASP_COMPLETED) || (hMcaspDevTx == NULL))
+ {
+ //IFPRINT(platform_write("mcaspBindDev for Tx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ /* Bind McASP2 for Rx */
+ status = mcaspBindDev(&hMcaspDevRx, CSL_MCASP_2, &mcaspRxParams);
+ if((status != MCASP_COMPLETED) || (hMcaspDevRx == NULL))
+ {
+ //IFPRINT(platform_write("mcaspBindDev for Rx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+#else /* HDMI or HDMI_STEREO */
+ /* Bind McASP0 for Rx and Tx */
+ status = mcaspBindDev(&hMcaspDevRx, CSL_MCASP_0, &mcaspRxParams);
+ if((status != MCASP_COMPLETED) || (hMcaspDevRx == NULL))
+ {
+ //IFPRINT(platform_write("mcaspBindDev for Rx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ hMcaspDevTx = hMcaspDevRx;
+#endif
+
+ /* Create McASP channel for Tx */
+ status = mcaspCreateChan(&hMcaspTxChan, hMcaspDevTx,
+ MCASP_OUTPUT,
+#ifdef AUDIO_DAC0_TEST
+ &mcaspTx0ChanParam,
+#else
+ &mcaspTx1ChanParam,
+#endif
+#ifdef IO_LOOPBACK_TEST
+ mcaspAppCallbackTx, NULL);
+#else
+ asopMcaspCallback, NULL);
+#endif
+
+ if((status != MCASP_COMPLETED) || (hMcaspTxChan == NULL))
+ {
+ //IFPRINT(platform_write("mcaspCreateChan for Tx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ /* Create McASP channel for Rx */
+ status = mcaspCreateChan(&hMcaspRxChan, hMcaspDevRx,
+ MCASP_INPUT,
+ &mcaspRxChanParam,
+#ifdef IO_LOOPBACK_TEST
+ mcaspAppCallbackRx, NULL);
+#else
+ asipMcaspCallback, NULL);
+#endif
+
+ if((status != MCASP_COMPLETED) || (hMcaspRxChan == NULL))
+ {
+ //IFPRINT(platform_write("mcaspCreateChan for Rx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ return (Audk2g_EOK);
+} /* mcaspAudioConfig */
+
+Audk2g_STATUS mcaspRxDeInit(void)
+{
+ mcaspDeleteChan(hMcaspRxChan);
+ hMcaspRxChan = NULL;
+
+ mcaspUnBindDev(hMcaspDevRx);
+ hMcaspDevRx = NULL;
+
+ return (Audk2g_EOK);
+}
+
+Audk2g_STATUS mcaspRxReset(void)
+{
+ if(hMcaspRxChan != NULL) {
+ mcaspDeleteChan(hMcaspRxChan);
+ hMcaspRxChan = NULL;
+ }
+
+ return (Audk2g_EOK);
+}
+
+Audk2g_STATUS mcaspRxCreate(void)
+{
+ Int status;
+
+ /* Create McASP channel for Rx */
+ status = mcaspCreateChan(&hMcaspRxChan, hMcaspDevRx,
+ MCASP_INPUT,
+ &mcaspRxChanParam,
+#ifdef IO_LOOPBACK_TEST
+ mcaspAppCallbackRx, NULL);
+#else
+ asipMcaspCallback, NULL);
+#endif
+
+ if((status != MCASP_COMPLETED) || (hMcaspRxChan == NULL))
+ {
+ //IFPRINT(platform_write("mcaspCreateChan for Rx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ return (Audk2g_EOK);
+}
+
+Audk2g_STATUS mcaspTxReset(void)
+{
+ if(hMcaspTxChan != NULL) {
+ mcaspDeleteChan(hMcaspTxChan);
+ hMcaspTxChan = NULL;
+ }
+
+ return (Audk2g_EOK);
+}
+
+Audk2g_STATUS mcaspTxCreate(void)
+{
+ Int status;
+
+ /* Create McASP channel for Tx */
+ status = mcaspCreateChan(&hMcaspTxChan, hMcaspDevTx,
+ MCASP_OUTPUT,
+ &mcaspTx0ChanParam,
+#ifdef IO_LOOPBACK_TEST
+ mcaspAppCallbackTx, NULL);
+#else
+ asopMcaspCallback, NULL);
+#endif
+ if((status != MCASP_COMPLETED) || (hMcaspTxChan == NULL))
+ {
+ //IFPRINT(platform_write("mcaspCreateChan for Tx Failed\n"));
+ return (Audk2g_EFAIL);
+ }
+
+ return (Audk2g_EOK);
+}
+
+Audk2g_STATUS mcaspRxCfgPCM(void)
+{
+ Int status = Audk2g_EOK;
+
+ if( (mcaspRxChanParam.wordWidth != Mcasp_WordLength_32)
+ /*|| (mcaspRxChanParam.wordBitsSelect != Mcasp_WordBitsSelect_LSB)*/ )
+ {
+ mcaspRxReset();
+
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_32;
+ //mcaspRxChanParam.wordBitsSelect = Mcasp_WordBitsSelect_LSB;
+
+ status = mcaspRxCreate();
+ }
+
+ return status;
+} // mcaspRxCfgPCM
+
+Audk2g_STATUS mcaspRxCfgBitstream(void)
+{
+ Int status = Audk2g_EOK;
+
+ if( (mcaspRxChanParam.wordWidth != Mcasp_WordLength_16)
+ /*|| (mcaspRxChanParam.wordBitsSelect != Mcasp_WordBitsSelect_MSB)*/ )
+ {
+ mcaspRxReset();
+
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_16;
+ //mcaspRxChanParam.wordBitsSelect = Mcasp_WordBitsSelect_MSB;
+
+ status = mcaspRxCreate();
+ }
+
+ return status;
+} // mcaspRxCfgBitstream
+
+/* Nothing past this point */
diff --git a/pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.h b/pasdk/test_dsp/application/itopo/evmk2g/mcasp_cfg.h
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file mcasp_config.h
+ *
+ * \brief McASP configuration header file
+ *
+ */
+
+#ifndef _MCASP_CONFIG_H_
+#define _MCASP_CONFIG_H_
+
+#include <xdc/std.h>
+#include <xdc/runtime/Memory.h>
+#include <xdc/runtime/IHeap.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/System.h>
+
+#include <ti/sysbios/io/GIO.h>
+#include <ti/sysbios/io/IOM.h>
+#include <ti/sysbios/heaps/HeapMem.h>
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Semaphore.h>
+#include <ti/sdo/edma3/drv/edma3_drv.h>
+#include <ti/sysbios/knl/Task.h>
+#include <ti/sysbios/hal/Cache.h>
+#include <ti/sysbios/family/c64p/Hwi.h>
+
+#include <stdio.h>
+
+#include <mcasp_drv.h>
+
+#include "audio_dc_cfg.h"
+#include "edma_cfg.h"
+
+/**
+ * \brief McASP configurations for Rx - DIR
+ */
+/** Receive format unit bit mask register defult value */
+#define MCASP_DIR_RMASK (0xFFFFFFFF)
+
+/** Receive bit stream format register defult value */
+#define MCASP_DIR_RFMT ( ( 1 << 16) /* RDATDLY: Transmit with 1 bit delay */ \
+ | ( 1 << 15) /* RXRVRS : MSB first */ \
+ | ( 0 << 13) /* RPAD : Pad extra bits with 0 */ \
+ | (15 << 4) /* RSSZ : 32-bit slot size */ \
+ | ( 0 << 3) /* RBUSSEL: Reads from edma port */ \
+ | ( 0 << 0)) /* RROT : No rotation */
+
+/** Receive frame sync control register defult value */
+#define MCASP_DIR_AFSRCTL ( (2 << 7) /* RMOD : 2-slot TDM */ \
+ | (1 << 4) /* FRWID: Single word frame sync */ \
+ | (0 << 1) /* FSRM : Externally-generated rx frame sync */ \
+ | (1 << 0)) /* FSRP : Start on falling edge */
+
+/** Receive TDM time slot 0-31 register defult value */
+#define MCASP_DIR_RTDM (0x00000003)
+
+/** Receive interrupt control register defult value */
+#define MCASP_DIR_RINTCTL (0x00000000)
+
+/** Receive status register defult value */
+#define MCASP_DIR_RSTAT (0x000001FF)
+
+/** Receive DMA event control register defult value */
+#define MCASP_DIR_REVTCTL (0x00000000)
+
+/** Receive clock control register defult value */
+#define MCASP_DIR_ACLKRCTL ( (1 << 7) /* CLKRP : RX on raising edge */ \
+ | (0 << 5) /* CLKRM : Externally generated ACLK */ \
+ | (0 << 0)) /* CLKRDIV: NA */
+
+/** Receive high-frequency clock control register defult value */
+#define MCASP_DIR_AHCLKRCTL ( (0 << 15) /* HCLKRM : Clock from AHCLKR pin */ \
+ | (0 << 14) /* HCLKRP : Falling edge */ \
+ | (0x400 << 0)) /* HCLKRDIV: AHCLKR = AUXCLK / 1 */
+
+/** Receive clock check control register defult value */
+#define MCASP_DIR_RCLKCHK (0x00000000)
+
+/**
+ * \brief Configures McASP module and creates the channel
+ * for audio Tx and Rx
+ *
+ * \return Platform_EOK on Success or error code
+ */
+Audk2g_STATUS mcaspAudioConfig(void);
+
+Audk2g_STATUS mcaspTxCreate(void);
+Audk2g_STATUS mcaspTxReset(void);
+Audk2g_STATUS mcaspRxCreate(void);
+Audk2g_STATUS mcaspRxReset(void);
+
+#endif /* _MCASP_CONFIG_H_ */
diff --git a/pasdk/test_dsp/application/itopo/evmk2g/sap_d10.c b/pasdk/test_dsp/application/itopo/evmk2g/sap_d10.c
index 8a1d201e73005396b47a9be699d3fe99cac76028..27b25a64066222a5c62158f2b831ec07c39bfe73 100644 (file)
return(audk2g_gpioReadInput(AUDK2G_GPIO_PORT_0, AUDK2G_AUDIO_HSR_HMINTz_GPIO));
}
+XDAS_Int32 D10_init()
+{
+ XDAS_Int32 result = 0;
+
+ // perform one time hardware initialization
+ if (!initDone) {
+ result = initD10 (NULL);
+ if (result) {
+ return result;
+ }
+ initDone = 1;
+ }
+
+ return 0;
+}
// EOF
index 41e959c7cb2e5132f5d1a10d21696b01c1bc3232..2a3a5323a8407ad51866063f01b15153428c5682 100644 (file)
#include "pfp/pfp.h"
#include "pfp_app.h" /* contains all PFP ID's */
+#include "ioConfig.h" //TODO: remove this header
extern Void initDev2(Void);
extern void evmI2CInit(uint8_t i2cportnumber); // missing in evmc66x_i2c.h
+#ifdef IO_LOOPBACK_TEST
+extern void McaspDevice_init();
+extern void D10_init();
+extern Audk2g_STATUS mcaspAudioConfig();
+extern void audioIoCreate(void);
+extern void ioSemaphoreCreate(void);
+#endif
+
/*
* ======== main ========
*/
//testRet(1);
}
+#ifdef PASDK_SIO_DEV
Log_info0("initDev2");
initDev2();
+#endif
+
+#ifdef IO_LOOPBACK_TEST
+ /* Initialize McASP HW details */
+ McaspDevice_init();
+
+ D10_init();
+
+#ifdef INPUT_SPDIF
+ // Input is DIR
+ AudStatus = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
+#else
+ // Input is HDMI
+ AudStatus = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
+#endif
+ if(AudStatus != Audk2g_EOK)
+ {
+ Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
+ }
+ audk2g_delay(50000); // Without delay between these 2 calls system aborts.
+
+ /* Initialize McASP module */
+ status = mcaspAudioConfig();
+ if(status != Audk2g_EOK)
+ {
+ Log_info0("McASP Configuration Failed!\n");
+ }
+
+ ioSemaphoreCreate();
+
+ audioIoCreate();
+
+ Task_setPri(TaskAfp, -1);
+ Task_setPri(TaskAip, -1);
+ Task_setPri(TaskSysInit, -1);
+ Task_setPri(TaskAsip, 5);
+ Task_setPri(TaskAsop, 5);
+#endif
Log_info0("IPC start");
// Initialize IPC
diff --git a/pasdk/test_dsp/framework/audioStreamInpProc.c b/pasdk/test_dsp/framework/audioStreamInpProc.c
index fb7b6ec41b305d481e6640ab349bead587db140c..7449c0779cb931933b0133c79eef76548e65c5eb 100644 (file)
#include "pfp/pfp.h"
#include "pfp_app.h" /* contains all PFP ID's */
+#include "ioConfig.h"
+
Int32 gNumPfpAsit1=0; // debug
Int32 gNumPfpAsit2=0;
* ======== taskAsipFxn ========
* Audio Stream Input Processing task function
*/
+#ifdef PASDK_SIO_DEV
Void taskAsipFxn(
-// Int betaPrimeValue, // FL: revisit
+#else
+Void taskAsipFxn_Not_Used(
+#endif
const PAF_ASIT_Params *pP,
const PAF_ASIT_Patchs *pQ
)
//Log_info0("Exit taskAsipFxn()");
}
+Int PAF_ASIT_ioCompCreate(PAF_AST_IoInp *pIoInp, int numInp, IHeap_Handle iHeapHandle)
+{
+ int i, j, num_alloc;
+ lib_mem_rec_t *mem_rec;
+ ioBuffHandle_t ioBufHandle;
+ ioPhyHandle_t ioPhyHandle;
+ ioDataHandle_t ioDataHandle;
+ Error_Block eb;
+
+ for(i=0; i<numInp; i++)
+ {
+ // Create an I/O BUFF instance
+ // Obtain number of memory blocks required by I/O BUFF
+ num_alloc = ioBuffNumAlloc();
+
+ // Obtain requirements of each memory block
+ mem_rec = (lib_mem_rec_t *)malloc(sizeof(lib_mem_rec_t)*num_alloc);
+ if(ioBuffAlloc(mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ /* Allocate memory and create I/O BUFF instance */
+ for(j=0; j<num_alloc; j++) {
+ mem_rec[j].base = Memory_calloc(iHeapHandle, mem_rec[j].size,
+ (1<<mem_rec[j].alignment), &eb);
+ }
+
+ if(ioBuffCreate(&ioBufHandle, mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ pIoInp[i].hIoBuff = ioBufHandle;
+
+ free(mem_rec);
+
+ // Create an I/O PHY instance
+ // Obtain number of memory blocks required by I/O PHY
+ num_alloc = ioPhyNumAlloc();
+
+ // Obtain requirements of each memory block
+ mem_rec = (lib_mem_rec_t *)malloc(sizeof(lib_mem_rec_t)*num_alloc);
+ if(ioPhyAlloc(mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ /* Allocate memory and create I/O PHY instance */
+ for(j=0; j<num_alloc; j++) {
+ mem_rec[j].base = Memory_calloc(iHeapHandle, mem_rec[j].size,
+ (1<<mem_rec[j].alignment), &eb);
+ }
+
+ if(ioPhyCreate(&ioPhyHandle, mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ pIoInp[i].hIoPhy = ioPhyHandle;
+
+ free(mem_rec);
+
+ // Create an I/O DATA instance
+ // Obtain number of memory blocks required by I/O DATA
+ num_alloc = ioDataNumAlloc();
+
+ // Obtain requirements of each memory block
+ mem_rec = (lib_mem_rec_t *)malloc(sizeof(lib_mem_rec_t)*num_alloc);
+ if(ioDataAlloc(mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ /* Allocate memory and create I/O DATA instance */
+ for(j=0; j<num_alloc; j++) {
+ mem_rec[j].base = Memory_calloc(iHeapHandle, mem_rec[j].size,
+ (1<<mem_rec[j].alignment), &eb);
+ }
+
+ if(ioDataCreate(&ioDataHandle, mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ pIoInp[i].hIoData = ioDataHandle;
+
+ free(mem_rec);
+
+ } // end of for loop
+
+ return 0;
+} // PAF_ASIT_ioCompCreate
+
// -----------------------------------------------------------------------------
// ASIT Initialization Function - Memory Allocation
//
{
PAF_AST_Config *pAstCfg;
Int as; /* Audio Stream Number (1, 2, etc.) */
- Int zMS;
+ Int zMS, errLineNum;
Error_Block eb;
IHeap_Handle decHeapHandle;
INPUTN * sizeof (*pAstCfg->xInp),
HEAP_ID_INTERNAL1_SHM, (IArg)pAstCfg->xInp);
+ /* Input I/O data structure memory */
+ if (!(pAsitCfg->pIoInp = Memory_calloc((IHeap_Handle)HEAP_INTERNAL1_SHM,
+ INPUTN * sizeof (*pAsitCfg->pIoInp), 4, &eb)))
+ {
+ TRACE_TERSE1("PAF_ASIT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
+ SW_BREAKPOINT;
+ return __LINE__;
+ }
+ TRACE_TERSE3("PAF_ASIT_initPhaseMalloc. (pAsitCfg->pIoInp) %d bytes from space %d at 0x%x.",
+ INPUTN * sizeof (*pAsitCfg->pIoInp),
+ HEAP_ID_INTERNAL1_SHM, (IArg)pAsitCfg->pIoInp);
+
+ /* I/O components memory for input */
+ errLineNum = PAF_ASIT_ioCompCreate(pAsitCfg->pIoInp, INPUTN, (IHeap_Handle)HEAP_INTERNAL1_SHM);
+ if(errLineNum)
+ {
+ SW_BREAKPOINT;
+ return errLineNum;
+ }
+
/* Decode memory */
#ifdef NON_CACHE_STATUS
decHeapHandle = (IHeap_Handle)HEAP_EXTERNAL_NONCACHED_SHM;
return frameLength;
}
+#define STRIDE_WORST_CASE 32 // 4-byte (32-bit) word, 2 slots, 4 serializers
+
+extern const MdUns iecFrameLength[23];
+extern void * hMcaspRxChan;
+
+void asipInitIoComps(const PAF_ASIT_Params *pP, PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
+{
+ ioBuffParams_t ioBuffParams;
+ ioPhyParams_t ioPhyParams;
+ ioDataParam_t ioDataCfg;
+
+ ioBuffParams.base = pInpBuf->inpBufConfig.base.pVoid;
+ ioBuffParams.size = pInpBuf->inpBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
+ ioBuffParams.sync = IOBUFF_WRITE_SYNC;
+ ioBuffParams.nominalDelay = 30720*2; // to remove magic number
+ if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
+ SW_BREAKPOINT;
+ }
+
+ ioPhyParams.ioBuffHandle = pInpIo->hIoBuff;
+ ioPhyParams.xferFrameSize = 128*8*2; // to remove magic number
+ ioPhyParams.mcaspChanHandle = hMcaspRxChan;
+ ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_WRITE;
+ if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+ SW_BREAKPOINT;
+ }
+
+ ioDataCfg.ioBuffHandle = pInpIo->hIoBuff;
+ ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
+ ioDataCfg.frameLengthsIEC = (uint_least16_t *)&iecFrameLength[0];
+ ioDataCfg.frameLengthPCM = 512; // to remove magic number
+ ioDataCfg.frameLengthDef = 128*8; // to remove magic number
+ ioDataCfg.ibMode = pInpBuf->inpBufConfig.pBufStatus->mode;
+ ioDataCfg.zeroRunRestart = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
+ ioDataCfg.zeroRunTrigger = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
+
+ if(ioDataInit(&pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
+ SW_BREAKPOINT;
+ }
+
+} /* asipInitIoComps */
diff --git a/pasdk/test_dsp/framework/audioStreamInpProc.h b/pasdk/test_dsp/framework/audioStreamInpProc.h
index 2d765cd1af293b8f1b4960f1719b0723af1aa62d..490fc2200003d44df0d55f015ff34bf8a758f2fb 100644 (file)
#include "audioStreamProc_config.h"
#include "audioStreamProc_master.h"
#include "statusOp_common.h"
+#include "ioPhy.h"
+#include "ioBuff.h"
+#include "ioData.h"
// Global debug counter */
extern Uint32 gTaskAsipCnt; // debug counter for ASP task
//const PAF_ASP_LinkInit * const (*i_encLinkInit);
} PAF_ASIT_Patchs;
+// Input I/O structure
+typedef struct PAF_AST_InpIO {
+ ioPhyHandle_t hIoPhy; /* handle to I/O physical layer */
+ ioBuffHandle_t hIoBuff; /* handle to I/O buffer management */
+ ioDataHandle_t hIoData; /* handle to I/O data processing */
+ const void *pRxParams; /* pointer to D10 Rx Params */
+ Int swapData;
+
+ Int syncState;
+ Int numPrimeXfers;
+ Int mcaspXferErr;
+/*
+ void *mcaspRxBuf1;
+ void *mcaspRxBuf2;
+ uint32_t mcaspRxSize1;
+ uint32_t mcaspRxSize2;
+ Int mcaspRxtwoXfers;
+*/
+ // debugging counters
+ //uint32_t numXferStart;
+ //uint32_t numXferFinish;
+ //uint32_t numXferInterm;
+ uint32_t numInputOverrun;
+ uint32_t numAsipRestart;
+ uint32_t numAsipDecodeQuit;
+
+} PAF_AST_IoInp;
// Audio Stream Input Task (ASIT) configuration
typedef struct PAF_ASIT_Config {
Task_Handle taskHandle; // ASIT handle
ACP_Handle acp; // ASIT local ACP handle
PAF_ASPM_Config *pAspmCfg; // ASIT/ASOT shared configuration
PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
+ PAF_AST_IoInp *pIoInp;
} PAF_ASIT_Config;
diff --git a/pasdk/test_dsp/framework/audioStreamOutProc.c b/pasdk/test_dsp/framework/audioStreamOutProc.c
index e744cd2a7b02ce31c0e60d0fb084e27924c9e26e..3812270780926c9b68fc4587f3ea142e4d7f8e85 100644 (file)
#include "evmc66x_gpio_dbg.h"
#include "dbgCapAf.h"
+#include "ioConfig.h"
// -----------------------------------------------------------------------------
// Debugging Trace Control, local to this file.
* ======== taskAsopFxn ========
* Audio Stream Output Processing task function
*/
+#ifdef PASDK_SIO_DEV
Void taskAsopFxn(
-// Int betaPrimeValue, // FL: revisit
+#else
+Void taskAsopFxn_Not_Used(
+#endif
const PAF_ASOT_Params *pP,
const PAF_ASOT_Patchs *pQ
)
//Log_info0("Exit taskAsopFxn()");
}
+Int PAF_ASOT_ioCompCreate(PAF_AST_IoOut *pIoOut, int numOut, IHeap_Handle iHeapHandle)
+{
+ int i, j, num_alloc;
+ lib_mem_rec_t *mem_rec;
+ ioBuffHandle_t ioBufHandle;
+ ioPhyHandle_t ioPhyHandle;
+ Error_Block eb;
+
+ for(i=0; i<numOut; i++)
+ {
+ // Create an I/O BUFF instance
+ // Obtain number of memory blocks required by I/O BUFF
+ num_alloc = ioBuffNumAlloc();
+
+ // Obtain requirements of each memory block
+ mem_rec = (lib_mem_rec_t *)malloc(sizeof(lib_mem_rec_t)*num_alloc);
+ if(ioBuffAlloc(mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ /* Allocate memory and create I/O BUFF instance */
+ for(j=0; j<num_alloc; j++) {
+ mem_rec[j].base = Memory_calloc(iHeapHandle, mem_rec[j].size,
+ (1<<mem_rec[j].alignment), &eb);
+ }
+
+ if(ioBuffCreate(&ioBufHandle, mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ pIoOut[i].hIoBuff = ioBufHandle;
+
+ free(mem_rec);
+
+ // Create an I/O PHY instance
+ // Obtain number of memory blocks required by I/O PHY
+ num_alloc = ioPhyNumAlloc();
+
+ // Obtain requirements of each memory block
+ mem_rec = (lib_mem_rec_t *)malloc(sizeof(lib_mem_rec_t)*num_alloc);
+ if(ioPhyAlloc(mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ /* Allocate memory and create I/O PHY instance */
+ for(j=0; j<num_alloc; j++) {
+ mem_rec[j].base = Memory_calloc(iHeapHandle, mem_rec[j].size,
+ (1<<mem_rec[j].alignment), &eb);
+ }
+
+ if(ioPhyCreate(&ioPhyHandle, mem_rec) != IOBUFF_NOERR) {
+ return __LINE__;
+ }
+
+ pIoOut[i].hIoPhy = ioPhyHandle;
+
+ free(mem_rec);
+
+ } // end of for loop
+
+ return 0;
+} // PAF_ASOT_ioCompCreate
+
// -----------------------------------------------------------------------------
// AST Initialization Function - Memory Allocation
//
{
PAF_AST_Config *pAstCfg;
Int as; /* Audio Stream Number (1, 2, etc.) */
- Int zMS;
+ Int zMS, errLineNum;
Error_Block eb;
//Int i;
OUTPUTN * sizeof (*pAstCfg->xOut),
HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
+ /* Output I/O data structure memory */
+ if (!(pAsotCfg->pIoOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAsotCfg->pIoOut), 4, &eb)))
+ {
+ TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
+ SW_BREAKPOINT;
+ return __LINE__;
+ }
+ TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAsotCfg->pIoOut) %d bytes from space %d at 0x%x.",
+ OUTPUTN * sizeof (*pAsotCfg->pIoOut),
+ HEAP_ID_INTERNAL, (IArg)pAsotCfg->pIoOut);
+
+ /* I/O components memory for output */
+ errLineNum = PAF_ASOT_ioCompCreate(pAsotCfg->pIoOut, OUTPUTN, (IHeap_Handle)HEAP_INTERNAL);
+ if(errLineNum)
+ {
+ SW_BREAKPOINT;
+ return errLineNum;
+ }
TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
return 0;
} //PAF_ASOT_initPhaseMalloc
diff --git a/pasdk/test_dsp/framework/audioStreamOutProc.h b/pasdk/test_dsp/framework/audioStreamOutProc.h
index c6c24eba29a379839c43d86bb3cdd803f8e3ff89..5cb7a14421e40cd94e1fcf6f15ab0d75b9770c31 100644 (file)
#include "audioStreamProc_patchs.h"
#include "audioStreamProc_config.h"
#include "audioStreamProc_master.h"
+#include "ioPhy.h"
+#include "ioBuff.h"
/* !!!!!!!!! Revisit !!!!!!!!!!!!!!
* Purpose : Temporary ASOT FL sizes.
const PAF_ASP_LinkInit * const (*i_encLinkInit);
} 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 */
+
+ void *mcaspTxBuf1;
+ void *mcaspTxBuf2;
+ uint32_t mcaspTxSize1;
+ uint32_t mcaspTxSize2;
+ int mcaspTxtwoXfers;
+
+ int numPrimeXfers;
+
+ uint32_t mcaspXferErr;
+
+ // debugging counters
+ uint32_t num_xfers;
+
+} PAF_AST_IoOut;
+
// Audio Stream Input Task (ASOT) configuration
typedef struct PAF_ASOT_Config {
Task_Handle taskHandle; // ASOT handle
Int8 cbDrainedFlag[DECODEN_MAX]; // CB drained flags
PAF_ASPM_Config *pAspmCfg; // ASIT/ASOT shared configuration
PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
+ PAF_AST_IoOut *pIoOut;
} PAF_ASOT_Config;
diff --git a/pasdk/test_dsp/io/ioBuff.c b/pasdk/test_dsp/io/ioBuff.c
--- /dev/null
@@ -0,0 +1,375 @@
+
+#include "ioBuff.h"
+#include "ioBuff_loc.h"
+#include "libarch.h"
+#include <stdint.h>
+#include <string.h>
+
+/******************************************************************************
+* Implementation of I/O Buffer Management Component
+******************************************************************************/
+
+#define IOBUF_NUM_MEM_ALLOCS 1
+#define IOBUFF_INST_ALIGN 3
+
+/*******************************************************************************
+* API function: ioBuffNumAlloc
+* Returns the maximum number of memory allocation requests that ioBuffAlloc()
+* requires.
+*******************************************************************************/
+int ioBuffNumAlloc(void)
+{
+ return (IOBUF_NUM_MEM_ALLOCS);
+}
+
+/*******************************************************************************
+* API function: ioBuffAlloc
+* Returns a table of memory records that describe the size, alignment, type
+* and memory space of all buffers required by this component.
+*******************************************************************************/
+int ioBuffAlloc(lib_mem_rec_t *mem_tbl)
+{
+ mem_tbl[0].size = sizeof(ioBuffInst_t);
+ mem_tbl[0].alignment = IOBUFF_INST_ALIGN;
+ mem_tbl[0].type = LIB_PMEM_SLOW;
+ mem_tbl[0].base = NULL;
+
+ return (IOBUFF_NOERR);
+}
+
+/*******************************************************************************
+* API function: ioBuffCreate
+* Create an I/O buffer management instance.
+*******************************************************************************/
+int ioBuffCreate(ioBuffHandle_t *handle, const lib_mem_rec_t *mem_tbl)
+{
+ ioBuffInst_t *inst;
+
+ if( (mem_tbl[0].size < sizeof(ioBuffInst_t))
+ ||libChkAlign(mem_tbl[0].base, IOBUFF_INST_ALIGN) ) {
+ // to add: check memory type
+ return (IOBUFF_ERR_MEMORY);
+ }
+
+ inst = (ioBuffInst_t *)mem_tbl[0].base;
+
+ *handle = (ioBuffHandle_t)inst;
+
+ return (IOBUFF_NOERR);
+}
+
+/*******************************************************************************
+* API function: ioBuffInit
+* Initializes the I/O buffer management instance.
+*******************************************************************************/
+int ioBuffInit (ioBuffHandle_t handle, const ioBuffParams_t *params)
+{
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ if(params == NULL) {
+ return (IOBUFF_ERR_BAD_PARAMS);
+ }
+
+ if((params->base == NULL) || (params->nominalDelay > params->size)) {
+ return (IOBUFF_ERR_BAD_PARAMS);
+ }
+
+ /* initialize the instance */
+ inst->base = params->base; // I/O memory pool base address
+ inst->size = params->size; // I/O memory pool size
+ inst->end = (void *)((uint_least32_t)inst->base + inst->size);
+ 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->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);
+
+// memset(inst->base, 0, inst->nom_delay);
+
+ return (IOBUFF_NOERR);
+} /* ioBuffInit */
+
+/*******************************************************************************
+* API function: Return read pointer(s)
+*******************************************************************************/
+int ioBuffGetReadPtrs(ioBuffHandle_t handle, size_t mem_size,
+ void **ptr1, size_t *size1, void **ptr2, size_t *size2)
+{
+ uint_least32_t address_end_of_read;
+ void * new_read_ptr;
+ int ret_val;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ if(inst->status != BUFF_STATUS_OVERFLOW) {
+ /* check if buffer underflows */
+ if( ( (!inst->rw_wrap_around)
+ &&(((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 + inst->size -
+ (uint_least32_t)inst->read_ptr) < mem_size)
+ )
+ ) {
+ /* Buffer underflows */
+ inst->status = BUFF_STATUS_UNDERFLOW;
+
+ if(inst->sync == IOBUff_READ_SYNC) {
+ /*If it's read-synchronized, don't return from here, but still return
+ read pointer(s) calculated below. */
+ /* reset the delay between read and write_complete pointers */
+ uint_least32_t delay_adjust = inst->nom_delay;
+ if(delay_adjust < mem_size) {
+ delay_adjust = mem_size;
+ }
+ inst->read_ptr = (void *)((uint_least32_t)inst->write_complete_ptr -
+ 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
+ }
+
+ ret_val = IOBUFF_ERR_UNDERFLOW;
+ }
+ else {
+ /* Return here if it underflows but is not read-synchronized. */
+ *ptr1 = NULL; *size1 = 0;
+ *ptr2 = NULL; *size2 = 0;
+ return(IOBUFF_ERR_UNDERFLOW);
+ }
+ }
+ else {
+ inst->status = BUFF_STATUS_NORMAL;
+ ret_val = IOBUFF_NOERR;
+ }
+ } /* if(inst->status != BUFF_STATUS_OVERFLOW) */
+ else {
+ /* already in overflow and remain in overflow untill there is some distance
+ between read pointer and write pointer */
+ ret_val = IOBUFF_ERR_OVERFLOW;
+ }
+
+ /* return 1 or 2 pointers depending buffer wraps around or not */
+ *ptr1 = inst->read_ptr; /* starting address to read */
+
+ /* check if read pointer is going to wrap around during this read */
+ address_end_of_read = (uint_least32_t)inst->read_ptr + mem_size;
+ if(address_end_of_read <= (uint_least32_t)inst->end) {
+ /* read pointer not going to wrap aound - return only 1 pointer */
+ *size1 = mem_size;
+ *ptr2 = NULL; *size2 = 0;
+ new_read_ptr = (void *)address_end_of_read;
+ if(address_end_of_read == (uint_least32_t)inst->end) {
+ new_read_ptr = inst->base;
+ }
+ }
+ else {
+ /* read pointer going to wrap around - return 2 pointers */
+ *size1 = (size_t)inst->end - (size_t)inst->read_ptr;
+ *ptr2 = inst->base;
+ *size2 = mem_size - *size1;
+ new_read_ptr = (void *)((uint_least32_t)inst->base + *size2);
+ }
+
+ /* update read pointer */
+ inst->read_ptr = new_read_ptr;
+
+ return (ret_val);
+} /* ioBuffGetReadPtrs */
+
+
+/*******************************************************************************
+* API function: Rewind read pointer by a given amount.
+*******************************************************************************/
+int ioBuffRewindReadPtr(ioBuffHandle_t handle, size_t rewind_size)
+{
+ uint_least32_t address_rewind_read;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ address_rewind_read = (uint_least32_t)inst->read_ptr - rewind_size;
+ if(address_rewind_read < (uint_least32_t)inst->base) {
+ address_rewind_read = (uint_least32_t)inst->end - ((uint_least32_t)inst->base-address_rewind_read );
+ }
+ inst->read_ptr = (void *)address_rewind_read;
+
+ return IOBUFF_NOERR;
+} /* ioBuffRewindReadPtr */
+
+/*******************************************************************************
+* API function: Return write pointer(s)
+*******************************************************************************/
+int ioBuffGetWritePtrs(ioBuffHandle_t handle, size_t mem_size,
+ void **ptr1, size_t *size1, void **ptr2, size_t *size2)
+{
+ int ret_val;
+ uint_least32_t address_end_of_write;
+ void * new_write_ptr;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ /* check if buffer overflows or not */
+ if(inst->status != BUFF_STATUS_UNDERFLOW) { // this condition may need to be removed!!!
+ if( ( (!inst->rw_wrap_around)
+ &&(((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) < mem_size)
+ )
+ ) {
+ /* Buffer overflows */
+ inst->status = BUFF_STATUS_OVERFLOW;
+
+ if(inst->sync == IOBUFF_WRITE_SYNC){
+ /* If it's write-synchronized, don't return from here. Still return the
+ write pointer(s) calculated below. */
+ ret_val = IOBUFF_ERR_OVERFLOW;
+ }
+ else {
+ /* Return here if it overflows but is not write-synchronized. */
+ *ptr1 = NULL; *size1 = 0;
+ *ptr2 = NULL; *size2 = 0;
+ return(IOBUFF_ERR_OVERFLOW);
+ }
+ }
+ else {
+ inst->status = BUFF_STATUS_NORMAL;
+ ret_val = IOBUFF_NOERR;
+ }
+ }
+ else {
+ /* already in underflow and remain in underflow untill write pointer is
+ ahead of read pointer */
+ ret_val = IOBUFF_ERR_UNDERFLOW;
+ }
+
+ /* return 1 or 2 pointers depending buffer wraps around or not */
+ *ptr1 = inst->write_ptr; /* starting address to write */
+
+ /* check if write pointer is going to wrap around during this write */
+ address_end_of_write = (uint_least32_t)inst->write_ptr + mem_size;
+ if(address_end_of_write <= (uint_least32_t)inst->end) {
+ /* write pointer not going to wrap aound, return only 1 pointer */
+ *size1 = mem_size;
+ *ptr2 = NULL; *size2 = 0;
+
+ new_write_ptr = (void *)address_end_of_write;
+ if(address_end_of_write == (uint_least32_t)inst->end) {
+ new_write_ptr = inst->base;
+ }
+ }
+ else {
+ /* write pointer going to wrap around, return 2 pointers */
+ *size1 = (size_t)inst->end - (size_t)inst->write_ptr;
+ *ptr2 = inst->base;
+ *size2 = mem_size - *size1;
+ new_write_ptr = (void *)((uint_least32_t)inst->base + *size2);
+ }
+
+ /* update write pointer */
+ inst->write_ptr = new_write_ptr;
+
+ return (ret_val);
+} /* ioBuffGetWritePtrs */
+
+/*******************************************************************************
+* API function: Mark read completion
+*******************************************************************************/
+int ioBuffReadComplete(ioBuffHandle_t handle, void *read_begin, size_t read_size)
+{
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ inst->read_complete_ptr = (void *)((uint_least32_t)read_begin+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
+ }
+
+ return (IOBUFF_NOERR);
+} /* ioBuffReadComplete */
+
+/*******************************************************************************
+* API function: Mark write completion
+*******************************************************************************/
+int ioBuffWriteComplete(ioBuffHandle_t handle, void *write_begin, size_t write_size)
+{
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ inst->write_complete_ptr = (void *)((uint_least32_t)write_begin+write_size);
+ 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
+ }
+
+ return (IOBUFF_NOERR);
+} /* ioBuffWriteComplete */
+
+
+int ioBuffGetInfo(ioBuffHandle_t handle, ioBuffInfo_t *info)
+{
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ info->base = inst->base;
+ info->read = inst->read_ptr;
+ info->write = inst->write_ptr;
+ info->size = inst->size;
+
+ return (IOBUFF_NOERR);
+} /* ioBuffGetInfo */
+
+
+void * ioBuffWrapPointer(ioBuffHandle_t handle, void *pPtr)
+{
+ uint_least32_t ptr_temp;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ ptr_temp = (uint_least32_t)pPtr;
+ if(ptr_temp >= (uint_least32_t)inst->end) {
+ ptr_temp = (uint_least32_t)inst->base + ptr_temp - (uint_least32_t)inst->end;
+ }
+
+ return ((void *)ptr_temp);
+} /* ioBuffWrapPointer */
+
+#if 0
+int ioBuffWrapPointer(ioBuffHandle_t handle, void **pPtr)
+{
+ uint_least32_t ptr_temp;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ ptr_temp = (uint_least32_t)*pPtr;
+ if(ptr_temp >= (uint_least32_t)inst->end) {
+ ptr_temp = (uint_least32_t)inst->base + ptr_temp - (uint_least32_t)inst->end;
+ }
+
+ *pPtr = (void *)ptr_temp;
+
+ return (IOBUFF_NOERR);
+} /* ioBuffWrapPointer */
+#endif
+
+int ioBuffAdjustDelay(ioBuffHandle_t handle, size_t delay)
+{
+ size_t temp;
+ ioBuffInst_t *inst = (ioBuffInst_t *)handle;
+
+ 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;
+ }
+ 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->nom_delay = delay;
+
+ return (IOBUFF_NOERR);
+} /* ioBuffAdjustDelay */
+
+/* Nothing past this point */
diff --git a/pasdk/test_dsp/io/ioBuff.h b/pasdk/test_dsp/io/ioBuff.h
--- /dev/null
@@ -0,0 +1,147 @@
+
+#ifndef _IOBUFF_H
+#define _IOBUFF_H
+
+#include <stdint.h>
+#include "libarch.h"
+/*
+ * I/O buffer management API
+*/
+
+enum {
+ IOBUFF_NOERR = 0,
+ IOBUFF_ERR_HANDLE,
+ IOBUFF_ERR_MEMORY,
+ IOBUFF_ERR_BAD_PARAMS,
+ IOBUFF_ERR_UNDERFLOW,
+ IOBUFF_ERR_OVERFLOW
+};
+
+enum {
+ IOBUff_NO_SYNC = 0,
+ IOBUff_READ_SYNC,
+ IOBUFF_WRITE_SYNC,
+ IOBUFF_RW_SYNC
+};
+
+// I/O memory pool configuration parameters
+typedef struct ioBuffParams {
+ void *base; /* base address of I/O memory provided by the framework */
+ uint_fast32_t size; /* size in MAU's (bytes) of I/O memory */
+ int_fast16_t sync; /* sync type: IOBUff_READ_SYNC, WRITE_SYNC, NO_SYNC, RW_SYNC */
+ uint_fast32_t nominalDelay; /* nominal delay as # of MAU's between write and read */
+} ioBuffParams_t;
+
+typedef void * ioBuffHandle_t;
+
+typedef struct ioBuffInfo_s {
+ void *base;
+ void *read;
+ void *write;
+ uint_fast32_t size;
+} ioBuffInfo_t;
+
+/**
+ * @brief ioBuffNumAlloc
+ * Returns the maximum number of memory allocation requests that ioBuffAlloc()
+ * requires.
+ */
+int ioBuffNumAlloc(void);
+
+/**
+ * @brief ioBuffAlloc
+ * Returns a table of memory records that describe the size, alignment, type
+ * and memory space of all buffers required by this component.
+ */
+int ioBuffAlloc(lib_mem_rec_t *mem_tbl);
+
+/**
+ * @brief ioBuffCreate
+ * Based on the provided memory blocks, this function creates an I/O BUFF
+ * instance and returns a handle. This handle points to the memory block
+ * that contains the instance.
+ */
+int ioBuffCreate(ioBuffHandle_t *handle, const lib_mem_rec_t *mem_tbl);
+
+/**
+ * @brief ioBuffInit
+ * Initializes the I/O buffer management instance.
+ */
+int ioBuffInit (ioBuffHandle_t handle, const ioBuffParams_t *params);
+
+/**
+ * @brief ioBuffGetReadPtrs
+ * Provides pointers to read a given size of data from the I/O buffer.
+ * - If I/O buffer wrapps around, two pointers will be provided, each with
+ * a corresponding read size.
+ * - If I/O buffer does not wrapp around, one pointer and the corresponding
+ * size will be provided. The size will be equal to the input mem_size.
+ * The second pointer will be NULL and the corresponding size will be
+ * zero.
+ *
+ * @param[in] handle
+ * @param[in] mem_size size of data to be read
+ * @param[out] rdptr1 read pointer 1
+ * @param[out] size1 read size corresponding to pointer 1
+ * @param[out] rdptr2 read pointer 2
+ * @param[out] size2 read size corresponding to pointer 2
+ *
+ */
+int ioBuffGetReadPtrs(ioBuffHandle_t handle, size_t mem_size,
+ void **rdptr1, size_t *size1,
+ void **rdptr2, size_t *size2);
+
+/**
+ * @brief ioBuffGetWritePtrs
+ * Provides pointers to write a given size of data to the I/O buffer.
+ * - If I/O buffer wrapps around, two pointers will be provided, each with
+ * a corresponding write size.
+ * - If I/O buffer does not wrapp around, one pointer and the corresponding
+ * size will be provided. The size will be equal to the input mem_size.
+ * The second pointer will be NULL and the corresponding size will be
+ * zero.
+ *
+ * @param[in] handle
+ * @param[in] mem_size size of data to be written to the I/O buffer
+ * @param[out] wrptr1 write pointer 1
+ * @param[out] size1 write size corresponding to pointer 1
+ * @param[out] wrptr2 write pointer 2
+ * @param[out] size2 write size corresponding to pointer 2
+ *
+ */
+int ioBuffGetWritePtrs(ioBuffHandle_t handle, size_t mem_size,
+ void **wrptr1, size_t *size1,
+ void **wrptr2, size_t *size2);
+
+/**
+ * @brief ioBuffReadComplete
+ * Marks a portion of the I/O buffer as read complete so that the data in it
+ * can be overwritten now.
+ *
+ * @param[in] handle
+ * @param[in] start start address of the read-completed portion
+ * @param[in] size size of the read-completed portion
+ *
+ * @remark If two buffers, then size should be sum of two sizes.....
+ */
+int ioBuffReadComplete(ioBuffHandle_t handle, void *start, size_t size);
+
+/**
+ * @brief ioBuffWriteComplete
+ * Marks a portion of the I/O buffer as write complete so that the data in it
+ * can be read now.
+ *
+ * @param[in] handle
+ * @param[in] start start address of the write-completed portion
+ * @param[in] size size of the write-completed portion
+ *
+ */
+int ioBuffWriteComplete(ioBuffHandle_t handle, void *start, size_t size);
+
+int ioBuffGetInfo(ioBuffHandle_t handle, ioBuffInfo_t *info);
+
+void * ioBuffWrapPointer(ioBuffHandle_t handle, void * pPtr);
+
+int ioBuffAdjustDelay(ioBuffHandle_t handle, size_t delay);
+
+#endif
diff --git a/pasdk/test_dsp/io/ioBuff_loc.h b/pasdk/test_dsp/io/ioBuff_loc.h
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include <stdint.h>
+
+#define BUFF_STATUS_NORMAL 0
+#define BUFF_STATUS_UNDERFLOW 1
+#define BUFF_STATUS_OVERFLOW 2
+
+typedef struct ioBuffInst_s {
+
+ void *base;
+ void *end;
+ void *read_ptr;
+ void *read_complete_ptr;
+ void *write_ptr;
+ void *write_complete_ptr;
+
+ uint_least32_t size;
+ int_fast16_t sync; /* sync type: ioBUff_READ_SYNC, WRITE_SYNC, NO_SYNC, RW_SYNC */
+ uint_fast32_t nom_delay; /* nominal delay as # of MAU's between write and read */
+
+ uint_fast16_t status; /* overflow, underflow, normal */
+ uint_fast16_t rw_wrap_around; /* flag to indicate write pointer wraps around
+ but read pointer has not yet */
+} ioBuffInst_t;
diff --git a/pasdk/test_dsp/io/ioConfig.h b/pasdk/test_dsp/io/ioConfig.h
--- /dev/null
@@ -0,0 +1,83 @@
+
+#ifndef IO_CONFIG_H
+#define IO_CONFIG_H
+
+#define PASDK_SIO_DEV // define this to use the legacy SIO/DEV based I/O driver
+
+//#define IO_LOOPBACK_TEST // define this to run a loopback test bypassing PASDK processing
+
+#define INPUT_HDMI_4xI2S // HDMI, 4 Rx serializers
+//#define INPUT_HDMI_STEREO // HDMI, 1 Rx serializer
+//#define INPUT_SPDIF // S/PDIF, 1 Rx serializer
+
+//#define INPUT_PCM_ONLY // debugging, input fixed to PCM
+
+#ifdef INPUT_HDMI_4xI2S
+#define RX_MCASP_USE_MULT_SER
+#define TX_MCASP_USE_MULT_SER // This is the normal operation. Undefine this for debugging and loopback
+//#define ASIP_ELEMENT_SIZE 2
+//#define ASIP_STRIDE 8 // 4 lane, stereo
+#endif
+
+#ifdef INPUT_HDMI_STEREO
+//#define ASIP_ELEMENT_SIZE 4
+//#define ASIP_STRIDE 2 // 1 lane, stereo
+#endif
+
+#ifdef INPUT_SPDIF
+//#define ASIP_ELEMENT_SIZE 4
+//#define ASIP_STRIDE 2 // 1 lane, stereo
+#endif
+
+// two options regarding I/O PHY transfer size and I/O DATA read size:
+// 1. fixed to 1024 words: simple for implementation and debugging, shorter delay,
+// but more interrupts and more McASP LLD calls.
+// 2. adjusted to frame size after auto-detection: less interrupts and McASP LLD calls,
+// but more complicated implementation and longer delay.
+#define ADJUST_XFER_SIZE_AFTER_AUTODET
+
+
+// Number of serializers configured for Rx McASP
+#ifdef RX_MCASP_USE_MULT_SER
+#define NUM_RX_SERIALIZER 4
+#else
+#define NUM_RX_SERIALIZER 1
+#endif
+
+// Number of serializers configured for Tx McASP
+#ifdef TX_MCASP_USE_MULT_SER
+#define NUM_TX_SERIALIZER 4
+#else
+#define NUM_TX_SERIALIZER 1
+#endif
+
+/* Number of submitted transfers in McASP LLD priming operation.
+ * Due to McASP LLD issue, there must be 3 or more transfer submits in priming. */
+#define NUM_PRIME_XFERS 3 // 3 and above is good
+
+// Define McASP transfer element size: number of bytes in one word
+#define WORD_SIZE_BITSTREAM 2
+#define WORD_SIZE_PCM 4
+
+// 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.
+#ifdef INPUT_HDMI_4xI2S
+#define INPUT_FRAME_LENGTH (256*NUM_RX_SERIALIZER) // 128 stereo/lane
+#else
+//#define INPUT_FRAME_LENGTH (128*NUM_RX_SERIALIZER) // 64 stereo/lane
+#define INPUT_FRAME_LENGTH (256*NUM_RX_SERIALIZER) // 128 stereo/lane
+#endif
+
+// Input frame size: number of bytes to be transfered in 1 transfer of McASP LLD Rx
+#define INPUT_FRAME_SIZE_DEF (INPUT_FRAME_LENGTH * WORD_SIZE_BITSTREAM)
+#define INPUT_FRAME_SIZE_PCM (INPUT_FRAME_LENGTH * WORD_SIZE_PCM)
+
+// Output frame length: number of words to be transfered in 1 transfer of McASP LLD Tx
+#define OUTPUT_FRAME_LENGTH (256*NUM_TX_SERIALIZER) // 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)
+
+
+
+#endif
diff --git a/pasdk/test_dsp/io/ioData.c b/pasdk/test_dsp/io/ioData.c
--- /dev/null
@@ -0,0 +1,877 @@
+
+
+#include <stdint.h>
+#include <limits.h> //INT_MAX
+
+#include "ioData.h"
+#include "iobuff.h"
+
+//#include "ioDataLoc.h"
+
+#include <ti/sysbios/hal/Cache.h>
+
+#define IODATA_NUM_MEM_ALLOCS 1
+#define IODATA_INST_ALIGN 3
+
+#define IODATA_NUM_BYTES_BITSTREAM 2
+#define IODATA_NUM_BYTES_PCMSAMPLE 4
+
+#define IODATA_ELEMENT_SIZE_DEF IODATA_NUM_BYTES_BITSTREAM
+
+#define TRUE 1
+#define FALSE 0
+
+#define IODATA_SYNC_PC_MASK 0x1F
+#define IODATA_SYNC_SUBTYPE_MASK 0x700
+#define IODATA_SYNC_SUBTYPE_SHIFT 8
+#define IODATA_SYNC_SUBTYPE_DTSHD 0x11
+#define IODATA_SYNC_DDP 0x15
+#define IODATA_SYNC_THD 0x16
+
+#define IODATA_MIN_NUM_ZEROS_BEFORE_PA 2
+#define IODATA_PREAMBLE_MAX_LEN 8 // TBD
+#define IODATA_HEADER_LENGTH_IEC 4
+#define IODATA_HEADER_CHECK_LENGTH_IEC 2 // For IEC, only look at 2 words to check SYNC.
+
+#define IEC_PA ((uint_least16_t) 0xF872)
+#define IEC_PB ((uint_least16_t) 0x4E1F)
+#define DTS16_SYNC_A ((uint_least16_t) 0x7FFE)
+#define DTS16_SYNC_B ((uint_least16_t) 0x8001)
+#define DTS16_SYNC_C ((uint_least16_t) 0xFC00)
+#define DTS14_SYNC_A ((uint_least16_t) 0x1FFF)
+#define DTS14_SYNC_B ((uint_least16_t) 0xE800)
+#define DTS14_SYNC_C ((uint_least16_t) 0x07F0)
+
+#define DTS_BURST_TYPE_I 0x008B
+#define DTS_BURST_TYPE_II 0x018C
+#define DTS_BURST_TYPE_III 0x028D
+#define DTS_BURST_TYPE_IV 0x0491
+
+#define DTS_BURST_TYPE_IV_CBR 0x02
+#define DTS_BURST_TYPE_IV_LBR 0x03
+#define DTS_BURST_TYPE_IV_HBR 0x04
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+//IBMODE
+enum
+{
+ IBMODE_DEFAULT = 0,
+ IBMODE_NO_ZERORUNRESTART = 1,
+ IBMODE_NO_ZERORUN = 2
+};
+
+enum {
+ AUTODET_RESET = 0,
+ AUTODET_SYNC_SEARCH_INITIAL,
+ AUTODET_SYNC_SEARCH_PCM,
+ AUTODET_SYNC_CHECK_ONGOING
+};
+
+// scanState
+enum
+{
+ SCANNED_NONE,
+ SCANNED_IEC_PA,
+ SCANNED_IEC_PB,
+ SCANNED_IEC_PC,
+ SCANNED_IEC_PD,
+ SCANNED_DTS14_SYNC_A,
+ SCANNED_DTS14_SYNC_B,
+ SCANNED_DTS14_SYNC_C,
+ SCANNED_DTS14_SYNC_D,
+ SCANNED_DTS16_SYNC_A,
+ SCANNED_DTS16_SYNC_B,
+ SCANNED_DTS16_SYNC_C
+};
+
+typedef struct autoDet_s {
+ int_least32_t frameLength;
+ int_least32_t timeOutCntr;
+ uint_least32_t zeroCount;
+ uint_least32_t numElementsRcvd;
+ uint_least32_t distToFrameEnd;
+
+ uint_least16_t preambleRef[IODATA_PREAMBLE_MAX_LEN];
+ uint_least16_t preambleBuf[IODATA_PREAMBLE_MAX_LEN];
+ int_fast32_t preambleInd;
+ uint8_t headerLength;
+ uint8_t headerCheckLen;
+
+ uint_least16_t scanState;
+ uint_least16_t checkState;
+
+ int8_t ibMode;
+ int8_t timeOutStarted;
+ int8_t preambleStartsPrevBuf;
+ int8_t syncDetected;
+ int8_t syncLost;
+ int8_t completeFrameRcvd;
+ uint_least16_t syncState;
+ uint_least16_t bitStreamInfo;
+ uint_least16_t *bitStreamSyncPtr;
+ uint_least16_t *frameDataStartTemp;
+ uint_least16_t *frameDataStartConfirm;
+} autoDet_t;
+
+typedef struct ioDataDebug_s {
+ uint_least32_t numFramesRcvd;
+ uint_least32_t numBuffUnderflow;
+ uint_least32_t numSyncLost;
+
+} ioDataDebug_t;
+
+typedef struct ioDataInst_s {
+ autoDet_t autoDet;
+ ioDataDebug_t dbgStats;
+ uint_least16_t autoDetState;
+ uint_least16_t *IECframeLengths;
+ uint_least16_t frameLengthPCM;
+ uint_least16_t frameLengthDef;
+ uint_least32_t frameLength; // frame length: number of elements in a frame
+ uint_least32_t numElementsRead; // number of elements to read from input buffer
+ uint_least32_t distToFrameEnd;
+ int8_t elementSize;
+ ioBuffHandle_t ioBuffHandle;
+ uint_least32_t zeroRunTrigger;
+ uint_least32_t zeroRunRestart;
+ int_least32_t timeOutCntr;
+ uint_least32_t unknownSourceTimeOut;
+
+ uint_least16_t *frameDataStart;
+ size_t frameDataSize;
+ uint8_t deliverZeros;
+ uint8_t ioBuffUnderFlow;
+ void *buff1;
+ void *buff2;
+ size_t size1;
+ size_t size2;
+
+} ioDataInst_t;
+
+
+// TODO: put this data structure somewhere, or use ioDataNumAlloc & ioDataAlloc to
+// dynamically allocate memory.
+//ioDataInst_t ioDataInst;
+
+void autoDetection(ioDataInst_t * pIoDataInst);
+void autoDetReset(ioDataInst_t * pIoDataInst);
+
+
+
+/*******************************************************************************
+* API function: ioDataNumAlloc
+* Returns the maximum number of memory allocation requests that ioDataAlloc()
+* requires.
+*******************************************************************************/
+int ioDataNumAlloc(void)
+{
+ return (IODATA_NUM_MEM_ALLOCS);
+} /* ioDataNumAlloc */
+
+/*******************************************************************************
+* API function: ioDataAlloc
+* Returns a table of memory records that describe the size, alignment, type
+* and memory space of all buffers required by I/O DATA component.
+*******************************************************************************/
+int ioDataAlloc(lib_mem_rec_t *mem_tbl)
+{
+ mem_tbl[0].size = sizeof(ioDataInst_t);
+ mem_tbl[0].alignment = IODATA_INST_ALIGN;
+ mem_tbl[0].type = LIB_PMEM_SLOW;
+ mem_tbl[0].base = NULL;
+
+ return (IODATA_NO_ERR);
+} /* ioDataAlloc */
+
+/*******************************************************************************
+* API function: ioDataCreate
+* Create an I/O DATA instance.
+*******************************************************************************/
+int ioDataCreate(ioDataHandle_t *handle, const lib_mem_rec_t *mem_tbl)
+{
+ ioDataInst_t *inst;
+
+ if( (mem_tbl[0].size < sizeof(ioDataInst_t))
+ ||libChkAlign(mem_tbl[0].base, IODATA_INST_ALIGN) ) {
+ // to add: check memory type
+ return (IODATA_ERR_MEMORY);
+ }
+
+ inst = (ioDataInst_t *)mem_tbl[0].base;
+
+ *handle = (ioDataHandle_t)inst;
+
+ return (IODATA_NO_ERR);
+} /* ioDataCreate */
+
+/*=============================================================================
+ * API function: this function initializes I/O data processing.
+ =============================================================================*/
+int ioDataInit(ioDataHandle_t handle, ioDataParam_t *cfgParams)
+{
+ ioDataInst_t *pIoDataInst = (ioDataInst_t *)handle;
+
+ if(cfgParams == NULL) {
+ return (IODATA_ERR_BAD_PARAMS);
+ }
+
+ pIoDataInst->ioBuffHandle = cfgParams->ioBuffHandle;
+ pIoDataInst->IECframeLengths = cfgParams->frameLengthsIEC;
+ pIoDataInst->frameLengthPCM = cfgParams->frameLengthPCM;
+ pIoDataInst->frameLengthDef = cfgParams->frameLengthDef;
+ pIoDataInst->autoDet.ibMode = cfgParams->ibMode;
+ pIoDataInst->zeroRunRestart = cfgParams->zeroRunRestart;
+ pIoDataInst->zeroRunTrigger = cfgParams->zeroRunTrigger;
+ pIoDataInst->unknownSourceTimeOut = cfgParams->unknownSourceTimeOut*2;
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_INITIAL;
+ pIoDataInst->dbgStats.numSyncLost = 0;
+ pIoDataInst->ioBuffUnderFlow = FALSE;
+
+ autoDetReset(pIoDataInst);
+
+ return IODATA_NO_ERR;
+} /* ioDataInit */
+
+
+/*=============================================================================
+ * API function: main function of I/O DATA component processing.
+ =============================================================================*/
+int ioDataProcess(ioDataHandle_t ioDataHandle)
+{
+ void *buff1, *buff2;
+ size_t size1, size2;
+ int status;
+ ioDataInst_t *pIoDataInst = (ioDataInst_t *)ioDataHandle;
+
+ // Get read pointers (or sub-buffers) of the input buffer
+ status = ioBuffGetReadPtrs(pIoDataInst->ioBuffHandle,
+ pIoDataInst->numElementsRead*pIoDataInst->elementSize,
+ &buff1, &size1, &buff2, &size2);
+ if(status == IOBUFF_ERR_UNDERFLOW) {
+ pIoDataInst->ioBuffUnderFlow = TRUE;
+ pIoDataInst->dbgStats.numBuffUnderflow += 1;
+
+ /* skip processing since there is no enough data to process */
+ return IODATA_ERR_IOBUF_UNDERFLOW;
+ }
+
+ // Store read pointers and sizes to instance for auto-detection to read
+ pIoDataInst->ioBuffUnderFlow = FALSE;
+ pIoDataInst->buff1 = buff1;
+ pIoDataInst->buff2 = buff2;
+ pIoDataInst->size1 = size1;
+ pIoDataInst->size2 = size2;
+
+ autoDetection(pIoDataInst);
+
+ return IODATA_NO_ERR;
+} /* ioDataProcess */
+
+
+/*=============================================================================
+ * API function - this function marks the sub-buffers provided by I/O BUFF as
+ * read complete. It makes API call to the associated I/O BUFF component to mark
+ * the data as reading completed.
+ =============================================================================*/
+int ioDataReadComplete(ioDataHandle_t ioDataHandle)
+{
+ ioDataInst_t *pIoDataInst = (ioDataInst_t *)ioDataHandle;
+
+ // If the associated I/O buffer underflows, i.e. no enough data to read, do not
+ // call I/O BUFF API to mark read complete.
+ if(pIoDataInst->ioBuffUnderFlow) {
+ return IODATA_ERR_IOBUF_UNDERFLOW;
+ }
+
+ ioBuffReadComplete(pIoDataInst->ioBuffHandle, pIoDataInst->buff1, pIoDataInst->size1);
+
+ if(pIoDataInst->buff2 != NULL) {
+ ioBuffReadComplete(pIoDataInst->ioBuffHandle, pIoDataInst->buff2, pIoDataInst->size2);
+ }
+
+ return IODATA_NO_ERR;
+} /* ioDataReadComplete */
+
+
+/*=============================================================================
+ * API function - this function allows framework to dynamically control I/O data
+ * component or get information from it.
+ =============================================================================*/
+int ioDataControl(ioDataHandle_t ioDataHandle, ioDataCtl_t *ioDataCtl)
+{
+ ioBuffInfo_t ioBuffInfo;
+
+ ioDataInst_t *pIoDataInst = (ioDataInst_t *)ioDataHandle;
+
+ switch (ioDataCtl->code)
+ {
+
+ case IODATA_CTL_SET_ELEMENT_SIZE:
+ pIoDataInst->elementSize = ioDataCtl->param.frameInfo.elementSize;
+ break;
+
+ case IODATA_CTL_SET_FRAME_LENGTH:
+ pIoDataInst->frameLength = ioDataCtl->param.frameInfo.frameLength;
+ break;
+
+ case IODATA_CTL_GET_INPBUFFINFO:
+ ioBuffGetInfo(pIoDataInst->ioBuffHandle, &ioBuffInfo);
+ ioDataCtl->param.dataReadInfo.buffBase = ioBuffInfo.base;
+ ioDataCtl->param.dataReadInfo.buffSize = ioBuffInfo.size;
+ ioDataCtl->param.dataReadInfo.startAddress = pIoDataInst->frameDataStart;
+ ioDataCtl->param.dataReadInfo.frameSize = pIoDataInst->frameDataSize;
+ break;
+
+ case IODATA_CTL_GET_AUTODET_STATUS:
+ ioDataCtl->param.autoDetStats.syncState = pIoDataInst->autoDet.syncState;
+ ioDataCtl->param.autoDetStats.deliverZeros = pIoDataInst->deliverZeros;
+ ioDataCtl->param.autoDetStats.bitStreamInfo = pIoDataInst->autoDet.bitStreamInfo;
+ break;
+/*
+ case IODATA_CTL_GET_STEAM_INFO:
+ break;
+*/
+ default:
+ break;
+ }
+
+ return IODATA_NO_ERR;
+} /* ioDataControl */
+
+//========== internal functions - to be moved to a different file ==========
+void autoDetSyncScan(ioDataInst_t * pIoDataInst);
+void autoDetSyncCheck(ioDataInst_t * pIoDataInst);
+void syncScan(void *buff, size_t size, int8_t elementSize, autoDet_t *pDet);
+void syncCheck(void *buff, size_t size, int8_t elementSize, autoDet_t *pDet);
+void syncCheckInit(ioDataInst_t * pIoDataInst);
+void syncScanPcmInit(ioDataInst_t * pIoDataInst);
+
+/*=============================================================================
+ * Main function of auto-detection of the I/O DATA component.
+ =============================================================================*/
+void autoDetection(ioDataInst_t * pIoDataInst)
+{
+ switch(pIoDataInst->autoDetState)
+ {
+ case AUTODET_SYNC_SEARCH_INITIAL:
+ /* Search for SYNC the first time */
+ autoDetSyncScan(pIoDataInst);
+
+ if(pIoDataInst->autoDet.syncDetected) {
+ syncCheckInit(pIoDataInst); // prepare for SYNC checking in subsequent frames
+
+ pIoDataInst->autoDet.frameDataStartConfirm = pIoDataInst->autoDet.frameDataStartTemp;
+ pIoDataInst->autoDet.syncState = IODATA_SYNC_ONE; // found SYNC once and to be verified
+ pIoDataInst->autoDetState = AUTODET_SYNC_CHECK_ONGOING;
+ }
+ /* Check time out counter if SYNC is not found:
+ - if autoDet.timeOutStarted == FALSE (no non-zero data has been received), look at pIoDataInst->timeOutCntr
+ - if autoDet.timeOutStarted == TRUE, look at pIoDataInst->autoDet.timeOutCntr
+ */
+ else if( ((!pIoDataInst->autoDet.timeOutStarted) && (pIoDataInst->timeOutCntr <= 0))
+ || (pIoDataInst->autoDet.timeOutCntr <= 0) ) {
+ /* Time out, decide whether to reset or go to PCM */
+ if ( (pIoDataInst->autoDet.ibMode == IBMODE_DEFAULT)
+ &&(pIoDataInst->autoDet.zeroCount >= pIoDataInst->zeroRunRestart) ) {
+ /* Reset if zero-run is long enough */
+ autoDetReset(pIoDataInst);
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_INITIAL;
+ }
+ else {
+ // inform decoder where to read PCM data
+ pIoDataInst->frameDataStart = pIoDataInst->buff1;
+ pIoDataInst->frameDataSize = pIoDataInst->size1;
+ if(pIoDataInst->buff2 != NULL) {
+ pIoDataInst->frameDataSize += pIoDataInst->size2;
+ }
+
+ // Go to PCM scanning - to play out PCM and keep scanning for SYNC
+ syncScanPcmInit(pIoDataInst);
+ pIoDataInst->autoDet.syncState = IODATA_SYNC_PCM;
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_PCM;
+ }
+ }
+ break;
+
+ case AUTODET_SYNC_SEARCH_PCM:
+ /* Search for SYNC while PCM is played out */
+ autoDetSyncScan(pIoDataInst);
+
+ /* Check if SYNC is detected or there is zero-run */
+ if(pIoDataInst->autoDet.syncDetected) {
+ autoDetReset(pIoDataInst);
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_INITIAL;
+ }
+ else {
+ // inform decoder where to read PCM data
+ pIoDataInst->frameDataStart = pIoDataInst->buff1;
+ pIoDataInst->frameDataSize = pIoDataInst->frameLengthPCM*pIoDataInst->elementSize;
+
+ pIoDataInst->deliverZeros = FALSE;
+
+ if(pIoDataInst->autoDet.ibMode == IBMODE_DEFAULT) {
+ if(pIoDataInst->autoDet.zeroCount >= pIoDataInst->zeroRunTrigger) {
+ pIoDataInst->deliverZeros = TRUE;
+ }
+
+ if(pIoDataInst->autoDet.zeroCount >= pIoDataInst->zeroRunRestart) {
+ /* Reset if zero-run is long enough */
+ autoDetReset(pIoDataInst);
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_INITIAL;
+ }
+ }
+ else if(pIoDataInst->autoDet.ibMode == IBMODE_NO_ZERORUNRESTART) {
+ if(pIoDataInst->autoDet.zeroCount >= pIoDataInst->zeroRunTrigger) {
+ pIoDataInst->deliverZeros = TRUE;
+ }
+ }
+ else {
+ // ibMode = IBMODE_NO_ZERORUN. Stay in this state and do nothing
+ }
+ }
+
+ break;
+
+ case AUTODET_SYNC_CHECK_ONGOING:
+ autoDetSyncCheck(pIoDataInst);
+
+ /* Check if a full frame has been received and if so, check if SYNC is maintained */
+ if(pIoDataInst->autoDet.completeFrameRcvd) {
+ if(pIoDataInst->autoDet.syncDetected) {
+ pIoDataInst->autoDet.syncState = IODATA_SYNC_BITSTREAM;
+ pIoDataInst->autoDet.completeFrameRcvd = FALSE;
+
+ // Inform decoder to read data from the beginning of current frame (after the preamble)
+ // Note: this address could be 1-word pass the end of input buffer and therefore needs
+ // to be wrapped around by ioBuffWrapPointer().
+ pIoDataInst->frameDataStart = ioBuffWrapPointer(pIoDataInst->ioBuffHandle,
+ pIoDataInst->autoDet.frameDataStartConfirm);
+ pIoDataInst->frameDataSize = pIoDataInst->autoDet.frameLength*pIoDataInst->elementSize;
+
+ // Store the beginning address of data in current frame (not including the preamble)
+ pIoDataInst->autoDet.frameDataStartConfirm = pIoDataInst->autoDet.frameDataStartTemp;
+ pIoDataInst->dbgStats.numFramesRcvd += 1;
+
+ // re-initialize for SYNC check
+ syncCheckInit(pIoDataInst);
+ }
+ else {
+ pIoDataInst->dbgStats.numSyncLost += 1; // what else needs to be done???
+ autoDetReset(pIoDataInst);
+ pIoDataInst->autoDetState = AUTODET_SYNC_SEARCH_INITIAL;
+ pIoDataInst->autoDet.syncState = IODATA_SYNC_NONE;
+ }
+ }
+ else {
+ ; //pIoDataInst->autoDet.syncState = IODATA_SYNC_CHECK;
+ }
+ break;
+
+ default: break;
+ }
+
+} /* autoDetection */
+
+/*=============================================================================
+ * This function resets auto-detection.
+ =============================================================================*/
+void autoDetReset(ioDataInst_t * pIoDataInst)
+{
+ pIoDataInst->deliverZeros = FALSE;
+ pIoDataInst->autoDet.zeroCount = 0;
+ pIoDataInst->autoDet.syncState = IODATA_SYNC_NONE;
+ pIoDataInst->autoDet.scanState = SCANNED_NONE;
+ pIoDataInst->autoDet.timeOutStarted = FALSE;
+ pIoDataInst->autoDet.syncDetected = FALSE;
+ pIoDataInst->autoDet.timeOutCntr = pIoDataInst->unknownSourceTimeOut;
+ //pIoDataInst->autoDet.timeOutCntr = pIoDataInst->unknownSourceTimeOut*20;
+ pIoDataInst->numElementsRead = pIoDataInst->frameLengthDef;
+ pIoDataInst->elementSize = IODATA_ELEMENT_SIZE_DEF;
+
+ pIoDataInst->timeOutCntr = pIoDataInst->unknownSourceTimeOut;
+ //pIoDataInst->timeOutCntr = pIoDataInst->unknownSourceTimeOut*20;
+ pIoDataInst->dbgStats.numFramesRcvd = 0;
+ pIoDataInst->dbgStats.numBuffUnderflow = 0;
+} /* autoDetReset */
+
+/*=============================================================================
+ * This function re-initializes auto-detection for scanning SYNC in PCM data
+ =============================================================================*/
+void syncScanPcmInit(ioDataInst_t * pIoDataInst)
+{
+ //pIoDataInst->deliverZeros = FALSE;
+ //pIoDataInst->autoDet.zeroCount = 0;
+ //pIoDataInst->autoDet.scanState = SCANNED_NONE;
+ //pIoDataInst->autoDet.timeOutStarted = FALSE;
+ //pIoDataInst->autoDet.syncDetected = FALSE;
+ //pIoDataInst->autoDet.timeOutCntr = pIoDataInst->unknownSourceTimeOut*2;
+ //pIoDataInst->autoDet.timeOutCntr = pIoDataInst->unknownSourceTimeOut*20;
+ pIoDataInst->numElementsRead = pIoDataInst->frameLengthPCM;
+ //pIoDataInst->timeOutCntr = pIoDataInst->unknownSourceTimeOut*2;
+ //pIoDataInst->timeOutCntr = pIoDataInst->unknownSourceTimeOut*20;
+ pIoDataInst->elementSize = IODATA_NUM_BYTES_PCMSAMPLE;
+} /* syncScanPcmInit */
+
+/*=============================================================================
+ * Initialization for checking sync in subsequent bitstream frames.
+ =============================================================================*/
+void syncCheckInit(ioDataInst_t * pIoDataInst)
+{
+ int i;
+ uint_least16_t pc = pIoDataInst->autoDet.bitStreamInfo & IODATA_SYNC_PC_MASK;
+
+ pIoDataInst->autoDet.frameLength = pIoDataInst->IECframeLengths[pc];
+ pIoDataInst->autoDet.distToFrameEnd = pIoDataInst->autoDet.frameLength
+ - pIoDataInst->autoDet.numElementsRcvd;
+
+//#ifdef ADJUST_XFER_SIZE_AFTER_AUTODET
+#if 1
+ // Adjust the read size such that next read will contain the preamble of next
+ // frame at the end of the read. For first frame after SYNC is detected, the
+ // read size will be smaller than frame size. For subsequent frames, the read
+ // size will be equal to the frame size.
+ pIoDataInst->numElementsRead = pIoDataInst->autoDet.distToFrameEnd
+ + pIoDataInst->autoDet.headerLength;
+#endif
+
+ pIoDataInst->autoDet.preambleStartsPrevBuf = FALSE;
+ pIoDataInst->autoDet.completeFrameRcvd = FALSE;
+ pIoDataInst->autoDet.syncDetected = FALSE;
+ pIoDataInst->autoDet.preambleInd = 0;
+
+ for(i=0; i<pIoDataInst->autoDet.headerLength; i++)
+ {
+ pIoDataInst->autoDet.preambleBuf[i] = 0x0;
+ }
+} /* syncCheckInit */
+
+
+/*=============================================================================
+ * This function scans for sync word (preamble) in the input buffer while
+ * checking for time out. It calls subroutine syncScan to scan the data.
+ *
+ * The read pointer(s) to the input buffer and the read sizes are provided by
+ * the I/O BUFF component and stored in auto-detection instance. The read
+ * pointers are also refered as sub-buffers.
+ *
+ * NOte: Since the input buffer may wrapp around, there may be two sub-buffers,
+ * one at the end of the input buffer and the other at the beginning,
+ * provided to auto-detection. In this case, syncScan subroutine will be
+ * called twice.
+ =============================================================================*/
+void autoDetSyncScan(ioDataInst_t * pIoDataInst)
+{
+ /* scan first sub-buffer for sync */
+ if((pIoDataInst->buff1 != NULL) && (pIoDataInst->size1 != 0)) {
+ syncScan(pIoDataInst->buff1, pIoDataInst->size1, pIoDataInst->elementSize,
+ &pIoDataInst->autoDet);
+ pIoDataInst->timeOutCntr -= pIoDataInst->size1/pIoDataInst->elementSize;
+ }
+
+ /* check if sync word is found in the first sub-buffer */
+ if(pIoDataInst->autoDet.syncDetected) {
+ /* skip scanning second sub-buffer if sync is detected */
+ if((pIoDataInst->buff2 != NULL) && (pIoDataInst->size2 != 0)) {
+ /* update the number of received elements in current frame */
+ pIoDataInst->autoDet.numElementsRcvd += pIoDataInst->size2;
+ }
+ }
+ else if((pIoDataInst->buff2 != NULL) && (pIoDataInst->size2 != 0)) {
+ /* scan second sub-buffer if there are two sub-buffers */
+ syncScan(pIoDataInst->buff2, pIoDataInst->size2, pIoDataInst->elementSize,
+ &pIoDataInst->autoDet);
+ pIoDataInst->timeOutCntr -= pIoDataInst->size2/pIoDataInst->elementSize;
+ }
+} /* ioDataAutoDetSyncScan */
+
+/*=============================================================================
+ * This function scans for sync word (preamble) in the provided sub-buffer.
+ =============================================================================*/
+void syncScan(void *buff, size_t size, int8_t elementSize, autoDet_t *pDet)
+{
+ uint_least16_t *pbuf;
+ int i, stride, scanCount, zeroCount;
+ uint_least16_t scanState;
+ uint_least16_t *syncPtr;
+
+ pbuf = (uint_least16_t *)buff;
+
+ /* check element size */
+ if (elementSize == IODATA_NUM_BYTES_PCMSAMPLE) {
+ /* skip every other 16-bit number and only look at MSB of PCM samples */
+ stride = IODATA_NUM_BYTES_PCMSAMPLE / sizeof(uint_least16_t);
+ pbuf += 1;
+ }
+ else {
+ stride = 1;
+ }
+
+ /* get ready for scanning */
+ scanCount = 0;
+ zeroCount = pDet->zeroCount;
+ scanState = pDet->scanState;
+
+ /* check if part of the sync words (preamble) are found in previous call */
+ if(scanState != SCANNED_NONE) {
+ /* count this sub-buffer in the number of received elements in current frame */
+ pDet->numElementsRcvd += size/sizeof(uint_least16_t);
+ }
+
+ /* scan until out of available data or sync is found */
+ for (i=0; i < size/elementSize; i+=stride) {
+ uint_least16_t tail = pbuf[i];
+
+ if (scanState == SCANNED_NONE) {
+ if (tail == IEC_PA) {
+ /* make sure there are some zeros before PA. */
+ if (zeroCount >= IODATA_MIN_NUM_ZEROS_BEFORE_PA) {
+ scanState = SCANNED_IEC_PA;
+ syncPtr = &pbuf[i]; /* mark the position of PA */
+ }
+ }
+
+ if(scanState != SCANNED_NONE) {
+ /* Found first sync word. Save its address */
+ pDet->bitStreamSyncPtr = syncPtr;
+
+ /* number of elements in current frame that have been received
+ * in this sub-buffer, including the preamble (sync words). */
+ pDet->numElementsRcvd = size/sizeof(uint_least16_t) - i;
+ pDet->preambleRef[0] = tail; /* save this word for sync check */
+ }
+
+ /* update zero count and prevent wrap around */
+ zeroCount = min (zeroCount+1,INT_MAX - 1);
+ if (tail != 0x0000) {
+ zeroCount = 0;
+ }
+
+ // don't start counting until we get the first non-zero
+ // sample while UNKNOWN. Note we don't have to worry
+ // about the other scanCount increments since these
+ // only occur after the first non-zero sample.
+ //
+ // so don't count unless one of the following is true:
+ // . the last sample was non-zero
+ // . we are already started counting (in this call)
+ // . we started counting in an earlier scanForSync (timeout has changed)
+ //if (scanCount || (tail != 0x0000) || pDet->timeOutStarted) {
+ // scanCount += 1;
+ //}
+
+ if (tail != 0x0000) {
+ scanCount += 1;
+ pDet->timeOutStarted = TRUE;
+ }
+ else if (scanCount || pDet->timeOutStarted) {
+ scanCount += 1;
+ }
+ else {
+ // don't increment scanCount
+ }
+
+ continue;
+ }
+
+ // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+
+ switch (scanState) {
+
+ case SCANNED_IEC_PA:
+ if (tail == IEC_PB) {
+ scanState = SCANNED_IEC_PB;
+ scanCount += 1;
+ pDet->preambleRef[1] = tail; /* save this word for sync check */
+ }
+ else {
+ scanState = SCANNED_NONE;
+ }
+ break;
+
+ case SCANNED_IEC_PB:
+ // Update scanCount here since, at this point, we are confident that
+ // this is a proper IEC stream. Regardless if we ignore it our not.
+ // Therefore we want to properly signal that this data has been scanned.
+ scanCount += 1;
+
+ // check for IEC pause packets at this time and if required ignore them.
+ // By construction we are guaranteed to have tail=PC at this time.
+ if ((pDet->ibMode == IBMODE_NO_ZERORUNRESTART) ||
+ (pDet->ibMode == IBMODE_NO_ZERORUN)) {
+ if ( ((tail&0x1F) == 0) || ((tail&0x1F) == 3)) {
+ scanState = SCANNED_NONE;
+ break;
+ }
+ }
+
+ // fall through to SCANNED_IEC_PC:
+ pDet->preambleRef[2] = tail; /* save this word for sync check */
+ pDet->bitStreamInfo = tail;
+ scanState = SCANNED_IEC_PC;
+ break;
+
+ case SCANNED_IEC_PC:
+ //pDevExt->headerSize = IEC_HEADER_SIZE;
+ pDet->preambleRef[3] = tail; /* save this word for sync check */
+ pDet->headerLength = IODATA_HEADER_LENGTH_IEC;
+ pDet->headerCheckLen = IODATA_HEADER_CHECK_LENGTH_IEC;
+ scanState = SCANNED_IEC_PD;
+
+ break;
+
+ case SCANNED_IEC_PD:
+ // wait untill full header is received
+ pDet->syncDetected = TRUE;
+ pDet->frameDataStartTemp = &pbuf[i];
+
+ break;
+
+ } /* switch */
+
+ if(pDet->syncDetected) {
+ break; // break from for loop
+ }
+ } /* for */
+
+ pDet->zeroCount = zeroCount;
+ pDet->scanState = scanState;
+ if (pDet->timeOutCntr > scanCount) {
+ pDet->timeOutCntr -= scanCount;
+ }
+ else {
+ pDet->timeOutCntr = 0;
+ }
+
+} /* syncScan */
+
+
+/*=============================================================================
+ * This function checks for sync word (preamble) at the expected location in the
+ * input buffer. Similar to ioDataAutoDetSyncScan, it looks into two sub-buffers
+ * when the input buffer wraps around.
+ *
+ =============================================================================*/
+void autoDetSyncCheck(ioDataInst_t * pIoDataInst)
+{
+ // look into first sub-buffer for preamble
+ if((pIoDataInst->buff1 != NULL) && (pIoDataInst->size1 != 0)) {
+ syncCheck(pIoDataInst->buff1, pIoDataInst->size1, pIoDataInst->elementSize,
+ &pIoDataInst->autoDet);
+ }
+
+ // check if first sub-buffer contains the expected preamble
+ if(pIoDataInst->autoDet.syncDetected) {
+ // skip second sub-buffer if first sub-buffer contains the expected preamble */
+ if((pIoDataInst->buff2 != NULL) && (pIoDataInst->size2 != 0)) {
+ // update the number of received elements in current frame
+ pIoDataInst->autoDet.numElementsRcvd += pIoDataInst->size2;
+ }
+ }
+ else if((pIoDataInst->buff2 != NULL) && (pIoDataInst->size2 != 0)) {
+ // look into second sub-buffer if there are two sub-buffers
+ syncCheck(pIoDataInst->buff2, pIoDataInst->size2, pIoDataInst->elementSize,
+ &pIoDataInst->autoDet);
+ }
+} /* autoDetSyncCheck */
+
+
+/*=============================================================================
+ * This function scans checks for sync word (preamble) in the provided sub-buffer.
+ =============================================================================*/
+void syncCheck(void *buff, size_t size, int8_t elementSize, autoDet_t *pDet)
+{
+ uint_least16_t *pbuf;
+ int i, diff, restOfPreamble;
+ uint_least32_t numElements;
+
+ pbuf = (uint_least16_t *)buff;
+ numElements = size / elementSize; // number of elements in provided sub-buffer
+
+ // Check if the preamble already starts from the sub-buffer in previous call
+ if(pDet->preambleStartsPrevBuf) {
+ // Calculate number of preamble words in this sub-buffer
+ restOfPreamble = pDet->headerLength - pDet->preambleInd;
+
+ // Save the preamble words for sync check
+ for(i=0; i<restOfPreamble; i++)
+ {
+ pDet->preambleBuf[pDet->preambleInd++] = pbuf[i];
+ }
+
+ // Starts counting elements for next sync check
+ pDet->frameDataStartTemp = &pbuf[i]; // starting address of data in next frame
+ pDet->numElementsRcvd += numElements; // number of received elements
+ pDet->preambleStartsPrevBuf = FALSE; // reset flag
+ }
+ else {
+ // Preamble hasn't started from the sub-buffer in previous call.
+ // Check if this frame ends in this sub-buffer:
+ // distToFrameEnd: distance from beginning of this sub-buffer to frame end
+ // numElements: number of elements in this sub-buffer
+ if(pDet->distToFrameEnd < numElements) {
+ // Preamble of next frame is in this sub-buffer, either full or partial.
+ // First distToFrameEnd elements in the sub-buffer are the end of current
+ // frame. Preamble of next frame starts from pbuf[pDet->distToFrameEnd].
+ if(pDet->distToFrameEnd <= (numElements-pDet->headerLength)) {
+ // All the preamble words are in this sub-buffer
+ for(i=pDet->distToFrameEnd; i<pDet->distToFrameEnd+pDet->headerLength; i++)
+ {
+ // Save preamble words for sync check
+ pDet->preambleBuf[pDet->preambleInd++] = pbuf[i];
+ }
+
+ // Store the starting address of data in next frame.
+ // Note: &pbuf[i] could be 1 word pass the input buffer end if
+ // the last word of preamble happens to be at the end of
+ // the input buffer. In this case, this address needs to
+ // be wrapped around to the beginning of input buffer.
+ pDet->frameDataStartTemp = &pbuf[i];
+ }
+ else {
+ // Only partial preamble is in this sub-buffer.
+ // The preamble spans across this sub-buffer and next.
+ for(i=pDet->distToFrameEnd; i<numElements; i++)
+ {
+ pDet->preambleBuf[pDet->preambleInd++] = pbuf[i];
+ }
+ pDet->preambleStartsPrevBuf = TRUE;
+ }
+
+ // Starts counting elements for next sync check
+ pDet->numElementsRcvd = numElements - pDet->distToFrameEnd;
+ }
+ else {
+ // Current frame doesn't end here.
+ // Preamble of next frame is not in this sub-buffer
+ pDet->distToFrameEnd -= numElements;
+ }
+ }
+
+ // Check if full preamble of next frame has been received
+ if(pDet->preambleInd == pDet->headerLength) {
+ pDet->completeFrameRcvd = TRUE;
+
+ // Check if the preamble matches the reference.
+ diff = 0;
+ for(i=0; i<pDet->headerCheckLen; i++)
+ {
+ diff += pDet->preambleBuf[i] - pDet->preambleRef[i];
+ }
+
+ // SYNC is maintained if preamble matches reference
+ if(diff == 0) {
+ pDet->syncDetected = TRUE;
+ }
+ else {
+ pDet->syncDetected = FALSE;
+ }
+
+ // Reset index for next preamble check
+ //pDet->preambleInd = 0;
+ }
+} /* syncCheck */
+
+
+/* nothing past this point */
diff --git a/pasdk/test_dsp/io/ioData.h b/pasdk/test_dsp/io/ioData.h
--- /dev/null
@@ -0,0 +1,136 @@
+
+#ifndef IODATA_H
+#define IODATA_H
+
+#include <stdint.h>
+#include "ioBuff.h"
+
+// I/O DATA error code
+enum {
+ IODATA_NO_ERR,
+ IODATA_ERR_MEMORY,
+ IODATA_ERR_BAD_PARAMS,
+ IODATA_ERR_IOBUF_UNDERFLOW,
+ IODATA_ERR_IOBUF_OVERFLOW
+};
+
+// define a type for I/O DATA handle
+typedef void * ioDataHandle_t;
+
+// I/O DATA configuration parameters
+typedef struct ioDataParam_s{
+ ioBuffHandle_t ioBuffHandle; // handle to the associated I/O BUFF
+ uint_least16_t *frameLengthsIEC; // pointer to array of supported IEC frame lengths
+ uint_least16_t frameLengthPCM; // frame length for PCM input
+ uint_least16_t frameLengthDef; // default frame length for SYNC search
+ int_least32_t unknownSourceTimeOut; // time out value to declare unknown source
+ uint_least32_t zeroRunTrigger; // threshold to declare zero run
+ uint_least32_t zeroRunRestart; // threshold to restart auto-detection under zero run
+ int8_t ibMode; // IB Mode
+} ioDataParam_t;
+
+// Information needed for decoders to read a bitstream frame
+typedef struct ioDataReadInfo_s {
+ void *buffBase; // base address of the buffer holding the bitstream data
+ uint_least32_t buffSize; // size of the buffer holding the bitstream data
+ void *startAddress; // start address of next complete frame to read
+ uint_least32_t frameSize; // size of the frame in bytes
+} ioDataReadInfo_t;
+
+// Control commands for ioDataControl
+enum {
+ IODATA_CTL_SET_ELEMENT_SIZE,
+ IODATA_CTL_SET_FRAME_LENGTH,
+ IODATA_CTL_GET_INPBUFFINFO,
+ IODATA_CTL_GET_AUTODET_STATUS,
+};
+
+// SYNC search/detection status
+enum
+{
+ IODATA_SYNC_NONE,
+ IODATA_SYNC_ONE,
+// IODATA_SYNC_CHECK,
+ IODATA_SYNC_BITSTREAM,
+ IODATA_SYNC_PCM,
+ IODATA_SYNC_PCM_FORCED,
+ IODATA_SYNC_PCM_ZERORUN,
+ IODATA_SYNC_AUTO
+};
+
+// Frame information
+typedef struct ioDataFrameInfo_s {
+ uint_fast32_t frameLength; // length in units of elements
+ int8_t elementSize; // size of elements in bytes
+} ioDataFrameInfo_t;
+
+// Auto-detection status
+typedef struct ioDataAutoDetStat_s {
+ uint_least16_t syncState; // SYNC state
+ uint_least16_t bitStreamInfo; // bit stream information - value of IEC_PC
+ uint8_t deliverZeros; // flag to indicate whether zeros should be sent to output
+} ioDataAutoDetStat_t;
+
+// I/O DATA control structure
+typedef struct ioDataCtl_s {
+ uint_fast16_t code;
+ union {
+ ioDataReadInfo_t dataReadInfo; // IODATA_CTL_GET_INPBUFFINFO
+ ioDataFrameInfo_t frameInfo; // IODATA_CTL_SET_ELEMENT_SIZE or IODATA_CTL_SET_FRAME_LENGTH
+ ioDataAutoDetStat_t autoDetStats; // IODATA_CTL_GET_AUTODET_STATUS
+ } param;
+} ioDataCtl_t;
+
+/**
+ * @brief ioDataNumAlloc
+ * Returns the maximum number of memory allocation requests that ioDataAlloc()
+ * requires.
+ */
+int ioDataNumAlloc(void);
+
+/**
+ * @brief ioDataAlloc
+ * Returns a table of memory records that describe the size, alignment, type
+ * and memory space of all buffers required by I/O DATA component.
+ */
+int ioDataAlloc(lib_mem_rec_t *mem_tbl);
+
+/**
+ * @brief ioDataCreate
+ * Based on the provided memory blocks, this function creates an I/O DATA
+ * instance and returns a handle. This handle points to the memory block
+ * that contains the instance.
+ */
+int ioDataCreate(ioDataHandle_t *handle, const lib_mem_rec_t *mem_tbl);
+
+/**
+ * @brief ioDATAInit
+ * Initializes the I/O DATA instance.
+ */
+int ioDataInit(ioDataHandle_t handle, ioDataParam_t *cfgParams);
+
+/**
+ * @brief ioDataProcess
+ * The main function of I/O DATA processing, i.e. auto-detection.
+ */
+int ioDataProcess(ioDataHandle_t handle);
+
+/**
+ * @brief ioDataReadComplete
+ * This function marks as read complete the data in the input buffer that has
+ * been processed by ioDataProcess and the decoder. It should be called after
+ * ioDataProcess() is called and after the decoder finishes reading current
+ * frame in the input buffer.
+ */
+int ioDataReadComplete(ioDataHandle_t handle);
+
+
+/**
+ * @brief ioDataControl
+ * This function allows run-time control of I/O DATA components through control
+ * command IODATA_CTL_XXX and control structure ioDataCtl_t.
+ */
+int ioDataControl(ioDataHandle_t handle, ioDataCtl_t *ctlParams);
+
+
+#endif
diff --git a/pasdk/test_dsp/io/ioPhy.c b/pasdk/test_dsp/io/ioPhy.c
--- /dev/null
@@ -0,0 +1,471 @@
+
+#include "ioPhy.h"
+#include "ioPhy_loc.h"
+#include "libarch.h"
+#include "mcasp_drv.h"
+
+#include <stdint.h>
+#include <xdc/runtime/System.h> // for System_printf
+#include <ti/sysbios/hal/Cache.h>
+
+#define NUM_MCASP_PRIME_PACKETS 3 // should be provided by McASP driver
+
+/******************************************************************************
+* Implementation of I/O Physical Layer Component
+******************************************************************************/
+
+#define IOPHY_NUM_MEM_ALLOCS 1
+#define IOPHY_INST_ALIGN 3
+
+//C:\ti\edma3_lld_2_12_01_24\packages\ti\sdo\edma3\drv\sample\src\platforms\sample_tci66ak2g02_cfg.c
+extern signed char* getGlobalAddr(signed char* addr); // to be replaced by lib_getGlobalAddr
+
+/*******************************************************************************
+* API function: ioPhyNumAlloc
+* Returns the maximum number of memory allocation requests that ioPhyAlloc()
+* requires.
+*******************************************************************************/
+int ioPhyNumAlloc(void)
+{
+ return (IOPHY_NUM_MEM_ALLOCS);
+}
+
+/*******************************************************************************
+* API function: ioPhyAlloc
+* Returns a table of memory records that describe the size, alignment, type
+* and memory space of all buffers required by I/O PHY component.
+*******************************************************************************/
+int ioPhyAlloc(lib_mem_rec_t *mem_tbl)
+{
+ mem_tbl[0].size = sizeof(ioPhyInst_t);
+ mem_tbl[0].alignment = IOPHY_INST_ALIGN;
+ mem_tbl[0].type = LIB_PMEM_SLOW;
+ mem_tbl[0].base = NULL;
+
+ return (IOPHY_NOERR);
+}
+
+/******************************************************************************
+* API function:
+* I/O physical layer creation.
+******************************************************************************/
+int ioPhyCreate(ioPhyHandle_t *handle, const lib_mem_rec_t *mem_tbl)
+{
+ ioPhyInst_t *io_phy_inst;
+
+ if( (mem_tbl[0].size < sizeof(ioPhyInst_t))
+ ||libChkAlign(mem_tbl[0].base, IOPHY_INST_ALIGN) ) {
+ return (IOPHY_ERR_MEMORY);
+ }
+
+ io_phy_inst = (ioPhyInst_t *)mem_tbl[0].base;
+
+ /* return I/O PHY instance */
+ *handle = (ioPhyHandle_t *)io_phy_inst;
+
+ return (IOPHY_NOERR);
+}
+
+/******************************************************************************
+* API function:
+* I/O physical layer initialization.
+******************************************************************************/
+int ioPhyInit(ioPhyHandle_t handle, const ioPhyParams_t *params)
+{
+ ioPhyInst_t *io_phy_inst;
+ Mcasp_IOcmd_e mcasp_cmd;
+ int i;
+
+ io_phy_inst = (ioPhyInst_t *)handle;
+
+ if(params == NULL) {
+ return (IOPHY_ERR_BAD_PARAMS);
+ }
+
+ /* attach I/O buffer manangement handle */
+ io_phy_inst->io_buff_handle = params->ioBuffHandle;
+
+ /* set transfer frame size - interrupt generated when the frame is transfered */
+ io_phy_inst->xfer_frame_size = params->xferFrameSize;
+
+ /* attach McASP driver channel handle */
+ io_phy_inst->mcasp_chan_handle = params->mcaspChanHandle;
+
+ /* set the operation that I/O PHY will perform to I/O buffer - read or write */
+ io_phy_inst->ioBuffOp = params->ioBuffOp;
+
+ /* attach ioBuff functions based on buffer operation */
+ if(params->ioBuffOp == IOPHY_IOBUFFOP_READ) {
+ io_phy_inst->ioBuffMarkComplete = ioBuffReadComplete;
+ io_phy_inst->ioBuffGetPtrs = ioBuffGetReadPtrs;
+ mcasp_cmd = MCASP_WRITE;
+ } else {
+ io_phy_inst->ioBuffMarkComplete = ioBuffWriteComplete;
+ io_phy_inst->ioBuffGetPtrs = ioBuffGetWritePtrs;
+ mcasp_cmd = MCASP_READ;
+ }
+ for(i=0; i<IOPHY_NUM_XFER_RECORD; i++)
+ {
+ io_phy_inst->xfered_packets[i].cmd = mcasp_cmd;
+ }
+ io_phy_inst->mcasp_cmd = mcasp_cmd;
+
+ /* initialize status variables */
+ io_phy_inst->sync_cntr = 0; /* to keep track xfer submit and complete */
+ io_phy_inst->submit_ind = 0; /* index to submited McASP packets */
+ io_phy_inst->complete_ind = 0; /* index to completed McASP packets */
+
+ return (IOPHY_NOERR);
+} /* ioPhyInit */
+
+/******************************************************************************
+* I/O PHY internal function:
+* Calculate transfer size in bytes based on encoding frame size passed
+* through ioPhyControl.
+******************************************************************************/
+static size_t ioPhy_calc_xfer_size(ioPhyInst_t *io_phy_inst)
+{
+ /* calc. xfer size based on io_phy_inst->frame_size */
+
+ return (io_phy_inst->xfer_frame_size);
+}
+
+/******************************************************************************
+* API function:
+* Submit transfer to underlining driver.
+*
+* - Called by audio processing task.
+******************************************************************************/
+int ioPhyXferSubmit(ioPhyHandle_t handle)
+{
+ int submit_ind, err_code, ret_value;
+ void *buff1, *buff2;
+ size_t size1, size2, xfer_size;
+ ioPhyInst_t *io_phy_inst = (ioPhyInst_t *)handle;
+
+ /* Figure out the transfer size in bytes */
+ xfer_size = ioPhy_calc_xfer_size(io_phy_inst); // internal function
+
+ ret_value = IOPHY_NOERR;
+
+ /* Get one or two buffers from I/O buffer management for write */
+ err_code = io_phy_inst->ioBuffGetPtrs(io_phy_inst->io_buff_handle, xfer_size,
+ &buff1, &size1, &buff2, &size2);
+
+ /* Don't return from here even if ioBuff overflows or underflows, since McASP
+ needs to be running and generating interrupts all the time. */
+ if(err_code == IOBUFF_ERR_UNDERFLOW) {
+ ret_value = IOPHY_ERR_BUFF_UNDERFLOW;
+ }
+ if(err_code == IOBUFF_ERR_OVERFLOW) {
+ ret_value = IOPHY_ERR_BUFF_OVERFLOW;
+ }
+
+ /* ioBuff needs to provide buffer to read/write even if it underflows/overflows */
+ if(buff1 == NULL) {
+ return (IOPHY_ERR_BUFF_BADPTRS);
+ }
+
+ /* Submit 1 or 2 transfers depending on whether I/O buffer wraps around */
+ submit_ind = io_phy_inst->submit_ind;
+
+ /* Compose McASP packet and save in the instance - McASP driver requires
+ the packet to be in permanent memory so that it can provide the packet
+ to the callback function. */
+// io_phy_inst->xfered_packets[submit_ind].cmd = 0;
+ io_phy_inst->xfered_packets[submit_ind].addr = (void*)(getGlobalAddr(buff1));
+ io_phy_inst->xfered_packets[submit_ind].size = size1;
+ io_phy_inst->xfered_packets[submit_ind].status = 0;
+ io_phy_inst->xfer_rec[submit_ind].base = buff1;
+ io_phy_inst->xfer_rec[submit_ind].size = size1;
+
+ if(buff2 == NULL) {
+ /* There is no wrap around in I/O buffer - submit one transfer */
+ /* indicate that this is the final transfer of a frame */
+ io_phy_inst->xfered_packets[submit_ind].arg = IOPHY_XFER_FINAL;
+ io_phy_inst->xfer_rec[submit_ind].packet_status = IOPHY_XFER_FINAL;
+ } else {
+ /* There is wrap around in I/O buffer - submit two tranfers */
+ /* indicate that this is the intermediate transfer of a frame */
+ io_phy_inst->xfered_packets[submit_ind].arg = IOPHY_XFER_INTER;
+ io_phy_inst->xfer_rec[submit_ind].packet_status = IOPHY_XFER_INTER;
+ }
+
+ /* make a transfer request */
+ if((err_code = mcaspSubmitChan(io_phy_inst->mcasp_chan_handle,
+ &io_phy_inst->xfered_packets[submit_ind])) != 1) {
+ //System_printf("mcaspSubmitChan failed with handle 0x%x and error code %d!\n",
+ // (unsigned int)io_phy_inst->mcasp_chan_handle, err_code);
+ return(IOPHY_ERR_MCASP_FAIL);
+ }
+
+ /* update submit index */
+ submit_ind++;
+ if(submit_ind == IOPHY_NUM_XFER_RECORD) {
+ submit_ind = 0;
+ }
+ io_phy_inst->submit_ind = submit_ind;
+
+ /* make another transfer request if ioBuff wraps around */
+ if(buff2 != NULL) {
+ /* Compose McASP packets and save in the instance */
+ //io_phy_inst->xfered_packets[submit_ind].cmd = 0;
+ io_phy_inst->xfered_packets[submit_ind].addr = (void*)(getGlobalAddr(buff2));
+ io_phy_inst->xfered_packets[submit_ind].size = size2;
+ io_phy_inst->xfered_packets[submit_ind].status = 0;
+ /* indicate that this is the final transfer of a frame */
+ io_phy_inst->xfered_packets[submit_ind].arg = IOPHY_XFER_FINAL;
+
+ io_phy_inst->xfer_rec[submit_ind].base = buff2;
+ io_phy_inst->xfer_rec[submit_ind].size = size2;
+ io_phy_inst->xfer_rec[submit_ind].packet_status = IOPHY_XFER_FINAL;
+
+ if((err_code = mcaspSubmitChan(io_phy_inst->mcasp_chan_handle,
+ &io_phy_inst->xfered_packets[submit_ind])) != 1) {
+ //System_printf("mcaspSubmitChan failed with handle 0x%x and error code %d!\n",
+ // (unsigned int)io_phy_inst->mcasp_chan_handle, err_code);
+ return(IOPHY_ERR_MCASP_FAIL);
+ }
+
+ submit_ind++;
+ if(submit_ind == IOPHY_NUM_XFER_RECORD) {
+ submit_ind = 0;
+ }
+ io_phy_inst->submit_ind = submit_ind;
+ }
+
+ return (ret_value);
+} /* ioPhyXferSubmit() */
+
+
+void swapData(void *buff, uint_least32_t size)
+{
+ int i;
+ int_least16_t L0, L1, L2, L3, R0, R1, R2, R3 = 0;
+ int_least16_t *p1, *p2;
+
+ int_least16_t *dataPtr = (int_least16_t *)buff;
+/*
+ for (i=0; i<size/2; i++)
+ {
+ if(dataPtr[i] == (int_least16_t)0xF872) {
+ dataPtr[i] = 0x278F;
+ }
+ }
+*/
+ for (i=0; i<size/2; i+=8)
+ {
+ p1 = &dataPtr[i];
+ p2 = p1;
+
+ L0 = *p1++;
+ L1 = *p1++;
+ L2 = *p1++;
+ L3 = *p1++;
+ R0 = *p1++;
+ R1 = *p1++;
+ R2 = *p1++;
+ R3 = *p1++;
+
+ *p2++ = L0;
+ *p2++ = R0;
+ *p2++ = L1;
+ *p2++ = R1;
+ *p2++ = L2;
+ *p2++ = R2;
+ *p2++ = L3;
+ *p2++ = R3;
+ }
+
+ return;
+}
+
+/*======================================================================================
+ * This function swaps HDMI input data in a given buffer
+ *====================================================================================*/
+void hdmiDataSwap(void * buff, uint_least32_t size)
+{
+ Cache_inv(buff, size, Cache_Type_ALL, 0);
+ Cache_wait();
+
+ swapData(buff, size);
+
+ Cache_wb (buff, size, Cache_Type_ALL, 0);
+ Cache_wait();
+} /* ioDataSwapBuffer */
+
+/******************************************************************************
+* API function:
+* Marks I/O buffer read/write complete.
+*
+* - Called by audio processing task.
+******************************************************************************/
+int ioPhyXferComplete(ioPhyHandle_t handle, int dataSwap)
+{
+ int complete_ind;
+ void *buff;
+ size_t size;
+
+ ioPhyInst_t *io_phy_inst = (ioPhyInst_t *)handle;
+
+ /* Based on index to completed packets, find the base address and size of the
+ just completed McASP packet and pass to ioBuff to mark read/write complete. */
+ complete_ind = io_phy_inst->complete_ind;
+ buff = io_phy_inst->xfer_rec[complete_ind].base;
+ size = io_phy_inst->xfer_rec[complete_ind].size;
+
+ if(dataSwap) {
+ hdmiDataSwap(buff, size);
+ }
+
+ io_phy_inst->ioBuffMarkComplete(io_phy_inst->io_buff_handle, buff, size);
+
+ /* Check if this is a single McASP transfer or batch transfer */
+ if(io_phy_inst->xfer_rec[complete_ind].packet_status == IOPHY_XFER_INTER) {
+ /* This is a batch transfer, so also mark next packet as complete. */
+ complete_ind++;
+ if(complete_ind == IOPHY_NUM_XFER_RECORD) {
+ complete_ind = 0;
+ }
+
+ if(io_phy_inst->xfer_rec[complete_ind].packet_status == IOPHY_XFER_FINAL) {
+ buff = io_phy_inst->xfer_rec[complete_ind].base;
+ size = io_phy_inst->xfer_rec[complete_ind].size;
+
+ if(dataSwap) {
+ hdmiDataSwap(buff, size);
+ }
+
+ io_phy_inst->ioBuffMarkComplete(io_phy_inst->io_buff_handle, buff, size);
+ } else {
+ // error!
+ }
+ }
+
+ /* increment index to point to next completed packet */
+ io_phy_inst->complete_ind = complete_ind+1;
+ if(io_phy_inst->complete_ind == IOPHY_NUM_XFER_RECORD) {
+ io_phy_inst->complete_ind = 0;
+ }
+
+ return (IOPHY_NOERR);
+} /* ioPhyXferComplete() */
+
+
+// TODO: add error check and recovery mechanism
+int ioPhyCheckXferStatus(ioPhyHandle_t handle, MCASP_Packet *mcasp_packet)
+{
+ int complete_ind, temp_ind;
+ ioPhyInst_t *io_phy_inst = (ioPhyInst_t *)handle;
+
+ // complete_ind points to the packet to be marked as complete
+ complete_ind = io_phy_inst->complete_ind;
+ temp_ind = complete_ind + 1;
+ if(temp_ind == IOPHY_NUM_XFER_RECORD) {
+ temp_ind = 0;
+ }
+
+ // check if next completed packet is part of two-packet transfer or not:
+ // - if two-packet transfer, it points to the first packet
+ // - if one-packet transfer, it points to the only packet
+ if(io_phy_inst->xfer_rec[complete_ind].packet_status == IOPHY_XFER_INTER) {
+ // this is a two-packet transfer and this function may be called after either the
+ // first or the second packet has been transfered.
+ if( (mcasp_packet->arg == IOPHY_XFER_INTER) // first packet
+ && (mcasp_packet->addr == io_phy_inst->xfer_rec[complete_ind].base) ) {
+ // this is the first packet
+ return (IOPHY_XFER_INTER);
+ }
+ else if( (mcasp_packet->arg == IOPHY_XFER_FINAL) // second packet
+ && (mcasp_packet->addr == io_phy_inst->xfer_rec[temp_ind].base) ) {
+ // this is the second packet
+ return (IOPHY_XFER_FINAL);
+ }
+ else {
+ return (IOPHY_XFER_ERROR);
+ }
+ }
+ else {
+ // this is a one-packet transfer
+ if( (mcasp_packet->arg == IOPHY_XFER_FINAL)
+ &&(mcasp_packet->addr == io_phy_inst->xfer_rec[complete_ind].base) ) {
+ return (IOPHY_XFER_FINAL);
+ }
+ else {
+ return (IOPHY_XFER_ERROR);
+ }
+ }
+
+#if 0
+ if(mcasp_packet->addr != io_phy_inst->xfer_rec[io_phy_inst->complete_ind].base) {
+ return (IOPHY_XFER_ERROR);
+ }
+
+ if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
+ return (IOPHY_XFER_FINAL);
+ }
+ else if (mcasp_packet->arg == IOPHY_XFER_INTER) {
+ return (IOPHY_XFER_INTER);
+ }
+ else {
+ return (IOPHY_XFER_ERROR);
+ }
+#endif
+
+} /* ioPhyCheckXferStatus */
+
+
+/******************************************************************************
+* API function: run-time control of IO Configuration component
+******************************************************************************/
+int ioPhyControl(ioPhyHandle_t handle, ioPhyCtl_t *ctl)
+{
+ ioPhyInst_t *io_phy_inst = (ioPhyInst_t *)handle;
+
+ switch(ctl->code) {
+ case IOPHY_CTL_FRAME_SIZE:
+ /* pass data frame size */
+ io_phy_inst->xfer_frame_size = ctl->params.xferFrameSize;
+ break;
+
+ case IOPHY_CTL_INPUT_CHANGE:
+ //ioPhyInit(handle, ctl->ioPhyRxParams);
+ break;
+
+ default:
+ break;
+ }
+
+ return (IOPHY_NOERR);
+} /* ioPhyControl */
+
+// change this API to something like ioPhyXferReSubmit(ioPhyHandle_t handle, int numXfer)
+int ioPhyXferErrRecover(ioPhyHandle_t handle)
+{
+ int submit_ind, i;
+ ioPhyInst_t *io_phy_inst = (ioPhyInst_t *)handle;
+
+ /* resend the latest #NUM_MCASP_PRIME_PACKETS packets */
+ submit_ind = io_phy_inst->submit_ind - NUM_MCASP_PRIME_PACKETS;
+ //submit_ind = io_phy_inst->submit_ind - (NUM_MCASP_PRIME_PACKETS-1);
+ if(submit_ind < 0) {
+ submit_ind += IOPHY_NUM_XFER_RECORD;
+ }
+
+ for(i=0; i<NUM_MCASP_PRIME_PACKETS; i++)
+ {
+ if((mcaspSubmitChan(io_phy_inst->mcasp_chan_handle,
+ &io_phy_inst->xfered_packets[submit_ind])) != 1) {
+ return(IOPHY_ERR_MCASP_FAIL);
+ }
+
+ submit_ind++;
+ if(submit_ind == IOPHY_NUM_XFER_RECORD) {
+ submit_ind = 0;
+ }
+ }
+
+ io_phy_inst->submit_ind = submit_ind;
+
+ return (IOPHY_NOERR);
+} /* ioPhyXferErrRecover */
diff --git a/pasdk/test_dsp/io/ioPhy.h b/pasdk/test_dsp/io/ioPhy.h
--- /dev/null
@@ -0,0 +1,107 @@
+
+
+#ifndef _IOPHY_H
+#define _IOPHY_H
+
+#include <stdint.h>
+#include "mcasp_drv.h"
+#include "libarch.h"
+#include "ioBuff.h"
+
+enum {
+ IOPHY_NOERR = 0,
+ IOPHY_ERR_HANDLE,
+ IOPHY_ERR_MEMORY,
+ IOPHY_ERR_BAD_PARAMS,
+ IOPHY_ERR_MCASP_FAIL,
+ IOPHY_ERR_BUFF_UNDERFLOW,
+ IOPHY_ERR_BUFF_OVERFLOW,
+ IOPHY_ERR_BUFF_BADPTRS,
+ IOPHY_ERR_BATCH_XFER_FAIL
+};
+
+enum {
+ IOPHY_IOBUFFOP_READ = 0,
+ IOPHY_IOBUFFOP_WRITE = 1
+};
+
+typedef uint_fast16_t ioPhyBuffOp_t;
+
+enum {
+ IOPHY_XFER_INTER = 0,
+ IOPHY_XFER_FINAL,
+ IOPHY_XFER_ERROR
+};
+
+typedef void * ioPhyHandle_t;
+
+typedef struct ioPhyParams {
+ void * mcaspChanHandle;
+ uint_least32_t xferFrameSize; // generate INT when this amount of data has been transfered
+ // can be changed at run time through control function
+ ioBuffHandle_t ioBuffHandle;
+ ioPhyBuffOp_t ioBuffOp; // READ or WRITE
+} ioPhyParams_t;
+
+enum {
+ IOPHY_CTL_FRAME_SIZE = 0,
+ IOPHY_CTL_INPUT_CHANGE,
+ IOPHY_CTL_INIT_DRIVER
+};
+
+typedef struct ioPhyCtl_s {
+ uint_fast16_t code;
+ union {
+ uint_least32_t xferFrameSize;
+ void * mcaspChanHandle;
+ } params;
+} ioPhyCtl_t;
+
+int ioPhyNumAlloc(void);
+int ioPhyAlloc(lib_mem_rec_t *memTab);
+int ioPhyCreate(ioPhyHandle_t *handle, const lib_mem_rec_t *mem_tbl);
+int ioPhyInit(ioPhyHandle_t handle, const ioPhyParams_t *params);
+
+/**
+ * @brief ioPhyXferCfg
+ * Configures next transfer.
+ * Reconfigure the EDMA driver link channel (PaRAM set) that has just finished
+ * transfer and generated TCINT.
+ *
+ * This function will call I/O buff API to get the write pointers.
+ *
+ * @param[in] handle
+ *
+ */
+int ioPhyXferSubmit(ioPhyHandle_t handle);
+
+/**
+ * @brief ioPhyXferComplete
+ * Marks complete the transfer which has just finished. This function will
+ * call I/O buff API to mark certain portion of the I/O buffer as
+ * write-completed.
+ *
+ * @param[in] handle
+ *
+ */
+int ioPhyXferComplete(ioPhyHandle_t handle, int dataSwap);
+
+/**
+ * @brief ioPhyControl
+ * Changes I/O PHY parameters at run time.
+ *
+ * @param[in] handle
+ * @param[in] ctl
+ *
+ * Configurable parameters:
+ * - ctl->xfer_frame_size: transfer frame size in bytes. Transfer completion
+ * INT is generated after this amount of data is
+ * transfered.
+ */
+int ioPhyControl(ioPhyHandle_t handle, ioPhyCtl_t *ctl);
+
+int ioPhyXferErrRecover(ioPhyHandle_t handle);
+
+int ioPhyCheckXferStatus(ioPhyHandle_t handle, MCASP_Packet *mcasp_packet);
+
+#endif
diff --git a/pasdk/test_dsp/io/ioPhy_loc.h b/pasdk/test_dsp/io/ioPhy_loc.h
--- /dev/null
@@ -0,0 +1,43 @@
+
+#ifndef IOPHY_LOC_H
+#define IOPHY_LOC_H
+
+#include <stdint.h>
+#include "ioBuff.h"
+#include "mcasp_drv.h"
+
+#define IOPHY_NUM_XFER_RECORD 8
+
+#define IOPHY_XFER_PACKET_INTER 0
+#define IOPHY_XFER_PACKET_FINAL 1
+
+
+typedef struct ioPhyXferRec_s {
+ void *base;
+ uint_least32_t size;
+ uint_fast16_t packet_status;
+} ioPhyXferRec_t;
+
+typedef struct ioPhyInst_s {
+ ioPhyXferRec_t xfer_rec[IOPHY_NUM_XFER_RECORD];
+ MCASP_Packet xfered_packets[IOPHY_NUM_XFER_RECORD];
+ ioBuffHandle_t io_buff_handle;
+ uint_least32_t xfer_frame_size;
+ Mcasp_IOcmd_e mcasp_cmd;
+
+ int_fast16_t sync_cntr;
+ uint_fast16_t submit_ind;
+ uint_fast16_t complete_ind;
+
+ void *mcasp_chan_handle;
+
+ ioPhyBuffOp_t ioBuffOp; // READ or WRITE
+ int (*ioBuffMarkComplete)(ioBuffHandle_t handle, void *start, size_t size);
+ int (*ioBuffGetPtrs)(ioBuffHandle_t handle, size_t mem_size,
+ void **rdptr1, size_t *size1,
+ void **rdptr2, size_t *size2);
+
+} ioPhyInst_t;
+
+
+#endif
diff --git a/pasdk/test_dsp/io/libarch.h b/pasdk/test_dsp/io/libarch.h
--- /dev/null
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#ifndef _LIBARCH_MEMMGT_H
+#define _LIBARCH_MEMMGT_H
+
+#include <stdlib.h>
+
+/** @defgroup libarch_memmgt Memory Management API
+ * @{
+ */
+/** @} */
+
+/** @addtogroup libarch_memmgt
+ * @brief Error return codes of memory management functions.
+ * @{
+ */
+/*@{*/
+#define LIB_MEMMGT_SUCCESS (0) /**< Success. No error. */
+#define LIB_MEMMGT_ERROR (-1) /**< Failure. */
+/*@}*/
+/** @} */
+
+/**
+ * @ingroup libarch_memmgt
+ * @brief Memory types in terms of speed and volatility
+ */
+enum {
+ LIB_SMEM_VFAST = 0, /**< Scratch memory, very fast */
+ LIB_SMEM_FAST, /**< Scratch memory, fast */
+ LIB_SMEM_MED, /**< Scratch memory, medium speed */
+ LIB_SMEM_SLOW, /**< Scratch memory, slow */
+ LIB_PMEM_MED, /**< Permanent memory, medium speed */
+ LIB_PMEM_SLOW, /**< Permanent memory, slow */
+ LIB_MEMTYPE_N /**< Total number of types */
+};
+
+typedef unsigned int lib_mem_type_t;
+
+typedef struct {
+ size_t size; /**< heap size in number of bytes */
+ lib_mem_type_t type;
+ unsigned int alignment;
+ void *base; /**< base address of the heap */
+} lib_mem_rec_t;
+
+#define libChkAlign(base, l2a) \
+ (((uint_least32_t)(base)&((~0UL<<(l2a))))==0UL)
+
+
+#endif /* _LIBARCH_MEMMGT_H */
+
+/* nothing past this point */
diff --git a/pasdk/test_dsp/io/test/audio_tsk.c b/pasdk/test_dsp/io/test/audio_tsk.c
--- /dev/null
@@ -0,0 +1,990 @@
+
+//#include "analog_test.h"
+#include "frame_work.h"
+#include "ioBuff.h"
+#include "ioData.h"
+#include "ioPhy.h"
+#include <mcasp_drv.h>
+#include "mcasp_cfg.h"
+#include "ioConfig.h"
+
+//#define TEST_OVERFLOW_UNDERFLOW
+//#define TEST_OVERFLOW_OVERFLOW
+#define NUM_BUFS_USED 8
+
+#define INPUT_SWITCH_HANGOVER 8
+
+/* Frame index for Rx and Tx buffers */
+uint8_t rxFrameIndex = 0;
+uint8_t txFrameIndex = 0;
+uint32_t rxBufIndex = 0;
+uint32_t txBufIndex = 0;
+
+/* McASP Tx and Rx frame buffers */
+MCASP_Packet rxFrame[NUM_BUFS];
+MCASP_Packet txFrame[NUM_BUFS];
+
+/* McASP Tx and Rx frame buffer pointers */
+Ptr txBuf[NUM_BUFS];
+Ptr rxBuf[NUM_BUFS];
+Ptr procBuf;
+
+/* Flags for counting Rx and Tx interrupts */
+volatile uint32_t rxFlag = 0;
+volatile uint32_t txFlag = 0;
+
+int dataFrameIndex=0;
+int RxTSKcnt = 0, TxTSKcnt = 0;
+volatile int RxFlag=0, RxFlag1=0, RxFlag2=0, TxFlag=0, TxFlag1=0, TxFlag2=0;
+
+/* Semaphore handle for Tx and Rx */
+Semaphore_Handle semR;
+Semaphore_Handle semT;
+Semaphore_Params SemParams;
+
+uint32_t mcaspRxChanArg = 1;
+uint32_t mcaspTxChanArg = 2;
+int num_gbl_err = 0;
+int txCount = 0;
+int rxCount = 0;
+int resetCount = 0;
+
+extern Mcasp_ChanParams mcaspRxChanParam;
+
+/* McASP channel handles */
+extern Ptr hMcaspTxChan;
+extern Ptr hMcaspRxChan;
+
+/* McASP device handles */
+extern Ptr hMcaspDevTx;
+extern Ptr hMcaspDevRx;
+
+extern uint32_t gblErrFlag;
+
+
+fwInst_t fwInst;
+extern Ptr databuf[NUM_BUFS];
+
+extern signed char* getGlobalAddr(signed char* addr);
+
+void inputXferStart();
+void outputXferStart();
+
+int check_mcasp_rx_overrun(void);
+void mcasp_rx_restart(void);
+int check_mcasp_tx_underrun(void);
+void mcasp_tx_restart(void);
+void ioRecfgRxPhyForPcm(void);
+void ioRecfgRxPhyForBitStream();
+
+extern void ioCompsInitInput();
+extern void ioCompsInitOutput();
+
+
+#ifndef USE_IO_COMPONENTS
+/**
+ * \brief McASP callback function called up on the data transfer completion
+ *
+ * \param arg [IN] - Application specific callback argument
+ * \param ioBuf [IN] - McASP IO buffer
+ *
+ * \return None
+ */
+void mcaspAppCallbackRx(void *arg, MCASP_Packet *ioBuf)
+{
+ /* Callback is triggered by Rx completion */
+
+ rxFlag++;
+
+ /* Post semaphore */
+ Semaphore_post(semR);
+}
+
+void mcaspAppCallbackTx(void *arg, MCASP_Packet *ioBuf)
+{
+ /* Callback is triggered by Tx completion */
+
+ txFlag++;
+
+ /* Post semaphore */
+ Semaphore_post(semT);
+}
+
+#else
+
+void *mcaspRxBuf1;
+void *mcaspRxBuf2;
+uint32_t mcaspRxSize1;
+uint32_t mcaspRxSize2;
+int mcaspRxtwoXfers = 0;
+
+void mcaspAppCallbackRx(void* arg, MCASP_Packet *mcasp_packet)
+{
+ RxFlag++;
+
+ /* post semaphore */
+ if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
+ RxFlag1++;
+
+ Semaphore_post(semR);
+ } else {
+ RxFlag2++;
+ }
+}
+
+void mcaspAppCallbackTx(void* arg, MCASP_Packet *mcasp_packet)
+{
+ TxFlag++;
+
+ /* post semaphore */
+ if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
+ TxFlag1++;
+
+ Semaphore_post(semT);
+ } else {
+ TxFlag2++;
+ }
+}
+#endif
+
+
+#ifdef IO_LOOPBACK_TEST
+
+#ifndef USE_IO_COMPONENTS
+
+/**
+ * \brief Task to echo the input data to output
+ *
+ * Waits for the McASP data transfer completion and copies the
+ * Rx data to Tx buffers
+ *
+ * \return Audk2g_EOK on Success or error code
+ */
+Void taskAsipFxn(
+ const PAF_ASIT_Params *pP, //JX: asip_params_PAi defined in itopo/params.c
+ const PAF_ASIT_Patchs *pQ //JX: asop_patchs_PAi defined in itopo/patchs.c
+)
+{
+ int32_t count;
+ Int status;
+
+ inputXferStart();
+
+ /* Forever loop to continuously receive and transmit audio data */
+ count = 0;
+ while (1)
+ {
+ if(gblErrFlag)
+ {
+ break;
+ }
+
+ //Log_info0("Pending Rx semaphore");
+
+ /* Reclaim full buffer from the input stream */
+ Semaphore_pend(semR, BIOS_WAIT_FOREVER);
+
+ /* Copy the receive information to the transmit buffer */
+ Cache_inv(rxBuf[rxFrameIndex], INPUT_FRAME_SIZE, Cache_Type_ALL, TRUE);
+ memcpy(procBuf, rxBuf[rxFrameIndex], INPUT_FRAME_SIZE);
+
+ /* Issue an empty buffer to the input stream */
+ rxFrame[rxFrameIndex].cmd = MCASP_READ;
+ rxFrame[rxFrameIndex].addr = (void*)(getGlobalAddr(rxBuf[rxFrameIndex]));
+ rxFrame[rxFrameIndex].size = INPUT_FRAME_SIZE;
+ rxFrame[rxFrameIndex].arg = (uint32_t) mcaspRxChanArg;
+ rxFrame[rxFrameIndex].status = 0;
+ rxFrame[rxFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ status = mcaspSubmitChan(hMcaspRxChan, &rxFrame[rxFrameIndex]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ Log_info0("mcaspSubmitChan for Rx Failed\n");
+ }
+
+ rxFrameIndex++;
+ if(rxFrameIndex==NUM_BUFS_USED) {
+ rxFrameIndex = 0;
+ }
+
+ // test McASP LLD reset
+ count += 1;
+ if(count == 1000) {
+ mcaspRxReset();
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_32;
+ mcaspRxCreate();
+ inputXferStart();
+
+ count = 0;
+ resetCount += 1;
+ }
+ }
+} /* taskAsipFxn */
+
+Void taskAsopFxn(
+ const PAF_ASOT_Params *pP,
+ const PAF_ASOT_Patchs *pQ
+)
+{
+ Int status;
+
+ outputXferStart();
+ //Semaphore_Params_init(¶ms);
+
+ /* Forever loop to continuously receive and transmit audio data */
+ while (1)
+ {
+ if(gblErrFlag)
+ {
+ break;
+ }
+
+ //Log_info0("Pending Tx semaphore");
+
+ /* Reclaim full buffer from the input stream */
+ Semaphore_pend(semT, BIOS_WAIT_FOREVER);
+
+ memcpy(txBuf[txFrameIndex], procBuf, OUTPUT_FRAME_SIZE);
+ Cache_wbInv(txBuf[txFrameIndex], OUTPUT_FRAME_SIZE, Cache_Type_ALL,TRUE);
+
+ /* Issue full buffer to the output stream */
+ /* TX frame processing */
+ txFrame[txFrameIndex].cmd = MCASP_WRITE;
+ txFrame[txFrameIndex].addr = (void*)(getGlobalAddr(txBuf[txFrameIndex]));
+ txFrame[txFrameIndex].size = OUTPUT_FRAME_SIZE;
+ txFrame[txFrameIndex].arg = (uint32_t) mcaspTxChanArg;
+ txFrame[txFrameIndex].status = 0;
+ txFrame[txFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ status = mcaspSubmitChan(hMcaspTxChan, &txFrame[txFrameIndex]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ Log_info0("mcaspSubmitChan for Tx Failed\n");
+ }
+ else {
+ txCount++;
+ }
+
+ txFrameIndex++;
+ if(txFrameIndex==NUM_BUFS_USED) {
+ txFrameIndex = 0;
+ }
+
+ }
+
+ //testRet(0);
+}
+
+
+/* put input and output in the same task */
+Void taskAsipFxn_1tsk(
+ const PAF_ASIT_Params *pP, //JX: asip_params_PAi defined in itopo/params.c
+ const PAF_ASIT_Patchs *pQ //JX: asop_patchs_PAi defined in itopo/patchs.c
+)
+{
+ Int status;
+
+// mcaspRxCfgPCM();
+
+ inputXferStart();
+ outputXferStart();
+
+ /* Forever loop to continuously receive and transmit audio data */
+ while (1)
+ {
+ if(gblErrFlag)
+ {
+ break;
+ }
+
+ /* pending on both Rx and Tx semaphore */
+ Semaphore_pend(semR, BIOS_WAIT_FOREVER);
+ Semaphore_pend(semT, BIOS_WAIT_FOREVER);
+
+ /* Copy the receive information to the transmit buffer */
+ Cache_inv(rxBuf[rxFrameIndex], INPUT_FRAME_SIZE, Cache_Type_ALL, TRUE);
+ memcpy(procBuf, rxBuf[rxFrameIndex], INPUT_FRAME_SIZE);
+
+ memcpy(txBuf[txFrameIndex], procBuf, INPUT_FRAME_SIZE);
+ Cache_wbInv(txBuf[txFrameIndex], OUTPUT_FRAME_SIZE, Cache_Type_ALL,TRUE);
+
+ /* Issue an empty buffer to the input stream */
+ rxFrame[rxFrameIndex].cmd = MCASP_READ;
+ rxFrame[rxFrameIndex].addr = (void*)(getGlobalAddr(rxBuf[rxFrameIndex]));
+ rxFrame[rxFrameIndex].size = INPUT_FRAME_SIZE;
+ rxFrame[rxFrameIndex].arg = (uint32_t) mcaspRxChanArg;
+ rxFrame[rxFrameIndex].status = 0;
+ rxFrame[rxFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ status = mcaspSubmitChan(hMcaspRxChan, &rxFrame[rxFrameIndex]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ Log_info0("mcaspSubmitChan for Rx Failed\n");
+ }
+
+ rxFrameIndex++;
+ if(rxFrameIndex==NUM_BUFS_USED) {
+ rxFrameIndex = 0;
+ }
+
+ /* Issue full buffer to the output stream */
+ /* TX frame processing */
+ txFrame[txFrameIndex].cmd = MCASP_WRITE;
+ txFrame[txFrameIndex].addr = (void*)(getGlobalAddr(txBuf[txFrameIndex]));
+ txFrame[txFrameIndex].size = OUTPUT_FRAME_SIZE;
+ txFrame[txFrameIndex].arg = (uint32_t) mcaspTxChanArg;
+ txFrame[txFrameIndex].status = 0;
+ txFrame[txFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ status = mcaspSubmitChan(hMcaspTxChan, &txFrame[txFrameIndex]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ Log_info0("mcaspSubmitChan for Tx Failed\n");
+ }
+ else {
+ txCount++;
+ }
+
+ txFrameIndex++;
+ if(txFrameIndex==NUM_BUFS_USED) {
+ txFrameIndex = 0;
+ }
+/*
+ if(txCount == 3000) {
+ mcaspRxReset();
+ mcaspRxCreate();
+ inputXferStart();
+
+ txCount = 0;
+ resetCount += 1;
+ }
+*/
+ }
+
+ //testRet(0);
+}
+
+Void taskAsopFxn_1tsk(
+ const PAF_ASOT_Params *pP,
+ const PAF_ASOT_Patchs *pQ
+)
+{
+
+}
+
+#else // else of #ifndef USE_IO_COMPONENTS
+
+void audio_rx_proc()
+{
+ void *buff1, *buff2;
+ size_t size1, size2;
+
+ /* Get read pointers of input memory pool */
+ if (ioBuffGetReadPtrs(fwInst.ioInp.hIoBuff, INPUT_FRAME_SIZE_PCM,
+ &buff1, &size1, &buff2, &size2)
+ == IOBUFF_ERR_UNDERFLOW) {
+ fwInst.buf_status_in = FW_IOBUF_UNDERFLOW;
+ //System_printf ("Debug: input buff underflows!\n");
+
+ /* skip processing since there is no enough data to process */
+ return;
+ } else {
+ fwInst.buf_status_in = FW_IOBUF_NORMAL;
+ }
+
+ /* copy the input data to data buffer */
+ Cache_inv(buff1, size1, Cache_Type_ALL, TRUE);
+ memcpy(databuf[0],buff1,size1);
+ ioBuffReadComplete(fwInst.ioInp.hIoBuff, buff1, size1);
+
+ if(buff2 != NULL) {
+ Cache_inv(buff2, size2, Cache_Type_ALL, TRUE);
+ memcpy((void *)((size_t)databuf[0]+size1),buff2,size2);
+ ioBuffReadComplete(fwInst.ioInp.hIoBuff, buff2, size2);
+ }
+
+ //Cache_wbInv(databuf[dataFrameIndex], INPUT_FRAME_SIZE, Cache_Type_ALL,TRUE);
+} /* audio_rx_proc */
+
+void audio_tx_proc()
+{
+ void *buff1, *buff2;
+ size_t size1, size2;
+ int status;
+/*
+ dataFrameIndex++;
+ if(dataFrameIndex==NUM_BUFS) {
+ dataFrameIndex = 0;
+ }
+*/
+ // Get write pointers of output memory pool
+ status = ioBuffGetWritePtrs(fwInst.ioOut.hIoBuff, OUTPUT_FRAME_SIZE,
+ &buff1, &size1, &buff2, &size2);
+ if (status == IOBUFF_ERR_OVERFLOW) {
+ fwInst.buf_status_out = FW_IOBUF_OVERFLOW;
+ //System_printf ("Debug: output buff overflows in Tx proc!\n");
+
+ /* skip processing since output buffer overflows */
+ return;
+ }
+ else if (status == IOBUFF_ERR_UNDERFLOW) {
+ /* already underflows and remain in underflow */
+ fwInst.buf_status_out = FW_IOBUF_UNDERFLOW;
+ }
+ else {
+ fwInst.buf_status_out = FW_IOBUF_NORMAL;
+ }
+
+ /* copy the output data from data buffer to output memory pool */
+ memcpy(buff1, databuf[0], size1);
+ Cache_wbInv(buff1, size1, Cache_Type_ALL,TRUE);
+
+ ioBuffWriteComplete(fwInst.ioOut.hIoBuff, buff1, size1);
+
+ if(buff2 != NULL) {
+ memcpy(buff2,(void *)((size_t)databuf[0]+size1),size2);
+ Cache_wbInv(buff2, size2, Cache_Type_ALL,TRUE);
+
+ ioBuffWriteComplete(fwInst.ioOut.hIoBuff, buff2, size2);
+ }
+} /* audio_tx_proc */
+
+void rxDecodeProcess()
+{
+ 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(fwInst.ioInp.hIoData, &ioDataCtl);
+
+ buffBase = ioDataCtl.param.dataReadInfo.buffBase;
+ buffSize = ioDataCtl.param.dataReadInfo.buffSize;
+ dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
+ frameSize = ioDataCtl.param.dataReadInfo.frameSize;
+
+ /* Depending on source information, either decode bit stream or simply
+ * copy PCM data to output buffer.
+ */
+ if(fwInst.syncState == IODATA_SYNC_PCM) {
+ // 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(databuf[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(databuf[0], dataStartAddress, size1);
+
+ Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
+ memcpy((void *)((size_t)databuf[0]+size1), buffBase, size2);
+ }
+ }
+ else if(fwInst.syncState == IODATA_SYNC_BITSTREAM) {
+ // Do nothing - there is no decoder
+ }
+} /* rxDecodeProcess */
+
+int numFrameReceived, numPcmFrameReceived, numSyncLost, numUnderflow;
+extern const MdUns iecFrameLength[23];
+
+#define SYNC_PC_MASK 0x001F
+
+Void taskAsipFxn(
+ const PAF_ASIT_Params *pP, //JX: asip_params_PAi defined in itopo/params.c
+ const PAF_ASIT_Patchs *pQ //JX: asop_patchs_PAi defined in itopo/patchs.c
+)
+{
+ int autoDetstatus;
+ ioDataCtl_t ioDataCtl;
+ ioPhyCtl_t ioPhyCtl;
+
+ /* Initialize I/O components for input */
+ ioCompsInitInput();
+
+#ifdef INPUT_HDMI_4xI2S // HDMI 4xI2S, bit stream or PCM
+#ifdef INPUT_PCM_ONLY
+ fwInst.ioInp.swapData = FALSE; // initialized to receive PCM
+#else
+ fwInst.ioInp.swapData = TRUE; // initialized to receive bit stream
+#endif
+#else
+ fwInst.ioInp.swapData = FALSE; // initialized to receive PCM
+#endif
+
+ fwInst.syncState = IODATA_SYNC_NONE;
+ fwInst.syncStatePrev = IODATA_SYNC_NONE;
+ fwInst.switchHangOver = 0;
+ fwInst.ioDelayAdjust = FALSE;
+
+ /* Start McASP LLD for input transfer */
+ inputXferStart();
+
+ numFrameReceived = 0;
+ numPcmFrameReceived = 0;
+ numSyncLost = 0;
+
+ /* Forever loop to continously receviec and transmit audio data */
+ while (1)
+ {
+ if(gblErrFlag) {
+ num_gbl_err++;
+ break;
+ }
+
+ Semaphore_pend(semR, BIOS_WAIT_FOREVER);
+
+ RxTSKcnt++;
+
+ ioPhyXferComplete(fwInst.ioInp.hIoPhy, fwInst.ioInp.swapData);
+
+#ifndef INPUT_PCM_ONLY
+ if(fwInst.switchHangOver)
+ {
+ void *buff1, *buff2;
+ size_t size1, size2;
+
+ // Get read pointers (or sub-buffers) of the input buffer
+ if (ioBuffGetReadPtrs(fwInst.ioInp.hIoBuff, fwInst.phyXferSize,
+ &buff1, &size1, &buff2, &size2)
+ == IOBUFF_ERR_UNDERFLOW) {
+ printf("Input buffer underflows during switch hangover!\n");
+ exit(0);
+ }
+
+ ioBuffReadComplete(fwInst.ioInp.hIoBuff, buff1, size1);
+
+ if(buff2 != NULL) {
+ ioBuffReadComplete(fwInst.ioInp.hIoBuff, buff2, size2);
+ }
+
+ memset(databuf[0], 0, OUTPUT_FRAME_SIZE);
+ fwInst.switchHangOver--;
+ }
+ else {
+ // Input format is unknown, perform auto-detection
+ autoDetstatus = ioDataProcess(fwInst.ioInp.hIoData);
+ if(autoDetstatus == IODATA_ERR_IOBUF_UNDERFLOW) {
+ // Input buffer underflows - no action is needed
+ //printf("Input buffer underflows.\n");
+ numUnderflow += 1;
+ }
+ else if(autoDetstatus != IODATA_NO_ERR) {
+ // print error log and return
+ printf("IODATA processing error!\n");
+ exit(0);
+ }
+ else {
+ // Check auto-detection status
+ ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
+ ioDataControl(fwInst.ioInp.hIoData, &ioDataCtl);
+
+ fwInst.syncState = ioDataCtl.param.autoDetStats.syncState;
+
+ if(fwInst.syncState == IODATA_SYNC_BITSTREAM) {
+ if(fwInst.syncStatePrev != IODATA_SYNC_BITSTREAM) {
+ // Change I/O PHY transfer size
+ int frameSize;
+ uint_least16_t pc = ioDataCtl.param.autoDetStats.bitStreamInfo & SYNC_PC_MASK; //0x001F
+ frameSize = iecFrameLength[pc] * WORD_SIZE_BITSTREAM;
+
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = frameSize;
+ ioPhyControl(fwInst.ioInp.hIoPhy, &ioPhyCtl);
+ fwInst.phyXferSize = ioPhyCtl.params.xferFrameSize;
+ }
+
+ numFrameReceived += 1;
+ }
+ else if(fwInst.syncState == IODATA_SYNC_PCM) {
+ // reconfigure McASP LLD if necessary
+ if(fwInst.syncStatePrev != IODATA_SYNC_PCM) {
+ ioRecfgRxPhyForPcm();
+
+ // Change I/O PHY transfer size
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_PCM;
+ ioPhyControl(fwInst.ioInp.hIoPhy, &ioPhyCtl);
+
+ // 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(fwInst.ioInp.hIoBuff, INPUT_FRAME_SIZE*2);
+ fwInst.ioInp.swapData = FALSE;
+ fwInst.phyXferSize = ioPhyCtl.params.xferFrameSize;
+
+ fwInst.switchHangOver = INPUT_SWITCH_HANGOVER;
+ fwInst.ioDelayAdjust = TRUE;
+ }
+
+ numPcmFrameReceived += 1;
+ }
+ else if (fwInst.syncState == IODATA_SYNC_NONE) {
+
+ if(fwInst.syncStatePrev != IODATA_SYNC_NONE) {
+ numSyncLost += 1;
+ numUnderflow = 0;
+ }
+
+ if(fwInst.syncStatePrev == IODATA_SYNC_PCM) {
+ // reconfigure McASP LLD to 16-bit packed bits
+ ioRecfgRxPhyForBitStream();
+
+ // Change I/O PHY transfer size
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
+ ioPhyControl(fwInst.ioInp.hIoPhy, &ioPhyCtl);
+
+ // 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(fwInst.ioInp.hIoBuff, INPUT_FRAME_SIZE*2);
+
+ fwInst.ioInp.swapData = TRUE;
+ fwInst.phyXferSize = ioPhyCtl.params.xferFrameSize;
+ numPcmFrameReceived = 0;
+
+ fwInst.switchHangOver = INPUT_SWITCH_HANGOVER; // don't need hangover, since data is all 0's anyway
+ fwInst.ioDelayAdjust = TRUE; // no need to adjust delay since read size doesn't change during PCM
+ }
+ else if(fwInst.syncStatePrev == IODATA_SYNC_BITSTREAM) {
+ numFrameReceived = 0;
+
+ // Change I/O PHY transfer size
+ ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+ ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
+ ioPhyControl(fwInst.ioInp.hIoPhy, &ioPhyCtl);
+ }
+ else {
+ // SYNC has not been detected
+ ;
+ }
+ }
+
+ fwInst.syncStatePrev = ioDataCtl.param.autoDetStats.syncState;
+
+ // Receive processing: decoding bitstream or simply passing PCM to output
+ // To add proper processing for HDMI 4xlane interface: bitstream or PCM
+ /*if ((fwInst.syncState != IODATA_SYNC_NONE) && (fwInst.switchHangOver == 0)) {
+ rxDecodeProcess();
+ }
+ else {
+ if(fwInst.switchHangOver > 0) {
+ fwInst.switchHangOver--;
+ }
+ memset(databuf[0], 0, OUTPUT_FRAME_SIZE);
+ }*/
+
+ if(fwInst.syncState == IODATA_SYNC_NONE) {
+ memset(databuf[0], 0, OUTPUT_FRAME_SIZE);
+ }
+ else {
+ if(fwInst.switchHangOver) {
+ memset(databuf[0], 0, OUTPUT_FRAME_SIZE);
+ fwInst.switchHangOver--;
+ }
+ else {
+ rxDecodeProcess();
+ }
+ }
+
+ // Mark the input as read complete
+ if(fwInst.ioDelayAdjust) {
+ // don't mark input buffer as read complete
+ ioBuffAdjustDelay(fwInst.ioInp.hIoBuff, fwInst.phyXferSize);
+ fwInst.ioDelayAdjust = FALSE;
+ }
+ else {
+ ioDataReadComplete(fwInst.ioInp.hIoData);
+ }
+ }
+ }
+#else
+ // Input is configured to PCM data
+ audio_rx_proc();
+
+ rxCount++;
+ if(rxCount == 2000) {
+ ioRecfgRxPhyForPcm();
+ }
+
+ if(rxCount == 4000) {
+ ioRecfgRxPhyForBitStream();
+ rxCount = 0;
+ }
+
+#if 0
+ // test McASP LLD reset
+ count += 1;
+ if(count == 1000) {
+ mcaspRxReset();
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_32;
+ mcaspRxCreate();
+ status = ioPhyXferErrRecover(fwInst.ioInp.hIoPhy);
+ if(status != IOPHY_NOERR) {
+ printf("ioPhyXferErrRecover fails with error code %d!\n.", status);
+ exit(0);
+ }
+
+ count = 0;
+ resetCount += 1;
+ }
+#endif
+#endif
+
+ if(check_mcasp_rx_overrun()) {
+ mcasp_rx_restart();
+ ioPhyXferErrRecover(fwInst.ioInp.hIoPhy);
+ }
+ else {
+ if(ioPhyXferSubmit(fwInst.ioInp.hIoPhy) == IOPHY_ERR_BUFF_OVERFLOW) {
+ fwInst.buf_status_in = FW_IOBUF_OVERFLOW;
+ printf("Input buffer overflows in Rx task!\n");
+ exit(0);
+ } else {
+ fwInst.buf_status_in = FW_IOBUF_NORMAL;
+ }
+ }
+ } /* while (1) */
+
+} /* taskAsipFxn */
+
+Void taskAsopFxn(const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ)
+{
+ /* Initialize I/O components for output */
+ ioCompsInitOutput();
+
+ /* Start McASP LLD for output transfer */
+ outputXferStart();
+
+ /* Forever loop to continously receviec and transmit audio data */
+ //for (i32Count = 0; i32Count >= 0; i32Count++)
+ while (1)
+ {
+ if(gblErrFlag) {
+ num_gbl_err++;
+ break;
+ }
+
+ Semaphore_pend(semT, BIOS_WAIT_FOREVER);
+
+ TxTSKcnt++;
+
+ ioPhyXferComplete(fwInst.ioOut.hIoPhy, FALSE);
+
+#ifdef TEST_OVERFLOW_UNDERFLOW
+ if(TxTSKcnt == 200) {
+ while(fwInst.buf_status_out != FW_IOBUF_OVERFLOW) {
+ audio_tx_proc(); // create output buffer overflow situation
+ }
+ }
+
+ if( (TxTSKcnt < 250) || (TxTSKcnt > 260)
+ || (fwInst.buf_status_out == FW_IOBUF_UNDERFLOW)) {
+ audio_tx_proc(); // create output buffer underflow situation
+ // between 250 and 260
+ }
+
+ if(fwInst.buf_status_out == FW_IOBUF_UNDERFLOW) {
+ audio_tx_proc(); // process one more frame during underflow
+ }
+
+ if(TxTSKcnt == 500) {
+ TxTSKcnt = 0;
+ TxFlag = 0;
+ TxFlag1 = 0;
+ TxFlag2 = 0;
+ }
+#else
+ audio_tx_proc(); // process one more frame during underflow
+#endif
+
+ if(check_mcasp_tx_underrun()) {
+ mcasp_tx_restart();
+ }
+ else {
+ if(ioPhyXferSubmit(fwInst.ioOut.hIoPhy)==IOPHY_ERR_BUFF_UNDERFLOW) {
+ fwInst.buf_status_out = FW_IOBUF_UNDERFLOW;
+ //System_printf("Debug: output buffer underflows in Tx task!\n");
+ }
+ else {
+ fwInst.buf_status_out = FW_IOBUF_NORMAL;
+ }
+ }
+ } /* while (1) */
+} /* taskAsopFxn */
+
+#endif // end of #ifndef USE_IO_COMPONENTS
+
+#endif // end of #ifdef IO_LOOPBACK_TEST
+
+
+extern const uint_least16_t IECframeLength[23];
+
+void inputXferStart(void)
+{
+ Int32 count;
+
+#ifdef USE_IO_COMPONENTS
+ for(count = 0; count < NUM_PRIME_XFERS; count++)
+ {
+ ioPhyXferSubmit(fwInst.ioInp.hIoPhy);
+ }
+#else
+ int status;
+
+ for(count = 0; count < NUM_PRIME_XFERS; count++)
+ {
+ /* Issue the first & second empty buffers to the input stream */
+ memset((uint8_t *)rxBuf[count], 0x0, INPUT_FRAME_SIZE);
+
+ /* RX frame processing */
+ rxFrame[count].cmd = MCASP_READ;
+ rxFrame[count].addr = (void*)(getGlobalAddr(rxBuf[count]));
+ rxFrame[count].size = INPUT_FRAME_SIZE;
+ rxFrame[count].arg = (uint32_t) mcaspRxChanArg;
+ rxFrame[count].status = 0;
+ rxFrame[count].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ /* Submit McASP packet for Rx */
+ status = mcaspSubmitChan(hMcaspRxChan, &rxFrame[count]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ IFPRINT(platform_write("mcaspSubmitChan for Rx Failed\n"));
+ exit(0);
+ }
+ }
+
+// rxFrameIndex = count;
+#endif
+} /* inputXferStart */
+
+void outputXferStart(void)
+{
+ Int32 count;
+
+ /* Create semaphores to wait for buffer reclaiming */
+// semT = Semaphore_create(0, &SemParams, &eb);
+// semT = Semaphore_create(0, NULL, NULL);
+
+#ifdef USE_IO_COMPONENTS
+ for(count = 0; count < NUM_PRIME_XFERS; count++)
+ {
+ if(ioPhyXferSubmit(fwInst.ioOut.hIoPhy)==IOPHY_ERR_BUFF_UNDERFLOW) {
+ fwInst.buf_status_out = FW_IOBUF_UNDERFLOW;
+ //System_printf("Debug, output buffer underflows in prime!\n");
+ } else {
+ fwInst.buf_status_out = FW_IOBUF_NORMAL;
+ }
+ }
+#else
+ int status;
+
+ for(count = 0; count < NUM_PRIME_XFERS; count++)
+ {
+ memset((uint8_t *)txBuf[count], 0x0, OUTPUT_FRAME_SIZE);
+
+ /* TX frame processing */
+ txFrame[count].cmd = MCASP_WRITE;
+ txFrame[count].addr = (void*)(getGlobalAddr(txBuf[count]));
+ txFrame[count].size = OUTPUT_FRAME_SIZE;
+ txFrame[count].arg = (uint32_t) mcaspTxChanArg;
+ txFrame[count].status = 0;
+ txFrame[count].misc = 1; /* reserved - used in callback to indicate asynch packet */
+
+ /* Submit McASP packet for Tx */
+ status = mcaspSubmitChan(hMcaspTxChan, &txFrame[count]);
+ if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
+ {
+ IFPRINT(platform_write("mcaspSubmitChan for Tx Failed\n"));
+ exit(0);
+ }
+ }
+
+// txFrameIndex = count;
+#endif
+} /* outputXferStart */
+
+int check_mcasp_rx_overrun(void)
+{
+ Mcasp_errCbStatus mcaspErrStat;
+
+ mcaspControlChan(hMcaspRxChan, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
+
+ return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
+}
+
+void mcasp_rx_restart(void)
+{
+ mcaspRxReset();
+ mcaspRxCreate();
+}
+
+int check_mcasp_tx_underrun(void)
+{
+ Mcasp_errCbStatus mcaspErrStat;
+
+ mcaspControlChan(hMcaspTxChan, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
+
+ return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
+}
+
+void mcasp_tx_restart(void)
+{
+ mcaspTxReset();
+ mcaspTxCreate();
+ ioPhyXferErrRecover(fwInst.ioOut.hIoPhy);
+}
+
+void ioSemaphoreCreate(void)
+{
+ Semaphore_Params_init(&SemParams);
+
+ semR = Semaphore_create(0, &SemParams, NULL);
+ semT = Semaphore_create(0, &SemParams, NULL);
+}
+
+void ioRecfgRxPhyForBitStream()
+{
+ Int status = Audk2g_EOK;
+
+ if(mcaspRxChanParam.wordWidth != Mcasp_WordLength_16) {
+ //mcaspRxReset();
+
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_16;
+ status = mcaspControlChan(hMcaspRxChan, Mcasp_IOCTL_CHAN_PARAMS_WORD_WIDTH, &mcaspRxChanParam);
+
+ //status = mcaspRxCreate();
+
+ if(status != Audk2g_EOK) {
+ printf("McASP LLD reconfiguration for bitstream fails!\n");
+ exit(0);
+ }
+
+ //ioPhyXferErrRecover(fwInst.ioInp.hIoPhy);
+ }
+} /* ioRecfgRxPhyForBitStream */
+
+void ioRecfgRxPhyForPcm(void)
+{
+ Int status = Audk2g_EOK;
+
+ if(mcaspRxChanParam.wordWidth != Mcasp_WordLength_32) {
+ //mcaspRxReset();
+
+ mcaspRxChanParam.wordWidth = Mcasp_WordLength_32;
+
+ status = mcaspControlChan(hMcaspRxChan, Mcasp_IOCTL_CHAN_PARAMS_WORD_WIDTH, &mcaspRxChanParam);
+ //status = mcaspRxCreate();
+ if(status != Audk2g_EOK) {
+ printf("McASP LLD reconfiguration for PCM fails!\n");
+ exit(0);
+ }
+
+ //ioPhyXferErrRecover(fwInst.ioInp.hIoPhy);
+ }
+} /* ioRecfgRxPhyForPcm */
diff --git a/pasdk/test_dsp/io/test/frame_work.c b/pasdk/test_dsp/io/test/frame_work.c
--- /dev/null
@@ -0,0 +1,207 @@
+
+#include <stdio.h>
+#include <xdc/runtime/Error.h>
+#include "../io/ioPhy.h"
+#include "../io/ioBuff.h"
+#include "frame_work.h"
+#include <ti/sysbios/io/IOM.h> // for definition of Ptr
+#include "audioStreamProc_common.h"
+#include "mcasp_cfg.h"
+#include "ioConfig.h"
+
+
+fwInst_t fwInst;
+
+/* Handle to heap object */
+//extern HeapMem_Handle heapHandle;
+//extern HeapMem_Handle HEAP_EXTERNAL;
+extern HeapMem_Handle heapMemDdr3;
+extern HeapMem_Handle heapMemL2Sram;
+
+/* McASP channel handles */
+extern Ptr hMcaspTxChan;
+extern Ptr hMcaspRxChan;
+
+Ptr databuf[NUM_BUFS];
+
+extern Int PAF_ASIT_ioCompCreate(PAF_AST_IoInp *pIoInp, int numInp, IHeap_Handle iHeapHandle);
+extern Int PAF_ASOT_ioCompCreate(PAF_AST_IoOut *pIoOut, int numOut, IHeap_Handle iHeapHandle);
+
+void ioCompsCreate()
+{
+ int errLineNum;
+ IHeap_Handle iheap;
+
+ iheap = HeapMem_Handle_to_xdc_runtime_IHeap(heapMemDdr3);
+
+ /* I/O components memory for input - only 1 input for standalone test */
+ errLineNum = PAF_ASIT_ioCompCreate(&fwInst.ioInp, 1, iheap);
+ if(errLineNum)
+ {
+ printf("Memory allocation fails for input I/O components!\n");
+ exit(0);
+ }
+
+ /* I/O components memory for output - only 1 output for standalone test */
+ errLineNum = PAF_ASOT_ioCompCreate(&fwInst.ioOut, 1, iheap);
+ if(errLineNum)
+ {
+ printf("Memory allocation fails for output I/O components!\n");
+ exit(0);
+ }
+}
+
+extern Ptr txBuf[NUM_BUFS];
+extern Ptr rxBuf[NUM_BUFS];
+extern Ptr procBuf;
+
+void ioBuffersCreate(void)
+{
+ Error_Block eb;
+ uint32_t count = 0;
+ IHeap_Handle iheap;
+ void *io_mempool_in;
+ void *io_mempool_out;
+
+ iheap = HeapMem_Handle_to_xdc_runtime_IHeap(heapMemDdr3);
+ Error_init(&eb);
+
+#ifdef USE_IO_COMPONENTS
+ /* Allocate memory for audio input memory pool */
+ io_mempool_in = Memory_calloc(iheap, INPUT_BUFF_SIZE, BUFALIGN, &eb);
+ if(NULL == io_mempool_in){
+ System_printf("\r\nMEM_calloc for io_mempool_in failed.\n");
+ exit(0);
+ }
+ fwInst.iomem_pool_input_base = io_mempool_in;
+ fwInst.iomem_pool_input_size = INPUT_BUFF_SIZE;
+
+ /* Allocate buffers for audio data processing */
+ for(count = 0; count < (NUM_BUFS); count ++)
+ {
+ databuf[count] = Memory_calloc(iheap, INPUT_FRAME_SIZE_PCM * 4,
+ BUFALIGN, &eb);
+ if(NULL == databuf[count]) {
+ System_printf("\r\nMEM_calloc failed.\n");
+ exit(0);
+ }
+ }
+
+ /* Allocate memory for audio output memory pool */
+ io_mempool_out = Memory_calloc(iheap, OUTPUT_BUFF_SIZE, BUFALIGN, &eb);
+ if(NULL == io_mempool_out){
+ System_printf("\r\nMEM_calloc for io_mempool_out failed.\n");
+ exit(0);
+ }
+ fwInst.iomem_pool_output_base = io_mempool_out;
+ fwInst.iomem_pool_output_size = OUTPUT_BUFF_SIZE;
+
+#else
+ /* Allocate buffers for the McASP data exchanges */
+ for(count = 0; count < NUM_BUFS; count++)
+ {
+ rxBuf[count] = Memory_calloc(iheap, INPUT_FRAME_SIZE_PCM,
+ BUFALIGN, &eb);
+ if(NULL == rxBuf[count])
+ {
+ IFPRINT(platform_write("\r\nMEM_calloc failed for Rx\n"));
+ }
+ }
+
+ /* Allocate buffers for the McASP data exchanges */
+ for(count = 0; count < NUM_BUFS; count++)
+ {
+ txBuf[count] = Memory_calloc(iheap, INPUT_FRAME_SIZE_PCM,
+ BUFALIGN, &eb);
+ if(NULL == txBuf[count])
+ {
+ IFPRINT(platform_write("\r\nMEM_calloc failed for Tx\n"));
+ }
+ }
+
+ procBuf = Memory_calloc(iheap, INPUT_FRAME_SIZE_PCM, BUFALIGN, &eb);
+#endif
+
+} /* ioBuffersCreate */
+
+void audioIoCreate(void)
+{
+#ifdef USE_IO_COMPONENTS
+ ioCompsCreate();
+#endif
+
+ ioBuffersCreate();
+}
+
+extern const MdUns iecFrameLength[23];
+
+void ioCompsInitInput()
+{
+ ioDataParam_t ioDataCfg;
+ ioBuffParams_t ioBuffParams;
+ ioPhyParams_t ioPhyParams;
+
+ ioBuffParams.base = fwInst.iomem_pool_input_base;
+ ioBuffParams.size = fwInst.iomem_pool_input_size;
+ ioBuffParams.sync = IOBUFF_WRITE_SYNC;
+ ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF*NUM_DELAY_BUFS_INPUT;
+ if(ioBuffInit(fwInst.ioInp.hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
+ printf("Input ioBuffInit error!\n");
+ exit(0);
+ }
+
+ ioPhyParams.ioBuffHandle = fwInst.ioInp.hIoBuff;
+#ifdef INPUT_PCM_ONLY
+ ioPhyParams.xferFrameSize = INPUT_FRAME_SIZE_PCM;
+#else
+ ioPhyParams.xferFrameSize = INPUT_FRAME_SIZE_DEF;
+#endif
+ ioPhyParams.mcaspChanHandle = hMcaspRxChan;
+ ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_WRITE;
+ if(ioPhyInit(fwInst.ioInp.hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+ printf("Input ioPhyInit error!\n");
+ exit(0);
+ }
+
+ ioDataCfg.ioBuffHandle = fwInst.ioInp.hIoBuff;
+ ioDataCfg.unknownSourceTimeOut = 30720; //30720;
+ ioDataCfg.frameLengthsIEC = (uint_least16_t *)&iecFrameLength[0];
+ ioDataCfg.frameLengthPCM = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
+ ioDataCfg.frameLengthDef = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
+ ioDataCfg.ibMode = 0;
+ ioDataCfg.zeroRunRestart = 300;
+ ioDataCfg.zeroRunTrigger = 20;
+
+ if(ioDataInit(fwInst.ioInp.hIoData, &ioDataCfg) != IODATA_NO_ERR) {
+ printf("Input ioDataInit error!\n");
+ exit(0);
+ }
+
+} /* ioCompsInitInput */
+
+void ioCompsInitOutput()
+{
+ ioBuffParams_t ioBuffParams;
+ ioPhyParams_t ioPhyParams;
+
+ ioBuffParams.base = fwInst.iomem_pool_output_base;
+ ioBuffParams.size = fwInst.iomem_pool_output_size;
+ ioBuffParams.sync = IOBUff_READ_SYNC;
+ ioBuffParams.nominalDelay = OUTPUT_FRAME_SIZE*NUM_DELAY_BUFS_OUTPUT;
+ if(ioBuffInit(fwInst.ioOut.hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
+ printf("Output ioBuffInit error!\n");
+ exit(0);
+ }
+
+ ioPhyParams.ioBuffHandle = fwInst.ioOut.hIoBuff;
+ ioPhyParams.xferFrameSize = OUTPUT_FRAME_SIZE;
+ ioPhyParams.mcaspChanHandle = hMcaspTxChan;
+ ioPhyParams.ioBuffOp = IOPHY_IOBUFFOP_READ;
+ if(ioPhyInit(fwInst.ioOut.hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+ printf("Output ioPhyInit error!\n");
+ exit(0);
+ }
+} /* ioCompsInitOutput */
+
+
+
diff --git a/pasdk/test_dsp/io/test/frame_work.h b/pasdk/test_dsp/io/test/frame_work.h
--- /dev/null
@@ -0,0 +1,82 @@
+
+#ifndef FRAME_WORK_H
+#define FRAME_WORK_H
+
+#include "ioPhy.h"
+#include "ioBuff.h"
+#include "ioData.h"
+
+#include "mcasp_cfg.h"
+#include "audioStreamInpProc.h"
+#include "audioStreamOutProc.h"
+
+#define USE_IO_COMPONENTS // define this to use I/O components: I/O BUFF and I/O PHY
+ // undefine for loopback test without using I/O components
+
+/** Num Bufs to be issued and reclaimed */
+#define NUM_BUFS (8) // Used for validation testing (not used for PASDK)
+
+#define BUFALIGN (128) /* Alignment of buffer for use of L2 cache */
+
+/* Number of I/O buffers - used for validation testing (not used for PASDK). */
+//#define NUM_INPUT_BUFS (30*3) // large enough to hold 3 THD frames
+#define NUM_INPUT_BUFS (30*4) // large enough to hold 3 THD frames
+#define NUM_OUTPUT_BUFS (12)
+
+/* Number of buffers constituting the nominal delay for I/O buffer management. */
+#define NUM_DELAY_BUFS_INPUT 1
+#define NUM_DELAY_BUFS_OUTPUT 3
+
+/* Size of total I/O buffer - used for validation testing (not used for PASDK). */
+#define INPUT_BUFF_SIZE (1024*2)*NUM_INPUT_BUFS // large enough to hold 3 THD frames
+#define OUTPUT_BUFF_SIZE (OUTPUT_FRAME_SIZE * NUM_OUTPUT_BUFS)
+
+/* Operation status of I/O buffer management. */
+enum {
+ FW_IOBUF_NORMAL = 0,
+ FW_IOBUF_UNDERFLOW,
+ FW_IOBUF_OVERFLOW
+};
+
+#if 0
+typedef struct fw_inst_s {
+ void * mcasp_chan_handle_input;
+ void * mcasp_chan_handle_output;
+ ioPhyHandle_t iophy_handle_input;
+ ioPhyHandle_t iophy_handle_output;
+ ioBuffHandle_t iobuf_handle_input;
+ ioBuffHandle_t iobuf_handle_output;
+ ioDataHandle_t iodata_handle;
+ void * iomem_pool_input_base;
+ size_t iomem_pool_input_size;
+ void * iomem_pool_output_base;
+ size_t iomem_pool_output_size;
+
+ uint_fast16_t buf_status_in;
+ uint_fast16_t buf_status_out;
+} fw_inst_t;
+
+extern void io_create(void *mcasp_chan_handle_rx, void *mcasp_chan_handle_tx);
+#endif
+
+typedef struct fwInst_s {
+ PAF_AST_IoInp ioInp;
+ PAF_AST_IoOut ioOut;
+ void * iomem_pool_input_base;
+ size_t iomem_pool_input_size;
+ void * iomem_pool_output_base;
+ size_t iomem_pool_output_size;
+ size_t phyXferSize;
+
+ void * hMcaspRxChan;
+
+ int_fast32_t switchHangOver;
+ uint_fast16_t buf_status_in;
+ uint_fast16_t buf_status_out;
+ uint_least16_t syncState;
+ uint_least16_t syncStatePrev;
+ uint_fast16_t ioDelayAdjust;
+
+}fwInst_t;
+
+#endif
index 980da950d9b8a900637d251deeb758b525ea19a6..ce7183a7e3eb8d184d1127fe30d9d820493b6ae1 100644 (file)
--- a/pasdk/test_dsp/mib/mib.c
+++ b/pasdk/test_dsp/mib/mib.c
};
// IEC framelengths (in 16bit words)
-static const MdUns iecFrameLength[23] =
+const MdUns iecFrameLength[23] =
{
0,
1536*2,