Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsElectronicsBasicsRepairDesignCADComponentsEquipmentElectrical Engineering
ElectronicsKB.com
Contact UsLink To UsSearch & Site Map

Electronics Forum / Basics / March 2006



Tip: Looking for answers? Try searching our database.

PIC, Keyboard, and USART

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Abstract Dissonance - 23 Mar 2006 18:38 GMT
I'm going to try to program a simple keyboard translator using the PIC2455
which has a built in EUSART.  At this point I just want to get the keyboard
codes into the pic and I just want to run this by you guys to make sure I'm
on the right track.

1. Setup hardware. Basicaly just have to connect the Data and Clock lines to
the EUSART pins on the pic
2. Enable the USART on the pic for Asynchronous mode and enable auto baud
rate dection(to make it easy).
3. Read the RCREG in the interrupt and do whatever with it(like make an LED
blink on certain codes).

Is that basicaly all I have to do?  Do I need to use pullups or anything
when connecting the lines or even use transistors to source/sink more
current?

(I'm running the keyboard off a 5V supply that can source up to .5mA or so)

Any potential pitfalls with this?

Thanks,
Jon
Jonathan Kirwan - 23 Mar 2006 18:41 GMT
>I'm going to try to program a simple keyboard translator using the PIC2455
>which has a built in EUSART.  At this point I just want to get the keyboard
>codes into the pic and I just want to run this by you guys to make sure I'm
>on the right track.

Are you talking about a PC keyboard?

><snip>
>Is that basicaly all I have to do?  Do I need to use pullups or anything
>when connecting the lines or even use transistors to source/sink more
>current?

Is this a PC keyboard?

>(I'm running the keyboard off a 5V supply that can source up to .5mA or so)

1/2 an mA???

>Any potential pitfalls with this?

Could be.  Is this a PC keyboard and are you really supplying it with
at most half a milliamp??

Jon
Abstract Dissonance - 23 Mar 2006 21:51 GMT
>>I'm going to try to program a simple keyboard translator using the PIC2455
>>which has a built in EUSART.  At this point I just want to get the
[quoted text clipped - 4 lines]
>
> Are you talking about a PC keyboard?

Yes, Ofcourse... isn't it obvious? ;)
>><snip>
>>Is that basicaly all I have to do?  Do I need to use pullups or anything
[quoted text clipped - 7 lines]
>
> 1/2 an mA???

Ofcourse not!!! .5A ;)

>>Any potential pitfalls with this?
>
> Could be.  Is this a PC keyboard and are you really supplying it with
> at most half a milliamp??
>
> Jon

Jon
Jonathan Kirwan - 23 Mar 2006 22:23 GMT
I assume that you are talking about PC/AT keyboards here (or simply
known as "AT keyboards.")  I think the original PC keyboard was
incompatible with the AT keyboard, but that all clones since that
advent are now following the AT keyboard arrangement and I doubt you
could even find a PC (non-AT) keyboard these days.  Of course, I have
long since forgotten, for sure.  Do check on what I'm saying.

Regarding AT keyboards, there is a very detailed electrical spec of
the hardware to be found in the IBM Technical Reference, Personal
Computer AT set (4 volume set, which I will protect with my life!)
That spec is the schematic itself, on page 17 of 22.  They use '07
open-collector drivers tied to an RC filter, with 10k and 47pF.

             +5
             |
             /
             \ 10k
             /
             |
     |\      |
>----| >-----+--------------+---O   (either connector pin 1 or 2)
     |/      |              |
             |              |
            ---             |
            ---             |
             | 47pF         |
             |              |
            ---             |
            ///             |
                            |
                            |
<---------------------------'

That spells out the exact details of both pin 1 and pin 2.  You should
be able to note that the IBM PC can use either line is input or
output.  There is a reason for that design.  If you intend to operate
the keyboard correctly, you will need to mimic it.

You will _also_ need to fully understand how the keyboard is properly
operated from the PC.  It is discussed on pages 1-31 to 1-44 and all
of chapter 4 of that Technical Reference I mentioned.  But in
particular there is the capability to observe aborts in transmission
and to deal with conflicts in securing the interface from one side or
the other.

I think that the technical details on the AT keyboard were fairly well
considered by IBM before laying them out and the proper operation of
the interface isn't entirely trivial, if you plan to get it right.
There are very specific timing issues you need to be aware of.  Have
you searched the web for all this info?  You should be aware of
something called the "BAT" and the power up exchanges, graceful
operation in the face of communication aborts, how to deal with
moments when both you and the keyboard decide to talk to each other,
etc.

Jon
Abstract Dissonance - 23 Mar 2006 22:48 GMT
>I assume that you are talking about PC/AT keyboards here (or simply
> known as "AT keyboards.")  I think the original PC keyboard was
[quoted text clipped - 8 lines]
> That spec is the schematic itself, on page 17 of 22.  They use '07
> open-collector drivers tied to an RC filter, with 10k and 47pF.

Sheesh... that would be helpful to have. I wonder if one can download these
online now?

>              +5
>              |
[quoted text clipped - 20 lines]
> output.  There is a reason for that design.  If you intend to operate
> the keyboard correctly, you will need to mimic it.

What is pin 1 and pin 2? The pins from the connectors? i.e., Data and Clock?
Is that an inverter(buffer I guess)?   (i.e. a bidirection link with a
pullup and LP filter?)

> You will _also_ need to fully understand how the keyboard is properly
> operated from the PC.  It is discussed on pages 1-31 to 1-44 and all
[quoted text clipped - 12 lines]
> moments when both you and the keyboard decide to talk to each other,
> etc.

What I have found on the net is not completely technical but just what
someone says works.  Although they did point out certain issues they do not
go into the details.

> Jon

Thanks for the info.  Its good to know there are technical specifications
out there for this... now I just have to get my hands on it.

Thanks again,
Jon
Jonathan Kirwan - 23 Mar 2006 22:56 GMT
>>I assume that you are talking about PC/AT keyboards here (or simply
>> known as "AT keyboards.")  I think the original PC keyboard was
[quoted text clipped - 11 lines]
>Sheesh... that would be helpful to have. I wonder if one can download these
>online now?

Not that I'm aware of.  I would suppose that IBM still holds the
copyright to it -- it's not _that_ old, yet.  I'd be happy to scan
them in and post them up, if permission to do so could be found.  It's
irreplaceable.  The set also includes _complete_ BIOS listings, as
well.  It's fairly complete, as I said.

>>              +5
>>              |
[quoted text clipped - 24 lines]
>Is that an inverter(buffer I guess)?   (i.e. a bidirection link with a
>pullup and LP filter?)

As I understand the connector from the schematic (no, I haven't done
keyboard experimentation on my own, so this isn't first hand), the
5-pin round DIN connector has pin 1 as clock and pin 2 as data.  3 is
no-connect, 4 is GND, and 5 is the +5 supply.

>> You will _also_ need to fully understand how the keyboard is properly
>> operated from the PC.  It is discussed on pages 1-31 to 1-44 and all
[quoted text clipped - 16 lines]
>someone says works.  Although they did point out certain issues they do not
>go into the details.

Bad news.

>Thanks for the info.  Its good to know there are technical specifications
>out there for this... now I just have to get my hands on it.

Yes.  It should be available somewhere.  I've not looked around.  But
it should be out on the net, I'd hope.

Jon
Jonathan Kirwan - 23 Mar 2006 23:15 GMT
On Thu, 23 Mar 2006 21:56:06 GMT, I wrote:

><snip>
>>What is pin 1 and pin 2? The pins from the connectors? i.e., Data and Clock?
[quoted text clipped - 6 lines]
>no-connect, 4 is GND, and 5 is the +5 supply.
><snip>

By the way, I'm not talking about USB keyboards.  And I think the PS/2
keyboard connectors (which didn't exist when IBM was putting out that
doc set) are 6-pin, not 5.  But the mapping should be findable on the
web.  It's probably quite simple.  (I have PS/2 to AT connector
adapter plugs that I'm pretty sure just route lines.)  It's slightly
possible that the PS/2 keyboards have added to the specifications for
the older DIN 5 connector types, adding more protocols.

The older DIN-5 connector only used 4 conductors.  Two power and two
signal.  I have a weird USB-looking to PS/2-looking connector adapter
that shows a mouse symbol embossed on the PS/2 end.  No idea what it
does, but it looks like it adapts something with a USB connector on it
so that it plugs into a PS/2 mouse adapter hole on a IBM PC/AT system.
So this makes me wonder about USB mice that can actually plug into a
plug normally designed for PS/2 mice.  If so, I'm baffled as it seems
to suggest that USB might have been originally designed as an
electrically compatible, but software incompatible, interface.  If so,
then it would be possible for a mouse with a USB connector on it to be
plugged into a PS/2 mouse port and to auto-detect which it is talking
with and switch protocols.  So now I'm curious about that and
interested in looking much more closely at the USB electrical spec.

Jon
Abstract Dissonance - 24 Mar 2006 00:43 GMT
> On Thu, 23 Mar 2006 21:56:06 GMT, I wrote:
>
[quoted text clipped - 17 lines]
> possible that the PS/2 keyboards have added to the specifications for
> the older DIN 5 connector types, adding more protocols.

yeah, the USB uses a HID protocol for keyboards.... something entirely
different I guess. I've downloaded the specs but haven't been over them yet.

The 5 and 6 pin connectors are compatible but the order is different.  The
web site I have gave me the order but I'm not sure if it corresponds to what
you have.

> The older DIN-5 connector only used 4 conductors.  Two power and two
> signal.  I have a weird USB-looking to PS/2-looking connector adapter
[quoted text clipped - 9 lines]
> with and switch protocols.  So now I'm curious about that and
> interested in looking much more closely at the USB electrical spec.

Could it be possible that there is some translation circuitry inside the
connector?  There is a difference in being that the USB uses a differential
pair for data transmission so its not possible for a rewiring?

> Jon

Thanks,
Jon
Abstract Dissonance - 24 Mar 2006 00:48 GMT
>>>I assume that you are talking about PC/AT keyboards here (or simply
>>> known as "AT keyboards.")  I think the original PC keyboard was
[quoted text clipped - 18 lines]
> irreplaceable.  The set also includes _complete_ BIOS listings, as
> well.  It's fairly complete, as I said.

Unfortunately that sucks... Its hard to find good documentation these days
for some reason and I'm sure that the reference would be something that
would come in handy.

>>>              +5
>>>              |
[quoted text clipped - 30 lines]
> 5-pin round DIN connector has pin 1 as clock and pin 2 as data.  3 is
> no-connect, 4 is GND, and 5 is the +5 supply.

hmm.. on the website I have looked at:

http://www.computer-engineering.org/ps2protocol/

there numbering is completely different ;/

oops... hehe... I am using the 6-pin DIN.  So I guess it is what you are
saying.

>>> You will _also_ need to fully understand how the keyboard is properly
>>> operated from the PC.  It is discussed on pages 1-31 to 1-44 and all
[quoted text clipped - 19 lines]
>
> Bad news.

Well, I guess I would have to look up the datasheet for the controller
used(the 8051 or something like that?) to really know whats going on?

>>Thanks for the info.  Its good to know there are technical specifications
>>out there for this... now I just have to get my hands on it.
>
> Yes.  It should be available somewhere.  I've not looked around.  But
> it should be out on the net, I'd hope.

Yeah... the problem nowdays is wading through all the crap sites... its on
my nerves sometimes.

> Jon

Thanks Again,
Jon
David L. Jones - 23 Mar 2006 22:16 GMT
> I'm going to try to program a simple keyboard translator using the PIC2455
> which has a built in EUSART.  At this point I just want to get the keyboard
[quoted text clipped - 5 lines]
> 2. Enable the USART on the pic for Asynchronous mode and enable auto baud
> rate dection(to make it easy).

No. You will need *synchronous* slave mode which uses the external
clock from the keyboard.

> 3. Read the RCREG in the interrupt and do whatever with it(like make an LED
> blink on certain codes).
>
> Is that basicaly all I have to do?  Do I need to use pullups or anything
> when connecting the lines or even use transistors to source/sink more
> current?

Yes, use pullup resistors.

> (I'm running the keyboard off a 5V supply that can source up to .5mA or so)

The keyboard takes a lot more than 0.5mA!

Dave :)
Abstract Dissonance - 23 Mar 2006 22:50 GMT
>> I'm going to try to program a simple keyboard translator using the
>> PIC2455
[quoted text clipped - 12 lines]
> No. You will need *synchronous* slave mode which uses the external
> clock from the keyboard.

Why is this? Wouldn't the auto baud rate detect and interrupts work? I will
look at it though and see... I'm not to familiar with the different methods.
I was thinking that each time the clock pulsed it would trigger an interrupt
and you could read the data off the data line and store it... or something
like that.

>> 3. Read the RCREG in the interrupt and do whatever with it(like make an
>> LED
[quoted text clipped - 10 lines]
>
> The keyboard takes a lot more than 0.5mA!

Sure ;)

> Dave :)

Thanks,
Jon
David L. Jones - 24 Mar 2006 01:21 GMT
> >> I'm going to try to program a simple keyboard translator using the
> >> PIC2455
[quoted text clipped - 18 lines]
> and you could read the data off the data line and store it... or something
> like that.

For starters, you said you were going to hook the CLK line from the
keyboard up to the TX pin of the USART. If you use asynchronous mode
then the TX pin will be an output, you can't feed a clock input into an
output pin!

You have 3 options:
1) Connect Keyboard DATA to RX and Keyboard CLK to TX *and* use
synchronous slave mode. This should work although I have never done it
myself. The USART baud rate will use external CLK from the keyboard.
You *cannot* connect the CLK line and use asynchronous mode, that's not
the way asynchronous works.

