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.

TM4C123GH6PM: TM4C and uDMA

Part Number: TM4C123GH6PM


Howdy,

I'm trying to use Port D on the TM4C with Tivaware as a digital output port with the data to write stored in RAM. The data should be transferred from waveform.array (a uint8_t array) one byte at a time to Port D bit band address (bits 0 to 5) when Timer 1A expires and the transfer should last for the size of the array (waveform.size). The goal is to use very little CPU to output a waveform onto Port D bits 0 to 5 with hardware timed precision until the waveform array is exhausted. 

My latest attempt is embedded in the post. The timer works fine and I'm able to verify it works by checking an interrupt function (not shown), but I'm getting an unspecified error in the "udma_error" function.

Questions:

  • Is the goal even possible using uDMA?
  • How do I determine uDMA errors other than an error occurred?
  • The setup of the channels in both the Tivaware and TM4C documentation is confusing, do I use GPIO D Channel or Timer A channel? Neither seem to work.

#define MDI_V2_DAC       (*((volatile unsigned long *)0x400070FC)) // Port D bits 5-0    
    
void udma_error(){
    uint32_t error = uDMAErrorStatusGet();
    uDMAErrorStatusClear();
}
    
void udma_timer_test(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1))
    {
    }

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))
    {
    }

    uDMAEnable();

    uDMAControlBaseSet(dma_table);

    uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR1A, 0);

    uDMAIntRegister(INT_UDMAERR, udma_error);

    //This configure the DMA to fire when Timer 1A times out, and increments the
    //memory to increment by 8 bytes, and the destination (GPIO to not change).
    //In short, when Timer 1A expires, it outputs a new value to the GPIO
    uDMAChannelControlSet(UDMA_CHANNEL_TMR1A | UDMA_PRI_SELECT,
                          UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);

    //Configure Timer 0 to be split pair timer, with timer A counting up
    TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_PERIODIC | TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC));

    //TimerIntRegister(TIMER1_BASE, TIMER_A, mdi_waveform_interrupt);

    //Increment on pos edge of the clock
    TimerControlEvent(TIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    
    uDMAChannelTransferSet(UDMA_CHANNEL_TMR1A | UDMA_PRI_SELECT,
                    UDMA_MODE_BASIC, waveform.array, MDI_V2_DAC,
                    waveform.size);

    //Enable the timer interrupt
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);

    //Set that Timer 1A timeout triggers a DMA
    TimerDMAEventSet(TIMER1_BASE, TIMER_DMA_TIMEOUT_A);

    //Enable DMA for Timer 1A
    uDMAChannelEnable(UDMA_CHANNEL_TMR1A);

    //Enable the timer
    TimerEnable(TIMER1_BASE, TIMER_A);
}

Thank you for any help!

Austin