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.

Triggering EDMA with Timer Question

Other Parts Discussed in Thread: SYSBIOS, TMP64

Hello,

I've research countless forums and the technical reference without any luck. I have a solution but I'm trying to research a more elegant approach. I'm using SYSBIOS, the omapl137 and I'm working on the DSP side.

I would like to trigger a DMA event only when TIMIN12 = one of the CMP (compare registers).

I'm reading: "SPRUH92D" Section: 30.1.9 and the description is a little ambiguous. Please excuse me if I missed something obvious.

30.1.9 DMA Event Support

Each of the timers can send either one of two separate timer events (TEVTn) to the DMA engine, depending on the operating mode of the timer. The timer events are generated when the count value in the counters register reaches the value specified in the period register. When the PLUSEN bit in the timer global control register TGCR) is set, matches between TIM12 and CMPn in dual 32-bit unchained mode will also generate DMA events. Setting the PLUSEN bit also enables additional features for control, status, and generation of dma events are enabled. See Section 30.1.11 for more information.

It states: "will also" does this means that it will trigger a DMA with both conditions: TIM12 = PRD12 and TIM12=CMPx or it will just do one of the two?

I'm trying to generate a pulse at 600 KHz but trigger the DMA 900 ns after the pulse is sent. I already have TMP64_OUT generating such pulse.

