Is it possible to read a data pin with PPI? (PS/2 bit banging using PPI)

Hi,

I am trying to implement a PS/2 bit banging driver. My initial attempt used the GPIO library and interrupts, but unfortunately the interrupts are not fast enough and oftentimes there are transmission errors due to missed bits.

Now I am exploring whether it would be possible to use PPI to read the data. 

PS2 uses a clock and data pin. The data pin is read on the falling edge of the clock pin. The frequency is approximately 10-16hz.

The PS2 data frame is 11bit:

  • Start bit
  • 8 data bits
  • Parity bit
  • Stop bit

I considered trying to use SPI, but it seems that it can‘t read odd number of bits. 

Now I’m exploring whether PPI would work. 

My idea is…

  1. Create a timer that counts whenever the clock pin triggers.

  2. Copy the data pin value to some kind of buffer every time the clock pin triggers
  3. When the timer reaches 11, copy the buffer using easy DMA to the cpu and trigger an interrupt to notify it. 
  4. Reset the timer counter so that it can start from scratch

Is something like this feasible?

If yes, could you please point me to some documentation on how to configure such PPI tasks? I couldn’t find any good explanations. 

I was able to find examples for counting, but not for storing the data pin value in a buffer array and for transmitting it using easy DMA.

Thank you so much,

Kim

Parents
  • Hi,

    Unfortunately, it is not possible to capture digital levels on GPIOs using PPI.

    The other alternative is to use the SAADC peripheral to capture the analog level of the GPIO and determine the logical level of the signal from the captured SAADC samples in your buffer. The SAADC sample task can be triggered through PPI. If the frames have a static length, you do not need a timer to capture the number of clock pulses, you can set the SAADC buffer length of the packet size and connect the GPIOTE input event from the clock pin directly to the sample task of the SAADC through PPI. When the SAADC buffer have been filled with the requested number of samples (corresponding to the number of bits in your package), the END event will be generated and you can handle the frame assembly in the SAADC event handler.

    Best regards,
    Jørgen 

Reply
  • Hi,

    Unfortunately, it is not possible to capture digital levels on GPIOs using PPI.

    The other alternative is to use the SAADC peripheral to capture the analog level of the GPIO and determine the logical level of the signal from the captured SAADC samples in your buffer. The SAADC sample task can be triggered through PPI. If the frames have a static length, you do not need a timer to capture the number of clock pulses, you can set the SAADC buffer length of the packet size and connect the GPIOTE input event from the clock pin directly to the sample task of the SAADC through PPI. When the SAADC buffer have been filled with the requested number of samples (corresponding to the number of bits in your package), the END event will be generated and you can handle the frame assembly in the SAADC event handler.

    Best regards,
    Jørgen 

Children
Related