Skip to content

Commit

Permalink
usage_page and usage arguments (#35)
Browse files Browse the repository at this point in the history
Customizable `usage` and `usage_page` selectors, addressing the need
found in
#29 (comment)
  • Loading branch information
carlossless committed Dec 23, 2023
1 parent 7f7c8f1 commit 4fa1b4a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 73 deletions.
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ sinowealth-kb-tool read -p nuphy-air60 --full full.hex

# custom device
sinowealth-kb-tool read \
--firmware_size 61440 \
--bootloader_size 4096 \
--page_size 2048 \
--vendor_id 0x05ac \
--product_id 0x024f \
--isp_index 0
--firmware_size 61440 \
--bootloader_size 4096 \ # optional
--page_size 2048 \ # optional
--isp_usage_page 0x00ff \ # optional
--isp_usage 0x0001 \ # optional
--isp_index 0 \ # optional
foobar.hex
```

Expand All @@ -47,12 +49,14 @@ sinowealth-kb-tool write -p nuphy-air60 foobar.hex

# custom device
sinowealth-kb-tool write \
--firmware_size 61440 \
--bootloader_size 4096 \
--page_size 2048 \
--vendor_id 0x05ac \
--product_id 0x024f \
--isp_index 0
--firmware_size 61440 \
--bootloader_size 4096 \ # optional
--page_size 2048 \ # optional
--isp_usage_page 0x00ff \ # optional
--isp_usage 0x0001 \ # optional
--isp_index 0 \ # optional
foobar.hex
```

Expand Down
4 changes: 2 additions & 2 deletions src/isp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ impl ISPDevice {
#[cfg(not(target_os = "linux"))]
return d.vendor_id() == part.vendor_id
&& d.product_id() == part.product_id
&& d.usage_page() == HID_ISP_USAGE_PAGE
&& d.usage() == HID_ISP_USAGE;
&& d.usage_page() == part.isp_usage_page
&& d.usage() == part.isp_usage;
#[cfg(target_os = "linux")]
return d.vendor_id() == part.vendor_id && d.product_id() == part.product_id;
})
Expand Down
47 changes: 19 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,30 +134,13 @@ impl PartCommand for Command {
self.arg(
arg!(-p --part <PART>)
.value_parser(Part::available_parts())
.required_unless_present_all([
"firmware_size",
"bootloader_size",
"page_size",
"vendor_id",
"product_id",
"isp_index",
]),
.required_unless_present_all(["firmware_size", "vendor_id", "product_id"]),
)
.arg(
arg!(--firmware_size <SIZE>)
.required_unless_present("part")
.value_parser(clap::value_parser!(usize)),
)
.arg(
arg!(--bootloader_size <SIZE>)
.required_unless_present("part")
.value_parser(clap::value_parser!(usize)),
)
.arg(
arg!(--page_size <SIZE>)
.required_unless_present("part")
.value_parser(clap::value_parser!(usize)),
)
.arg(
arg!(--vendor_id <VID>)
.required_unless_present("part")
Expand All @@ -168,11 +151,11 @@ impl PartCommand for Command {
.required_unless_present("part")
.value_parser(maybe_hex::<u16>),
)
.arg(
arg!(--isp_index <PID>)
.required_unless_present("part")
.value_parser(clap::value_parser!(usize)),
)
.arg(arg!(--bootloader_size <SIZE>).value_parser(clap::value_parser!(usize)))
.arg(arg!(--page_size <SIZE>).value_parser(clap::value_parser!(usize)))
.arg(arg!(--isp_usage_page <PID>).value_parser(maybe_hex::<u16>))
.arg(arg!(--isp_usage <PID>).value_parser(maybe_hex::<u16>))
.arg(arg!(--isp_index <PID>).value_parser(clap::value_parser!(usize)))
}
}

