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.

Omap-l138 mcasp CPU interrupt problem

Other Parts Discussed in Thread: OMAP-L138

hi,

I am using Omap-l138 the ARM side. I want to use the Mcasp port in CPU interrupt mode to output audio signal through the codec.

what I got is no out put at AXR11 pin. I did some debuging through serial port and found that the ISR is called three times only.

here is the code I used to setup the ARM INTC and Mcasp and the ISR.

hope you help me with it.

regards.

uint32_t MCASP_init(void)
{
	// enable the psc and config pinmux for mcasp.
	EVMAM1808_lpscTransition(PSC1, DOMAIN0, LPSC_MCASP0, PSC_ENABLE);
	EVMAM1808_pinmuxConfig(PINMUX_MCASP_REG_0, PINMUX_MCASP_MASK_0, PINMUX_MCASP_VAL_0);
	EVMAM1808_pinmuxConfig(PINMUX_MCASP_REG_1, PINMUX_MCASP_MASK_1, PINMUX_MCASP_VAL_1);

	// reset mcasp.
	MCASP->GBLCTL  = 0;

	// configure receive registers.
	MCASP->RMASK      = 0xFFFFFFFF;
	MCASP->RFMT       = 0x00008078;
	MCASP->AFSRCTL    = 0x00000112;
	MCASP->ACLKRCTL   = 0x000000B3;
	MCASP->AHCLKRCTL  = 0x00000000;
	MCASP->RTDM       = 0x00000003;
	MCASP->RINTCTL    = 0x00000000;
	MCASP->RCLKCHK    = 0x00FF0008;

	MCASP->XMASK      = 0x0000FFFF;
	MCASP->XFMT       = 0x0001807c;
	MCASP->AFSXCTL    = 0x00000112;
	MCASP->ACLKXCTL   = 0x000000B3;
	MCASP->AHCLKXCTL  = 0x00008004;
	MCASP->XTDM       = 0x00000003;
	MCASP->XINTCTL    = 0x00000000;
	MCASP->XCLKCHK    = 0x00FF0008;

	// config serializers (11 = xmit, 12 = rcv).
	MCASP->SRCTL11    = 0x000D;
	MCASP->SRCTL12    = 0x000E;

	// config pin function and direction.
	MCASP->PFUNC      = 0;
	MCASP->PDIR       = 0x14000800;

	//
	MCASP->DITCTL     = 0x00000000;
	MCASP->DLBCTL     = 0x00000000;
	MCASP->AMUTE      = 0x00000000;

	MCASP->XSTAT = 0x0000FFFF;        // Clear all
	MCASP->RSTAT = 0x0000FFFF;        // Clear all

	return (ERR_NO_ERROR);
}

void McASP_Start_TTO(void){
	SETBIT(MCASP->XGBLCTL, XHCLKRST);
	while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {}
	SETBIT(MCASP->RGBLCTL, RHCLKRST);
	while (!CHKBIT(MCASP->RGBLCTL, RHCLKRST)) {}

	SETBIT(MCASP->XGBLCTL, XCLKRST);
	while (!CHKBIT(MCASP->XGBLCTL, XCLKRST)) {}
	SETBIT(MCASP->RGBLCTL, RCLKRST);
	while (!CHKBIT(MCASP->RGBLCTL, RCLKRST)) {}

	SETBIT(MCASP->XINTCTL, XDATA);
	while (!CHKBIT(MCASP->XINTCTL, XDATA)) {}

	SETBIT(MCASP->XGBLCTL, XSRCLR);
	while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {}
	SETBIT(MCASP->RGBLCTL, RSRCLR);
	while (!CHKBIT(MCASP->RGBLCTL, RSRCLR)) {}

	/* Write a 0, so that no underrun occurs after releasing the state machine */
	MCASP->XBUF11 = 0;
	//MCASP->RBUF12 = 0;

	SETBIT(MCASP->XGBLCTL, XSMRST);
	while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {}
	SETBIT(MCASP->RGBLCTL, RSMRST);
	while (!CHKBIT(MCASP->RGBLCTL, RSMRST)) {}

	SETBIT(MCASP->XGBLCTL, XFRST);
	while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {}
	SETBIT(MCASP->RGBLCTL, RFRST);
	while (!CHKBIT(MCASP->RGBLCTL, RFRST)) {}

	// wait for transmit ready and send a dummy byte.
	while(!CHKBIT(MCASP->SRCTL11, XRDY)) {}
	MCASP->XBUF11 = 0;
}

void mcasp_isr(){
	if(CHKBIT(MCASP->SRCTL11, XRDY))
	{				//if ISR triggered by XRDY...
		dataOut32 = cos_table[sample];
		sample++;
		MCASP->XBUF0=dataOut32;
		UART_txByte(DEBUG_PORT,'0');
	}
	CLRBIT(aintcRegs->SICR,0x3ff);
	SETBIT(aintcRegs->SICR,54);
}

