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.

MSPM0L1306: How to detect that a GPIO had a rising edge during a timer period?

Part Number: MSPM0L1306
Other Parts Discussed in Thread: SYSCONFIG

Hello, I have been through the academy examples and tutorials reguarding timers, GPIO, and the event fabric. Our goal is to route a GPIO rising-edge to a timer (capture) such that at the end of the timer period we can determine if there has been any activity (e.g. any number of rising edges) on the IO pin. We do not want to interrupt or wake the CPU on every rising edge, we only want to wake up at the end of the time period and know if there has been at least one rising edge.

It seems this should be possible but we cannot find any examples and our attempt to construct one does not work (project code here: gpio_to_timer_event.zip ). What we want is similar to the "comp_dac_timer_event" example in the SDK, but that example wakes up on every comparator event, we need to stay in lower power mode until the timer expires.

Our project (using the MSPM0L1306 launchpad) uses syscfg to define the timer, GPIO pin, and event fabric to capture rising edges in the timer capture registers. But when we read the capture registers at the end of the time period, they always read as zero even when there were (many) rising edges while the timer was running.

Any help, advice, or working examples would be appreciated.

 

  • What you want is "Edge Counting"; this is demonstrated in example timx_timer_mode_compare_edge_count (here). This example counts edges in CTR, then interrupts when CTR reaches 5. It would be relatively easy to set the Load value arbitrarily high (so the CTR never reaches it) and then fetch the CTR value at intervals.

    I suspect you want to use the same timer both for counting and for measuring the intervals. This can be done, but Driverlib/Sysconfig won't make it easy. The most expedient thing would probably be to adopt a second timer, and use that in a periodic mode (counts repeatedly up to Load value) and fetch the CTR of the first timer on a Load interrupt.

    [Edit: Minor clarification]

  • Thanks, this is exactly the sample I needed to see how this can be done. I modified it to add another (interval) timer that reads the counter periodically (I am not expert enough to try to make the same timer do both). I setup the counter timer with no interrupts because I don't ever want it to wake the system up.

    I set the timer count to the max (65535) and "Edge Count Up Counting" mode. In the interval timer ISR I read that counter and then reset it to zero so it starts over every period:

                edgeCount = DL_TimerG_getTimerCount(COMPARE_0_INST);
                DL_TimerG_setTimerCount(COMPARE_0_INST, 0);
                if (edgeCount == 0) {
                    // no events in the last time period
                }
                else {
                    // at least one event in the last time period
                }
    I suppose there is a tiny race condition between reading the counter and setting it to zero such that an event could be missed. I suppose the ISR could store the last-read count and compare to that instead of zero and skip the setTimerCount() call (and assuming it will roll over at 65535).
    Thanks for the help making this proof of concept work.