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.

RTOS/TM4C1294NCPDT: Timer and uDMA

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Tool/software: TI-RTOS

Hello

I try to measure are pulsewitdh with timer compare. I've allready done this by using an interrupt at the rising edge and on the falling edge and reading the time registers to calculate the high time.

Now I'm try to use the uDMA for this but it won't work. Please help me to find the error in this configuration. I found an example in the "Stellaris Ware" package and adapt it to timer 3.

Kind regards

René 

    //
    // Enable the uDMA peripheral
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    //
    // Enable the uDMA controller error interrupt.  This interrupt will occur
    // if there is a bus error during a transfer.
    //
    ROM_IntEnable(UDMA_INT_ERR);

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

    //
    // Point at the control table to use for channel control structures.
    //
    ROM_uDMAControlBaseSet(ucControlTable);

    uDMAChannelSelectSecondary(UDMA_DEF_USBEP2TX_SEC_TMR3B);
    //
    // Put the attributes in a known state for the uDMA Timer3B channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_TMR3B,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

    //
    // Set up the DMA channel for Timer 0A.  Set it up to transfer single
    // 32-bit words at a time.  The source is non-incrementing, the
    // destination is incrementing.
    //
    ROM_uDMAChannelControlSet(UDMA_SEC_CHANNEL_TMR3B | UDMA_PRI_SELECT,
                              UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_1);

    //
    // Set up the transfer for Timer 0A DMA channel.  Basic mode is used,
    // which means that one transfer will occur per timer request (timeout).
    // The amount transferred per timeout is determined by the arbitration
    // size (see function above).  The source will be the value of free running
    // Timer1, and the destination is a memory buffer.  Thus, the value of the
    // free running Timer1 will be stored in a buffer every time the periodic
    // Timer0 times out.
    //
    ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_TMR3B | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, (void *)(TIMER3_BASE + TIMER_O_TBR),
                               g_ulTimerBuf, MAX_TIMER_EVENTS);

    uDMAChannelEnable(UDMA_SEC_CHANNEL_TMR3B);

  • Has someone an idea how to configure the uDMA for this purpose?
    By the way I configured the timer to activate the uDMA with

    TimerDMAEventSet(TIMER3_BASE, TIMER_DMA_CAPMATCH_B);

    Best regards
    René
  • Hi Rene,
    Can you reference the TivaWare DMA example under <TivaWare_Installation>\examples\boards\ek-tm4c1294xl\udma_demo?

    What is the reason that you want to use secondary channel and not the primary channel?
    You are enabling the DMA at the beginning before the DMA is setup. You should enable DMA after all DMA configuration is done. Please refer to the TivaWare example.
  • Hello Charles

    In the driverlib documentation (SW-TM4C-DRL-UG-2.1.3.156.pdf) is written:
    "In order to use the uDMA controller, you must first enable it by calling uDMAEnable()."
    And in the Demo-Project you mention "uDMAEnable()" its also called before config!
    I thinks what you mean is "uDMAChannelEnable()" and thats done in the last line.

    I couldn't use Timer 1/2 because my input for the signal is only on Timer 3 (Pin D5 T3CCP1) and there is no primary channel for this.

    I refer to the TivaWare example but I didn't find anything that helps me with this problem.

    In the documentation I found only that I should use
    "uDMAChannelAssign(UDMA_CH3_TIMER3B);"
    instead of
    "uDMAChannelSelectSecondary(UDMA_DEF_USBEP2TX_SEC_TMR3B);"

    But to change this didn't fix that my problem.

    The adress of the config is in the SRAM at
    0x2002d400 uDMAControlTable
    That should be also right.

    Any other advise?

    Best regards
    René
  • I think you should try uDMAChannelAssign(UDMA_CH3_TIMER3B) instead. Reading the source code it looks like the uDMAChannelSelectSecondary() is meant to be deprecated.
  • Hi Charles

    As mention in the answer before. I tried this already but didn't fix the problem.

    Kind regards
    René
  • Hi Rene,
    In the registers browser window in CCS can you go to uDMA module and look at the UDMA_WAITSTAT register. Is the channel 3 waiting for request? Perhaps the TMR didn't generate the request to the uDMA. Why don't you try to generate the DMA request based on the timeout event as an experiment? The event should be generated periodic and it is easier to observe if request is properly setup.
  • Hi Charles

    I got it. The request wasn't set because I registered it to the wrong one.

    Thats the failure:
    TimerDMAEventSet(TIMER3_BASE, TIMER_DMA_CAPMATCH_B);

    Thats the solution:
    TimerDMAEventSet(TIMER3_BASE, TIMER_DMA_CAPEVENT_B);

    Thanks for you advice.

    Kind regards
    René