2) Connect Keyboard DATA to RX only and forget the CLK line. Use
asynchronous mode and let the USART module detect the baud rate. This
may not work, the keyboard is not a set frequency and may not have a
defined start bit (I can't remember exactly).

3) Connect the Keyboard DATA and CLK lines to normal I/O pins on the
PIC. You can then interrupt off the CLK line falling edge (if you want
to use interrupts). Then just decode in software. When the CLK line
goes low you call a function which reads all your bits and constructs
the byte.
No need for a USART module. I've done this and it works fine. Plenty of
example code around too.
Only if your processor is taxed with other tasks at the same time will
you have to use a USART for this.

Dave :)
Abstract Dissonance - 25 Mar 2006 22:59 GMT
>> >> I'm going to try to program a simple keyboard translator using the
>> >> PIC2455
[quoted text clipped - 30 lines]
> then the TX pin will be an output, you can't feed a clock input into an
> output pin!

I was thinking that the autobaud rate stuff needed a line to sense the
"clock" on... I didn't know it could sense it directly from the data ;/
(like what if you sense all low's... how can it sense?)

> You have 3 options:
> 1) Connect Keyboard DATA to RX and Keyboard CLK to TX *and* use
> synchronous slave mode. This should work although I have never done it
> myself. The USART baud rate will use external CLK from the keyboard.
> You *cannot* connect the CLK line and use asynchronous mode, that's not
> the way asynchronous works.

