A project to implement a console using the Mbed using VGA for video output and a PS/2 keyboard for the input. The eventual goal is to also include tools for managing SD cards, and a semi-self-hosting programming environment.

Dependencies:   PS2_MbedConsole fastlib SDFileSystem vga640x480g_mbedconsole lightvm mbed

MbedConsole is a cool little project to have a self-contained computer all on an Mbed. So far it has VGA and PS/2 support and can stand alone without a computer powering it. Next planned features are SD card support and a lightweight programmable VM complete with a file editor and self-hosted assembler.

You can view additional details about it at http://earlz.net/tags/mbedconsole

Committer:
earlz
Date:
Wed Sep 26 05:22:44 2012 +0000
Revision:
10:bda85442b674
Child:
11:fede136943a9
AlloyOS' keyboard driver port is mostly a success. Problem now is that apparently our translation set is for scancode set 1 and not scancode set 2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
earlz 10:bda85442b674 1 #include "mbedconsole.h"
earlz 10:bda85442b674 2 /**This is basically a straight rip off of my x86 OS project AlloyOS. I just ported the keyboard driver from it cause it always treated me well**/
earlz 10:bda85442b674 3
earlz 10:bda85442b674 4
earlz 10:bda85442b674 5 #define KEYBOARD_DATAPIN p11
earlz 10:bda85442b674 6 #define KEYBOARD_CLOCKPIN p12
earlz 10:bda85442b674 7
earlz 10:bda85442b674 8 //how many keys the buffer can hold
earlz 10:bda85442b674 9 #define KBD_BUFFER_SIZE 128
earlz 10:bda85442b674 10
earlz 10:bda85442b674 11 //key defines
earlz 10:bda85442b674 12 #define LSHIFT_KEY 42
earlz 10:bda85442b674 13 #define RSHIFT_KEY 54
earlz 10:bda85442b674 14 #define CTRL_KEY 29
earlz 10:bda85442b674 15 #define ALT_KEY 56
earlz 10:bda85442b674 16 #define CAPS_KEY 58
earlz 10:bda85442b674 17 #define NUM_KEY 69
earlz 10:bda85442b674 18 #define SCROLL_KEY 70
earlz 10:bda85442b674 19 #define F_BASE_KEY 59 //59 is F1, 60 is F2, and so on until F10
earlz 10:bda85442b674 20 #define HOME_KEY 71
earlz 10:bda85442b674 21 #define UP_KEY 72
earlz 10:bda85442b674 22 #define PAGE_UP_KEY 73
earlz 10:bda85442b674 23 #define LEFT_KEY 75
earlz 10:bda85442b674 24 #define RIGHT_KEY 77
earlz 10:bda85442b674 25 #define END_KEY 79
earlz 10:bda85442b674 26 #define DOWN_KEY 80
earlz 10:bda85442b674 27 #define PAGE_DOWN_KEY 81
earlz 10:bda85442b674 28 #define INSERT_KEY 82
earlz 10:bda85442b674 29 #define DEL_KEY 83
earlz 10:bda85442b674 30 #define F11_KEY 87
earlz 10:bda85442b674 31 #define F12_KEY 89
earlz 10:bda85442b674 32
earlz 10:bda85442b674 33 #define SCROLL_LED 1
earlz 10:bda85442b674 34 #define NUM_LED 2
earlz 10:bda85442b674 35 #define CAPS_LED 4
earlz 10:bda85442b674 36
earlz 10:bda85442b674 37
earlz 10:bda85442b674 38 const char kbdus[128] =
earlz 10:bda85442b674 39 {
earlz 10:bda85442b674 40 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
earlz 10:bda85442b674 41 '9', '0', '-', '=', '\b', /* Backspace */
earlz 10:bda85442b674 42 '\t', /* Tab */
earlz 10:bda85442b674 43 'q', 'w', 'e', 'r', /* 19 */
earlz 10:bda85442b674 44 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
earlz 10:bda85442b674 45 0, /* 29 - Control */
earlz 10:bda85442b674 46 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
earlz 10:bda85442b674 47 '\'', '`', 0, /* Left shift */
earlz 10:bda85442b674 48 '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
earlz 10:bda85442b674 49 'm', ',', '.', '/', 0, /* Right shift */
earlz 10:bda85442b674 50 '*',
earlz 10:bda85442b674 51 0, /* Alt */
earlz 10:bda85442b674 52 ' ', /* Space bar */
earlz 10:bda85442b674 53 0, /* Caps lock */
earlz 10:bda85442b674 54 0, /* 59 - F1 key ... > */
earlz 10:bda85442b674 55 0, 0, 0, 0, 0, 0, 0, 0,
earlz 10:bda85442b674 56 0, /* < ... F10 */
earlz 10:bda85442b674 57 0, /* 69 - Num lock*/
earlz 10:bda85442b674 58 0, /* Scroll Lock */
earlz 10:bda85442b674 59 0, /* Home key */
earlz 10:bda85442b674 60 0, /* Up Arrow */
earlz 10:bda85442b674 61 0, /* Page Up */
earlz 10:bda85442b674 62 '-',
earlz 10:bda85442b674 63 0, /* Left Arrow */
earlz 10:bda85442b674 64 0,
earlz 10:bda85442b674 65 0, /* Right Arrow */
earlz 10:bda85442b674 66 '+',
earlz 10:bda85442b674 67 0, /* 79 - End key*/
earlz 10:bda85442b674 68 0, /* Down Arrow */
earlz 10:bda85442b674 69 0, /* Page Down */
earlz 10:bda85442b674 70 0, /* Insert Key */
earlz 10:bda85442b674 71 0, /* Delete Key */
earlz 10:bda85442b674 72 0, 0, 0,
earlz 10:bda85442b674 73 0, /* F11 Key */
earlz 10:bda85442b674 74 0, /* F12 Key */
earlz 10:bda85442b674 75 0, /* All other keys are undefined */
earlz 10:bda85442b674 76 };
earlz 10:bda85442b674 77
earlz 10:bda85442b674 78 const char kbdus_caps[128] =
earlz 10:bda85442b674 79 {
earlz 10:bda85442b674 80 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
earlz 10:bda85442b674 81 '(', ')', '_', '+', '\b', /* Backspace */
earlz 10:bda85442b674 82 '\t', /* Tab */
earlz 10:bda85442b674 83 'Q', 'W', 'E', 'R', /* 19 */
earlz 10:bda85442b674 84 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter key */
earlz 10:bda85442b674 85 0, /* 29 - Control */
earlz 10:bda85442b674 86 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
earlz 10:bda85442b674 87 '"', '~', 0, /* Left shift */
earlz 10:bda85442b674 88 '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */
earlz 10:bda85442b674 89 'M', '<', '>', '?', 0, /* Right shift */
earlz 10:bda85442b674 90 '*',
earlz 10:bda85442b674 91 0, /* Alt */
earlz 10:bda85442b674 92 ' ', /* Space bar */
earlz 10:bda85442b674 93 0, /* Caps lock */
earlz 10:bda85442b674 94 0, /* 59 - F1 key ... > */
earlz 10:bda85442b674 95 0, 0, 0, 0, 0, 0, 0, 0,
earlz 10:bda85442b674 96 0, /* < ... F10 */
earlz 10:bda85442b674 97 0, /* 69 - Num lock*/
earlz 10:bda85442b674 98 0, /* Scroll Lock */
earlz 10:bda85442b674 99 0, /* Home key */
earlz 10:bda85442b674 100 0, /* Up Arrow */
earlz 10:bda85442b674 101 0, /* Page Up */
earlz 10:bda85442b674 102 '-',
earlz 10:bda85442b674 103 0, /* Left Arrow */
earlz 10:bda85442b674 104 0,
earlz 10:bda85442b674 105 0, /* Right Arrow */
earlz 10:bda85442b674 106 '+',
earlz 10:bda85442b674 107 0, /* 79 - End key*/
earlz 10:bda85442b674 108 0, /* Down Arrow */
earlz 10:bda85442b674 109 0, /* Page Down */
earlz 10:bda85442b674 110 0, /* Insert Key */
earlz 10:bda85442b674 111 0, /* Delete Key */
earlz 10:bda85442b674 112 0, 0, 0,
earlz 10:bda85442b674 113 0, /* F11 Key */
earlz 10:bda85442b674 114 0, /* F12 Key */
earlz 10:bda85442b674 115 0, /* All other keys are undefined */
earlz 10:bda85442b674 116 };
earlz 10:bda85442b674 117
earlz 10:bda85442b674 118
earlz 10:bda85442b674 119 typedef struct {
earlz 10:bda85442b674 120 unsigned char caps;
earlz 10:bda85442b674 121 unsigned char shift;
earlz 10:bda85442b674 122 unsigned char scroll;
earlz 10:bda85442b674 123 unsigned char num;
earlz 10:bda85442b674 124 unsigned char ctrl;
earlz 10:bda85442b674 125 unsigned char alt;
earlz 10:bda85442b674 126 }
earlz 10:bda85442b674 127 shift_locks; /*for simplicity and speed*/
earlz 10:bda85442b674 128
earlz 10:bda85442b674 129 extern volatile shift_locks kbd_shifts;
earlz 10:bda85442b674 130
earlz 10:bda85442b674 131
earlz 10:bda85442b674 132 typedef struct {
earlz 10:bda85442b674 133 uint16_t scancode;
earlz 10:bda85442b674 134 uint8_t asci;
earlz 10:bda85442b674 135 }kbd_key;
earlz 10:bda85442b674 136
earlz 10:bda85442b674 137
earlz 10:bda85442b674 138 PS2KB_INIT *ps2_kb_init;
earlz 10:bda85442b674 139 PS2KB *ps2_kb;
earlz 10:bda85442b674 140
earlz 10:bda85442b674 141 volatile kbd_key *keys;
earlz 10:bda85442b674 142 volatile uint8_t current_key=0;
earlz 10:bda85442b674 143 volatile uint8_t key_got=0;
earlz 10:bda85442b674 144 volatile char pending_key=0;
earlz 10:bda85442b674 145 volatile uint8_t led_status=0;
earlz 10:bda85442b674 146
earlz 10:bda85442b674 147 void keyboard_callback(PS2KB kb, uint8_t val);
earlz 10:bda85442b674 148
earlz 10:bda85442b674 149 void keyboard_init()
earlz 10:bda85442b674 150 {
earlz 10:bda85442b674 151 keys=(kbd_key*)malloc(256*sizeof(kbd_key));
earlz 10:bda85442b674 152 kbd_shifts.shift=0;
earlz 10:bda85442b674 153 kbd_shifts.caps=0;
earlz 10:bda85442b674 154 kbd_shifts.num=0;
earlz 10:bda85442b674 155 kbd_shifts.scroll=0;
earlz 10:bda85442b674 156 kbd_shifts.ctrl=0;
earlz 10:bda85442b674 157 kbd_shifts.alt=0;
earlz 10:bda85442b674 158 ps2_kb_init=new PS2KB_INIT(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN);
earlz 10:bda85442b674 159 ps2_kb=new PS2KB(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN, (KeyboardCallback) &keyboard_callback);
earlz 10:bda85442b674 160 }
earlz 10:bda85442b674 161
earlz 10:bda85442b674 162
earlz 10:bda85442b674 163
earlz 10:bda85442b674 164 volatile shift_locks kbd_shifts;
earlz 10:bda85442b674 165
earlz 10:bda85442b674 166
earlz 10:bda85442b674 167
earlz 10:bda85442b674 168 /**The way the keyboard driver works is this:
earlz 10:bda85442b674 169 the buffer is 256 elements big. key_got and current_key are both
earlz 10:bda85442b674 170 bytes. Rather than setting current_key to 0, the entire buffer is constantly
earlz 10:bda85442b674 171 in use. when a key is pushed, current key is incremented. when a key is got(with safety checks)
earlz 10:bda85442b674 172 key_got is incremented. Also, when it reaches the end of the buffer, it simply wraps around
earlz 10:bda85442b674 173 to the beginning due to byte overflow. The worst that can happen is if 256 bytes get
earlz 10:bda85442b674 174 built up, in which case everything will be screwed up.. I should eventually controlt he capture
earlz 10:bda85442b674 175 of these keys to where not all of them are stored, and they are only stored when needed**/
earlz 10:bda85442b674 176
earlz 10:bda85442b674 177 int kbd_PutBuffer(uint16_t scan,uint8_t asci){
earlz 10:bda85442b674 178 keys[current_key].scancode=scan;
earlz 10:bda85442b674 179 keys[current_key].asci=asci;
earlz 10:bda85442b674 180 current_key++;
earlz 10:bda85442b674 181 pending_key++;;
earlz 10:bda85442b674 182 return 0;
earlz 10:bda85442b674 183 }
earlz 10:bda85442b674 184
earlz 10:bda85442b674 185 kbd_key kbd_PopBuffer(){
earlz 10:bda85442b674 186 kbd_key k;
earlz 10:bda85442b674 187 while(pending_key==0){
earlz 10:bda85442b674 188 //hlt();
earlz 10:bda85442b674 189 //fill in busy code here
earlz 10:bda85442b674 190 }
earlz 10:bda85442b674 191
earlz 10:bda85442b674 192 k.scancode=keys[key_got].scancode;
earlz 10:bda85442b674 193 k.asci=keys[key_got].asci;
earlz 10:bda85442b674 194 pending_key--;
earlz 10:bda85442b674 195 key_got++;
earlz 10:bda85442b674 196 return k;
earlz 10:bda85442b674 197 }
earlz 10:bda85442b674 198
earlz 10:bda85442b674 199 uint8_t kbd_GetKey(){ //this will just return the asci code
earlz 10:bda85442b674 200 kbd_key k;
earlz 10:bda85442b674 201 k.asci=0;
earlz 10:bda85442b674 202 while(k.asci==0){
earlz 10:bda85442b674 203 k=kbd_PopBuffer();
earlz 10:bda85442b674 204 }
earlz 10:bda85442b674 205 return k.asci;
earlz 10:bda85442b674 206 }
earlz 10:bda85442b674 207
earlz 10:bda85442b674 208
earlz 10:bda85442b674 209 void kbd_update_leds(uint8_t status){
earlz 10:bda85442b674 210 uint8_t tmp;
earlz 10:bda85442b674 211 //TODO
earlz 10:bda85442b674 212 /*while((inportb(0x64)&2)!=0){}
earlz 10:bda85442b674 213 outportb(0x60,0xED);
earlz 10:bda85442b674 214
earlz 10:bda85442b674 215 while((inportb(0x64)&2)!=0){}
earlz 10:bda85442b674 216 outportb(0x60,status);
earlz 10:bda85442b674 217 */
earlz 10:bda85442b674 218 }
earlz 10:bda85442b674 219
earlz 10:bda85442b674 220
earlz 10:bda85442b674 221
earlz 10:bda85442b674 222 int kbd_DoShifts(uint8_t scan){
earlz 10:bda85442b674 223 switch(scan){
earlz 10:bda85442b674 224 case RSHIFT_KEY:
earlz 10:bda85442b674 225 kbd_shifts.shift++;
earlz 10:bda85442b674 226 break;
earlz 10:bda85442b674 227 case LSHIFT_KEY:
earlz 10:bda85442b674 228 kbd_shifts.shift++;
earlz 10:bda85442b674 229 break;
earlz 10:bda85442b674 230 case CTRL_KEY:
earlz 10:bda85442b674 231 kbd_shifts.ctrl++;
earlz 10:bda85442b674 232 break;
earlz 10:bda85442b674 233 case ALT_KEY:
earlz 10:bda85442b674 234 kbd_shifts.alt++;
earlz 10:bda85442b674 235 break;
earlz 10:bda85442b674 236 case CAPS_KEY:
earlz 10:bda85442b674 237 led_status^=CAPS_LED;
earlz 10:bda85442b674 238 kbd_update_leds(led_status);
earlz 10:bda85442b674 239 kbd_shifts.caps^=1;
earlz 10:bda85442b674 240 break;
earlz 10:bda85442b674 241 case NUM_KEY:
earlz 10:bda85442b674 242 led_status^=NUM_LED;
earlz 10:bda85442b674 243 kbd_update_leds(led_status);
earlz 10:bda85442b674 244 kbd_shifts.num^=1;
earlz 10:bda85442b674 245 break;
earlz 10:bda85442b674 246 case SCROLL_KEY:
earlz 10:bda85442b674 247 led_status^=SCROLL_LED;
earlz 10:bda85442b674 248 kbd_update_leds(led_status);
earlz 10:bda85442b674 249 kbd_shifts.scroll^=1;
earlz 10:bda85442b674 250 break;
earlz 10:bda85442b674 251 default:
earlz 10:bda85442b674 252 return 0;
earlz 10:bda85442b674 253 break;
earlz 10:bda85442b674 254 }
earlz 10:bda85442b674 255 return 1;
earlz 10:bda85442b674 256 }
earlz 10:bda85442b674 257
earlz 10:bda85442b674 258 int kbd_DoUnshifts(uint8_t scan){
earlz 10:bda85442b674 259 switch(scan){
earlz 10:bda85442b674 260 case RSHIFT_KEY:
earlz 10:bda85442b674 261 kbd_shifts.shift--;
earlz 10:bda85442b674 262 break;
earlz 10:bda85442b674 263 case LSHIFT_KEY:
earlz 10:bda85442b674 264 kbd_shifts.shift--;
earlz 10:bda85442b674 265 break;
earlz 10:bda85442b674 266 case CTRL_KEY:
earlz 10:bda85442b674 267 kbd_shifts.ctrl--;
earlz 10:bda85442b674 268 break;
earlz 10:bda85442b674 269 case ALT_KEY:
earlz 10:bda85442b674 270 kbd_shifts.alt--;
earlz 10:bda85442b674 271 break;
earlz 10:bda85442b674 272 case CAPS_KEY:
earlz 10:bda85442b674 273 //kbd_shifts.caps=0;
earlz 10:bda85442b674 274 break;
earlz 10:bda85442b674 275 case NUM_KEY:
earlz 10:bda85442b674 276 //kbd_shifts.num=0;
earlz 10:bda85442b674 277 break;
earlz 10:bda85442b674 278 case SCROLL_KEY:
earlz 10:bda85442b674 279 //kbd_shifts.scroll=0;
earlz 10:bda85442b674 280 break;
earlz 10:bda85442b674 281 default:
earlz 10:bda85442b674 282 return 0;
earlz 10:bda85442b674 283 break;
earlz 10:bda85442b674 284 }
earlz 10:bda85442b674 285 return 1;
earlz 10:bda85442b674 286 }
earlz 10:bda85442b674 287 volatile bool expecting_break=false;
earlz 10:bda85442b674 288 void keyboard_callback(PS2KB kb, uint8_t val) //this is called from interrupt! Must be fast
earlz 10:bda85442b674 289 {
earlz 10:bda85442b674 290 //stopints();
earlz 10:bda85442b674 291 if(expecting_break){
earlz 10:bda85442b674 292 val^=0x80;
earlz 10:bda85442b674 293 kbd_DoUnshifts(val);
earlz 10:bda85442b674 294 expecting_break=false;
earlz 10:bda85442b674 295 }else{
earlz 10:bda85442b674 296 if(val>=0x80){
earlz 10:bda85442b674 297 expecting_break=true;
earlz 10:bda85442b674 298 }else{
earlz 10:bda85442b674 299 if(kbd_DoShifts(val)==0){ //if not a shift-type key
earlz 10:bda85442b674 300
earlz 10:bda85442b674 301 if ((kbd_shifts.caps^kbd_shifts.shift)==1) {
earlz 10:bda85442b674 302 kbd_PutBuffer(val,kbdus_caps[val]);
earlz 10:bda85442b674 303 }else{
earlz 10:bda85442b674 304 kbd_PutBuffer(val,kbdus[val]);
earlz 10:bda85442b674 305 }
earlz 10:bda85442b674 306 }
earlz 10:bda85442b674 307 }
earlz 10:bda85442b674 308 }
earlz 10:bda85442b674 309 }
earlz 10:bda85442b674 310
earlz 10:bda85442b674 311