Vystem 0.2
This commit is contained in:
777
shelter/lib/src/devs/input/ps2.c
Normal file
777
shelter/lib/src/devs/input/ps2.c
Normal file
@@ -0,0 +1,777 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#include "devs/input/ps2.h"
|
||||
#include "devs/input/kbd.h"
|
||||
#include "irq/irq.h"
|
||||
enum ps2_scancode_state {
|
||||
PS2_SCANCODE_STATE_NORMAL,
|
||||
PS2_SCANCODE_STATE_E0,
|
||||
PS2_SCANCODE_STATE_E1
|
||||
};
|
||||
enum ps2_command_state {
|
||||
PS2_COMMAND_STATE_IDLE,
|
||||
PS2_COMMAND_STATE_WAIT_ACK,
|
||||
PS2_COMMAND_STATE_WAIT_LED_ACK_1,
|
||||
PS2_COMMAND_STATE_WAIT_LED_ACK_2,
|
||||
PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1,
|
||||
PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2,
|
||||
PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK,
|
||||
PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1,
|
||||
PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2,
|
||||
PS2_COMMAND_STATE_WAIT_ECHO,
|
||||
PS2_COMMAND_STATE_WAIT_RESET_ACK,
|
||||
PS2_COMMAND_STATE_WAIT_RESET_RESULT
|
||||
};
|
||||
typedef struct {
|
||||
enum ps2_scancode_state scancode_state;
|
||||
enum ps2_command_state command_state;
|
||||
sh_ps2_KBD_COMMAND current_command;
|
||||
sh_uint8 last_byte;
|
||||
sh_uint8 e1_bytes_left;
|
||||
sh_uint8 e1_bytes_idx;
|
||||
sh_uint8 e1_bytes_array[5];
|
||||
sh_bool command_in_progress;
|
||||
sh_uint8 keyboard_id[2];
|
||||
sh_uint8 keyboard_id_len;
|
||||
sh_bool scanning_enabled;
|
||||
sh_bool shift_state;
|
||||
sh_bool l_alt_state;
|
||||
sh_bool r_alt_state;
|
||||
sh_bool l_ctrl_state;
|
||||
sh_bool r_ctrl_state;
|
||||
sh_bool win_state;
|
||||
sh_bool capslock_state;
|
||||
sh_bool numlock_state;
|
||||
sh_kbd_DRIVER_HANDLE *d_handle;
|
||||
} ps2_state_template;
|
||||
ps2_state_template ps2_state;
|
||||
static void sh_ps2_send_keyboard_command(sh_uint8 cmd,sh_uint8 data,sh_bool has_data) {
|
||||
ps2_state.current_command.command=cmd;
|
||||
ps2_state.current_command.data=data;
|
||||
ps2_state.current_command.has_data=has_data;
|
||||
ps2_state.command_in_progress=SH_TRUE;
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_DATA,cmd);
|
||||
}
|
||||
SH_STATUS sh_ps2_send_keyboard_command_wait(sh_uint8 cmd,sh_uint8 data,sh_bool has_data) {
|
||||
sh_ps2_send_keyboard_command(cmd,data,has_data);
|
||||
while (ps2_state.command_in_progress) {
|
||||
asm volatile("hlt");
|
||||
}
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
// Because we don't have a scheduler or kernel threads/worker, we can't properly update these leds for the moment
|
||||
__attribute__((__unused__)) static void sh_ps2_update_leds() {
|
||||
sh_uint8 led_byte=0;
|
||||
if (ps2_state.numlock_state) {
|
||||
led_byte|=SH_PS2_KBD_LEDS_NUM_LOCK;
|
||||
}
|
||||
if (ps2_state.capslock_state) {
|
||||
led_byte|=SH_PS2_KBD_LEDS_CAPS_LOCK;
|
||||
}
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_SET_LEDS,led_byte,SH_TRUE);
|
||||
return;
|
||||
}
|
||||
static SH_STATUS sh_ps2_handle_command_response(sh_uint8 data) {
|
||||
if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_ACK) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
if (ps2_state.current_command.command==SH_PS2_KBD_COMMAND_DISABLE_SCANNING) {
|
||||
ps2_state.scanning_enabled=SH_FALSE;
|
||||
} else if (ps2_state.current_command.command==SH_PS2_KBD_COMMAND_ENABLE_SCANNING) {
|
||||
ps2_state.scanning_enabled=SH_TRUE;
|
||||
}
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.current_command.command=0;
|
||||
ps2_state.current_command.data=0;
|
||||
ps2_state.current_command.has_data=SH_FALSE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
sh_ps2_send_keyboard_command(ps2_state.current_command.command,ps2_state.current_command.data,ps2_state.current_command.has_data);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_ECHO) {
|
||||
if (data==SH_PS2_KBD_COMMAND_ECHO) {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else {
|
||||
sh_iprint(SH_DEBUG,"wrong echo\n");
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
ps2_state.keyboard_id_len=0;
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_IDENTIFY,0,SH_FALSE);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1) {
|
||||
ps2_state.keyboard_id[0]=data;
|
||||
ps2_state.keyboard_id_len=1;
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2) {
|
||||
ps2_state.keyboard_id[1]=data;
|
||||
ps2_state.keyboard_id_len=2;
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_LED_ACK_1) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_2;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_SET_LEDS,ps2_state.current_command.data,SH_TRUE);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_LED_ACK_2) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_RESET_ACK) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_RESET_RESULT;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_RESET,0,SH_FALSE);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_RESET_ACK;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_RESET_RESULT) {
|
||||
if (data==0xAA || data==0xFC) {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else {
|
||||
sh_iprintf(SH_DEBUG,"wrong reset\n");
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_SC_SET,ps2_state.current_command.data,SH_TRUE);
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1;
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2) {
|
||||
if (data==SH_PS2_KBD_ACK) {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
return SH_STATUS_SUCCESS;
|
||||
} else if (data==SH_PS2_KBD_RESEND) {
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
return SH_STATUS_INVALID_STATE;
|
||||
}
|
||||
static inline sh_bool sh_ps2_shift() {
|
||||
return ps2_state.shift_state;
|
||||
}
|
||||
static inline sh_bool sh_ps2_alt() {
|
||||
return ps2_state.l_alt_state || ps2_state.r_alt_state;
|
||||
}
|
||||
static inline sh_bool sh_ps2_ctrl() {
|
||||
return ps2_state.l_ctrl_state || ps2_state.r_ctrl_state;
|
||||
}
|
||||
static void sh_ps2_handle_scancodes(sh_uint8 data) {
|
||||
if (data==0xE0 && ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_E0;
|
||||
return;
|
||||
} else if (data==0xE1 && ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_E1;
|
||||
ps2_state.e1_bytes_left=5;
|
||||
ps2_state.e1_bytes_idx=0;
|
||||
return;
|
||||
}
|
||||
if (ps2_state.scancode_state!=PS2_SCANCODE_STATE_E1) {
|
||||
switch (data) {
|
||||
case 0x1D: {
|
||||
// ctrl pressed
|
||||
if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LCTRL,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.l_ctrl_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RCTRL,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.r_ctrl_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x9D: {
|
||||
// ctrl released
|
||||
if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LCTRL,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.l_ctrl_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RCTRL,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.r_ctrl_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x36: {
|
||||
// right shift pressed
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RSHIFT,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.shift_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x2A: {
|
||||
// left shift pressed
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LSHIFT,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.shift_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0xAA: {
|
||||
// left shift released
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LSHIFT,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.shift_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0xB6: {
|
||||
// right shift released
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RSHIFT,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.shift_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x38: {
|
||||
// alt pressed
|
||||
if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LALT,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.l_alt_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RALT,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.r_alt_state=SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xB8: {
|
||||
// alt released
|
||||
if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_LALT,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.l_alt_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_RALT,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.r_alt_state=SH_FALSE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt());
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xC5: {
|
||||
// numlock released
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_NUMLOCK,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.numlock_state=ps2_state.numlock_state?SH_FALSE:SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_VER_NUM,ps2_state.numlock_state);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings numlock flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0xBA: {
|
||||
// capslock released
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_CAPSLOCK,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
ps2_state.capslock_state=ps2_state.capslock_state?SH_FALSE:SH_TRUE;
|
||||
status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_VER_MAJ,ps2_state.capslock_state);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error settings capslock flags: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x45: {
|
||||
// numlock pressed
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_NUMLOCK,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x3A: {
|
||||
// capslock pressed
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=SH_KBD_CONTEXT_CAPSLOCK,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_CONTEXT,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) {
|
||||
if (data & (1u<<7)) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=0x0000|data,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_PS2_NORMAL,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=0x0000|data,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_PS2_NORMAL,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) {
|
||||
if (data & (1u<<7)) {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=0xE000|data,
|
||||
.pressed=SH_FALSE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_PS2_E0,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=0xE000|data,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_PS2_E0,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E1) {
|
||||
ps2_state.e1_bytes_array[ps2_state.e1_bytes_idx]=data;
|
||||
ps2_state.e1_bytes_left--;
|
||||
ps2_state.e1_bytes_idx++;
|
||||
if (ps2_state.e1_bytes_idx==5 && ps2_state.e1_bytes_left==0) ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
sh_kbd_EVENT ev={
|
||||
.scancode=0,
|
||||
.pressed=SH_TRUE,
|
||||
.context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()),
|
||||
.context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state),
|
||||
.context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state),
|
||||
.context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state),
|
||||
.event_type=SH_EVENT_TYPE_KBD_PAUSE,
|
||||
.timestamp=sh_tsc_get_kernel_current_tsc()
|
||||
};
|
||||
SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev);
|
||||
if (sh_status_error(status)) {
|
||||
sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
void sh_ps2_irq1_handler() {
|
||||
sh_uint8 data;
|
||||
if (!sh_ps2_output_ready()) return;
|
||||
data=sh_asm_inb(SH_PS2_PORT_DATA);
|
||||
ps2_state.last_byte=data;
|
||||
if (ps2_state.command_in_progress) {
|
||||
sh_ps2_handle_command_response(data);
|
||||
return;
|
||||
}
|
||||
if (ps2_state.scanning_enabled) {
|
||||
sh_ps2_handle_scancodes(data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
SH_STATUS sh_ps2_driver_init() {
|
||||
sh_asm_cli();
|
||||
// flush output buffer
|
||||
while (sh_ps2_output_ready()) {
|
||||
sh_asm_inb(SH_PS2_PORT_DATA);
|
||||
}
|
||||
// debug log status and config byte
|
||||
sh_printf(SH_DEBUG,"PS2 status byte initial value: 0x%1U\n",sh_ps2_read_status());
|
||||
sh_printf(SH_DEBUG,"PS2 config byte initial value: 0x%1U\n",sh_ps2_read_config());
|
||||
// disable ps2 ports
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_DISABLE);
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT2_DISABLE);
|
||||
// reflush output buffer
|
||||
while (sh_ps2_output_ready()) {
|
||||
sh_asm_inb(SH_PS2_PORT_DATA);
|
||||
}
|
||||
// disable IRQs
|
||||
sh_uint8 cfg=sh_ps2_read_config();
|
||||
cfg&= (sh_uint8)~SH_PS2_CONFIG_PORT1_IRQ;
|
||||
cfg&= (sh_uint8)~SH_PS2_CONFIG_PORT2_IRQ;
|
||||
sh_ps2_write_config(cfg);
|
||||
// ps2 self test
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PS2_SELF_TEST);
|
||||
while (!sh_ps2_output_ready());
|
||||
sh_uint8 result=sh_asm_inb(SH_PS2_PORT_DATA);
|
||||
if (result!=SH_PS2_SELF_TEST_SUCCESS) return SH_STATUS_TEST_FAILED;
|
||||
// port1 test
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_TEST);
|
||||
while (!sh_ps2_output_ready());
|
||||
result=sh_asm_inb(SH_PS2_PORT_DATA);
|
||||
if (result!=SH_PS2_PORTS_SELF_TEST_SUCCESS) return SH_STATUS_TEST_FAILED;
|
||||
// enable port1
|
||||
while (sh_ps2_cant_write());
|
||||
sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_ENABLE);
|
||||
// enable translation
|
||||
cfg=sh_ps2_read_config();
|
||||
cfg|=SH_PS2_CONFIG_TRANSLATION;
|
||||
sh_ps2_write_config(cfg);
|
||||
// initialize ps2_state struct
|
||||
ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL;
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_IDLE;
|
||||
ps2_state.current_command.command=0;
|
||||
ps2_state.current_command.data=0;
|
||||
ps2_state.current_command.has_data=SH_FALSE;
|
||||
ps2_state.last_byte=0;
|
||||
ps2_state.e1_bytes_left=0;
|
||||
ps2_state.command_in_progress=SH_FALSE;
|
||||
ps2_state.keyboard_id[0]=0;
|
||||
ps2_state.keyboard_id[1]=0;
|
||||
ps2_state.keyboard_id_len=0;
|
||||
ps2_state.shift_state=SH_FALSE;
|
||||
ps2_state.l_alt_state=SH_FALSE;
|
||||
ps2_state.r_alt_state=SH_FALSE;
|
||||
ps2_state.l_ctrl_state=SH_FALSE;
|
||||
ps2_state.r_ctrl_state=SH_FALSE;
|
||||
ps2_state.win_state=SH_FALSE;
|
||||
ps2_state.capslock_state=SH_FALSE;
|
||||
ps2_state.numlock_state=SH_FALSE;
|
||||
// enabling IRQ1
|
||||
cfg=sh_ps2_read_config();
|
||||
cfg|=(sh_uint8)SH_PS2_CONFIG_PORT1_IRQ;
|
||||
sh_ps2_write_config(cfg);
|
||||
SH_STATUS status=sh_irq_legacy_register_handler(1,&sh_ps2_irq1_handler);
|
||||
if (sh_status_error(status)) return status;
|
||||
sh_asm_sti();
|
||||
// disabling scanning
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_DISABLE_SCANNING,0,SH_FALSE);
|
||||
// set leds
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_SET_LEDS,0,SH_TRUE);
|
||||
// identify keyboard
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_IDENTIFY,0,SH_FALSE);
|
||||
sh_printf(SH_DEBUG,"PS2 identifier value : 0x%1U 0x%1U\n",ps2_state.keyboard_id[0],ps2_state.keyboard_id[1]);
|
||||
// register ps2 keyboard
|
||||
status=sh_kbd_register_ps2(SH_TRUE,&ps2_state.d_handle);
|
||||
if (sh_status_error(status)) return status;
|
||||
// enable scanning
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_ENABLE_SCANNING,0,SH_FALSE);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_ps2_disable_scanning() {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_DISABLE_SCANNING,0,SH_FALSE);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
SH_STATUS sh_ps2_enable_scanning() {
|
||||
ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK;
|
||||
sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_ENABLE_SCANNING,0,SH_FALSE);
|
||||
return SH_STATUS_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user