I thought asynchronous was basicaly for bidirectionality?  In the specs it
says that asynch mode is the only one that supports full-duplex or something
like that and also is the only one that will use the autobaud rate
dectionion.

> 2) Connect Keyboard DATA to RX only and forget the CLK line. Use
> asynchronous mode and let the USART module detect the baud rate. This
> may not work, the keyboard is not a set frequency and may not have a
> defined start bit (I can't remember exactly).

What is a "defined start bit"? The serial data consists of a start bit, 8
data bits, 1 parity, and 1 stop bit.

> 3) Connect the Keyboard DATA and CLK lines to normal I/O pins on the
> PIC. You can then interrupt off the CLK line falling edge (if you want
[quoted text clipped - 5 lines]
> Only if your processor is taxed with other tasks at the same time will
> you have to use a USART for this.

This is the more intuitive way but I feel I'm doing more than I have
to(which isn't a bad think necessarily but...).  I figure that since I have
the USART I might as well take advantage of it.  I might try both the asynch
and synch methods and see what happens.

> Dave :)

Thanks,
Jon
Jonathan Kirwan - 23 Mar 2006 23:00 GMT
>> I'm going to try to program a simple keyboard translator using the PIC2455
>> which has a built in EUSART.  At this point I just want to get the keyboard
[quoted text clipped - 9 lines]
>clock from the keyboard.
><snip>

Actually, the clock line should also be able to be driven by the
non-keyboard end of things, as well.  The other end is responsible for
it's own clock driving action.  These are bi-directional lines
supporting bi-directional communication and there is a negotiating
protocol that should be supported.

Jon
Abstract Dissonance - 24 Mar 2006 00:52 GMT
>>> I'm going to try to program a simple keyboard translator using the
>>> PIC2455
[quoted text clipped - 22 lines]
>
> Jon

yeah... There is a "master" and "slave".  When the master pulls the clock
low the slave waits for a transmission and if it was in the process of
tranmitting it will have to resend later(and buffer its data)... or
something like that.  At this point I just want to make sure I can read what
the keyboard has to say... I have no logic analyzer to "see" whats going on
and I don't like guessing.  I'm not to worried about sending commands to the
keyboard yet but would just like to know its "working".

Jon
Anthony Fremont - 24 Mar 2006 01:23 GMT
> I'm going to try to program a simple keyboard translator using the PIC2455
> which has a built in EUSART.  At this point I just want to get the keyboard
[quoted text clipped - 11 lines]
> when connecting the lines or even use transistors to source/sink more
> current?

A PC keyboard doesn't spit out async serial data, they are synchronous
(allot like I2C as I recall).  There are some other things you need to
know as well, like that the keyboard can talk three different protocols.
That means you have to send it some data to initialize it unless you
want the default output.

I did this a few years ago on a 16F84, it was the first thing I did with
a PIC.  It read data from a keyboard, partially translated the scancodes
and sent it out a serial port.  Here is some code that should get you
started on the road to communicating with the hateful things.  ;-)

