source: rtems/c/src/lib/libbsp/powerpc/shared/console/inch.c @ 969de1f3

4.104.114.84.95
Last change on this file since 969de1f3 was acc25ee, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 2, 1999 at 2:31:19 PM

Merged of mcp750 and mvme2307 BSP by Eric Valette <valette@…>.
As part of this effort, the mpc750 libcpu code is now shared with the
ppc6xx.

  • Property mode set to 100644
File size: 8.6 KB
Line 
1/*
2 *  inch.c  -- keyboard minimal driver
3 *
4 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
5 *
6 * This code is based on the pc386 BSP inch.c so the following
7 * copyright also applies :
8 *
9 * (C) Copyright 1997 -
10 * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
11 *
12 * http://pandora.ist.utl.pt
13 *
14 * Instituto Superior Tecnico * Lisboa * PORTUGAL
15 *  The license and distribution terms for this file may be
16 *  found in found in the file LICENSE in this distribution or at
17 *  http://www.OARcorp.com/rtems/license.html.
18 *
19 * $Id$
20 */
21
22#include <bsp.h>
23#include <bsp/irq.h>
24
25/*-------------------------------------------------------------------------+
26| Constants
27+--------------------------------------------------------------------------*/
28#define KBD_CTL      0x61  /* -------------------------------- */
29#define KBD_DATA     0x60  /* Ports for PC keyboard controller */
30#define KBD_STATUS   0x64  /* -------------------------------- */
31
32#define KBD_BUF_SIZE 256
33
34/*-------------------------------------------------------------------------+
35| Global Variables
36+--------------------------------------------------------------------------*/
37static char key_map[] =
38{
39  0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
40  'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
41  'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
42  0134,'z','x','c','v','b','n','m',',','.','/',0x80,
43  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
44  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
45  0x80,0x80,0x80,'0',0177
46}; /* Keyboard scancode -> character map with no modifiers.       */
47
48static char shift_map[] =
49{
50  0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
51  'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
52  'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
53  '|','Z','X','C','V','B','N','M','<','>','?',0x80,
54  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
55  0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
56  '1','2','3','0',177
57}; /* Keyboard scancode -> character map with SHIFT key modifier. */ 
58
59static char             kbd_buffer[KBD_BUF_SIZE];
60static rtems_unsigned16 kbd_first = 0;
61static rtems_unsigned16 kbd_last  = 0;
62static rtems_unsigned16 kbd_end   = KBD_BUF_SIZE - 1;
63
64/*-------------------------------------------------------------------------+
65|         Function: rtemsReboot
66|      Description: Reboot the PC.
67| Global Variables: None.
68|        Arguments: None.
69|          Returns: Nothing.
70+--------------------------------------------------------------------------*/
71void rtemsReboot(void)
72{
73  /* shutdown and reboot */
74  outport_byte(0x64, 0xFE);      /* use keyboard controler to do the job... */
75} /* rtemsReboot */
76
77/*-------------------------------------------------------------------------+
78|         Function: _IBMPC_scankey
79|      Description: This function can be called during a poll for input, or by
80|                   an ISR. Basically any time you want to process a keypress.
81| Global Variables: key_map, shift_map.
82|        Arguments: outChar - character read in case of a valid reading,
83|                   otherwise unchanged.
84|          Returns: TRUE in case a valid character has been read,
85|                   FALSE otherwise.
86+--------------------------------------------------------------------------*/
87rtems_boolean
88_IBMPC_scankey(char *outChar)
89{
90  unsigned char inChar;
91  static int alt_pressed   = 0;
92  static int ctrl_pressed  = 0;
93  static int shift_pressed = 0;
94  static int caps_pressed  = 0;
95  static int extended      = 0;
96
97  *outChar = NULL; /* default value if we return FALSE */
98
99  /* Read keyboard controller, toggle enable */
100  inport_byte(KBD_CTL, inChar);
101  outport_byte(KBD_CTL, inChar & ~0x80);
102  outport_byte(KBD_CTL, inChar | 0x80);
103  outport_byte(KBD_CTL, inChar & ~0x80);
104
105  /* See if it has data */
106  inport_byte(KBD_STATUS, inChar);
107  if ((inChar & 0x01) == 0)
108    return FALSE;
109
110  /* Read the data.  Handle nonsense with shift, control, etc. */
111  inport_byte(KBD_DATA, inChar);
112
113  if (extended)
114    extended--;
115
116  switch (inChar)
117  {
118    case 0xe0:
119      extended = 2;
120      return FALSE;
121      break;
122
123    case 0x38:
124      alt_pressed = 1;
125      return FALSE;
126      break;
127    case 0xb8:
128      alt_pressed = 0;
129      return FALSE;
130      break;
131
132    case 0x1d:
133      ctrl_pressed = 1;
134      return FALSE;
135      break;
136    case 0x9d:
137      ctrl_pressed = 0;
138      return FALSE;
139      break;
140
141    case 0x2a:
142      if (extended)
143        return FALSE;
144    case 0x36:
145      shift_pressed = 1;
146      return FALSE;
147      break;
148    case 0xaa:
149      if (extended)
150        return FALSE;
151    case 0xb6:
152      shift_pressed = 0;
153      return FALSE;
154      break;
155
156    case 0x3a:
157      caps_pressed = 1;
158      return FALSE;
159      break;
160    case 0xba:
161      caps_pressed = 0;
162      return FALSE;
163      break;
164
165    case 0x53:
166      if (ctrl_pressed && alt_pressed) 
167        rtemsReboot(); /* ctrl+alt+del -> reboot */
168      break;
169
170    /*
171     * Ignore unrecognized keys--usually arrow and such
172     */
173    default:
174      if ((inChar & 0x80) || (inChar > 0x39))
175      /* High-bit on means key is being released, not pressed */
176        return FALSE;
177      break;
178  } /* switch */
179
180  /* Strip high bit, look up in our map */
181  inChar &= 0x7f;
182  if (ctrl_pressed)
183  {
184    *outChar = key_map[inChar];
185    *outChar &= 037;
186  }
187  else
188  {
189    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
190    if (caps_pressed)
191    {
192      if (*outChar >= 'A' && *outChar <= 'Z')
193        *outChar += 'a' - 'A';
194      else if (*outChar >= 'a' && *outChar <= 'z')
195        *outChar -= 'a' - 'A';
196    }
197  }
198
199  return TRUE;
200} /* _IBMPC_scankey */
201
202/*-------------------------------------------------------------------------+
203|         Function: _IBMPC_keyboard_isr
204|      Description: Interrupt Service Routine for keyboard (0x01) IRQ.
205| Global Variables: kbd_buffer, kbd_first, kbd_last.
206|        Arguments: vector - standard RTEMS argument - see documentation.
207|          Returns: standard return value - see documentation.
208+--------------------------------------------------------------------------*/
209void _IBMPC_keyboard_isr()
210{
211  if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
212  {
213    /* Got one; save it if there is enough room in buffer. */
214    unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
215
216    if (next != kbd_first)
217      {
218        kbd_last = next;
219      }
220  }
221} /* _IBMPC_keyboard_isr */
222
223
224/*-------------------------------------------------------------------------+
225|         Function: _IBMPC_chrdy
226|      Description: Check keyboard ISR buffer and return character if not empty.
227| Global Variables: kbd_buffer, kbd_first, kbd_last.
228|        Arguments: c - character read if keyboard buffer not empty, otherwise
229|                   unchanged.
230|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
231+--------------------------------------------------------------------------*/
232rtems_boolean
233_IBMPC_chrdy(char *c)
234{
235  /* Check buffer our ISR builds */
236  if (kbd_first != kbd_last)
237  {
238    *c = kbd_buffer[kbd_first];
239
240    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
241    return TRUE;
242  }
243  else
244    return FALSE;
245} /* _IBMPC_chrdy */
246
247
248/*-------------------------------------------------------------------------+
249|         Function: _IBMPC_inch
250|      Description: Poll keyboard until a character is ready and return it.
251| Global Variables: None.
252|        Arguments: None.
253|          Returns: character read from keyboard.
254+--------------------------------------------------------------------------*/
255char
256_IBMPC_inch(void)
257{
258    char c;
259    while (!_IBMPC_chrdy(&c))
260      continue;
261
262    return c;
263} /* _IBMPC_inch */
264
265 
266 /*
267  * Routine that can be used before interrupt management is initialized.
268  */
269 
270char
271BSP_wait_polled_input(void)
272{
273  char c;
274  while (!_IBMPC_scankey(&c))
275    continue;
276
277  return c;
278}
279
280/*-------------------------------------------------------------------------+
281|         Function: _IBMPC_inch_sleep
282|      Description: If charcter is ready return it, otherwise sleep until
283|                   it is ready
284| Global Variables: None.
285|        Arguments: None.
286|          Returns: character read from keyboard.
287+--------------------------------------------------------------------------*/
288char
289_IBMPC_inch_sleep(void)
290{
291    char           c;
292    rtems_interval ticks_per_second;
293
294    ticks_per_second = 0;
295
296    for(;;)
297      {
298        if(_IBMPC_chrdy(&c))
299          {
300            return c;
301          }
302 
303        if(ticks_per_second == 0)
304          {
305            rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, 
306                            &ticks_per_second);
307          }
308        rtems_task_wake_after((ticks_per_second+24)/25);
309      }
310       
311    return c;
312} /* _IBMPC_inch */
313
314
315
316
317
318
Note: See TracBrowser for help on using the repository browser.