This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRA78: It works only when outputting from one slot but not when trying to output from many slots in McASP(TDM16)

Part Number: DRA78

 board : dra78x custom board

 example for reference : pdk_dra7xx_1_0_10/packages/ti/csl/exampl/mcasp/mcasp_transmit

changes :

example my source
trigger edma event polling
slot number(TXFMCTL register) 2 16
used tx pin AXR 0, 1 AXR 2
clock(ACLKS, FSX) internal external
mode I2S TDM16
McASPn McASP1 McASP3

 - This board has run mcasp properly in sysbios environment. But it needs to work without sysbios

 - I have confirmed that XRFST, XSMRST, XSRCLR, XHCLKRST in the GBLCTL register is activated

 - If I activate only one slot or use burst mode, it works fine(TXTDM = 0 or 1)

 - If I activate more than one slot, it will not work(TXTDM = 2, 3, 4 .... 16)

(1) Activate slot 0 only (oscilloscope ch1 : frame sync clk , oscilloscope ch2 : AXR 2, TXTDM = 1)

(2) Activate slot 1 only (oscilloscope ch1 : frame sync clk , oscilloscope ch2 : AXR 2, TXTDM = 2)

(3) Activate slot 0, 1 (oscilloscope ch1 : frame sync clk , oscilloscope ch2 : AXR 2, TXTDM = 3)

 Thank for your help.

  • this my test code

    static void McASP2Configure(void)
    {
    McASPSetPowerIdleConfig(SOC_MCASP3_CFG_BASE, MCASP_IDLEMODE_NOIDLE);
    //McASPTxIntDisable(SOC_MCASP3_CFG_BASE, uint32_t intMask);

    McASPTxReset(SOC_MCASP3_CFG_BASE);

    /* Activate the serializers */
    McASPTxSerActivate(SOC_MCASP3_CFG_BASE);
    //McASPTxStatusSet(SOC_MCASP3_CFG_BASE, 0xFF); //Status reset
    //HW_WR_REG32(SOC_MCASP3_CFG_BASE + MCASP_GBLCTLX, 0x400);
    //while( (HW_RD_REG32(SOC_MCASP3_CFG_BASE + MCASP_GBLCTLX) & 0x400) != 0x400 );

    /* Enable the FIFOs for DMA transfer */
    //McASPWriteFifoEnable(SOC_MCASP3_CFG_BASE, 2, 16);
    McASPWriteFifoDisable(SOC_MCASP3_CFG_BASE);


    McASPTxFmtMaskSet(SOC_MCASP3_CFG_BASE, 0xFFFFFFFF);
    /* Set I2S format in the transmitter/receiver format units */
    //McASPTxFmtI2SSet(SOC_MCASP3_CFG_BASE, WORD_SIZE, SLOT_SIZE, MCASP_TX_MODE_DMA);
    //McASPTxFmtI2SSet(SOC_MCASP3_CFG_BASE, WORD_SIZE, SLOT_SIZE, MCASP_TX_MODE_NON_DMA);

    McASPTxFmtSet(SOC_MCASP3_CFG_BASE, MCASP_TX_SYNC_DELAY_1BIT |
    MCASP_TX_BITSTREAM_MSB_FIRST |
    MCASP_TX_PAD_WITH_0 |
    MCASP_TX_SLOTSIZE_32BITS |
    MCASP_TX_BUF_PERICONFIGPORT |
    MCASP_TX_ROT_RIGHT_NONE
    );


    McASPTxFrameSyncCfg(SOC_MCASP3_CFG_BASE, 16, MCASP_TX_FS_WIDTH_BIT, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);
    //McASPTxFrameSyncCfg(SOC_MCASP3_CFG_BASE, 0, MCASP_TX_FS_WIDTH_BIT, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);
    //McASPTxFrameSyncCfg(SOC_MCASP3_CFG_BASE, 2, MCASP_TX_FS_WIDTH_BIT, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);

    /* configure the clock for transmitter */
    //McASPTxClkCfg(SOC_MCASP3_CFG_BASE, MCASP_TX_CLK_INTERNAL,
    // ((MCASP_ACLKX_CLKXDIV_VALUE & MCASP_ACLKXCTL_CLKXDIV_MASK) >> MCASP_ACLKXCTL_CLKXDIV_SHIFT),
    // ((MCASP_AHCLKX_HCLKXDIV_VALUE & MCASP_AHCLKXCTL_HCLKXDIV_MASK) >> MCASP_AHCLKXCTL_HCLKXDIV_SHIFT));
    McASPTxClkCfg(SOC_MCASP3_CFG_BASE, MCASP_TX_CLK_EXTERNAL, 0, 0);
    HW_WR_FIELD32(SOC_MCASP3_CFG_BASE + MCASP_ACLKXCTL, CSL_MCASP_ACLKXCTL_ASYNC, 0x00); //sync

    //HW_WR_FIELD32(SOC_MCASP3_CFG_BASE + MCASP_AHCLKXCTL, CSL_MCASP_AHCLKXCTL_HCLKXM, 0x01); //AHCLKX Internal
    //HW_WR_FIELD32(SOC_MCASP3_CFG_BASE + MCASP_AHCLKXCTL, CSL_MCASP_AHCLKXCTL_HCLKXDIV, 0x00); //AHCLKX /1

    McASPTxClkPolaritySet(SOC_MCASP3_CFG_BASE, MCASP_TX_CLK_POL_RIS_EDGE);

    McASPTxClkCheckConfig(SOC_MCASP3_CFG_BASE, MCASP_TX_CLKCHCK_DIV1, 0x00, 0xFF);

    /* Enable the transmitter/receiver slots. I2S uses 2 slots */
    //McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, I2S_SLOTS);
    //McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, 0xFFFF);
    McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, 0x01);

    //McASPTxIntEnable(SOC_MCASP3_CFG_BASE , MCASP_TX_DATAREADY | MCASP_TX_LASTSLOT);


    /*
    ** Set the serializers
    */
    McASPSerializerTxSet(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2);
    McASPSerializerRxSet(SOC_MCASP3_CFG_BASE, MCASP_XSER_RX_0);

    /*
    ** Configure the McASP pins
    ** Output - Frame Sync, Clock, Serializer Rx and Serializer Tx
    ** (Clocks generated internally)
    */
    McASPPinMcASPSet(SOC_MCASP3_CFG_BASE, (MCASP_PIN_AFSR |
    MCASP_PIN_ACLKR |
    MCASP_PIN_AFSX |
    MCASP_PIN_AHCLKX |
    MCASP_PIN_ACLKX |
    //MCASP_PIN_AMUTE |
    MCASP_PIN_AXR(MCASP_XSER_TX_2) |
    MCASP_PIN_AXR(MCASP_XSER_RX_0) ));

    /* Configure high clock as Output */
    //McASPPinDirOutputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_AHCLKX);
    McASPPinDirInputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_AFSX);
    McASPPinDirInputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_ACLKX);

    McASPPinDirInputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_AFSR);
    McASPPinDirInputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_ACLKR);

    /* Both Serializers used to output data out */
    McASPPinDirInputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_AXR(MCASP_XSER_RX_0));
    McASPPinDirOutputSet(SOC_MCASP3_CFG_BASE, MCASP_PIN_AXR(MCASP_XSER_TX_2));
    //McASPPinDirOutputSet(SOC_MCASP_CFG_BASE, MCASP_PIN_AXR(MCASP_XSER_TX_1));
    }

    /*
    ** Activates the data transmission/reception
    ** The DMA parameters shall be ready before calling this function.
    */

    int sine_wav[1000]; //
    int cnt = 0 ;
    int maxcnt = 0;
    int ChChange = 0;
    unsigned char NowCh = 1;

    static void McASP2TxActivate(void)
    {
    int i=0;
    float time = 0;
    uint32_t tmp;

    uint32_t result = 0;

    int ChChangeMax = 0;
    float freq = 200.;
    maxcnt = (int)((1./freq) / (1./48000.));
    time = 0;

    for(i=0;i<maxcnt;i++)
    {
    sine_wav[i] = ((int)(0.1*sinf(2*3.14159*freq*time)*4194304.0)) << 8;
    time += 0.000020;
    }
    ChChangeMax = 2/time;

    /* Start the clocks */
    McASPTxClkStart(SOC_MCASP3_CFG_BASE, MCASP_TX_CLK_EXTERNAL);

    // Enable EDMA for the transfer
    //EDMA3EnableTransfer(SOC_EDMA_TPCC_BASE_VIRT, CSL_EDMA3_CHA_MCASP2_TX,
    // EDMA3_TRIG_MODE_EVENT);
    McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, 0x00);


    // Activate the state machines
    McASPTxEnable(SOC_MCASP3_CFG_BASE);


    while(1)
    {
    result = McASPTxStatusGet(SOC_MCASP3_CFG_BASE);

    while ( !(result & MCASP_TX_STAT_DATAREADY) )
    {
    result = McASPTxStatusGet(SOC_MCASP3_CFG_BASE);
    if(result & MCASP_TX_STAT_UNDERRUN)
    {
    //McASPTxStatusSet(SOC_MCASP3_CFG_BASE, McASPTxStatusGet);


    //McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, 0xFF0000FF);

    }

    }
    //McASPTxStatusSet(SOC_MCASP3_CFG_BASE, MCASP_TX_STAT_DATAREADY);



    if( (result & MCASP_TX_STAT_LASTSLOT) )
    {
    McASPTxStatusSet(SOC_MCASP3_CFG_BASE, MCASP_TX_STAT_LASTSLOT);

    //while ( !(HW_RD_FIELD32(SOC_MCASP3_CFG_BASE + CSL_MCASP_SRCTL2, CSL_MCASP_SRCTL2_XRDY)) ) ;
    while( !McASPIsSerializerXmtReady(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2) );

    //McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, 0xAAAA5555);
    McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, sine_wav[cnt]);
    //HW_WR_REG32(0x4843A000, sine_wav[cnt]);

    cnt++;
    if(cnt >= maxcnt)
    {
    cnt = 0;
    /*
    ChChange++;
    if(ChChange >= ChChangeMax)
    {
    NowCh <<= 1;
    if(NowCh == 0) NowCh = 1;
    McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, NowCh);
    ChChange = 0;
    }
    */
    }

    }else if( result & MCASP_TX_STAT_STARTOFFRAME)
    {
    //McASPTxStatusSet(SOC_MCASP3_CFG_BASE, MCASP_TX_STAT_STARTOFFRAME);
    while( !McASPIsSerializerXmtReady(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2) );

    //McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, 0xAAAA5555);
    McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, sine_wav[cnt]);
    //HW_WR_REG32(0x4843A000, sine_wav[cnt]);
    }else{
    //while ( !(HW_RD_FIELD32(SOC_MCASP3_CFG_BASE + CSL_MCASP_SRCTL2, CSL_MCASP_SRCTL2_XRDY)) ) ;
    while( !McASPIsSerializerXmtReady(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2) );

    //McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, 0xAAAA5555);
    McASPTxBufWrite(SOC_MCASP3_CFG_BASE, MCASP_XSER_TX_2, sine_wav[cnt]);
    //HW_WR_REG32(0x4843A000, sine_wav[cnt]);
    }

    }

    }
  • Hi Jinse,

    I assume the test code is the working case with a single slot?

    Note that there is no such thing as TDM mode with 1 slot or burst mode with multiple slots.  If you need 1 slot then you must use burst mode, and 2-32 slots will be TDM mode.  MCASP_TXFMCTL.XMOD must also be set to the number of TDM slots needed.  This should match the number of active TDM slots set in the MCASP_TXTDM.XTDMS.

    Thanks,
    Stephen

  • If i set TXTDM to 0xFFFF and TXTDM.XTDMS to 16, it will not work like the third picture. Activating only one slot is only a result of trying to solve the problem.

    In the test code, only one slot is active, but what I want is to activate all 16 slots. It is correct to set it according to the answer, but the problem is that it does not work.

    Now(works)
    McASPTxFrameSyncCfg(SOC_MCASP3_CFG_BASE, 16, MCASP_TX_FS_WIDTH_BIT, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);
    McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, 0x01);

    Your answer(Does not work)
    McASPTxFrameSyncCfg(SOC_MCASP3_CFG_BASE, 16, MCASP_TX_FS_WIDTH_BIT, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);
    McASPTxTimeSlotSet(SOC_MCASP3_CFG_BASE, 0xFFFF);


    Thank you for answer.