The cheesy serial code I glommed from the internet along with some other
bits here and there.  Now when I bit-bang serial, I use timer interrupts
to clock things in and out.  This code is a real mess, but it should
work using a 4MHz clock.  You'll certainly need to make some changes to
get it running on an 18F.

;-----------------------------------------------------------------------
----------------------
;       HEADER:
;-----------------------------------------------------------------------
----------------------
             LIST        P=16f84
             RADIX       DEC
             INCLUDE     "p16f84.inc"
             __CONFIG    _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON

;-----------------------------------------------------------------------
----------------------
;       EQUATES:
;-----------------------------------------------------------------------
----------------------
RS            equ         0                   ;LCD's pin 4 should be
connected to PORTB.0
RW            equ         1                   ;LCD's pin 5 should be
connected to PORTB.1
EN            equ         2                   ;LCD's pin 6 should be
connected to PORTB.2

KBCLK         equ         1                   ;Keyboard's clock pin
connected to PORTA.1
KBDATA        equ         2                   ;Keyboard's data pin
connected to PORTA.2

TEMP0         equ     0x0C                ;Four general purpose
registers
TEMP1         equ         0x0D
TEMP2         equ         0x0E
TEMP3         equ         0x0F

#define     SERIAL_OUT      PORTA, 0

; DELAY_TIME should be (ClockSpeed/4/SerialSpeed-14)/3
; 4MHz 9600 baud would be (4000000/4/9600-14)/3 = 30
; 4MHz 2400=134 4800=65 9600=30 19200=13 38400=4 57600=1

; 10Mhz  4800=169
DELAY_TIME  equ D'30'

Scancode      equ         0x10                ;Added by mike
AsciiValue    equ         0x11
KBFlags       equ         0x12                ;Keyboard Flags byte
SHIFT         equ         0                   ;Shift key down flag
ALT           equ         1                   ;Alt key down flag
CTRL          equ         2                   ;Ctrl key down flag

             cblock 0x13                     ; variables
serialDelayCount
serialCount
serialData
             endc

;-----------------------------------------------------------------------
----------------------
;       START:
;-----------------------------------------------------------------------
----------------------
             org         0x000
             goto        Start
             org         0x004
             goto        Start

Start         bsf         STATUS, RP0         ;Switch to Bank 1
             movlw       b'00000110'         ;Define I/O on Port A
(KBCLK and KBDATA input)
             movwf       TRISA & 0x07F
             movlw       b'00000000'         ;Define I/O on Port B (LCD
Display output)
             movwf       TRISB & 0x07F
             bcf         STATUS, RP0         ;Back to Bank 0
             clrf        PORTA               ;Initialize PORTA
             clrf        PORTB               ;Initialize PORTB
             clrf        KBFlags             ;Turn off all flags for
keyboard
             call        KBCLK_Low           ;Put keyboard on hold
right away
             call        serialInit          ;get ready for serial
stuff

             movlw       0x01                ;Wait a while for keyboard
to init
             call        Delay
             movlw       0x01                ;Wait a while for keyboard
to init
             call        Delay
             movlw       0x01                ;Wait a while for keyboard
to init
             call        Delay

             call        Read_KB             ;trash the keyboards post
code

Main          call        Read_KB             ;Get a scancode byte into
W
             movwf       Scancode            ;Save it

;              goto        PrintIt             ;Skip over checks

             movf        Scancode, w
             xorlw       0x12                ;Was it left shift key
down
             btfsc       STATUS, Z
              goto       SKeyDown            ;Special key down

             movf        Scancode, w
             xorlw       0x59                ;Was it right shift key
down
             btfsc       STATUS, Z
              goto       SKeyDown            ;Shift key down

             movf        Scancode, w
             xorlw       0xF0                ;Was it a break code
prefix - F0
             btfsc       STATUS, Z
              goto       DoBreak             ;Yes, so process it

             movf        Scancode, w         ;Restore W
             xorlw       0xE0                ;Was it a different break
code prefix - E0
             btfsc       STATUS, Z
              goto       Skipit              ;Yes, so skip it

             movf        Scancode, w         ;Restore W
             xorlw       0xE1                ;Was it a different break
code prefix - E1
             btfsc       STATUS, Z
              goto       Skipit              ;Yes, so skip it

             goto        PrintIt             ;It passed the checks for
printability

SKeyDown
             bsf         KBFlags, SHIFT      ;Set the shifted flag
             goto        Main

SKeyUp
             bcf         KBFlags, SHIFT      ;Un-Set the shifted flag
             goto        Main

DoBreak
             call        Read_KB             ;Get a scancode into w
             movwf       Scancode            ;Save it

             movf        Scancode, w
             xorlw       0x12                ;Was it left shift key up
             btfsc       STATUS, Z
              goto       SKeyUp              ;Shift key up

             movf        Scancode, w
             xorlw       0x59                ;Was it right shift key up
             btfsc       STATUS, Z
              goto       SKeyUp              ;Shift key up

             goto        Main                ;Get next scancode
;
;Skip the break code and the next keyboard byte after receiving break
code
;
Skipit
             call        Read_KB             ;get a scancode byte
             goto        Main                ; and throw it away

PrintIt
             movf        Scancode, w         ;Load the scancode and
             call        Translate           ; get ascii value into W
             movwf       AsciiValue          ;Save it

;              movf        AsciiValue, W       ;Refresh W
             call        serialTransmit      ;Send the keystroke

             goto        Main                ;Read/Display again
;-----------------------------------------------------------------------
-------
;
;   Translate - Convert scancode in W to ASCII returned in W
;
;-----------------------------------------------------------------------
-------
Translate     andlw       0x7f                ;Maintain sanity (less
than 128)
             movwf       TEMP3               ;Save truncated scancode
temporarily
             btfsc       KBFlags, SHIFT      ;Are we shifted or not
              goto        kb_shifted         ;Yes, use shifted table
                                             ;No, use primary table
             MOVLW       HIGH XLAT_Tbl + 1   ;Move the High Byte of the
first table
                                             ;location into W
             MOVWF       PCLATH              ;and then into PCLATH
             MOVLW       XLAT_Tbl + 1        ;Load W with the address
