Re: PIC, Keyboard, and USART




"Abstract Dissonance" <Abstract.Dissonance@xxxxxxxxxxx> wrote in message
news:122k7nhpgjn5r32@xxxxxxxxxxxxxxxxxxxxx

what if the clock is a bit off? Not sure if I want to do asynch yet since
I
have the clock availiable. Seems like one less problem to worry about if
something doesn't work.

and if its not? ;/ lol. Damn I wish I would have kept all those keyboards
that I ruined by spilling crap on them... Could have looked the what chips
they were using and got the data *** on them ;/


regards,
- Jan

Thanks again,
Jon



Hello,

I've done this with both PS2 mice and keyboards on a 16F628. Using the
internal pull-ups and standard I/O ports. Never used the UART as the PS2
standard is weird basically, someone at IBM was having a really bad day.

What I would suggest is that you start from the bottom up by trial and
error. you WILL need to implement procedures for both MASTER>SLAVE and
SLAVE>MASTER communication. Mice for example won't report until you tell
them too, some keyboard's too. Also, kit from different manufacturers works
at slightly different speeds. The way I did it was to poll for input and
then time out after a set period. Doing it this way also allows you to
build in the ability to hot-swap the slave devices by using some conditional
branches and alike. Asking a mouse it's status will tell you if it's been
hot-swapped or not.

Detecting errors with PS2 packets is also a nightmare too, as parity
detection is only right half of the time... In the end I used parity and
also checked for wayyyy-out values, then asking the slave to retransmit
them.

PS2 as a standard is possibly as dreadful as USB. The other alternative
would be to use a decoder chip instead so that plain values are presented to
the MCU and you don't have to worry about PS2 at all.

These are the documents I referred to at the time;
http://www.computer-engineering.org/ps2protocol/ A digital dual trace scope
may also be handy. Basically implement from the ground up bit by bit.

:)

Hope that helps a bit :)

Aly

ps. a snippet for you from some code laying about, don't ask me about it,
long time since the picture was in my head.

; --------------------------------------
; READ A SINGLE BYTE FROM THE PS2 DEVICE
; --------------------------------------
;on exit, byte read contained in ps2_byte_

PS2_RECEIVE_BYTE
CLRF ps2_byte_ ;reset our variable
MOVLW 8 ;8 bits to be read
MOVWF ps2_bits_remaining_
CLRF ps2_calculated_parity_ ;parity will be stored in here
Wait_for_start_bit:
COMF PORTB, W ; wait till CLOCK and DATA are high
ANDLW b'11000000'
BTFSS STATUS,Z
GOTO Wait_for_start_bit
CALL PS2_WAIT_FOR_CLOCK_LOW
BTFSC ps2_control_flags_, PS2_TIMEOUT_
GOTO Ps2_read_byte_timeout
Read_start_bit:
MOVF PORTB, W
ANDLW b'01000000'
MOVWF ps2_start_bit_
CALL PS2_WAIT_FOR_CLOCK_HIGH
BTFSS ps2_start_bit_, 0x06
GOTO Start_bit_good

Start_bit_bad: GOTO Wait_for_start_bit
Start_bit_good:
Read_data_bit: CALL PS2_WAIT_FOR_CLOCK_LOW ;have to wait for it to go high
again

BCF STATUS, C ;we don't want an accident for what we're going to do now
RRF ps2_byte_, F ;rotate one to the right
BTFSS PORTB, PS2_DATA_PORTB_
GOTO Read_data_bit_is_0
Read_data_bit_is_1:
BSF ps2_byte_, 0x07
INCF ps2_calculated_parity_, F
Read_data_bit_is_0:
CALL PS2_WAIT_FOR_CLOCK_HIGH

;if we skipped to here, then it remains a 0
;time to get the next bit now

;we now need to check if we've read 8 bits
;if not, then we do this again
DECFSZ ps2_bits_remaining_, F
GOTO Read_data_bit

;ok, so we're here, that's our byte read
;now it's the parity bit about to come
CALL PS2_WAIT_FOR_CLOCK_LOW

MOVF PORTB, W
ANDLW b'01000000'
MOVWF ps2_parity_bit_

;our parity bit is now on data
;we're going to discard it!!

;now to wait for the end bit
CALL PS2_WAIT_FOR_CLOCK_HIGH

CALL PS2_WAIT_FOR_CLOCK_LOW

MOVF PORTB, W
ANDLW b'01000000'
MOVWF ps2_stop_bit_
;discard it, no action!!

;our byte is now sitting in ps2_byte_
Ps2_read_byte_timeout:
RETURN


.


Loading