Acorn Electron keyboard scanner, turns an old Acorn Electron into a USB keyboard.

Dependencies:   USBDevice mbed

Files at this revision

API Documentation at this revision

Comitter:
IH
Date:
Wed Apr 30 21:26:27 2014 +0000
Child:
1:84cd616cc684
Commit message:
Basic HID KBD working. Bedtime!

Changed in this revision

USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
hid_keys.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Wed Apr 30 21:26:27 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/USBDevice/#5b7d31d9d3f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hid_keys.h	Wed Apr 30 21:26:27 2014 +0000
@@ -0,0 +1,368 @@
+#ifndef USB_HID_KEYBOARD_H
+#define USB_HID_KEYBOARD_H
+
+/* Placed in the public domain by its author, Ian Harvey */
+
+/* Modifier key bit values */
+
+#define MODBIT_LEFT_CTRL        0x01
+#define MODBIT_LEFT_SHIFT       0x02
+#define MODBIT_LEFT_ALT         0x04
+#define MODBIT_LEFT_GUI         0x08
+#define MODBIT_RIGHT_CTRL       0x10
+#define MODBIT_RIGHT_SHIFT      0x20
+#define MODBIT_RIGHT_ALT        0x40
+#define MODBIT_RIGHT_GUI        0x80
+
+/* From USB HID Usage Tables Version 1.12, Section 10 */
+
+#define KEY_NONE            0
+#define KEY_ErrorRollOver   1
+#define KEY_POSTFail        2
+#define KEY_ErrorUndefined  3
+#define KEY_A   4
+#define KEY_B   5
+#define KEY_C   6
+#define KEY_D   7
+#define KEY_E   8
+#define KEY_F   9
+#define KEY_G   10
+#define KEY_H   11
+#define KEY_I   12
+#define KEY_J   13
+#define KEY_K   14
+#define KEY_L   15
+#define KEY_M   16
+#define KEY_N   17
+#define KEY_O   18
+#define KEY_P   19
+#define KEY_Q   20
+#define KEY_R   21
+#define KEY_S   22
+#define KEY_T   23
+#define KEY_U   24
+#define KEY_V   25
+#define KEY_W   26
+#define KEY_X   27
+#define KEY_Y   28
+#define KEY_Z   29
+#define KEY_1   30
+#define KEY_2   31
+#define KEY_3   32
+#define KEY_4   33
+#define KEY_5   34
+#define KEY_6   35
+#define KEY_7   36
+#define KEY_8   37
+#define KEY_9   38
+#define KEY_0   39
+
+#define KEY_ENTER       40
+#define KEY_ESC         41
+#define KEY_BACKSPACE   42
+#define KEY_TAB         43
+#define KEY_SPACE       44
+#define KEY_MINUS       45 /* And underscore */
+#define KEY_EQUALS      46 /* And plus */
+#define KEY_OPEN_SQUARE 47 /* And open-curly-bracket */
+#define KEY_CLOSE_SQUARE    48 /* And close-curly-bracket */
+#define KEY_BACKSLASH   49
+#define KEY_HASH_TILDE  50
+#define KEY_SEMICOLON   51
+#define KEY_SINGLE_QUOTE    52
+#define KEY_BACKTICK_TILDE  53
+#define KEY_COMMA       54 /* And less-than */
+#define KEY_PERIOD      55 /* And greater-than */
+#define KEY_SLASH       56 /* And question-mark */
+#define KEY_CAPS_LOCK   57
+
+#define KEY_F1          58
+#define KEY_F2          59
+#define KEY_F3          60
+#define KEY_F4          61
+#define KEY_F5          62
+#define KEY_F6          63
+#define KEY_F7          64
+#define KEY_F8          65
+#define KEY_F9          66
+#define KEY_F10         67
+#define KEY_F11         68
+#define KEY_F12         69
+
+#define KEY_PRINT_SCREEN    70
+#define KEY_SCROLL_LOCK     71
+#define KEY_PAUSE       72
+#define KEY_INSERT      73
+#define KEY_HOME        74
+#define KEY_PAGE_UP     75
+#define KEY_DELETE      76 /* i.e. forward delete */
+#define KEY_END         77
+#define KEY_PAGE_DOWN   78
+#define KEY_RIGHT_ARROW 79
+#define KEY_LEFT_ARROW  80
+#define KEY_DOWN_ARROW  81
+#define KEY_UP_ARROW    82
+
+/* TODO: keypad codes */
+
+#define KEY_LEFT_CTRL       0xE0
+#define KEY_LEFT_SHIFT      0xE1
+#define KEY_LEFT_ALT        0xE2
+#define KEY_LEFT_GUI        0xE3
+#define KEY_RIGHT_CTRL      0xE4
+#define KEY_RIGHT_SHIFT     0xE5
+#define KEY_RIGHT_ALT       0xE6
+#define KEY_RIGHT_GUI       0xE7
+
+#define KEY_MODIFIERS_START 0xE0
+#define KEY_MODIFIERS_END   0xE7
+#define IS_MODIFIER(key) ((key) >= KEY_MODIFIERS_START && (key) <= KEY_MODIFIERS_END)
+#define MODIFIER_BIT(key) (1 << ((key)-KEY_MODIFIERS_START))
+
+
+
+#endif /* USB_HID_KEYBOARD_H */
+#ifndef USB_HID_KEYBOARD_H
+#define USB_HID_KEYBOARD_H
+
+/* Modifier key bit values */
+
+#define MODBIT_LEFT_CTRL        0x01
+#define MODBIT_LEFT_SHIFT       0x02
+#define MODBIT_LEFT_ALT         0x04
+#define MODBIT_LEFT_GUI         0x08
+#define MODBIT_RIGHT_CTRL       0x10
+#define MODBIT_RIGHT_SHIFT      0x20
+#define MODBIT_RIGHT_ALT        0x40
+#define MODBIT_RIGHT_GUI        0x80
+
+/* From USB HID Usage Tables Version 1.12, Section 10 */
+
+#define KEY_NONE            0
+#define KEY_ErrorRollOver   1
+#define KEY_POSTFail        2
+#define KEY_ErrorUndefined  3
+#define KEY_A   4
+#define KEY_B   5
+#define KEY_C   6
+#define KEY_D   7
+#define KEY_E   8
+#define KEY_F   9
+#define KEY_G   10
+#define KEY_H   11
+#define KEY_I   12
+#define KEY_J   13
+#define KEY_K   14
+#define KEY_L   15
+#define KEY_M   16
+#define KEY_N   17
+#define KEY_O   18
+#define KEY_P   19
+#define KEY_Q   20
+#define KEY_R   21
+#define KEY_S   22
+#define KEY_T   23
+#define KEY_U   24
+#define KEY_V   25
+#define KEY_W   26
+#define KEY_X   27
+#define KEY_Y   28
+#define KEY_Z   29
+#define KEY_1   30
+#define KEY_2   31
+#define KEY_3   32
+#define KEY_4   33
+#define KEY_5   34
+#define KEY_6   35
+#define KEY_7   36
+#define KEY_8   37
+#define KEY_9   38
+#define KEY_0   39
+
+#define KEY_ENTER       40
+#define KEY_ESC         41
+#define KEY_BACKSPACE   42
+#define KEY_TAB         43
+#define KEY_SPACE       44
+#define KEY_MINUS       45 /* And underscore */
+#define KEY_EQUALS      46 /* And plus */
+#define KEY_OPEN_SQUARE 47 /* And open-curly-bracket */
+#define KEY_CLOSE_SQUARE    48 /* And close-curly-bracket */
+#define KEY_BACKSLASH   49
+#define KEY_HASH_TILDE  50
+#define KEY_SEMICOLON   51
+#define KEY_SINGLE_QUOTE    52
+#define KEY_BACKTICK_TILDE  53
+#define KEY_COMMA       54 /* And less-than */
+#define KEY_PERIOD      55 /* And greater-than */
+#define KEY_SLASH       56 /* And question-mark */
+#define KEY_CAPS_LOCK   57
+
+#define KEY_F1          58
+#define KEY_F2          59
+#define KEY_F3          60
+#define KEY_F4          61
+#define KEY_F5          62
+#define KEY_F6          63
+#define KEY_F7          64
+#define KEY_F8          65
+#define KEY_F9          66
+#define KEY_F10         67
+#define KEY_F11         68
+#define KEY_F12         69
+
+#define KEY_PRINT_SCREEN    70
+#define KEY_SCROLL_LOCK     71
+#define KEY_PAUSE       72
+#define KEY_INSERT      73
+#define KEY_HOME        74
+#define KEY_PAGE_UP     75
+#define KEY_DELETE      76 /* i.e. forward delete */
+#define KEY_END         77
+#define KEY_PAGE_DOWN   78
+#define KEY_RIGHT_ARROW 79
+#define KEY_LEFT_ARROW  80
+#define KEY_DOWN_ARROW  81
+#define KEY_UP_ARROW    82
+
+/* TODO: keypad codes */
+
+#define KEY_LEFT_CTRL       0xE0
+#define KEY_LEFT_SHIFT      0xE1
+#define KEY_LEFT_ALT        0xE2
+#define KEY_LEFT_GUI        0xE3
+#define KEY_RIGHT_CTRL      0xE4
+#define KEY_RIGHT_SHIFT     0xE5
+#define KEY_RIGHT_ALT       0xE6
+#define KEY_RIGHT_GUI       0xE7
+
+#define KEY_MODIFIERS_START 0xE0
+#define KEY_MODIFIERS_END   0xE7
+#define IS_MODIFIER(key) ((key) >= KEY_MODIFIERS_START && (key) <= KEY_MODIFIERS_END)
+#define MODIFIER_BIT(key) (1 << ((key)-KEY_MODIFIERS_START))
+
+
+
+#endif /* USB_HID_KEYBOARD_H */
+#ifndef USB_HID_KEYBOARD_H
+#define USB_HID_KEYBOARD_H
+
+/* Modifier key bit values */
+
+#define MODBIT_LEFT_CTRL        0x01
+#define MODBIT_LEFT_SHIFT       0x02
+#define MODBIT_LEFT_ALT         0x04
+#define MODBIT_LEFT_GUI         0x08
+#define MODBIT_RIGHT_CTRL       0x10
+#define MODBIT_RIGHT_SHIFT      0x20
+#define MODBIT_RIGHT_ALT        0x40
+#define MODBIT_RIGHT_GUI        0x80
+
+/* From USB HID Usage Tables Version 1.12, Section 10 */
+
+#define KEY_NONE            0
+#define KEY_ErrorRollOver   1
+#define KEY_POSTFail        2
+#define KEY_ErrorUndefined  3
+#define KEY_A   4
+#define KEY_B   5
+#define KEY_C   6
+#define KEY_D   7
+#define KEY_E   8
+#define KEY_F   9
+#define KEY_G   10
+#define KEY_H   11
+#define KEY_I   12
+#define KEY_J   13
+#define KEY_K   14
+#define KEY_L   15
+#define KEY_M   16
+#define KEY_N   17
+#define KEY_O   18
+#define KEY_P   19
+#define KEY_Q   20
+#define KEY_R   21
+#define KEY_S   22
+#define KEY_T   23
+#define KEY_U   24
+#define KEY_V   25
+#define KEY_W   26
+#define KEY_X   27
+#define KEY_Y   28
+#define KEY_Z   29
+#define KEY_1   30
+#define KEY_2   31
+#define KEY_3   32
+#define KEY_4   33
+#define KEY_5   34
+#define KEY_6   35
+#define KEY_7   36
+#define KEY_8   37
+#define KEY_9   38
+#define KEY_0   39
+
+#define KEY_ENTER       40
+#define KEY_ESC         41
+#define KEY_BACKSPACE   42
+#define KEY_TAB         43
+#define KEY_SPACE       44
+#define KEY_MINUS       45 /* And underscore */
+#define KEY_EQUALS      46 /* And plus */
+#define KEY_OPEN_SQUARE 47 /* And open-curly-bracket */
+#define KEY_CLOSE_SQUARE    48 /* And close-curly-bracket */
+#define KEY_BACKSLASH   49
+#define KEY_HASH_TILDE  50
+#define KEY_SEMICOLON   51
+#define KEY_SINGLE_QUOTE    52
+#define KEY_BACKTICK_TILDE  53
+#define KEY_COMMA       54 /* And less-than */
+#define KEY_PERIOD      55 /* And greater-than */
+#define KEY_SLASH       56 /* And question-mark */
+#define KEY_CAPS_LOCK   57
+
+#define KEY_F1          58
+#define KEY_F2          59
+#define KEY_F3          60
+#define KEY_F4          61
+#define KEY_F5          62
+#define KEY_F6          63
+#define KEY_F7          64
+#define KEY_F8          65
+#define KEY_F9          66
+#define KEY_F10         67
+#define KEY_F11         68
+#define KEY_F12         69
+
+#define KEY_PRINT_SCREEN    70
+#define KEY_SCROLL_LOCK     71
+#define KEY_PAUSE       72
+#define KEY_INSERT      73
+#define KEY_HOME        74
+#define KEY_PAGE_UP     75
+#define KEY_DELETE      76 /* i.e. forward delete */
+#define KEY_END         77
+#define KEY_PAGE_DOWN   78
+#define KEY_RIGHT_ARROW 79
+#define KEY_LEFT_ARROW  80
+#define KEY_DOWN_ARROW  81
+#define KEY_UP_ARROW    82
+
+/* TODO: keypad codes */
+
+#define KEY_LEFT_CTRL       0xE0
+#define KEY_LEFT_SHIFT      0xE1
+#define KEY_LEFT_ALT        0xE2
+#define KEY_LEFT_GUI        0xE3
+#define KEY_RIGHT_CTRL      0xE4
+#define KEY_RIGHT_SHIFT     0xE5
+#define KEY_RIGHT_ALT       0xE6
+#define KEY_RIGHT_GUI       0xE7
+
+#define KEY_MODIFIERS_START 0xE0
+#define KEY_MODIFIERS_END   0xE7
+#define IS_MODIFIER(key) ((key) >= KEY_MODIFIERS_START && (key) <= KEY_MODIFIERS_END)
+#define MODIFIER_BIT(key) (1 << ((key)-KEY_MODIFIERS_START))
+
+
+
+#endif /* USB_HID_KEYBOARD_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 30 21:26:27 2014 +0000
@@ -0,0 +1,112 @@
+#include "mbed.h"
+#include "USBKeyboard.h"
+#include "hid_keys.h"
+
+#define MAX_ROWS 5
+#define MAX_COLS 14
+#define REPORT_LEN 9
+#define REPORT_ID_KEYBOARD 1
+
+const uint8_t hid_keys[MAX_ROWS * MAX_COLS] = 
+{
+    KEY_PERIOD,     KEY_L,          KEY_O,      KEY_9,      KEY_BACKSPACE,
+    KEY_SLASH,      KEY_SEMICOLON,  KEY_P,      KEY_0,      KEY_NONE,
+    KEY_NONE,       KEY_EQUALS,     KEY_UP_ARROW,   KEY_MINUS, KEY_NONE,
+    KEY_DELETE,     KEY_ENTER,      KEY_DOWN_ARROW, KEY_LEFT_ARROW, KEY_NONE,
+    KEY_SPACE,      KEY_NONE,       KEY_OPEN_SQUARE, KEY_RIGHT_ARROW, KEY_NONE,
+    KEY_COMMA,      KEY_K,          KEY_I,      KEY_8,      KEY_NONE,
+    KEY_M,          KEY_J,          KEY_U,      KEY_7,      KEY_NONE,
+    KEY_N,          KEY_H,          KEY_Y,      KEY_6,      KEY_NONE,
+    KEY_B,          KEY_G,          KEY_T,      KEY_5,      KEY_NONE,
+    KEY_V,          KEY_F,          KEY_R,      KEY_4,      KEY_NONE,
+    KEY_C,          KEY_D,          KEY_E,      KEY_3,      KEY_NONE,
+    KEY_X,          KEY_S,          KEY_W,      KEY_2,      KEY_NONE,
+    KEY_Z,          KEY_A,          KEY_Q,      KEY_1,      KEY_NONE,
+    KEY_LEFT_SHIFT, KEY_LEFT_CTRL,  KEY_TAB,    KEY_ESC,    KEY_NONE,
+};
+
+
+BusOut leds(LED1, LED2, LED3);
+
+BusOut scanCols(
+    PTC10,PTC8, 
+    PTC6, PTA5,   
+    PTC5, PTA4,  
+    PTC4, PTA12,
+    PTC3, PTD4,   
+    PTC0, PTA2,  
+    PTC7, PTA1  
+    );
+
+BusIn inRows(
+    PTB10,
+    PTB11,
+    PTE2,
+    PTE3,
+    PTE5 );
+
+DigitalOut extLed(PTE4);
+
+USBKeyboard kbd;
+
+static int scanColumn(int col)
+{
+    int rowBits;
+    // Drive output low to scan
+    scanCols.write(0x3FFF ^ (1 << col));
+    leds.write(col >> 1);
+    wait(0.01);
+    rowBits = inRows.read();
+    scanCols.write(0x3FFF);
+    // Inputs also active-low
+    return rowBits ^ 0x1F;
+}
+    
+int main()
+{
+    // Setup
+    inRows.mode(PullUp);
+    extLed = 1;
+
+    // Run loop
+    while(1)
+    {
+        int col, ocount;
+        HID_REPORT report;
+        
+        report.data[0] = REPORT_ID_KEYBOARD;
+        report.data[1] = 0; // modifiers
+        report.data[2] = 0;
+        ocount = 3;
+        
+        for (col=0; col < MAX_COLS; col++)
+        {
+            int row;
+            int rowBits = scanColumn(col);
+            if ( !rowBits )
+              continue;
+            
+            for (row=0; row < MAX_ROWS; row++)
+            {
+              if ( rowBits & (1 << row) )
+              {
+                uint8_t key = hid_keys[col * MAX_ROWS + row];
+                if ( IS_MODIFIER(key) )
+                  report.data[1] |= MODIFIER_BIT(key);
+                else if ( key != KEY_NONE )
+                {
+                  if ( ocount < REPORT_LEN )
+                    report.data[ocount++] = key;
+                }
+                //kbd.printf("c%dr%d ", col, row);
+              }
+            }
+        }
+
+        while( ocount < REPORT_LEN )
+          report.data[ocount++] = KEY_NONE;
+            
+        report.length = REPORT_LEN;  
+        kbd.send(&report);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 30 21:26:27 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/8a40adfe8776
\ No newline at end of file