Browse Source

Tidy up the ir:USER code/example and fix a bug in the service code

pull/129/head
AzureMarker 2 years ago committed by Mark Drobnak
parent
commit
39b6bc92b5
No known key found for this signature in database
GPG Key ID: 47A133F3BF9D03D3
  1. 64
      ctru-rs/examples/ir-user.rs
  2. 24
      ctru-rs/src/services/ir_user.rs

64
ctru-rs/examples/ir-user.rs

@ -15,9 +15,12 @@ fn main() {
let apt = Apt::init().unwrap(); let apt = Apt::init().unwrap();
let hid = Hid::init().unwrap(); let hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap(); let gfx = Gfx::init().unwrap();
let bottom_console = Console::init(gfx.bottom_screen.borrow_mut());
let top_console = Console::init(gfx.top_screen.borrow_mut()); let top_console = Console::init(gfx.top_screen.borrow_mut());
let bottom_console = Console::init(gfx.bottom_screen.borrow_mut());
println!("Welcome to the ir:USER / Circle Pad Pro Demo");
println!("Starting up ir:USER service");
let ir_user = IrUser::init( let ir_user = IrUser::init(
PACKET_BUFFER_SIZE, PACKET_BUFFER_SIZE,
PACKET_COUNT, PACKET_COUNT,
@ -25,12 +28,13 @@ fn main() {
PACKET_COUNT, PACKET_COUNT,
) )
.expect("Couldn't initialize ir:USER service"); .expect("Couldn't initialize ir:USER service");
println!("ir:USER service initialized\nPress A to connect to the CPP");
let print_status_info = || { let print_status_info = || {
bottom_console.select();
bottom_console.clear();
println!("{:#x?}", ir_user.get_status_info());
top_console.select(); top_console.select();
top_console.clear();
println!("{:#x?}", ir_user.get_status_info());
bottom_console.select();
}; };
let conn_status_event = ir_user let conn_status_event = ir_user
@ -56,6 +60,8 @@ fn main() {
} }
if hid.keys_down().contains(KeyPad::KEY_A) && !is_connected { if hid.keys_down().contains(KeyPad::KEY_A) && !is_connected {
println!("Attempting to connect to the CPP");
// Connection loop // Connection loop
loop { loop {
hid.scan_input(); hid.scan_input();
@ -114,7 +120,7 @@ fn main() {
print_status_info(); print_status_info();
if recv_event_result.is_ok() { if recv_event_result.is_ok() {
println!("Got packet from CPP"); println!("Got first packet from CPP");
handle_packet(&ir_user, &top_console, &bottom_console); handle_packet(&ir_user, &top_console, &bottom_console);
break; break;
} }
@ -136,44 +142,29 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
writeln!(&mut output_buffer, "{:x?}", ir_user.get_status_info()).unwrap(); writeln!(&mut output_buffer, "{:x?}", ir_user.get_status_info()).unwrap();
ir_user.process_shared_memory(|ir_mem| { ir_user.process_shared_memory(|ir_mem| {
writeln!(&mut output_buffer, "ReceiveBufferInfo:").unwrap(); writeln!(&mut output_buffer, "\nReceiveBufferInfo:").unwrap();
let mut counter = 0; write_buffer_as_hex(&ir_mem[0x10..0x20], &mut output_buffer);
for byte in &ir_mem[0x10..0x20] {
write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1;
if counter % 12 == 0 {
writeln!(&mut output_buffer).unwrap();
}
}
writeln!(&mut output_buffer, "\nReceiveBuffer:").unwrap(); writeln!(&mut output_buffer, "\nReceiveBuffer:").unwrap();
counter = 0; write_buffer_as_hex(&ir_mem[0x20..0x20 + PACKET_BUFFER_SIZE], &mut output_buffer);
for byte in &ir_mem[0x20..0x20 + PACKET_BUFFER_SIZE] {
write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1;
if counter % 12 == 0 {
writeln!(&mut output_buffer).unwrap();
}
}
writeln!(&mut output_buffer).unwrap(); writeln!(&mut output_buffer).unwrap();
}); });
let mut packets = ir_user.get_packets(); let packets = ir_user.get_packets();
let packet_count = packets.len(); let packet_count = packets.len();
writeln!(&mut output_buffer, "Packet count: {packet_count}").unwrap(); writeln!(&mut output_buffer, "\nPacket count: {packet_count}").unwrap();
let last_packet = packets.pop().unwrap(); let last_packet = packets.last().unwrap();
writeln!(&mut output_buffer, "{last_packet:02x?}").unwrap(); writeln!(&mut output_buffer, "{last_packet:02x?}").unwrap();
let cpp_response = CirclePadProInputResponse::try_from(last_packet) let cpp_response = CirclePadProInputResponse::try_from(last_packet)
.expect("Failed to parse CPP response from IR packet"); .expect("Failed to parse CPP response from IR packet");
writeln!(&mut output_buffer, "{cpp_response:#02x?}").unwrap(); writeln!(&mut output_buffer, "\n{cpp_response:#02x?}").unwrap();
// Write output to bottom screen // Write output to top screen
bottom_console.select();
bottom_console.clear();
std::io::stdout().write_all(&output_buffer).unwrap();
top_console.select(); top_console.select();
top_console.clear();
std::io::stdout().write_all(&output_buffer).unwrap();
bottom_console.select();
// Done handling the packet, release it // Done handling the packet, release it
ir_user ir_user
@ -185,3 +176,14 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
println!("Error: {e:?}"); println!("Error: {e:?}");
} }
} }
fn write_buffer_as_hex(buffer: &[u8], output: &mut Vec<u8>) {
let mut counter = 0;
for byte in buffer {
write!(output, "{byte:02x} ").unwrap();
counter += 1;
if counter % 16 == 0 {
writeln!(output).unwrap();
}
}
}

24
ctru-rs/src/services/ir_user.rs

@ -11,7 +11,6 @@ use std::time::Duration;
static IR_USER_ACTIVE: Mutex<usize> = Mutex::new(0); static IR_USER_ACTIVE: Mutex<usize> = Mutex::new(0);
static IR_USER_STATE: Mutex<Option<IrUserState>> = Mutex::new(None); static IR_USER_STATE: Mutex<Option<IrUserState>> = Mutex::new(None);
#[non_exhaustive]
pub struct IrUser { pub struct IrUser {
_service_reference: ServiceReference, _service_reference: ServiceReference,
} }
@ -264,9 +263,10 @@ impl IrUser {
let packet_info_section_size = user_state.recv_packet_count * 8; let packet_info_section_size = user_state.recv_packet_count * 8;
let packet_data = |idx| -> u8 { let packet_data = |idx| -> u8 {
let offset = 0x20 + packet_info_section_size + (offset_to_data_buffer + idx); let header_size = 0x20 + packet_info_section_size;
let data_buffer_size = (user_state.recv_buffer_size - packet_info_section_size); let data_buffer_offset = offset_to_data_buffer + idx;
shared_mem[offset % data_buffer_size] let data_buffer_size = user_state.recv_buffer_size - packet_info_section_size;
shared_mem[header_size + data_buffer_offset % data_buffer_size]
}; };
let (payload_length, payload_offset) = if packet_data(2) & 0x40 != 0 { let (payload_length, payload_offset) = if packet_data(2) & 0x40 != 0 {
@ -282,6 +282,9 @@ impl IrUser {
assert_eq!(data_length, payload_offset + payload_length + 1); assert_eq!(data_length, payload_offset + payload_length + 1);
let magic_number = packet_data(0);
assert_eq!(magic_number, 0xA5);
IrUserPacket { IrUserPacket {
magic_number: packet_data(0), magic_number: packet_data(0),
destination_network_id: packet_data(1), destination_network_id: packet_data(1),
@ -400,7 +403,6 @@ pub struct IrUserPacket {
#[derive(Debug)] #[derive(Debug)]
pub struct CirclePadProInputResponse { pub struct CirclePadProInputResponse {
pub response_id: u8,
pub c_stick_x: u16, pub c_stick_x: u16,
pub c_stick_y: u16, pub c_stick_y: u16,
pub battery_level: u8, pub battery_level: u8,
@ -410,10 +412,10 @@ pub struct CirclePadProInputResponse {
pub unknown_field: u8, pub unknown_field: u8,
} }
impl TryFrom<IrUserPacket> for CirclePadProInputResponse { impl TryFrom<&IrUserPacket> for CirclePadProInputResponse {
type Error = String; type Error = String;
fn try_from(packet: IrUserPacket) -> Result<Self, Self::Error> { fn try_from(packet: &IrUserPacket) -> Result<Self, Self::Error> {
if packet.payload.len() != 6 { if packet.payload.len() != 6 {
return Err(format!( return Err(format!(
"Invalid payload length (expected 6 bytes, got {})", "Invalid payload length (expected 6 bytes, got {})",
@ -422,6 +424,13 @@ impl TryFrom<IrUserPacket> for CirclePadProInputResponse {
} }
let response_id = packet.payload[0]; let response_id = packet.payload[0];
if response_id != 0x10 {
return Err(format!(
"Invalid response ID (expected 0x10, got {:#x}",
packet.payload[0]
));
}
let c_stick_x = packet.payload[1] as u16 + (((packet.payload[2] & 0x0F) as u16) << 8); let c_stick_x = packet.payload[1] as u16 + (((packet.payload[2] & 0x0F) as u16) << 8);
let c_stick_y = let c_stick_y =
(((packet.payload[2] & 0xF0) as u16) >> 4) + ((packet.payload[3] as u16) << 4); (((packet.payload[2] & 0xF0) as u16) >> 4) + ((packet.payload[3] as u16) << 4);
@ -432,7 +441,6 @@ impl TryFrom<IrUserPacket> for CirclePadProInputResponse {
let unknown_field = packet.payload[5]; let unknown_field = packet.payload[5];
Ok(CirclePadProInputResponse { Ok(CirclePadProInputResponse {
response_id,
c_stick_x, c_stick_x,
c_stick_y, c_stick_y,
battery_level, battery_level,

Loading…
Cancel
Save