Pause and resume PPI

I am controlling the SPI via PPI at regular time intervals and it is working as expected.

However, I want the SPI to operate manually at any given time under certain conditions, and then when those conditions are lifted, I want to control the SPI again via the SPI.

To do this, it would seem that I would need to disable PPI once before I allow SPI to operate manually, and then re-enable PPI when the condition is lifted.
However, I do not know what steps or functions to use to disable PPI once and what steps or functions to use to restart PPI.
Could you please tell me?

Parents
  • Hello,

    I don't know what API you are currently using to set up the PPI. I guess you are either writing to some bare metal registers manually, or you are using some PPI API. 

    If you are using the registers directly, then you are probably enabling the PPI using the CHENSET register to enable the PPI channel. Then you can use the CHENCLR register to disable that same channel(s).

    If you are using some API, then you are probably using something like: nrf_drv_ppi_channel_enable() (or an equivalent using the softdevice API). In that case, look for a function called nrf_drv_ppi_channel_disable() (or the equivalent softdevice API version). 

    Then, when you are done with the custom SPI operations, you can enable the PPI channel like you did when you first set it up. The configuration will probably still be the same, so you just need to enable the channel(s).

    Best regards,

    Edvin

  • Thanks for the reply.

    I am using the API to set up the PPI. A part of the programme is shown below.

    (Program overview)

    Triggered by the reception of an ESB, the GPI outputs a total of 10 pulses, 9 PWM and 1 'GPIOE' via the PPI.
    I input those 10 pulses to another GPIO port and trigger that GPIOE input to run the SPI via PPI.

    What I want to do is to stop the sequence of these pulses when a certain condition is met, and run the SPI at an arbitrary timing, and when that condition is lifted, restart the above sequence again.
    When the condition is lifted, the above sequence is restarted again.

    (Pause)
    Question (1).
    I am aware that the API includes xxx_event_enable, xxx_task_enable, xxx_channel_enable, etc.
    To stop the system at once, do I need to disable all events, tasks and channels using the API?

    Question (2).
    Are there any other APIs to be executed other than disable?


    (Resume)
    Question (3).
    To restart PPI, is it sufficient to enable event, task and channel using the API?
    If so, should the order in which they are enabled be as in the above programe?

Reply
  • Thanks for the reply.

    I am using the API to set up the PPI. A part of the programme is shown below.

    (Program overview)

    Triggered by the reception of an ESB, the GPI outputs a total of 10 pulses, 9 PWM and 1 'GPIOE' via the PPI.
    I input those 10 pulses to another GPIO port and trigger that GPIOE input to run the SPI via PPI.

    What I want to do is to stop the sequence of these pulses when a certain condition is met, and run the SPI at an arbitrary timing, and when that condition is lifted, restart the above sequence again.
    When the condition is lifted, the above sequence is restarted again.

    (Pause)
    Question (1).
    I am aware that the API includes xxx_event_enable, xxx_task_enable, xxx_channel_enable, etc.
    To stop the system at once, do I need to disable all events, tasks and channels using the API?

    Question (2).
    Are there any other APIs to be executed other than disable?


    (Resume)
    Question (3).
    To restart PPI, is it sufficient to enable event, task and channel using the API?
    If so, should the order in which they are enabled be as in the above programe?

Children
  • Hi
    By executing 'nrf_drv_ppi_channel_disable()' for each configured PPI channel, PPI could be stopped and SPI could be controlled at any time PPI

    PPI operation could also be restarted by reconfiguring PPI with the above programme.

    Thank you very much for your advice.

  • Hello,

    TML_YT said:
    I am aware that the API includes xxx_event_enable, xxx_task_enable, xxx_channel_enable, etc.
    To stop the system at once, do I need to disable all events, tasks and channels using the API?

    xxx_event_enable and xxx_task_enable belongs to the gpiote library, so that is not really relevant for the PPI (but you need to enable it if you want to use gpiote in PPI).

    If you just want to disable the ppi, you can just disable the ppi channel using nrf_drv_ppi_channel_disable

    TML_YT said:

    Are there any other APIs to be executed other than disable?

    If you do not intend to use the same ppi channel for other purposes, but actually intend to use it for the same puprose later, then you can just disable the channel, and then enable it when you want to use it again later. 

    As long as you didn't change any of the configurations for the ppi channels, such as changing the events and tasks that will be connected/assigned, you just need to enable that channel again. 

    TML_YT said:
    If so, should the order in which they are enabled be as in the above programe?

    That depends on your application logic. Since it takes a few clock cycles to enable all 3 (for the CPU to actually call nrf_drv_ppi_channel_enable()), then they will be enabled in the order that you call it. So if they are dependent on eachother, then you need to make sure to enable them in the correct order. The correct order depends on what your tasks are doing. Just from looking at your snippet, I can't tell whether they are dependent on eachother, or if enabling them (or disabling them) in a certain order will cause some weird behavior. 

    An example:

    Let us say that you had two PPI channels:

    ppi_ch1: gpio1 event -> SPI1 start task

    ppi_ch2: SPI1 end event -> SPI2 start task

    and SPI1 and SPI2 are two different messages going to some external HW that expects to receive two messages, and will "break" if it only receives one.

    In that case, if you disable ppi_ch2 first, and the gpio1 event occurs before you disable ppi_ch1, then it will send only the first message, because ppi_ch2 is disabled. 

    Then you disable ppi_ch1, do your custom stuff, and then enable both ppi_channels later, then the SPI1 message will be sent when the gpio event occurs again, and the SPI receiver will receive two SPI1 messages in a row. 

    So if your ppi channels are chained in this way, you may want to disable the ppi channel handling the first event first, so you don't end up in some unwanted state.

    Best regards,

    Edvin

Related