Skip to content

Commit 378c69f

Browse files
committed
V1.0.2 Initial Public release
0 parents  commit 378c69f

File tree

8 files changed

+484
-0
lines changed

8 files changed

+484
-0
lines changed

PS2KeyRaw.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/* Version V1.0.2
2+
PS2KeyRaw.cpp - PS2KeyRaw library
3+
Copyright (c) 2007 Free Software Foundation. All right reserved.
4+
Written by Paul Carpenter, PC Services <[email protected]>
5+
6+
Stripped down version of PS2Keyboard to get every key code byte from a PS2
7+
Keyboard for testing purposes. Enables capture of all bytes see example.
8+
9+
IMPORTANT WARNING
10+
11+
If using a DUE or similar board with 3V3 I/O you MUST put a level translator
12+
like a Texas Instruments TXS0102 or FET circuit as the signals are
13+
Bi-directional (signals transmitted from both ends on same wire).
14+
15+
Failure to do so may damage your Arduino Due or similar board.
16+
17+
Test History
18+
September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0
19+
January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board
20+
Manager V1.6.6
21+
22+
Created September 2014 based, on PS2Keyboard which was
23+
Written by Christian Weichel <[email protected]>
24+
** Mostly rewritten Paul Stoffregen <[email protected]> 2010, 2011
25+
** Modified for use beginning with Arduino 13 by L. Abraham Smith, <[email protected]> *
26+
** Modified for easy interrupt pin assignment on method begin(datapin,irq_pin). Cuningan <[email protected]> **
27+
V1.0.1 Modified September 2014 Paul Carpenter for easier state machines and parity checks
28+
V1.0.2 Modified January 2016 to improve interrupt assignment with new Arduino macros
29+
30+
This library is free software; you can redistribute it and/or
31+
modify it under the terms of the GNU Lesser General Public
32+
License as published by the Free Software Foundation; either
33+
version 2.1 of the License, or (at your option) any later version.
34+
35+
This library is distributed in the hope that it will be useful,
36+
but WITHOUT ANY WARRANTY; without even the implied warranty of
37+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38+
Lesser General Public License for more details.
39+
40+
You should have received a copy of the GNU Lesser General Public
41+
License along with this library; if not, write to the Free Software
42+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
43+
*/
44+
45+
#include "PS2KeyRaw.h"
46+
47+
/* Private variable definition */
48+
#define BUFFER_SIZE 16
49+
volatile uint8_t buffer[ BUFFER_SIZE ];
50+
volatile uint8_t head, tail;
51+
uint8_t PS2_DataPin;
52+
53+
/* Private function declarations */
54+
uint8_t get_scan_code( );
55+
56+
// The ISR for the external interrupt
57+
// To receive 11 bits start, 8 data, ODD parity, stop
58+
// Interrupt every falling incoming clock edge from keyboard
59+
void ps2interrupt( void )
60+
{
61+
static uint8_t bitcount = 0; // Main state variable and bit count
62+
static uint8_t incoming;
63+
static uint8_t parity;
64+
static uint32_t prev_ms = 0;
65+
uint32_t now_ms;
66+
uint8_t val;
67+
68+
val = digitalRead( PS2_DataPin );
69+
now_ms = millis();
70+
if( now_ms - prev_ms > 250 )
71+
bitcount = 0;
72+
prev_ms = now_ms;
73+
bitcount++; // Now point to next bit
74+
switch( bitcount )
75+
{
76+
case 1: // Start bit
77+
incoming = 0;
78+
parity = 0;
79+
break;
80+
case 2:
81+
case 3:
82+
case 4:
83+
case 5:
84+
case 6:
85+
case 7:
86+
case 8:
87+
case 9: // Data bits
88+
parity += val; // another one received ?
89+
incoming >>= 1; // right shift one place for next bit
90+
incoming |= ( val ) ? 0x80 : 0; // or in MSbit
91+
break;
92+
case 10: // Parity check
93+
parity &= 1; // Get LSB if 1 = odd number of 1's so parity should be 0
94+
if( parity == val ) // Both same parity error
95+
parity = 0xFD; // To ensure at next bit count clear and discard
96+
break;
97+
case 11: // Stop bit
98+
if( parity >= 0xFD ) // had parity error
99+
{
100+
// Should send resend byte command here currently discard
101+
}
102+
else // Good so save byte in buffer
103+
{
104+
val = head + 1;
105+
if( val >= BUFFER_SIZE )
106+
val = 0;
107+
if( val != tail )
108+
{
109+
buffer[ val ] = incoming;
110+
head = val;
111+
}
112+
}
113+
// fall through to default
114+
default: // in case of weird error and end of byte reception re-sync
115+
bitcount = 0;
116+
}
117+
}
118+
119+
120+
uint8_t get_scan_code(void)
121+
{
122+
uint8_t i;
123+
124+
i = tail;
125+
if( i == head ) // check for empty buffer
126+
return 0;
127+
i++;
128+
if( i >= BUFFER_SIZE )
129+
i = 0;
130+
tail = i;
131+
return buffer[ i ];
132+
}
133+
134+
135+
int8_t PS2KeyRaw::available()
136+
{
137+
int8_t i;
138+
139+
if( tail == head )
140+
return false;
141+
i = tail - head;
142+
if( i < 0 )
143+
i += BUFFER_SIZE;
144+
return i;
145+
}
146+
147+
148+
int PS2KeyRaw::read()
149+
{
150+
uint8_t result;
151+
152+
result = 0;
153+
if( ( result = available() ) )
154+
result = get_scan_code();
155+
if( result == 0 )
156+
result = -1;
157+
return result;
158+
}
159+
160+
161+
PS2KeyRaw::PS2KeyRaw() {
162+
// nothing to do here, begin() does it all
163+
}
164+
165+
166+
void PS2KeyRaw::begin( uint8_t data_pin, uint8_t irq_pin )
167+
{
168+
PS2_DataPin = data_pin;
169+
170+
// initialize the pins
171+
#ifdef INPUT_PULLUP
172+
pinMode(irq_pin, INPUT_PULLUP);
173+
pinMode(data_pin, INPUT_PULLUP);
174+
#else
175+
pinMode(irq_pin, INPUT);
176+
digitalWrite(irq_pin, HIGH);
177+
pinMode(data_pin, INPUT);
178+
digitalWrite(data_pin, HIGH);
179+
#endif
180+
181+
// Initialise buffer indexes
182+
head = 0;
183+
tail = 0;
184+
185+
// Setup interrupt handler
186+
attachInterrupt( digitalPinToInterrupt( irq_pin ), ps2interrupt, FALLING );
187+
}
188+

PS2KeyRaw.h

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/* Version V1.0.2
2+
PS2KeyRaw.h - PS2KeyRaw library
3+
Copyright (c) 2007 Free Software Foundation. All right reserved.
4+
Written by Paul Carpenter, PC Services <[email protected]>
5+
6+
Stripped down version of PS2Keyboard to get every key code byte from a PS2
7+
Keyboard for testing purposes. Enables capture of all bytes see examples.
8+
9+
IMPORTANT WARNING
10+
11+
If using a DUE or similar board with 3V3 I/O you MUST put a level translator
12+
like a Texas Instruments TXS0102 or FET circuit as the signals are
13+
Bi-directional (signals transmitted from both ends on same wire).
14+
15+
Failure to do so may damage your Arduino Due or similar board.
16+
17+
Test History
18+
September 2014 Uno and Mega 2560 September 2014 using Arduino V1.6.0
19+
January 2016 Uno, Mega 2560 and Due using Arduino 1.6.7 and Due Board
20+
Manager V1.6.6
21+
The circuit:
22+
* KBD Clock (PS2 pin 1) to an interrupt pin on Arduino ( this example pin 3 )
23+
* KBD Data (PS2 pin 5) to a data pin ( this example pin 4 )
24+
* +5V from Arduino to PS2 pin 4
25+
* GND from Arduino to PS2 pin 3
26+
27+
The connector to mate with PS2 keyboard is a 6 pin Female Mini-Din connector
28+
PS2 Pins to signal
29+
1 KBD Data
30+
3 GND
31+
4 +5V
32+
5 KBD Clock
33+
34+
Keyboard has 5V and GND connected see plenty of examples and
35+
photos around on Arduino site and other sites about the PS2 Connector.
36+
37+
Interrupts
38+
39+
Clock pin from PS2 keyboard MUST be connected to an interrupt
40+
pin, these vary with the different types of Arduino
41+
42+
Valid irq pins:
43+
Arduino Uno: 2, 3
44+
Arduino Due: All pins, except 13 (LED)
45+
Arduino Mega: 2, 3, 18, 19, 20, 21
46+
Teensy 2.0: All pins, except 13 (LED)
47+
Teensy 2.0: 5, 6, 7, 8
48+
Teensy 1.0: 0, 1, 2, 3, 4, 6, 7, 16
49+
Teensy++ 2.0: 0, 1, 2, 3, 18, 19, 36, 37
50+
Teensy++ 1.0: 0, 1, 2, 3, 18, 19, 36, 37
51+
Sanguino: 2, 10, 11
52+
53+
Created September 2014 based, on PS2Keyboard which was
54+
Written by Christian Weichel <[email protected]>
55+
** Mostly rewritten Paul Stoffregen <[email protected]> 2010, 2011
56+
** Modified for use beginning with Arduino 13 by L. Abraham Smith, <[email protected]> *
57+
** Modified for easy interrupt pin assignment on method begin(datapin,irq_pin). Cuningan <[email protected]> **
58+
V1.0.1 Modified September 2014 Paul Carpenter for easier state machines and parity checks
59+
V1.0.2 Modified January 2016 to improve interrupt assignment with new Arduino macros
60+
61+
This library is free software; you can redistribute it and/or
62+
modify it under the terms of the GNU Lesser General Public
63+
License as published by the Free Software Foundation; either
64+
version 2.1 of the License, or (at your option) any later version.
65+
66+
This library is distributed in the hope that it will be useful,
67+
but WITHOUT ANY WARRANTY; without even the implied warranty of
68+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
69+
Lesser General Public License for more details.
70+
71+
You should have received a copy of the GNU Lesser General Public
72+
License along with this library; if not, write to the Free Software
73+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
74+
*/
75+
76+
#ifndef PS2KeyRaw_h
77+
#define PS2KeyRaw_h
78+
#include "Arduino.h" // for attachInterrupt, FALLING
79+
80+
/**
81+
* Purpose: Provides an easy access to PS2 keyboards
82+
* Author: Christian Weichel
83+
*/
84+
class PS2KeyRaw {
85+
public:
86+
/**
87+
* This constructor does basically nothing. Please call the begin(int,int)
88+
* method before using any other method of this class.
89+
*/
90+
PS2KeyRaw();
91+
92+
/**
93+
* Starts the keyboard "service" by registering the external interrupt.
94+
* setting the pin modes correctly and driving those needed to high.
95+
* The best place to call this method is in the setup routine.
96+
*/
97+
static void begin( uint8_t dataPin, uint8_t irq_pin );
98+
99+
/**
100+
* Returns number of bytes available.
101+
*/
102+
static int8_t available();
103+
104+
/**
105+
* Returns the char last read from the keyboard.
106+
* If there is no char available, -1 is returned.
107+
*/
108+
static int read();
109+
};
110+
#endif

0 commit comments

Comments
 (0)