Expand All @@ -181,30 +164,38 @@ fn get_part_from_matches(sub_matches: &ArgMatches) -> Part {

let mut part = match part_name {
Some(part_name) => *PARTS.get(part_name).unwrap(),
_ => Part::default(),
_ => PART_BASE_DEFAULT,
};

let firmware_size = sub_matches.get_one::<usize>("firmware_size");
let bootloader_size = sub_matches.get_one::<usize>("bootloader_size");
let page_size = sub_matches.get_one::<usize>("page_size");
let vendor_id = sub_matches.get_one::<u16>("vendor_id");
let product_id = sub_matches.get_one::<u16>("product_id");
let isp_usage_page = sub_matches.get_one::<u16>("isp_usage_page");
let isp_usage = sub_matches.get_one::<u16>("isp_usage");
let isp_index = sub_matches.get_one::<usize>("isp_index");

if let Some(firmware_size) = firmware_size {
part.firmware_size = *firmware_size;
}
if let Some(vendor_id) = vendor_id {
part.vendor_id = *vendor_id;
}
if let Some(product_id) = product_id {
part.product_id = *product_id;
}
if let Some(bootloader_size) = bootloader_size {
part.bootloader_size = *bootloader_size;
}
if let Some(page_size) = page_size {
part.page_size = *page_size;
}
if let Some(vendor_id) = vendor_id {
part.vendor_id = *vendor_id;
if let Some(isp_usage_page) = isp_usage_page {
part.isp_usage_page = *isp_usage_page;
}
if let Some(product_id) = product_id {
part.product_id = *product_id;
if let Some(isp_usage) = isp_usage {
part.isp_usage = *isp_usage;
}
if let Some(isp_index) = isp_index {
part.isp_index = *isp_index;
Expand Down
73 changes: 40 additions & 33 deletions src/part.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,103 @@
use phf::{phf_map, Map};

#[derive(Default, Clone, Copy)]
#[derive(Clone, Copy)]
pub struct Part {
pub firmware_size: usize,
pub bootloader_size: usize,
pub page_size: usize,
pub vendor_id: u16,
pub product_id: u16,
/// Index of usage_page == 0xff00 && usage == 0x0001 collections at which the isp report appears in.
/// Important only for windows because its HIDAPI requires us to use a specific device for each collection

// The following properties and values are important only for windows support because its
// HIDAPI requires us to use a specific device for each collection
/// HID collection `usage_page` with the ISP report
pub isp_usage_page: u16,
/// HID collection `usage` with the ISP report
pub isp_usage: u16,
/// Index of matching (usage_page && usage) collection at which the ISP report appears in.
pub isp_index: usize,
}

pub const PART_NUPHY_AIR60: Part = Part {
firmware_size: 61440, // 61440 until bootloader
pub const PART_BASE_DEFAULT: Part = Part {
firmware_size: 0,
bootloader_size: 4096,
page_size: 2048,

vendor_id: 0x0000,
product_id: 0x0000,

isp_usage_page: 0xff00,
isp_usage: 0x0001,
isp_index: 0,
};

pub const PART_BASE_SH68F90: Part = Part {
firmware_size: 61440, // 61440 until bootloader
..PART_BASE_DEFAULT
};

pub const PART_BASE_SH68F881: Part = Part {
firmware_size: 28672, // 28672 until bootloader
..PART_BASE_DEFAULT
};

pub const PART_NUPHY_AIR60: Part = Part {
vendor_id: 0x05ac,
product_id: 0x024f,
isp_index: 1,
..PART_BASE_SH68F90
};

pub const PART_XINMENG_K916: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x00a1,
isp_index: 1,
..PART_BASE_SH68F90
};

pub const PART_RE_K70_BYK800: Part = Part {
firmware_size: 28672, // 28672 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x001a,
isp_index: 0,
..PART_BASE_SH68F881
};

pub const PART_TERPORT_TR95: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x0049,
isp_index: 1,
..PART_BASE_SH68F90
};

pub const PART_REDRAGON_FIZZ_K617: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x0049,
isp_index: 1,
..PART_BASE_SH68F90
};

pub const PART_REDRAGON_ANIVIA_K614: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x0049,
isp_index: 1,
..PART_BASE_SH68F90
};

pub const PART_GENESIS_THOR_300: Part = Part {
firmware_size: 28672, // 28672 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x001f,
isp_index: 0,
..PART_BASE_SH68F881
};

pub const PART_GENESIS_THOR_300_RGB: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x0090,
isp_index: 0,
..PART_BASE_SH68F90
};

pub const PART_ROYALKLUDGE_RK100: Part = Part {
firmware_size: 61440, // 61440 until bootloader
bootloader_size: 4096,
page_size: 2048,
vendor_id: 0x258a,
product_id: 0x0056,
isp_index: 0,
..PART_BASE_SH68F90
};

pub static PARTS: Map<&'static str, Part> = phf_map! {
Expand Down
34 changes: 32 additions & 2 deletions tools/functional-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ FILE_FULL="$FILE_PREFIX-read-full.hex"
FILE_CUSTOM="$FILE_PREFIX-read-custom.hex"
FILE_OVERRIDE="$FILE_PREFIX-read-override.hex"
FILE_POST_WRITE="$FILE_PREFIX-post-write.hex"
FILE_POST_WRITE_CUSTOM="$FILE_PREFIX-post-write-custom.hex"

function reboot_device () {
echo "Turning off port..."
Expand Down Expand Up @@ -58,10 +59,12 @@ reboot_device
echo "Custom read..."
$TOOL read \
--firmware_size 61440 \
--bootloader_size 4096 \
--page_size 2048 \
--vendor_id 0x05ac \
--product_id 0x024f \
--bootloader_size 4096 \
--page_size 2048 \
--isp_usage_page 0x00ff \
--isp_usage 0x0001 \
--isp_index 1 \
"$FILE_CUSTOM"

Expand Down Expand Up @@ -126,4 +129,31 @@ fi

reboot_device

echo "Custom write..."
$TOOL write \
--firmware_size 61440 \
--vendor_id 0x05ac \
--product_id 0x024f \
--bootloader_size 4096 \
--page_size 2048 \
--isp_usage_page 0x00ff \
--isp_usage 0x0001 \
--isp_index 1 \
"$FILE_DEFAULT"

reboot_device

echo "Post-write read..."
$TOOL read --part "$PART" "$FILE_POST_WRITE_CUSTOM"

READ_POST_WRITE_CUSTOM_MD5=$(get_md5_from_hex "$FILE_POST_WRITE_CUSTOM")

echo "Checking post-write checksum"
if [[ "$READ_POST_WRITE_CUSTOM_MD5" != "$READ_MD5" ]]; then
echo "MD5 mismatch $READ_POST_WRITE_CUSTOM_MD5 != $READ_MD5"
exit 1
fi

reboot_device

echo "Passed all tests!"

0 comments on commit 4fa1b4a

Please sign in to comment.