⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbd_support.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
     KBD_Empty,     KBD_Empty,      KBD_Empty,      KBD_Empty },
};

static cyg_uint8 kbd_chars[96] = {
    /* 0x00 - 0x0F */
    0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    /* 0x10 - 0x1F */
     '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',  '0',  '-',  '=', 0x08, 0x00, 0x00, 0x00,
    /* 0x20 - 0x2F */
    '\t',  'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',  'o',  'p',  '[',  ']', '\\', 0x00, 0x00,
    /* 0x30 - 0x3F */
    0x00,  'a',  's',  'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';', '\'', 0x0D, 0x00, 0x00, 0x00,
    /* 0x40 - 0x4F */
    0x00,  'z',  'x',  'c',  'v',  'b',  'n',  'm',  ',',  '.',  '/', 0x00, 0x00, 0x00, 0x00, 0x00,
    /* 0x50 - 0x5F */
    0x00, 0x00, 0x00, 0x00,  ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

static cyg_uint8 kbd_shifted_chars[96] = {
    /* 0x00 - 0x0F */
    '\b', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    /* 0x10 - 0x1F */
     '!',  '@',  '#',  '$',  '%',  '^',  '&',  '*',  '(',  ')',  '_',  '+', 0x08, 0x00, 0x00, 0x00,
    /* 0x20 - 0x2F */
    '\t',  'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',  'O',  'P',  '{',  '}',  '|', 0x00, 0x00,
    /* 0x30 - 0x3F */
    0x00,  'A',  'S',  'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',  '"', 0x0D, 0x00, 0x00, 0x00,
    /* 0x40 - 0x4F */
    0x00,  'Z',  'X',  'C',  'V',  'B',  'N',  'M',  '<',  '>',  '?', 0x00, 0x00, 0x00, 0x00, 0x00,
    /* 0x50 - 0x5F */
    0x00, 0x00, 0x00, 0x00,  ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

// This ISR is called when the keyboard interrupt occurs
static int
keyboard_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
{
    cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_KBDINT);
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
}

// This DSR handles the keyboard [logical] processing
static void
keyboard_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
    // Tell the keyboard processing thread to give it a shot
    cyg_semaphore_post(&kbd_sem);
}

static void
kbd_server(cyg_addrword_t p)
{
    int col, bit, key, event, timeout;
    diag_printf("KBD server here\n");
    while (TRUE) {
        cyg_semaphore_wait(&kbd_sem);
        // As long as keys are pressed, scan and update
        timeout = 0;
        while (TRUE) {
            // Wait for 20ms - time to debounce keyboard
            cyg_thread_delay(2);
            // Scan keyboard
            kbd_scan();
            // Reset state
            for (key = 0;  key < sizeof(kbd_new_state);  key++) {
                kbd_new_state[key] = 0;
            }
            // Check state of all keys and send events for those that change
            for (col = 0;  col < 8;  col++) {
                for (bit = 0;  bit < 8;  bit++) {
                    if (col_state[col] & (1<<bit)) {
                        key = kbd_map[col][bit];
                        if (key != KBD_Empty) {
                            kbd_new_state[key] = 1;
                        }
                    }
                    if (ext_state[col] & (1<<bit)) {
                        key = kbd_map[col][bit+8];
                        if (key != KBD_Empty) {
                            kbd_new_state[key] = 1;
                        }
                    }
                }
            }
            // Compare new and old (known) states, generate events for changes
            // Send events for modifier keys first.
            for (key = 0;  key < sizeof(kbd_new_state);  key++) {
                if (kbd_state[key] != kbd_new_state[key]) {
                    event = 0xFF;
                    switch (key) {
                    case KBD_LeftShift:
                    case KBD_RightShift:
                    case KBD_Ctrl:
                    case KBD_LeftAlt:
                    case KBD_RightAlt:
                    case KBD_Function:
                    case KBD_CapsLock:
                        if (kbd_state[key]) {
                            // Key going up
                            event = key;
                        } else {
                            // Key going down
                            event = key + KBD_Press;
                        }
                        kbd_state[key] = kbd_new_state[key];
                    }
                    if (event != 0xFF) {
                        if (!cyg_mbox_tryput(kbd_events_mbox_handle, (void *)event)) {
                            diag_printf("KBD event lost: %x\n", event);
                        }
                    }
                }
            }
            // First key up events
            for (key = 0;  key < sizeof(kbd_new_state);  key++) {
                if (kbd_state[key] != kbd_new_state[key]) {
                    if (kbd_state[key]) {
                        // Key going up
                        event = key;
                    } else {
                        // Key going down
                        event = key + KBD_Press;
                    }
                    if (!cyg_mbox_tryput(kbd_events_mbox_handle, (void *)event)) {
                        diag_printf("KBD event lost: %x\n", event);
                    }
                }
                kbd_state[key] = kbd_new_state[key];
            }
            // Clear interrupt (true when keys are pressed)
            cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_KBDINT);
#if 0
            if (*(volatile cyg_uint32 *)INTSR2 & INTSR2_KBDINT) {
                timeout = 0;
            } else if (++timeout == 5) {
                // No keys for 100ms
                break;
            }
#endif
        }
        // Allow interrupts to happen again
        cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_KBDINT);
        cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_KBDINT);
    }
}