of the first
                         ;  piece of data in Table2
             ADDWF       TEMP3,w             ;Calculate the offset
address and
             BTFSC       STATUS, C           ; see if it overflows
              INCF       PCLATH,f            ;If so, increment PCLATH
and
             CALL        XLAT_Tbl            ;Jump to the data table
entry (translating scan code)
             return
kb_shifted
             MOVLW       HIGH XLAT_Shift + 1   ;Move the High Byte of
the first table
                                             ;location into W
             MOVWF       PCLATH              ;and then into PCLATH
             MOVLW       XLAT_Shift + 1        ;Load W with the address
of the first
                         ;  piece of data in Table2
             ADDWF       TEMP3,w             ;Calculate the offset
address and
             BTFSC       STATUS, C           ; see if it overflows
              INCF       PCLATH,f            ;If so, increment PCLATH
and
             CALL        XLAT_Shift          ;Jump to the data table
entry (translating scan code)
             return

;---------------------------------------------------
;
;  Read the keyboard and return scancode in W
;
;---------------------------------------------------
Read_KB       call        KBCLK_Norm          ;clear to send now
             call        PS2_Get
             movwf       TEMP3               ;Save scancode byte read
             call        KBCLK_Low           ;turn off the KB
             movf        TEMP3, w            ;Return with scancode in W
             return

;---------------------------------------------------
;
;   KCLK_Low - Pull the keyboard clock line low
;
;---------------------------------------------------
KBCLK_Low      bsf         STATUS, RP0         ;Make KBCLK an Output
             bcf         TRISA & 0x07F, KBCLK
             bcf         STATUS, RP0
             bcf         PORTA, KBCLK        ;Pull it low
;              movlw       0xFE                ;Wait at least 100
microseconds.
;              call        Delay
             return

;-----------------------------------------------------------------------
;
;   KCLK_Norm - Return keyboard clock line back to normal operation
;
;-----------------------------------------------------------------------
KBCLK_Norm     bsf         STATUS, RP0         ;Select Bank 1.
             bsf         TRISA & 0x07F, KBCLK    ;Make PORTA.1 Input
Again
             bcf         STATUS, RP0         ;Back to Bank 0.
             return

Delay         movwf       TEMP0               ;Efficient, imprecise
delay routine
             addlw       1
             btfsc       STATUS, Z
             incfsz      TEMP0, f
             goto        $ - 3
             return

PS2_Get       call        PS2_Get1            ;Get/ignore the start bit
             movlw       d'8'                ;Load Counter
             movwf       TEMP0
PS2_Get0      rrf         TEMP1, f
             call        PS2_Get1            ;Read a bit from the
keyboard/mouse
             iorwf       TEMP1, f            ;TEMP1.7 = bit read from
device
             iorlw       b'01111111'
             andwf       TEMP1, f
             decfsz      TEMP0, f            ;Read 8 data bits yet?
             goto        PS2_Get0            ;  No.  Get another bit.
             call        PS2_Get1            ;  Yes. Get/ignore parity
bit.
             call        PS2_Get1            ;Get/ignore stop bit
             movf        TEMP1, w            ;Put result in w.
             return                          ;Done--return.

PS2_Get1      btfss       PORTA, KBCLK        ;Make sure clock is high.
             goto        $ - 1
             btfsc       PORTA, KBCLK        ;Read data on falling edge
             goto        $ - 1
             btfss       PORTA, KBDATA       ;Read data.
             retlw       b'00000000'         ;  w.7 = bit read.
             retlw       b'10000000'         ;  w.7 = bit read.
;-----------------------------------------------------------------------
-
;
;  Serial Port Stuff
;
;-----------------------------------------------------------------------
-
serialDelayThird
   movlw   DELAY_TIME/3
   movwf   serialDelayCount    ; only count 1/3
   goto    serialDelayLoop     ; use routine below
serialDelay
   movlw   DELAY_TIME
   movwf   serialDelayCount    ; Count down from DELAY_TIME
   nop             ; Helps with high speed
serialDelayLoop
   decfsz  serialDelayCount, F ; Countdown
    goto   serialDelayLoop     ; keep counting
   return              ; done
;_______________________________________________________________________
_

serialInit
   bsf STATUS, RP0     ; Select Bank 1
;   bsf SERIAL_IN       ; Setup input
   bcf SERIAL_OUT      ; Setup output
   bcf STATUS, RP0     ; Select Bank 0
       bsf     SERIAL_OUT
   return

;_______________________________________________________________________
_

serialTransmit
   movwf   serialData      ; save the outgoing byte
   movlw   D'10'
   movwf   serialCount     ; set the bit count
   clrc                ; prep for start bit
serialTransmitLoop
   bsf SERIAL_OUT      ; assume send low
   skpc                ; if sending 0
    bcf    SERIAL_OUT      ; send high
   call    serialDelay     ; delay
   setc                ; prep for stop bit
   rrf serialData, F       ; roll serialIn bits
   decfsz  serialCount, F      ; if not complete
    goto   serialTransmitLoop  ; loop back for more
   return              ; all done
;

;serialReceive
;   btfss   SERIAL_IN       ; Check for Start bit
;    retlw  0           ; not receiving now
;   movlw   D'9'
;   movwf   serialCount     ; gonna read 9 bits
;   call    serialDelayThird    ; skip third a bit
;serialReceiveLoop
;   clrc                ; assume clear carry
;   btfss   SERIAL_IN       ; if receiving 0
;    setc               ; set carry
;   rrf serialData, F       ; roll serialData bits
;   call    serialDelay     ; delay
;   nop             ; keep timing w/ transmit
;   decfsz  serialCount, F      ; if not complete
;    goto   serialReceiveLoop   ; loop back for more
;   movfw   serialData      ; return the data
;   return

             org         0x1FF
