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.

MSP432P4111: DMA mappings on I2C port (EUSCIB1)

Part Number: MSP432P4111

I'm currently sharing DMA channel 2 between an I2C port and a UART port, because I can't get the I2C port to map to another DMA channel.

Based on what I see in dma.h of the DriverLib, I'm constrained in my mappings for EUSCIB1 to channels 0, 2, 4, or 6, but channels 0 and 2 are already being used by other peripherals, and I cannot get channels 4 or 6 to work for some reason.

 The following is the code to initiate the DMA transfer:

DMA_assignChannel(I2C_TX_DMA_ASSNMT);
DMA_setChannelControl(UDMA_PRI_SELECT | I2C_TX_DMA_ASSNMT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(UDMA_PRI_SELECT | I2C_TX_DMA_ASSNMT, UDMA_MODE_BASIC, PTxData, (void*) I2C_TX_DMA_BUF_ADDR, TXByteCtr);
DMA_assignInterrupt(I2C_TX_DMA_INT, I2C_TX_DMA_CH);
DMA_enableInterrupt(I2C_TX_DMA_INT);
Interrupt_enableInterrupt(I2C_TX_DMA_INT);
DMA_enableChannel(I2C_TX_DMA_CH);
I2C_masterSendStart(I2C_BASE_ADDR);

I've created the following constants so I have flexibility in mapping the DMA channels:

I2C_TX_DMA_CH = DMA_CHANNEL_2

I2C_TX_DMA_ASSNMT = CMA_CH2_EUSCIB1TX0

I2C_TX_DMA_INT = DMA_INT3

When I change the DMA channel to DMA_CHANNEL_4 and the assignment to DMA_CH4_EUSCIB1TX1 it doesn't work, nor does it work when I change it to DMA_CHANNEL_6 and the assignment parameter to DMA_CH6_EUSCIB1TX2.

Any ideas as to why the assignments for channel 4 and channel 6 don't work?

Thanks.

  • Hi,

    did you try to use one of our register based code examples? In principle the driver lib files should work, but as there are so many possible variations, in some cases not all have been tested. Thus there might be an issue with the driver lib versions. With the register based ones, one can see, which registers are being addressed.

    Another option would be applying the driver lib initialization and then check whether the register settings have been correctly applied. One can use the working versions as reference, checking if in case of the not working ones the same settings are applied, of course with changed channel settings.

    Best regards

    Peter

  • It turns out re-mapping the I2C port to a different DMA channel won't help things, because we're using DMA to transmit data through four UART ports and the I2C port for a total of five ports, all of which have been mapped to the four DMA channels that accommodate UART transmit operation (channel 0, 2, 4, 6).  I cannot use the odd numbered DMA channels because they can only be used for receiving data through the ports.

    I have tried using a "brute force" approach on the port that conflicts with the I2C, sending out the outgoing data buffer one byte at a time in a loop, but the throughput on the port is not so good, so I'd like to maintain shared DMA channel 2 between the I2C and the UART.  

    The problem I'm seeing with sharing the I2C port and the UART port on the same DMA channel is that the I2C DMA interrupt (DMA_INT3) gets triggered on a regular basis, while the UART DMA interrupt (DMA_INT0) does not.  I've tried to remap the UART DMA interrupt to a different interrupt (DMA_INT1), but that didn't work.

    If I disable the I2C, the UART DMA interrupt gets triggered, so it seems like the I2C DMA function is interfering with the UART DMA interrupt.

  • FYI, the following is the code to initiate the DMA transfer on the UART:

    DMA_disableChannel(RS232_UART_TX_DMA_CH);
    DMA_assignChannel(RS232_UART_TX_DMA_ASSNMT);
    DMA_disableChannelAttribute(RS232_UART_TX_DMA_ASSNMT,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK);
    DMA_setChannelControl(UDMA_PRI_SELECT | RS232_UART_TX_DMA_ASSNMT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    DMA_setChannelTransfer(UDMA_PRI_SELECT | RS232_UART_TX_DMA_ASSNMT, UDMA_MODE_BASIC, (void *)rs232Env.u32MsgBufAddr, RS232_UART_TX_DMA_BUF_ADDR, u16TxSize);
    DMA_assignInterrupt(RS232_UART_TX_DMA_INT, RS232_UART_TX_DMA_CH);

    where:

    RS232_UART_TX_DMA_CH = DMA_CHANNEL_2

    RS232_UART_TX_DMA_ASSNMT = DMA_CH2_EUSCIA1TX

    RS232_UART_TX_DMA_INT = DMA_INT0

**Attention** This is a public forum