Feasibility of driving PS/2 via GPIO on a busy mcu.

We would like to drive two ps/2 interfaces via nrf52840 gpio pins (i.e., reading the protocol bit by bit, via gpio interrupts). A trouble is that ps/2 is timing sensitive. 

Namely, a proof of concept of the driver running with interrupt priority 4 is running fine only as long as bluetooth is disabled. Once bluetooth gets enabled, the driver is no longer usable.

Therefore we are thinking about implementing the driver with direct latency interrupts, running it at the same or higher interrupt priority as radio. 

We fear that this (i.e., preempting radio interrupts) might easily introduce new issues that would be very hard to investigate or even detect, especially with bluetooth communication. 

Questions:

- In your expert opinion, is the above a feasible idea? 
- In your expert opinion, is the above a good idea? 
- How safe is it?

  • Hi,

     

    The bluetooth stack will assert if the timing is off, meaning that this is not a recommended solution:

    Therefore we are thinking about implementing the driver with direct latency interrupts, running it at the same or higher interrupt priority as radio. 

    PS/2 is to my knowledge, in the 10+ kHz domain, ie. around 100 us slots. I would recommend that you consider using a SPI hardware module to shift out clock/data, instead of bit banging using gpio directly.

    Although SPIM peripheral only lists down to 125 kHz: https://docs.nordicsemi.com/bundle/ps_nrf52840/page/spim.html#ariaid-title26

    you can use this approximation to get the wanted value:  RE: UART BAUDRATE register values 

     

    Kind regards,

    Håkon

  • Hi Hakon!

    I am not sure I understand.

    With ps/2, the device sets clock and decides when to send data, which means that we would have to act as an spi slave, which further complicates writing the data. We would still have to bit-bang writes to initialize the device. (After the peripheral is initialized, we only need to read the data, so this is doable.)

    More problems come because we probably need to have the timestamps of the bits, as the peripheral in question alternates the signal states when idle. Also ps/2 communicates in 11 bit packets, while spi is 8bit, which further complicates reading out data.

    All in all, unless I have missed something, this doesn't sound as a very attractive option.

    -----------------------------

    AI had one more idea: use PPI to trigger timer capture task:

    ```
    - You configure the PPI channel once
    - Every time PS/2 clock falls, TIMER automatically captures its value
    - This keeps happening continuously, all in hardware
    - CPU can read the captured values later (perhaps after N captures, or via DMA)
    ```

    If I understand everything correctly, we would basically get lists of edge transition timestamps out of that, that we would have to correlate.

    Again that would only solve reading, and we would have to be able to do this on four channels at the same time.

    Does that sound sane at all, or does the LLM just hallucinate?

    -----------------------------

    (Another solution is of course add another microcontroller to the board just to drive the ps/2 peripherals.)

  • Hi,

     

    Sorry, I assumed you were to drive the communication. Implementing a slave will be more difficult, yes.

    kat829 said:

    AI had one more idea: use PPI to trigger timer capture task:

    ```
    - You configure the PPI channel once
    - Every time PS/2 clock falls, TIMER automatically captures its value
    - This keeps happening continuously, all in hardware
    - CPU can read the captured values later (perhaps after N captures, or via DMA)
    ```

    I think you are right to question the llm in this case, as I have some doubts about this segment. A timer does what in this case?

    A timer alone cannot capture a GPIO state, but will only give you a capture, ie. from "start to capture" number.

    Using PPI, TIMER, GPIOTE, you can generate a pulse train, but it sounds like you want to sample, not shift out bits.

     

    There is no generic DMA in nRF5-series devices, only local-to-the-peripheral EasyDMA.

     

    kat829 said:
    If I understand everything correctly, we would basically get lists of edge transition timestamps out of that, that we would have to correlate.

    Again that would only solve reading, and we would have to be able to do this on four channels at the same time.

    You can setup a variety of TIMER+PPI+GPIOTE to time a edge, you can count the amount of either rising- or falling edges, but it will not store each capture in a individual register.

    PPI cannot do a if/else evaluation, it is just connecting tasks and events.

    Have you considered using nRF54L-series device, which has a faster cortex m33 core, and has an risc-v core in addition?

     

    Kind regards,

    Håkon

  • > Sorry, I assumed you were to drive the communication. Implementing a slave will be more difficult, yes.

    Well, we implement the central, but in ps/2 it is the peripheral that drives clock. 

    > but it will not store each capture in a individual register.

    I see.

    > Have you considered using nRF54L-series device, which has a faster cortex m33 core, and has an risc-v core in addition?

    You mean that we would shift the bit banging onto the risc-v coprocessor? 

    Sounds intriquing.

  • > Have you considered using nRF54L-series device, which has a faster cortex m33 core, and has an risc-v core in addition?

    Sorry for so late answer. 

    We would love to have the nRF54L-series. Unfortunately, according to our information it is not available at the moment and probably will not be in any forseeable future.

    At the moment, we plan to use the nrf52840 and and add another secondary mcu onto the board just to drive the ps/2. 

Related