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.

TMS320C5517: McBSP Transmit does not trigger DMA3CH1, Receive triggers DMA3CH0

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.