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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers keyboard.cpp Source File

keyboard.cpp

00001 /*
00002 <Copyright Header>
00003 Copyright (c) 2012 Jordan "Earlz" Earls  <http://lastyearswishes.com>
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions
00008 are met:
00009 
00010 1. Redistributions of source code must retain the above copyright
00011    notice, this list of conditions and the following disclaimer.
00012 2. Redistributions in binary form must reproduce the above copyright
00013    notice, this list of conditions and the following disclaimer in the
00014    documentation and/or other materials provided with the distribution.
00015 3. The name of the author may not be used to endorse or promote products
00016    derived from this software without specific prior written permission.
00017    
00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00020 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
00021 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00022 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00023 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00024 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00025 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00026 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00027 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 
00029 This file is part of the MbedConsole project
00030 */
00031 
00032 #include "mbedconsole.h"
00033 #include "keyboard.h"
00034 /**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**/
00035 
00036 
00037 const char kbdus[0x84] =
00038 {
00039     0, 
00040     0, //1 F9
00041     0, //2 ?
00042     0, //3 f5
00043     0, //4 f3
00044     0, //5 F1
00045     0, //6 F2
00046     0, //7 F12
00047     0, //8 ?
00048     0, //9 F10
00049     0, //A F8
00050     0, //B F6
00051     0, //C F4
00052     '\t',
00053     '`',
00054     0, //F ?
00055     0, //10 ?
00056     0, //11 L alt
00057     0, //L shift
00058     0, //13 ?
00059     0, //14 L CTRL
00060     'q', '1',
00061     0, 0, 0, //17-19 ?
00062     'z', 's', 'a', 'w', '2',
00063     0, 0, //1F-20 ?
00064     'c', 'x', 'd', 'e', '4', '3',
00065     0, 0, //27-28 ? 
00066     ' ', 'v', 'f', 't', 'r', '5', 
00067     0, 0, //2F-30 ?
00068     'n', 'b', 'h', 'g', 'y', '6',
00069     0, 0, 0, //37-39 ?
00070     'm','j', 'u', '7', '8',
00071     0, 0, //3F-40 ?
00072     ',', 'k', 'i', 'o', '0', '9',
00073     0, 0, //47-48 ?
00074     '.', '/', 'l', ';', 'p', '-',
00075     0, 0, 0, //4f-51 ?
00076     '\'',
00077     0, //53 ?
00078     '[', '=', 
00079     0, 0, //56-57 ?
00080     0, //58 caplock
00081     0, //59 R shift
00082     '\n', //5A enter
00083     ']', 
00084     0, //5C ?
00085     '\\',
00086     0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ?
00087     '\b', //backspace
00088     0, 0, //67-68
00089     0, //69 End 1
00090     0, //6a ?
00091     '4', //6b left 4
00092     0, //6c home 7
00093     0, 0, 0, //6d-6f ?
00094     '0', //70 ins 0
00095     0, //71 del .
00096     '2', //72 down 2
00097     '5', //73 5
00098     '6', //74 right 6
00099     '8', //75 up 8
00100     27, //76 esc
00101     0, //77 numlock
00102     0, //78 f11
00103     '+', //79 +
00104     '3', //7A pagedown 3
00105     '-', //7B
00106     '*', //7C
00107     '9', //7D pageup 9
00108     '0', //7E scroll lock
00109     0, 0, 0, 0, //7F-82 ?
00110     0, //83 F7
00111 };
00112 
00113 
00114 const char kbdus_caps[0x84] =
00115 {
00116     0, 
00117     0, //1 F9
00118     0, //2 ?
00119     0, //3 f5
00120     0, //4 f3
00121     0, //5 F1
00122     0, //6 F2
00123     0, //7 F12
00124     0, //8 ?
00125     0, //9 F10
00126     0, //A F8
00127     0, //B F6
00128     0, //C F4
00129     '\t',
00130     '~',
00131     0, //F ?
00132     0, //10 ?
00133     0, //11 L alt
00134     0, //L shift
00135     0, //13 ?
00136     0, //14 L CTRL
00137     'Q', '!',
00138     0, 0, 0, //17-19 ?
00139     'Z', 'S', 'A', 'W', '@',
00140     0, 0, //1F-20 ?
00141     'C', 'X', 'D', 'E', '#', '$',
00142     0, 0, //27-28 ? 
00143     ' ', 'V', 'F', 'T', 'R', '%', 
00144     0, 0, //2F-30 ?
00145     'N', 'B', 'H', 'G', 'Y', '^',
00146     0, 0, 0, //37-39 ?
00147     'M','J', 'U', '&', '*',
00148     0, 0, //3F-40 ?
00149     '<', 'K', 'I', 'O', ')', '(',
00150     0, 0, //47-48 ?
00151     '>', '?', 'L', ':', 'P', '_',
00152     0, 0, 0, //4f-51 ?
00153     '\"',
00154     0, //53 ?
00155     '{', '+', 
00156     0, 0, //56-57 ?
00157     0, //58 caplock
00158     0, //59 R shift
00159     '\n', //5A enter
00160     '}', 
00161     0, //5C ?
00162     '|',
00163     0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ?
00164     '\b', //backspace
00165     0, 0, //67-68
00166     0, //69 End 1
00167     0, //6a ?
00168     '4', //6b left 4
00169     0, //6c home 7
00170     0, 0, 0, //6d-6f ?
00171     '0', //70 ins 0
00172     0, //71 del .
00173     '2', //72 down 2
00174     '5', //73 5
00175     '6', //74 right 6
00176     '8', //75 up 8
00177     27, //76 esc
00178     0, //77 numlock
00179     0, //78 f11
00180     '+', //79 +
00181     '3', //7A pagedown 3
00182     '-', //7B
00183     '*', //7C
00184     '9', //7D pageup 9
00185     '0', //7E scroll lock
00186     0, 0, 0, 0, //7F-82 ?
00187     0, //83 F7
00188 };
00189 
00190 PS2KB_INIT *ps2_kb_init;
00191 PS2KB *ps2_kb;
00192 
00193 volatile kbd_key *keys;
00194 volatile uint8_t current_key=0;
00195 volatile uint8_t key_got=0;
00196 volatile char pending_key=0;
00197 volatile uint8_t led_status=0;
00198 
00199 void keyboard_init()
00200 {
00201     keys=(kbd_key*)malloc(256*sizeof(kbd_key));
00202     kbd_shifts.shift=0;
00203     kbd_shifts.caps=0;
00204     kbd_shifts.num=0;
00205     kbd_shifts.scroll=0;
00206     kbd_shifts.ctrl=0;
00207     kbd_shifts.alt=0;
00208     ps2_kb_init=new PS2KB_INIT(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN);
00209     ps2_kb=new PS2KB(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN, (KeyboardCallback) &keyboard_callback);
00210 }
00211 
00212 
00213 
00214 volatile shift_locks kbd_shifts;
00215 
00216 
00217 
00218 /**The way the keyboard driver works is this:
00219 the buffer is 256 elements big. key_got and current_key are both
00220 bytes. Rather than setting current_key to 0, the entire buffer is constantly
00221 in use. when a key is pushed, current key is incremented. when a key is got(with safety checks)
00222 key_got is incremented. Also, when it reaches the end of the buffer, it simply wraps around
00223 to the beginning due to byte overflow. The worst that can happen is if 256 bytes get
00224 built up, in which case everything will be screwed up.. I should eventually controlt he capture
00225 of these keys to where not all of them are stored, and they are only stored when needed**/
00226 
00227 int kbd_PutBuffer(uint16_t scan,uint8_t asci){
00228     keys[current_key].scancode=scan;
00229     keys[current_key].asci=asci;
00230     current_key++;
00231     pending_key++;;
00232     return 0;
00233 }
00234 
00235 kbd_key kbd_PopBuffer(){
00236     kbd_key k;
00237     while(pending_key==0){
00238         //hlt();
00239     //fill in busy code here    
00240     }
00241     
00242     k.scancode=keys[key_got].scancode;
00243     k.asci=keys[key_got].asci;
00244     pending_key--;
00245     key_got++;
00246     return k;
00247 }
00248 
00249 uint8_t kbd_GetKey(){ //this will just return the asci code
00250     kbd_key k;
00251     k.asci=0;
00252     while(k.asci==0){
00253         k=kbd_PopBuffer();
00254     }
00255     return k.asci;
00256 }
00257 
00258 
00259 void kbd_update_leds(uint8_t status){
00260     uint8_t tmp;
00261     //TODO
00262     /*while((inportb(0x64)&2)!=0){}
00263     outportb(0x60,0xED);
00264     
00265     while((inportb(0x64)&2)!=0){}
00266     outportb(0x60,status);
00267     */
00268 }
00269 
00270 
00271  
00272 int kbd_DoShifts(uint8_t scan){
00273     switch(scan){
00274         case RSHIFT_KEY:
00275             kbd_shifts.shift++;
00276             break;
00277         case LSHIFT_KEY:
00278             kbd_shifts.shift++;
00279             break;
00280         case CTRL_KEY:
00281             kbd_shifts.ctrl++;
00282             break;
00283         case ALT_KEY:
00284             kbd_shifts.alt++;
00285             break;
00286         case CAPS_KEY:
00287             led_status^=CAPS_LED;
00288             kbd_update_leds(led_status);
00289             kbd_shifts.caps^=1;
00290             break;
00291         case NUM_KEY:
00292             led_status^=NUM_LED;
00293             kbd_update_leds(led_status);
00294             kbd_shifts.num^=1;
00295             break;
00296         case SCROLL_KEY:
00297             led_status^=SCROLL_LED;
00298             kbd_update_leds(led_status);
00299             kbd_shifts.scroll^=1;
00300             break;
00301         default:
00302             return 0;
00303             break;
00304     }
00305     return 1;
00306 }
00307 
00308 int kbd_DoUnshifts(uint8_t scan){
00309     switch(scan){
00310         case RSHIFT_KEY:
00311             kbd_shifts.shift--;
00312             break;
00313         case LSHIFT_KEY:
00314             kbd_shifts.shift--;
00315             break;
00316         case CTRL_KEY:
00317             kbd_shifts.ctrl--;
00318             break;
00319         case ALT_KEY:
00320             kbd_shifts.alt--;
00321             break;
00322         case CAPS_KEY:
00323             //kbd_shifts.caps=0;
00324             break;
00325         case NUM_KEY:
00326             //kbd_shifts.num=0;
00327             break;
00328         case SCROLL_KEY:
00329             //kbd_shifts.scroll=0;
00330             break;
00331         default:
00332             return 0;
00333             break;
00334     }
00335     return 1;
00336 }
00337 volatile bool expecting_break=false;
00338 void keyboard_callback(PS2KB kb, uint8_t val) //this is called from interrupt! Must be fast
00339 {
00340         //stopints();
00341     if(expecting_break){
00342         //val^=0xF0;
00343         kbd_DoUnshifts(val);
00344         expecting_break=false;
00345     }else{
00346         if(val>=0xF0){     
00347             expecting_break=true;
00348         }else{
00349             //add check for 0x84 to make sure we don't go over our keymap
00350             if(val<=0x84 && kbd_DoShifts(val)==0){ //if not a shift-type key
00351                 
00352                 if ((kbd_shifts.caps^kbd_shifts.shift)==1) {
00353                     kbd_PutBuffer(val,kbdus_caps[val]);
00354                 }else{
00355                     kbd_PutBuffer(val,kbdus[val]);
00356                 }
00357             }
00358         }
00359     }
00360 }
00361 
00362 
00363 
00364