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:
Mon Apr 15 02:37:02 2013 +0000
Revision:
20:13556e5bac04
Parent:
16:370b9e559f92
Finally got SD card support working. WOW that was trickier than I expected

Who changed what in which revision?

UserRevisionLine numberNew contents of line
earlz 16:370b9e559f92 1 /*
earlz 16:370b9e559f92 2 <Copyright Header>
earlz 16:370b9e559f92 3 Copyright (c) 2012 Jordan "Earlz" Earls <http://lastyearswishes.com>
earlz 16:370b9e559f92 4 All rights reserved.
earlz 16:370b9e559f92 5
earlz 16:370b9e559f92 6 Redistribution and use in source and binary forms, with or without
earlz 16:370b9e559f92 7 modification, are permitted provided that the following conditions
earlz 16:370b9e559f92 8 are met:
earlz 16:370b9e559f92 9
earlz 16:370b9e559f92 10 1. Redistributions of source code must retain the above copyright
earlz 16:370b9e559f92 11 notice, this list of conditions and the following disclaimer.
earlz 16:370b9e559f92 12 2. Redistributions in binary form must reproduce the above copyright
earlz 16:370b9e559f92 13 notice, this list of conditions and the following disclaimer in the
earlz 16:370b9e559f92 14 documentation and/or other materials provided with the distribution.
earlz 16:370b9e559f92 15 3. The name of the author may not be used to endorse or promote products
earlz 16:370b9e559f92 16 derived from this software without specific prior written permission.
earlz 16:370b9e559f92 17
earlz 16:370b9e559f92 18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
earlz 16:370b9e559f92 19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
earlz 16:370b9e559f92 20 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
earlz 16:370b9e559f92 21 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
earlz 16:370b9e559f92 22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
earlz 16:370b9e559f92 23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
earlz 16:370b9e559f92 24 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
earlz 16:370b9e559f92 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
earlz 16:370b9e559f92 26 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
earlz 16:370b9e559f92 27 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
earlz 16:370b9e559f92 28
earlz 16:370b9e559f92 29 This file is part of the MbedConsole project
earlz 16:370b9e559f92 30 */
earlz 16:370b9e559f92 31
earlz 10:bda85442b674 32 #include "mbedconsole.h"
earlz 12:3ee3062cc11c 33 #include "keyboard.h"
earlz 10:bda85442b674 34 /**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 35
earlz 10:bda85442b674 36
earlz 11:fede136943a9 37 const char kbdus[0x84] =
earlz 10:bda85442b674 38 {
earlz 11:fede136943a9 39 0,
earlz 11:fede136943a9 40 0, //1 F9
earlz 11:fede136943a9 41 0, //2 ?
earlz 11:fede136943a9 42 0, //3 f5
earlz 11:fede136943a9 43 0, //4 f3
earlz 11:fede136943a9 44 0, //5 F1
earlz 11:fede136943a9 45 0, //6 F2
earlz 11:fede136943a9 46 0, //7 F12
earlz 11:fede136943a9 47 0, //8 ?
earlz 11:fede136943a9 48 0, //9 F10
earlz 11:fede136943a9 49 0, //A F8
earlz 11:fede136943a9 50 0, //B F6
earlz 11:fede136943a9 51 0, //C F4
earlz 11:fede136943a9 52 '\t',
earlz 11:fede136943a9 53 '`',
earlz 11:fede136943a9 54 0, //F ?
earlz 11:fede136943a9 55 0, //10 ?
earlz 11:fede136943a9 56 0, //11 L alt
earlz 11:fede136943a9 57 0, //L shift
earlz 11:fede136943a9 58 0, //13 ?
earlz 11:fede136943a9 59 0, //14 L CTRL
earlz 11:fede136943a9 60 'q', '1',
earlz 11:fede136943a9 61 0, 0, 0, //17-19 ?
earlz 11:fede136943a9 62 'z', 's', 'a', 'w', '2',
earlz 11:fede136943a9 63 0, 0, //1F-20 ?
earlz 11:fede136943a9 64 'c', 'x', 'd', 'e', '4', '3',
earlz 11:fede136943a9 65 0, 0, //27-28 ?
earlz 11:fede136943a9 66 ' ', 'v', 'f', 't', 'r', '5',
earlz 11:fede136943a9 67 0, 0, //2F-30 ?
earlz 11:fede136943a9 68 'n', 'b', 'h', 'g', 'y', '6',
earlz 11:fede136943a9 69 0, 0, 0, //37-39 ?
earlz 11:fede136943a9 70 'm','j', 'u', '7', '8',
earlz 11:fede136943a9 71 0, 0, //3F-40 ?
earlz 11:fede136943a9 72 ',', 'k', 'i', 'o', '0', '9',
earlz 11:fede136943a9 73 0, 0, //47-48 ?
earlz 11:fede136943a9 74 '.', '/', 'l', ';', 'p', '-',
earlz 11:fede136943a9 75 0, 0, 0, //4f-51 ?
earlz 11:fede136943a9 76 '\'',
earlz 11:fede136943a9 77 0, //53 ?
earlz 11:fede136943a9 78 '[', '=',
earlz 11:fede136943a9 79 0, 0, //56-57 ?
earlz 11:fede136943a9 80 0, //58 caplock
earlz 11:fede136943a9 81 0, //59 R shift
earlz 11:fede136943a9 82 '\n', //5A enter
earlz 11:fede136943a9 83 ']',
earlz 11:fede136943a9 84 0, //5C ?
earlz 11:fede136943a9 85 '\\',
earlz 11:fede136943a9 86 0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ?
earlz 11:fede136943a9 87 '\b', //backspace
earlz 11:fede136943a9 88 0, 0, //67-68
earlz 11:fede136943a9 89 0, //69 End 1
earlz 11:fede136943a9 90 0, //6a ?
earlz 11:fede136943a9 91 '4', //6b left 4
earlz 11:fede136943a9 92 0, //6c home 7
earlz 11:fede136943a9 93 0, 0, 0, //6d-6f ?
earlz 11:fede136943a9 94 '0', //70 ins 0
earlz 11:fede136943a9 95 0, //71 del .
earlz 11:fede136943a9 96 '2', //72 down 2
earlz 11:fede136943a9 97 '5', //73 5
earlz 11:fede136943a9 98 '6', //74 right 6
earlz 11:fede136943a9 99 '8', //75 up 8
earlz 11:fede136943a9 100 27, //76 esc
earlz 11:fede136943a9 101 0, //77 numlock
earlz 11:fede136943a9 102 0, //78 f11
earlz 11:fede136943a9 103 '+', //79 +
earlz 11:fede136943a9 104 '3', //7A pagedown 3
earlz 11:fede136943a9 105 '-', //7B
earlz 11:fede136943a9 106 '*', //7C
earlz 11:fede136943a9 107 '9', //7D pageup 9
earlz 11:fede136943a9 108 '0', //7E scroll lock
earlz 11:fede136943a9 109 0, 0, 0, 0, //7F-82 ?
earlz 11:fede136943a9 110 0, //83 F7
earlz 10:bda85442b674 111 };
earlz 10:bda85442b674 112
earlz 11:fede136943a9 113
earlz 11:fede136943a9 114 const char kbdus_caps[0x84] =
earlz 10:bda85442b674 115 {
earlz 11:fede136943a9 116 0,
earlz 11:fede136943a9 117 0, //1 F9
earlz 11:fede136943a9 118 0, //2 ?
earlz 11:fede136943a9 119 0, //3 f5
earlz 11:fede136943a9 120 0, //4 f3
earlz 11:fede136943a9 121 0, //5 F1
earlz 11:fede136943a9 122 0, //6 F2
earlz 11:fede136943a9 123 0, //7 F12
earlz 11:fede136943a9 124 0, //8 ?
earlz 11:fede136943a9 125 0, //9 F10
earlz 11:fede136943a9 126 0, //A F8
earlz 11:fede136943a9 127 0, //B F6
earlz 11:fede136943a9 128 0, //C F4
earlz 11:fede136943a9 129 '\t',
earlz 11:fede136943a9 130 '~',
earlz 11:fede136943a9 131 0, //F ?
earlz 11:fede136943a9 132 0, //10 ?
earlz 11:fede136943a9 133 0, //11 L alt
earlz 11:fede136943a9 134 0, //L shift
earlz 11:fede136943a9 135 0, //13 ?
earlz 11:fede136943a9 136 0, //14 L CTRL
earlz 11:fede136943a9 137 'Q', '!',
earlz 11:fede136943a9 138 0, 0, 0, //17-19 ?
earlz 11:fede136943a9 139 'Z', 'S', 'A', 'W', '@',
earlz 11:fede136943a9 140 0, 0, //1F-20 ?
earlz 11:fede136943a9 141 'C', 'X', 'D', 'E', '#', '$',
earlz 11:fede136943a9 142 0, 0, //27-28 ?
earlz 11:fede136943a9 143 ' ', 'V', 'F', 'T', 'R', '%',
earlz 11:fede136943a9 144 0, 0, //2F-30 ?
earlz 11:fede136943a9 145 'N', 'B', 'H', 'G', 'Y', '^',
earlz 11:fede136943a9 146 0, 0, 0, //37-39 ?
earlz 11:fede136943a9 147 'M','J', 'U', '&', '*',
earlz 11:fede136943a9 148 0, 0, //3F-40 ?
earlz 11:fede136943a9 149 '<', 'K', 'I', 'O', ')', '(',
earlz 11:fede136943a9 150 0, 0, //47-48 ?
earlz 11:fede136943a9 151 '>', '?', 'L', ':', 'P', '_',
earlz 11:fede136943a9 152 0, 0, 0, //4f-51 ?
earlz 11:fede136943a9 153 '\"',
earlz 11:fede136943a9 154 0, //53 ?
earlz 11:fede136943a9 155 '{', '+',
earlz 11:fede136943a9 156 0, 0, //56-57 ?
earlz 11:fede136943a9 157 0, //58 caplock
earlz 11:fede136943a9 158 0, //59 R shift
earlz 11:fede136943a9 159 '\n', //5A enter
earlz 11:fede136943a9 160 '}',
earlz 11:fede136943a9 161 0, //5C ?
earlz 11:fede136943a9 162 '|',
earlz 11:fede136943a9 163 0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ?
earlz 11:fede136943a9 164 '\b', //backspace
earlz 11:fede136943a9 165 0, 0, //67-68
earlz 11:fede136943a9 166 0, //69 End 1
earlz 11:fede136943a9 167 0, //6a ?
earlz 11:fede136943a9 168 '4', //6b left 4
earlz 11:fede136943a9 169 0, //6c home 7
earlz 11:fede136943a9 170 0, 0, 0, //6d-6f ?
earlz 11:fede136943a9 171 '0', //70 ins 0
earlz 11:fede136943a9 172 0, //71 del .
earlz 11:fede136943a9 173 '2', //72 down 2
earlz 11:fede136943a9 174 '5', //73 5
earlz 11:fede136943a9 175 '6', //74 right 6
earlz 11:fede136943a9 176 '8', //75 up 8
earlz 11:fede136943a9 177 27, //76 esc
earlz 11:fede136943a9 178 0, //77 numlock
earlz 11:fede136943a9 179 0, //78 f11
earlz 11:fede136943a9 180 '+', //79 +
earlz 11:fede136943a9 181 '3', //7A pagedown 3
earlz 11:fede136943a9 182 '-', //7B
earlz 11:fede136943a9 183 '*', //7C
earlz 11:fede136943a9 184 '9', //7D pageup 9
earlz 11:fede136943a9 185 '0', //7E scroll lock
earlz 11:fede136943a9 186 0, 0, 0, 0, //7F-82 ?
earlz 11:fede136943a9 187 0, //83 F7
earlz 10:bda85442b674 188 };
earlz 10:bda85442b674 189
earlz 10:bda85442b674 190 PS2KB_INIT *ps2_kb_init;
earlz 10:bda85442b674 191 PS2KB *ps2_kb;
earlz 10:bda85442b674 192
earlz 10:bda85442b674 193 volatile kbd_key *keys;
earlz 10:bda85442b674 194 volatile uint8_t current_key=0;
earlz 10:bda85442b674 195 volatile uint8_t key_got=0;
earlz 10:bda85442b674 196 volatile char pending_key=0;
earlz 10:bda85442b674 197 volatile uint8_t led_status=0;
earlz 10:bda85442b674 198
earlz 10:bda85442b674 199 void keyboard_init()
earlz 10:bda85442b674 200 {
earlz 10:bda85442b674 201 keys=(kbd_key*)malloc(256*sizeof(kbd_key));
earlz 11:fede136943a9 202 kbd_shifts.shift=0;
earlz 11:fede136943a9 203 kbd_shifts.caps=0;
earlz 11:fede136943a9 204 kbd_shifts.num=0;
earlz 11:fede136943a9 205 kbd_shifts.scroll=0;
earlz 11:fede136943a9 206 kbd_shifts.ctrl=0;
earlz 11:fede136943a9 207 kbd_shifts.alt=0;
earlz 10:bda85442b674 208 ps2_kb_init=new PS2KB_INIT(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN);
earlz 10:bda85442b674 209 ps2_kb=new PS2KB(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN, (KeyboardCallback) &keyboard_callback);
earlz 10:bda85442b674 210 }
earlz 10:bda85442b674 211
earlz 10:bda85442b674 212
earlz 10:bda85442b674 213
earlz 10:bda85442b674 214 volatile shift_locks kbd_shifts;
earlz 10:bda85442b674 215
earlz 10:bda85442b674 216
earlz 10:bda85442b674 217
earlz 10:bda85442b674 218 /**The way the keyboard driver works is this:
earlz 10:bda85442b674 219 the buffer is 256 elements big. key_got and current_key are both
earlz 10:bda85442b674 220 bytes. Rather than setting current_key to 0, the entire buffer is constantly
earlz 10:bda85442b674 221 in use. when a key is pushed, current key is incremented. when a key is got(with safety checks)
earlz 10:bda85442b674 222 key_got is incremented. Also, when it reaches the end of the buffer, it simply wraps around
earlz 10:bda85442b674 223 to the beginning due to byte overflow. The worst that can happen is if 256 bytes get
earlz 10:bda85442b674 224 built up, in which case everything will be screwed up.. I should eventually controlt he capture
earlz 10:bda85442b674 225 of these keys to where not all of them are stored, and they are only stored when needed**/
earlz 10:bda85442b674 226
earlz 10:bda85442b674 227 int kbd_PutBuffer(uint16_t scan,uint8_t asci){
earlz 11:fede136943a9 228 keys[current_key].scancode=scan;
earlz 11:fede136943a9 229 keys[current_key].asci=asci;
earlz 11:fede136943a9 230 current_key++;
earlz 11:fede136943a9 231 pending_key++;;
earlz 11:fede136943a9 232 return 0;
earlz 10:bda85442b674 233 }
earlz 10:bda85442b674 234
earlz 10:bda85442b674 235 kbd_key kbd_PopBuffer(){
earlz 11:fede136943a9 236 kbd_key k;
earlz 11:fede136943a9 237 while(pending_key==0){
earlz 11:fede136943a9 238 //hlt();
earlz 11:fede136943a9 239 //fill in busy code here
earlz 11:fede136943a9 240 }
earlz 11:fede136943a9 241
earlz 11:fede136943a9 242 k.scancode=keys[key_got].scancode;
earlz 11:fede136943a9 243 k.asci=keys[key_got].asci;
earlz 11:fede136943a9 244 pending_key--;
earlz 11:fede136943a9 245 key_got++;
earlz 11:fede136943a9 246 return k;
earlz 10:bda85442b674 247 }
earlz 10:bda85442b674 248
earlz 10:bda85442b674 249 uint8_t kbd_GetKey(){ //this will just return the asci code
earlz 11:fede136943a9 250 kbd_key k;
earlz 11:fede136943a9 251 k.asci=0;
earlz 11:fede136943a9 252 while(k.asci==0){
earlz 11:fede136943a9 253 k=kbd_PopBuffer();
earlz 11:fede136943a9 254 }
earlz 11:fede136943a9 255 return k.asci;
earlz 10:bda85442b674 256 }
earlz 10:bda85442b674 257
earlz 10:bda85442b674 258
earlz 10:bda85442b674 259 void kbd_update_leds(uint8_t status){
earlz 11:fede136943a9 260 uint8_t tmp;
earlz 11:fede136943a9 261 //TODO
earlz 11:fede136943a9 262 /*while((inportb(0x64)&2)!=0){}
earlz 11:fede136943a9 263 outportb(0x60,0xED);
earlz 11:fede136943a9 264
earlz 11:fede136943a9 265 while((inportb(0x64)&2)!=0){}
earlz 11:fede136943a9 266 outportb(0x60,status);
earlz 11:fede136943a9 267 */
earlz 10:bda85442b674 268 }
earlz 10:bda85442b674 269
earlz 10:bda85442b674 270
earlz 10:bda85442b674 271
earlz 10:bda85442b674 272 int kbd_DoShifts(uint8_t scan){
earlz 11:fede136943a9 273 switch(scan){
earlz 11:fede136943a9 274 case RSHIFT_KEY:
earlz 11:fede136943a9 275 kbd_shifts.shift++;
earlz 11:fede136943a9 276 break;
earlz 11:fede136943a9 277 case LSHIFT_KEY:
earlz 11:fede136943a9 278 kbd_shifts.shift++;
earlz 11:fede136943a9 279 break;
earlz 11:fede136943a9 280 case CTRL_KEY:
earlz 11:fede136943a9 281 kbd_shifts.ctrl++;
earlz 11:fede136943a9 282 break;
earlz 11:fede136943a9 283 case ALT_KEY:
earlz 11:fede136943a9 284 kbd_shifts.alt++;
earlz 11:fede136943a9 285 break;
earlz 11:fede136943a9 286 case CAPS_KEY:
earlz 11:fede136943a9 287 led_status^=CAPS_LED;
earlz 11:fede136943a9 288 kbd_update_leds(led_status);
earlz 11:fede136943a9 289 kbd_shifts.caps^=1;
earlz 11:fede136943a9 290 break;
earlz 11:fede136943a9 291 case NUM_KEY:
earlz 11:fede136943a9 292 led_status^=NUM_LED;
earlz 11:fede136943a9 293 kbd_update_leds(led_status);
earlz 11:fede136943a9 294 kbd_shifts.num^=1;
earlz 11:fede136943a9 295 break;
earlz 11:fede136943a9 296 case SCROLL_KEY:
earlz 11:fede136943a9 297 led_status^=SCROLL_LED;
earlz 11:fede136943a9 298 kbd_update_leds(led_status);
earlz 11:fede136943a9 299 kbd_shifts.scroll^=1;
earlz 11:fede136943a9 300 break;
earlz 11:fede136943a9 301 default:
earlz 11:fede136943a9 302 return 0;
earlz 11:fede136943a9 303 break;
earlz 11:fede136943a9 304 }
earlz 11:fede136943a9 305 return 1;
earlz 10:bda85442b674 306 }
earlz 10:bda85442b674 307
earlz 10:bda85442b674 308 int kbd_DoUnshifts(uint8_t scan){
earlz 11:fede136943a9 309 switch(scan){
earlz 11:fede136943a9 310 case RSHIFT_KEY:
earlz 11:fede136943a9 311 kbd_shifts.shift--;
earlz 11:fede136943a9 312 break;
earlz 11:fede136943a9 313 case LSHIFT_KEY:
earlz 11:fede136943a9 314 kbd_shifts.shift--;
earlz 11:fede136943a9 315 break;
earlz 11:fede136943a9 316 case CTRL_KEY:
earlz 11:fede136943a9 317 kbd_shifts.ctrl--;
earlz 11:fede136943a9 318 break;
earlz 11:fede136943a9 319 case ALT_KEY:
earlz 11:fede136943a9 320 kbd_shifts.alt--;
earlz 11:fede136943a9 321 break;
earlz 11:fede136943a9 322 case CAPS_KEY:
earlz 11:fede136943a9 323 //kbd_shifts.caps=0;
earlz 11:fede136943a9 324 break;
earlz 11:fede136943a9 325 case NUM_KEY:
earlz 11:fede136943a9 326 //kbd_shifts.num=0;
earlz 11:fede136943a9 327 break;
earlz 11:fede136943a9 328 case SCROLL_KEY:
earlz 11:fede136943a9 329 //kbd_shifts.scroll=0;
earlz 11:fede136943a9 330 break;
earlz 11:fede136943a9 331 default:
earlz 11:fede136943a9 332 return 0;
earlz 11:fede136943a9 333 break;
earlz 11:fede136943a9 334 }
earlz 11:fede136943a9 335 return 1;
earlz 10:bda85442b674 336 }
earlz 10:bda85442b674 337 volatile bool expecting_break=false;
earlz 10:bda85442b674 338 void keyboard_callback(PS2KB kb, uint8_t val) //this is called from interrupt! Must be fast
earlz 10:bda85442b674 339 {
earlz 11:fede136943a9 340 //stopints();
earlz 10:bda85442b674 341 if(expecting_break){
earlz 11:fede136943a9 342 //val^=0xF0;
earlz 10:bda85442b674 343 kbd_DoUnshifts(val);
earlz 10:bda85442b674 344 expecting_break=false;
earlz 10:bda85442b674 345 }else{
earlz 11:fede136943a9 346 if(val>=0xF0){
earlz 11:fede136943a9 347 expecting_break=true;
earlz 11:fede136943a9 348 }else{
earlz 11:fede136943a9 349 //add check for 0x84 to make sure we don't go over our keymap
earlz 11:fede136943a9 350 if(val<=0x84 && kbd_DoShifts(val)==0){ //if not a shift-type key
earlz 11:fede136943a9 351
earlz 11:fede136943a9 352 if ((kbd_shifts.caps^kbd_shifts.shift)==1) {
earlz 11:fede136943a9 353 kbd_PutBuffer(val,kbdus_caps[val]);
earlz 11:fede136943a9 354 }else{
earlz 11:fede136943a9 355 kbd_PutBuffer(val,kbdus[val]);
earlz 11:fede136943a9 356 }
earlz 11:fede136943a9 357 }
earlz 11:fede136943a9 358 }
earlz 11:fede136943a9 359 }
earlz 10:bda85442b674 360 }
earlz 10:bda85442b674 361
earlz 10:bda85442b674 362
earlz 11:fede136943a9 363
earlz 11:fede136943a9 364