Hi I've been experimenting with a PS/2 keyboard i/f . I started of with the code from the cookbook entry for the prototype MBED and have got a simpler version for the 1768. I use p21 for keyboard clock and p22 for keyboard data. The pinout in the original example seems wrong. I got my info from this site 'http://www.beyondlogic.org/keyboard/keybrd.htm', a very good explanation of how to read the clk/data lines etc.
The code below works really well (better than I expected).
DigitalInOut kbclk(p21);
DigitalInOut kbdata(p22);
/** Wait for single scan code from keyboard...
*
* @return 8-bit scan code...
*/
unsigned char kbget()
{
int i;
unsigned char data = 0;
int start, stop, parity;
for (i=0; i<11; i++)
{
while (kbclk.read()==1) {} // Wait for hi/lo transition on clock line...
switch (i)
{
case 0: // Start bit...
start = kbdata.read(); // Start bit, should be 0...
break;
case 9: // Parity bit...
parity = kbdata.read();
break;
case 10: // Stop bit...
stop = kbdata.read(); // Stop bit, should be 1...
break;
default: // Data bits..
data >>=1;
if (kbdata.read())
data |= 0x80;
break;
}
while (kbclk.read()==0) {} // Wait for lo/hi transition on clock line...
}
return data;
}
...however, this is a completely blocking function, so I thought this would be perfect for an interrrupt service handler, so voila...
DigitalInOut kbdata(p22);
InterruptIn kbclk(p21);
void kb_interrupt()
{
static unsigned char data;
int bit, start, stop, parity;
static int state=0;
bit = kbdata.read();
switch (state)
{
case 0:
start = bit; // Start bit rxd.
state = 1; // Move state.
data = 0; // Reset data value.
break;
case 9:
parity = bit;
state = 10; // Move state.
break;
case 10:
stop = bit;
...at this point I push the data (scan code) into a circular buffer, details deleted for clarity.
state = 0; // Reset state machine.
break;
default:
// Read in data bit and OR into data value...
data >>=1;
if (bit)
data |= 0x80;
state++;
break;
}
}
int main()
{
.. yada yada
kbclk.fall(&kb_interrupt); // Set up interrupt handler (triggers on falling kb clock signal).
while(1)
{
// Get scans from circular bufer, yada yada...
}
}
I've edited above code for brevity. My problem is that this appears to work in that for every key press/release I get the expected number of interrupts (11, 1 start, 8 data, 1 parity, 1 stop) but the data is garbled (different codes for same keys, different codes for everty restart of mbed etc).
Any ideas??
I've tried servicing interrupt on rising clock, in snippets above I've left out test code where I'm counting interrupts etc.
PS: I made the interface cable from an old keyboard extension cable, I've put a two pin header on the power and the clk/data wires for easy use in breadboard.
Hi I've been experimenting with a PS/2 keyboard i/f . I started of with the code from the cookbook entry for the prototype MBED and have got a simpler version for the 1768. I use p21 for keyboard clock and p22 for keyboard data. The pinout in the original example seems wrong. I got my info from this site 'http://www.beyondlogic.org/keyboard/keybrd.htm', a very good explanation of how to read the clk/data lines etc.
The code below works really well (better than I expected).
...however, this is a completely blocking function, so I thought this would be perfect for an interrrupt service handler, so voila...
I've edited above code for brevity. My problem is that this appears to work in that for every key press/release I get the expected number of interrupts (11, 1 start, 8 data, 1 parity, 1 stop) but the data is garbled (different codes for same keys, different codes for everty restart of mbed etc).
Any ideas??
I've tried servicing interrupt on rising clock, in snippets above I've left out test code where I'm counting interrupts etc.
PS: I made the interface cable from an old keyboard extension cable, I've put a two pin header on the power and the clk/data wires for easy use in breadboard.