XLAT_Tbl      movwf       PCL
             retlw       0xFF                 ;00
             retlw       0xFF                 ;01
             retlw       0xFF                 ;02
             retlw       0xFF                 ;03
             retlw       0xFF                 ;04
             retlw       0xFF                 ;05
             retlw       0xFF                 ;06
             retlw       0xFF                 ;07
             retlw       0xFF                 ;08
             retlw       0xFF                 ;09
             retlw       0xFF                 ;0A
             retlw       0xFF                 ;0B
             retlw       0xFF                 ;0C
             retlw       0xFF                 ;0D
             retlw       0xFF                 ;0E
             retlw       0xFF                 ;0F
             retlw       0xFF                 ;10
             retlw       0xFF                 ;11
             retlw       0xFF                 ;12
             retlw       0xFF                 ;13
             retlw       0xFF                 ;14
             retlw       'q'                 ;15
             retlw       '1'                 ;16
             retlw       0xFF                 ;17
             retlw       0xFF                 ;18
             retlw       0xFF                 ;19
             retlw       'z'                 ;1A
             retlw       's'                 ;1B
             retlw       'a'                 ;1C
             retlw       'w'                 ;1D
             retlw       '2'                 ;1E
             retlw       0xFF                 ;1F
             retlw       0xFF                 ;20
             retlw       'c'                 ;21
             retlw       'x'                 ;22
             retlw       'd'                 ;23
             retlw       'e'                 ;24
             retlw       '4'                 ;25
             retlw       '3'                 ;26
             retlw       0xFF                 ;27
             retlw       0xFF                 ;28
             retlw       ' '                 ;29
             retlw       'v'                 ;2A
             retlw       'f'                 ;2B
             retlw       't'                 ;2C
             retlw       'r'                 ;2D
             retlw       '5'                 ;2E
             retlw       0xFF                 ;2F
             retlw       0xFF                 ;30
             retlw       'n'                 ;31
             retlw       'b'                 ;32
             retlw       'h'                 ;33
             retlw       'g'                 ;34
             retlw       'y'                 ;35
             retlw       '6'                 ;36
             retlw       0xFF                 ;37
             retlw       0xFF                 ;38
             retlw       0xFF                 ;39
             retlw       'm'                 ;3A
             retlw       'j'                 ;3B
             retlw       'u'                 ;3C
             retlw       '7'                 ;3D
             retlw       '8'                 ;3E
             retlw       0xFF                 ;3F
             retlw       0xFF                 ;40
             retlw       ','                 ;41
             retlw       'k'                 ;42
             retlw       'i'                 ;43
             retlw       'o'                 ;44
             retlw       '0'                 ;45
             retlw       '9'                 ;46
             retlw       0xFF                 ;47
             retlw       0xFF                 ;48
             retlw       '.'                 ;49
             retlw       '/'                 ;4A
             retlw       'l'                 ;4B
             retlw       ';'                 ;4C
             retlw       'p'                 ;4D
             retlw       '-'                 ;4E
             retlw       0xFF                 ;4F
             retlw       0xFF                 ;50
             retlw       0xFF                 ;51
             retlw       '\''                 ;52
             retlw       0xFF                 ;53
             retlw       '['                 ;54
             retlw       '='                 ;55
             retlw       0xFF                 ;56
             retlw       0xFF                 ;57
             retlw       0xFF                 ;58
             retlw       0xFF                 ;59
             retlw       0x0D                 ;5A
             retlw       ']'                 ;5B
             retlw       0xFF                 ;5C
             retlw       '\\'                 ;5D
             retlw       0xFF                 ;5E
             retlw       0xFF                 ;5F
             retlw       0xFF                 ;60
             retlw       0xFF                 ;61
             retlw       0xFF                 ;62
             retlw       0xFF                 ;63
             retlw       0xFF                 ;64
             retlw       0xFF                 ;65
             retlw       0xFF                 ;66
             retlw       0xFF                 ;67
             retlw       0xFF                 ;68
             retlw       0xFF                 ;69
             retlw       0xFF                 ;6A
             retlw       0xFF                 ;6B
             retlw       0xFF                 ;6C
             retlw       0xFF                 ;6D
             retlw       0xFF                 ;6E
             retlw       0xFF                 ;6F
             retlw       0xFF                 ;70
             retlw       0xFF                 ;71
             retlw       0xFF                 ;72
             retlw       0xFF                 ;73
             retlw       0xFF                 ;74
             retlw       0xFF                 ;75
             retlw       0xFF                 ;76
             retlw       0xFF                 ;77
             retlw       0xFF                 ;78
             retlw       0xFF                 ;79
             retlw       0xFF                 ;7A
             retlw       0xFF                 ;7B
             retlw       0xFF                 ;7C
             retlw       0xFF                 ;7D
             retlw       0xFF                 ;7E
             retlw       0xFF                 ;7F

             org         0x2FF