void
kbd_init(void)
{
    // Initialize environment, setup interrupt handler
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_KBDINT,
                             99,                     // Priority - what goes here?
                             0,                      //  Data item passed to interrupt handler
                             (cyg_ISR_t *)keyboard_isr,
                             (cyg_DSR_t *)keyboard_dsr,
                             &kbd_interrupt_handle,
                             &kbd_interrupt);
    cyg_drv_interrupt_attach(kbd_interrupt_handle);
    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_KBDINT);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_KBDINT);
    // Set up the mbox for keyboard data
    cyg_mbox_create(&kbd_events_mbox_handle, &kbd_events_mbox);
    // This semaphore is set when there is a keypress
    cyg_semaphore_init(&kbd_sem, 0);  
    // Create a thread whose job it is to de-bounce the keyboard and
    // actually process the input, turning it into a series of events
    cyg_thread_create(10,                           // Priority - just a number
                      kbd_server,                   // entry
                      0,                            // initial parameter
                      "KBD_server",                 // Name
                      &kbd_server_stack[0],         // Stack
                      STACK_SIZE,                   // Size
                      &kbd_server_thread_handle,    // Handle
                      &kbd_server_thread_data       // Thread data structure
            );
    cyg_thread_resume(kbd_server_thread_handle);  // Start it
}

#define MOD_Shift    0x40
#define MOD_Ctrl     0x20
#define MOD_CapsLock 0x10
static cyg_uint32    kbd_modifiers;

cyg_uint8 
kbd_getc(void)
{
    cyg_uint8 ch;
    cyg_uint32 kbd_event;
    while (TRUE) {
        kbd_event = (cyg_uint32)cyg_mbox_get(kbd_events_mbox_handle);
        switch (kbd_event & 0x7F) {
        case KBD_LeftShift:
        case KBD_RightShift:
            if (kbd_event & KBD_Press) {
                kbd_modifiers |= MOD_Shift;
            } else {
                kbd_modifiers &= ~MOD_Shift;
            }
            break;
        case KBD_Ctrl:
            if (kbd_event & KBD_Press) {
                kbd_modifiers |= MOD_Ctrl;
            } else {
                kbd_modifiers &= ~MOD_Ctrl;
            }
            break;
        case KBD_CapsLock:
            if (kbd_event & KBD_Press) {                
                kbd_modifiers ^= MOD_CapsLock;
            }
            break;
        case KBD_LeftAlt:
        case KBD_RightAlt:
        case KBD_Function:
        default:
        }
        // Return character [if one has arrived]
        if (kbd_event & KBD_Press) {
            if (kbd_modifiers & (MOD_Shift|MOD_CapsLock)) {
                ch = kbd_shifted_chars[kbd_event & 0x7F];
            } else {
                ch = kbd_chars[kbd_event & 0x7F];
            }
            if (kbd_modifiers & MOD_Ctrl) {
                ch &= 0x1F;
            }
            if (ch) {
                return (ch);
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -