pyreworks_g560_driver/
raw.rs1use nusb::Interface;
2use nusb::transfer::{ControlOut, ControlType, Recipient};
3use thiserror::Error;
4
5pub const VENDOR_ID: u16 = 0x046d;
6pub const PRODUCT_ID: u16 = 0x0a78;
7
8pub fn detach_and_claim_interface() -> Result<Interface, ClaimInterfaceError> {
9 let device = nusb::list_devices()?
10 .find(|dev| dev.vendor_id() == VENDOR_ID && dev.product_id() == PRODUCT_ID)
11 .ok_or(ClaimInterfaceError::InterfaceNotFound)?
12 .open()?;
13
14 Ok(device.detach_and_claim_interface(0x02)?)
15}
16
17#[derive(Error, Debug)]
18pub enum ClaimInterfaceError {
19 #[error("could not find \"g560\" device with vendor_id {0} and product_id {1}", VENDOR_ID, PRODUCT_ID)]
20 InterfaceNotFound,
21 #[error("could not open \"g560\" device")]
22 InterfaceClaimFailed(#[from] nusb::Error),
23}
24
25pub async fn send_raw_command(
26 interface: &Interface,
27 value: &[u8; 10]
28)
29-> Result<(), SendCommandError>
30{
31 let prefix = [0x11, 0xff, 0x04, 0x3a];
32 let suffix = [0x00; 6];
33
34 let mut data = Vec::with_capacity(20);
35 data.extend_from_slice(&prefix);
36 data.extend_from_slice(value);
37 data.extend_from_slice(&suffix);
38
39 let control_out = ControlOut {
40 recipient: Recipient::Interface,
41 control_type: ControlType::Class,
42 request: 0x09,
43 value: 0x0211,
44 index: 0x02,
45 data: &data,
46 };
47
48 interface.control_out(control_out).await.into_result()?;
49
50 Ok(())
51}
52
53#[derive(Error, Debug)]
54pub enum SendCommandError {
55 #[error("control out failed")]
56 ControlOutFailed(#[from] nusb::transfer::TransferError),
57}