Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

keyboard.c File Reference

Low level keyboard driver. More...

#include <const.h>
#include <arch/i386.h>
#include <arch/interrupt.h>
#include <kernel/console.h>
#include <kernel/kernel.h>
#include <kernel/queue.h>
#include <kernel/semaphore.h>
#include <kernel/speaker.h>
#include <kernel/task.h>
#include <kernel/keyboard.h>

Go to the source code of this file.

Functions

void keyb_wait ()
 Wait after a keyboard operation.

void update_leds ()
 Update keyboard leds.

word scan_key ()
 Get the hitten key keyboard code.
Returns:
The hitten key scan code.


void keyboard_handler ()
 This is the keyboard interrupt handler routine. It is invoked every time a key is pressed or released on the keyboard.

void init_keyboard ()
 Initialize the low-level keyboard driver.

int kgetchar ()
 Wait for keypressed and return the hitten character ASCII code.
Returns:
The hitten character ASCII code.


int keyb_read ()
 Return the first key in the buffer, without waiting if the buffer is empty.
Returns:
The hitten character ASCII code if a character has been hitten or NULL otherwise.



Variables

word regular [128]
 US keyboard keymap :: regular keys.

word with_shift [128]
 US keyboard keymap :: "with SHIFT" keys.

word with_alt [128]
 US keyboard keymap :: "with ALT" keys.

word with_control [128]
 US keyboard keymap :: "with CTRL" keys.

byte keypad_char [] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}
 The keypad map.

byte shift = 0
 SHIFT flag.

byte ctrl = 0
 CTRL flag.

byte alt = 0
 ALT flag.

queue_tkeyb_queue = NULL
 Queue for the task that are waiting for the keyboard.


Detailed Description

Low level keyboard driver.

Author:
Andrea Righi <drizzt@inwind.it>
Date:
Last update: 2003-01-01
Note:
Copyright (©) 2003 Andrea Righi

Definition in file keyboard.c.


Function Documentation

void init_keyboard  
 

Initialize the low-level keyboard driver.

Definition at line 280 of file keyboard.c.

00281 {
00282         // Install the keyboard handler                                 //
00283         install_irq_handler( KEYBOARD_IRQ, (void *)&keyboard_handler );
00284 
00285         // Set typematic delay as short as possible                     //
00286         outportb(KEYB_PORT, KEYB_SET_TYPEMATIC);
00287         keyb_wait();
00288         // typematic 0 means "MODE CON RATE=30 DELAY=1"                 //
00289         outportb(KEYB_PORT, 0);
00290 
00291         // Initialize leds //
00292         update_leds();
00293 }

int keyb_read  
 

Return the first key in the buffer, without waiting if the buffer is empty.

Returns:
The hitten character ASCII code if a character has been hitten or NULL otherwise.

Definition at line 341 of file keyboard.c.

00342 {
00343         console_t *cons = get_console_addr( get_curr_task()->console );
00344         word key;
00345         dword IF = GET_IF();
00346 
00347         // If the task's console is not the current console return      //
00348         while ( get_curr_task()->console != get_curr_console() )
00349                 return(NULL);
00350 
00351         // If the keyboard buffer is empty return NULL                  //
00352         if (cons->keyb_buf_count==0) return(NULL);
00353 
00354         disable();
00355 
00356         // Update keyboard buffer in mutual exclusion                   //
00357         (cons->keyb_buf_count)--;
00358         if ( ++(cons->keyb_buf_read) >= KEYB_BUF_DIM )
00359                 cons->keyb_buf_read = 0;
00360         key = cons->keyb_buffer[cons->keyb_buf_read];
00361 
00362         SET_IF(IF);
00363 
00364         return(key);
00365 }

void keyb_wait  
 

Wait after a keyboard operation.

Todo:
Put here a timeout!

Definition at line 90 of file keyboard.c.

00091 {
00092         uint32_t retries=500000L;
00093 
00094         while (((inportb(KEYB_STATUS) & KEYB_BUSY) == KEYB_BUSY) && retries!=0)
00095         {
00096                 retries--;
00097         }
00098 }

void keyboard_handler  
 

This is the keyboard interrupt handler routine. It is invoked every time a key is pressed or released on the keyboard.

Definition at line 145 of file keyboard.c.

