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: ADC ---> Memory using uDMA.

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

I am trying to just simply read the temperature sensor from the ADC0 with uDMA, then read it over UART. 

Here is my code: https://paste.ofcode.org/37m72pGspzZ47eUVU5mMmwq  

Every time I go into calculate temperature, and the ADC gets triggered, the uDMA goes into a bus error. I have no idea what I am doing. I am trying to understand uDMA and how to use it, but this simple program is killing me. I've already tested to see if it works without UDMA. I also know that I'm only using one register in the AVG, just trying to start small then plan on adding the others when I get one to work. 

I have read others people code and problems, and I feel like I have done everything they have suggested. Maybe not. What am I blatantly missing? I appreciate any help. Thank you very much.

  • Hi,

      There is a ready to use example for ADC with uDMA. Please find the example in:

    C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c123gxl\adc_udma_pingpong

      Compare this example with yours and you should be able to narrow down the fault. Please see below link to an app note about diagnosing faults in the system. 

  • Hello, so like I already stated. I've followed all those examples, and I tried the debugging. The NVIC_fault_stat is 0. Like I said already, the bus fault happens in the uDMA not the NVIC. 

    Here is my code again because I'm guessing you aren't allowed to click links. 

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/tm4c123gh6pm.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "utils/uartstdio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/udma.h"
    //********************
    
    typedef struct{
        uint16_t adcBuffer[8];
        uint16_t AVG;
        uint16_t C;
        uint16_t F;
    }Temp_t;
    
    
    typedef struct{
    
        unsigned char input;
    
    }UART_t;
    
    
    void calculate_avg_temperature(Temp_t *temp_t);
    //*******************
    
    
    //********************
    
    uint8_t DMAControlTable[1024];
    
    //*******************
    int main(void)
    {
    
          //Config System Clock
         SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_XTAL_16MHZ | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN );
    
         Temp_t temp_t = {0};
    
         volatile UART_t uart_t;
    
    
         //Config UART
         SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
         GPIOPinConfigure(GPIO_PA1_U0TX);
         GPIOPinConfigure(GPIO_PA0_U0RX);
         GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1 | GPIO_PIN_0);
         UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600UL, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
         UARTStdioConfig(0, 9600, SysCtlClockGet());
         //
    
          SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
         //Config uDMA
           SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    
           uDMAEnable();
           uDMAControlBaseSet(DMAControlTable);
    
           uDMAChannelAttributeDisable(UDMA_CH14_ADC0_0, UDMA_ATTR_ALL);
           uDMAChannelAttributeDisable(UDMA_CH14_ADC0_0 | UDMA_ALT_SELECT, UDMA_ATTR_ALL);
    
           uDMAChannelAttributeEnable(UDMA_CH14_ADC0_0, UDMA_ATTR_USEBURST);
    
           uDMAChannelControlSet(UDMA_CH14_ADC0_0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    
           uDMAChannelTransferSet(UDMA_CH14_ADC0_0 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void*)(ADC0_SSFIFO0_R), temp_t.adcBuffer, sizeof(temp_t.adcBuffer));
    
           uDMAChannelEnable(UDMA_CH14_ADC0_0);
    
    
    
         //Config ADC
    
    
         ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_HALF, 1);
    
         SysCtlDelay(10);
    
         ADCSequenceDisable(ADC0_BASE, 0u);
    
         ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_TS | ADC_CTL_END | ADC_CTL_IE);
         ADCSequenceEnable(ADC0_BASE, 0);
         ADCSequenceDMAEnable(ADC0_BASE, 0);
    
    
    
    
        while(1)
        {
        calculate_avg_temperature(&temp_t);
            UARTprintf("C %3d\t", temp_t.C);
        }
    }
    
    
    //Calculate the average
    void calculate_avg_temperature(Temp_t *temp_t){
    
        while(!(uDMAChannelModeGet(UDMA_CH14_ADC0_0 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)){
            ADCProcessorTrigger(ADC0_BASE, 0);
            while(!(ADCIntStatus(ADC0_BASE, 0, false))){};
            ADCIntClear(ADC0_BASE, 0);
        };
    
    
        temp_t->AVG = (temp_t->adcBuffer[0]);
        temp_t->C = (1475 - (2475 * temp_t->AVG) / 4096)/10;
        temp_t->F = ((temp_t->C * 9) + 160) / 5;
    
        uDMAChannelTransferSet(UDMA_CH14_ADC0_0 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void*)(ADC0_SSFIFO0_R), temp_t->adcBuffer, sizeof(temp_t->adcBuffer));
        uDMAChannelEnable(UDMA_CH14_ADC0_0);
    
    }

    So like I said already, when the ADCProcessorTrigger happens, the uDMA bus fault triggers. The datasheet doesn't give any more information on this and what causes it.