void setup_ARM_INTC (void)
{
	// Reset AINTC
	aintcRegs->ECR1 = AINTC_SYSINT_0_31_ALL;
	aintcRegs->ECR2 = AINTC_SYSINT_32_63_ALL;
	aintcRegs->ECR3 = AINTC_SYSINT_64_95_ALL;
	aintcRegs->SECR1 = AINTC_SYSINT_0_31_ALL;
	aintcRegs->SECR2 = AINTC_SYSINT_32_63_ALL;
	aintcRegs->SECR3 = AINTC_SYSINT_64_95_ALL;

	sysISRtbl[AINTC_EVENTID_MCASP_INT] = mcasp_isr;

	aintcRegs->VBR = (unsigned int) sysISRtbl;						// Assign the ISR Table Address to VBR
	aintcRegs->VSR = 0;

	CLRBIT(aintcRegs->CMR13, AINTC_CMR13_CHNL_NPLUS2_MASK);			// Map MCASP Interrupts to Channel 2
	SETBIT(aintcRegs->CMR13, 0x00020000);

	CLRBIT(aintcRegs->EISR,AINTC_EISR_INDEX_MASK);					// Enable MCASP Interrupts
	SETBIT(aintcRegs->EISR,AINTC_EVENTID_MCASP_INT);


	SETBIT(aintcRegs->HIEISR,ENABLE_IRQ_INTERRUPT);					/* Enable IRQ Interrupts */
	SETBIT(aintcRegs->GER,AINTC_GER_ENABLE_MASK);	/*enable global INT*/
}

  • Hi,

    Thanks for your post.

    I have suggestions for you are below and kindly valdate the same:

    1. Start the Rx. & Tx. clocks after enabling error interrupts for McASP like

    /* Enable error interrupts for McASP */

     McASPTxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_TX_DATAREADY  

                                             | MCASP_TX_CLKFAIL

                                             | MCASP_TX_SYNCERROR

                                             | MCASP_TX_UNDERRUN);

     McASPRxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_RX_DATAREADY  

                                             | MCASP_RX_CLKFAIL

                                             | MCASP_RX_SYNCERROR

                                             | MCASP_RX_OVERRUN);

    /* Start the clocks */

        McASPRxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL);

        McASPTxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL);

    2. Please ensure codec ISR mapping to CPU mask interrupt C674X_MASK_INT5 should be done before configuring the AIC31 codec for I2S mode:

         IntRegister(C674X_MASK_INT5, Codec_ISR);

         IntEventMap(C674X_MASK_INT5, SYS_INT_MCASP0_INT);

         IntEnable(C674X_MASK_INT5);

    3.  In the McASPI2SConfigure(void) function code, activate the state machines after making sure that the XDATA bit is cleared to zero like below:

    /* make sure that the XDATA bit is cleared to zero */

    Kindly ensure to get INTx in the Interrupt vector table (i.e control is transferred to ISR - Codec_ISR() ).

    while(McASPTxStatusGet(SOC_MCASP_0_CTRL_REGS) & MCASP_TX_STAT_DATAREADY);

    /* Activate the state machines */

     McASPRxEnable(SOC_MCASP_0_CTRL_REGS);

     McASPTxEnable(SOC_MCASP_0_CTRL_REGS);

    4. I think, to enable Tx. and Rx. McASP interrupts, kindly ensure to configure McASP error interrupts through  McASPTxIntEnable() & McASPRxIntEnable () which would trigger error interrupts if any.

     mcasp->rintctl    = 0x00000001;  // overrun interrupt only

     mcasp->xintctl    = 0x00000020;  // data interrupts

    Kindly validate the above configuration and try it.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question

    -------------------------------------------------------------------------------------------------------

  • Hi Mr. Sivaraj K
    thanks for replying.
    I am not familier with StarterWare routines, I am using the BSL provided with the kit.
    I follow Mcasp init sequence (25.2.1.1.2) in spruh77a.
    what I noticed is that, when mcasp INT is enabled in AINTC before starting the clocks, it causes the processor to wait for XRDY
    while(!CHKBIT(MCASP->SRCTL11, XRDY)) {} , hence my programm gets hanged here.
    Then I enabled the interrupt after the clocks started, I inserted UART_txByte(DEBUG_PORT,'0'); in the ISR to check the whether it gets called or not. a couple of zeroes are printed through serial port and no more.
    the frame sync and bit clocks are running continuously.

    I enabled the errors as you suggested, and added a uart_txString in each case, I got TX UNDERRUN error. I tried to clear this by writing to Xstat but nothing happens.

    regards,,