00146 {
00147         task_t *p;
00148         int console, count;
00149         // Current console structure.
00150         console_t *curr_cons = get_console_addr( get_curr_console() );
00151         // Key hitten ASCII code.
00152         word code;
00153         // Key hitten keyboard code.
00154         word keypressed = scan_key();
00155 
00156         // If CTRL+ALT+Canc => Reboot the system...                     //
00157         if (ctrl==1 && alt==1 && keypressed==DEL_SCAN) reboot();
00158 
00159         if (alt==1) code = with_alt[keypressed];
00160         else if (ctrl==1) code = with_control[keypressed];
00161         else
00162         {
00163                 if (curr_cons->caps_lock==0 && shift==0) code = regular[keypressed];
00164                 else if (curr_cons->caps_lock==0 && shift==1) code = with_shift[keypressed];
00165                 else if (curr_cons->caps_lock==1 && shift==0)
00166                 {
00167                         code = regular[keypressed];
00168                         if (((code&0xFF)>='a') && ((code&0xFF)<='z')) code-='a'-'A';
00169                 }
00170                 else
00171                 {
00172                         code = with_shift[keypressed];
00173                         if (((code&0xFF)>='A') && ((code&0xFF)<='Z')) code+='a'-'A';
00174                 }
00175                 if ((curr_cons->num_lock!=shift) && (keypressed>=71 && keypressed<=83))
00176                         code = keypad_char[keypressed-71];
00177         }
00178 
00179         // Print the char only if it's not released (bit 8 set)         //
00180         switch (keypressed)
00181         {
00182                 case 42:        // LShift
00183                 shift=1;
00184                 break;
00185 
00186                 case (42+128):
00187                 shift=0;
00188                 break;
00189 
00190                 case 54:        // RShift
00191                 shift=1;
00192                 break;
00193 
00194                 case (54+128):
00195                 shift=0;
00196                 break;
00197 
00198                 case 56:        // ALT
00199                 alt=1;
00200                 break;
00201 
00202                 case (56+128):
00203                 alt=0;
00204                 break;
00205 
00206                 case 29:        // CTRL
00207                 ctrl=1;
00208                 break;
00209 
00210                 case (29+128):
00211                 ctrl=0;
00212                 break;
00213 
00214                 case 58:        // CAPS LOCK
00215                 curr_cons->caps_lock ^= 1;
00216                 update_leds();
00217                 break;
00218 
00219                 case 69:        // NUM LOCK
00220                 curr_cons->num_lock ^= 1;
00221                 update_leds();
00222                 break;
00223 
00224                 case 70:        // SCROLL LOCK
00225                 curr_cons->scroll_lock ^= 1;
00226                 update_leds();
00227                 break;
00228 
00229                 case 0xE1:      // PAUSE
00230                 // Wait until released... //
00231                 while (scan_key() != 0xC5);
00232                 break;
00233 
00234                 default:
00235 
00236                 // Update keyboard buffer. This is an interrupt         //
00237                 // handler so we are already in mutual exclusion!!!     //
00238 
00239                 if (!(keypressed & 0x80))
00240                 {
00241                         if ( (code>=ALT_F1) && (code<=ALT_F10) )
00242                         {
00243                                 // Change console                       //
00244                                 console = ((code-ALT_F1) >> 8) + 1;
00245                                 switch_to_console( console );
00246 
00247                                 // Every task in the selected console
00248                                 // need to wake-up.
00249                                 count = count_queue( &keyb_queue );
00250                                 for ( ; count; --count )
00251                                 {
00252                                         p = pick_queue( &keyb_queue );
00253                                         if ( p->console==console )
00254                                         {
00255                                                 wakeup_task( p );
00256                                                 rem_queue( &keyb_queue, p );
00257                                         }
00258                                 }
00259                                 return;
00260                         }
00261                         // A key has been released => update the buffer //
00262                         if ( (curr_cons->keyb_buf_count) < KEYB_BUF_DIM )
00263                         {
00264                                 (curr_cons->keyb_buf_count)++;
00265                                 if ( ++(curr_cons->keyb_buf_write) >= KEYB_BUF_DIM )
00266                                         curr_cons->keyb_buf_write = 0;
00267                                 curr_cons->keyb_buffer[curr_cons->keyb_buf_write] = code;
00268                         }
00269                         else
00270                         {
00271                                 // Buffer full => beep!                 //
00272                                 beep();
00273                         }
00274                 }
00275                 break;
00276         }
00277 }

int kgetchar  
 

Wait for keypressed and return the hitten character ASCII code.

Returns:
The hitten character ASCII code.

Definition at line 298 of file keyboard.c.

00299 {
00300         task_t *ct = get_curr_task();
00301         console_t *cons = get_console_addr( ct->console );
00302         word key;
00303         uint32_t IF = GET_IF();
00304 
00305 repeat:
00306         disable();
00307         // If the task's console is not the current console auto-sleep  //
00308         if ( ct->console != get_curr_console() )
00309         {
00310                 add_queue( &keyb_queue, ct );
00311                 sleep_task( ct );
00312                 enable();
00313                 idle();
00314                 goto repeat;
00315         }
00316         // If the keyboard buffer is empty enable interrupts and wait   //
00317         if ( cons->keyb_buf_count==0 )
00318         {
00319                 enable();
00320                 idle();
00321                 goto repeat;
00322         }
00323 
00324         // Update keyboard buffer in mutual exclusion                   //
00325         (cons->keyb_buf_count)--;
00326         if ( ++(cons->keyb_buf_read) >= KEYB_BUF_DIM )
00327                 cons->keyb_buf_read = 0;
00328         key = cons->keyb_buffer[cons->keyb_buf_read];
00329 
00330         SET_IF(IF);
00331 
00332         return( key );
00333 }

word scan_key  
 

Get the hitten key keyboard code.

Returns:
The hitten key scan code.

Definition at line 123 of file keyboard.c.

00124 {
00125         static int code, val;
00126         dword IF = GET_IF();
00127 
00128         disable();
00129 
00130         code = inportb(KEYB_PORT);      // Get scan code
00131         val =  inportb(KEYB_ACK);       // Get keyboard acknowledge
00132         outportb(KEYB_ACK, val | 0x80); // Disable bit 7
00133         outportb(KEYB_ACK, val);        // Send that back
00134 
00135         SET_IF(IF);
00136 
00137         return code;
00138 }

void update_leds  
 

Update keyboard leds.

Definition at line 101 of file keyboard.c.

00102 {
00103         int leds;
00104         console_t *curr_cons = get_console_addr( get_curr_console() );
00105         dword IF = GET_IF();
00106 
00107         leds =  (curr_cons->scroll_lock) |
00108                 (curr_cons->num_lock << 1) |
00109                 (curr_cons->caps_lock << 2);
00110 
00111         disable();
00112 
00113         keyb_wait();
00114         outportb(KEYB_PORT, KEYB_LED_CODE);
00115         keyb_wait();
00116         outportb(KEYB_PORT, leds);
00117 
00118         SET_IF(IF);
00119 }


Generated on Fri Feb 20 15:32:19 2004 for Minirighi by doxygen1.2.18