Using 08M2 for PS2 Keyboard

DocZaf

Member
I want to use the PicAxe 08M2 device as a PS2 keyboard driver.
But I note that kbin and keyin are not supported on this device (Its flags up both keywords as an error in PE6 editor (command not supported on this device)).

How should I proceed in order to use the 08M2 for this purpose?

I can not be sure, but I guess the obvious solution is bit-banging...
Is that the correct route?
 

AllyCat

Senior Member
Hi,

As I understand it, PS2 uses a "high speed" protocol which cannot be bit-banged by PICaxe Basic commands. At one time, there were keyboards that operated with dual modes of PS2 and the original PC serial ("RS232" COM port) protocols, but I don't know if they are still available.

But this is probably a case where an upgrade to a 14M2 is necessary.

Cheers, Alan.
 

DocZaf

Member
Hi Alan,

Thank you, that is a bit disappointing to discover, because I had thought that the old 08 dip8 chip was capable of this, and the new 08M2 is even more powerful so it would work with the new one too...
 

erco

Senior Member
OTOH the 14M2, 18M2 and 20M2 work well to read PS2 keyboards, as listed in their datasheets. The 08M2 does not list this feature, but if it's any consolation it alone has Happy Birthday, Jingle Bells and 2 more tunes hard-coded inside. :)


 
Last edited:

DocZaf

Member
Thank you papaof2 and erco for your help too.

It looks like I'll just have to get a 14M2 as recommended and save myself from a lot of bit-banging at the same time.

Love that robot arm too!
 

AllyCat

Senior Member
Hi,

@hippy may have some definitive "inside information" but it looks to me as if "conventional" bit banging is not possible. Google produced a specification HERE which I've heavily edited below, with a few details highlighted:

Communication: Device-to-Host :
The PS/2 mouse and keyboard implement a bidirectional synchronous serial protocol. The bus is "idle" when both lines are high (open-collector). This is the only state where the keyboard/mouse is allowed begin transmitting data. The host [i.e. the PICaxe] has ultimate control over the bus and may inhibit communication at any time by pulling the Clock line low. The device always generates the clock signal. .. the keyboard and mouse use a serial protocol with 11-bit frames. These bits are:
1 start bit. This is always 0.
8 data bits, least significant bit first.
1 parity bit (odd parity).
1 stop bit. This is always 1.
The keyboard/mouse writes a bit on the Data line when Clock is high, and it is read by the host when Clock is low.
The clock frequency must be in the range 10 - 16.7 kHz. This means clock must be high for 30 - 50 microseconds and low for 30 - 50 microseconds.. .... the host may inhibit communication at any time by pulling the Clock line low for at least 100 microseconds. If a transmission is inhibited before the 11th clock pulse, the device must abort the current transmission and prepare to re-transmit the current "chunk" of data when host releases Clock. A "chunk" of data could be a make code, break code, device ID, mouse movement packet, etc. For example, if a keyboard is interrupted while sending the second byte of a two-byte break code, it will need to re-transmit both bytes of that break code, not just the one that was interrupted. ....if new data is created that needs to be transmitted, it will have to be buffered until the host releases Clock. Keyboards have a 16-byte buffer for this purpose.


The device (keyboard) generating the clock and the 11-bit frame are potential "issues" and 30us is shorter than any PICaxe (M2) instruction execution time, even at SETFREQ 32 MHz. However, the parity bit and "re-transmit" capability might help. IMHO the only possibility is a "Polling List" of the form: b1 = pinsC : b2 = pinsC : etc, (or in practice a list of about 20 x @bptrinc = pinsC ). That might be "Post-Processed" to decode a single character, but multiple characters and/or sending commands to the keyboard is probably impossible. Also, I don't believe there is a way to start the polling list, without sometimes "missing" the first data bit (let alone the Start bit), unless the keyboard can be assumed to transmit a byte from its buffer immediately after the clock line is released by the host PICaxe (i.e. low to high edge).

However, it might be possible to use the HSERIN Hardware (NOT the PICaxe HSERIN command) to receive one byte (or maybe two bytes consecutively), but it needs relatively "Advanced" programming: The Start pulse is of the correct polarity (negative-going) for the base PIC UART, and a POKESFR command can set up a Parity Bit mode (and two "Stop" Bits if required) to receive the 11-bit Frame. So there is a reasonable chance of receiving also a second byte (the total hardware buffer is only 2 bytes). But the clock waveform is not being monitored, so this assumes that the bit-period is "known" and constant. This would require a teach/learning stage (e.g. of a known character sequence) before reliable data can be received. Since the reception would be a "background" (chip hardware) task, it may be possible to manipulate the clock line to achieve data-repeats (from the keyboard buffer) if necessary.

Cheers, Alan.
 

hippy

