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

Using PPI to periodically pass memory to hardware peripherals (specifically PWM)

Is it possible to pass a memory location to PWM (preferably via DMA) via PPI. This is a sound project and my intent is to update two 8 bit PWM outputs at 44.1kHz. I typically do this with interrupts in a bare metal application. But I do not believe this method is acceptable in a SoftDevice (S112) application because the SoftDevice has a higher interrupt priority than my application. Can I use PPI to accomplish what I want without CPU intervention? 

Below is the psuedo code of what I am trying to accomplish:

//this IRQ fires every 363 16MHz clock cycles (22.6875us)
void TIMERx_IRQHandler{
	UpdatePWMx(buffer[n]); //update PWMx with new byte
	UpdatePWMy(buffer[n+1]); //update PWMy with new byte
	n+=2;
}

CPU: NRF52810

SDK: 15.2

SoftDevice: S112

Thanks in advance.

Parents
  • I am a bit confused regarding what you mean with PWM buffer. Maybe you can find something that you can use in the PWM examples? Are you using the PWM driver or the PWM library?

  • Hi Edvin. Thanks for your response. I understand how to output a PWM signal using the driver and the library. My question is not "how can I output a PWM signal". My question is "can I change the PWM output without CPU intervention?" The buffer I am referring to is a page of SPI flash memory consisting of 2048 bytes. My goal, if possible, is to update the PWM outputs every ~22us with the next two values in the flash buffer. I want to use the CPU cycles to read SPI flash and update the buffer; not to update the PWM output.

  • Ok. So I assume you are using the PWM peripheral, then, which is the one used in the pwm_driver example, and not the one used in the pwm_library example. 

    If you study the PWM registers on infocenter, you can see the tasks and events that are present in the PWM peripheral.

    For you, the interresting parts are (N = 0 or 1):

    SEQ[N].PTR

    SEQ[N].CNT

    TASKS_SEQSTART[N]

    TASKS_NEXTSTEP[N]

    So you can use these tasks together with PPI to update the PWM duty cycles. But you need to use the CPU to update SEQ.PTR and CNT, and the actual values. But when these are set, you can iterate through them using the PPI (so without the CPU).

    You need an event that can trigger the PPI. If it needs to be updated every 22µs, then you can use a timer which can generate the events.

    BR,

    Edvin

  • Edvin,

    Perfect! This is exactly the information I wanted. Thank you so much for pointing me to the tasks I need to use. I get it now. Thanks for your help!

    Ryan

Reply Children
No Data
Related