use spin::Mutex;
use device::io::Port;
pub struct Ps2 {
pub controller: Port<u8>,
pub device: Port<u8>,
}
impl Ps2 {
pub const unsafe fn new(controller: u16, device: u16) -> Ps2 {
Ps2 {
controller: Port::new(controller),
device: Port::new(device),
}
}
pub fn wait_then_read(&mut self) -> u8 {
while self.controller.read() & 0x1 == 0 {}
self.device.read()
}
pub fn wait_then_write(&mut self, data: u8) {
while self.controller.read() & 0x2 == 1 {}
self.device.write(data);
}
pub fn init(&mut self) {
self.controller.write(0xAD);
self.controller.write(0xA7);
self.device.read();
self.controller.write(0x20);
let mut config_byte: u8 = self.wait_then_read();
config_byte &= !(1 << 0);
config_byte &= !(1 << 1);
self.controller.write(0x60);
self.wait_then_write(config_byte);
self.controller.write(0xAA);
assert!(self.wait_then_read() == 0x55, "PS/2 self test failed");
self.controller.write(0xAB);
assert!(self.wait_then_read() == 0x0, "Interface tests failed",);
self.controller.write(0xAE);
self.controller.write(0x20);
let mut enable: u8 = self.wait_then_read();
enable |= 1 << 0;
self.controller.write(0x60);
self.wait_then_write(enable);
self.device.read();
println!("[ OK ] PS/2 driver.");
}
pub fn read_char(&mut self) -> u8 {
self.device.read()
}
}
pub static PS2: Mutex<Ps2> = Mutex::new(unsafe { Ps2::new(0x64, 0x60) });
pub fn read_char() -> u8 {
PS2.lock().read_char()
}