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.

PWMSS INTC: Double triggered Events

Other Parts Discussed in Thread: AM3358

Hi,

I'm using ePWM0 to trigger interrupts in the PRU (AM3358, Beaglebone Black). For some reason, these interrupts are always triggered twice. Once on CNT_PRD and once just after this.

Relevant code:

#define HOST_INT_NUM 1

#define INT_CHAN_NUM 1

#define PWM0_PRD_EVENT 43

[init ePWM0 to up/down counting, no clock divisor, event on first period]

[init INTC to trigger host interrupt HOST_INT_NUM on channel INT_CHAN_NUM  with source from event PWM0_PRD_EVENT]

    MOV  regAddr, EPWM0_BASE

PWM_EVENT_WAIT:
    WBS r31, #(30+HOST_INT_NUM)

[...do something for about 60cycles...]

    //Clear PWM interrupt flag
    LDI  regTmp0.b0, PWM0_PRD_EVENT
    SBCO regTmp0.b0, CONST_PRUINTC, OFS_INTC_SICR, 1 //Clear pending sys event interrupt

    //Clear PWM event flag
    LDI  regTmp0.w0, 1
    SBBO regTmp0.w0, regAddr, OFS_PWM_ETCLR, 2


JMP PWM_EVENT_WAIT

 

The first event is triggered as expected after about 4*PWM_Period Cycles (PRU at 200MHz, PWM_Clk at 100MHz, up/down counting). The second event is triggered with a latency of about the runtime of the outer loop. It seems to me as the clearing of the flags doesn't propagate so that WBS would block. Is there any better way to do that?

  • I will forward this to the PRU experts. They will respond here.
  • Ok, thanks. Some more observations: R31 bit 31 is always set in the loop (WBS exits); ePWM0's ETFLG is only set every second run. Clearing all Event/Channel and Channel/HostInt mappings doesn't help
  • Claudius,

    Can you try swapping the order that you clear the event/interrupt flags? So, clear the PWM event flag in the ePWM0 module before you clear the PWM system event flag from the PRU INTC.

    I had a similar issue while working with the mailbox interrupts from the PRU. You need to clear the event in the external module first so that when you clear the PRU INTC event it won't get immediately re-enabled by the external module (since the event is still triggered and not yet cleared in the external module). 

    Jason Reeder

  • And I think all PRU writes routed to the L3 interconnect are posted, hence the write to the PWM peripheral should be followed by a read (of any register of the peripheral) to ensure it has arrived at the target?

  • Matthijs makes a good point.
  • Matthijs & Jason: Thank you! That was it.
    - I first switched the order of the clearing code but that didn't help alone.
    - Adding the extra LBBO was the key.
    - Only the LBBO with the original ordering doesn't work either, so both solutions are needed.

    New code looks as follows:
    MOV regAddr, EPWM0_BASE //2 cyc
    PWM_EVENT_WAIT:
    WBS r31, #(30+HOST_INT_NUM)

    LBBO regVal.w0, regAddr, OFS_PWM_TBCNT, 2 //40cyc

    [some more code]

    //Clear PWM event flag
    MOV regAddr, EPWM0_BASE //2 cyc
    LDI regTmp0.w0, 1 //1 cyc
    SBBO regTmp0.w0, regAddr, OFS_PWM_ETCLR, 2 //2cyc
    LBBO regTmp0.w0, regAddr, OFS_PWM_ETCLR, 2 //2cyc

    //Clear PWM interrupt flag
    LDI regTmp0, PWM0_PRD_EVENT //1cyc
    SBCO regTmp0, CONST_PRUINTC, OFS_INTC_SICR, 4 //Clear pending sys event interrupt, 2cyc

    JMP PWM_EVENT_WAIT

    The regVal.w0 now contains the value 14 (=140ns delay between Counter overflow and first action)

    Claudius