wooooo i spy with my little eye an emulated HID keyboard

This commit is contained in:
bunnie 2022-05-16 13:15:21 +08:00
parent 2b57fa559d
commit ffbfa1dc3f
2 changed files with 94 additions and 21 deletions

View file

@ -530,7 +530,7 @@ impl SpinalUsbDevice {
PollResult::Data {ep_out, ep_in_complete, ep_setup} =>
format!("PollResult::Data out:{:x} in:{:x} setup:{:x}", ep_out, ep_in_complete, ep_setup),
};
log::info!("<<<< {}", info);
log::debug!("<<<< {}", info);
}
#[allow(dead_code)]
pub fn print_ep_stats(&self) {
@ -587,12 +587,6 @@ impl SpinalUsbDevice {
ep0_out_desc.set_next_desc_and_len(0, 0);
ep0_out_desc.set_desc_flags(UsbDirection::Out, true, true, true);
}
pub(crate) fn ep0_in_reset(&self) {
let ep0_out_desc = self.descriptor_ep0_out();
ep0_out_desc.set_offset(0);
ep0_out_desc.set_next_desc_and_len(0, 8);
ep0_out_desc.set_desc_flags(UsbDirection::In, true, true, true);
}
pub(crate) fn status_read_volatile(&self, index: usize) -> UdcEpStatus {
unsafe {
self.eps.load(Ordering::SeqCst).add(index).read_volatile()
@ -757,14 +751,14 @@ impl UsbBus for SpinalUsbDevice {
/// enumeration, as well as ensure that all endpoints previously allocated with alloc_ep are
/// initialized as specified.
fn reset(&self) {
log::info!("reset");
log::debug!("reset");
self.regs.set_address(0x0); // this does *not* require the trigger
self.address.store(0, Ordering::SeqCst);
self.ep0_out_reset();
for (index, &ep) in self.ep_allocs.iter().enumerate() {
if let Some((head_offset, max_len)) = ep {
if index == 0 {
log::info!("ep0 reset");
log::trace!("ep0 reset");
// basically rewrite the whole EP0 setup from scratch.
let mut ep0_status = self.status_read_volatile(0);
ep0_status.set_head_offset(head_offset as u32);
@ -779,7 +773,7 @@ impl UsbBus for SpinalUsbDevice {
descriptor.set_desc_flags(UsbDirection::In, true, true, true);
} else {
let mut ep_status = self.status_read_volatile(index);
log::info!("ep{} reset from {:?}", index, ep_status);
log::trace!("ep{} reset from {:?}", index, ep_status);
ep_status.set_max_packet_size(max_len as u32);
ep_status.set_head_offset(head_offset as u32);
let descriptor = self.descriptor_from_status(&ep_status);
@ -863,13 +857,12 @@ impl UsbBus for SpinalUsbDevice {
},
buf.len()
);
if ep_addr.index() == 0 {
// this is required to commit the ep_status record once all the setup is done
self.status_write_volatile(0, ep_status);
let epcheck = self.status_read_volatile(0);
log::trace!("ep0 sanity check: {:?}", epcheck);
log::trace!("desc0 sanity check: {:?}", self.descriptor_from_status(&epcheck));
}
// this is required to commit the ep_status record once all the setup is done
self.status_write_volatile(ep_addr.index(), ep_status);
let epcheck = self.status_read_volatile(ep_addr.index());
log::trace!("ep0 sanity check: {:?}", epcheck);
log::trace!("desc0 sanity check: {:?}", self.descriptor_from_status(&epcheck));
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
log::info!("ep{} write: {:x?}", ep_addr.index(), &buf);
Ok(buf.len())
@ -1034,7 +1027,7 @@ impl UsbBus for SpinalUsbDevice {
fn poll(&self) -> PollResult {
let interrupts = self.regs.interrupts();
let mut ints_to_clear = UdcInterrupts(0);
log::info!(">>>> frame {}: {:x?}", self.regs.frame_id(), interrupts);
log::debug!(">>>> frame {}: {:x?}", self.regs.frame_id(), interrupts);
let poll_result =
if interrupts.reset() {
ints_to_clear.set_reset(true);

View file

@ -198,14 +198,18 @@ fn xmain() -> ! {
}),
// this is via physical keyboard
Some(Opcode::HandlerTrigger) => {
keyboard.interface().write_report(&[Keyboard::A]).ok(); // just for testing
keyboard.interface().tick().unwrap();
let rawstates = kbd.update();
// interpret scancodes
let kc: Vec<char> = kbd.track_keys(&rawstates);
// handle keys, if any
for &key in kc.iter() {
// send it to the USB interface
let code = hid_convert(key);
keyboard.interface().write_report(&code).ok();
keyboard.interface().tick().unwrap();
keyboard.interface().write_report(&[]).ok(); // this is the key-up
keyboard.interface().tick().unwrap();
if key != '\u{000d}' {
cmdline.push(key);
} else {
@ -356,4 +360,80 @@ mod tests {
last_alloc = offset + len;
}
}
}
fn hid_convert(key: char) -> Vec<Keyboard> {
let mut code = vec![];
match key {
'a' => code.push(Keyboard::A),
'b' => code.push(Keyboard::B),
'c' => code.push(Keyboard::C),
'd' => code.push(Keyboard::D),
'e' => code.push(Keyboard::E),
'f' => code.push(Keyboard::F),
'g' => code.push(Keyboard::G),
'h' => code.push(Keyboard::H),
'i' => code.push(Keyboard::I),
'j' => code.push(Keyboard::J),
'k' => code.push(Keyboard::K),
'l' => code.push(Keyboard::L),
'm' => code.push(Keyboard::M),
'n' => code.push(Keyboard::N),
'o' => code.push(Keyboard::O),
'p' => code.push(Keyboard::P),
'q' => code.push(Keyboard::Q),
'r' => code.push(Keyboard::R),
's' => code.push(Keyboard::S),
't' => code.push(Keyboard::T),
'u' => code.push(Keyboard::U),
'v' => code.push(Keyboard::V),
'w' => code.push(Keyboard::W),
'x' => code.push(Keyboard::X),
'y' => code.push(Keyboard::Y),
'z' => code.push(Keyboard::Z),
'A' => {code.push(Keyboard::A); code.push(Keyboard::LeftShift)},
'B' => {code.push(Keyboard::B); code.push(Keyboard::LeftShift)},
'C' => {code.push(Keyboard::C); code.push(Keyboard::LeftShift)},
'D' => {code.push(Keyboard::D); code.push(Keyboard::LeftShift)},
'E' => {code.push(Keyboard::E); code.push(Keyboard::LeftShift)},
'F' => {code.push(Keyboard::F); code.push(Keyboard::LeftShift)},
'G' => {code.push(Keyboard::G); code.push(Keyboard::LeftShift)},
'H' => {code.push(Keyboard::H); code.push(Keyboard::LeftShift)},
'I' => {code.push(Keyboard::I); code.push(Keyboard::LeftShift)},
'J' => {code.push(Keyboard::J); code.push(Keyboard::LeftShift)},
'K' => {code.push(Keyboard::K); code.push(Keyboard::LeftShift)},
'L' => {code.push(Keyboard::L); code.push(Keyboard::LeftShift)},
'M' => {code.push(Keyboard::M); code.push(Keyboard::LeftShift)},
'N' => {code.push(Keyboard::N); code.push(Keyboard::LeftShift)},
'O' => {code.push(Keyboard::O); code.push(Keyboard::LeftShift)},
'P' => {code.push(Keyboard::P); code.push(Keyboard::LeftShift)},
'Q' => {code.push(Keyboard::Q); code.push(Keyboard::LeftShift)},
'R' => {code.push(Keyboard::R); code.push(Keyboard::LeftShift)},
'S' => {code.push(Keyboard::S); code.push(Keyboard::LeftShift)},
'T' => {code.push(Keyboard::T); code.push(Keyboard::LeftShift)},
'U' => {code.push(Keyboard::U); code.push(Keyboard::LeftShift)},
'V' => {code.push(Keyboard::V); code.push(Keyboard::LeftShift)},
'W' => {code.push(Keyboard::W); code.push(Keyboard::LeftShift)},
'X' => {code.push(Keyboard::X); code.push(Keyboard::LeftShift)},
'Y' => {code.push(Keyboard::Y); code.push(Keyboard::LeftShift)},
'Z' => {code.push(Keyboard::Z); code.push(Keyboard::LeftShift)},
'0' => code.push(Keyboard::Keyboard0),
'1' => code.push(Keyboard::Keyboard1),
'2' => code.push(Keyboard::Keyboard2),
'3' => code.push(Keyboard::Keyboard3),
'4' => code.push(Keyboard::Keyboard4),
'5' => code.push(Keyboard::Keyboard5),
'6' => code.push(Keyboard::Keyboard6),
'7' => code.push(Keyboard::Keyboard7),
'8' => code.push(Keyboard::Keyboard8),
'9' => code.push(Keyboard::Keyboard9),
'\u{000d}' => code.push(Keyboard::ReturnEnter),
' ' => code.push(Keyboard::Space),
'\u{0008}' => code.push(Keyboard::DeleteBackspace),
_ => log::info!("Unhandled character: {}", key),
};
code
}