OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [drivers/] [keyboard.c] - Diff between revs 2 and 175

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 175
#include "common.h"
#include "common.h"
#include "board.h"
#include "board.h"
#include "support.h"
#include "support.h"
#include "int.h"
#include "int.h"
#include "keyboard.h"
#include "keyboard.h"
 
 
#if KBD_ENABLED
#if KBD_ENABLED
 
 
volatile int kbd_tail = 0;
volatile int kbd_tail = 0;
volatile int kbd_head = 0;
volatile int kbd_head = 0;
volatile int kbd_buf[KBDBUF_SIZE];
volatile int kbd_buf[KBDBUF_SIZE];
 
 
static const unsigned char scan2ascii[2][0x40] = {
static const unsigned char scan2ascii[2][0x40] = {
 {0x1f, 0x00, '1', '2',  '3', '4', '5', '6',   /* 0x00 */
 {0x1f, 0x00, '1', '2',  '3', '4', '5', '6',   /* 0x00 */
  '7', '8', '9', '0',    '-', '=', '\b', '\t',
  '7', '8', '9', '0',    '-', '=', '\b', '\t',
  'q', 'w', 'e', 'r',    't', 'y', 'u', 'i',   /* 0x10 */
  'q', 'w', 'e', 'r',    't', 'y', 'u', 'i',   /* 0x10 */
  'o', 'p', '[', ']',    '\n', 0x00, 'a', 's',
  'o', 'p', '[', ']',    '\n', 0x00, 'a', 's',
  'd', 'f', 'g', 'h',    'j', 'k', 'l', ';',   /* 0x20 */
  'd', 'f', 'g', 'h',    'j', 'k', 'l', ';',   /* 0x20 */
  '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v',
  '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v',
  'b', 'n', 'm', ',',    '.', '/', 0xff, 0x00, /* 0x30 */
  'b', 'n', 'm', ',',    '.', '/', 0xff, 0x00, /* 0x30 */
  0x00, ' ', 0x00, 0x00, 0x00, 0x00,0x00,0x00},
  0x00, ' ', 0x00, 0x00, 0x00, 0x00,0x00,0x00},
 
 
 {0x00, 0x00, '!', '@',  '#', '$', '%', '^',  /* 0x00 */
 {0x00, 0x00, '!', '@',  '#', '$', '%', '^',  /* 0x00 */
  '&',  '*', '(', ')',   '_', '+', 0x00,0x00,
  '&',  '*', '(', ')',   '_', '+', 0x00,0x00,
  'Q', 'W', 'E', 'R',    'T', 'Y', 'U', 'I',  /* 0X10 */
  'Q', 'W', 'E', 'R',    'T', 'Y', 'U', 'I',  /* 0X10 */
  'O', 'P', '{', '}',    '\n', 0x00, 'A', 'S',
  'O', 'P', '{', '}',    '\n', 0x00, 'A', 'S',
  'D', 'F', 'G', 'H',    'J', 'K', 'L', ':',  /* 0X20 */
  'D', 'F', 'G', 'H',    'J', 'K', 'L', ':',  /* 0X20 */
  '"', '~', 0xff, '|',   'Z', 'X', 'C', 'V',
  '"', '~', 0xff, '|',   'Z', 'X', 'C', 'V',
  'B', 'N', 'M', '<',    '>', '?', 0xff, 0x00,/* 0x30 */
  'B', 'N', 'M', '<',    '>', '?', 0xff, 0x00,/* 0x30 */
  0x00, ' ', 0x00, 0x00, 0x00, 0x00,0x00,0x00}};
  0x00, ' ', 0x00, 0x00, 0x00, 0x00,0x00,0x00}};
 
 
