Part Number: TMS320C5517
Hello dear e2e.
The title says most of it.
I have McBSP configured for TDM I2S, and for now have enabled digital loopback for testing.
The (for now hardcoded) contents of DXR (U and L) is properly and repeatedly clocked out of the module, and with the loopback, it is received and also copied to the correct place in memory by the DMA controller (DMA3CH0).
But the transmitter module is not being served by the DMA controller (DMA3CH1). As a test, I set DMA3CH1 to trigger on REVT, and then it triggers fine, so the problem seems to be that the transmit part of the McBSP module doesn't actually flag the DMA controller on the transmit event (XEVT).
I am not using any multichannel functions of the module.
The initialisation code for the DMA is the following:
void i2sDMAInit(void) {
// Enable clocks for DMA3
PCGCR2 &= 0xFFFF - (1 << 5);
// Clear DMA interrupt flags
DMAIFR = 0xFFFF;
// Enable DMA interrupts for channel 0 and 1
IER0 |= 0x0100;
DMAIER |= 0x3000;
// 0x0001: McBSP transmit event for CH1, 0x0002: McBSP receive event for CH0
DMA3CESR1 = (0x0001 << 8) + (0x0002);
// DMA3CH0 (receiver)
// Source: x2000 offset in DMA addresses for McBSP sectiona
DMA3CH0SSAL = (uint16_t) (&MCBSP_DRRL) + 0x2000;
DMA3CH0SSAU = 0x0000;
// Destination: Conversion from CPU word address to DMA byte addres ( << 1), split into lower and upper, and ad 0x8 to upper for 0x90000 offset for SARAM (even though manual says to add 0x9).
DMA3CH0DSAL = (uint16_t) (((uint32_t) inMcBSPDMA3CH0->buf) << 1);
DMA3CH0DSAU = (uint16_t) ((((uint32_t) inMcBSPDMA3CH0->buf) >> 15) + 8);
// 2 bytes/word, 2 channels (L+R), 2 buffers (ping+pong), 9 codecs, times BUFSIZE
DMA3CH0TCR1 = BUFSIZE * 2 * 2 * 2 * 9;
// EN = 1, INTEN = 1, AUTORLD = 1, DSTAMODE auto-increment, SRAMODE constant address, BURSTMODE = 0 (32 bit), SYNCMODE = 1, PING_PONG_EN = 1
DMA3CH0TCR2 = 0xB085;
// DMA3CH1 (transmitter)
// Destination: x2000 offset in DMA addresses for McBSP section
DMA3CH1DSAL = (uint16_t) (&MCBSP_DXRL) + 0x2000;
DMA3CH1DSAU = 0x0000;
// Source: Conversion from CPU word address to DMA byte addres ( << 1), split into lower and upper, and ad 0x8 to upper for 0x90000 offset for SARAM (even though manual says to add 0x9).
DMA3CH1SSAL = (uint16_t) (((uint32_t) outMcBSPDMA3CH1->buf) << 1);
DMA3CH1SSAU = (uint16_t) ((((uint32_t) outMcBSPDMA3CH1->buf) >> 15) + 8);
// 2 bytes/word, 2 channels (L+R), 2 buffers (ping+pong), 9 codecs, times BUFSIZE
DMA3CH1TCR1 = BUFSIZE * 2 * 2 * 2 * 9;
// EN = 1, INTEN = 1, AUTORLD = 1, DSTAMODE constant address, SRAMODE auto-increment, BURSTMODE = 0 (32 bit), SYNCMODE = 1, PING_PONG_EN = 1
DMA3CH1TCR2 = 0xB205;
}
And the initialisation of the McBSP is this:
void mcbspInit(void) {
PCGCR1 |= 0x0020; //disable McBSP peripheral
EBSR |= 0x0300; // Setup SP0 to McBSP
PCGCR1 &= ~0x0020; //enable MCBSP clock
CLKSTOP1 &= ~0x0040; //disable MPBCLKSTPREQ
PRCR |= 0x0040; //reset MCBSP
while ((PRCR & 0x0040) == 0x0040);
//Step 2
MCBSP_SPCRL = 0x0000;
MCBSP_SPCRU = 0x0000;
MCBSP_PCRL |= 0x0A00; // set FSXM to output and internal source .
//Step 3
MCBSP_RCRL = (31 << 8) + (0x5 << 5); // RFRLEN1: (31 + 1) words per frame (18 rx lines), RWDLEN1: 16 bits per word (table 8-29)
MCBSP_RCRU = 0x0000;
MCBSP_XCRL = (31 << 8) + (0x5 << 5); // XFRLEN1: (31 + 1) words per frame (18 tx lines), XWDLEN1: 16 bits per word (table 8-29)
MCBSP_XCRU = 0x0000;
MCBSP_SRGRU = (0x1 << 13) + (0x1 << 12) + 511; // FSGM = CLKSM = 1, FPER = 511 + 1 (table 8-34)
MCBSP_SRGRL = (uint16_t) (255 << 8) + 15; // FWID = 255 + 1, CLKGDV = 15 + 1
nop(50);
MCBSP_SPCRU |= (1 << 6); // enable CLKG (disable GRST)
nop(50); // wait two CLKG clock cycles for sync
MCBSP_SPCRU |= 0x1; // enable transmit (Disable XRST)
nop(50); // wait two CLKG cycles for possible sync error
MCBSP_SPCRU &= ~0x0001; // disable transmit to clear sync error
MCBSP_SPCRU |= 0x0001; // reenable transmit (Disable XRST)
MCBSP_SPCRL |= 0x8001; // enable receive (Disable RRST)
MCBSP_PCRL |= (0x1 << 11) + (0x1 << 9); // set FSXM to output and internal source (CLKXM = 1).
MCBSP_SPCRU |= 0x0280; // enable Frame sync generator (FRST = 1) and free fun mode
Are there any usual pitfalls of the McBSP-DMA combination that I'm missing, or can someone spot a horribly simple mistake I've made somewhere? I've been staring at this and debugging for 2 days and have become a bit blind on it.
Best regards.