Hi Experts,
I'm in the process of implementing a McASP audio playback program that works on interrupts and not-EDMA. I am interested in accessing data sample by sample and processing them rather than using a EDMA buffer. I have made the following modifcations to the existing McASPPlaybk starterware project.
=> An ISR has been included to process data sample by sample [Codec_ISR() in code]
=> The "intvecs.asm" file has been modified to branch to appropriate ISRs when triggered.
=> The McASP configuration has been modified to allow for Interrupt processing (not EDMA).
I've tried various configurations, and i'm able to get control to the ISRs but, sometimes either the DAC output is very noisy or I get an transmit underrun error XUNDRN. I think there is something going wrong with my McASP configurations. Could you please have a look at the code and if you could please tell me where am i going wrong / or any pointers will be of great help.
McASPPlayback_withInterrupts.rar
Here's a snippet of the McASP module configuration:
/* ** Configures the McASP Transmit Section in I2S mode. */ static void McASPI2SConfigure(void) { //unsigned int sysIntNum = 0; McASP* mcasp = McASP0_Base; McASPRxReset(SOC_MCASP_0_CTRL_REGS); McASPTxReset(SOC_MCASP_0_CTRL_REGS); /* Enable the FIFOs for DMA transfer- Commented by Smita since DMAs are not used */ //McASPReadFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1); //McASPWriteFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1); /* Set I2S format in the transmitter/receiver format units */ //McASPRxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, // MCASP_RX_MODE_DMA);// Commented by Smita McASPRxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, MCASP_RX_MODE_NON_DMA);//Modification by Smita //McASPTxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, // MCASP_TX_MODE_DMA); McASPTxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, MCASP_TX_MODE_NON_DMA);//Modification by Smita /* Configure the frame sync. I2S shall work in TDM format with 2 slots */ McASPRxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_RX_FS_WIDTH_WORD, MCASP_RX_FS_EXT_BEGIN_ON_RIS_EDGE); McASPTxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_TX_FS_WIDTH_WORD, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE); /* configure the clock for receiver */ McASPRxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL, 0, 0); McASPRxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_POL_RIS_EDGE); McASPRxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLKCHCK_DIV32, 0x00, 0xFF); /* configure the clock for transmitter */ McASPTxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL, 0, 0); McASPTxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_POL_FALL_EDGE); McASPTxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLKCHCK_DIV32, 0x00, 0xFF); /* Enable synchronization of RX and TX sections */ McASPTxRxClkSyncEnable(SOC_MCASP_0_CTRL_REGS); /* Enable the transmitter/receiver slots. I2S uses 2 slots */ McASPRxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS); McASPTxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS); /* ** Set the serializers, Currently only one serializer is set as ** transmitter and one serializer as receiver. */ McASPSerializerRxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_RX); McASPSerializerTxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_TX); /* ** Configure the McASP pins ** Input - Frame Sync, Clock and Serializer Rx ** Output - Serializer Tx is connected to the input of the codec */ McASPPinMcASPSet(SOC_MCASP_0_CTRL_REGS, 0xFFFFFFFF); McASPPinDirOutputSet(SOC_MCASP_0_CTRL_REGS, MCASP_PIN_AXR(MCASP_XSER_TX)); McASPPinDirInputSet(SOC_MCASP_0_CTRL_REGS, MCASP_PIN_AFSX | MCASP_PIN_ACLKX | MCASP_PIN_AFSR | MCASP_PIN_ACLKR | MCASP_PIN_AXR(MCASP_XSER_RX)); /* Start the clocks */ McASPRxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL); McASPTxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL); /* Enable error interrupts for McASP */ //Commented by Smita Shekar //McASPTxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_TX_DMAERROR // | MCASP_TX_CLKFAIL // | MCASP_TX_SYNCERROR // | MCASP_TX_UNDERRUN); McASPTxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_TX_DATAREADY | MCASP_TX_CLKFAIL | MCASP_TX_SYNCERROR | MCASP_TX_UNDERRUN);//Modified by Smita : Added MCASP_TX_DATAREADY //McASPRxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_RX_DMAERROR // | MCASP_RX_CLKFAIL // | MCASP_RX_SYNCERROR // | MCASP_RX_OVERRUN); McASPRxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_RX_DATAREADY | MCASP_RX_CLKFAIL | MCASP_RX_SYNCERROR | MCASP_RX_OVERRUN);//Modified by Smita : Added MCASP_RX_DATAREADY //Added by Smita , enable Tx and Rx McASP interrupts mcasp->rintctl = 0x00000001; // overrun interrupt only mcasp->xintctl = 0x00000020; // data interrupts /* Activate the serializers */ McASPRxSerActivate(SOC_MCASP_0_CTRL_REGS); McASPTxSerActivate(SOC_MCASP_0_CTRL_REGS); //Added by Smita Shekar IntRegister(C674X_MASK_INT12, Codec_ISR); IntEventMap(C674X_MASK_INT12, SYS_INT_MCASP0_INT); IntEnable(C674X_MASK_INT12); //Added by Smita for interrupt method McASPTxBufWrite(SOC_MCASP_0_CTRL_REGS, 13, 0x0); /* Activate the state machines */ McASPRxEnable(SOC_MCASP_0_CTRL_REGS); McASPTxEnable(SOC_MCASP_0_CTRL_REGS); /* make sure that the XDATA bit is cleared to zero */ /*Additional Comment by Smita - On commenting/disabling the line below, i am able to get INT12 in the Interrupt vector table (i.e control is transferred to ISR - Codec_ISR() ). But values in L/R channel registers are zeros */ while(McASPTxStatusGet(SOC_MCASP_0_CTRL_REGS) & MCASP_TX_STAT_DATAREADY); }
Thanks a lot
Smita