XLAT_Shift    movwf       PCL
             retlw       0xFF                 ;00
             retlw       0xFF                 ;01
             retlw       0xFF                 ;02
             retlw       0xFF                 ;03
             retlw       0xFF                 ;04
             retlw       0xFF                 ;05
             retlw       0xFF                 ;06
             retlw       0xFF                 ;07
             retlw       0xFF                 ;08
             retlw       0xFF                 ;09
             retlw       0xFF                 ;0A
             retlw       0xFF                 ;0B
             retlw       0xFF                 ;0C
             retlw       0xFF                 ;0D
             retlw       0xFF                 ;0E
             retlw       0xFF                 ;0F
             retlw       0xFF                 ;10
             retlw       0xFF                 ;11
             retlw       0xFF                 ;12
             retlw       0xFF                 ;13
             retlw       0xFF                 ;14
             retlw       'Q'                 ;15
             retlw       '!'                 ;16
             retlw       0xFF                 ;17
             retlw       0xFF                 ;18
             retlw       0xFF                 ;19
             retlw       'Z'                 ;1A
             retlw       'S'                 ;1B
             retlw       'A'                 ;1C
             retlw       'W'                 ;1D
             retlw       '@'                 ;1E
             retlw       0xFF                 ;1F
             retlw       0xFF                 ;20
             retlw       'C'                 ;21
             retlw       'X'                 ;22
             retlw       'D'                 ;23
             retlw       'E'                 ;24
             retlw       '$'                 ;25
             retlw       '#'                 ;26
             retlw       0xFF                 ;27
             retlw       0xFF                 ;28
             retlw       ' '                 ;29
             retlw       'V'                 ;2A
             retlw       'F'                 ;2B
             retlw       'T'                 ;2C
             retlw       'R'                 ;2D
             retlw       '%'                 ;2E
             retlw       0xFF                 ;2F
             retlw       0xFF                 ;30
             retlw       'N'                 ;31
             retlw       'B'                 ;32
             retlw       'H'                 ;33
             retlw       'G'                 ;34
             retlw       'Y'                 ;35
             retlw       '^'                 ;36
             retlw       0xFF                 ;37
             retlw       0xFF                 ;38
             retlw       0xFF                 ;39
             retlw       'M'                 ;3A
             retlw       'J'                 ;3B
             retlw       'U'                 ;3C
             retlw       '&'                 ;3D
             retlw       '*'                 ;3E
             retlw       0xFF                 ;3F
             retlw       0xFF                 ;40
             retlw       '<'                 ;41
             retlw       'K'                 ;42
             retlw       'I'                 ;43
             retlw       'O'                 ;44
             retlw       ')'                 ;45
             retlw       '('                 ;46
             retlw       0xFF                 ;47
             retlw       0xFF                 ;48
             retlw       '>'                 ;49
             retlw       '?'                 ;4A
             retlw       'L'                 ;4B
             retlw       ':'                 ;4C
             retlw       'P'                 ;4D
             retlw       '_'                 ;4E
             retlw       0xFF                 ;4F
             retlw       0xFF                 ;50
             retlw       0xFF                 ;51
             retlw       '\"'                 ;52
             retlw       0xFF                 ;53
             retlw       '{'                 ;54
             retlw       '+'                 ;55
             retlw       0xFF                 ;56
             retlw       0xFF                 ;57
             retlw       0xFF                 ;58
             retlw       0xFF                 ;59
             retlw       0x0D                 ;5A
             retlw       '}'                 ;5B
             retlw       0xFF                 ;5C
             retlw       '|'                 ;5D
             retlw       0xFF                 ;5E
             retlw       0xFF                 ;5F
             retlw       0xFF                 ;60
             retlw       0xFF                 ;61
             retlw       0xFF                 ;62
             retlw       0xFF                 ;63
             retlw       0xFF                 ;64
             retlw       0xFF                 ;65
             retlw       0xFF                 ;66
             retlw       0xFF                 ;67
             retlw       0xFF                 ;68
             retlw       0xFF                 ;69
             retlw       0xFF                 ;6A
             retlw       0xFF                 ;6B
             retlw       0xFF                 ;6C
             retlw       0xFF                 ;6D
             retlw       0xFF                 ;6E
             retlw       0xFF                 ;6F
             retlw       0xFF                 ;70
             retlw       0xFF                 ;71
             retlw       0xFF                 ;72
             retlw       0xFF                 ;73
             retlw       0xFF                 ;74
             retlw       0xFF                 ;75
             retlw       0xFF                 ;76
             retlw       0xFF                 ;77
             retlw       0xFF                 ;78
             retlw       0xFF                 ;79
             retlw       0xFF                 ;7A
             retlw       0xFF                 ;7B
             retlw       0xFF                 ;7C
             retlw       0xFF                 ;7D
             retlw       0xFF                 ;7E
             retlw       0xFF                 ;7F
             end
Abstract Dissonance - 25 Mar 2006 23:03 GMT
>> I'm going to try to program a simple keyboard translator using the
> PIC2455
[quoted text clipped - 24 lines]
> That means you have to send it some data to initialize it unless you
> want the default output.

I didn't know this. I can't seem to find good info on it ;/  Most are just
what some people have done to get it to work but nothing technical and
specific ;/

> I did this a few years ago on a 16F84, it was the first thing I did with
> a PIC.  It read data from a keyboard, partially translated the scancodes
[quoted text clipped - 6 lines]
> work using a 4MHz clock.  You'll certainly need to make some changes to
> get it running on an 18F.

yeah.  I was thinking I could setup a timed interrupt but what I have read
says that the keyboard's clock can be anywhere from 10khz to 20khz so this
doesn't help(and you would need to sample twice as fast or something).  I
like the edge triggered interrupt method since its pretty straight forward.

Seems to me the USART handles everything for me directly though and it would
be nice to take advantage of it if its not to difficult.

I'll look at your code and see what I can get from it.  I just need to start
playing around I guess.

Thanks,

Jon

