trouble with synchronous serial receive
Hi all,
I'm attempting to make a basic keyboard code reader for the PS/2 click, and running into an issue. The protocol looks like this: https://www.researchgate.net/figure/PS-2-protocol-involved-in-the-keyboard-to-computer-communication_fig7_220848551 A clock signal is usually high, and pulses low when data is available. 11 bits are used: 1 start, 8 data, 1 parity, 1 stop. At first I was manually checking the pin values but I was told about the synchronous serial receive smart pin option which sounded like a more intelligent way to do things.
From the propeller manual, "When a word is received, IN is raised and the data can then be read via RDPIN/RQPIN." My problem is, IN is always 1, if I'm understanding how to read it correctly.
A snipped of code here:
CON PIN_KEY = 32 ' keyboard data input PIN_CLK = 33 ' keyboard clock input _CLKFREQ = 250_000_000 VAR hitKey ' what key is currently hit PUB Start()|startTime,tempk,deltaTime PinFloat(PIN_KEY) PinFloat(PIN_CLK) WRPin(%0000_1001_000_0000000000000_00_11101_0,PIN_KEY) ' synchronous serial receive on PIN_KEY, with inverted clock on PIN_KEY+1 WXPin(%11010,PIN_KEY) ' read 11 bits of data coincident with clock edge hitKey := 0 startTime := getms() repeat repeat ' use synchronous serial receive to grab bits off the pin, if available. if PinRead(PIN_KEY) == 1 ' there's data waiting tempk := RDPin(PIN_KEY) if tempk <> 0 hitKey := 1 deltaTime := getms()-startTime while deltaTime < 50 'do something with hitKey here
My understanding is PinRead is used as a flag in smart pin mode to say that data has been received. However, it appears to always be 1, whether or not I'm typing on the keyboard. I tried inverting the clock signal, but that didn't have an effect. Is there something else I'm missing (not setting something right, some other command, etc), or is my understanding of this smart pin method incorrect?
Comments
Do you have a pullup resistor fitted on your clock and data pins? Most PS/2 devices are open collector output IIRC.
Better PS/2 info is here :
http://www.hardwarebook.info/AT_Keyboard/Mouse_protocol
PS/2 is a bit more complicated than a simple synchronous serial, as both the clock and data pins are bidirectional, and I guess you want to support LED controls ?
LEDs are often used for power-up and user check the keyboard is connected and alive.
@kwagner If you use three back-ticks (on ~ key) above and below your code, you don't have to add the dots (which make it difficult for those wanting to copy-and-paste your snippets)
There is a P1 object in the standard Propeller library called keyboard.spin that Chip wrote many years ago -- it might be a place to start.
Here is a 1-pin keyboard driver. I use the PS2 Keyboard as a serial receive only. Note the baud has to be determined as PS2 keyboards vary the speed - probably a cheap RC oscillator version keyboard chip.
https://forums.parallax.com/discussion/120422/debug-to-tv-using-1-pintv-option-1-pinkbd-minimal-footprint-screen-buf-overl
Thanks all. I'll try to address one at a time:
For this specific project, I only care about receipt. I don't need to set LEDs and I can assume the keyboard is present. Hopefully that makes things easier.
Thanks! I tried a few different methods, but couldn't get it right. When I used the "code" option from the dropdown above the comment box, it only used two back-ticks and put the cursor in the middle of them. I couldn't figure out the right way to format it from that, so I did the blockquote instead (which of course trimmed whitespace). Fixed now.
Thanks! I'll take a look.
I'll check this out as well. All the keyboards should be the same for this project, so I would hope they all use the same speed. I wasn't sure if a given keyboard had a consistent baudrate since the clock only goes out when a key is pressed/released. I suppose it would be possible to do like how the old DOS games calibrated joysticks on startup, have the user press a key and sample the clock speed from that.
So Chip's code looks like what I was doing originally (which makes sense as it's for a P1):
Since that seemed to work before, I'll stick with that logic to continue with my project, and revisit it later when I understand smart pins more
I tested a number of keyboards, some were just PS2 and some were USB with PS2 support. It was necessary to have 10K pull-ups (5V, not sure if 3V3 will work) and a series resistor (value from standard P1 schematic - 180R???).
The speed varied considerably between keyboards - way more than the spec said!!!
I could tune easily by sending a space char from the keyboard. Standard async serial works IIRC.
Checkout the code. It’s quite simple.
Interesting. I haven't added any resistors yet, maybe it's the click or the keyboard is just lucky in that regard?
Here's the code that I have working. I gave it its own cog and it seems to behave itself:
You need the 10K pullups !!!
If I'm reading this schematic right, the PS/2 click has 1K pullups built in:
https://download.mikroe.com/documents/add-on-boards/click/ps2/ps2-click-manual-v100.pdf
Is that sufficient?
That should suffice.
It would be nice if there was a bit more resistance to not load the P2 with 5V so much, but I think the protection diodes would take it. My own rule of thumb from the P1 days is not to put more than 0.5mA through them so I'd choose around 2k2 but 1k should still work.
[doh! posted in wrong topic]