// Sending out a command. The controller command, if any, gets sent here.
// This is followed by the first byte for the keyboard or mouse. The
// remaining bytes and any retransmits will be handled by the interrupt
// handler.
static void
ps2_send_command(int controller_command, unsigned char* command, int length, int mouse)
{
    int     status;
    
    CYG_PRECONDITION(NULL == ps2_command, "Only one send command is allowed at a time");
    CYG_PRECONDITION((KC_CONTROL_NULL != controller_command) || (NULL != command), "no-op");
    CYG_PRECONDITION(!mouse || (KC_CONTROL_NULL == controller_command), "cannot combine controller and mouse commands");
    
    ps2_command         = command;
    ps2_command_index   = 0;
    ps2_command_length  = length;
    ps2_command_mouse   = 0;
    ps2_command_ack     = 0;

    if (KC_CONTROL_NULL != controller_command) {
        do {
            HAL_READ_UINT8(KC_STATUS, status);
        } while (status & KC_STATUS_INPB);
        HAL_WRITE_UINT8(KC_CONTROL, controller_command);
    }

    if (length > 0) {
        if (mouse) {
            do {
                HAL_READ_UINT8(KC_STATUS, status);
            } while (status & KC_STATUS_INPB);
            HAL_WRITE_UINT8(KC_CONTROL, KC_CONTROL_WRITE_AUX);
        }
        do {
            HAL_READ_UINT8(KC_STATUS, status);
        } while (status & KC_STATUS_INPB);
        HAL_WRITE_UINT8(KC_INPUT, command[0]);
    }
}
Beispiel #2
0
int main(int argc, char** argv)
{
    CYG_ASSERT( true, message);
    CYG_ASSERT( false, message);
    CYG_ASSERTC(true);
    CYG_ASSERTC(false);
    
    CYG_FAIL(message);
    
    CYG_CHECK_DATA_PTR( &argc, message);
    CYG_CHECK_DATA_PTR( 0,     message);
    CYG_CHECK_FUNC_PTR( &main, message);
    CYG_CHECK_FUNC_PTR( 0,     message);
    CYG_CHECK_DATA_PTRC(&argc);
    CYG_CHECK_DATA_PTRC(0);
    CYG_CHECK_FUNC_PTRC(&main);
    CYG_CHECK_FUNC_PTRC(0);

    CYG_PRECONDITION(true, message);
    CYG_PRECONDITION(false, message);
    CYG_PRECONDITIONC(true);
    CYG_PRECONDITIONC(false);

    CYG_POSTCONDITION(true, message);
    CYG_POSTCONDITION(false, message);
    CYG_POSTCONDITIONC(true);
    CYG_POSTCONDITIONC(false);

    CYG_LOOP_INVARIANT(true, message);
    CYG_LOOP_INVARIANT(false, message);
    CYG_LOOP_INVARIANTC(true);
    CYG_LOOP_INVARIANTC(false);

    CYG_INVARIANT(true, message);
    CYG_INVARIANT(false, message);
    CYG_INVARIANTC(true);
    CYG_INVARIANTC(false);
    
    CYG_TEST_PASS_FINISH("disabled assertions in C code do nothing");
    return 0;
}
static void
ps2kbd_process_scancodes(void)
{
    static int      e0_seen             = 0;
    static MWKEY    pending_up          = MWKEY_UNKNOWN;
    static int      pending_scancode    = 0;
    static int      discard             = 0;
    int scancode;
    int i;
    
    CYG_PRECONDITION(MWKEY_UNKNOWN == ps2kbd_current_key, "There should be no pending key");

    if (MWKEY_UNKNOWN != pending_up) {
        ps2kbd_current_key          = pending_up;
        ps2kbd_current_scancode     = pending_scancode;
        ps2kbd_current_keydown      = 0;
        pending_up                  = MWKEY_UNKNOWN;
        return;
    }
    
    while (MWKEY_UNKNOWN == ps2kbd_current_key) {
        // The ISR will manipulate the scancode buffer directly, so
        // interrupts have to be disabled temporarily.
        scancode = -1;
        cyg_drv_isr_lock();
        if (ps2kbd_scancode_buffer_head != ps2kbd_scancode_buffer_tail) {
            scancode = ps2kbd_scancode_buffer[ps2kbd_scancode_buffer_tail];
            ps2kbd_scancode_buffer_tail = (ps2kbd_scancode_buffer_tail + 1) % PS2KBD_SCANCODE_BUFSIZE;
        }
        cyg_drv_isr_unlock();

        if (scancode == -1) {
            // No more data to be processed.
            break;
        }

        // Are we in one of the special sequences, where bytes should be
        // discarded?
        if (discard > 0) {
            discard -= 1;
            continue;
        }

        // A real scancode has been extracted. Are we in an E0 sequence?
        if (e0_seen) {
            e0_seen = 0;
            ps2kbd_current_keydown = (0 == (scancode & 0x0080));
            scancode &= 0x007F;
            if ((scancode >= PS2KBD_E0_MIN) && (scancode <= PS2KBD_E0_MAX)) {
                ps2kbd_current_key = ps2kbd_e0_map[scancode - PS2KBD_E0_MIN];
                ps2kbd_current_scancode = 0x80 + scancode - PS2KBD_E0_MIN;  // Invent a key scancode
            }
            // We may or may not have a valid keycode at this time, so go
            // around the loop again to check for MWKEY_UNKNOWN
            continue;
        }

        // Is this the start of an E0 sequence?
        if (0x00E0 == scancode) {
            e0_seen = 1;
            continue;
        }

        // How about E1?
        if (0x00E1 == scancode) {
            // For now there is only one key which generates E1 sequences
            ps2kbd_current_key      = MWKEY_BREAK;
            ps2kbd_current_keydown  = 1;
            ps2kbd_current_scancode = 0x00E1;   // Invent another key scancode
            pending_up              = MWKEY_BREAK;
            pending_scancode        = 0x00E1;
            discard = 5;
            return;
        }

        // Must be an ordinary key.
        ps2kbd_current_keydown  = (0 == (scancode & 0x0080));
        scancode &= 0x007F;
        ps2kbd_current_scancode = scancode;
        ps2kbd_current_key      = ps2kbd_keymap[scancode].normal;

        // Detect the modifier keys.
        for (i = 0; MWKEY_UNKNOWN != ps2kbd_modifier_map[i].key; i++) {
            if (ps2kbd_current_key == ps2kbd_modifier_map[i].key) {
                // capslock etc. behave differently. Toggle the current
                // status on the keyup event, ignore key down (because
                // of hardware autorepeat).
                if (ps2kbd_modifier_map[i].toggle) {
                    if (!ps2kbd_current_keydown) {
                        ps2kbd_current_modifiers ^= ps2kbd_modifier_map[i].modifier;
                    }
                } else if (ps2kbd_current_keydown) {
                    ps2kbd_current_modifiers |= ps2kbd_modifier_map[i].modifier;
                } else {
                    ps2kbd_current_modifiers &= ~ps2kbd_modifier_map[i].modifier;
                }
                break;
            }
        }

        // Cope with some of the modifiers.
        if (0 != (ps2kbd_current_modifiers & (MWKMOD_LCTRL | MWKMOD_RCTRL))) {
            // Control key. a-z and A-Z go to ctrl-A - ctrl-Z, i.e. 1 to 26
            // Other characters in the range 64 to 96, e.g. [ and ], also
            // get translated. This includes the A-Z range.
            if ((64 <= ps2kbd_current_key) && (ps2kbd_current_key < 96)) {
                ps2kbd_current_key -= 64;
            } else if (('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) {
                ps2kbd_current_key -= 96;
            }
        } else if (ps2kbd_current_modifiers & (MWKMOD_LSHIFT | MWKMOD_RSHIFT)) {
            // Pick up the shift entry from the keymap
            ps2kbd_current_key = ps2kbd_keymap[scancode].shifted;
        }
        
        if (ps2kbd_current_modifiers & MWKMOD_CAPS) {
            // Capslock only affects a-z and A-z
            if ( ('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) {
                ps2kbd_current_key = (ps2kbd_current_key -'a') + 'A';
            } else if (('A' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'Z')) {
                ps2kbd_current_key = (ps2kbd_current_key -'A') + 'a';
            }
        }

        // If we have found a real key, the loop will exit.
        // Otherwise try again.
    }
}