> ;-----------------------------------------------------------------------
> ----------------------
[quoted text clipped - 616 lines]
>              retlw       0xFF                 ;7F
>              end
Jan Wagner - 26 Mar 2006 12:04 GMT
> I'm going to try to program a simple keyboard translator using the PIC2455
> which has a built in EUSART.  At this point I just want to get the keyboard
[quoted text clipped - 13 lines]
>
> (I'm running the keyboard off a 5V supply that can source up to .5mA or so)

Apart from the "writing bugs" others already commented on, doing this
with UART could be a real nightmare. Ok, 9600 baud and 8 databit, 1 odd
parity, 1 start and 1 stop bit, and separate clock input, it is
basically easy (if your microcontroller supports that many bits!! 11 of
them). But then there is also the bidirectional communication needed
especially if you want to configure the keyboard to something sensible
by sending commands to it. Basically you'd have to switch off the UART
and put the pins into output mode for the handshakes etc, then switch
back to UART again to receive or transmit. For both receive /and/
transmit, you'd have to use the clock provided by the keyboard, i.e.
synchronous UART. It's a real mess.

You can find some valuable background info at
http://www.beyondlogic.org/keyboard/keybrd.htm#1

If you only want to receive, and your uC does support full 11 bits UART
("Enhanced USART" sounds like it might, but then maybe that's just
marketing bull...) then this should be very easy to do.

Just add the pull-up resistors, data line to UART RX, clock input not
strictly necessary - until you want to transmit.

regards,
 - Jan
Abstract Dissonance - 28 Mar 2006 05:12 GMT
>> I'm going to try to program a simple keyboard translator using the
>> PIC2455 which has a built in EUSART.  At this point I just want to get
[quoted text clipped - 25 lines]
> transmit. For both receive /and/ transmit, you'd have to use the clock
> provided by the keyboard, i.e. synchronous UART. It's a real mess.

yeah... after looking at slave mode I saw this.  Difference between master
and slave is who supplies the clock.

I was thinking that all I would have to do is switch between master and
slave mode for tranmission and reception.  Not sure if this would work
though or not... I'd still have to setup the clock speed properly for
tranmission but I figure that it shouldn't be to hard to do cause they are
two disjoint parts. The main problem is when worrying about collisions.

> You can find some valuable background info at
> http://www.beyondlogic.org/keyboard/keybrd.htm#1

Yeah, I'm still trying to read up on all this stuff.  Its a good site but
trying to make some sense of the datasheet for the pic. It gives different
methods to do the same thing and I'm confused on which is right.

> If you only want to receive, and your uC does support full 11 bits UART
> ("Enhanced USART" sounds like it might, but then maybe that's just
> marketing bull...) then this should be very easy to do.

Well, I'm not sure. It says 9-bits but not sure if that includes the start
and stop bit ;/

> Just add the pull-up resistors, data line to UART RX, clock input not
> strictly necessary - until you want to transmit.

? Is that for asynch mode?   I'd need to use the clock in slave mode for the
getting data? (since I don't know its data rate).  I could use asynch mode
and auto detect the clock but I'm not sure how reliable this is ;/  and I
think there has to be a calibration test or something and I have no idea how
to get that done.

> regards,
>  - Jan

Thanks,
Jon
Jan Wagner - 28 Mar 2006 20:40 GMT
> I was thinking that all I would have to do is switch between master and
> slave mode for tranmission and reception.  

Basically yes, but, with the additional protocol thingy in between to
tell the keyboard that it should start clocking data in and not out.

> Not sure if this would work
> though or not... I'd still have to setup the clock speed properly for
> tranmission but I figure that it shouldn't be to hard to do cause they are
> two disjoint parts. The main problem is when worrying about collisions.

The way I've seen this and used the keyboard is that the keyboard
actually is always master and provides the clock i.e. tells the PC when
it can start sending a command byte. But I'm not an AT keyboard
specifications guru, maybe the specs provide for a little-known slave
mode also.

>> You can find some valuable background info at
>> http://www.beyondlogic.org/keyboard/keybrd.htm#1
[quoted text clipped - 9 lines]
> Well, I'm not sure. It says 9-bits but not sure if that includes the start
> and stop bit ;/

I had a quick glance at the PIC18F2455 datasheet (I like to spot PIC
flaws ;-)), and searched the PDF for "parity". Not many search results.

In section 20.2 EUSART Asynchronous Mode the datasheet says that "Parity
is not supported by the hardware but can be implemented in software and
stored as the 9th data bit.". So the USART might not be that "Enhanced"
after all if, it lacks such basic features as parity bit. But it's up to
you to check the PIC18 family users guide etc in more depth to see if
this is actually the full truth or not (considering it is a PIC, it'd be
hardly surprising if the parity feature was really missing ;-)

Anyway, from that one datasheet sentence I'd guess the Enhanced USART
does only start + stop bit and 7..9 bits of data. So if you want to
/receive/, enable 9 bit mode, and ignore the 9th bit (since at only 9600
baud the chance for errors must be really small :)) For transmitting
something, do the parity calculation in software.

>> Just add the pull-up resistors, data line to UART RX, clock input not
>> strictly necessary - until you want to transmit.
[quoted text clipped - 4 lines]
> think there has to be a calibration test or something and I have no idea how
> to get that done.

Yup, asynch, no need for the external clock when receiving because
basically the keyboard is supposed to be sending at 9600baud (IIRC).

Your PIC UART will (or, /should/ ;-) sync up at the start bit
automatically, provided you have set the UART to a fixed 9600 baud and
don't use any kind of unreliable "automatic baud rate detection" features.

With UART set to 9600 baud the actual data rate or delay between bytes
is irrelevant, as long as bit rate of one individual byte is those 9600
baud - and the PC keyboard takes care of that already.

regards,
 - Jan
Abstract Dissonance - 29 Mar 2006 06:45 GMT
>> I was thinking that all I would have to do is switch between master and
>> slave mode for tranmission and reception.
[quoted text clipped - 11 lines]
> start sending a command byte. But I'm not an AT keyboard specifications
> guru, maybe the specs provide for a little-known slave mode also.

I'm not sure. My foggy recollection from a few web sites is that when
transmitting to the keyboard you gotta hold the clock line low for a certain
amount of time and the keyboard will know then that you are going to
transmit something and then will wait.  I'm not sure if I'm even close but
thats what I remember at this point.

>>> You can find some valuable background info at
>>
[quoted text clipped - 28 lines]
> chance for errors must be really small :)) For transmitting something, do
> the parity calculation in software.

yeah, it does start, stop and 8 to 9 data bits but treats the 9th bit as
data and not something special like parity.  I'm not sure if I need to do
parity at this point since I wouldn't even know how to request tranmission
of data.  I'm still trying to figure out how to use the USART for my pic.
The docs are pretty technical but I get a little lost in know exactly what
to do.  They give the info on all the bits and a small description but hell
if I know how to use them properly(like in what order and stuff).   They do
give some example code and I think I'm making it harder than what it is.

I figure that I just have to flip a few bits to set the right mode and put
some code on an interrupt to handle when I recieve the data and hopefully it
should work.

>>> Just add the pull-up resistors, data line to UART RX, clock input not
>>> strictly necessary - until you want to transmit.
[quoted text clipped - 7 lines]
> Yup, asynch, no need for the external clock when receiving because
> basically the keyboard is supposed to be sending at 9600baud (IIRC).

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.

> Your PIC UART will (or, /should/ ;-) sync up at the start bit
> automatically, provided you have set the UART to a fixed 9600 baud and
[quoted text clipped - 3 lines]
> irrelevant, as long as bit rate of one individual byte is those 9600
> baud - and the PC keyboard takes care of that already.

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 sheet on them ;/

> regards,
>  - Jan

Thanks again,
Jon
techie_alison - 29 Mar 2006 19:24 GMT
> 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
[quoted text clipped - 5 lines]
> 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
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.