static int shift_state = 0;
static int shift_state = 0;
 
 
static void put_queue(int ch)
static void put_queue(int ch)
{
{
  //putc (ch);
  //putc (ch);
  debug ("put_queue %c (%i,%i)\n", ch, kbd_head, kbd_tail);
  debug ("put_queue %c (%i,%i)\n", ch, kbd_head, kbd_tail);
        kbd_buf[kbd_head] = ch;
        kbd_buf[kbd_head] = ch;
        kbd_head = (kbd_head + 1) % KBDBUF_SIZE;
        kbd_head = (kbd_head + 1) % KBDBUF_SIZE;
}
}
 
 
static void handle_scancode (unsigned char scan)
static void handle_scancode (unsigned char scan)
{
{
  unsigned char c;
  unsigned char c;
  if (scan >= 0x40) {
  if (scan >= 0x40) {
    scan &= 0x7f;
    scan &= 0x7f;
    if (scan >= 0x40) return;
    if (scan >= 0x40) return;
    c = scan2ascii[shift_state][scan];
    c = scan2ascii[shift_state][scan];
    if (c == 0xff) shift_state = 0;
    if (c == 0xff) shift_state = 0;
    return;
    return;
  }
  }
  c = scan2ascii[shift_state][scan];
  c = scan2ascii[shift_state][scan];
  if (c == 0xff) shift_state = 1;
  if (c == 0xff) shift_state = 1;
  else put_queue (c);
  else put_queue (c);
}
}
 
 
static void keyboard_interrupt(void)
static void keyboard_interrupt(void)
{
{
        unsigned char status = REG8(KBD_BASE_ADD + 0x4);
        unsigned char status = REG8(KBD_BASE_ADD + 0x4);
        debug ("keyboard_interrupt\n");
        debug ("keyboard_interrupt\n");
        do {
        do {
                if (status & 0x01) handle_scancode(REG8(KBD_BASE_ADD + 0x0));
                if (status & 0x01) handle_scancode(REG8(KBD_BASE_ADD + 0x0));
                status = REG8(KBD_BASE_ADD + 0x4);
                status = REG8(KBD_BASE_ADD + 0x4);
        } while (status & 0x01);
        } while (status & 0x01);
}
}
 
 
static int kbd_wait_for_input(void)
static int kbd_wait_for_input(void)
{
{
  int     n;
  int     n;
  int     status, data;
  int     status, data;
 
 
  n = TIMEOUT_CONST;
  n = TIMEOUT_CONST;
  do {
  do {
    status = REG8(KBD_STATUS_REG);
    status = REG8(KBD_STATUS_REG);
     /*
     /*
      * Wait for input data to become available.  This bit will
      * Wait for input data to become available.  This bit will
      * then be cleared by the following read of the DATA
      * then be cleared by the following read of the DATA
      * register.
      * register.
      */
      */
 
 
    if (!(status & KBD_OBF)) continue;
    if (!(status & KBD_OBF)) continue;
 
 
                data = REG8(KBD_DATA_REG);
                data = REG8(KBD_DATA_REG);
 
 
    /*
    /*
     * Check to see if a timeout error has occurred.  This means
     * Check to see if a timeout error has occurred.  This means
     * that transmission was started but did not complete in the
     * that transmission was started but did not complete in the
     * normal time cycle.  PERR is set when a parity error occurred
     * normal time cycle.  PERR is set when a parity error occurred
     * in the last transmission.
     * in the last transmission.
     */
     */
    if (status & (KBD_GTO | KBD_PERR)) continue;
    if (status & (KBD_GTO | KBD_PERR)) continue;
 
 
                return (data & 0xff);
                return (data & 0xff);
  } while (--n);
  } while (--n);
  return (-1);  /* timed-out if fell through to here... */
  return (-1);  /* timed-out if fell through to here... */
}
}
 
 
static void kbd_write (int address, int data)
static void kbd_write (int address, int data)
{
{
        int status;
        int status;
        do {
        do {
                status = REG8(KBD_STATUS_REG);  /* spin until input buffer empty*/
                status = REG8(KBD_STATUS_REG);  /* spin until input buffer empty*/
        } while (status & KBD_IBF);
        } while (status & KBD_IBF);
  REG8 (address) = data;               /* write out the data*/
  REG8 (address) = data;               /* write out the data*/
}
}
 
 
int kbd_init(void)
int kbd_init(void)
{
{
        int_add (KBD_IRQ, keyboard_interrupt);
        int_add (KBD_IRQ, keyboard_interrupt);
 
 
        /* Flush any pending input. */
        /* Flush any pending input. */
        while (kbd_wait_for_input() != -1) continue;
        while (kbd_wait_for_input() != -1) continue;
 
 
        /*
        /*
         * Test the keyboard interface.
         * Test the keyboard interface.
         * This seems to be the only way to get it going.
         * This seems to be the only way to get it going.
         * If the test is successful a x55 is placed in the input buffer.
         * If the test is successful a x55 is placed in the input buffer.
         */
         */
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST);
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST);
        if (kbd_wait_for_input() != 0x55) {
        if (kbd_wait_for_input() != 0x55) {
                printf ("initialize_kbd: keyboard failed self test.\n");
                printf ("initialize_kbd: keyboard failed self test.\n");
                return(-1);
                return(-1);
        }
        }
 
 
        /*
        /*
         * Perform a keyboard interface test.  This causes the controller
         * Perform a keyboard interface test.  This causes the controller
         * to test the keyboard clock and data lines.  The results of the
         * to test the keyboard clock and data lines.  The results of the
         * test are placed in the input buffer.
         * test are placed in the input buffer.
         */
         */
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2);
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2);
        if (kbd_wait_for_input() != 0x00) {
        if (kbd_wait_for_input() != 0x00) {
                printf ("initialize_kbd: keyboard failed self test 2.\n");
                printf ("initialize_kbd: keyboard failed self test 2.\n");
                return(-1);
                return(-1);
        }
        }
 
 
        /* Enable the keyboard by allowing the keyboard clock to run. */
        /* Enable the keyboard by allowing the keyboard clock to run. */
        kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE);
        kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE);
 
 
        /*
        /*
         * Reset keyboard. If the read times out
         * Reset keyboard. If the read times out
         * then the assumption is that no keyboard is
         * then the assumption is that no keyboard is
         * plugged into the machine.
         * plugged into the machine.
         * This defaults the keyboard to scan-code set 2.
         * This defaults the keyboard to scan-code set 2.
         */
         */
        kbd_write(KBD_DATA_REG, KBD_RESET);
        kbd_write(KBD_DATA_REG, KBD_RESET);
        if (kbd_wait_for_input() != KBD_ACK) {
        if (kbd_wait_for_input() != KBD_ACK) {
                printf ("initialize_kbd: reset kbd failed, no ACK.\n");
                printf ("initialize_kbd: reset kbd failed, no ACK.\n");
                return(-1);
                return(-1);
        }
        }
 
 
        if (kbd_wait_for_input() != KBD_POR) {
        if (kbd_wait_for_input() != KBD_POR) {
                printf ("initialize_kbd: reset kbd failed, not POR.\n");
                printf ("initialize_kbd: reset kbd failed, not POR.\n");
                return(-1);
                return(-1);
        }
        }
 
 
        /*
        /*
         * now do a DEFAULTS_DISABLE always
         * now do a DEFAULTS_DISABLE always
         */
         */
        kbd_write(KBD_DATA_REG, KBD_DISABLE);
        kbd_write(KBD_DATA_REG, KBD_DISABLE);
        if (kbd_wait_for_input() != KBD_ACK) {
        if (kbd_wait_for_input() != KBD_ACK) {
                printf ("initialize_kbd: disable kbd failed, no ACK.\n");
                printf ("initialize_kbd: disable kbd failed, no ACK.\n");
                return(-1);
                return(-1);
        }
        }
 
 
        /*
        /*
         * Enable keyboard interrupt, operate in "sys" mode,
         * Enable keyboard interrupt, operate in "sys" mode,
         *  enable keyboard (by clearing the disable keyboard bit),
         *  enable keyboard (by clearing the disable keyboard bit),
         *  disable mouse, do conversion of keycodes.
         *  disable mouse, do conversion of keycodes.
         */
         */
        kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE);
        kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE);
        kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC);
        kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC);
 
 
        /*
        /*
         * now ENABLE the keyboard to set it scanning...
         * now ENABLE the keyboard to set it scanning...
         */
         */
        kbd_write(KBD_DATA_REG, KBD_ENABLE);
        kbd_write(KBD_DATA_REG, KBD_ENABLE);
        if (kbd_wait_for_input() != KBD_ACK) {
        if (kbd_wait_for_input() != KBD_ACK) {
                printf ("initialize_kbd: keyboard enable failed.\n");
                printf ("initialize_kbd: keyboard enable failed.\n");
                return(-1);
                return(-1);
        }
        }
 
 
  int_enable (KBD_IRQ);
  int_enable (KBD_IRQ);
        printf ("PS/2 keyboard initialized at 0x%x (irq = %d).\n", KBD_BASE_ADD, KBD_IRQ);
        printf ("PS/2 keyboard initialized at 0x%x (irq = %d).\n", KBD_BASE_ADD, KBD_IRQ);
        return (1);
        return (1);
}
}
 
 
#endif /* KBD_ENABLED */
#endif /* KBD_ENABLED */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.