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.

No uDMA for SSI3?

Hi all,

When reading the data sheet of TM4C1294, it seems all four QSSI channels have the registers to support uDMA, but when I tried to use uDMA in CCS, udma.h stops short of that

//*****************************************************************************
//
// Channel numbers to be passed to API functions that require a channel number
// ID.
//
//*****************************************************************************
#define UDMA_CHANNEL_USBEP1RX 0
#define UDMA_CHANNEL_USBEP1TX 1
#define UDMA_CHANNEL_USBEP2RX 2
#define UDMA_CHANNEL_USBEP2TX 3
#define UDMA_CHANNEL_USBEP3RX 4
#define UDMA_CHANNEL_USBEP3TX 5
#define UDMA_CHANNEL_ETH0RX 6
#define UDMA_CHANNEL_ETH0TX 7
#define UDMA_CHANNEL_UART0RX 8
#define UDMA_CHANNEL_UART0TX 9
#define UDMA_CHANNEL_SSI0RX 10
#define UDMA_CHANNEL_SSI0TX 11
#define UDMA_CHANNEL_ADC0 14
#define UDMA_CHANNEL_ADC1 15
#define UDMA_CHANNEL_ADC2 16
#define UDMA_CHANNEL_ADC3 17
#define UDMA_CHANNEL_TMR0A 18
#define UDMA_CHANNEL_TMR0B 19
#define UDMA_CHANNEL_TMR1A 20
#define UDMA_CHANNEL_TMR1B 21
#define UDMA_CHANNEL_UART1RX 22
#define UDMA_CHANNEL_UART1TX 23
#define UDMA_CHANNEL_SSI1RX 24
#define UDMA_CHANNEL_SSI1TX 25
#define UDMA_CHANNEL_I2S0RX 28
#define UDMA_CHANNEL_I2S0TX 29
#define UDMA_CHANNEL_SW 30

Can I use uDMA on SSI3?

Thanks for pointer!

  • Hello David,

    Do not use the defines as given in that particular section of the udma.h

    Instead a few lines down is the new method of channel assignment

    #define UDMA_CH14_SSI3RX 0x0002000E
    #define UDMA_CH15_SSI3TX 0x0002000F

    Regards
    Amit
  • Are you sure these newer definition work with uDMAChannelControlSet?

    When I feed either one to uDMAChannelAttributeDisable in forms of

    uDMAChannelAttributeDisable(UDMA_CH14_SSI3RX ,
    UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
    (UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK));
    uDMAChannelAttributeDisable(UDMA_CH15_SSI3TX ,
    UDMA_ATTR_ALTSELECT |
    UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK);

    it executes fine

    but when I feed it to uDMAChannelControlSet in form of

    uDMAChannelControlSet (UDMA_CH14_SSI3RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);

    I get hard fault. (when I use the old definition of SSI0, all work fine)

  • Hello David,

    To use the new form of Channel configuration you need to mask the lower 5 bits before applying the primary select

    uDMAChannelControlSet (((UDMA_CH14_SSI3RX & 0x1F)| UDMA_PRI_SELECT), UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);

    Regards
    Amit
  • inside uDMAChannelControlSet , it already does

    ui32ChannelStructIndex &= 0x3f;
  • Hello David,

    Can you check what address does the CPU Bus Fault?

    Regards
    Amit
  • I just realized I have a section of conditional codes were not in place, let me clean them up and see if the problem goes away.

    Thanks!
  • No hardfault, but DMA doesn't run

    looking into udma.c, I am not sure if we can use the new form of channel to enable DMA, there will be a conflict with lower DMA channels. See below (ui32ChannelNum & 0x1f). Do you have example that use the new form of channel assignment?

    uDMAChannelEnable(uint32_t ui32ChannelNum)
    {
    //
    // Check the arguments.
    //
    ASSERT((ui32ChannelNum & 0xffff) < 32);

    //
    // Set the bit for this channel in the enable set register.
    //
    HWREG(UDMA_ENASET) = 1 << (ui32ChannelNum & 0x1f);
    }
  • Hello David,

    I have a GPIO triggered DMA transaction. Also it is important to check if the SSI DMA is enabled or not

    void
    InituDMA(void)
    {
    //
    // Enable the uDMA controller at the system level. Enable it to continue
    // to run while the processor is in sleep.
    //
    SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA);
    SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    SysCtlDelay(10);

    //
    // Enable the uDMA controller.
    //
    uDMAEnable();

    //
    // Point at the control table to use for channel control structures.
    //
    uDMAControlBaseSet(pui8ControlTable);

    uDMAChannelAssign(UDMA_CH15_GPIOF);

    //
    // Put the attributes in a known state for the uDMA GPIOF channel. These
    // should already be disabled by default.
    //
    uDMAChannelAttributeDisable(UDMA_CH15_GPIOF,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK);

    //
    // Configure the control parameters for the primary control structure for
    // the GPIOF channel. The primary contol structure is used for the "A"
    // part of the ping-pong receive. The transfer data size is 8 bits, the
    // destination does not increment since it will be written to GPIO
    // Data Registet The source address increment is byte 8-bit bytes. The
    // arbitration size is set to 1
    //
    uDMAChannelControlSet(UDMA_CH15_GPIOF | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
    UDMA_ARB_1);

    //
    // Configure the control parameters for the alternate control structure for
    // the GPIO F channel. The alternate contol structure is used for the "B"
    // part of the ping-pong receive. The configuration is identical to the
    // primary/A control structure.
    //
    uDMAChannelControlSet(UDMA_CH15_GPIOF | UDMA_ALT_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
    UDMA_ARB_1);

    //
    // Set up the transfer parameters for the GPIO F primary control
    // structure.
    //
    uDMAChannelTransferSet(UDMA_CH15_GPIOF | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    g_ui8TxBufA, (void *)(GPIO_PORTE_BASE + 0x3FC),
    sizeof(g_ui8TxBufA));

    //
    // Set up the transfer parameters for the GPIO F alternate control
    // structure.
    //
    uDMAChannelTransferSet(UDMA_CH15_GPIOF | UDMA_ALT_SELECT,
    UDMA_MODE_PINGPONG,
    g_ui8TxBufB, (void *)(GPIO_PORTE_BASE + 0x3FC),
    sizeof(g_ui8TxBufB));

    //
    // Now both the uDMA UART TX and RX channels are primed to start a
    // transfer. As soon as the channels are enabled, the peripheral will
    // issue a transfer request and the data transfers will begin.
    //
    uDMAChannelEnable(UDMA_CH15_GPIOF);

    }

    Regards
    Amit