This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Question about customized task for GPIOTE

Hi,

I was writing a program that uses the PPI with event from the timer and the task to one of the GPIO pins. The ideal scenario is that, whenever the timer fires, it will trigger the task and cause the GPIO pin to do a customized behavior (for example, turn on, then turn off, and turn on again).

I was aware that there are some default behavior (tasks) that can be used, such as GPIO_CONFIG_OUT_TASK_TOGGLE. I wonder if there is a way to define a task myself, so that I can update that pin many times in a customized way for each triggering event.

Thanks,

Jinyue

Parents
  • Hi,

     

    I was writing a program that uses the PPI with event from the timer and the task to one of the GPIO pins. The ideal scenario is that, whenever the timer fires, it will trigger the task and cause the GPIO pin to do a customized behavior (for example, turn on, then turn off, and turn on again).

     You can setup the NRF_TIMERx to trigger several EVENTS_COMPARE[], which you connect using PPI channels.

    If you need a specific timer to trigger the "start" sequence, you likely have to use two timers.

     

    The NRF_TIMERy runs every 500 ms (then generates EVENTS_COMPARE[0], where this is shorted in NRF_TIMERy->SHORTS to restart the timer), for instance.

    You take that event NRF_TIMERy->EVENTS_COMPARE[0], and route that to start the next NRF_TIMERx.

    You could for instance setup NRF_TIMERx like this:

    1. EVENTS_COMPARE[0] happens after 100 ms

    2. EVENTS_COMPARE[1] happens after 250 ms (delta = 250-100=150ms)

    3. EVENTS_COMPARE[2] happens after 500 ms

    Each event should then have a corresponding PPI channel, with a defined GPIOTE task (set, clear or toggle)

    The last event occurring (time-wise) should be the one configured to restart the counter (see the SHORTS.COMPAREx_CLEAR mask here)

    If you need two things to occur from the same event, see PPI fork functionality.

     

    I was aware that there are some default behavior (tasks) that can be used, such as GPIO_CONFIG_OUT_TASK_TOGGLE. I wonder if there is a way to define a task myself, so that I can update that pin many times in a customized way for each triggering event.

    PPI only routes events to tasks. If you cannot generate an event, or set the functionality using one task; then it cannot be done with PPI.

     

    Kind regards,

    Håkon

  • Hi Håkon,

    Thanks for this update! Your proposed methodology makes sense.

    I have another question though. I wonder if there’s a way to write the gpio output pin based on different conditions.

    the idea scenario is that, I could loop through an array. If a bit is 1, I set the gpio pin. If the bit is 0, I clear the pin. Of course, this can be done using a timer interrupt, and I can check the array during the interrupt and call the pin_set or pin_clear method.

    however, if I am using PPI and GPIOTE, i find it very hard to implement this behavior. Because the connection and the task behavior is set beforehand, a given task for the gpio pin could only be SET, CLEAR, or TOGGLE. Is there a way to customize the task such that whenever a timer fired, it is linked to a gpiote task, and that task could write a 1 or 0 depending on the circumstances?

    thanks!

    jinyue

  • Hi,

     

    Jinyue Zhu said:
    the idea scenario is that, I could loop through an array.

    If you want to make this run without the involvement of the CPU, the PWM peripheral is the closest.

     

    Jinyue Zhu said:
    however, if I am using PPI and GPIOTE, i find it very hard to implement this behavior. Because the connection and the task behavior is set beforehand, a given task for the gpio pin could only be SET, CLEAR, or TOGGLE. Is there a way to customize the task such that whenever a timer fired, it is linked to a gpiote task, and that task could write a 1 or 0 depending on the circumstances?

    PPI is not conditional, so you cannot set it up to "if this, do that, else do something_different". You need to involve the CPU if you want to do more advance patterns like this.

     

    Jinyue Zhu said:
    Another completely unrelated question. I am wondering if I can disable the timer in its own event_compare interrupt.

    Yes you can do this. that'll run TASKS_SHUTDOWN on the timer. 

     

    Jinyue Zhu said:
    I want to figure out a way to disable the timer after it has run some certain number of times...

    increment a counter, check if it is greater or equal than the amount of times it should run; then disable (remember to reset your variable as well).

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    Jinyue Zhu said:
    the idea scenario is that, I could loop through an array.

    If you want to make this run without the involvement of the CPU, the PWM peripheral is the closest.

     

    Jinyue Zhu said:
    however, if I am using PPI and GPIOTE, i find it very hard to implement this behavior. Because the connection and the task behavior is set beforehand, a given task for the gpio pin could only be SET, CLEAR, or TOGGLE. Is there a way to customize the task such that whenever a timer fired, it is linked to a gpiote task, and that task could write a 1 or 0 depending on the circumstances?

    PPI is not conditional, so you cannot set it up to "if this, do that, else do something_different". You need to involve the CPU if you want to do more advance patterns like this.

     

    Jinyue Zhu said:
    Another completely unrelated question. I am wondering if I can disable the timer in its own event_compare interrupt.

    Yes you can do this. that'll run TASKS_SHUTDOWN on the timer. 

     

    Jinyue Zhu said:
    I want to figure out a way to disable the timer after it has run some certain number of times...

    increment a counter, check if it is greater or equal than the amount of times it should run; then disable (remember to reset your variable as well).

     

    Kind regards,

    Håkon

Children
No Data
Related