PDA

View Full Version : pic as ps/2 keyboard



mischl
- 21st April 2005, 11:11
hello

i want change out a ps/2 keyboard with a pic and searched for informations. has anyone links or informations to the clock speed and the data transmission?

many thanks

NavMicroSystems
- 21st April 2005, 11:40
see:
here (http://www.picbasic.co.uk/forum/showthread.php?t=165)
and
here (http://www.picbasic.co.uk/forum/showthread.php?t=81)

mischl
- 21st April 2005, 13:27
thank you ralph for the reply

what i'm not sure :
- i need no external hardware, or?
- i can realise the software with shiftout?

NavMicroSystems
- 21st April 2005, 13:44
mischl,

this is probably the link (http://www.electronic-engineering.ch/microchip/projects/keyboard/v1xx/keyboard_v1xx.html) you are after

mischl
- 25th May 2005, 09:27
ralph, thanks for the help.

i've looked for many sites and found asm as well bs examples. i read a lot about protocols and test my own code. because i have several problems and i'm a bit confused my question : has anybody else a piece of code which send at-keyboard commands to pc host?

if it is only a piece to test, it would me helps a lot

thanks for a support

JEC
- 25th May 2005, 19:53
I had a PS/2 KB emulator running a few weeks ago. I don't have the code right in front of me, but I wrote it all in PBP.

You can use the SHIFTOUT command with no problems - just tell shiftout to only send 9 bits instead of 16.

Don't forget to calculate the parity bit (odd) and tack it on at the end.

Clock and data both idle high, so make sure you use pullup resistors.

I'll dig around and see if I can find the code later this afternoon.

John

JEC
- 25th May 2005, 20:18
Here's a code snippet to transmit PS/2 data:

In this case, dataout is an array of bytes I may want to send to the computer.

Odd parity is NOT the value of all bits XOR'ed together.

Good luck!

John


* * *
for x = 0 to 7
if dataout[x] <> 0 then
sendthis = dataout[x]
parity = not(sendthis.0 ^^ sendthis.1 ^^ sendthis.2 ^^ sendthis.3 ^^ sendthis.4 ^^ sendthis.5 ^^ sendthis.6 ^^ sendthis.7)
sendthis = sendthis << 1 'move over to insert start bit
sendthis.0 = 0 'start bit
sendthis.9 = parity
sendthis.10 = 1 'stop bit
shiftout kbddata,kbdclk,4,[sendthis\11]
dataout[x] = 0
endif
next x

mischl
- 25th May 2005, 20:59
hello john

thanks for your support.

i work with a similar code. so i have some additional questions :

- which osc speed do you use? - i have a 16f876 with 4M
- have you defined a shift_pauseus? - i try it . around 40us seems best
- how long do you wait until you send the release code (F0) after the button press comand? - i don't wait
- how looks your hardware setup? - 2 transistors at portc with pull up works at best. nod good because i get different chars... when i only take pullups instead the transisitors, after connect the keyboard it wouldn't be initialized.
- what are you doing at the booting from the pc?

best regards

JEC
- 25th May 2005, 21:16
- which osc speed do you use? - i have a 16f876 with 4M

'628 @ 20 MHz

- have you defined a shift_pauseus? - i try it . around 40us seems best

I used 50 uS

- how long do you wait until you send the release code (F0) after the button press comand? - i don't wait

In my particular application, I sent a 'make' code at keydown and a 'break' code at keyup. So the waiting time was up to the buttonpusher.

- how looks your hardware setup? - 2 transistors at portc with pull up works at best. nod good because i get different chars... when i only take pullups instead the transisitors, after connect the keyboard it wouldn't be initialized.

Just a pair of 4K7 pullup resistors on clock and data. The pins on my pic are set to be inputs (high impedence) unless I'm transmitting.

- what are you doing at the booting from the pc?

My project doesn't so far parse all of the boot communication which takes place, because it's only used after Windows has totally started.

I'd started to send copies of the incoming data out to a terminal program so I could see what was being said, but didn't spend much time there due to other projects.

However, one of the documents mentioned earlier in this thread has a fairly detailed description of the commands and responses that will be flying around on a properly configured system.

Sorry I can't help much more.

John

ultiblade
- 10th May 2007, 15:48
I'm trying to simulate (emulate) a ps/2 keyboard from a pic to laptop's ps/2 port. The PIC (12F509) needs to send a few keystrokes to the laptop.

Using a part of JEC's code i got it working, but the output (e.g. what i see on my notepad on my laptop screen does not look like the characters i should be seeing, when i look at various scan code tables.

What am i doing wrong ?

Here's the code :



INCLUDE "modedefs.bas"
DEFINE SHIFT_PAUSEUS 50

'==== Andere test ! ================================================== ==========
parity var word
sendthis vaR word
kbddata var GPIO.0
kbdclk var GPIO.1

start:
high kbddata
high kbdclk

pause 500

sendthis = %11010110 'sending this results in a "y" on screen
gosub calsub

sendthis = %11110000 'This should be 0xF0 the "release code"
gosub calsub
sendthis = %11010110 'For release code
gosub calsub
goto start


calsub

parity = not(sendthis.0 ^^ sendthis.1 ^^ sendthis.2 ^^ sendthis.3 ^^ sendthis.4 ^^ sendthis.5 ^^ sendthis.6 ^^ sendthis.7)

sendthis = sendthis << 1 'move over to insert start bit

sendthis.0 = 1 'start bit 'In JEC's code this was a 0, but that did'nt work

sendthis.9 = parity

sendthis.10 = 0 'stop bit 'In JEC's code this was a 1, but that did'nt work

shiftout kbddata,kbdclk,4,[sendthis\11]

return

goto start



The "y" i got when i was experimenting, other thing i saw was :

11000111 = 3
11000110 = DEL
00010010 = o
11010110 = y
00110010 = F4
11011110 = NUM-LOCK
11110110 = PAGE-UP

What is wrong ???

Best Regards, UB

skimask
- 10th May 2007, 17:02
INCLUDE "modedefs.bas"
DEFINE SHIFT_PAUSEUS 50
parity var word:sendthis var word:kbddata var GPIO.0:kbdclk var GPIO.1
start:
high kbddata:high kbdclk:pause 500:sendthis=$d6:gosub calsub:sendthis=$f0
gosub calsub:sendthis=$d6:gosub calsub:goto start

calsub: <---ADD COLON HERE

parity=not(sendthis.0^^sendthis.1^^sendthis.2^^sen dthis.3^^sendthis.4^^sendthis.5^^sendthis.6^^sendt his.7)
sendthis=sendthis<<1:sendthis.0=1:sendthis.9=parity:sendthis.10=0:shi ftout kbddata,kbdclk,4,[sendthis\11]:return
goto start

mister_e
- 10th May 2007, 19:55
what happen if your change NOT by ~ ?

skimask
- 10th May 2007, 21:34
what happen if your change NOT by ~ ?

Agh! Missed that one! And it was right below my comment!

ultiblade
- 11th May 2007, 07:53
Thanks mister_e & skimask for replying ...

I will try the ~ this morning see what happens.

Thank you !

ultiblade
- 11th May 2007, 10:52
Hi Mister_e & Skimask,

I thought i figured it out:

When googeling if found that the scancode for an "a" = 0x1C = 00011100, the key-scancode has to
be send LSB first resulting in 00111000.



sendthis = %00111000 'LSB first "a"
gosub calsub
sendthis = %00001111 'LSB first 0xF0 'for release key
gosub calsub
sendthis = %00111000 'LSB first "a"
gosub calsub
goto start


calsub:
parity = ~(sendthis.0 ^^ sendthis.1 ^^ sendthis.2 ^^ sendthis.3 ^^ sendthis.4 ^^ sendthis.5 ^^ sendthis.6 ^^ sendthis.7)
sendthis = sendthis << 1 'move over to insert start bit
sendthis.0 = 0 'start bit
sendthis.9 = parity
sendthis.10 = 1 'stop bit
shiftout kbddata,kbdclk,1,[sendthis\11]
return


Then i thought that the problem was the shiftout. I was sure that it had to be LSB first, clock idles high, because the clock is high to low. But a little experiment with setting this to 1 (Shift data out highest bit first. Clock idles low).

Resulted in a perfect "a" on the laptop sceen !!

But however, that was about the only character that i could generate, so i think this is not right also.
Melanie has posted a scancode table, stating that the scancode for an "a" has to be 0x1E

I can send characters, but they don't match any of the scancodes i input ? What is happening here ?

Anyone ?

Best Regards, UB

ultiblade
- 11th May 2007, 14:10
Update:

Ok messed up some of the scancode's. I can now send normal characters
by sending the reversed scancode with shiftout

For example : if i send 0x15 = 00010101, LSB first = 10101000 = "q" on screen, that's perfect. I tried other codes and they work also.

There was an error with the parity calculator also, so i skipped that ....

But now, i want to use Left-shift + q, which, when looking at the scancode
table this would be 0x12 for left shift, 0x15 for "q", 0xF0 for release, 0x15 for release "q" and 0xF0 and 0x12 for release left shift.

Doing this results in an F10 being received ??

Here's the code :


sendthis = %01001000 'left shift
test = 1 'parity bit
gosub calsub

sendthis = %10101000 'q
test = 0
gosub calsub

sendthis = %00001111 'Release
test = 1
gosub calsub

sendthis = %10101000 'q
test = 0
gosub calsub

sendthis = %00001111 'Release
test = 1
gosub calsub

sendthis = %01001000 'left shift
test = 1
gosub calsub

goto start


calsub:
sendthis = sendthis << 1 'move over to insert start bit
sendthis.0 = 0 'start bit
sendthis.9 = test 'parity
sendthis.10 = 1 'stop bit
shiftout kbddata,kbdclk,1,[sendthis\11]
return



Best regards, UB

mister_e
- 11th May 2007, 15:15
not sure but i think you have to send some other code(s) + sendthis as well.

ultiblade
- 11th May 2007, 15:34
Mister_e,

I found some source code in basic stamp, the author claims it works.
Apart from the fact that everything is inverted (he inverts the inputs in his
schematic using transistors) i can't find anything other tahn my code ?



' -----[ Program Description ]----------------------------------------
'
' This simple program shows how to connect a BASIC Stamp II to the AT
' keyboard port on a PC and to send characters when one of three buttons
' is pressed. Please read KEYBTST.TXT for more information about it's
' limitations and for a simple schematic.

' -----[ Constants ]--------------------------------------------------
'
datpin con 0 'Keyboard Data
clkpin con 1 'Keyboard Clock
btn00 con 2 'Button 0
btn01 con 3 'Button 1
btn02 con 4 'Button 2

' -----[ Variables ]--------------------------------------------------
'
temp var B2 'Temp variabel
char var W2 'Variabel containing the character
breakcode var W3 'Variabel containing "Breakcode"
extcode var W4 'Variabel containing "Extended charcode"

' -----[ Initialization ]---------------------------------------------
'

'Set pin 0 and 1 as outputs, rest as inputs
Dirl= %00000011

'Set datpin and clkpin default to high (1)
low datpin
low clkpin

'Define breakcode
' s--DATA--PS (s=start, DATA=LSB First, P=parity, S=stop)
breakcode=%11111000000 '/F0H
'Define extcode
' s--DATA--PS (s=start, DATA=LSB First, P=parity, S=stop)
extcode=%11111100010 '/E0H

' -----[ Main Code ]--------------------------------------------------
'

start:

temp=0
pause 1000
button btn00,0,255,100,temp,1,button00
button btn01,0,255,100,temp,1,button01
button btn02,0,255,100,temp,1,button02

goto start

' -----[ Test Characters ]--------------------------------------------
'
' s--DATA--PS (s=startbit, DATA=LSB First, P=paritybit, S=stopbit)
'char=%10110101110 '/SPACE
'char=%11100011110 '/a
'char=%11010010100 '/CR
'char=%11011001110 '/b
'char=%11100101110 '/t
'char=%10100101100 '/r
'char=%10011101110 '/d
'char=%10101111100 '/F1
'char=%11111000110 '/INS

button00:
'Assign char a character with startbit, parity and stopbit. OBS inverted !
' s--DATA--PS (s=startbit, DATA=LSB First, P=paritybit, S=stopbit)
char=%11100011110 '/a
gosub sendchar
goto start

button01:
'Assign char a character with startbit, parity and stopbit. OBS inverted !
' s--DATA--PS (s=startbit, DATA=LSB First, P=paritybit, S=stopbit)
char=%11010010100 '/CR
gosub sendchar
goto start

button02:
'Assigne char a character with startbit, parity and stopbit. OBS inverted !
' s--DATA--PS (s=startbit, DATA=LSB First, P=paritybit, S=stopbit)
char=%11111000110 '/INS
gosub sendextchar
goto start

' -----[ Subroutines ]------------------------------------------------
'
sendchar
'Send character
shiftout datpin,clkpin,1,[char\11]
'Send breakcode + character
shiftout datpin,clkpin,1,[breakcode\11]
shiftout datpin,clkpin,1,[char\11]
return

sendextchar
'Send extcode + character
shiftout datpin,clkpin,1,[extcode\11]
shiftout datpin,clkpin,1,[char\11]
'Send extcode + breakcode + character
shiftout datpin,clkpin,1,[extcode\11]
shiftout datpin,clkpin,1,[breakcode\11]
shiftout datpin,clkpin,1,[char\11]
return

' -----[ End ]--------------------------------------------------------


Best regards, UB

mister_e
- 11th May 2007, 15:38
YEAH as i thought... it's all there... sequence of char, breakcode and extcode. I knew something was missing.

ultiblade
- 15th May 2007, 08:10
Thanks guys, for thinking this over with me ....

Above code does seem to work !

Best Regards,
UB

mister_e
- 15th May 2007, 16:13
http://www.mister-e.org/Pics/Awesome.gif

T.Jackson
- 15th May 2007, 16:33
Out of interest - I wonder what the requirements would be to get a PC to boot with a PIC attached rather than the actual keyboard. Anyone done this?

mister_e
- 15th May 2007, 16:40
mmm, i would probably suggest to record what's happen on the Keyboard Data line first.. or maybe there's a way to tell the BIOS to skip the Keyboard test... sure someone already done this before.

MAybe it just need to see a logic level. I would guess of pull-up.

skimask
- 15th May 2007, 16:44
mmm, i would probably suggest to record what's happen on the Keyboard Data line first.. or maybe there's a way to tell the BIOS to skip the Keyboard test... sure someone already done this before.

Generally, if you select 'Quick Boot' (or whatever else it might be called), bypass some of the POST checks, in the BIOS, the PC won't check the keyboard except for watching for stuck keys. I just tried it on my new-ish Asus Mobo with a 945 chipset.

Quick Boot disabled - No keyboard (USB or PS/2) - Failed, wouldn't continue booting.
Quick Boot enabled - No keyboard - Passed.
Quick Boot enabled - Keyboard, holding down space bar - Failed, but continued booting.

EDIT: There's usually a couple of settings for 'Halt on Disk/Key errors' that can be turned on/off.

T.Jackson
- 15th May 2007, 16:49
Could be a project of interest. I've read magazine articles suggesting some crude ways to get your PC to boot without a keyboard. One suggested method was to gut an old keyboard, grab the board out and cut everything off except the controller IC then whack it in a box. This never seemed very appealing, so I never attempted it.

mister_e
- 15th May 2007, 16:53
mmm somewhere at the bottom of the page of this link
http://www.computer-engineering.org/ps2keyboard/

they say

Initialization:

The following is the communication between my computer and keyboard when it boots-up. I beleive the first three commands were initiated by the keyboad controller, the next command (which enables Num lock LED) was sent by the BIOS, then the rest of the commands were sent my the OS (Win98SE). Remember, these results are specific to my computer, but it should give you a general idea as to what happens at startup.

Keyboard: AA Self-test passed ;Keyboard controller init
Host: ED Set/Reset Status Indicators
Keyboard: FA Acknowledge
Host: 00 Turn off all LEDs
Keyboard: FA Acknowledge
Host: F2 Read ID
Keyboard: FA Acknowledge
Keyboard: AB First byte of ID
Host: ED Set/Reset Status Indicators ;BIOS init
Keyboard: FA Acknowledge
Host: 02 Turn on Num Lock LED
Keyboard: FA Acknowledge
Host: F3 Set Typematic Rate/Delay ;Windows init
Keyboard: FA Acknowledge
Host: 20 500 ms / 30.0 reports/sec
Keyboard: FA Acknowledge
Host: F4 Enable
Keyboard: FA Acknowledge
Host: F3 Set Typematic Rate/delay
Keyboard: FA Acknowledge
Host: 00 250 ms / 30.0 reports/sec
Keyboard: FA Acknowledge


not sure if it's all true AND OR outdated.