Technical Support
Staff member
@hippy may have some definitive "inside information" but it looks to me as if "conventional" bit banging is not possible.
That would be my conclusion. It's the microsecond timings required which almost certainly puts it beyond the abilities of a PICAXE to bit-bang.

There might be some clever ways to do it but there are probably issues which will get in the way. There's nothing as simple or as easy as using a PICAXE which does support PS/2 keyboard.

If Microchip have made one chip but in different sizes it could have been possible to include all functionality across the entire range of PICAXE devices but unfortunately that's not the case. Smaller chips have fewer capabilities while larger chips have more. Though the 08M2 does provide a lot it doesn't support everything the larger PICAXE do.
 

DocZaf

Member
Hi AllyCat and Hippy,

Thank you both for sharing your knowledge and guiding us beginners who usually have lots of questions, because answering one question raises twice as many ore lol

I had read the kbin and keyin command pages on the website, and In the kbin command page (https://picaxe.com/basic-commands/advanced-io-interfacing/kbin/)

It stated the following:
Effect of Increased Clock Speed
This command will automatically use the internal 4MHz resonator for correct operation.

This made me think I could get away with using an 08M2 at 32Mhz and drop down to 4Mhz during any communication procedures (with the ps2 device), Its all conjecture really since I'm new-ish (returning after about 10 yrs due to being busy all the time).

And the info which Allycat pointed out, I'd come across that in my search for more info.
These are the two best (for me) internet pages which i came across that I was using to understand everything about communicating with a PS2 keyboard



This is how far I had got before I stopped and looked at the 14M2 instead of the 08M2

The attached program file kind of shows the route I was taking...
Maybe my code will give you a laugh, because its non standard, but I just tend to put it down as I think and iron out issues later.
I'm sure it can be improved/optimised lots (and bugfixed lots too!), and i'm not even sure if it (the code) would logically work.....
But I like to keep busy and it helps stop my grey matter from conking out lol

Its not finished, since I wanted to support most of the ps2 keyboard keys rather than just the common ones.
But as things stand, and heeding the advice of experienced members, it looks like I will need to start afresh and use the 14M2 ...
 

Attachments

hippy

Technical Support
Staff member
This command will automatically use the internal 4MHz resonator for correct operation.

This made me think I could get away with using an 08M2 at 32Mhz and drop down to 4Mhz during any communication procedures (with the ps2 device),
Unfortunately not. The keyboard code is written in native assembler so runs incredibly quickly, which is what allows it to interact with a PS/2 device. That code was written with 4MHz operation in mind so, rather than have to provide versions for all possible clock speeds it temporarily changes the clock speed to 4Mz while it runs, then back again afterwards.

I haven't studied your code but it looks like it's the sort of approach to bit-banging PS/2 which would probably work if it could be executed quickly enough or the PS/2 interface were slower. Even at 32MHz it's likely not going to run fast enough to keep things correct.
 

AllyCat

Senior Member
Hi,
Code:
    setfreq m4
    SETINT OFF
    '
    '-> Process interruption
    Select Case bIntBit
        'Start Bit
        Case 0
            Gosub RxBit
            bIntBit = bIntBit + 1
        'Data Bits
        Case 1 To 8
            GoSUb RxBit
            If bRxBit = 1 Then
                Select Case bIntBit
                    Case 1
                        bRxByte = bRxByte AND _BIT0_MASK
                    Case 2
                        bRxByte = bRxByte AND _BIT1_MASK
                    Case 3
                        bRxByte = bRxByte AND _BIT2_MASK
                    Case 4
                        bRxByte = bRxByte AND _BIT3_MASK
                    case 5
                        bRxByte = bRxByte AND _BIT4_MASK
                    Case 6
                        bRxByte = bRxByte AND _BIT5_MASK
                    Case 7
                        bRxByte = bRxByte AND _BIT6_MASK
                    Case 8
                        bRxByte = bRxByte AND _BIT7_MASK
                End Select
            End If
            bIntBit = bIntBit + 1
        '-> Parity Bit
        Case 9
            Gosub RxBit
            'We will ignore this for now because we dont know if the 08M2 is fast enough
            bIntBit = bIntBit + 1
        '-> Stop Bit
        Case 10
            Gosub RxBit
            bIntBit = bIntBit + 1
        '-> FInished
        Case 11
            '-> Note - At this point the byte that was read in can be found in variable bRxByte
            'if first byte is $E0 (224) or $F0 (240) then this ia a break code
            If bRxByte = 240 Then
                bIntBit = 0
            ElseIf bRxByte = 224 Then
                bIntBit = 0
        Else
                bScanCode = bRxByte
                Gosub DecodeScanCode
                'The inputted scancode is in bAsciByte now in asci format
                bIntBit = 0
            End If
            '
    End Select
You need to appreciate that PICaxe Basic is an Interpreted Language, where the Bit Banging operations (in particular) such as HIGH... , LOW.. IF pin THEN... run about 400 - 600 times slower than native assembler, so multiplying the clock by 8 is not going to help much. Some of the higher level operations can be even worse, for example a CALL ... RETURN (and I believe an interrupt) takes over 3 ms (@4MHz) and the CASE ... SELECT structure is converted to a linear sequence of IF .. THENs so can take many milliseconds. To be honest, I'm not sure if the code structure above could run fast enough even in a Compiled Language.

To me the real "killer" is if you want to send commands to the keyboard, because the Keyboard generates the clock sequence. The "base PIC "SPI hardware might be accessed in the 08M2, but the problem is that the PS2 protocol has at least a 9-bit frame (+Start and Stop bits) but AFAIK the hardware works only with bytes. My assumption was that sending commands to the keyboard was only a "nice to have" to switch the LEDs on/off, and even that is probably impossible in PICaxe Basic (except with the KBLED or KEYLED commands).

If receive-only operation is acceptable, then I suspect that the PS2 keyboard clock might actually be sufficiently predictable/constant (perhaps 80us period) so that the base PIC hardware UART could be used. But we're still talking in terms of highly "Hand-Crafted" code (PEEKSFR , POKESFR and perhaps ON .. GOTO ..), not any forms of High Level coding.

Cheers, Alan.
 

oracacle

Senior Member
This thread reminds of one of Ben Eaters' videos on using a PS2 kayboard with a 6502 computer.
He uses an RC filter and schmitt trigger to build a serial to parrallel buffer (the 08 doesn't ahve the pins for that). I think if you could find or build some sort of hardware serial buffer that the 08M2 can read when its ready could work. But there are things that need to be taken into account that I am not sure if the picaxe would be fast enough to deal with it in software. The problem is all the extra hardware, so you just as well use a larger picaxe.

There are are 3 11bit frames, one for press, one that says it was released and another of the button that was replaced, maybe just ingnore tha first 2 frames using the RC filter and schmitt trigger to work out which frame it is.

@AllyCat do you know how low it takes to leave a do...loop?
I was thinking that if you had a loop that just loops while the clock pin was low/high then exits as soon as it goes, do that 11 times,

Code:
do
loop while key_clock = 0

bit0 = key_data

do
loop while key_clock = 0

bit1 = key_data
...
Keyboard interface hardware - YouTube
 

AllyCat

Senior Member
Hi,
@AllyCat[/USER] do you know how low it takes to leave a do...loop?
A (conditional) DO : LOOP is basically : dolabel: IF {pin condition} THEN GOTO dolabel which takes around 1200 "base PIC" Instruction Cycles, or 1.2 ms @ 4 MHz or 150 us @ 32 MHz. If we are "unlucky" and the pin changes just after it is tested, then there will be at least a 150 us delay, plus the "fall through" time and the instruction decode of the subsequent instruction(s) before anything else can happen.

But the clock period could be 60 us (or optimistically 80 us if the PS2 is at its nominal value) so the code could "lose" at least the first two clock cycles after the leading edge of the Start bit. That's why I wasn't optimistic that one could even post-process the linear code list : DO : LOOP WHILE datapin = 1 : @bptrinc = pinsC : @bptrinc = pinsC : etc. (at least 20 times). The post-processing would need to work through around 15 samples of the Data and Clock pins (i.e. less than two samples per clock period) to attempt to identify the Stop bit and work backwards through the 9 relevant Data bits (with only the one parity bit to help) for each byte.

Even after writing "fast" PICaxe code for around 10 years now, it's not something that I would want to attempt, particularly when the price of a 14M2 is only around 20% more than an 08M2 and about another 0.1 square inch (60 mm2) of PCB space.

Cheers, Alan.
 

oracacle

Senior Member
That is my thought as well, why jump through hoops when the difference in cost and PCB real estate is so little.

Its funny how the perception of "fast" is so different. For some, its the operations for cycle, for others its the how much it appear to be doing at any one time. Both come with their own challanges.
 

westaust55

Moderator
The 08 did not have a keyboard interface. To my knowledge, that was available in the 18X.
Ye that is correct, in the earlier chips the 18A and hen the 18X had the kbin command. Never the 8 or 14 pin chips.
Snip from earlier 2004 PICAXE Manual Part 2:
KeyIn - Older chips.png
 

DocZaf

Member
@hippy - I had never even thought about that, that its written in native assembler...

@alleycat - as much as 400 to 600 slower wow, that helps explain lots...

@oracacle - yes you're right, its much easier to simply upgrade the mcu...

@westaust55 - I don't know what made think the 08 supported keyboard commands, it has been about 10 yrs since I last visited the PicAxe microcontroller and simply got confused (happens with old age lol)...

Well Thank you all for taking the time to explain so nicely...
And Merry Christmas to you all!!
 
Top