-
-
Notifications
You must be signed in to change notification settings - Fork 40.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] PS/2 PIO Driver for RP2040 #17893
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! First quick pass over the code, reads nicely 👍 found one soundness issue and we can re-use ChibiOS facilities for the bytes queue.
I think we can unify the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some optimizations in the PIO code may be possible (but I did not try them on any real hardware), and maybe it would be possible to keep the proper open drain behavior of PS/2 pins instead of actively driving them high in some places.
Thank you for your contribution! |
Plan is to finish some suggestions about PIO code |
Hi, thank you for this excellent work! This is an eagerly awaited feature :) My apologies for intruding on this PR, but I've made an attempt to optimize the PIO code as per the reviewer suggestions. I would be happy to share my changes, if it's of interest? It seems to work nicely with my Tex trackpoint in stream mode. Again, I don't mean to encroach anyone's work. If you would like to retain sole ownership of this feature, that is also perfectly fine :) |
Hi @joh , happy to hear that it works good for you! About the changes, I'm open to the improvements, although, down-side is that the QMK PIO source have only pre-compiled version, stripping off all the comments or constants. I plan to release this PS/2 driver as standalone library for pico-sdk, where will be also .pio file, and the compiled version will be re-used here in QMK driver. (So when anyone want to make improvements to QMK PIO code, he can test it and do changes on library version, and then port it over here). So, if we can add your changes to my standalone PS/2 PIO library, then we can get it also over here. |
Great! I also did most of the development and testing first in pico-sdk, before porting it over to QMK. I will be happy to contribute the improvements to your pico-sdk library as well, whenever you're ready :) In the meantime, I'm attaching a patch with my changes here so it can be tested and reviewed for QMK. I don't think multiple people can push to the same PR, so I think the best approach would be if you apply the patch with |
Please find attached patch which ensures
0001-Ensure-pio_rx_buffer-is-aligned-for-32-bit-access.patch.txt |
@gamelaster friendly ping if you want the driver to be merged before 29th of January. Which is this breaking changes cycle closing date. |
@KarlK90 thanks for reminder, I will try to do it within following days. About the PIO rework, I will rather do it from scratch and in my testing repo, I have some nice tests done here, which will help me to assure that all changes doesn't break anything, but I will take inspiration from your patch. Thanks! |
* Use pindirs to keep proper open drain behavior of PS/2. * Invert output enable on PS2_*_PIN so that pindirs works correctly with open-drain interface. * Enable autopull. * Disable sideset, as it's not used. * Optimize PIO code as per suggestions in PR qmk#17893.
Great! For reference, here is a commented version of the PIO code:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expect two minor nits this is good to go in from my side! Thank you.
@gamelaster With the last review in this is good to go. Sorry for the delay and thanks for your work. |
Co-authored-by: Johannes H. Jensen <[email protected]>
Quick question - what's the right values for ps2.clock_pin and ps2.data_pin - e.g., "GP17" and "GP18" only works when the #if is commented out; 17 and 18 as values are not accepted as being not valid by the schema. |
@marfrit does the driver work for you when you comment the #if ? |
@gamelaster I cannot yet find out; plan is to adjust my improvised adaption of the TMK ibmpc converter to use PIO instead; however, that requires soldering for which I don't have much time nowadays. Subsequently, I will need two PS2 interfaces to support the Model M13 and M4. |
@gamelaster please see https://github.com/marfrit/qmk_firmware/tree/pio_ps2_converter/keyboards/converter/pio_ps2_converter as an examle, info.json has
and What am I doing wrong? |
@marfrit as it says, PS/2 Clock pin must be followed by data pin. That means that clock must be GP21 and data ping GP20 |
@gamelaster Hi, "A must be followed by B" does mean in my understanding that A comes first, B comes second. Thank you. |
@marfrit I agree, the order of your pins looks correct: first clock pin (GP20), then data pin (GP21). What is the numerical value of GP20 and GP21 for your board? |
Not sure if this is the right place to ask, but I wonder if it is good to use this driver for PS/2 directly without any level shifter, as the voltage for PS/2 is 5V while RP2040 GPIO pins are technically not 5V tolerant. I tried this with a trackpoint (PTPM754DR) using RP2040 zero pin 14, 15 and PIO1, with 4.7k pull up resistors. It will fail to initialize intermittently, there is a success rate of 40%, but as long as it initialized correctly (the mouse can move) it doesn't have any problem. I tried the exact same circuit with a blackpill stm32f401 without connecting the reset pins and everything works correctly. Do you have any clue why it can fail like this? |
@pca006132 I use it like this on RP2040, and it works properly (via pull-ups). Are you sure you have RESET circuit properly done? |
No, I don't have reset circuit for now as I don't have capacitors at hand. I tried using GP26 to control RST by setting it to input floating, pull up using 4.7k, wait for 1000ms and then change to output low, but it doesn't work and I found that the measured voltage is just 4.0V when I use input floating, which is really weird... |
Oh OK, it seems that GP26 can be used for ADC and have different behavior... other pins work fine. Will try to see if I can make it work reliably. |
@pca006132 I had this kind of undefined behavior when the RESET circuit was not good. If you can, I can send you the circuit which works for me. |
It will be great if you can send me the circuit. Thanks! |
@pca006132 it may work to use 5v to power the trackpoint, but the RP2040's gpios are not 5v tolerant, and it may lead to failure. some trackpoints can be powered by 3.3v, otherwise there's level shifters as you've said. |
@wolfwood Most of times, you don't need level shifters, as most of trackpoints will treat 3V3 still as high. Thus, pull-ups data and clock line to 3V3 is sufficient. |
@gamelaster if 3V3 is sufficient, do we need the pull-ups or can we let the internal pull-ups do it? |
@pca006132 I don't know if it is possible to have pin both as PIO pin and also have pull-up here, according to some articles on internet it seems to be possible, but we have external pull-ups. So, maybe, you need to try. |
About "should work with keyboards": it does - https://github.com/marfrit/qmk_firmware/tree/pio_ps2_converter (with hw not published yet), but can also be created with a Pico dev board and a level shifter. If I wanted to have two PS/2 devices - say a mouse and a keyboard (i.e. https://sharktastica.co.uk/wiki?id=modelm4) - what would be the proper way? |
Co-authored-by: Johannes H. Jensen <[email protected]>
Can anyone enlighten me as to why the clock pin has to follow the data pin in the pinout sequence? |
Implementing the “data_pin = clock_pin + 1” configuration could be possible, but would need a separate revision of the PIO program (or patching the existing PIO code on the fly):
Although maybe it could be possible to use the side-set feature to control one of the pindirs — that could make it possible to use completely arbitrary clock and data pins (the |
Thanks for the clarification! My board is going in for a respin anyway, so
not a huge need here, I can just flip them in the next round, and find an
easier approach with the prior generic ARM implementation for current half
dozen users who are experimenting with this.
…On Sun, Jul 23, 2023 at 3:13 PM Sergey Vlasov ***@***.***> wrote:
Implementing the “data_pin = clock_pin + 1” configuration could be
possible, but would need a separate revision of the PIO program (or
patching the existing PIO code on the fly):
- The set pindirs, … PIO instructions depend on the data and clock
pins being next to each other and in the particular order. Here the 2-bit
data values would need to be changed to swap the bits (and the set
mapping would need to be changed to use the clock pin as the base).
- The wait 0 pin, 1 and wait 1 pin, 1 instructions also depend on
clock_pin = data_pin+1 (data_pin needs to be the first in the in
mapping, so that the in instruction could read it). In this case
something like wait 0 pin, 31 would need to be used (hopefully such
wrapping around would work).
Although maybe it could be possible to use the side-set feature to control
one of the pindirs — that could make it possible to use completely
arbitrary clock and data pins (the wait instructions could use the wait
gpio variant with dynamic code rewriting to put the pin number there;
unfortunately, jmp !pin does not exist). The modifications won't be as
simple as they could be though, because the simplest way would require
allocating 2 bits for the optional side-set data, and those bits would need
to be taken from the “delay” field, therefore specifying a delay of 31
won't be possible. Although if the state of the clock pindir could be
defined as a constant for all instructions, only a single side-set bit
would be needed.
—
Reply to this email directly, view it on GitHub
<#17893 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAGVYM6G4XOWFE7OMYZXYDXRWOYDANCNFSM55ONPW4A>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
note: If you're using this on a split and using PIO0 for split comms, you'll need to |
Description
This PR contains PS/2 PIO Driver for RP2040. It supports both PS/2 Mouse Stream and Remote modes, and it should support PS/2 Keyboard too.
Please, let me know if there are any changes needed in terms of code, comments or documentation. Thanks!
Merge instructions
Types of Changes
Checklist