Jaime

  • Jaime,

    You are being polite saying it is a "little ambiguous", so thank you for that. You have not missed anything obvious, but the PLUS features that were added (not meaningful unless you worked with an older version of the timer, so that is confusing) are to allow both the TIM==PRD state and the TIM12==CMP12 state to cause an interrupt or a DMA event.

    After reading through it a few times, I cannot find a way to trigger a CPU interrupt off one state and a DMA Event off the other state. But thankfully, it does not sound like you need to do that.

    From my reading of it (and I am not in a position to test it for you, sorry), you will put INTCTLSTAT.PRDINTEN12=0 to disable the TIM==PRD interrupt/event and INTCTLSTAT.EVTINTEN12=1 to enable the TIM12==CMP12 interrupt/event. That way, you will get your TMP64_OUT pulses like you do already, and you will get a DMA event when TIM12 matches CMPx for the 900ns DMA trigger.

    Please let us know if this is working for you. I apologize it took a week to get back to you, and you probably tried it already and have it working. We will try to do better next time.

    Regards,
    RandyP
  • Thank you for your reply. I will be able to test it tomorrow and will make sure to mark "verify answer" if it works.
  • Hi Randy, 

    Unless I'm missing something it does not work as you describe. For testing purposes I'm able to trigger a ping ping DMA with:

    // Enable Timer0 Interrupts

    CSL_FINST(tmr0Regs->INTCTLSTAT, TMR_INTCTLSTAT_PRDINTEN12, ENABLE);

    as soon as I set it to DISABLE the DMAs are not triggered.

    For this test bench I'm setting:

    // Set Timer0 Period

    CSL_FINS(tmr0Regs->PRD12, TMR_PRD12_PRD12, (CSL_ASYNC_2_FREQ/2));

    // Define Compare Registers
    CSL_FINS(tmr0Regs->CMP0, TMR_CMP0_CMP0, (CSL_ASYNC_2_FREQ/4));

    CSL_ASYNC_2_FREQ = 24e6

    actually here is my entire timer0 configuration, please excuse the long thread.

    void setup_Timer0 ()
    {
    // GPIP5_9 -> CSL_SYSCFG_PINMUX8_PINMUX8_19_16_TM64P0_OUT12
    CSL_FINST(sysRegs->PINMUX8, SYSCFG_PINMUX8_PINMUX8_19_16, TM64P0_OUT12);

    // Configure Timer0 with the DSP CPU
    CSL_FINST(sysRegs->SUSPSRC, SYSCFG_SUSPSRC_TIMER64_0SRC, DSP);

    // Set Timer0 as 32 Bit Unchain
    CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_TIMMODE, 32BIT_UNCHAIN);

    // Remove Timer0 from Reset
    CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_TIM12RS, NO_RESET);

    // Set Timer0 Period; 1.7us PRD12 = 40
    CSL_FINS(tmr0Regs->PRD12, TMR_PRD12_PRD12, (CSL_ASYNC_2_FREQ/2));

    // Define Compare Registers
    CSL_FINS(tmr0Regs->CMP0, TMR_CMP0_CMP0, (CSL_ASYNC_2_FREQ/4));

    // Select Internal Clock for Timer0 (24 MHz)
    CSL_FINST(tmr0Regs->TCR, TMR_TCR_CLKSRC12, INTERNAL);

    // CSL_TMR_GPINTGPEN_GPENO12_TIMER.
    CSL_FINST(tmr0Regs->TCR, TMR_GPINTGPEN_GPENO12, TIMER);

    // CSL_TMR_TCR_INVOUTP12_NON_INVERTED
    CSL_FINST(tmr0Regs->TCR, TMR_TCR_INVOUTP12, NON_INVERTED);

    // CSL_TMR_TCR_CP12_PULSE
    CSL_FINST(tmr0Regs->TCR, TMR_TCR_CP12, PULSE);

    // CSL_TMR_TCR_PWID12_FOUR_CLK
    CSL_FINST(tmr0Regs->TCR, TMR_TCR_PWID12, FOUR_CLK);

    // Reset the Counter for Timer0
    CSL_FINST(tmr0Regs->TIM12, TMR_TIM12_TIM12, RESETVAL);

    // Enable the New Timer Features
    CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_PLUSEN, ENABLE);

    // Enable Timer0 Interrupts
    CSL_FINST(tmr0Regs->INTCTLSTAT, TMR_INTCTLSTAT_PRDINTEN12, ENABLE);

    // CSL_TMR_INTCTLSTAT_EVTINTEN12_ENABLE
    CSL_FINST(tmr0Regs->INTCTLSTAT, TMR_INTCTLSTAT_EVTINTEN12, ENABLE);

    // Enable Timer0:12 Continuously
    CSL_FINST(tmr0Regs->TCR, TMR_TCR_ENAMODE12, EN_CONT);
    }/* setup_Timer0 */

  • Jaime,

    When you set both EVTINTEN12 and PRDINTEN12, do you get DMAs triggered at the PRD match and also the CMP0 match?

    What status do you see on EVTINTSTAT12 and PRDINTSTAT12 before enabling the timer on the last line, and after running for a while?

    Regards,
    RandyP
  • Is hard to tell as the edma channel is the same. I tried the following, although it feels there should be a easier way, I configured the PRD12 for 10 seconds and the CMPO to 16.667 us. Edma was fired, for sure at 10 seconds not right away as if CMP trigger it. PRDINTSTAT12 = PEND and I can see it in an ISR I configured for debugging. EVENTSTAT12 =NOPEND when I hit a breakpoint in the CMPISR.

    Both EVENTEN12 and PRDINTEN12 are set to enable, the register tab in CCS is really helpful. It would be very difficult to read straight of of memory :)

    This makes me hopeful as it looks like I'm missing something in the configuration.

    I checked the EDMA and there is only one channel for each half of the timer, and I'm sure is set properly as the edma callback works as expected, new features are enabled, the CMP isr works, and since the timer does not have many register, I already reviewed them all and can't figure out what am I missing.

    Although I might be able to get my application working using the SPI timing controls, use the C2TDELAY, using CMP to trigger the EDMA to write to SPI without the timing parameters will be more elegant and flexible. The SPI T2C and C2T can barely meet timing for our ADC.
  • Hi Randy, I think we can close this issue. We are pursuing a different way of triggering edma.

    I have run into 2 things that I would recommend better documentation is available:

    1- for the timer to trigger edma you need to clear the interrupt (PRDINTSTAT12 ) in an ISR. This will not work for me since the timer is running really fast ~1.66667 u. SYSBIOS does not like being interrupted so often.
    2- I was not able to trigger the edma with the CMPs as the documentation states is possible. Not sure if I'm missing something, but today myself and a teammate try a couple of things and nothing worked. The CMP trigger event would have been great since such event does not need to clear any register.

  • Jaime,

    #1 is not the way we tend to design these things, so I am sorry that it is happening that way. We usually keep things more workable.

    For #2, the documentation could really use some clarification. It clearly makes one believe CMPx matches should be able to trigger a DMA channel. That is not the kind of mistake we usually make in our documentation, especially when it has been out for so long and has been very popular.

    If we figure out anything, we will post it here for posterity, but I am glad you have a work-around.

    Regards,
    RandyP