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:
Fri Sep 28 04:35:00 2012 +0000
Revision:
12:3ee3062cc11c
Parent:
11:fede136943a9
Child:
16:370b9e559f92
Converted to completely use PS/2 keyboard for console; Also added a couple of commands

Who changed what in which revision?

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