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

nRF52 softdevice corrupts ps/2 packets

I've been working on using an nRF52 as a host for a PS/2 synaptics touchpad mouse (to integrate with BLE HID).  I was able to get a correct mouse position using two GPIO pins (clock and data) while BLE was disabled.  

Once I turned on BLE, many of my packets were corrupted.  PS/2 is a very slow protocol (25-50 microsecond clock intervals) with a parity bit as its only consistency check.  As it turns out, the softdevice that runs the BLE stack is known for stealing CPU cycles, which seem to be the culprit.

Before I go down a rabbit hole here, I wanted to throw a few questions out:

  • Is there a way to put the BLE to sleep for a few milliseconds while I poll my PS/2 device, then wake it to send the mouse report?  (doesn't seem likely but worth a shot).
  • I'm not using interrupts for detecting the PS/2 clock pin (seemed like overkill at first).  Could this help in my case or would the softdevice still take priority?
  • Are there tweaks I can make to the BLE config or the softdevice to make it less chatty?  I'd assume it should stay quiet until it's time to send data (I'm seeing packet loss just from BLE being enabled. Peered, connected, or advertising. No other data needs to be sent)
  • Is a timeshared chip like nRF52 a bad fit for this project, or am I doing something wrong here? I would love to take advantage of nRF52's unmatched low power consumption.

The board is Adafruit Bluefruit nRF52832 Feather using the Adafruit libraries. 

Parents
  • Is there a way to put the BLE to sleep for a few milliseconds while I poll my PS/2 device, then wake it to send the mouse report?  (doesn't seem likely but worth a shot).

    Yes. You can use the Timeslot API to ask the SD for a few ms without interrupts.

    The PS/2 protocol allows the host to plull the clock line low - inhibiting device communication. This should be done outside the "time slot".

  • So the Adafruit nRF52 Bluefruit Feather board libraries deploys your softdevice and implements some of your basic libraries to control it, but it's definitely missing what I need.  

    I started pulling pieces of the nRF5 15.2 SDK into my project, and I found there is no middle ground.  It looks like I would need to pull nearly everything in the SDK, which I can guarantee would become a problem.  

    Can someone point me to a thread or resource that could help me integrate the libraries (if possible)?  

  • If this isn't possible or would be a large effort, then it seems like I have two possible solutions:

    1. Try implementing my code using interrupts (instead of while loops), and set the priority as high as allowed by the softdevice. This is low effort and might help me bring the packet loss to a correctable level.  
    2. Rebuild my app using the nRF5 SDK directly.  This isn't ideal since I am trying to keep this project at a low effort, but this might by my best option.  
  • I will always recommend our SDKs as we cannot support 3rd party software. We do not have much experience with the Feather framework. If the Feather framework is open sourced then you should be able to use the majority of it as it is most likely based on our SDK. 

Reply Children
  • Thanks!  It looks like the feather isn't supported by the Nordic SDK yet, but I see there is an active effort to add it.  I already designed and prototyped my PCB with the feather's headers, so my second option above will require new hardware (not ideal).  

    The second option is starting to look even better. Feather library seems to support assigning interrupt priorities without modification.  If that doesn't work,  I wanted to try hijacking a TWI interrupt as a Hail Mary.  I'm already using i2c in my design (feather seems to assign TWI1 to it's i2c ports), but TWI0 is open. 

    If I get the failure rate low enough with either of these changes, the user won't notice the dropped frame on the ps/2 device (if a  bit takes too long to read, I can assume the softdevice took over and can throw out the entire packet for instance). 

    If interrupts don't mitigate corrupt packets, I will keep pushing forward with attempting to integrate the SDK with feather's framework, but that's my last resort before buying a new board (unless I stumble upon an example of someone else implementing this successfully)

    I'll keep this thread updated once I find a solution. Either way, I think I'll rewrite my app using the Nordic SDK once my board is supported so I can avoid this pain in the future. 

  • I don't understand why you have to re-design your board? Feather headers or not, it's all the same to the nRF5 SDK. 

  • I didn't see the board definition so I assumed it wasn't supported (it looks like I can create my own custom def though).  

    It looks like I can purchase an SWD programmer and solder to a pad on the back of the board for programming (a considerable effort but would be worth it).  
    devzone.nordicsemi.com/.../can-adafruit-feather-be-programmed-with-nrf51-sdk

  • You can use the nRF52DK as the programmer for external boards. Look up the nRF52DK User Guide for details. 

    You should know that the GPIOs are all fully multiplexed with the exception of the 8 Analog pins. You can assign any GPIO to any peripheral( SPI, UART, GPIOTE, etc.)

    "I didn't see the board definition so I assumed it wasn't supported (it looks like I can create my own custom def though).  " 

    I think you need to define a custom_board.h or something and set the proper Define somewhere

  • You can use the nRF52DK as the programmer for external boards. Look up the nRF52DK User Guide for details. 

    You should know that the GPIOs are all fully multiplexed with the exception of the 8 Analog pins. You can assign any GPIO to any peripheral( SPI, UART, GPIOTE, etc.)

    "I didn't see the board definition so I assumed it wasn't supported (it looks like I can create my own custom def though).  " 

    I think you need to define a custom_board.h or something and set the proper Define somewhere

Related