diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dd2cd7..9e47950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,14 +10,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `--speed` option to specify protocol speed +- Add `erase --method power-off` option to support erase with power off +- Add a simple chip ID db, now wlink can identify chip type automatically ### Fixed - Regression in `flash` command +- Use chip type from the protocol, close #25 +- Support 2.10 (aka. v30) firmware, close #27 ### Changed - Allow underscore `_` in number literals in command line +- Refine protocol naming +- Add a simple DMI algorithm skeleton ## [0.0.5] - 2023-07-31 diff --git a/README.md b/README.md index 61cf46c..4174257 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ Current firmware version: 2.9 - [CH592]/CH591 - [ ] [CH643] - I don't have this chip, help wanted - [CH32X035] +- [ ] [CH32L103] - I don't have this chip, help wanted +- [ ] [CH8571] - No other source about this chip, help wanted - ... (Feel free to open an issue if you have tested on other chips) [CH32V003]: http://www.wch-ic.com/products/CH32V003.html @@ -58,11 +60,13 @@ Current firmware version: 2.9 [CH32V208]: http://www.wch-ic.com/products/CH32V208.html [CH32V307]: http://www.wch-ic.com/products/CH32V307.html [CH32X035]: http://www.wch-ic.com/products/CH32X035.html +[CH32L103]: http://www.wch-ic.com/products/CH32L103.html [CH569]: http://www.wch-ic.com/products/CH569.html [CH573]: http://www.wch-ic.com/products/CH573.html [CH583]: http://www.wch-ic.com/products/CH583.html [CH592]: https://www.wch-ic.com/products/CH592.html [CH643]: https://www.wch-ic.com/products/CH643.html +[CH8571]: https://www.wch.cn/news/606.html ## Install diff --git a/docs/CH32L103.md b/docs/CH32L103.md new file mode 100644 index 0000000..0527df4 --- /dev/null +++ b/docs/CH32L103.md @@ -0,0 +1,14 @@ +# CH32L103 + + +## Chips + +``` + * CH32L103C8U6-0x103007x0 + * CH32L103C8T6-0x103107x0 + * CH32L103F8P6-0x103A07x0 + * CH32L103G8R6-0x103B07x0 + * CH32L103K8U6-0x103207x0 + * CH32L103F8U6-0x103D07x0 + * CH32L103F7P6-0x103707x0 + ``` diff --git a/docs/CH32V003.md b/docs/CH32V003.md index 44bb8ba..94dc2f1 100644 --- a/docs/CH32V003.md +++ b/docs/CH32V003.md @@ -33,3 +33,12 @@ GND <-> GND@MCU 13:41:51 [INFO] resume executing... 13:41:51 [WARN] resume fails ``` + +## Chips + +``` + * CH32V003F4P6-0x003005x0 + * CH32V003F4U6-0x003105x0 + * CH32V003A4M6-0x003205x0 + * CH32V003J4M6-0x003305x0 +``` diff --git a/docs/CH32V103.md b/docs/CH32V103.md index 930b684..d42237a 100644 --- a/docs/CH32V103.md +++ b/docs/CH32V103.md @@ -8,3 +8,10 @@ SWCLK - PA14 @ MCU ## USBISP BOOT0 to VCC + +## Chips + +``` + * CH32F103C8T6-0x20004102 + * CH32F103R8T6-0x2000410F +``` diff --git a/docs/CH32V20x.md b/docs/CH32V20x.md index 0eafcc4..7a0575b 100644 --- a/docs/CH32V20x.md +++ b/docs/CH32V20x.md @@ -10,3 +10,27 @@ [nanoCH32V203]: https://github.com/wuxx/nanoCH32V203 [FlappyBoard]: https://github.com/metro94/FlappyBoard + +## Notes + +- Erased bytes `39 e3 39 e3` + +## Chips + +``` + * CH32V203C8U6-0x203005x0 + * CH32V203C8T6-0x203105x0 + * CH32V203K8T6-0x203205x0 + * CH32V203C6T6-0x203305x0 + * CH32V203K6T6-0x203505x0 + * CH32V203G6U6-0x203605x0 + * CH32V203G8R6-0x203B05x0 + * CH32V203F8U6-0x203E05x0 + * CH32V203F6P6-0x203705x0-0x203905x0 + * CH32V203F8P6-0x203A05x0 + * CH32V203RBT6-0x203405xC + * CH32V208WBU6-0x208005xC + * CH32V208RBT6-0x208105xC + * CH32V208CBU6-0x208205xC + * CH32V208GBU6-0x208305xC + ``` diff --git a/docs/CH32V307.md b/docs/CH32V307.md index ff44ef5..2154901 100644 --- a/docs/CH32V307.md +++ b/docs/CH32V307.md @@ -12,3 +12,23 @@ wlink -v dump 0x08000000 0x10` 14:40:22 [INFO] Read memory from 0x08000000 to 0x08000010 08000000: b7 00 00 08 67 80 80 00 73 50 40 30 73 50 40 34 ×00•g××0sP@0sP@4 ``` + +## Notes + +- erased flash `39 e3 39 e3` + +## Chips + +``` + * CH32V303CBT6-0x303305x4 + * CH32V303RBT6-0x303205x4 + * CH32V303RCT6-0x303105x4 + * CH32V303VCT6-0x303005x4 + * CH32V305FBP6-0x305205x8 + * CH32V305RBT6-0x305005x8 + * CH32V305GBU6-0x305B05x8 + * CH32V307WCU6-0x307305x8 + * CH32V307FBP6-0x307205x8 + * CH32V307RCT6-0x307105x8 + * CH32V307VCT6-0x307005x8 +``` diff --git a/docs/CH32X035.md b/docs/CH32X035.md index b0c40af..529a521 100644 --- a/docs/CH32X035.md +++ b/docs/CH32X035.md @@ -4,3 +4,25 @@ SWDIO - PC18/DIO @ MCU SWCLK - PC19/DCK @ MCU PC17 to High, enable USB ISP DOWNLOAD MODE + +## Boards + +Official CH32X035EVT + +- CH32X035F8U6-R0 +- CH32X035G8U6-R0 +- CH32X035C8T6-R0 + +LED1, LED2 blue LED, active low, open, connected to open jumper + +## Chips + +``` + * CH32X035R8T6-0x035006x1 + * CH32X035C8T6-0x035106x1 + * CH32X035F8U6-0x035E06x1 + * CH32X035G8U6-0x035606x1 + * CH32X035G8R6-0x035B06x1 + * CH32X035F7P6-0x035706x1 + * CH32X033F8P6-0x035A06x1 +``` diff --git a/docs/CH56X.md b/docs/CH56X.md new file mode 100644 index 0000000..4c36056 --- /dev/null +++ b/docs/CH56X.md @@ -0,0 +1,10 @@ +# CH569 + +## Boards + +- CH569W-R0-1v0 + +## Pins + +- TCK=HTACK=PA10 +- TIO=HTCLK=PA11 diff --git a/docs/CH57x_CH58x_CH59x.md b/docs/CH57x_CH58x_CH59x.md index afb7864..ac46544 100644 --- a/docs/CH57x_CH58x_CH59x.md +++ b/docs/CH57x_CH58x_CH59x.md @@ -4,3 +4,9 @@ - PB15 TCK - PB14 TIO + +## Notes + +- Enable debug using WCHISPTool +- After debug enabled, flash should be prgrammed at lease once +- `a9 bd f9 f3` means erased flash or protected flash, the detailed mechanism is unknown diff --git a/docs/CH643.md b/docs/CH643.md new file mode 100644 index 0000000..f7d8130 --- /dev/null +++ b/docs/CH643.md @@ -0,0 +1,10 @@ +# CH643 + +## Chips + +``` +* CH643W-0x64300601 +* CH643Q-0x64310601 +* CH643L-0x64330601 +* CH643U-0x64340601 +``` diff --git a/src/chips.rs b/src/chips.rs new file mode 100644 index 0000000..ed5b3f0 --- /dev/null +++ b/src/chips.rs @@ -0,0 +1,90 @@ +//! The chip DB. + +pub fn chip_id_to_chip_name(chip_id: u32) -> Option<&'static str> { + match chip_id & 0xFFF00000 { + 0x650_00000 => Some("CH565"), + 0x690_00000 => Some("CH569"), + 0x710_00000 => Some("CH571"), + 0x730_00000 => Some("CH573"), + 0x810_00000 => Some("CH581"), + 0x820_00000 => Some("CH582"), + 0x830_00000 => Some("CH583"), + 0x920_00000 => Some("CH592"), + 0x003_00000 => match chip_id & 0xFFFFFF0F { + 0x003_00500 => Some("CH32V003F4P6"), + 0x003_10500 => Some("CH32V003F4U6"), + 0x003_20500 => Some("CH32V003A4M6"), + 0x003_30500 => Some("CH32V003J4M6"), + _ => None, + }, + 0x035_00000 => match chip_id & 0xFFFFFF0F { + 0x035_00601 => Some("CH32X035R8T6"), + 0x035_10601 => Some("CH32X035C8T6"), + 0x035_E0601 => Some("CH32X035F8U6"), + 0x035_60601 => Some("CH32X035G8U6"), + 0x035_B0601 => Some("CH32X035G8R6"), + 0x035_70601 => Some("CH32X035F7P6"), + 0x035_A0601 => Some("CH32X033F8P6"), + _ => None, + }, + 0x103_00000 => match chip_id & 0xFFFFFF0F { + 0x103_00700 => Some("CH32L103C8U6"), + 0x103_10700 => Some("CH32L103C8T6"), + 0x103_A0700 => Some("CH32L103F8P6"), + 0x103_B0700 => Some("CH32L103G8R6"), + 0x103_20700 => Some("CH32L103K8U6"), + 0x103_D0700 => Some("CH32L103F8U6"), + 0x103_70700 => Some("CH32L103F7P6"), + _ => None, + }, + 0x200_00000 => match chip_id { + 0x200_04102 => Some("CH32F103C8T6"), + 0x200_0410F => Some("CH32F103R8T6"), + _ => None, + }, + 0x203_00000 => match chip_id & 0xFFFFFF0F { + 0x203_00500 => Some("CH32V203C8U6"), + 0x203_10500 => Some("CH32V203C8T6"), + 0x203_20500 => Some("CH32V203K8T6"), + 0x203_30500 => Some("CH32V203C6T6"), + 0x203_50500 => Some("CH32V203K6T6"), + 0x203_60500 => Some("CH32V203G6U6"), + 0x203_B0500 => Some("CH32V203G8R6"), + 0x203_E0500 => Some("CH32V203F8U6"), + 0x203_70500 => Some("CH32V203F6P6"), + 0x203_90500 => Some("CH32V203F6P6"), + 0x203_A0500 => Some("CH32V203F8P6"), + 0x203_4050C => Some("CH32V203RBT6"), + _ => None, + }, + 0x208_00000 => match chip_id & 0xFFFFFF0F { + 0x208_0050C => Some("CH32V208WBU6"), + 0x208_1050C => Some("CH32V208RBT6"), + 0x208_2050C => Some("CH32V208CBU6"), + 0x208_3050C => Some("CH32V208GBU6"), + _ => None, + }, + 0x303_00000 | 0x305_00000 | 0x307_00000 => match chip_id & 0xFFFFFF0F { + 0x303_30504 => Some("CH32V303CBT6"), + 0x303_20504 => Some("CH32V303RBT6"), + 0x303_10504 => Some("CH32V303RCT6"), + 0x303_00504 => Some("CH32V303VCT6"), + 0x305_20508 => Some("CH32V305FBP6"), + 0x305_00508 => Some("CH32V305RBT6"), + 0x305_B0508 => Some("CH32V305GBU6"), + 0x307_30508 => Some("CH32V307WCU6"), + 0x307_20508 => Some("CH32V307FBP6"), + 0x307_10508 => Some("CH32V307RCT6"), + 0x307_00508 => Some("CH32V307VCT6"), + _ => None, + }, + 0x643_00000 => match chip_id { + 0x643_00601 => Some("CH643W"), + 0x643_10601 => Some("CH643Q"), + 0x643_30601 => Some("CH643L"), + 0x643_40601 => Some("CH643U"), + _ => None, + }, + _ => None, + } +} diff --git a/src/commands.rs b/src/commands.rs index 805bc68..3ccc830 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,6 +1,7 @@ //! WCH-Link commands and response types. use std::fmt; +use std::fmt::Debug; use crate::error::{Error, Result}; @@ -8,7 +9,7 @@ use crate::error::{Error, Result}; pub mod control; /// Command to call the WCH-Link -pub trait Command { +pub trait Command: Debug { type Response: Response; const COMMAND_ID: u8; fn payload(&self) -> Vec; @@ -37,8 +38,10 @@ pub trait Response { if len != resp[3..].len() { return Err(Error::InvalidPayloadLength); } - let payload = resp[3..3 + len].to_vec(); - Err(Error::Protocol(reason, payload)) + if reason == 0x55 { + return Err(Error::Protocol(reason, resp.to_vec())); + } + Err(Error::Protocol(reason, resp.to_vec())) } else if resp[0] == 0x82 { let len = resp[2] as usize; if len != resp[3..].len() { @@ -73,6 +76,8 @@ impl Response for u8 { } } +/// Generic raw command +#[derive(Debug)] pub struct RawCommand(pub Vec); impl Command for RawCommand { type Response = Vec; @@ -82,13 +87,14 @@ impl Command for RawCommand { } } -/// Set RAM address (0x08000000) -pub struct SetRamAddress { +/// Set address and offset of the firmware, 0x01. +#[derive(Debug)] +pub struct SetWriteMemoryRegion { // 0x08000000 or 0x00000000 pub start_addr: u32, pub len: u32, } -impl Command for SetRamAddress { +impl Command for SetWriteMemoryRegion { type Response = (); const COMMAND_ID: u8 = 0x01; fn payload(&self) -> Vec { @@ -99,21 +105,44 @@ impl Command for SetRamAddress { } } +/// Read a block of memory from the chip. +#[derive(Debug)] +pub struct SetReadMemoryRegion { + pub start_addr: u32, + pub len: u32, +} +impl Command for SetReadMemoryRegion { + type Response = (); + const COMMAND_ID: u8 = 0x03; + fn payload(&self) -> Vec { + let mut bytes = Vec::with_capacity(8); + bytes.extend_from_slice(&self.start_addr.to_be_bytes()); + bytes.extend_from_slice(&self.len.to_be_bytes()); + bytes + } +} + +/// 0x02 subset #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Program { // wlink_erase EraseFlash = 0x01, - BeginWriteFlash = 0x02, - // after write memory - BeginWriteMemory = 0x05, + // Before write firmware bytes, choice between 0x02 and 0x04 + WriteFlash = 0x02, + // after write flash + WriteFlashAndVerify = 0x04, + /// Write Flash OP + WriteFlashOP = 0x05, // before SetRamAddress Prepare = 0x06, - - ExecMemory = 0x07, // or 0x0c for risvchip=1 + /// Unknown, maybe commit flash op written + Unknown07AfterFlashOPWritten = 0x07, // or 0x0B for riscvchip=1 + /// Unknown, maybe commit flash op written, only for riscvchip=1 + Unknown0BAfterFlashOPWritten = 0x0B, // EndProgram End = 0x08, - // after read memory - BeginReadMemory = 0x0c, + /// Read memory section + ReadMemory = 0x0c, } impl Command for Program { type Response = u8; @@ -123,50 +152,52 @@ impl Command for Program { } } -/// Read a block of memory from the chip. -pub struct ReadMemory { - pub start_addr: u32, - pub len: u32, -} -impl Command for ReadMemory { - type Response = (); - const COMMAND_ID: u8 = 0x03; - fn payload(&self) -> Vec { - let mut bytes = Vec::with_capacity(8); - bytes.extend_from_slice(&self.start_addr.to_be_bytes()); - bytes.extend_from_slice(&self.len.to_be_bytes()); - bytes - } -} - -/// (0x06, _) +/// 0x06 subset // query -> check -> set #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -pub enum FlashProtect { - Query = 0x01, // 1 for protected, 2 for unprotected - QueryV2 = 0x04, // 1 for protected, 0 for unprotected, - Protect = 0x03, - // dummy 0xf0 mask - ProtectV2 = 0xf3, // with 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - Unprotect = 0x02, - // dummy 0xf0 mask - UnprotectV2 = 0xf2, // with 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -} -impl FlashProtect { +pub enum ConfigChip { + /// 06, _, 01 + CheckReadProtect, // 1 for protected, 2 for unprotected + /// 06, _, 02 + Unprotect, + /// 06, _, 03 + Protect, + /// 06, _, 04 + CheckReadProtectEx, // 1 for protected, 0 for unprotected, + /// bf, or e7 + UnprotectEx(u8), // with 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + // prefix byte 0xe7 ? for ch32x035 + ProtectEx(u8), // with 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /// Config flags + /// 81 06 08 02 3f 00 00 ff ff ff ff + /// __ __ __ __ __ [DATA] [WRP ] + Config { + /// User data + data: u16, + /// WRP write protection + wrp: u32, + }, +} +impl ConfigChip { pub const FLAG_PROTECTED: u8 = 0x01; } -impl Command for FlashProtect { +impl Command for ConfigChip { type Response = u8; const COMMAND_ID: u8 = 0x06; fn payload(&self) -> Vec { match *self { - FlashProtect::ProtectV2 => vec![0x03, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - FlashProtect::UnprotectV2 => vec![0x02, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - _ => vec![*self as u8], + ConfigChip::CheckReadProtect => vec![0x01], + ConfigChip::Unprotect => vec![0x02], + ConfigChip::Protect => vec![0x03], + ConfigChip::CheckReadProtectEx => vec![0x04], + ConfigChip::UnprotectEx(b) => vec![0x02, b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + ConfigChip::ProtectEx(b) => vec![0x03, b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + ConfigChip::Config { data: _, wrp: _ } => todo!("ConfigChip"), } } } +#[derive(Debug)] pub struct SetFlashProtected { pub protected: bool, } @@ -185,13 +216,13 @@ impl Command for SetFlashProtected { /// Get Chip UID, the UID is also avaliable in the `wchisp` command. // ??? 0x11, 0x01, _ (riscvchip) #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -pub enum QueryChipInfo { +pub enum GetChipInfo { V1 = 0x09, // spot on WCH-LinkUtility v1.70 V2 = 0x06, } -impl Command for QueryChipInfo { - type Response = ChipId; +impl Command for GetChipInfo { + type Response = ChipUID; const COMMAND_ID: u8 = 0x11; fn payload(&self) -> Vec { vec![*self as u8] @@ -203,8 +234,8 @@ impl Command for QueryChipInfo { // UID in wchisp: cd-ab-b4-ae-45-bc-c6-16 // e339e339e339e339 => inital value of erased flash /// Chip UID, also reported by wchisp -pub struct ChipId(pub [u8; 8]); -impl Response for ChipId { +pub struct ChipUID(pub [u8; 8]); +impl Response for ChipUID { fn from_raw(resp: &[u8]) -> Result { if resp.len() <= 12 { return Err(Error::InvalidPayloadLength); @@ -227,7 +258,7 @@ impl Response for ChipId { unreachable!("ChipId is not be parsed from payload; qed") } } -impl fmt::Display for ChipId { +impl fmt::Display for ChipUID { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str( &self @@ -239,16 +270,17 @@ impl fmt::Display for ChipId { ) } } -impl fmt::Debug for ChipId { +impl fmt::Debug for ChipUID { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&format!("ChipId({:02x?})", &self.0[..])) } } /// Device reset (0x0b, _) +#[derive(Debug)] pub enum Reset { /// wlink_quitreset - Quit, + ResetAndRun, // the most common reset Normal, Normal2, } @@ -257,7 +289,7 @@ impl Command for Reset { const COMMAND_ID: u8 = 0x0b; fn payload(&self) -> Vec { match self { - Reset::Quit => vec![0x01], + Reset::ResetAndRun => vec![0x01], Reset::Normal => vec![0x03], Reset::Normal2 => vec![0x02], } @@ -267,32 +299,32 @@ impl Command for Reset { /// Speed settings #[derive(Debug, Copy, Clone, clap::ValueEnum, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum Speed { + /// 400 Low = 0x03, + /// 4000 Medium = 0x02, + /// 6000 High = 0x01, - Max = 0x00, } - impl Default for Speed { fn default() -> Self { Speed::High } } -/// (0x0c, [riscvchip, 1/2/3]) -pub struct SetTwoLineMode { +/// Set CLK Speed, 0x0C +#[derive(Debug)] +pub struct SetSpeed { pub riscvchip: u8, pub speed: Speed, } - -impl Command for SetTwoLineMode { +impl Command for SetSpeed { type Response = bool; const COMMAND_ID: u8 = 0x0c; fn payload(&self) -> Vec { vec![self.riscvchip, self.speed as u8] } } - impl Response for bool { fn from_payload(resp: &[u8]) -> Result { if resp.len() != 1 { @@ -303,6 +335,7 @@ impl Response for bool { } /// DMI operations +#[derive(Debug)] pub enum DmiOp { Nop, Read { addr: u8 }, @@ -380,6 +413,27 @@ impl Response for DmiOpResponse { } } +#[derive(Debug)] +pub struct DisableDebug; +impl Command for DisableDebug { + type Response = (); + const COMMAND_ID: u8 = 0x0e; + // 0x81, 0x0e, 0x01, 0x01 + fn payload(&self) -> Vec { + vec![0x01] + } +} + +// 81 0D 05 11 SetAccessAddress +// 81 0F 01 02 GetDeviceMode +// 81 0D 01 07 EnableQE +// 81 0D 01 06 CheckQE +// 81 FE 01 00 DisEncrypt +// 81 0D 01 0F ClearCodeFlashB +// 81 0D 02 08 xx ClearCodeFlash +// 81 11 01 0D unkown in query info, before GetChipRomRamSplit +// 81 0d 02 ee 00 stop flash ? + #[cfg(test)] mod tests { use super::*; @@ -388,7 +442,7 @@ mod tests { fn chip_id_parsing() { let raw = hex::decode("ffff0020aeb4abcd16c6bc45e339e339e339e339").unwrap(); - let uid = ChipId::from_raw(&raw).unwrap(); + let uid = ChipUID::from_raw(&raw).unwrap(); println!("=> {uid:?}"); assert_eq!("cd-ab-b4-ae-45-bc-c6-16", uid.to_string()); diff --git a/src/commands/control.rs b/src/commands/control.rs index 0305f8d..947afdf 100644 --- a/src/commands/control.rs +++ b/src/commands/control.rs @@ -7,7 +7,8 @@ use crate::{RiscvChip, WchLinkVariant}; use super::*; -/// (0x0d, 0x01) +/// GetDeviceVersion (0x0d, 0x01) +#[derive(Debug)] pub struct GetProbeInfo; impl Command for GetProbeInfo { type Response = ProbeInfo; @@ -55,6 +56,7 @@ impl fmt::Display for ProbeInfo { } /// ?SetChipType (0x0d, 0x02) +#[derive(Debug)] pub struct AttachChip; impl Command for AttachChip { type Response = AttachChipResponse; @@ -68,7 +70,7 @@ impl Command for AttachChip { pub struct AttachChipResponse { pub chip_family: RiscvChip, pub riscvchip: u8, - pub chip_type: u32, + pub chip_id: u32, } impl AttachChipResponse {} impl Response for AttachChipResponse { @@ -79,30 +81,51 @@ impl Response for AttachChipResponse { Ok(Self { chip_family: RiscvChip::try_from_u8(bytes[0])?, riscvchip: bytes[0], - chip_type: u32::from_be_bytes(bytes[1..5].try_into().unwrap()), + chip_id: u32::from_be_bytes(bytes[1..5].try_into().unwrap()), }) } } // For logging impl fmt::Display for AttachChipResponse { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}(0x{:08x})", self.chip_family, self.chip_type) + if self.chip_id == 0 { + write!(f, "{:?}", self.chip_family) + } else if let Some(chip_name) = crate::chips::chip_id_to_chip_name(self.chip_id) { + write!( + f, + "{:?} [{}] (ChipID: 0x{:08x})", + self.chip_family, chip_name, self.chip_id + ) + } else { + write!(f, "{:?} (ChipID: 0x{:08x})", self.chip_family, self.chip_id) + } } } -// ?? close out -/// (0x0d, 0xff) -pub struct DetachChip; -impl Command for DetachChip { +/// Erase code flash, only supported by WCH-LinkE. +#[derive(Debug)] +pub enum EraseCodeFlash { + ByPinRST, + ByPowerOff, +} +impl Command for EraseCodeFlash { type Response = (); const COMMAND_ID: u8 = 0x0d; fn payload(&self) -> Vec { - vec![0xff] + match self { + // TODO: This is more complex, require RST pin to be connected. + EraseCodeFlash::ByPinRST => { + // vec![0x08, 0x06] + todo!("ByPinRST, This is more complex, require RST pin to be connected") + } + EraseCodeFlash::ByPowerOff => vec![0x0f, 0x06], + } } } -/// Only avaliable for CH32V2, CH32V3, CH56X +/// GetROMRAM, Only avaliable for CH32V2, CH32V3, CH56X /// 0, 1, 2, 3 +#[derive(Debug)] pub struct GetChipRomRamSplit; impl Command for GetChipRomRamSplit { type Response = u8; @@ -112,13 +135,46 @@ impl Command for GetChipRomRamSplit { } } -/// Special command for CH32V20X, CH32V30X, CH32V003, CH32V103 -/// After attach chip -pub struct Unknown3; -impl Command for Unknown3 { +/// 0, 1, 2, 3 +#[derive(Debug)] +pub struct SetChipRomRamSplit(u8); +impl Command for SetChipRomRamSplit { + type Response = (); + const COMMAND_ID: u8 = 0x0d; + fn payload(&self) -> Vec { + vec![0x05, self.0] + } +} + +// ?? close out +/// Detach Chip, (0x0d, 0xff) +#[derive(Debug)] +pub struct OptEnd; +impl Command for OptEnd { type Response = (); const COMMAND_ID: u8 = 0x0d; fn payload(&self) -> Vec { - vec![0x03] + vec![0xff] + } +} + +/// Set Power, from pow3v3, pow5v fn +#[derive(Debug)] +pub enum SetPower { + Enable3V3, + Disable3V3, + Enable5V, + Disable5V, +} +impl Command for SetPower { + type Response = (); + const COMMAND_ID: u8 = 0x0d; + fn payload(&self) -> Vec { + match self { + SetPower::Enable3V3 => vec![0x09], + SetPower::Disable3V3 => vec![0x0A], + SetPower::Enable5V => vec![0x0B], + SetPower::Disable5V => vec![0x0C], + } } } diff --git a/src/device.rs b/src/device.rs index 5ace282..59b0c08 100644 --- a/src/device.rs +++ b/src/device.rs @@ -4,7 +4,7 @@ use log::info; use rusb::{DeviceHandle, UsbContext}; use crate::{ - commands::{control::ProbeInfo, ChipId, RawCommand, Response}, + commands::{control::ProbeInfo, ChipUID, RawCommand, Response}, transport::Transport, Result, RiscvChip, }; @@ -24,19 +24,13 @@ const ENDPOINT_OUT_DAP: u8 = 0x02; /// Attached chip information #[derive(Debug)] pub struct ChipInfo { - pub uid: Option, + /// UID + pub uid: Option, pub chip_family: RiscvChip, - pub chip_type: u32, + /// 0x303305x4 like chip_id, In SDK, `DBGMCU_GetCHIPID` is used to get this value + pub chip_id: u32, /// parsed marchid: WCH-V4B, WCH-V4F... pub march: Option, - - pub flash_size: u32, - pub page_size: u32, - pub memory_start_addr: u32, - // Fields for ROM/RAM split - pub sram_code_mode: u8, - //pub(crate) rom_kb: u32, - //pub(crate) ram_kb: u32, } #[derive(Debug)] @@ -119,6 +113,7 @@ impl WchLink { } pub fn send_command(&mut self, cmd: C) -> Result { + log::debug!("send command: {:?}", cmd); let raw = cmd.to_raw(); self.device_handle.write_command_endpoint(&raw)?; let resp = self.device_handle.read_command_endpoint()?; @@ -151,7 +146,7 @@ pub fn try_switch_from_rv_to_dap(nth: usize) -> Result<()> { }; let info = dev.probe_info()?; info!("probe info: {:?}", info); - if info.variant.can_switch_mode() { + if info.variant.support_switch_mode() { let _ = dev.send_command(RawCommand::<0xff>(vec![0x41])); Ok(()) } else { diff --git a/src/dmi.rs b/src/dmi.rs new file mode 100644 index 0000000..70e8e92 --- /dev/null +++ b/src/dmi.rs @@ -0,0 +1,227 @@ +use crate::{ + commands::DmiOp, + device::WchLink, + error::{AbstractcsCmdErr, Error, Result}, + regs::{Abstractcs, DMReg, Dmstatus}, +}; +use std::{thread, time::Duration}; + +// FPEC, OPTWRE to unlock, +pub const KEY1: u32 = 0x45670123; +pub const KEY2: u32 = 0xCDEF89AB; + +/// RISC-V DMI +pub trait DebugModuleInterface { + fn dmi_nop(&mut self) -> Result<()>; + fn dmi_read(&mut self, reg: u8) -> Result; + fn dmi_write(&mut self, reg: u8, value: u32) -> Result<()>; + + fn read_dmi_reg(&mut self) -> Result + where + R: DMReg, + { + let val = self.dmi_read(R::ADDR)?; + Ok(R::from(val)) + } + + fn write_dmi_reg(&mut self, reg: R) -> Result<()> + where + R: DMReg, + { + self.dmi_write(R::ADDR, reg.into())?; + Ok(()) + } +} + +impl DebugModuleInterface for WchLink { + fn dmi_nop(&mut self) -> Result<()> { + self.send_command(DmiOp::nop())?; + Ok(()) + } + + fn dmi_read(&mut self, reg: u8) -> Result { + let mut n = 0; + loop { + let resp = self.send_command(DmiOp::read(reg))?; + if resp.op == 0x03 && resp.data == 0xffffffff && resp.addr == 0x7d { + // special code for NotAttached + return Err(Error::NotAttached); + } + if resp.is_success() { + return Ok(resp.data); + } else if n > 100 { + return Err(Error::Timeout); + } else if resp.is_busy() { + log::warn!("dmi_read: busy, retrying"); + thread::sleep(Duration::from_millis(10)); + n += 1; + } else { + return Err(Error::DmiFailed); + } + } + } + + fn dmi_write(&mut self, reg: u8, value: u32) -> Result<()> { + self.send_command(DmiOp::write(reg, value))?; + Ok(()) + } +} + +pub enum HaltMode { + NoReset, + Reset, + Reboot, + Resume, + /// Halt then go to bootloader + Bootloader, +} + +pub struct Algorigthm<'a, D: DebugModuleInterface> { + dmi: &'a mut D, +} + +impl<'a, D: DebugModuleInterface> Algorigthm<'a, D> { + pub fn new(dmi: &'a mut D) -> Self { + Self { dmi } + } + + fn clear_abstractcs_cmderr(&mut self) -> Result<()> { + let mut abstractcs = Abstractcs::from(0); + abstractcs.set_cmderr(0b111); + self.dmi.write_dmi_reg(abstractcs)?; + Ok(()) + } + + pub fn ensure_mcu_halt(&mut self) -> Result<()> { + let dmstatus = self.dmi.read_dmi_reg::()?; + if dmstatus.allhalted() && dmstatus.anyhalted() { + log::trace!("Already halted, nop"); + } else { + loop { + // Initiate a halt request + self.dmi.dmi_write(0x10, 0x80000001)?; + let dmstatus = self.dmi.read_dmi_reg::()?; + if dmstatus.anyhalted() && dmstatus.allhalted() { + break; + } else { + log::warn!("Not halt, try send"); + thread::sleep(Duration::from_millis(10)); + } + } + } + + // Clear the halt request bit. + self.dmi.dmi_write(0x10, 0x00000001)?; + + Ok(()) + } + + pub fn read_mem32(&mut self, addr: u32) -> Result { + self.dmi.dmi_write(0x20, 0x0002a303)?; // lw x6,0(x5) + self.dmi.dmi_write(0x21, 0x00100073)?; // ebreak + + self.dmi.dmi_write(0x04, addr)?; // data0 <- address + self.clear_abstractcs_cmderr()?; + + self.dmi.dmi_write(0x17, 0x00271005)?; + + let abstractcs: Abstractcs = self.dmi.read_dmi_reg()?; + if abstractcs.busy() { + return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy + } + if abstractcs.cmderr() != 0 { + AbstractcsCmdErr::try_from_cmderr(abstractcs.cmderr() as _)?; + } + + self.dmi.dmi_write(0x17, 0x00221006)?; // data0 <- x6 + if abstractcs.busy() { + return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy + } + if abstractcs.cmderr() != 0 { + AbstractcsCmdErr::try_from_cmderr(abstractcs.cmderr() as _)?; + } + + let data0 = self.dmi.dmi_read(0x04)?; + + Ok(data0) + } + + pub fn write_mem32(&mut self, addr: u32, data: u32) -> Result<()> { + // rasm2 -a riscv -d 23a07200 + // sw t2, 0(t0) + self.dmi.dmi_write(0x20, 0x0072a023)?; // sw x7,0(x5) + self.dmi.dmi_write(0x21, 0x00100073)?; // ebreak + + self.dmi.dmi_write(0x04, addr)?; // data0 <- address + + self.clear_abstractcs_cmderr()?; + self.dmi.dmi_write(0x17, 0x00231005)?; // x5 <- data0 + + let abstractcs: Abstractcs = self.dmi.read_dmi_reg()?; + log::trace!("{:?}", abstractcs); + if abstractcs.busy() { + return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy + } + if abstractcs.cmderr() != 0 { + AbstractcsCmdErr::try_from_cmderr(abstractcs.cmderr() as _)?; + } + + self.dmi.dmi_write(0x04, data)?; // data0 <- data + self.clear_abstractcs_cmderr()?; + + self.dmi.dmi_write(0x17, 0x00271007)?; // x7 <- data0 + + let abstractcs: Abstractcs = self.dmi.read_dmi_reg()?; + log::trace!("{:?}", abstractcs); + if abstractcs.busy() { + return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy + } + if abstractcs.cmderr() != 0 { + AbstractcsCmdErr::try_from_cmderr(abstractcs.cmderr() as _)?; + } + Ok(()) + } + + pub fn unlock_flash(&mut self) {} + + /// Read register value + /// CSR: 0x0000 - 0x0fff + /// GPR: 0x1000 - 0x101f + /// FPR: 0x1020 - 0x103f + // ref: QingKeV2 Microprocessor Debug Manual + pub fn read_reg(&mut self, regno: u16) -> Result { + self.clear_abstractcs_cmderr()?; + + let reg = regno as u32; + self.dmi.dmi_write(0x04, 0x00000000)?; // Clear the Data0 register + self.dmi.dmi_write(0x17, 0x00220000 | (reg & 0xFFFF))?; + + let abstractcs = self.dmi.read_dmi_reg::()?; + if abstractcs.busy() { + return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); // resue busy + } + if abstractcs.cmderr() != 0 { + AbstractcsCmdErr::try_from_cmderr(abstractcs.cmderr() as _)?; + } + + let resp = self.dmi.dmi_read(0x04)?; + + Ok(resp) + } + + pub fn dump_pmp(&mut self) -> Result<()> { + let regs = [ + ("pmpcfg0", 0x3A0), + ("pmpaddr0", 0x3B0), + ("pmpaddr1", 0x3B1), + ("pmpaddr2", 0x3B2), + ("pmpaddr3", 0x3B3), + ]; + for (name, addr) in regs.iter() { + let val = self.read_reg(*addr)?; + log::info!("{}: 0x{:08x}", name, val); + } + + Ok(()) + } +} diff --git a/src/error.rs b/src/error.rs index 30c80f9..887e1fd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,6 +15,8 @@ pub enum Error { ProbeNotFound, #[error("WCH-Link is connected, but is not in RV mode")] ProbeModeNotSupported, + #[error("WCH-Link doesn't support current chip: {0:?}")] + UnsupportedChip(RiscvChip), #[error("Unknown WCH-Link variant: {0}")] UnknownLinkVariant(u8), #[error("Unknown RISC-V Chip: 0x{0:02x}")] diff --git a/src/flash_op.rs b/src/flash_op.rs index a77de29..05efea1 100644 --- a/src/flash_op.rs +++ b/src/flash_op.rs @@ -1,380 +1,509 @@ //! Flash loader program for WCH's RISC-V MCUs. -//! -//! These bytes are from WCH's OpenOCD fork, which shoule be licensed under the GNU General Public License v2.0. -//! But the code is not available in the public repository, you need to ask WCH official for a copy. -//! -//! NOTE: No flash op code for CH58X found. /// For both CH32V20X and CH32V30X -pub const CH32V307: [u8; 512] = [ - 0x93, 0x77, 0x15, 0x00, 0x41, 0x11, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, 0x02, 0x40, - 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, 0xd8, 0xc3, - 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x95, 0xc7, 0xb7, 0x27, 0x02, 0x40, 0x98, 0x4b, - 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, 0x93, 0x86, - 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x61, 0xeb, 0x98, 0x4b, - 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, 0xf6, 0x0f, 0xa1, 0x83, - 0x2e, 0xc0, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xc4, 0xb7, 0x08, 0x02, 0x00, 0xb7, 0x27, 0x02, 0x40, - 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, 0x33, 0x67, 0x17, 0x01, - 0x98, 0xcb, 0x02, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, - 0x05, 0x8b, 0x41, 0xeb, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x02, 0x47, 0x13, 0x07, 0x07, 0x10, - 0x3a, 0xc0, 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, 0x69, 0xfb, 0x93, 0x77, 0x85, 0x00, 0xd5, 0xcb, - 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc0, 0xa1, 0x83, 0x3e, 0xc4, 0x37, 0x27, 0x02, 0x40, 0x1c, 0x4b, - 0xc1, 0x66, 0x41, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, 0xb7, 0x27, 0x02, 0x40, - 0x93, 0x08, 0x00, 0x04, 0x37, 0x03, 0x20, 0x00, 0x98, 0x4b, 0x33, 0x67, 0x07, 0x01, 0x98, 0xcb, - 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0x02, 0x47, 0x3a, 0xc2, 0x46, 0xc6, 0x32, 0x47, 0x0d, 0xef, - 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0xd8, 0x47, - 0x41, 0x8b, 0x39, 0xc3, 0xd8, 0x47, 0xc1, 0x76, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, - 0x98, 0x4b, 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x01, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, - 0x25, 0xb7, 0x23, 0x20, 0x03, 0x01, 0xa5, 0xb7, 0x12, 0x47, 0x13, 0x8e, 0x46, 0x00, 0x94, 0x42, - 0x14, 0xc3, 0x12, 0x47, 0x11, 0x07, 0x3a, 0xc2, 0x32, 0x47, 0x7d, 0x17, 0x3a, 0xc6, 0xd8, 0x47, - 0x09, 0x8b, 0x75, 0xff, 0xf2, 0x86, 0x5d, 0xb7, 0x02, 0x47, 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc0, - 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, 0x49, 0xf3, 0x98, 0x4b, 0xc1, 0x76, 0xfd, 0x16, 0x75, 0x8f, - 0x98, 0xcb, 0x41, 0x89, 0x15, 0xc9, 0x2e, 0xc0, 0x0d, 0x06, 0x02, 0xc4, 0x09, 0x82, 0x32, 0xc6, - 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xa2, 0x47, 0x82, 0x46, 0x8a, 0x07, - 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x1c, 0xf7, 0x00, 0xa2, 0x47, 0x85, 0x07, 0x3e, 0xc4, 0xa2, 0x46, - 0x32, 0x47, 0xb2, 0x87, 0xe3, 0xe0, 0xe6, 0xfe, 0x01, 0x45, 0xbd, 0xbf, 0x41, 0x45, 0xad, 0xbf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +// 5, 6 +// flash op packet size = 128 +pub const CH32V307: [u8; 446] = [ + 0x01, 0x11, 0x02, 0xce, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, + 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x95, 0xc7, 0xb7, 0x27, 0x02, 0x40, + 0x98, 0x4b, 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, + 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x61, 0xeb, + 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, 0xf6, 0x0f, + 0xa1, 0x83, 0x2e, 0xc6, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xca, 0xb7, 0x08, 0x02, 0x00, 0xb7, 0x27, + 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, 0x33, 0x67, + 0x17, 0x01, 0x98, 0xcb, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, + 0xd8, 0x47, 0x05, 0x8b, 0x41, 0xeb, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x32, 0x47, 0x13, 0x07, + 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x69, 0xfb, 0x93, 0x77, 0x85, 0x00, + 0xd5, 0xcb, 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc6, 0xa1, 0x83, 0x3e, 0xca, 0x37, 0x27, 0x02, 0x40, + 0x1c, 0x4b, 0xc1, 0x66, 0x41, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x08, 0x00, 0x04, 0x37, 0x03, 0x20, 0x00, 0x98, 0x4b, 0x33, 0x67, 0x07, 0x01, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0x32, 0x47, 0x3a, 0xc8, 0x46, 0xcc, 0x62, 0x47, + 0x0d, 0xef, 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, + 0xd8, 0x47, 0x41, 0x8b, 0x39, 0xc3, 0xd8, 0x47, 0xc1, 0x76, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, + 0xd8, 0xc7, 0x98, 0x4b, 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x05, 0x61, 0x02, 0x90, 0x23, 0x20, + 0xd8, 0x00, 0x25, 0xb7, 0x23, 0x20, 0x03, 0x01, 0xa5, 0xb7, 0x42, 0x47, 0x13, 0x8e, 0x46, 0x00, + 0x94, 0x42, 0x14, 0xc3, 0x42, 0x47, 0x11, 0x07, 0x3a, 0xc8, 0x62, 0x47, 0x7d, 0x17, 0x3a, 0xcc, + 0xd8, 0x47, 0x09, 0x8b, 0x75, 0xff, 0xf2, 0x86, 0x5d, 0xb7, 0x32, 0x47, 0x13, 0x07, 0x07, 0x10, + 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x49, 0xf3, 0x98, 0x4b, 0xc1, 0x76, 0xfd, 0x16, + 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, 0x19, 0xe1, 0x01, 0x45, 0x45, 0xbf, 0x2e, 0xc6, 0x0d, 0x06, + 0x02, 0xca, 0x09, 0x82, 0x32, 0xcc, 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, + 0xd2, 0x47, 0xb2, 0x46, 0x8a, 0x07, 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x18, 0xf7, 0x02, 0xd2, 0x47, + 0x32, 0x47, 0x8a, 0x07, 0xba, 0x97, 0x98, 0x43, 0xf2, 0x47, 0xba, 0x97, 0x3e, 0xce, 0xd2, 0x47, + 0x85, 0x07, 0x3e, 0xca, 0xd2, 0x46, 0x62, 0x47, 0xb2, 0x87, 0xe3, 0xe8, 0xe6, 0xfc, 0xb7, 0x27, + 0x00, 0x20, 0x98, 0x4b, 0xf2, 0x47, 0xe3, 0x09, 0xf7, 0xfa, 0x41, 0x45, 0xb9, 0xbf, ]; /// For CH32V103 -pub const CH32V103: [u8; 512] = [ - 0x93, 0x77, 0x15, 0x00, 0x41, 0x11, 0x99, 0xCF, 0xB7, 0x06, 0x67, 0x45, 0xB7, 0x27, 0x02, 0x40, - 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xEF, 0xCD, 0xD4, 0xC3, 0x13, 0x07, 0xB7, 0x9A, 0xD8, 0xC3, - 0xD4, 0xD3, 0xD8, 0xD3, 0x93, 0x77, 0x25, 0x00, 0x9D, 0xC7, 0xB7, 0x27, 0x02, 0x40, 0x98, 0x4B, - 0xAD, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xCB, 0x98, 0x4B, 0x93, 0x86, - 0xA6, 0xAA, 0x13, 0x67, 0x07, 0x04, 0x98, 0xCB, 0xD8, 0x47, 0x05, 0x8B, 0x63, 0x1F, 0x07, 0x10, - 0x98, 0x4B, 0x6D, 0x9B, 0x98, 0xCB, 0x93, 0x77, 0x45, 0x00, 0xA9, 0xCB, 0x93, 0x07, 0xF6, 0x07, - 0x9D, 0x83, 0x2E, 0xC0, 0x2D, 0x68, 0x81, 0x76, 0x3E, 0xC4, 0xB7, 0x08, 0x02, 0x00, 0xB7, 0x27, - 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xA8, 0xAA, 0xFD, 0x16, 0x98, 0x4B, 0x33, 0x67, - 0x17, 0x01, 0x98, 0xCB, 0x02, 0x47, 0xD8, 0xCB, 0x98, 0x4B, 0x13, 0x67, 0x07, 0x04, 0x98, 0xCB, - 0xD8, 0x47, 0x05, 0x8B, 0x71, 0xEF, 0x98, 0x4B, 0x75, 0x8F, 0x98, 0xCB, 0x02, 0x47, 0x13, 0x07, - 0x07, 0x08, 0x3A, 0xC0, 0x22, 0x47, 0x7D, 0x17, 0x3A, 0xC4, 0x69, 0xFB, 0x93, 0x77, 0x85, 0x00, - 0xED, 0xC3, 0x93, 0x07, 0xF6, 0x07, 0x2E, 0xC0, 0x9D, 0x83, 0x37, 0x27, 0x02, 0x40, 0x3E, 0xC4, - 0x1C, 0x4B, 0xC1, 0x66, 0x37, 0x08, 0x08, 0x00, 0xD5, 0x8F, 0x1C, 0xCB, 0xA1, 0x48, 0x37, 0x17, - 0x00, 0x20, 0xB7, 0x27, 0x02, 0x40, 0x37, 0x03, 0x04, 0x00, 0x94, 0x4B, 0xB3, 0xE6, 0x06, 0x01, - 0x94, 0xCB, 0xD4, 0x47, 0x85, 0x8A, 0xF5, 0xFE, 0x82, 0x46, 0x3A, 0x8E, 0x36, 0xC2, 0x46, 0xC6, - 0x92, 0x46, 0x83, 0x2E, 0x07, 0x00, 0x41, 0x07, 0x23, 0xA0, 0xD6, 0x01, 0x92, 0x46, 0x83, 0x2E, - 0x47, 0xFF, 0x23, 0xA2, 0xD6, 0x01, 0x92, 0x46, 0x83, 0x2E, 0x87, 0xFF, 0x23, 0xA4, 0xD6, 0x01, - 0x92, 0x46, 0x03, 0x2E, 0xCE, 0x00, 0x23, 0xA6, 0xC6, 0x01, 0x94, 0x4B, 0xB3, 0xE6, 0x66, 0x00, - 0x94, 0xCB, 0xD4, 0x47, 0x85, 0x8A, 0xF5, 0xFE, 0x92, 0x46, 0x3A, 0x8E, 0xC1, 0x06, 0x36, 0xC2, - 0xB2, 0x46, 0xFD, 0x16, 0x36, 0xC6, 0xCD, 0xFE, 0x82, 0x46, 0xD4, 0xCB, 0x94, 0x4B, 0x93, 0xE6, - 0x06, 0x04, 0x94, 0xCB, 0xD4, 0x47, 0x85, 0x8A, 0xF5, 0xFE, 0xD4, 0x47, 0xD1, 0x8A, 0x85, 0xC6, - 0xD8, 0x47, 0xB7, 0x06, 0xF3, 0xFF, 0xFD, 0x16, 0x13, 0x67, 0x47, 0x01, 0xD8, 0xC7, 0x98, 0x4B, - 0x21, 0x45, 0x75, 0x8F, 0x98, 0xCB, 0x41, 0x01, 0x02, 0x90, 0x23, 0x20, 0xD8, 0x00, 0xE9, 0xBD, - 0x23, 0x20, 0x03, 0x01, 0x31, 0xBF, 0x82, 0x46, 0x93, 0x86, 0x06, 0x08, 0x36, 0xC0, 0xA2, 0x46, - 0xFD, 0x16, 0x36, 0xC4, 0xB9, 0xFA, 0x98, 0x4B, 0xB7, 0x06, 0xF3, 0xFF, 0xFD, 0x16, 0x75, 0x8F, - 0x98, 0xCB, 0x41, 0x89, 0x15, 0xC9, 0x2E, 0xC0, 0x0D, 0x06, 0x02, 0xC4, 0x09, 0x82, 0x32, 0xC6, - 0xB7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xA2, 0x47, 0x82, 0x46, 0x8A, 0x07, - 0xB6, 0x97, 0x9C, 0x43, 0x63, 0x1C, 0xF7, 0x00, 0xA2, 0x47, 0x85, 0x07, 0x3E, 0xC4, 0xA2, 0x46, - 0x32, 0x47, 0xB2, 0x87, 0xE3, 0xE0, 0xE6, 0xFE, 0x01, 0x45, 0x71, 0xBF, 0x41, 0x45, 0x61, 0xBF, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +// 1 +pub const CH32V103: [u8; 494] = [ + 0x01, 0x11, 0x02, 0xce, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, + 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, 0x02, 0x40, + 0x98, 0x4b, 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, + 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x63, 0x1f, + 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, + 0xf6, 0x07, 0x9d, 0x83, 0x2e, 0xc6, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xca, 0xb7, 0x08, 0x02, 0x00, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, + 0x33, 0x67, 0x17, 0x01, 0x98, 0xcb, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x71, 0xef, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x32, 0x47, + 0x13, 0x07, 0x07, 0x08, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x69, 0xfb, 0x93, 0x77, + 0x85, 0x00, 0xed, 0xc3, 0x93, 0x07, 0xf6, 0x07, 0x2e, 0xc6, 0x9d, 0x83, 0x37, 0x27, 0x02, 0x40, + 0x3e, 0xca, 0x1c, 0x4b, 0xc1, 0x66, 0x37, 0x08, 0x08, 0x00, 0xd5, 0x8f, 0x1c, 0xcb, 0xa1, 0x48, + 0x37, 0x17, 0x00, 0x20, 0xb7, 0x27, 0x02, 0x40, 0x37, 0x03, 0x04, 0x00, 0x94, 0x4b, 0xb3, 0xe6, + 0x06, 0x01, 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0xf5, 0xfe, 0xb2, 0x46, 0x3a, 0x8e, 0x36, 0xc8, + 0x46, 0xcc, 0xc2, 0x46, 0x83, 0x2e, 0x07, 0x00, 0x41, 0x07, 0x23, 0xa0, 0xd6, 0x01, 0xc2, 0x46, + 0x83, 0x2e, 0x47, 0xff, 0x23, 0xa2, 0xd6, 0x01, 0xc2, 0x46, 0x83, 0x2e, 0x87, 0xff, 0x23, 0xa4, + 0xd6, 0x01, 0xc2, 0x46, 0x03, 0x2e, 0xce, 0x00, 0x23, 0xa6, 0xc6, 0x01, 0x94, 0x4b, 0xb3, 0xe6, + 0x66, 0x00, 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0xf5, 0xfe, 0xc2, 0x46, 0x3a, 0x8e, 0xc1, 0x06, + 0x36, 0xc8, 0xe2, 0x46, 0xfd, 0x16, 0x36, 0xcc, 0xcd, 0xfe, 0xb2, 0x46, 0xd4, 0xcb, 0x94, 0x4b, + 0x93, 0xe6, 0x06, 0x04, 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0xf5, 0xfe, 0xd4, 0x47, 0xd1, 0x8a, + 0x85, 0xc6, 0xd8, 0x47, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x47, 0x01, 0xd8, 0xc7, + 0x98, 0x4b, 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x05, 0x61, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, + 0xe9, 0xbd, 0x23, 0x20, 0x03, 0x01, 0x31, 0xbf, 0xb2, 0x46, 0x93, 0x86, 0x06, 0x08, 0x36, 0xc6, + 0xd2, 0x46, 0xfd, 0x16, 0x36, 0xca, 0xb9, 0xfa, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, + 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, 0x19, 0xe1, 0x01, 0x45, 0xf9, 0xb7, 0x2e, 0xc6, 0x0d, 0x06, + 0x02, 0xca, 0x09, 0x82, 0x32, 0xcc, 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, + 0xd2, 0x47, 0xb2, 0x46, 0x8a, 0x07, 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x18, 0xf7, 0x02, 0xd2, 0x47, + 0x32, 0x47, 0x8a, 0x07, 0xba, 0x97, 0x98, 0x43, 0xf2, 0x47, 0xba, 0x97, 0x3e, 0xce, 0xd2, 0x47, + 0x85, 0x07, 0x3e, 0xca, 0xd2, 0x46, 0x62, 0x47, 0xb2, 0x87, 0xe3, 0xe8, 0xe6, 0xfc, 0xb7, 0x27, + 0x00, 0x20, 0x98, 0x4b, 0xf2, 0x47, 0xe3, 0x09, 0xf7, 0xfa, 0x41, 0x45, 0xb5, 0xbf, ]; /// For CH56X -pub const CH569: [u8; 1204] = [ - 0x79, 0x71, 0x22, 0xd4, 0x26, 0xd2, 0x5a, 0xc8, 0x06, 0xd6, 0x4a, 0xd0, 0x4e, 0xce, 0x52, 0xcc, - 0x56, 0xca, 0x5e, 0xc6, 0x93, 0x77, 0x15, 0x00, 0x2a, 0x84, 0x2e, 0x8b, 0xb2, 0x84, 0x9d, 0xe7, - 0x93, 0x77, 0x24, 0x00, 0x99, 0xc7, 0xb7, 0x85, 0x07, 0x00, 0x01, 0x45, 0x59, 0x22, 0x89, 0x47, - 0x15, 0xe1, 0x93, 0x77, 0x44, 0x00, 0x91, 0xc7, 0x85, 0x65, 0x5a, 0x85, 0x9d, 0x2a, 0x91, 0x47, - 0x11, 0xe9, 0x93, 0x77, 0x84, 0x01, 0x9d, 0xe3, 0x81, 0x47, 0x29, 0xa0, 0x01, 0x45, 0xc5, 0x26, - 0x85, 0x47, 0x79, 0xd5, 0xb2, 0x50, 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, - 0xd2, 0x4a, 0x42, 0x4b, 0xb2, 0x4b, 0x3e, 0x85, 0x45, 0x61, 0x02, 0x90, 0x93, 0x84, 0xf4, 0x0f, - 0x93, 0x7b, 0x84, 0x00, 0xa1, 0x80, 0x01, 0x49, 0xb7, 0x1a, 0x00, 0x20, 0x41, 0x88, 0x93, 0x19, - 0x89, 0x00, 0x33, 0x8a, 0x69, 0x01, 0x63, 0x9e, 0x0b, 0x00, 0x0d, 0xc4, 0x13, 0x06, 0x00, 0x10, - 0xb3, 0x85, 0x59, 0x01, 0x52, 0x85, 0x01, 0x2e, 0x13, 0x75, 0xf5, 0x0f, 0x01, 0xcd, 0xc1, 0x47, - 0x55, 0xbf, 0x13, 0x06, 0x00, 0x10, 0xb3, 0x85, 0x59, 0x01, 0x52, 0x85, 0xed, 0x22, 0x71, 0xdd, - 0xa1, 0x47, 0x4d, 0xb7, 0x05, 0x09, 0xe3, 0x94, 0x24, 0xfd, 0x79, 0xb7, 0x37, 0x17, 0x00, 0x40, - 0x83, 0x47, 0xa7, 0x01, 0xe2, 0x07, 0xe1, 0x87, 0xe3, 0xcc, 0x07, 0xfe, 0x23, 0x0d, 0x07, 0x00, - 0x82, 0x80, 0x37, 0x17, 0x00, 0x40, 0x83, 0x47, 0xa7, 0x01, 0xe2, 0x07, 0xe1, 0x87, 0xe3, 0xcc, - 0x07, 0xfe, 0x23, 0x0c, 0xa7, 0x00, 0x82, 0x80, 0x37, 0x17, 0x00, 0x40, 0x83, 0x47, 0xa7, 0x01, - 0xe2, 0x07, 0xe1, 0x87, 0xe3, 0xcc, 0x07, 0xfe, 0x03, 0x45, 0x87, 0x01, 0x82, 0x80, 0x41, 0x11, - 0x22, 0xc4, 0x2a, 0x84, 0x41, 0x81, 0x13, 0x75, 0xf5, 0x0f, 0x06, 0xc6, 0xd9, 0x37, 0x13, 0x55, - 0x84, 0x00, 0x13, 0x75, 0xf5, 0x0f, 0x75, 0x3f, 0x13, 0x75, 0xf4, 0x0f, 0x22, 0x44, 0xb2, 0x40, - 0x41, 0x01, 0x45, 0xbf, 0x01, 0x11, 0x22, 0xcc, 0x26, 0xca, 0x06, 0xce, 0x37, 0x14, 0x00, 0x40, - 0x2a, 0xc6, 0x23, 0x0d, 0x04, 0x00, 0x9d, 0x44, 0x23, 0x0d, 0x94, 0x00, 0x99, 0x47, 0x23, 0x0c, - 0xf4, 0x00, 0xad, 0x3f, 0x23, 0x0d, 0x04, 0x00, 0x23, 0x0d, 0x94, 0x00, 0x32, 0x45, 0x23, 0x0c, - 0xa4, 0x00, 0xf2, 0x40, 0x62, 0x44, 0xd2, 0x44, 0x05, 0x61, 0x82, 0x80, 0x79, 0x71, 0x4a, 0xd0, - 0x37, 0x19, 0x00, 0x40, 0x22, 0xd4, 0x26, 0xd2, 0x4e, 0xce, 0x52, 0xcc, 0x06, 0xd6, 0x37, 0x04, - 0x28, 0x00, 0xa9, 0x37, 0x93, 0x04, 0xa9, 0x01, 0x1d, 0x4a, 0x95, 0x49, 0x23, 0x80, 0x04, 0x00, - 0x23, 0x80, 0x44, 0x01, 0x23, 0x0c, 0x39, 0x01, 0x85, 0x37, 0xb9, 0x3f, 0x2a, 0xc6, 0x3d, 0x37, - 0x32, 0x45, 0x05, 0x89, 0x09, 0xcd, 0x7d, 0x14, 0x75, 0xf0, 0x13, 0x05, 0xf0, 0x0f, 0xb2, 0x50, - 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, 0x45, 0x61, 0x82, 0x80, 0x01, 0x45, - 0xfd, 0xb7, 0xb7, 0x16, 0x00, 0x40, 0x03, 0xc7, 0x46, 0x00, 0x41, 0x8b, 0x71, 0xeb, 0x05, 0x67, - 0x01, 0x11, 0x7d, 0x17, 0x22, 0xcc, 0x33, 0x84, 0xe5, 0x00, 0x69, 0x8f, 0x26, 0xca, 0x3a, 0x94, - 0xfd, 0x74, 0x65, 0x8c, 0x06, 0xce, 0xe9, 0x8c, 0x4a, 0xc8, 0x4e, 0xc6, 0x37, 0x06, 0x08, 0x00, - 0xaa, 0x87, 0x13, 0x05, 0xe0, 0x0f, 0x63, 0xf7, 0xc4, 0x06, 0x33, 0x07, 0x94, 0x00, 0x13, 0x05, - 0xa0, 0x0f, 0x63, 0x61, 0xe6, 0x06, 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, 0xe6, 0x00, 0x13, 0x07, - 0x80, 0xfa, 0x23, 0x80, 0xe6, 0x00, 0x03, 0xc7, 0x46, 0x00, 0x3d, 0x65, 0xe9, 0x8f, 0x13, 0x67, - 0xc7, 0x08, 0x23, 0x82, 0xe6, 0x00, 0x91, 0xe7, 0xb7, 0x09, 0x07, 0x00, 0x41, 0x69, 0x63, 0xe2, - 0x34, 0x05, 0xa2, 0x94, 0x05, 0x69, 0xb3, 0x89, 0x84, 0x40, 0x63, 0x79, 0x24, 0x05, 0x01, 0x45, - 0x37, 0x17, 0x00, 0x40, 0x93, 0x07, 0x70, 0x05, 0x23, 0x00, 0xf7, 0x00, 0x93, 0x07, 0x80, 0xfa, - 0x23, 0x00, 0xf7, 0x00, 0x83, 0x47, 0x47, 0x00, 0x93, 0xf7, 0x37, 0x07, 0x93, 0xe7, 0x07, 0x08, - 0x23, 0x02, 0xf7, 0x00, 0xf2, 0x40, 0x62, 0x44, 0xd2, 0x44, 0x42, 0x49, 0xb2, 0x49, 0x05, 0x61, - 0x82, 0x80, 0xe3, 0x60, 0x24, 0xfd, 0x13, 0x05, 0x80, 0x0d, 0x6d, 0x3d, 0x26, 0x85, 0x41, 0x3d, - 0xf5, 0x35, 0x5d, 0xfd, 0xca, 0x94, 0x33, 0x04, 0x24, 0x41, 0x55, 0xb7, 0x13, 0x05, 0x00, 0x02, - 0x55, 0x35, 0x4e, 0x85, 0xad, 0x3d, 0xd9, 0x3d, 0x45, 0xf5, 0x33, 0x04, 0x24, 0x41, 0x61, 0xbf, - 0x13, 0x05, 0xb0, 0x0f, 0x82, 0x80, 0x01, 0x11, 0x22, 0xcc, 0x37, 0x04, 0x00, 0x10, 0x71, 0x14, - 0x69, 0x8c, 0x21, 0x65, 0x2a, 0x94, 0x06, 0xce, 0x26, 0xca, 0x4a, 0xc8, 0x4e, 0xc6, 0x37, 0x07, - 0x08, 0x00, 0x13, 0x05, 0xe0, 0x0f, 0x63, 0x71, 0xe4, 0x0e, 0xb3, 0x07, 0xc4, 0x00, 0x13, 0x05, - 0xa0, 0x0f, 0x63, 0x6b, 0xf7, 0x0c, 0xb7, 0x17, 0x00, 0x40, 0x03, 0xc7, 0x47, 0x00, 0x13, 0x05, - 0xb0, 0x0f, 0x41, 0x8b, 0x71, 0xe3, 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, 0xe7, 0x00, 0x13, 0x07, - 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x00, 0x03, 0xc7, 0x47, 0x00, 0x2e, 0x89, 0x93, 0x59, 0x26, 0x00, - 0x13, 0x67, 0xc7, 0x08, 0x23, 0x82, 0xe7, 0x00, 0xb7, 0x14, 0x00, 0x40, 0x63, 0x94, 0x09, 0x00, - 0x01, 0x45, 0x8d, 0xa8, 0x09, 0x45, 0x39, 0x3d, 0x22, 0x85, 0xd5, 0x3b, 0x33, 0x05, 0x24, 0x41, - 0x11, 0x09, 0x83, 0x27, 0xc9, 0xff, 0xdc, 0xc8, 0x83, 0xc7, 0xa4, 0x01, 0x93, 0xe7, 0x07, 0x01, - 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, - 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, - 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, - 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, - 0xfd, 0x19, 0x33, 0x04, 0xa9, 0x00, 0x63, 0x85, 0x09, 0x00, 0x93, 0x77, 0xf4, 0x0f, 0xcd, 0xf3, - 0xf5, 0x33, 0x49, 0xd5, 0x37, 0x17, 0x00, 0x40, 0x93, 0x07, 0x70, 0x05, 0x23, 0x00, 0xf7, 0x00, - 0x93, 0x07, 0x80, 0xfa, 0x23, 0x00, 0xf7, 0x00, 0x83, 0x47, 0x47, 0x00, 0x93, 0xf7, 0x37, 0x07, - 0x93, 0xe7, 0x07, 0x08, 0x23, 0x02, 0xf7, 0x00, 0xf2, 0x40, 0x62, 0x44, 0xd2, 0x44, 0x42, 0x49, - 0xb2, 0x49, 0x05, 0x61, 0x82, 0x80, 0x01, 0x11, 0xa1, 0x67, 0x26, 0xca, 0x3e, 0x95, 0x06, 0xce, - 0x22, 0xcc, 0x4a, 0xc8, 0x4e, 0xc6, 0x52, 0xc4, 0xb7, 0x07, 0x08, 0x00, 0x93, 0x04, 0xe0, 0x0f, - 0x63, 0x71, 0xf5, 0x04, 0xb7, 0x17, 0x00, 0x40, 0x03, 0xc7, 0x47, 0x00, 0x93, 0x04, 0xb0, 0x0f, - 0x41, 0x8b, 0x05, 0xeb, 0x23, 0x8d, 0x07, 0x00, 0x1d, 0x47, 0x23, 0x8d, 0xe7, 0x00, 0x2d, 0x47, - 0x23, 0x8c, 0xe7, 0x00, 0x2e, 0x84, 0x93, 0x54, 0x26, 0x00, 0x11, 0x3b, 0xf5, 0x39, 0xed, 0x39, - 0xfd, 0x59, 0x37, 0x1a, 0x00, 0x40, 0x13, 0x89, 0xf4, 0xff, 0x63, 0x1d, 0x39, 0x01, 0x81, 0x44, - 0x75, 0x39, 0xf2, 0x40, 0x62, 0x44, 0x26, 0x85, 0x42, 0x49, 0xd2, 0x44, 0xb2, 0x49, 0x22, 0x4a, - 0x05, 0x61, 0x82, 0x80, 0xd1, 0x39, 0xc9, 0x39, 0xc1, 0x39, 0xf9, 0x31, 0x11, 0x04, 0x03, 0x27, - 0x4a, 0x01, 0x83, 0x27, 0xc4, 0xff, 0xe3, 0x1d, 0xf7, 0xfc, 0xca, 0x84, 0xe9, 0xb7, 0x79, 0x71, - 0x4a, 0xd0, 0x37, 0x19, 0x00, 0x40, 0x22, 0xd4, 0x26, 0xd2, 0x4e, 0xce, 0x52, 0xcc, 0x06, 0xd6, - 0x37, 0x04, 0x28, 0x00, 0xa5, 0x39, 0x93, 0x04, 0xa9, 0x01, 0x1d, 0x4a, 0x95, 0x49, 0x23, 0x80, - 0x04, 0x00, 0x23, 0x80, 0x44, 0x01, 0x23, 0x0c, 0x39, 0x01, 0x79, 0x31, 0x71, 0x31, 0x2a, 0xc6, - 0xb1, 0x39, 0x32, 0x45, 0x93, 0x77, 0x15, 0x00, 0xa9, 0xc3, 0x7d, 0x14, 0x6d, 0xf0, 0x13, 0x05, - 0xf0, 0x0f, 0xb2, 0x50, 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, 0x45, 0x61, - 0x82, 0x80, 0x13, 0x07, 0x40, 0x04, 0x01, 0x45, 0xe3, 0x85, 0xe7, 0xfe, 0x05, 0x45, 0x59, 0x39, - 0x13, 0x05, 0x40, 0x04, 0x3d, 0x39, 0x09, 0x45, 0x2d, 0x39, 0x22, 0x54, 0xb2, 0x50, 0x92, 0x54, - 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, 0x45, 0x61, 0x55, 0xb9, 0x93, 0x77, 0xc5, 0x07, 0xf1, 0xfb, - 0x01, 0x45, 0xc1, 0xb7, +// 3 +pub const CH569: [u8; 1156] = [ + 0x79, 0x71, 0x22, 0xd4, 0x4a, 0xd0, 0x56, 0xca, 0x06, 0xd6, 0x26, 0xd2, 0x4e, 0xce, 0x52, 0xcc, + 0x5a, 0xc8, 0x5e, 0xc6, 0x62, 0xc4, 0x93, 0x77, 0x15, 0x00, 0x2a, 0x84, 0xae, 0x8a, 0x32, 0x89, + 0xbd, 0xe7, 0x93, 0x77, 0x24, 0x00, 0x99, 0xc7, 0xb7, 0x85, 0x07, 0x00, 0x01, 0x45, 0xa9, 0x2c, + 0x89, 0x47, 0x35, 0xe1, 0x93, 0x77, 0x44, 0x00, 0x91, 0xc7, 0x85, 0x65, 0x56, 0x85, 0xa9, 0x24, + 0x91, 0x47, 0x31, 0xe9, 0x93, 0x77, 0x84, 0x01, 0x01, 0x4a, 0xd9, 0xc7, 0xb7, 0x14, 0x00, 0x20, + 0x13, 0x09, 0xf9, 0x0f, 0x93, 0x84, 0x04, 0x10, 0x13, 0x59, 0x89, 0x00, 0x01, 0x4a, 0xb3, 0x8a, + 0x9a, 0x40, 0x93, 0x7b, 0x84, 0x00, 0x13, 0x7c, 0x04, 0x01, 0x33, 0x8b, 0x9a, 0x00, 0x63, 0x91, + 0x0b, 0x04, 0x63, 0x0e, 0x0c, 0x04, 0x93, 0x89, 0x04, 0xf0, 0x13, 0x06, 0x00, 0x10, 0xce, 0x85, + 0x5a, 0x85, 0x2d, 0x26, 0x13, 0x75, 0xf5, 0x0f, 0x0d, 0xcd, 0xc1, 0x47, 0x29, 0xa0, 0x01, 0x45, + 0x69, 0x2e, 0x85, 0x47, 0x59, 0xd5, 0xb2, 0x50, 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, + 0x62, 0x4a, 0xd2, 0x4a, 0x42, 0x4b, 0xb2, 0x4b, 0x22, 0x4c, 0x3e, 0x85, 0x45, 0x61, 0x02, 0x90, + 0x13, 0x06, 0x00, 0x10, 0x93, 0x85, 0x04, 0xf0, 0x5a, 0x85, 0xcd, 0x22, 0x5d, 0xd9, 0xa1, 0x47, + 0xd9, 0xbf, 0x83, 0xa7, 0x09, 0x00, 0x91, 0x09, 0x3e, 0x9a, 0xe3, 0x9c, 0x34, 0xff, 0x7d, 0x19, + 0x93, 0x84, 0x04, 0x10, 0xe3, 0x1b, 0x09, 0xf8, 0x41, 0x88, 0x81, 0x47, 0x4d, 0xdc, 0x37, 0x67, + 0x00, 0x20, 0x18, 0x4b, 0xe3, 0x09, 0x47, 0xfb, 0x4d, 0xb7, 0xb7, 0x17, 0x00, 0x40, 0x23, 0x8d, + 0x07, 0x00, 0x1d, 0x47, 0x23, 0x8d, 0xe7, 0x00, 0x23, 0x8c, 0xa7, 0x00, 0x82, 0x80, 0x37, 0x17, + 0x00, 0x40, 0x83, 0x47, 0xa7, 0x01, 0xe2, 0x07, 0xe1, 0x87, 0xe3, 0xcc, 0x07, 0xfe, 0x23, 0x0d, + 0x07, 0x00, 0x82, 0x80, 0x37, 0x17, 0x00, 0x40, 0x83, 0x47, 0xa7, 0x01, 0xe2, 0x07, 0xe1, 0x87, + 0xe3, 0xcc, 0x07, 0xfe, 0x23, 0x0c, 0xa7, 0x00, 0x82, 0x80, 0x37, 0x17, 0x00, 0x40, 0x83, 0x47, + 0xa7, 0x01, 0xe2, 0x07, 0xe1, 0x87, 0xe3, 0xcc, 0x07, 0xfe, 0x03, 0x45, 0x87, 0x01, 0x82, 0x80, + 0x41, 0x11, 0x22, 0xc4, 0x2a, 0x84, 0x41, 0x81, 0x13, 0x75, 0xf5, 0x0f, 0x06, 0xc6, 0xd9, 0x37, + 0x13, 0x55, 0x84, 0x00, 0x13, 0x75, 0xf5, 0x0f, 0x75, 0x3f, 0x13, 0x75, 0xf4, 0x0f, 0x22, 0x44, + 0xb2, 0x40, 0x41, 0x01, 0x45, 0xbf, 0x41, 0x11, 0x22, 0xc4, 0x2a, 0x84, 0x19, 0x45, 0x06, 0xc6, + 0xad, 0x3f, 0x71, 0x37, 0x22, 0x85, 0x22, 0x44, 0xb2, 0x40, 0x41, 0x01, 0xbd, 0xb7, 0x01, 0x11, + 0x22, 0xcc, 0x06, 0xce, 0x37, 0x04, 0x28, 0x00, 0x9d, 0x3f, 0x15, 0x45, 0xb9, 0x3f, 0x71, 0x3f, + 0x69, 0x3f, 0x2a, 0xc6, 0xad, 0x37, 0x32, 0x45, 0x05, 0x89, 0x09, 0xc9, 0x7d, 0x14, 0x75, 0xf4, + 0x13, 0x05, 0xf0, 0x0f, 0xf2, 0x40, 0x62, 0x44, 0x05, 0x61, 0x82, 0x80, 0x01, 0x45, 0xdd, 0xbf, + 0x85, 0x67, 0xfd, 0x17, 0x01, 0x11, 0xbe, 0x95, 0xe9, 0x8f, 0x26, 0xca, 0xae, 0x97, 0xfd, 0x74, + 0x22, 0xcc, 0x06, 0xce, 0x33, 0xf4, 0x97, 0x00, 0x4a, 0xc8, 0x4e, 0xc6, 0xe9, 0x8c, 0xb7, 0x06, + 0x08, 0x00, 0x63, 0xf8, 0xd4, 0x0a, 0xb3, 0x07, 0x94, 0x00, 0x2a, 0x87, 0x13, 0x05, 0xa0, 0x0f, + 0x63, 0xe3, 0xf6, 0x06, 0xb7, 0x17, 0x00, 0x40, 0x93, 0x06, 0x70, 0x05, 0x23, 0x80, 0xd7, 0x00, + 0x93, 0x06, 0x80, 0xfa, 0x23, 0x80, 0xd7, 0x00, 0x83, 0xc6, 0x47, 0x00, 0x3d, 0x65, 0x69, 0x8f, + 0x93, 0xe6, 0xc6, 0x08, 0x23, 0x82, 0xd7, 0x00, 0x11, 0xe7, 0xb7, 0x09, 0x07, 0x00, 0x41, 0x69, + 0x63, 0xe2, 0x34, 0x05, 0xa2, 0x94, 0x05, 0x69, 0xb3, 0x89, 0x84, 0x40, 0x63, 0x79, 0x24, 0x05, + 0x01, 0x45, 0x37, 0x17, 0x00, 0x40, 0x93, 0x07, 0x70, 0x05, 0x23, 0x00, 0xf7, 0x00, 0x93, 0x07, + 0x80, 0xfa, 0x23, 0x00, 0xf7, 0x00, 0x83, 0x47, 0x47, 0x00, 0x93, 0xf7, 0x37, 0x07, 0x93, 0xe7, + 0x07, 0x08, 0x23, 0x02, 0xf7, 0x00, 0xf2, 0x40, 0x62, 0x44, 0xd2, 0x44, 0x42, 0x49, 0xb2, 0x49, + 0x05, 0x61, 0x82, 0x80, 0xe3, 0x60, 0x24, 0xfd, 0x13, 0x05, 0x80, 0x0d, 0x29, 0x37, 0x26, 0x85, + 0xc5, 0x35, 0x31, 0x3f, 0x5d, 0xfd, 0xca, 0x94, 0x33, 0x04, 0x24, 0x41, 0x55, 0xb7, 0x13, 0x05, + 0x00, 0x02, 0xd5, 0x3d, 0x4e, 0x85, 0xe9, 0x35, 0x19, 0x37, 0x45, 0xf5, 0x33, 0x04, 0x24, 0x41, + 0x61, 0xbf, 0x13, 0x05, 0xe0, 0x0f, 0xc1, 0xb7, 0xb7, 0x17, 0x00, 0x40, 0x83, 0xc7, 0x47, 0x00, + 0xc1, 0x8b, 0x91, 0xe3, 0x31, 0xbf, 0x13, 0x05, 0xb0, 0x0f, 0x82, 0x80, 0x01, 0x11, 0x22, 0xcc, + 0x37, 0x04, 0x00, 0x10, 0x71, 0x14, 0x69, 0x8c, 0x21, 0x65, 0x2a, 0x94, 0x06, 0xce, 0x26, 0xca, + 0x4a, 0xc8, 0x4e, 0xc6, 0x37, 0x07, 0x08, 0x00, 0x13, 0x05, 0xe0, 0x0f, 0x63, 0x71, 0xe4, 0x0e, + 0xb3, 0x07, 0xc4, 0x00, 0x13, 0x05, 0xa0, 0x0f, 0x63, 0x6b, 0xf7, 0x0c, 0xb7, 0x17, 0x00, 0x40, + 0x03, 0xc7, 0x47, 0x00, 0x13, 0x05, 0xb0, 0x0f, 0x41, 0x8b, 0x71, 0xe3, 0x13, 0x07, 0x70, 0x05, + 0x23, 0x80, 0xe7, 0x00, 0x13, 0x07, 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x00, 0x03, 0xc7, 0x47, 0x00, + 0x2e, 0x89, 0x93, 0x59, 0x26, 0x00, 0x13, 0x67, 0xc7, 0x08, 0x23, 0x82, 0xe7, 0x00, 0xb7, 0x14, + 0x00, 0x40, 0x63, 0x94, 0x09, 0x00, 0x01, 0x45, 0x8d, 0xa8, 0x09, 0x45, 0xa9, 0x3d, 0x22, 0x85, + 0x05, 0x3d, 0x33, 0x05, 0x24, 0x41, 0x11, 0x09, 0x83, 0x27, 0xc9, 0xff, 0xdc, 0xc8, 0x83, 0xc7, + 0xa4, 0x01, 0x93, 0xe7, 0x07, 0x01, 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, + 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, + 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, + 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, 0x03, 0xc7, 0xa4, 0x01, 0x62, 0x07, 0x61, 0x87, 0xe3, 0x4c, + 0x07, 0xfe, 0x23, 0x8d, 0xf4, 0x00, 0xfd, 0x19, 0x33, 0x04, 0xa9, 0x00, 0x63, 0x85, 0x09, 0x00, + 0x93, 0x77, 0xf4, 0x0f, 0xcd, 0xf3, 0x21, 0x35, 0x49, 0xd5, 0x37, 0x17, 0x00, 0x40, 0x93, 0x07, + 0x70, 0x05, 0x23, 0x00, 0xf7, 0x00, 0x93, 0x07, 0x80, 0xfa, 0x23, 0x00, 0xf7, 0x00, 0x83, 0x47, + 0x47, 0x00, 0x93, 0xf7, 0x37, 0x07, 0x93, 0xe7, 0x07, 0x08, 0x23, 0x02, 0xf7, 0x00, 0xf2, 0x40, + 0x62, 0x44, 0xd2, 0x44, 0x42, 0x49, 0xb2, 0x49, 0x05, 0x61, 0x82, 0x80, 0x01, 0x11, 0x4a, 0xc8, + 0x21, 0x69, 0x26, 0xca, 0x06, 0xce, 0x22, 0xcc, 0x4e, 0xc6, 0x52, 0xc4, 0x2a, 0x99, 0xb7, 0x07, + 0x08, 0x00, 0x93, 0x04, 0xe0, 0x0f, 0x63, 0x7c, 0xf9, 0x02, 0xb7, 0x17, 0x00, 0x40, 0x83, 0xc7, + 0x47, 0x00, 0x93, 0x04, 0xb0, 0x0f, 0xc1, 0x8b, 0x9d, 0xe3, 0x2d, 0x45, 0x2e, 0x84, 0x93, 0x54, + 0x26, 0x00, 0x21, 0x33, 0x4a, 0x85, 0xa9, 0x3b, 0x89, 0x33, 0x81, 0x33, 0xfd, 0x59, 0x37, 0x1a, + 0x00, 0x40, 0x13, 0x89, 0xf4, 0xff, 0x63, 0x1d, 0x39, 0x01, 0x81, 0x44, 0x09, 0x33, 0xf2, 0x40, + 0x62, 0x44, 0x26, 0x85, 0x42, 0x49, 0xd2, 0x44, 0xb2, 0x49, 0x22, 0x4a, 0x05, 0x61, 0x82, 0x80, + 0x29, 0x3b, 0x21, 0x3b, 0x19, 0x3b, 0x11, 0x3b, 0x11, 0x04, 0x03, 0x27, 0x4a, 0x01, 0x83, 0x27, + 0xc4, 0xff, 0xe3, 0x1d, 0xf7, 0xfc, 0xca, 0x84, 0xe9, 0xb7, 0x01, 0x11, 0x22, 0xcc, 0x06, 0xce, + 0x37, 0x04, 0x28, 0x00, 0xe9, 0x31, 0x15, 0x45, 0x4d, 0x39, 0xc5, 0x39, 0xfd, 0x31, 0x2a, 0xc6, + 0x7d, 0x39, 0x32, 0x45, 0x93, 0x77, 0x15, 0x00, 0x8d, 0xcb, 0x7d, 0x14, 0x6d, 0xf4, 0x13, 0x05, + 0xf0, 0x0f, 0xf2, 0x40, 0x62, 0x44, 0x05, 0x61, 0x82, 0x80, 0x13, 0x07, 0x40, 0x04, 0x01, 0x45, + 0xe3, 0x89, 0xe7, 0xfe, 0x05, 0x45, 0x01, 0x33, 0x13, 0x05, 0x40, 0x04, 0x65, 0x31, 0x09, 0x45, + 0x55, 0x31, 0x62, 0x44, 0xf2, 0x40, 0x05, 0x61, 0x19, 0xb3, 0x93, 0x77, 0xc5, 0x07, 0xf1, 0xff, + 0x01, 0x45, 0xc1, 0xbf, ]; -/// For both CH57X andxs CH58X -pub const CH573: [u8; 1280] = [ - 0x79, 0x71, 0x22, 0xD4, 0x26, 0xD2, 0x5A, 0xC8, 0x06, 0xD6, 0x4A, 0xD0, 0x4E, 0xCE, 0x52, 0xCC, - 0x56, 0xCA, 0x5E, 0xC6, 0x93, 0x77, 0x15, 0x00, 0x2A, 0x84, 0x2E, 0x8B, 0xB2, 0x84, 0x9D, 0xEF, - 0x93, 0x77, 0x24, 0x00, 0x99, 0xCB, 0xB7, 0x86, 0x07, 0x00, 0x01, 0x46, 0x81, 0x45, 0x05, 0x45, - 0x9D, 0x22, 0x93, 0x77, 0xF5, 0x0F, 0x09, 0x45, 0x9D, 0xEB, 0x93, 0x77, 0x44, 0x00, 0x91, 0xCB, - 0x85, 0x66, 0x01, 0x46, 0xDA, 0x85, 0x05, 0x45, 0xB9, 0x22, 0x93, 0x77, 0xF5, 0x0F, 0x11, 0x45, - 0x99, 0xEF, 0x93, 0x77, 0x84, 0x01, 0x9D, 0xE7, 0x01, 0x45, 0x11, 0xA8, 0x81, 0x46, 0x01, 0x46, - 0x81, 0x45, 0x21, 0x45, 0x0D, 0x2A, 0x93, 0x77, 0xF5, 0x0F, 0x05, 0x45, 0xD5, 0xDB, 0xB2, 0x50, - 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xF2, 0x49, 0x62, 0x4A, 0xD2, 0x4A, 0x42, 0x4B, 0xB2, 0x4B, - 0x45, 0x61, 0x02, 0x90, 0x93, 0x84, 0xF4, 0x0F, 0x93, 0x7B, 0x84, 0x00, 0xA1, 0x80, 0x01, 0x49, - 0xB7, 0x5A, 0x00, 0x20, 0x41, 0x88, 0x93, 0x19, 0x89, 0x00, 0x33, 0x8A, 0x69, 0x01, 0x63, 0x9F, - 0x0B, 0x00, 0x0D, 0xC8, 0x93, 0x06, 0x00, 0x10, 0x33, 0x86, 0x59, 0x01, 0xD2, 0x85, 0x0D, 0x45, - 0xDD, 0x20, 0x13, 0x75, 0xF5, 0x0F, 0x19, 0xCD, 0x41, 0x45, 0x55, 0xBF, 0x93, 0x06, 0x00, 0x10, - 0x33, 0x86, 0x59, 0x01, 0xD2, 0x85, 0x09, 0x45, 0xF9, 0x20, 0x13, 0x75, 0xF5, 0x0F, 0x71, 0xD9, - 0x21, 0x45, 0x71, 0xBF, 0x05, 0x09, 0xE3, 0x10, 0x99, 0xFC, 0xBD, 0xBF, 0x23, 0x03, 0x04, 0x80, - 0x95, 0x47, 0x23, 0x03, 0xF4, 0x80, 0x23, 0x02, 0xA4, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, - 0xE3, 0xCE, 0x07, 0xFE, 0x23, 0x03, 0x04, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, 0xE3, 0xCE, - 0x07, 0xFE, 0x03, 0x45, 0x44, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, 0xE3, 0xCE, 0x07, 0xFE, - 0x23, 0x02, 0xA4, 0x80, 0x82, 0x80, 0x41, 0x11, 0x26, 0xC4, 0x4A, 0xC2, 0x4E, 0xC0, 0x06, 0xC6, - 0x13, 0x77, 0xF5, 0x0B, 0xAD, 0x47, 0xAA, 0x89, 0x2E, 0x89, 0x95, 0x44, 0x63, 0x06, 0xF7, 0x00, - 0x19, 0x45, 0x6D, 0x37, 0x65, 0x3F, 0x8D, 0x44, 0x4E, 0x85, 0x4D, 0x37, 0xFD, 0x59, 0xFD, 0x14, - 0x63, 0x98, 0x34, 0x01, 0xB2, 0x40, 0xA2, 0x44, 0x12, 0x49, 0x82, 0x49, 0x41, 0x01, 0x82, 0x80, - 0x13, 0x55, 0x09, 0x01, 0x13, 0x75, 0xF5, 0x0F, 0x45, 0x3F, 0x22, 0x09, 0xCD, 0xB7, 0x01, 0x11, - 0x26, 0xCC, 0x06, 0xCE, 0xB7, 0x04, 0x08, 0x00, 0x51, 0x37, 0x15, 0x45, 0x85, 0x3F, 0x71, 0x37, - 0x69, 0x37, 0x2A, 0xC6, 0xA5, 0x3F, 0x32, 0x45, 0x93, 0x77, 0x15, 0x00, 0x89, 0xEB, 0x13, 0x65, - 0x15, 0x00, 0x13, 0x75, 0xF5, 0x0F, 0xF2, 0x40, 0xE2, 0x44, 0x05, 0x61, 0x82, 0x80, 0xFD, 0x14, - 0xE9, 0xFC, 0x01, 0x45, 0xCD, 0xBF, 0x39, 0x71, 0x26, 0xDC, 0x4A, 0xDA, 0x4E, 0xD8, 0x52, 0xD6, - 0x56, 0xD4, 0x5A, 0xD2, 0x5E, 0xD0, 0x06, 0xDE, 0x62, 0xCE, 0x66, 0xCC, 0xB7, 0xE7, 0x00, 0xE0, - 0x7D, 0x57, 0x83, 0xAA, 0x07, 0x00, 0x22, 0xC6, 0x03, 0xAA, 0x47, 0x00, 0x23, 0xA0, 0xE7, 0x18, - 0x23, 0xA2, 0xE7, 0x18, 0xB7, 0x17, 0x00, 0x40, 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, 0xE7, 0x04, - 0x13, 0x07, 0x80, 0xFA, 0x23, 0x80, 0xE7, 0x04, 0x83, 0xC7, 0x47, 0x04, 0x13, 0x09, 0x75, 0xFF, - 0xB6, 0x84, 0xE2, 0x07, 0x13, 0x79, 0xF9, 0x0F, 0x85, 0x46, 0xAA, 0x89, 0xAE, 0x8B, 0x32, 0x8B, - 0x37, 0x24, 0x00, 0x40, 0xE1, 0x87, 0x01, 0x57, 0x63, 0xFA, 0x26, 0x01, 0x63, 0x08, 0xD5, 0x00, - 0x89, 0x46, 0x13, 0x07, 0x00, 0x02, 0x63, 0x13, 0xD5, 0x00, 0x01, 0x57, 0xD9, 0x8F, 0x93, 0xF7, - 0xF7, 0x0F, 0xB7, 0x1C, 0x00, 0x40, 0x23, 0x82, 0xFC, 0x04, 0x11, 0x47, 0x23, 0x03, 0xE4, 0x80, - 0x13, 0x05, 0xF0, 0x0F, 0x65, 0x3D, 0x09, 0x4C, 0xD1, 0x35, 0x63, 0x69, 0x2C, 0x11, 0xB7, 0x07, - 0x07, 0x00, 0xBE, 0x9B, 0x37, 0x87, 0x07, 0x00, 0x79, 0x55, 0x63, 0xFE, 0xEB, 0x02, 0xB3, 0x87, - 0x9B, 0x00, 0x63, 0x6A, 0xF7, 0x02, 0xA9, 0x47, 0x63, 0x99, 0xF9, 0x06, 0x89, 0xE4, 0x81, 0x44, - 0x71, 0x3D, 0x26, 0x85, 0x0D, 0xA0, 0xDE, 0x85, 0x09, 0x45, 0x75, 0x3D, 0x05, 0x0B, 0x03, 0x45, - 0xFB, 0xFF, 0xFD, 0x14, 0x85, 0x0B, 0x4D, 0x35, 0x81, 0xC4, 0x93, 0xF7, 0xFB, 0x0F, 0xFD, 0xF7, - 0xFD, 0x35, 0x69, 0xFD, 0x7D, 0x55, 0xB7, 0x17, 0x00, 0x40, 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, - 0xE7, 0x04, 0x13, 0x07, 0x80, 0xFA, 0x23, 0x80, 0xE7, 0x04, 0x03, 0xC7, 0x47, 0x04, 0x41, 0x8B, - 0x23, 0x82, 0xE7, 0x04, 0xF2, 0x50, 0xB7, 0xE7, 0x00, 0xE0, 0x23, 0xA0, 0x57, 0x11, 0x23, 0xA2, - 0x47, 0x11, 0xE2, 0x54, 0x32, 0x44, 0x52, 0x59, 0xC2, 0x59, 0x32, 0x5A, 0xA2, 0x5A, 0x12, 0x5B, - 0x82, 0x5B, 0x72, 0x4C, 0xE2, 0x4C, 0x21, 0x61, 0x82, 0x80, 0xA5, 0x47, 0x63, 0x95, 0xF9, 0x06, - 0x85, 0x69, 0x13, 0x09, 0xF0, 0x0F, 0xB3, 0x06, 0x99, 0x00, 0xB3, 0xF4, 0x2B, 0x01, 0xB6, 0x94, - 0x13, 0x49, 0xF9, 0xFF, 0xB3, 0x74, 0x99, 0x00, 0x41, 0x6B, 0x33, 0x79, 0x79, 0x01, 0x85, 0x6B, - 0x93, 0x87, 0xF9, 0xFF, 0xB3, 0xF7, 0x27, 0x01, 0x99, 0xE3, 0x63, 0xFC, 0x34, 0x01, 0x93, 0xD9, - 0x49, 0x00, 0xC1, 0x47, 0xE3, 0xE6, 0x37, 0xFF, 0x99, 0xBF, 0x05, 0x69, 0xC1, 0x69, 0x7D, 0x19, - 0xD9, 0xB7, 0x13, 0x05, 0x80, 0x0D, 0x63, 0x88, 0x69, 0x01, 0x13, 0x05, 0x00, 0x02, 0x63, 0x84, - 0x79, 0x01, 0x13, 0x05, 0x10, 0x08, 0xCA, 0x85, 0xFD, 0x3B, 0x91, 0x35, 0x21, 0xDD, 0x4E, 0x99, - 0xB3, 0x84, 0x34, 0x41, 0xD9, 0xB7, 0xDE, 0x85, 0x2D, 0x45, 0xF5, 0x33, 0xDA, 0x94, 0xE3, 0x00, - 0x9B, 0xF2, 0x05, 0x0B, 0xD9, 0x33, 0xA3, 0x0F, 0xAB, 0xFE, 0xD5, 0xBF, 0x93, 0x87, 0xF9, 0xFF, - 0x93, 0xF7, 0xF7, 0x0F, 0x63, 0x6C, 0xFC, 0x08, 0x03, 0xC7, 0x5C, 0x04, 0xB7, 0x07, 0x08, 0x00, - 0x13, 0x77, 0x07, 0x02, 0x19, 0xE3, 0xB7, 0x87, 0x07, 0x00, 0x79, 0x55, 0xE3, 0xFD, 0xFB, 0xF0, - 0x33, 0x87, 0x9B, 0x00, 0xE3, 0xE9, 0xE7, 0xF0, 0x89, 0x47, 0x63, 0x90, 0xF9, 0x04, 0x89, 0x80, - 0x55, 0x49, 0xE3, 0x8E, 0x04, 0xEC, 0xDE, 0x85, 0x09, 0x45, 0x71, 0x3B, 0x11, 0x0B, 0x03, 0x27, - 0xCB, 0xFF, 0x91, 0x47, 0x23, 0x20, 0xE4, 0x80, 0x03, 0x07, 0x64, 0x80, 0xE3, 0x4E, 0x07, 0xFE, - 0x23, 0x03, 0x24, 0x81, 0xFD, 0x17, 0xED, 0xFB, 0xFD, 0x14, 0x91, 0x0B, 0x81, 0xC4, 0x93, 0xF7, - 0xFB, 0x0F, 0xE9, 0xFF, 0x6D, 0x3B, 0x71, 0xF5, 0xF1, 0xB5, 0x85, 0x47, 0xE3, 0x87, 0xF9, 0xF4, - 0xDE, 0x85, 0x2D, 0x45, 0x8D, 0x33, 0x13, 0x89, 0xF4, 0xFF, 0xE3, 0x8A, 0x04, 0xE8, 0x35, 0x3B, - 0x93, 0x77, 0x39, 0x00, 0x91, 0xEB, 0x83, 0x26, 0x04, 0x80, 0x03, 0x27, 0x0B, 0x00, 0x93, 0x07, - 0x4B, 0x00, 0xE3, 0x9F, 0xE6, 0xE6, 0x3E, 0x8B, 0xCA, 0x84, 0xF1, 0xBF, 0xA1, 0x47, 0x63, 0x92, - 0xF9, 0x04, 0xB5, 0x3B, 0x81, 0x44, 0x63, 0x8D, 0x0B, 0x00, 0x8D, 0x47, 0x93, 0x04, 0xC0, 0x03, - 0x63, 0x88, 0xFB, 0x00, 0x93, 0x04, 0x00, 0x05, 0x63, 0x84, 0x8B, 0x01, 0x93, 0x04, 0x40, 0x04, - 0x13, 0x75, 0xC5, 0x07, 0xE3, 0x05, 0x95, 0xE4, 0x19, 0x45, 0xC9, 0x39, 0xC5, 0x31, 0x05, 0x45, - 0xF1, 0x31, 0x26, 0x85, 0xD5, 0x39, 0x09, 0x45, 0xC5, 0x39, 0x91, 0x33, 0xE3, 0x19, 0x05, 0xE2, - 0x91, 0xBD, 0xE3, 0x86, 0x09, 0xE2, 0xF1, 0x54, 0x25, 0xB5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +// 2 +pub const CH573: [u8; 1102] = [ + 0x79, 0x71, 0x22, 0xd4, 0x4a, 0xd0, 0x52, 0xcc, 0x06, 0xd6, 0x26, 0xd2, 0x4e, 0xce, 0x56, 0xca, + 0x5a, 0xc8, 0x5e, 0xc6, 0x93, 0x77, 0x15, 0x00, 0x2a, 0x84, 0x2e, 0x8a, 0x32, 0x89, 0x9d, 0xef, + 0x93, 0x77, 0x24, 0x00, 0x99, 0xcb, 0xb7, 0x86, 0x07, 0x00, 0x01, 0x46, 0x81, 0x45, 0x05, 0x45, + 0x69, 0x22, 0x93, 0x77, 0xf5, 0x0f, 0x09, 0x45, 0x9d, 0xeb, 0x93, 0x77, 0x44, 0x00, 0x91, 0xcb, + 0x85, 0x66, 0x01, 0x46, 0xd2, 0x85, 0x05, 0x45, 0x8d, 0x2a, 0x93, 0x77, 0xf5, 0x0f, 0x11, 0x45, + 0x99, 0xef, 0x93, 0x77, 0x84, 0x01, 0x9d, 0xe7, 0x01, 0x45, 0x11, 0xa8, 0x81, 0x46, 0x01, 0x46, + 0x81, 0x45, 0x21, 0x45, 0x99, 0x2a, 0x93, 0x77, 0xf5, 0x0f, 0x05, 0x45, 0xd5, 0xdb, 0xb2, 0x50, + 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, 0xd2, 0x4a, 0x42, 0x4b, 0xb2, 0x4b, + 0x45, 0x61, 0x02, 0x90, 0xb7, 0x54, 0x00, 0x20, 0x13, 0x09, 0xf9, 0x0f, 0x93, 0x84, 0x04, 0x10, + 0x93, 0x7b, 0x84, 0x00, 0x13, 0x59, 0x89, 0x00, 0x81, 0x4a, 0x33, 0x0a, 0x9a, 0x40, 0x41, 0x88, + 0x33, 0x0b, 0x9a, 0x00, 0x63, 0x90, 0x0b, 0x02, 0x21, 0xc0, 0x93, 0x89, 0x04, 0xf0, 0x93, 0x06, + 0x00, 0x10, 0x4e, 0x86, 0xda, 0x85, 0x0d, 0x45, 0x09, 0x22, 0x13, 0x75, 0xf5, 0x0f, 0x19, 0xcd, + 0x41, 0x45, 0x75, 0xb7, 0x93, 0x06, 0x00, 0x10, 0x13, 0x86, 0x04, 0xf0, 0xda, 0x85, 0x09, 0x45, + 0xed, 0x20, 0x13, 0x75, 0xf5, 0x0f, 0x69, 0xd9, 0x21, 0x45, 0x51, 0xbf, 0x83, 0xa7, 0x09, 0x00, + 0x91, 0x09, 0xbe, 0x9a, 0xe3, 0x9c, 0x99, 0xfe, 0x7d, 0x19, 0x93, 0x84, 0x04, 0x10, 0xe3, 0x19, + 0x09, 0xfa, 0x3d, 0xd0, 0xb7, 0x67, 0x00, 0x20, 0x9c, 0x4b, 0xe3, 0x8f, 0x57, 0xf5, 0xc9, 0xb7, + 0x23, 0x03, 0x04, 0x80, 0x95, 0x47, 0x23, 0x03, 0xf4, 0x80, 0x23, 0x02, 0xa4, 0x80, 0x82, 0x80, + 0x83, 0x07, 0x64, 0x80, 0xe3, 0xce, 0x07, 0xfe, 0x23, 0x03, 0x04, 0x80, 0x82, 0x80, 0x83, 0x07, + 0x64, 0x80, 0xe3, 0xce, 0x07, 0xfe, 0x03, 0x45, 0x44, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, + 0xe3, 0xce, 0x07, 0xfe, 0x23, 0x02, 0xa4, 0x80, 0x82, 0x80, 0x41, 0x11, 0x26, 0xc4, 0x4a, 0xc2, + 0x4e, 0xc0, 0x06, 0xc6, 0x13, 0x77, 0xf5, 0x0b, 0xad, 0x47, 0xaa, 0x89, 0x2e, 0x89, 0x95, 0x44, + 0x63, 0x06, 0xf7, 0x00, 0x19, 0x45, 0x6d, 0x37, 0x65, 0x3f, 0x8d, 0x44, 0x4e, 0x85, 0x4d, 0x37, + 0xfd, 0x59, 0xfd, 0x14, 0x63, 0x98, 0x34, 0x01, 0xb2, 0x40, 0xa2, 0x44, 0x12, 0x49, 0x82, 0x49, + 0x41, 0x01, 0x82, 0x80, 0x13, 0x55, 0x09, 0x01, 0x13, 0x75, 0xf5, 0x0f, 0x45, 0x3f, 0x22, 0x09, + 0xcd, 0xb7, 0x01, 0x11, 0x26, 0xcc, 0x06, 0xce, 0xb7, 0x04, 0x08, 0x00, 0x51, 0x37, 0x15, 0x45, + 0x85, 0x3f, 0x71, 0x37, 0x69, 0x37, 0x2a, 0xc6, 0xa5, 0x3f, 0x32, 0x45, 0x93, 0x77, 0x15, 0x00, + 0x89, 0xeb, 0x13, 0x65, 0x15, 0x00, 0x13, 0x75, 0xf5, 0x0f, 0xf2, 0x40, 0xe2, 0x44, 0x05, 0x61, + 0x82, 0x80, 0xfd, 0x14, 0xe9, 0xfc, 0x01, 0x45, 0xcd, 0xbf, 0x39, 0x71, 0x26, 0xdc, 0x4a, 0xda, + 0x4e, 0xd8, 0x52, 0xd6, 0x56, 0xd4, 0x5a, 0xd2, 0x5e, 0xd0, 0x06, 0xde, 0x62, 0xce, 0x66, 0xcc, + 0xb7, 0xe7, 0x00, 0xe0, 0x7d, 0x57, 0x83, 0xaa, 0x07, 0x00, 0x22, 0xc6, 0x03, 0xaa, 0x47, 0x00, + 0x23, 0xa0, 0xe7, 0x18, 0x23, 0xa2, 0xe7, 0x18, 0xb7, 0x17, 0x00, 0x40, 0x13, 0x07, 0x70, 0x05, + 0x23, 0x80, 0xe7, 0x04, 0x13, 0x07, 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x04, 0x83, 0xc7, 0x47, 0x04, + 0x13, 0x09, 0x75, 0xff, 0xb6, 0x84, 0xe2, 0x07, 0x13, 0x79, 0xf9, 0x0f, 0x85, 0x46, 0xaa, 0x89, + 0xae, 0x8b, 0x32, 0x8b, 0x37, 0x24, 0x00, 0x40, 0xe1, 0x87, 0x01, 0x57, 0x63, 0xfa, 0x26, 0x01, + 0x63, 0x08, 0xd5, 0x00, 0x89, 0x46, 0x13, 0x07, 0x00, 0x02, 0x63, 0x13, 0xd5, 0x00, 0x01, 0x57, + 0xd9, 0x8f, 0x93, 0xf7, 0xf7, 0x0f, 0xb7, 0x1c, 0x00, 0x40, 0x23, 0x82, 0xfc, 0x04, 0x11, 0x47, + 0x23, 0x03, 0xe4, 0x80, 0x13, 0x05, 0xf0, 0x0f, 0x65, 0x3d, 0x09, 0x4c, 0xd1, 0x35, 0x63, 0x69, + 0x2c, 0x11, 0xb7, 0x07, 0x07, 0x00, 0xbe, 0x9b, 0x37, 0x87, 0x07, 0x00, 0x79, 0x55, 0x63, 0xfe, + 0xeb, 0x02, 0xb3, 0x87, 0x9b, 0x00, 0x63, 0x6a, 0xf7, 0x02, 0xa9, 0x47, 0x63, 0x99, 0xf9, 0x06, + 0x89, 0xe4, 0x81, 0x44, 0x71, 0x3d, 0x26, 0x85, 0x0d, 0xa0, 0xde, 0x85, 0x09, 0x45, 0x75, 0x3d, + 0x05, 0x0b, 0x03, 0x45, 0xfb, 0xff, 0xfd, 0x14, 0x85, 0x0b, 0x4d, 0x35, 0x81, 0xc4, 0x93, 0xf7, + 0xfb, 0x0f, 0xfd, 0xf7, 0xfd, 0x35, 0x69, 0xfd, 0x7d, 0x55, 0xb7, 0x17, 0x00, 0x40, 0x13, 0x07, + 0x70, 0x05, 0x23, 0x80, 0xe7, 0x04, 0x13, 0x07, 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x04, 0x03, 0xc7, + 0x47, 0x04, 0x41, 0x8b, 0x23, 0x82, 0xe7, 0x04, 0xf2, 0x50, 0xb7, 0xe7, 0x00, 0xe0, 0x23, 0xa0, + 0x57, 0x11, 0x23, 0xa2, 0x47, 0x11, 0xe2, 0x54, 0x32, 0x44, 0x52, 0x59, 0xc2, 0x59, 0x32, 0x5a, + 0xa2, 0x5a, 0x12, 0x5b, 0x82, 0x5b, 0x72, 0x4c, 0xe2, 0x4c, 0x21, 0x61, 0x82, 0x80, 0xa5, 0x47, + 0x63, 0x95, 0xf9, 0x06, 0x85, 0x69, 0x13, 0x09, 0xf0, 0x0f, 0xb3, 0x06, 0x99, 0x00, 0xb3, 0xf4, + 0x2b, 0x01, 0xb6, 0x94, 0x13, 0x49, 0xf9, 0xff, 0xb3, 0x74, 0x99, 0x00, 0x41, 0x6b, 0x33, 0x79, + 0x79, 0x01, 0x85, 0x6b, 0x93, 0x87, 0xf9, 0xff, 0xb3, 0xf7, 0x27, 0x01, 0x99, 0xe3, 0x63, 0xfc, + 0x34, 0x01, 0x93, 0xd9, 0x49, 0x00, 0xc1, 0x47, 0xe3, 0xe6, 0x37, 0xff, 0x99, 0xbf, 0x05, 0x69, + 0xc1, 0x69, 0x7d, 0x19, 0xd9, 0xb7, 0x13, 0x05, 0x80, 0x0d, 0x63, 0x88, 0x69, 0x01, 0x13, 0x05, + 0x00, 0x02, 0x63, 0x84, 0x79, 0x01, 0x13, 0x05, 0x10, 0x08, 0xca, 0x85, 0xfd, 0x3b, 0x91, 0x35, + 0x21, 0xdd, 0x4e, 0x99, 0xb3, 0x84, 0x34, 0x41, 0xd9, 0xb7, 0xde, 0x85, 0x2d, 0x45, 0xf5, 0x33, + 0xda, 0x94, 0xe3, 0x00, 0x9b, 0xf2, 0x05, 0x0b, 0xd9, 0x33, 0xa3, 0x0f, 0xab, 0xfe, 0xd5, 0xbf, + 0x93, 0x87, 0xf9, 0xff, 0x93, 0xf7, 0xf7, 0x0f, 0x63, 0x6c, 0xfc, 0x08, 0x03, 0xc7, 0x5c, 0x04, + 0xb7, 0x07, 0x08, 0x00, 0x13, 0x77, 0x07, 0x02, 0x19, 0xe3, 0xb7, 0x87, 0x07, 0x00, 0x79, 0x55, + 0xe3, 0xfd, 0xfb, 0xf0, 0x33, 0x87, 0x9b, 0x00, 0xe3, 0xe9, 0xe7, 0xf0, 0x89, 0x47, 0x63, 0x90, + 0xf9, 0x04, 0x89, 0x80, 0x55, 0x49, 0xe3, 0x8e, 0x04, 0xec, 0xde, 0x85, 0x09, 0x45, 0x71, 0x3b, + 0x11, 0x0b, 0x03, 0x27, 0xcb, 0xff, 0x91, 0x47, 0x23, 0x20, 0xe4, 0x80, 0x03, 0x07, 0x64, 0x80, + 0xe3, 0x4e, 0x07, 0xfe, 0x23, 0x03, 0x24, 0x81, 0xfd, 0x17, 0xed, 0xfb, 0xfd, 0x14, 0x91, 0x0b, + 0x81, 0xc4, 0x93, 0xf7, 0xfb, 0x0f, 0xe9, 0xff, 0x6d, 0x3b, 0x71, 0xf5, 0xf1, 0xb5, 0x85, 0x47, + 0xe3, 0x87, 0xf9, 0xf4, 0xde, 0x85, 0x2d, 0x45, 0x8d, 0x33, 0x13, 0x89, 0xf4, 0xff, 0xe3, 0x8a, + 0x04, 0xe8, 0x35, 0x3b, 0x93, 0x77, 0x39, 0x00, 0x91, 0xeb, 0x83, 0x26, 0x04, 0x80, 0x03, 0x27, + 0x0b, 0x00, 0x93, 0x07, 0x4b, 0x00, 0xe3, 0x9f, 0xe6, 0xe6, 0x3e, 0x8b, 0xca, 0x84, 0xf1, 0xbf, + 0xa1, 0x47, 0x63, 0x92, 0xf9, 0x04, 0xb5, 0x3b, 0x81, 0x44, 0x63, 0x8d, 0x0b, 0x00, 0x8d, 0x47, + 0x93, 0x04, 0xc0, 0x03, 0x63, 0x88, 0xfb, 0x00, 0x93, 0x04, 0x00, 0x05, 0x63, 0x84, 0x8b, 0x01, + 0x93, 0x04, 0x40, 0x04, 0x13, 0x75, 0xc5, 0x07, 0xe3, 0x05, 0x95, 0xe4, 0x19, 0x45, 0xc9, 0x39, + 0xc5, 0x31, 0x05, 0x45, 0xf1, 0x31, 0x26, 0x85, 0xd5, 0x39, 0x09, 0x45, 0xc5, 0x39, 0x91, 0x33, + 0xe3, 0x19, 0x05, 0xe2, 0x91, 0xbd, 0xe3, 0x86, 0x09, 0xe2, 0xf1, 0x54, 0x25, 0xb5, ]; -/// For CH32V003. It's a riscv32ec core, not supported by Rust yet. -pub const CH32V003: [u8; 512] = [ - 0x21, 0x11, 0x22, 0xca, 0x26, 0xc8, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, - 0xb7, 0x27, 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, - 0xb7, 0x9a, 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, - 0x02, 0x40, 0x98, 0x4b, 0xad, 0x66, 0x37, 0x33, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, - 0x98, 0x4b, 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, - 0x63, 0x16, 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, - 0x93, 0x07, 0xf6, 0x03, 0x99, 0x83, 0x2e, 0xc0, 0x2d, 0x63, 0x81, 0x76, 0x3e, 0xc4, 0xb7, 0x32, - 0x00, 0x40, 0xb7, 0x27, 0x02, 0x40, 0x13, 0x03, 0xa3, 0xaa, 0xfd, 0x16, 0x98, 0x4b, 0xb7, 0x03, - 0x02, 0x00, 0x33, 0x67, 0x77, 0x00, 0x98, 0xcb, 0x02, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, - 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, - 0x02, 0x47, 0x13, 0x07, 0x07, 0x04, 0x3a, 0xc0, 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, 0x79, 0xf7, - 0x93, 0x77, 0x85, 0x00, 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x03, 0x2e, 0xc0, 0x99, 0x83, 0x37, 0x27, - 0x02, 0x40, 0x3e, 0xc4, 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x63, 0xd5, 0x8f, 0x1c, 0xcb, 0x37, 0x07, - 0x00, 0x20, 0x13, 0x07, 0x07, 0x20, 0xb7, 0x27, 0x02, 0x40, 0xb7, 0x03, 0x08, 0x00, 0xb7, 0x32, - 0x00, 0x40, 0x13, 0x03, 0xa3, 0xaa, 0x94, 0x4b, 0xb3, 0xe6, 0x76, 0x00, 0x94, 0xcb, 0xd4, 0x47, - 0x85, 0x8a, 0xf5, 0xfe, 0x82, 0x46, 0xba, 0x84, 0x37, 0x04, 0x04, 0x00, 0x36, 0xc2, 0xc1, 0x46, - 0x36, 0xc6, 0x92, 0x46, 0x84, 0x40, 0x11, 0x07, 0x84, 0xc2, 0x94, 0x4b, 0xc1, 0x8e, 0x94, 0xcb, - 0xd4, 0x47, 0x85, 0x8a, 0xb1, 0xea, 0x92, 0x46, 0xba, 0x84, 0x91, 0x06, 0x36, 0xc2, 0xb2, 0x46, - 0xfd, 0x16, 0x36, 0xc6, 0xf9, 0xfe, 0x82, 0x46, 0xd4, 0xcb, 0x94, 0x4b, 0x93, 0xe6, 0x06, 0x04, - 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0x85, 0xee, 0xd4, 0x47, 0xc1, 0x8a, 0x85, 0xce, 0xd8, 0x47, - 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, 0x21, 0x45, - 0x75, 0x8f, 0x98, 0xcb, 0x52, 0x44, 0xc2, 0x44, 0x61, 0x01, 0x02, 0x90, 0x23, 0x20, 0xd3, 0x00, - 0xf5, 0xb5, 0x23, 0xa0, 0x62, 0x00, 0x3d, 0xb7, 0x23, 0xa0, 0x62, 0x00, 0x55, 0xb7, 0x23, 0xa0, - 0x62, 0x00, 0xc1, 0xb7, 0x82, 0x46, 0x93, 0x86, 0x06, 0x04, 0x36, 0xc0, 0xa2, 0x46, 0xfd, 0x16, - 0x36, 0xc4, 0xb5, 0xf2, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, 0x98, 0xcb, - 0x41, 0x89, 0x05, 0xcd, 0x2e, 0xc0, 0x0d, 0x06, 0x02, 0xc4, 0x09, 0x82, 0xb7, 0x07, 0x00, 0x20, - 0x32, 0xc6, 0x93, 0x87, 0x07, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xa2, 0x47, 0x82, 0x46, - 0x8a, 0x07, 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x1c, 0xf7, 0x00, 0xa2, 0x47, 0x85, 0x07, 0x3e, 0xc4, - 0xa2, 0x46, 0x32, 0x47, 0xb2, 0x87, 0xe3, 0xe0, 0xe6, 0xfe, 0x01, 0x45, 0x61, 0xb7, 0x41, 0x45, - 0x51, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +// 7, 11 +pub const CH583: [u8; 1326] = [ + 0x79, 0x71, 0x22, 0xd4, 0x4a, 0xd0, 0x56, 0xca, 0x06, 0xd6, 0x26, 0xd2, 0x4e, 0xce, 0x52, 0xcc, + 0x5a, 0xc8, 0x5e, 0xc6, 0x62, 0xc4, 0x93, 0x77, 0x15, 0x00, 0x2a, 0x84, 0xae, 0x8a, 0x32, 0x89, + 0xc1, 0xe3, 0x93, 0x77, 0x24, 0x00, 0x99, 0xcb, 0xb7, 0x86, 0x07, 0x00, 0x01, 0x46, 0x81, 0x45, + 0x05, 0x45, 0x49, 0x2a, 0x93, 0x77, 0xf5, 0x0f, 0x09, 0x45, 0xa5, 0xef, 0x93, 0x77, 0x44, 0x00, + 0x91, 0xcb, 0x85, 0x66, 0x01, 0x46, 0xd6, 0x85, 0x05, 0x45, 0xad, 0x2a, 0x93, 0x77, 0xf5, 0x0f, + 0x11, 0x45, 0xa5, 0xe3, 0x93, 0x77, 0x84, 0x01, 0x01, 0x4a, 0xd9, 0xcf, 0xb7, 0x54, 0x00, 0x20, + 0x13, 0x09, 0xf9, 0x0f, 0x93, 0x84, 0x04, 0x10, 0x13, 0x59, 0x89, 0x00, 0x01, 0x4a, 0xb3, 0x8a, + 0x9a, 0x40, 0x93, 0x7b, 0x84, 0x00, 0x13, 0x7c, 0x04, 0x01, 0x33, 0x8b, 0x9a, 0x00, 0x63, 0x96, + 0x0b, 0x04, 0x63, 0x06, 0x0c, 0x06, 0x93, 0x89, 0x04, 0xf0, 0x93, 0x06, 0x00, 0x10, 0x4e, 0x86, + 0xda, 0x85, 0x0d, 0x45, 0x05, 0x2a, 0x13, 0x75, 0xf5, 0x0f, 0x21, 0xc5, 0x41, 0x45, 0x11, 0xa8, + 0x81, 0x46, 0x01, 0x46, 0x81, 0x45, 0x21, 0x45, 0x31, 0x2a, 0x93, 0x77, 0xf5, 0x0f, 0x05, 0x45, + 0xad, 0xdb, 0xb2, 0x50, 0x22, 0x54, 0x92, 0x54, 0x02, 0x59, 0xf2, 0x49, 0x62, 0x4a, 0xd2, 0x4a, + 0x42, 0x4b, 0xb2, 0x4b, 0x22, 0x4c, 0x45, 0x61, 0x02, 0x90, 0x93, 0x06, 0x00, 0x10, 0x13, 0x86, + 0x04, 0xf0, 0xda, 0x85, 0x09, 0x45, 0xfd, 0x20, 0x13, 0x75, 0xf5, 0x0f, 0x5d, 0xd1, 0x21, 0x45, + 0xc9, 0xbf, 0x83, 0xa7, 0x09, 0x00, 0x91, 0x09, 0x3e, 0x9a, 0xe3, 0x9c, 0x34, 0xff, 0x7d, 0x19, + 0x93, 0x84, 0x04, 0x10, 0xe3, 0x13, 0x09, 0xf8, 0x41, 0x88, 0x01, 0x45, 0x5d, 0xd8, 0xb7, 0x67, + 0x00, 0x20, 0x9c, 0x4b, 0xe3, 0x87, 0x47, 0xfb, 0x51, 0xbf, 0x23, 0x03, 0x04, 0x80, 0x95, 0x47, + 0x23, 0x03, 0xf4, 0x80, 0x23, 0x02, 0xa4, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, 0xe3, 0xce, + 0x07, 0xfe, 0x23, 0x03, 0x04, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, 0xe3, 0xce, 0x07, 0xfe, + 0x03, 0x45, 0x44, 0x80, 0x82, 0x80, 0x83, 0x07, 0x64, 0x80, 0xe3, 0xce, 0x07, 0xfe, 0x23, 0x02, + 0xa4, 0x80, 0x82, 0x80, 0x41, 0x11, 0x26, 0xc4, 0x4a, 0xc2, 0x4e, 0xc0, 0x06, 0xc6, 0x13, 0x77, + 0xf5, 0x0b, 0xad, 0x47, 0xaa, 0x89, 0x2e, 0x89, 0x95, 0x44, 0x63, 0x06, 0xf7, 0x00, 0x19, 0x45, + 0x6d, 0x37, 0x65, 0x3f, 0x8d, 0x44, 0x4e, 0x85, 0x4d, 0x37, 0xfd, 0x59, 0xfd, 0x14, 0x63, 0x98, + 0x34, 0x01, 0xb2, 0x40, 0xa2, 0x44, 0x12, 0x49, 0x82, 0x49, 0x41, 0x01, 0x82, 0x80, 0x13, 0x55, + 0x09, 0x01, 0x13, 0x75, 0xf5, 0x0f, 0x45, 0x3f, 0x22, 0x09, 0xcd, 0xb7, 0x01, 0x11, 0x26, 0xcc, + 0x06, 0xce, 0xb7, 0x04, 0x08, 0x00, 0x51, 0x37, 0x15, 0x45, 0x85, 0x3f, 0x71, 0x37, 0x69, 0x37, + 0x2a, 0xc6, 0xa5, 0x3f, 0x32, 0x45, 0x93, 0x77, 0x15, 0x00, 0x89, 0xeb, 0x13, 0x65, 0x15, 0x00, + 0x13, 0x75, 0xf5, 0x0f, 0xf2, 0x40, 0xe2, 0x44, 0x05, 0x61, 0x82, 0x80, 0xfd, 0x14, 0xe9, 0xfc, + 0x01, 0x45, 0xcd, 0xbf, 0x39, 0x71, 0x26, 0xdc, 0x4a, 0xda, 0x4e, 0xd8, 0x52, 0xd6, 0x56, 0xd4, + 0x5a, 0xd2, 0x5e, 0xd0, 0x06, 0xde, 0x62, 0xce, 0x66, 0xcc, 0xb7, 0xe7, 0x00, 0xe0, 0x7d, 0x57, + 0x83, 0xaa, 0x07, 0x00, 0x22, 0xc6, 0x03, 0xaa, 0x47, 0x00, 0x23, 0xa0, 0xe7, 0x18, 0x23, 0xa2, + 0xe7, 0x18, 0xb7, 0x17, 0x00, 0x40, 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, 0xe7, 0x04, 0x13, 0x07, + 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x04, 0x83, 0xc7, 0x47, 0x04, 0x93, 0x0b, 0x75, 0xff, 0xb6, 0x84, + 0xe2, 0x07, 0x93, 0xfb, 0xfb, 0x0f, 0x85, 0x46, 0xaa, 0x89, 0x2e, 0x8b, 0x32, 0x89, 0x37, 0x24, + 0x00, 0x40, 0xe1, 0x87, 0x01, 0x57, 0x63, 0xfa, 0x76, 0x01, 0x63, 0x08, 0xd5, 0x00, 0x89, 0x46, + 0x13, 0x07, 0x00, 0x02, 0x63, 0x13, 0xd5, 0x00, 0x01, 0x57, 0xd9, 0x8f, 0x93, 0xf7, 0xf7, 0x0f, + 0xb7, 0x1c, 0x00, 0x40, 0x23, 0x82, 0xfc, 0x04, 0x11, 0x47, 0x23, 0x03, 0xe4, 0x80, 0x13, 0x05, + 0xf0, 0x0f, 0x65, 0x3d, 0x09, 0x4c, 0xd1, 0x35, 0x63, 0x6d, 0x7c, 0x11, 0xb7, 0x05, 0x07, 0x00, + 0xda, 0x95, 0x37, 0x87, 0x07, 0x00, 0x79, 0x55, 0x63, 0xf2, 0xe5, 0x04, 0xb3, 0x87, 0x95, 0x00, + 0x63, 0x6e, 0xf7, 0x02, 0x37, 0x0b, 0x08, 0x00, 0xa9, 0x47, 0x33, 0xeb, 0x65, 0x01, 0x63, 0x99, + 0xf9, 0x06, 0x89, 0xe4, 0x81, 0x44, 0x51, 0x3d, 0x26, 0x85, 0x0d, 0xa0, 0xda, 0x85, 0x09, 0x45, + 0x55, 0x3d, 0x05, 0x09, 0x03, 0x45, 0xf9, 0xff, 0xfd, 0x14, 0x05, 0x0b, 0x69, 0x3d, 0x81, 0xc4, + 0x93, 0x77, 0xfb, 0x0f, 0xfd, 0xf7, 0xdd, 0x35, 0x69, 0xfd, 0x7d, 0x55, 0xb7, 0x17, 0x00, 0x40, + 0x13, 0x07, 0x70, 0x05, 0x23, 0x80, 0xe7, 0x04, 0x13, 0x07, 0x80, 0xfa, 0x23, 0x80, 0xe7, 0x04, + 0x03, 0xc7, 0x47, 0x04, 0x41, 0x8b, 0x23, 0x82, 0xe7, 0x04, 0xf2, 0x50, 0xb7, 0xe7, 0x00, 0xe0, + 0x23, 0xa0, 0x57, 0x11, 0x23, 0xa2, 0x47, 0x11, 0xe2, 0x54, 0x32, 0x44, 0x52, 0x59, 0xc2, 0x59, + 0x32, 0x5a, 0xa2, 0x5a, 0x12, 0x5b, 0x82, 0x5b, 0x72, 0x4c, 0xe2, 0x4c, 0x21, 0x61, 0x82, 0x80, + 0xa5, 0x47, 0x63, 0x95, 0xf9, 0x06, 0x85, 0x69, 0x13, 0x09, 0xf0, 0x0f, 0xb3, 0x06, 0x99, 0x00, + 0xb3, 0x74, 0x2b, 0x01, 0xb6, 0x94, 0x13, 0x49, 0xf9, 0xff, 0xb3, 0x74, 0x99, 0x00, 0x85, 0x6b, + 0x33, 0x79, 0x69, 0x01, 0x41, 0x6b, 0x93, 0x87, 0xf9, 0xff, 0xb3, 0xf7, 0x27, 0x01, 0x99, 0xe3, + 0x63, 0xfc, 0x34, 0x01, 0x93, 0xd9, 0x49, 0x00, 0xc1, 0x47, 0xe3, 0xe6, 0x37, 0xff, 0x99, 0xbf, + 0x05, 0x69, 0xc1, 0x69, 0x7d, 0x19, 0xd9, 0xb7, 0x13, 0x05, 0x80, 0x0d, 0x63, 0x88, 0x69, 0x01, + 0x13, 0x05, 0x00, 0x02, 0x63, 0x84, 0x79, 0x01, 0x13, 0x05, 0x10, 0x08, 0xca, 0x85, 0xdd, 0x3b, + 0x35, 0x3d, 0x21, 0xdd, 0x4e, 0x99, 0xb3, 0x84, 0x34, 0x41, 0xd9, 0xb7, 0xda, 0x85, 0x2d, 0x45, + 0xd5, 0x33, 0xca, 0x94, 0xe3, 0x00, 0x99, 0xf2, 0x05, 0x09, 0x7d, 0x3b, 0xa3, 0x0f, 0xa9, 0xfe, + 0xd5, 0xbf, 0x93, 0x87, 0xf9, 0xff, 0x93, 0xf7, 0xf7, 0x0f, 0x63, 0x61, 0xfc, 0x0c, 0x83, 0xc7, + 0x1c, 0x04, 0x13, 0x07, 0x30, 0x08, 0x63, 0x1f, 0xf7, 0x04, 0x37, 0x07, 0x08, 0x00, 0x63, 0x6b, + 0xeb, 0x04, 0xb3, 0x07, 0x9b, 0x00, 0xb7, 0x06, 0x10, 0x00, 0x63, 0xf5, 0xd7, 0x04, 0x33, 0x4b, + 0xeb, 0x00, 0x89, 0x47, 0x63, 0x93, 0xf9, 0x06, 0x89, 0x80, 0xd5, 0x49, 0xe3, 0x8c, 0x04, 0xec, + 0xda, 0x85, 0x09, 0x45, 0x41, 0x3b, 0x11, 0x09, 0x03, 0x27, 0xc9, 0xff, 0x91, 0x47, 0x23, 0x20, + 0xe4, 0x80, 0x03, 0x07, 0x64, 0x80, 0xe3, 0x4e, 0x07, 0xfe, 0x23, 0x03, 0x34, 0x81, 0xfd, 0x17, + 0xed, 0xfb, 0xfd, 0x14, 0x11, 0x0b, 0x81, 0xc4, 0x93, 0x77, 0xfb, 0x0f, 0xe9, 0xff, 0x7d, 0x33, + 0x71, 0xf5, 0xe1, 0xb5, 0xb7, 0x17, 0x00, 0x40, 0x03, 0xc7, 0x57, 0x04, 0xb7, 0x07, 0x08, 0x00, + 0x13, 0x77, 0x07, 0x02, 0x19, 0xe3, 0xb7, 0x87, 0x07, 0x00, 0x79, 0x55, 0xe3, 0x78, 0xfb, 0xea, + 0x33, 0x07, 0x9b, 0x00, 0xe3, 0xff, 0xe7, 0xf8, 0x55, 0xb5, 0x85, 0x47, 0xe3, 0x82, 0xf9, 0xf2, + 0xda, 0x85, 0x2d, 0x45, 0x05, 0x3b, 0x93, 0x89, 0xf4, 0xff, 0xe3, 0x85, 0x04, 0xe6, 0x29, 0x33, + 0x93, 0xf7, 0x39, 0x00, 0x91, 0xeb, 0x83, 0x26, 0x04, 0x80, 0x03, 0x27, 0x09, 0x00, 0x93, 0x07, + 0x49, 0x00, 0xe3, 0x9a, 0xe6, 0xe4, 0x3e, 0x89, 0xce, 0x84, 0xf1, 0xbf, 0xb5, 0x47, 0x63, 0x96, + 0xf9, 0x00, 0x13, 0x05, 0x90, 0x0b, 0xd1, 0x31, 0x35, 0xbd, 0xb1, 0x47, 0x13, 0x05, 0xb0, 0x0a, + 0xe3, 0x8b, 0xf9, 0xfe, 0x99, 0x47, 0x63, 0x91, 0xf9, 0x04, 0xb7, 0x05, 0x08, 0x00, 0xb3, 0x65, + 0xbb, 0x00, 0x2d, 0x45, 0xc5, 0x31, 0x81, 0x44, 0x8d, 0x4b, 0xa1, 0x49, 0x75, 0x39, 0x63, 0x96, + 0x74, 0x01, 0x83, 0x27, 0x04, 0x80, 0x23, 0x20, 0xf9, 0x00, 0x85, 0x04, 0xe3, 0x98, 0x34, 0xff, + 0x83, 0x27, 0x04, 0x80, 0x13, 0x17, 0x2b, 0x01, 0x63, 0x55, 0x07, 0x00, 0x23, 0x12, 0xf9, 0x00, + 0xd5, 0xbb, 0x23, 0x22, 0xf9, 0x00, 0xfd, 0xb3, 0x9d, 0x47, 0x63, 0x99, 0xf9, 0x02, 0x81, 0x45, + 0x13, 0x05, 0xb0, 0x04, 0x45, 0x31, 0xbd, 0x44, 0x23, 0x20, 0x09, 0x00, 0x23, 0x22, 0x09, 0x00, + 0xfd, 0x59, 0x9d, 0x39, 0x93, 0xf7, 0x74, 0x00, 0xca, 0x97, 0x03, 0xc7, 0x07, 0x00, 0xfd, 0x14, + 0x39, 0x8d, 0x23, 0x80, 0xa7, 0x00, 0xe3, 0x96, 0x34, 0xff, 0x6d, 0xbb, 0xa1, 0x47, 0x63, 0x92, + 0xf9, 0x04, 0x6d, 0x39, 0x81, 0x44, 0x63, 0x0d, 0x0b, 0x00, 0x8d, 0x47, 0x93, 0x04, 0xc0, 0x03, + 0x63, 0x08, 0xfb, 0x00, 0x93, 0x04, 0x00, 0x05, 0x63, 0x04, 0x8b, 0x01, 0x93, 0x04, 0x40, 0x04, + 0x13, 0x75, 0xc5, 0x07, 0xe3, 0x08, 0x95, 0xd8, 0x19, 0x45, 0x01, 0x39, 0x39, 0x39, 0x05, 0x45, + 0x29, 0x31, 0x26, 0x85, 0x0d, 0x39, 0x09, 0x45, 0x3d, 0x31, 0x49, 0x31, 0xe3, 0x1c, 0x05, 0xd6, + 0x69, 0xbb, 0x91, 0x47, 0x63, 0x99, 0xf9, 0x00, 0x13, 0x05, 0x60, 0x06, 0xfd, 0x36, 0xf5, 0x3e, + 0x13, 0x05, 0x90, 0x09, 0x0d, 0xb7, 0xe3, 0x8f, 0x09, 0xd4, 0xf1, 0x54, 0xa9, 0xbb, ]; -pub const UNKNOWN_10: [u8; 0x300] = [ - 0x31, 0x11, 0x22, 0xc8, 0x26, 0xc6, 0x93, 0x77, 0x25, 0x00, 0xb5, 0xc3, 0xb7, 0x17, 0x00, 0x40, - 0x13, 0x07, 0xf0, 0x04, 0x23, 0x8f, 0xe7, 0x02, 0x7d, 0x57, 0xa3, 0x8e, 0xe7, 0x02, 0xa3, 0x8d, - 0x07, 0x02, 0x79, 0x53, 0x23, 0x8e, 0x67, 0x02, 0xa3, 0x8f, 0xe7, 0x02, 0xf5, 0x56, 0x23, 0x8e, - 0xd7, 0x02, 0x99, 0x42, 0xa3, 0x8f, 0x57, 0x02, 0x23, 0x8e, 0x67, 0x02, 0xa3, 0x8f, 0xe7, 0x02, - 0x23, 0x8e, 0xd7, 0x02, 0x93, 0x02, 0x70, 0xfc, 0xa3, 0x8f, 0x57, 0x02, 0x23, 0x8e, 0x67, 0x02, - 0xa3, 0x8f, 0xe7, 0x02, 0x23, 0x8e, 0xd7, 0x02, 0x15, 0x47, 0xa3, 0x8f, 0xe7, 0x02, 0x03, 0xc7, - 0xf7, 0x03, 0x05, 0x8b, 0x6d, 0xff, 0x23, 0x8f, 0x07, 0x02, 0xa3, 0x8e, 0x07, 0x02, 0x93, 0x77, - 0x45, 0x00, 0xad, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0xa1, 0x83, 0x2e, 0xc0, 0x3e, 0xc2, 0xb7, 0x17, - 0x00, 0x40, 0x93, 0x86, 0xc7, 0x03, 0xf9, 0x53, 0x7d, 0x53, 0xf5, 0x52, 0x13, 0x04, 0x10, 0xf8, - 0x23, 0x80, 0x76, 0x00, 0xa3, 0x8f, 0x67, 0x02, 0x23, 0x80, 0x56, 0x00, 0xa3, 0x8f, 0x87, 0x02, - 0x02, 0x47, 0x41, 0x83, 0x13, 0x77, 0xf7, 0x0f, 0xa3, 0x8f, 0xe7, 0x02, 0x02, 0x47, 0x21, 0x83, - 0x13, 0x77, 0xf7, 0x0f, 0xa3, 0x8f, 0xe7, 0x02, 0x02, 0x47, 0x13, 0x77, 0xf7, 0x0f, 0xa3, 0x8f, - 0xe7, 0x02, 0x23, 0x80, 0x76, 0x00, 0xa3, 0x8f, 0x67, 0x02, 0x23, 0x80, 0x56, 0x00, 0x15, 0x47, - 0xa3, 0x8f, 0xe7, 0x02, 0x03, 0xc7, 0xf7, 0x03, 0x05, 0x8b, 0x6d, 0xff, 0x02, 0x47, 0x13, 0x07, - 0x07, 0x10, 0x3a, 0xc0, 0x12, 0x47, 0x7d, 0x17, 0x3a, 0xc2, 0x5d, 0xf3, 0x93, 0x77, 0x85, 0x00, - 0xdd, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0xa1, 0x83, 0x2e, 0xc0, 0x3e, 0xc2, 0xb7, 0x17, 0x00, 0x40, - 0x37, 0x17, 0x00, 0x20, 0x13, 0x84, 0xd7, 0x03, 0xfd, 0x52, 0xf9, 0x56, 0x75, 0x53, 0x93, 0x04, - 0xf0, 0x04, 0x23, 0x8f, 0x97, 0x02, 0x23, 0x00, 0x54, 0x00, 0xa3, 0x8d, 0x07, 0x02, 0x23, 0x8e, - 0xd7, 0x02, 0xa3, 0x8f, 0x57, 0x02, 0x23, 0x8e, 0x67, 0x02, 0x99, 0x44, 0xa3, 0x8f, 0x97, 0x02, - 0x23, 0x8e, 0xd7, 0x02, 0xa3, 0x8f, 0x57, 0x02, 0x23, 0x8e, 0x67, 0x02, 0x89, 0x43, 0xa3, 0x8f, - 0x77, 0x02, 0x82, 0x43, 0x93, 0x04, 0xf0, 0x0f, 0x93, 0xd3, 0x03, 0x01, 0x93, 0xf3, 0xf3, 0x0f, - 0xa3, 0x8f, 0x77, 0x02, 0x82, 0x43, 0x93, 0xd3, 0x83, 0x00, 0x93, 0xf3, 0xf3, 0x0f, 0xa3, 0x8f, - 0x77, 0x02, 0x82, 0x43, 0x93, 0xf3, 0xf3, 0x0f, 0xa3, 0x8f, 0x77, 0x02, 0x02, 0xc4, 0xa2, 0x43, - 0x63, 0xf8, 0x74, 0x10, 0x23, 0x8e, 0xd7, 0x02, 0xfd, 0x54, 0xa3, 0x8f, 0x97, 0x02, 0x23, 0x8e, - 0x67, 0x02, 0x95, 0x43, 0xa3, 0x8f, 0x77, 0x02, 0x83, 0xc3, 0xf7, 0x03, 0x93, 0xf3, 0x13, 0x00, - 0xe3, 0x9c, 0x03, 0xfe, 0x23, 0x8f, 0x07, 0x02, 0x23, 0x00, 0x04, 0x00, 0x82, 0x43, 0x93, 0x83, - 0x03, 0x10, 0x1e, 0xc0, 0x92, 0x43, 0xfd, 0x13, 0x1e, 0xc2, 0xe3, 0x92, 0x03, 0xf6, 0x41, 0x89, - 0x61, 0xc1, 0x13, 0x06, 0xf6, 0x0f, 0x2e, 0xc0, 0x21, 0x82, 0xb7, 0x17, 0x00, 0x40, 0x32, 0xc2, - 0xb7, 0x16, 0x00, 0x20, 0x13, 0x85, 0xe7, 0x03, 0x93, 0x02, 0xf0, 0x04, 0x7d, 0x57, 0x79, 0x56, - 0xf5, 0x55, 0x23, 0x00, 0x55, 0x00, 0xa3, 0x8e, 0xe7, 0x02, 0xa3, 0x8d, 0x07, 0x02, 0x23, 0x8e, - 0xc7, 0x02, 0xa3, 0x8f, 0xe7, 0x02, 0x23, 0x8e, 0xb7, 0x02, 0x19, 0x44, 0xa3, 0x8f, 0x87, 0x02, - 0x23, 0x8e, 0xc7, 0x02, 0xa3, 0x8f, 0xe7, 0x02, 0x23, 0x8e, 0xb7, 0x02, 0x2d, 0x44, 0xa3, 0x8f, - 0x87, 0x02, 0x02, 0x43, 0x93, 0x03, 0xf0, 0x0f, 0x13, 0x53, 0x03, 0x01, 0x13, 0x73, 0xf3, 0x0f, - 0xa3, 0x8f, 0x67, 0x02, 0x02, 0x43, 0x13, 0x53, 0x83, 0x00, 0x13, 0x73, 0xf3, 0x0f, 0xa3, 0x8f, - 0x67, 0x02, 0x02, 0x43, 0x13, 0x73, 0xf3, 0x0f, 0xa3, 0x8f, 0x67, 0x02, 0xa3, 0x8f, 0x07, 0x02, - 0x02, 0xc4, 0x22, 0x43, 0x63, 0xf1, 0x63, 0x06, 0x23, 0x8e, 0xc7, 0x02, 0xa3, 0x8f, 0xe7, 0x02, - 0x23, 0x8e, 0xb7, 0x02, 0x15, 0x43, 0xa3, 0x8f, 0x67, 0x02, 0x03, 0xc3, 0xf7, 0x03, 0x13, 0x73, - 0x13, 0x00, 0xe3, 0x1c, 0x03, 0xfe, 0x23, 0x00, 0x05, 0x00, 0xa3, 0x8e, 0x07, 0x02, 0x02, 0x43, - 0x13, 0x03, 0x03, 0x10, 0x1a, 0xc0, 0x12, 0x43, 0x7d, 0x13, 0x1a, 0xc2, 0xe3, 0x13, 0x03, 0xf6, - 0xb7, 0x17, 0x00, 0x40, 0x23, 0x8f, 0x07, 0x02, 0xa3, 0x8e, 0x07, 0x02, 0x01, 0x45, 0xb9, 0xa8, - 0x83, 0x43, 0x07, 0x00, 0x05, 0x07, 0x93, 0xf3, 0xf3, 0x0f, 0xa3, 0x8f, 0x77, 0x02, 0xa2, 0x43, - 0x85, 0x03, 0x1e, 0xc4, 0xe9, 0xbd, 0x83, 0xc4, 0xf7, 0x03, 0x13, 0x84, 0x16, 0x00, 0x83, 0xc6, - 0x06, 0x00, 0x13, 0x83, 0xf7, 0x03, 0x93, 0xf6, 0xf6, 0x0f, 0x63, 0x8d, 0x96, 0x02, 0x79, 0x57, - 0x23, 0x8e, 0xe7, 0x02, 0x7d, 0x57, 0xa3, 0x8f, 0xe7, 0x02, 0x75, 0x57, 0x23, 0x8e, 0xe7, 0x02, - 0x95, 0x47, 0x23, 0x00, 0xf3, 0x00, 0xb7, 0x17, 0x00, 0x40, 0x03, 0xc7, 0xf7, 0x03, 0x05, 0x8b, - 0x6d, 0xff, 0x23, 0x8f, 0x07, 0x02, 0xa3, 0x8e, 0x07, 0x02, 0x41, 0x45, 0x42, 0x44, 0xb2, 0x44, - 0x51, 0x01, 0x02, 0x90, 0xa2, 0x46, 0x85, 0x06, 0x36, 0xc4, 0xa2, 0x86, 0x99, 0xb7, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +/// For CH32V003. It's a riscv32ec core, not supported by Rust yet. +// 9 +pub const CH32V003: [u8; 498] = [ + 0x11, 0x11, 0x22, 0xcc, 0x26, 0xca, 0x02, 0xc8, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, + 0x67, 0x45, 0xb7, 0x27, 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, + 0x13, 0x07, 0xb7, 0x9a, 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, + 0xb7, 0x27, 0x02, 0x40, 0x98, 0x4b, 0xad, 0x66, 0x37, 0x33, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, + 0x98, 0xcb, 0x98, 0x4b, 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, + 0x05, 0x8b, 0x63, 0x16, 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, + 0xa9, 0xcb, 0x93, 0x07, 0xf6, 0x03, 0x99, 0x83, 0x2e, 0xc0, 0x2d, 0x63, 0x81, 0x76, 0x3e, 0xc4, + 0xb7, 0x32, 0x00, 0x40, 0xb7, 0x27, 0x02, 0x40, 0x13, 0x03, 0xa3, 0xaa, 0xfd, 0x16, 0x98, 0x4b, + 0xb7, 0x03, 0x02, 0x00, 0x33, 0x67, 0x77, 0x00, 0x98, 0xcb, 0x02, 0x47, 0xd8, 0xcb, 0x98, 0x4b, + 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, + 0x98, 0xcb, 0x02, 0x47, 0x13, 0x07, 0x07, 0x04, 0x3a, 0xc0, 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, + 0x79, 0xf7, 0x93, 0x77, 0x85, 0x00, 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x03, 0x2e, 0xc0, 0x99, 0x83, + 0x37, 0x27, 0x02, 0x40, 0x3e, 0xc4, 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x63, 0xd5, 0x8f, 0x1c, 0xcb, + 0x37, 0x07, 0x00, 0x20, 0x13, 0x07, 0x07, 0x20, 0xb7, 0x27, 0x02, 0x40, 0xb7, 0x03, 0x08, 0x00, + 0xb7, 0x32, 0x00, 0x40, 0x13, 0x03, 0xa3, 0xaa, 0x94, 0x4b, 0xb3, 0xe6, 0x76, 0x00, 0x94, 0xcb, + 0xd4, 0x47, 0x85, 0x8a, 0xf5, 0xfe, 0x82, 0x46, 0xba, 0x84, 0x37, 0x04, 0x04, 0x00, 0x36, 0xc2, + 0xc1, 0x46, 0x36, 0xc6, 0x92, 0x46, 0x84, 0x40, 0x11, 0x07, 0x84, 0xc2, 0x94, 0x4b, 0xc1, 0x8e, + 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0xb1, 0xea, 0x92, 0x46, 0xba, 0x84, 0x91, 0x06, 0x36, 0xc2, + 0xb2, 0x46, 0xfd, 0x16, 0x36, 0xc6, 0xf9, 0xfe, 0x82, 0x46, 0xd4, 0xcb, 0x94, 0x4b, 0x93, 0xe6, + 0x06, 0x04, 0x94, 0xcb, 0xd4, 0x47, 0x85, 0x8a, 0x85, 0xee, 0xd4, 0x47, 0xc1, 0x8a, 0x85, 0xce, + 0xd8, 0x47, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, + 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x62, 0x44, 0xd2, 0x44, 0x71, 0x01, 0x02, 0x90, 0x23, 0x20, + 0xd3, 0x00, 0xf5, 0xb5, 0x23, 0xa0, 0x62, 0x00, 0x3d, 0xb7, 0x23, 0xa0, 0x62, 0x00, 0x55, 0xb7, + 0x23, 0xa0, 0x62, 0x00, 0xc1, 0xb7, 0x82, 0x46, 0x93, 0x86, 0x06, 0x04, 0x36, 0xc0, 0xa2, 0x46, + 0xfd, 0x16, 0x36, 0xc4, 0xb5, 0xf2, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, + 0x98, 0xcb, 0x41, 0x89, 0x19, 0xe1, 0x01, 0x45, 0x7d, 0xbf, 0x2e, 0xc0, 0x0d, 0x06, 0x02, 0xc4, + 0x09, 0x82, 0xb7, 0x07, 0x00, 0x20, 0x32, 0xc6, 0x93, 0x87, 0x07, 0x20, 0x94, 0x43, 0x13, 0x87, + 0x47, 0x00, 0xa2, 0x47, 0x02, 0x46, 0x8a, 0x07, 0xb2, 0x97, 0x9c, 0x43, 0x63, 0x99, 0xf6, 0x02, + 0xa2, 0x47, 0x82, 0x46, 0x8a, 0x07, 0xb6, 0x97, 0x94, 0x43, 0xc2, 0x47, 0xb6, 0x97, 0x3e, 0xc8, + 0xa2, 0x47, 0x85, 0x07, 0x3e, 0xc4, 0x22, 0x46, 0xb2, 0x46, 0xba, 0x87, 0xe3, 0x68, 0xd6, 0xfc, + 0xb7, 0x07, 0x00, 0x20, 0x03, 0xa7, 0x07, 0x61, 0xc2, 0x47, 0xe3, 0x06, 0xf7, 0xfa, 0x41, 0x45, + 0x9d, 0xb7, ]; -pub const UNKNOWN_12: [u8; 0x300] = [ - 0x93, 0x77, 0x15, 0x00, 0x41, 0x11, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, 0x02, 0x40, - 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, 0xd8, 0xc3, - 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, 0x02, 0x40, 0x98, 0x4b, - 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, 0x93, 0x86, - 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x63, 0x16, 0x07, 0x10, - 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, 0xf6, 0x0f, - 0xa1, 0x83, 0x2e, 0xc0, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xc4, 0xb7, 0x08, 0x02, 0x00, 0xb7, 0x27, - 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, 0x33, 0x67, - 0x17, 0x01, 0x98, 0xcb, 0x02, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, - 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x02, 0x47, 0x13, 0x07, - 0x07, 0x10, 0x3a, 0xc0, 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, 0x69, 0xfb, 0x93, 0x77, 0x85, 0x00, - 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc0, 0xa1, 0x83, 0x3e, 0xc4, 0x37, 0x27, 0x02, 0x40, - 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, 0xb7, 0x27, - 0x02, 0x40, 0x37, 0x03, 0x08, 0x00, 0x13, 0x0e, 0x00, 0x04, 0xb7, 0x0e, 0x04, 0x00, 0xb7, 0x38, - 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, 0xd8, 0x47, - 0x05, 0x8b, 0x75, 0xff, 0x02, 0x47, 0x36, 0x8f, 0x3a, 0xc2, 0x72, 0xc6, 0x12, 0x47, 0x03, 0x2f, - 0x0f, 0x00, 0x91, 0x06, 0x23, 0x20, 0xe7, 0x01, 0x98, 0x4b, 0x33, 0x67, 0xd7, 0x01, 0x98, 0xcb, - 0xd8, 0x47, 0x05, 0x8b, 0x21, 0xeb, 0x12, 0x47, 0x36, 0x8f, 0x11, 0x07, 0x3a, 0xc2, 0x32, 0x47, - 0x7d, 0x17, 0x3a, 0xc6, 0x61, 0xff, 0x02, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, - 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x15, 0xeb, 0xd8, 0x47, 0x41, 0x8b, 0x15, 0xcb, 0xd8, 0x47, - 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, 0x21, 0x45, - 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x01, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, 0xf5, 0xb5, 0x23, 0x20, - 0x03, 0x01, 0x3d, 0xb7, 0x23, 0xa0, 0x08, 0x01, 0x65, 0xb7, 0x23, 0xa0, 0x08, 0x01, 0xd1, 0xb7, - 0x02, 0x47, 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc0, 0x22, 0x47, 0x7d, 0x17, 0x3a, 0xc4, 0x25, 0xf7, - 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, 0x15, 0xc9, - 0x2e, 0xc0, 0x0d, 0x06, 0x02, 0xc4, 0x09, 0x82, 0x32, 0xc6, 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, - 0x13, 0x86, 0x47, 0x00, 0xa2, 0x47, 0x82, 0x46, 0x8a, 0x07, 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x1c, - 0xf7, 0x00, 0xa2, 0x47, 0x85, 0x07, 0x3e, 0xc4, 0xa2, 0x46, 0x32, 0x47, 0xb2, 0x87, 0xe3, 0xe0, - 0xe6, 0xfe, 0x01, 0x45, 0x41, 0xbf, 0x41, 0x45, 0x71, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +// 10 +pub const OP8571: [u8; 0x580] = [ + 0x01, 0x11, 0x02, 0xce, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, + 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, 0x02, 0x40, + 0x98, 0x4b, 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, + 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x63, 0x16, + 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, + 0xf6, 0x0f, 0xa1, 0x83, 0x2e, 0xc6, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xca, 0xb7, 0x08, 0x02, 0x00, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, + 0x33, 0x67, 0x17, 0x01, 0x98, 0xcb, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x32, 0x47, + 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x69, 0xfb, 0x93, 0x77, + 0x85, 0x00, 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc6, 0xa1, 0x83, 0x3e, 0xca, 0x37, 0x27, + 0x02, 0x40, 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x03, 0x08, 0x00, 0x13, 0x0e, 0x00, 0x04, 0xb7, 0x0e, 0x04, 0x00, + 0xb7, 0x38, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, + 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0x32, 0x47, 0x36, 0x8f, 0x3a, 0xc8, 0x72, 0xcc, 0x42, 0x47, + 0x03, 0x2f, 0x0f, 0x00, 0x91, 0x06, 0x23, 0x20, 0xe7, 0x01, 0x98, 0x4b, 0x33, 0x67, 0xd7, 0x01, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x21, 0xeb, 0x42, 0x47, 0x36, 0x8f, 0x11, 0x07, 0x3a, 0xc8, + 0x62, 0x47, 0x7d, 0x17, 0x3a, 0xcc, 0x61, 0xff, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, + 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x15, 0xeb, 0xd8, 0x47, 0x41, 0x8b, 0x15, 0xcb, + 0xd8, 0x47, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, + 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x05, 0x61, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, 0xf5, 0xb5, + 0x23, 0x20, 0x03, 0x01, 0x3d, 0xb7, 0x23, 0xa0, 0x08, 0x01, 0x65, 0xb7, 0x23, 0xa0, 0x08, 0x01, + 0xd1, 0xb7, 0x32, 0x47, 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, + 0x25, 0xf7, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, + 0x19, 0xe1, 0x01, 0x45, 0xc9, 0xb7, 0x2e, 0xc6, 0x0d, 0x06, 0x02, 0xca, 0x09, 0x82, 0x32, 0xcc, + 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xd2, 0x47, 0xb2, 0x46, 0x8a, 0x07, + 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x18, 0xf7, 0x02, 0xd2, 0x47, 0x32, 0x47, 0x8a, 0x07, 0xba, 0x97, + 0x98, 0x43, 0xf2, 0x47, 0xba, 0x97, 0x3e, 0xce, 0xd2, 0x47, 0x85, 0x07, 0x3e, 0xca, 0xd2, 0x46, + 0x62, 0x47, 0xb2, 0x87, 0xe3, 0xe8, 0xe6, 0xfc, 0xb7, 0x27, 0x00, 0x20, 0x98, 0x4b, 0xf2, 0x47, + 0xe3, 0x09, 0xf7, 0xfa, 0x41, 0x45, 0x85, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x47, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x18, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe8, 0xdd, 0x69, 0x00, 0x54, 0x2b, 0x68, 0x00, 0x40, 0xdd, 0x69, 0x00, 0xdd, 0xb6, 0x42, 0x00, - 0x2a, 0xc2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc4, 0x42, 0x00, 0xf2, 0xc5, 0x42, 0x00, - 0xe0, 0xc5, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0x93, 0x6a, 0x00, 0x14, 0xb6, 0x68, 0x00, 0x80, 0x92, 0x6a, 0x00, 0x0c, 0x2f, 0x43, 0x00, + 0x04, 0x3b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x3d, 0x43, 0x00, 0xcc, 0x3e, 0x43, 0x00, + 0xba, 0x3e, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x2a, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0xdf, 0x69, 0x00, 0x66, 0xc9, 0x42, 0x00, 0xbf, 0xc9, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0xdf, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xe1, 0x69, 0x00, - 0x13, 0xcd, 0x42, 0x00, 0x6c, 0xcd, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x95, 0x6a, 0x00, 0x06, 0x44, 0x43, 0x00, 0x5f, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x95, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0x6a, 0x00, + 0xb3, 0x47, 0x43, 0x00, 0x0c, 0x48, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0xe6, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xe6, 0x69, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x10, 0x9c, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x9c, 0x6a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0xe2, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0xe2, 0x69, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x2f, 0xe2, 0x69, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0xe2, 0x69, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xe0, 0x97, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x97, 0x6a, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xef, 0x97, 0x6a, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfa, 0x97, 0x6a, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x98, 0x6a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x98, 0x6a, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x18, 0x98, 0x6a, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, 0x98, 0x6a, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0xeb, 0x6a, 0x00, 0x7a, 0xfd, 0x43, 0x00, 0x2c, 0xfe, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x87, 0xeb, 0x6a, 0x00, 0xd3, 0xfd, 0x43, 0x00, 0x2c, 0xfe, 0x43, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xec, 0x6a, 0x00, 0x4b, 0x10, 0x44, 0x00, + 0x38, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xf3, 0x6a, 0x00, 0x5b, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, + 0x65, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, + 0x65, 0xf3, 0x6a, 0x00, 0x6e, 0xf3, 0x6a, 0x00, 0x65, 0xf3, 0x6a, 0x00, 0x82, 0xf3, 0x6a, 0x00, + 0x65, 0xf3, 0x6a, 0x00, 0x98, 0xf3, 0x6a, 0x00, 0xa6, 0xf3, 0x6a, 0x00, 0xbc, 0xf3, 0x6a, 0x00, + 0x40, 0xb7, 0x68, 0x00, 0x40, 0xb7, 0x68, 0x00, 0x48, 0xb7, 0x68, 0x00, 0x48, 0xb7, 0x68, 0x00, + 0x50, 0xb7, 0x68, 0x00, 0x50, 0xb7, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xe6, 0x68, 0x00, 0x80, 0xea, 0x68, 0x00, 0x80, 0xe7, 0x68, 0x00, 0x00, 0xe6, 0x68, 0x00, + 0xc0, 0xe9, 0x68, 0x00, 0x00, 0xe9, 0x68, 0x00, 0x40, 0xe8, 0x68, 0x00, 0x60, 0xf8, 0x68, 0x00, + 0x20, 0xf9, 0x68, 0x00, 0xe0, 0xf9, 0x68, 0x00, 0xc0, 0xba, 0x68, 0x00, 0xe0, 0xf3, 0x68, 0x00, + 0x60, 0xf2, 0x68, 0x00, 0x20, 0xf3, 0x68, 0x00, 0x40, 0xe5, 0x68, 0x00, 0xc0, 0xfb, 0x68, 0x00, + 0xc0, 0xfd, 0x68, 0x00, 0xa0, 0xf1, 0x68, 0x00, 0xe0, 0xf5, 0x68, 0x00, 0xa0, 0xf6, 0x68, 0x00, + 0xa0, 0xb8, 0x68, 0x00, 0xe0, 0xf0, 0x68, 0x00, 0x00, 0xfb, 0x68, 0x00, 0x40, 0xff, 0x68, 0x00, + 0x20, 0x00, 0x69, 0x00, 0x00, 0x01, 0x69, 0x00, 0xc0, 0xbb, 0x68, 0x00, 0x80, 0x02, 0x69, 0x00, + 0xc0, 0x01, 0x69, 0x00, 0x40, 0x03, 0x69, 0x00, 0xe0, 0xbe, 0x68, 0x00, 0xa0, 0xfc, 0x68, 0x00, + 0x60, 0xf7, 0x68, 0x00, 0x00, 0xe4, 0x68, 0x00, 0x40, 0xe3, 0x68, 0x00, 0x80, 0xfe, 0x68, 0x00, + 0x00, 0xba, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb7, 0x68, 0x00, 0xf8, 0xb7, 0x68, 0x00, + 0x00, 0xb8, 0x68, 0x00, 0x00, 0xb8, 0x68, 0x00, 0x08, 0xb8, 0x68, 0x00, 0x08, 0xb8, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0x6b, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x4d, 0x61, 0x6b, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5d, 0x61, 0x6b, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x6b, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7d, 0x61, 0x6b, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x8f, 0x61, 0x6b, 0x00, 0x06, 0x00, 0x00, 0x00, 0x97, 0x61, 0x6b, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x9f, 0x61, 0x6b, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaf, 0x61, 0x6b, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xb8, 0x61, 0x6b, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xbe, 0x61, 0x6b, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0xcd, 0x61, 0x6b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd7, 0x61, 0x6b, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0x8c, 0x6b, 0x00, 0x76, 0xfe, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0xfe, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xfe, 0x45, 0x00, + 0xc8, 0xfe, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +]; + +// 12 +pub const CH643: [u8; 488] = [ + 0x01, 0x11, 0x02, 0xce, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, + 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, 0x02, 0x40, + 0x98, 0x4b, 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, + 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x63, 0x16, + 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, + 0xf6, 0x0f, 0xa1, 0x83, 0x2e, 0xc6, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xca, 0xb7, 0x08, 0x02, 0x00, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, + 0x33, 0x67, 0x17, 0x01, 0x98, 0xcb, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x32, 0x47, + 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x69, 0xfb, 0x93, 0x77, + 0x85, 0x00, 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc6, 0xa1, 0x83, 0x3e, 0xca, 0x37, 0x27, + 0x02, 0x40, 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x03, 0x08, 0x00, 0x13, 0x0e, 0x00, 0x04, 0xb7, 0x0e, 0x04, 0x00, + 0xb7, 0x38, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, + 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0x32, 0x47, 0x36, 0x8f, 0x3a, 0xc8, 0x72, 0xcc, 0x42, 0x47, + 0x03, 0x2f, 0x0f, 0x00, 0x91, 0x06, 0x23, 0x20, 0xe7, 0x01, 0x98, 0x4b, 0x33, 0x67, 0xd7, 0x01, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x21, 0xeb, 0x42, 0x47, 0x36, 0x8f, 0x11, 0x07, 0x3a, 0xc8, + 0x62, 0x47, 0x7d, 0x17, 0x3a, 0xcc, 0x61, 0xff, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, + 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x15, 0xeb, 0xd8, 0x47, 0x41, 0x8b, 0x15, 0xcb, + 0xd8, 0x47, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, + 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x05, 0x61, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, 0xf5, 0xb5, + 0x23, 0x20, 0x03, 0x01, 0x3d, 0xb7, 0x23, 0xa0, 0x08, 0x01, 0x65, 0xb7, 0x23, 0xa0, 0x08, 0x01, + 0xd1, 0xb7, 0x32, 0x47, 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, + 0x25, 0xf7, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, + 0x19, 0xe1, 0x01, 0x45, 0xc9, 0xb7, 0x2e, 0xc6, 0x0d, 0x06, 0x02, 0xca, 0x09, 0x82, 0x32, 0xcc, + 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xd2, 0x47, 0xb2, 0x46, 0x8a, 0x07, + 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x18, 0xf7, 0x02, 0xd2, 0x47, 0x32, 0x47, 0x8a, 0x07, 0xba, 0x97, + 0x98, 0x43, 0xf2, 0x47, 0xba, 0x97, 0x3e, 0xce, 0xd2, 0x47, 0x85, 0x07, 0x3e, 0xca, 0xd2, 0x46, + 0x62, 0x47, 0xb2, 0x87, 0xe3, 0xe8, 0xe6, 0xfc, 0xb7, 0x27, 0x00, 0x20, 0x98, 0x4b, 0xf2, 0x47, + 0xe3, 0x09, 0xf7, 0xfa, 0x41, 0x45, 0x85, 0xbf, +]; + +// 14 +pub const CH32L103: [u8; 0x200] = [ + 0x01, 0x11, 0x02, 0xce, 0x93, 0x77, 0x15, 0x00, 0x99, 0xcf, 0xb7, 0x06, 0x67, 0x45, 0xb7, 0x27, + 0x02, 0x40, 0x93, 0x86, 0x36, 0x12, 0x37, 0x97, 0xef, 0xcd, 0xd4, 0xc3, 0x13, 0x07, 0xb7, 0x9a, + 0xd8, 0xc3, 0xd4, 0xd3, 0xd8, 0xd3, 0x93, 0x77, 0x25, 0x00, 0x9d, 0xc7, 0xb7, 0x27, 0x02, 0x40, + 0x98, 0x4b, 0xad, 0x66, 0x37, 0x38, 0x00, 0x40, 0x13, 0x67, 0x47, 0x00, 0x98, 0xcb, 0x98, 0x4b, + 0x93, 0x86, 0xa6, 0xaa, 0x13, 0x67, 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x63, 0x16, + 0x07, 0x10, 0x98, 0x4b, 0x6d, 0x9b, 0x98, 0xcb, 0x93, 0x77, 0x45, 0x00, 0xa9, 0xcb, 0x93, 0x07, + 0xf6, 0x0f, 0xa1, 0x83, 0x2e, 0xc6, 0x2d, 0x68, 0x81, 0x76, 0x3e, 0xca, 0xb7, 0x08, 0x02, 0x00, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x33, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0xfd, 0x16, 0x98, 0x4b, + 0x33, 0x67, 0x17, 0x01, 0x98, 0xcb, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, 0x07, 0x04, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x69, 0xe7, 0x98, 0x4b, 0x75, 0x8f, 0x98, 0xcb, 0x32, 0x47, + 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, 0x69, 0xfb, 0x93, 0x77, + 0x85, 0x00, 0xf1, 0xcf, 0x93, 0x07, 0xf6, 0x0f, 0x2e, 0xc6, 0xa1, 0x83, 0x3e, 0xca, 0x37, 0x27, + 0x02, 0x40, 0x1c, 0x4b, 0xc1, 0x66, 0x2d, 0x68, 0xd5, 0x8f, 0x1c, 0xcb, 0xb7, 0x16, 0x00, 0x20, + 0xb7, 0x27, 0x02, 0x40, 0x37, 0x03, 0x08, 0x00, 0x13, 0x0e, 0x00, 0x04, 0xb7, 0x0e, 0x04, 0x00, + 0xb7, 0x38, 0x00, 0x40, 0x13, 0x08, 0xa8, 0xaa, 0x98, 0x4b, 0x33, 0x67, 0x67, 0x00, 0x98, 0xcb, + 0xd8, 0x47, 0x05, 0x8b, 0x75, 0xff, 0x32, 0x47, 0x36, 0x8f, 0x3a, 0xc8, 0x72, 0xcc, 0x42, 0x47, + 0x03, 0x2f, 0x0f, 0x00, 0x91, 0x06, 0x23, 0x20, 0xe7, 0x01, 0x98, 0x4b, 0x33, 0x67, 0xd7, 0x01, + 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x21, 0xeb, 0x42, 0x47, 0x36, 0x8f, 0x11, 0x07, 0x3a, 0xc8, + 0x62, 0x47, 0x7d, 0x17, 0x3a, 0xcc, 0x61, 0xff, 0x32, 0x47, 0xd8, 0xcb, 0x98, 0x4b, 0x13, 0x67, + 0x07, 0x04, 0x98, 0xcb, 0xd8, 0x47, 0x05, 0x8b, 0x15, 0xeb, 0xd8, 0x47, 0x41, 0x8b, 0x15, 0xcb, + 0xd8, 0x47, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x13, 0x67, 0x07, 0x01, 0xd8, 0xc7, 0x98, 0x4b, + 0x21, 0x45, 0x75, 0x8f, 0x98, 0xcb, 0x05, 0x61, 0x02, 0x90, 0x23, 0x20, 0xd8, 0x00, 0xf5, 0xb5, + 0x23, 0x20, 0x03, 0x01, 0x3d, 0xb7, 0x23, 0xa0, 0x08, 0x01, 0x65, 0xb7, 0x23, 0xa0, 0x08, 0x01, + 0xd1, 0xb7, 0x32, 0x47, 0x13, 0x07, 0x07, 0x10, 0x3a, 0xc6, 0x52, 0x47, 0x7d, 0x17, 0x3a, 0xca, + 0x25, 0xf7, 0x98, 0x4b, 0xb7, 0x06, 0xf3, 0xff, 0xfd, 0x16, 0x75, 0x8f, 0x98, 0xcb, 0x41, 0x89, + 0x19, 0xe1, 0x01, 0x45, 0xc9, 0xb7, 0x2e, 0xc6, 0x0d, 0x06, 0x02, 0xca, 0x09, 0x82, 0x32, 0xcc, + 0xb7, 0x17, 0x00, 0x20, 0x98, 0x43, 0x13, 0x86, 0x47, 0x00, 0xd2, 0x47, 0xb2, 0x46, 0x8a, 0x07, + 0xb6, 0x97, 0x9c, 0x43, 0x63, 0x18, 0xf7, 0x02, 0xd2, 0x47, 0x32, 0x47, 0x8a, 0x07, 0xba, 0x97, + 0x98, 0x43, 0xf2, 0x47, 0xba, 0x97, 0x3e, 0xce, 0xd2, 0x47, 0x85, 0x07, 0x3e, 0xca, 0xd2, 0x46, + 0x62, 0x47, 0xb2, 0x87, 0xe3, 0xe8, 0xe6, 0xfc, 0xb7, 0x27, 0x00, 0x20, 0x98, 0x4b, 0xf2, 0x47, + 0xe3, 0x09, 0xf7, 0xfa, 0x41, 0x45, 0x85, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]; diff --git a/src/lib.rs b/src/lib.rs index 3df1d5e..793b9cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ use std::{fmt, str::FromStr}; +pub mod chips; pub mod commands; pub mod device; +pub mod dmi; pub mod error; pub mod flash_op; pub mod format; @@ -9,6 +11,9 @@ mod operations; pub mod regs; pub mod transport; +use commands::RawCommand; +use device::WchLink; + pub use crate::error::{Error, Result}; /// All WCH-Link probe variants, see-also: @@ -37,9 +42,30 @@ impl WchLinkVariant { } } - pub fn can_switch_mode(&self) -> bool { + /// CH549 variant does not support mode switch. re-program is needed. + pub fn support_switch_mode(&self) -> bool { !matches!(self, WchLinkVariant::Ch549) } + + /// Only W, E mode support this, power functions + pub fn support_power_funcs(&self) -> bool { + matches!(self, WchLinkVariant::WCh32v208 | WchLinkVariant::ECh32v305) + } + + /// Better use E variant, the Old CH549-based variant does not support all chips + pub fn support_chip(&self, chip: RiscvChip) -> bool { + match self { + WchLinkVariant::Ch549 => !matches!( + chip, + RiscvChip::CH32V003 | RiscvChip::CH32X035 | RiscvChip::CH643 + ), + WchLinkVariant::WCh32v208 => !matches!( + chip, + RiscvChip::CH56X | RiscvChip::CH57X | RiscvChip::CH58X | RiscvChip::CH59X + ), + _ => true, + } + } } impl fmt::Display for WchLinkVariant { @@ -67,28 +93,34 @@ pub enum RiscvChip { CH32V20X = 0x05, /// CH32V30X RISC-V4C/V4F series, The same as type 5 CH32V30X = 0x06, - /// CH58x RISC-V4A BLE 5.3 series, fallback as CH57X + /// CH58x RISC-V4A BLE 5.3 series CH58X = 0x07, /// CH32V003 RISC-V2A series CH32V003 = 0x09, - _Unkown0A = 0x0A, // 10 - /// CH59x RISC-V4C BLE 5.4 series, fallback as CH57X + // The only reference I can find is . + /// RISC-V EC controller, undocumented. + CH8571 = 0x0A, // 10, + /// CH59x RISC-V4C BLE 5.4 series, fallback as CH58X CH59X = 0x0B, // 11 - _Unkown0C = 0x0C, // 12 - /// CH32X035 RISC-V4C series, fallbak as 0x0C + /// CH643 RISC-V4C series, RGB Display Driver MCU + CH643 = 0x0C, // 12 + /// CH32X035 RISC-V4C PDUSB series, fallbak as CH643 CH32X035 = 0x0D, // 13 + /// CH32L103 RISC-V4C low power series + CH32L103 = 0x0E, // 14 } impl RiscvChip { /// Support flash protect commands, and info query commands - pub(crate) fn support_flash_protect(&self) -> bool { - // type 3, 2, 7, 0x0A, 0x0b do not support write protect + pub fn support_flash_protect(&self) -> bool { matches!( self, RiscvChip::CH32V103 - | RiscvChip::CH32V003 | RiscvChip::CH32V20X | RiscvChip::CH32V30X + | RiscvChip::CH32V003 + | RiscvChip::CH643 + | RiscvChip::CH32L103 | RiscvChip::CH32X035 ) } @@ -98,15 +130,36 @@ impl RiscvChip { matches!(self, RiscvChip::CH32V20X | RiscvChip::CH32V30X) } - /// Very unsafe. This disables the debug interface of the chip. + /// Support config registers, query info(UID, etc.) + pub fn support_query_info(&self) -> bool { + !matches!( + self, + RiscvChip::CH57X | RiscvChip::CH56X | RiscvChip::CH58X | RiscvChip::CH59X + ) + } + + /// Very unsafe. + /// This disables the debug interface of the chip. /// Command sequence is 810e0101 - pub fn can_disable_debug(&self) -> bool { + pub fn support_disable_debug(&self) -> bool { matches!( self, RiscvChip::CH57X | RiscvChip::CH56X | RiscvChip::CH58X | RiscvChip::CH59X ) } + /// Erase code flash by RST pin or power-off + pub fn support_special_erase(&self) -> bool { + !matches!( + self, + RiscvChip::CH57X + | RiscvChip::CH56X + | RiscvChip::CH58X + | RiscvChip::CH59X + | RiscvChip::CH32V003 + ) + } + pub fn reset_command(&self) -> crate::commands::Reset { match self { RiscvChip::CH57X | RiscvChip::CH58X | RiscvChip::CH59X => { @@ -116,16 +169,47 @@ impl RiscvChip { } } + /// Device-specific post init logic + pub fn post_init(&self, probe: &mut WchLink) -> Result<()> { + match self { + RiscvChip::CH32V103 => { + // 81 0d 01 03 + // 81 0d 01 10 + let _ = probe.send_command(RawCommand::<0x0d>(vec![0x03]))?; + // let _ = probe.send_command(RawCommand::<0x0d>(vec![0x10]))?; + } + RiscvChip::CH32V30X | RiscvChip::CH8571 | RiscvChip::CH32V003 => { + // 81 0d 01 03 + // let _ = probe.send_command(RawCommand::<0x0d>(vec![0x03]))?; + } + RiscvChip::CH57X | RiscvChip::CH58X => { + log::warn!("The debug interface has been opened, there is a risk of code leakage."); + log::warn!("Please ensure that the debug interface has been closed before leaving factory!"); + } + RiscvChip::CH56X => { + log::warn!("The debug interface has been opened, there is a risk of code leakage."); + log::warn!("Please ensure that the debug interface has been closed before leaving factory!"); + // 81 0d 01 04 + // should test returen value + let resp = probe.send_command(RawCommand::<0x0d>(vec![0x04]))?; + log::debug!("TODO, handle CH56X resp {:?}", resp); + } + _ => (), + } + Ok(()) + } + fn flash_op(&self) -> &[u8] { match self { - RiscvChip::CH32V103 => &flash_op::CH32V103, RiscvChip::CH32V003 => &flash_op::CH32V003, - RiscvChip::CH57X | RiscvChip::CH58X | RiscvChip::CH59X => &flash_op::CH573, - RiscvChip::CH56X => &flash_op::CH569, + RiscvChip::CH32V103 => &flash_op::CH32V103, RiscvChip::CH32V20X | RiscvChip::CH32V30X => &flash_op::CH32V307, - RiscvChip::_Unkown0A => &flash_op::UNKNOWN_10, - RiscvChip::_Unkown0C => &flash_op::UNKNOWN_12, - RiscvChip::CH32X035 => &flash_op::UNKNOWN_12, + RiscvChip::CH56X => &flash_op::CH569, + RiscvChip::CH57X => &flash_op::CH573, + RiscvChip::CH58X | RiscvChip::CH59X => &flash_op::CH583, + RiscvChip::CH8571 => &flash_op::OP8571, + RiscvChip::CH32X035 | RiscvChip::CH643 => &flash_op::CH643, + RiscvChip::CH32L103 => &flash_op::CH32L103, } } fn try_from_u8(value: u8) -> Result { @@ -137,13 +221,17 @@ impl RiscvChip { 0x06 => Ok(RiscvChip::CH32V30X), 0x07 => Ok(RiscvChip::CH58X), 0x09 => Ok(RiscvChip::CH32V003), + 0x0A => Ok(RiscvChip::CH8571), 0x0B => Ok(RiscvChip::CH59X), + 0x0C => Ok(RiscvChip::CH643), 0x0D => Ok(RiscvChip::CH32X035), + 0x0E => Ok(RiscvChip::CH32L103), _ => Err(Error::UnknownChip(value)), } } - pub fn page_size(&self) -> u32 { + /// Packet data length of data endpoint + pub fn data_packet_size(&self) -> usize { match self { RiscvChip::CH32V103 => 128, RiscvChip::CH32V003 => 64, @@ -153,13 +241,16 @@ impl RiscvChip { pub fn code_flash_start(&self) -> u32 { match self { - RiscvChip::CH56X | RiscvChip::CH57X | RiscvChip::CH58X | RiscvChip::CH59X => { - 0x0000_0000 - } + RiscvChip::CH56X + | RiscvChip::CH57X + | RiscvChip::CH58X + | RiscvChip::CH59X + | RiscvChip::CH8571 => 0x0000_0000, _ => 0x0800_0000, } } + // packsize for fastprogram pub fn write_pack_size(&self) -> u32 { match self { RiscvChip::CH32V003 => 1024, @@ -183,6 +274,9 @@ impl FromStr for RiscvChip { "CH58X" => Ok(RiscvChip::CH58X), "CH59X" => Ok(RiscvChip::CH59X), "CH32X035" => Ok(RiscvChip::CH32X035), + "CH643" => Ok(RiscvChip::CH643), + "CH32L103" => Ok(RiscvChip::CH32L103), + "CH8571" => Ok(RiscvChip::CH8571), _ => Err(Error::UnknownChip(0)), } } diff --git a/src/main.rs b/src/main.rs index 723124f..7aa60c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ use std::{thread::sleep, time::Duration}; use anyhow::Result; -use wlink::{commands, device::WchLink, format::read_firmware_from_file, regs, RiscvChip}; +use wlink::{ + commands, device::WchLink, dmi::DebugModuleInterface, format::read_firmware_from_file, regs, + RiscvChip, +}; use clap::{Parser, Subcommand}; @@ -17,7 +20,7 @@ struct Cli { verbose: u8, /// Detach chip after operation - #[arg(long, global = true)] + #[arg(long, global = true, default_value = "true")] detach: bool, /// Specify the chip type, e.g. CH32V30X @@ -32,6 +35,16 @@ struct Cli { command: Option, } +#[derive(Debug, Clone, Copy, clap::ValueEnum)] +enum EraseMode { + /// Erase code flash by power off, the probe will power off the target chip + PowerOff, + /// Erase code flash by RST pin, the probe will active the nRST line. Requires a RST pin connection + PinRst, + /// Erase code flash by probe command + Default, +} + #[derive(Subcommand)] enum Commands { /// Dump memory region @@ -47,16 +60,26 @@ enum Commands { /// Dump registers Regs {}, /// Erase flash - Erase {}, - /// Program the flash + Erase { + /// Erase mode + #[arg(long, default_value = "default")] + method: EraseMode, + }, + /// Program the code flash Flash { /// Address in u32 #[arg(short, long, value_parser = parse_number)] address: Option, - /// Path to the binary file to flash + /// Do not erase flash before flashing + #[arg(long, short = 'E', default_value = "false")] + no_erase: bool, + /// Do not reset and run after flashing + #[arg(long, short = 'R', default_value = "false")] + no_run: bool, + /// Path to the firmware file to flash path: String, }, - /// Unlock flash, enable debugging + /// Unlock flash Unprotect {}, /// Protect flash Protect {}, @@ -93,6 +116,7 @@ enum Commands { #[arg(long)] dap: bool, }, + Dev {}, } fn main() -> Result<()> { @@ -130,6 +154,7 @@ fn main() -> Result<()> { None => { wlink::device::check_usb_device()?; println!("No command given, use --help for help."); + println!("hint: use `wlink status` to get started."); } Some(ModeSwitch { rv, dap }) => { wlink::device::check_usb_device()?; // list all connected devices @@ -145,9 +170,21 @@ fn main() -> Result<()> { Some(command) => { let mut probe = WchLink::open_nth(device_index)?; probe.set_speed(cli.speed); - probe.probe_info()?; probe.attach_chip(cli.chip)?; match command { + Dev {} => { + // probe.erase_flash_by_power_off()?; + // const FLASH_KEYR: u32 = 0x2000_0030; + //let mut algo = wlink::dmi::Algorigthm::new(&mut probe); + // algo.write_mem32(FLASH_KEYR, 0x45670123)?; + + //algo.ensure_mcu_halt()?; + //let address = 0x40001041; + //let v = algo.read_mem32(address)?; + //println!("0x{:08x}: 0x{:08x}", address, v); + + // algo.dump_pmp()?; + } Dump { address, length } => { log::info!( "Read memory from 0x{:08x} to 0x{:08x}", @@ -168,39 +205,56 @@ fn main() -> Result<()> { log::info!("Resume MCU"); probe.ensure_mcu_resume()?; - let dmstatus: regs::Dmstatus = probe.dmi_read()?; + let dmstatus: regs::Dmstatus = probe.read_dmi_reg()?; log::info!("{dmstatus:#?}"); } - Erase {} => { - log::info!("Erase Flash"); - probe.erase_flash()?; + Erase { method } => { + log::info!("Erase Flash using {:?} method", method); + match method { + EraseMode::Default => { + probe.erase_flash()?; + } + EraseMode::PinRst => { + unimplemented!("Erase by RST pin"); + } + EraseMode::PowerOff => { + probe.erase_flash_by_power_off()?; + } + } } - Flash { address, path } => { - // NOTE: this is required for Flash command - probe.dump_info()?; + Flash { + address, + no_erase, + no_run, + path, + } => { + probe.dump_info(false)?; let firmware = read_firmware_from_file(path)?; - - let start_address = - address.unwrap_or_else(|| probe.chip.as_ref().unwrap().memory_start_addr); + let start_address = address.unwrap_or_else(|| { + probe.chip.as_ref().unwrap().chip_family.code_flash_start() + }); log::info!( "Flashing {} bytes to 0x{:08x}", firmware.len(), start_address ); + if !no_erase { + log::info!("Erase Flash"); + probe.erase_flash()?; + } + probe.write_flash(&firmware, start_address)?; log::info!("Flash done"); sleep(Duration::from_millis(500)); - log::info!("Now reset..."); - probe.send_command(commands::Reset::Quit)?; - sleep(Duration::from_millis(500)); - // reattach - probe.attach_chip(cli.chip)?; - log::info!("Resume executing..."); - probe.ensure_mcu_resume()?; + if !no_run { + log::info!("Now reset..."); + probe.send_command(commands::Reset::ResetAndRun)?; + sleep(Duration::from_millis(500)); + } } Unprotect {} => { log::info!("Unprotect Flash"); @@ -229,9 +283,21 @@ fn main() -> Result<()> { probe.write_memory_word(address, value)?; } Status {} => { - probe.dump_info()?; - let dmstatus: regs::Dmstatus = probe.dmi_read()?; - log::info!("{dmstatus:#?}"); + probe.dump_info(true)?; + + let dmstatus: regs::Dmstatus = probe.read_dmi_reg()?; + log::info!("{dmstatus:#x?}"); + let dmcontrol: regs::Dmcontrol = probe.read_dmi_reg()?; + log::info!("{dmcontrol:#x?}"); + let hartinfo: regs::Hartinfo = probe.read_dmi_reg()?; + log::info!("{hartinfo:#x?}"); + let abstractcs: regs::Abstractcs = probe.read_dmi_reg()?; + log::info!("{abstractcs:#x?}"); + let haltsum0 = probe.dmi_read(0x40)?; + log::info!("haltsum0: {:#x?}", haltsum0); + + let cpbr = probe.dmi_read(0x7E)?; + log::info!("cpbr: {:#x?}", cpbr); } _ => unreachable!("unimplemented command"), } diff --git a/src/operations.rs b/src/operations.rs index dbaa9e8..856171b 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -3,10 +3,15 @@ use std::{thread::sleep, time::Duration}; use crate::{ - commands::{self, control::ProbeInfo, DmiOp, Program, ReadMemory, SetRamAddress}, + commands::{ + self, + control::{self, ProbeInfo}, + DmiOp, Program, SetReadMemoryRegion, SetWriteMemoryRegion, + }, device::{ChipInfo, WchLink}, + dmi::DebugModuleInterface, error::AbstractcsCmdErr, - regs::{self, Abstractcs, DMReg, Dmcontrol, Dmstatus}, + regs::{self, Abstractcs, Dmcontrol, Dmstatus}, transport::Transport, Error, Result, RiscvChip, }; @@ -17,23 +22,26 @@ impl WchLink { log::info!("{}", info); Ok(info) } + /// Attach chip and get chip info pub fn attach_chip(&mut self, expected_chip: Option) -> Result<()> { if self.chip.is_some() { log::warn!("Chip already attached"); } - if expected_chip.is_none() { - log::warn!("No expected chip type specified, assume CH32V30X (use --chip to specify chip type)"); - } - let probe_info = self.send_command(commands::control::GetProbeInfo)?; + let probe_info = self.probe_info()?; + + if let Some(chip) = expected_chip { + if !probe_info.variant.support_chip(chip) { + log::error!("WCH-Link doesn't support the choosen MCU, please use WCH-LinkE!"); + return Err(Error::UnsupportedChip(chip)); + } + } let mut chip_info = None; for _ in 0..3 { - // self.send_command(commands::control::DetachChip)?; - - self.send_command(commands::SetTwoLineMode { - riscvchip: expected_chip.unwrap_or(RiscvChip::CH32V30X) as u8, + self.send_command(commands::SetSpeed { + riscvchip: expected_chip.unwrap_or(RiscvChip::CH32V20X) as u8, speed: self.speed, })?; @@ -51,6 +59,14 @@ impl WchLink { return Err(Error::ChipMismatch(expected_chip, resp.chip_family)); } } + // set speed again + if expected_chip.is_none() { + self.send_command(commands::SetSpeed { + riscvchip: resp.chip_family as u8, + speed: self.speed, + })?; + } + break; } else { log::debug!("retrying..."); @@ -59,23 +75,20 @@ impl WchLink { } let chip_info = chip_info.ok_or(Error::NotAttached)?; - self.send_command(commands::control::Unknown3)?; + chip_info.chip_family.post_init(self)?; + + //let ret = self.send_command(control::CheckQE)?; + //log::info!("Check QE: {:?}", ret); // riscvchip = 7 => 2 - let flash_addr = chip_info.chip_family.code_flash_start(); - let page_size = chip_info.chip_family.page_size(); + //let flash_addr = chip_info.chip_family.code_flash_start(); + //let page_size = chip_info.chip_family.data_packet_size(); let info = ChipInfo { uid: None, // TODO chip_family: chip_info.chip_family, - chip_type: chip_info.chip_type, + chip_id: chip_info.chip_id, march: None, - flash_size: 0, // TODO: read flash size - memory_start_addr: flash_addr, - sram_code_mode: 0, // TODO - page_size, - //rom_kb: 0, // TODO: - //ram_kb: 0, // TODO: }; self.chip = Some(info); @@ -84,66 +97,52 @@ impl WchLink { Ok(()) } - // NOTE: this halts the MCU - pub fn dump_info(&mut self) -> Result<()> { + // NOTE: this halts the MCU, so it's not suitable except for dumping info + pub fn dump_info(&mut self, detailed: bool) -> Result<()> { let probe_info = self.probe.as_ref().unwrap(); - if self - .chip - .as_ref() - .unwrap() - .chip_family - .support_flash_protect() - { + let chip_family = self.chip.as_ref().unwrap().chip_family; + + if chip_family.support_query_info() { let chip_id = if probe_info.version() >= (2, 9) { - self.send_command(commands::QueryChipInfo::V2)? + self.send_command(commands::GetChipInfo::V2)? } else { - self.send_command(commands::QueryChipInfo::V1)? + self.send_command(commands::GetChipInfo::V1)? }; log::info!("Chip UID: {chip_id}"); - // self.uid = Some(chip_id); - let flash_protected = self.send_command(commands::FlashProtect::Query)?; - let protected = flash_protected == commands::FlashProtect::FLAG_PROTECTED; + let flash_protected = self.send_command(commands::ConfigChip::CheckReadProtect)?; + let protected = flash_protected == commands::ConfigChip::FLAG_PROTECTED; log::info!("Flash protected: {}", protected); if protected { log::warn!("Flash is protected, debug access is not available"); } } - if self - .chip - .as_ref() - .unwrap() - .chip_family - .support_ram_rom_mode() - { + if chip_family.support_ram_rom_mode() { let sram_code_mode = self.send_command(commands::control::GetChipRomRamSplit)?; log::debug!("SRAM CODE split mode: {}", sram_code_mode); } - let misa = self.read_reg(regs::MISA)?; - log::trace!("Read csr misa: {misa:08x}"); - let misa = parse_misa(misa); - log::info!("RISC-V ISA: {misa:?}"); - - // detect chip's RISC-V core version, QingKe cores - let marchid = self.read_reg(regs::MARCHID)?; - log::trace!("Read csr marchid: {marchid:08x}"); - let core_type = parse_marchid(marchid); - log::info!("RISC-V arch: {core_type:?}"); + if detailed { + let misa = self.read_reg(regs::MISA)?; + log::trace!("Read csr misa: {misa:08x}"); + let misa = parse_misa(misa); + log::info!("RISC-V ISA: {misa:?}"); + // detect chip's RISC-V core version, QingKe cores + let marchid = self.read_reg(regs::MARCHID)?; + log::trace!("Read csr marchid: {marchid:08x}"); + let core_type = parse_marchid(marchid); + log::info!("RISC-V arch: {core_type:?}"); + } Ok(()) } pub fn protect_flash(&mut self, protect: bool) -> Result<()> { // HACK: requires a fresh attach - self.send_command(commands::control::DetachChip)?; + self.reattach_chip()?; - let probe_info = self.send_command(commands::control::GetProbeInfo)?; - - self.send_command(commands::control::AttachChip)?; - - let flash_protected_flag = self.send_command(commands::FlashProtect::Query)?; - let protected = flash_protected_flag == commands::FlashProtect::FLAG_PROTECTED; + let flash_protected_flag = self.send_command(commands::ConfigChip::CheckReadProtect)?; + let protected = flash_protected_flag == commands::ConfigChip::FLAG_PROTECTED; if protect == protected { log::info!( "Flash already {}", @@ -153,30 +152,24 @@ impl WchLink { "unprotected" } ); - // - // return Ok(()); } - let use_v2 = probe_info.version() >= (2, 9); + let use_v2 = self.probe.as_ref().unwrap().version() >= (2, 9); let cmd = match (protect, use_v2) { - (true, true) => commands::FlashProtect::ProtectV2, - (false, true) => commands::FlashProtect::UnprotectV2, - (true, false) => commands::FlashProtect::Protect, - (false, false) => commands::FlashProtect::Unprotect, + (true, true) => commands::ConfigChip::ProtectEx(0xbf), + (true, false) => commands::ConfigChip::Protect, + (false, true) => commands::ConfigChip::UnprotectEx(0xbf), + (false, false) => commands::ConfigChip::Unprotect, }; - self.send_command(cmd)?; - self.send_command(commands::Reset::Quit)?; // quit reset - self.send_command(commands::control::DetachChip)?; + self.send_command(commands::Reset::ResetAndRun)?; // quit reset + self.send_command(control::AttachChip)?; - self.send_command(commands::control::GetProbeInfo)?; - self.send_command(commands::control::AttachChip)?; - - let flash_protected = self.send_command(commands::FlashProtect::Query)?; + let flash_protected = self.send_command(commands::ConfigChip::CheckReadProtect)?; log::info!( "Flash protected: {}", - flash_protected == commands::FlashProtect::FLAG_PROTECTED + flash_protected == commands::ConfigChip::FLAG_PROTECTED ); Ok(()) @@ -186,11 +179,18 @@ impl WchLink { /// Detach chip and let it resume pub fn detach_chip(&mut self) -> Result<()> { log::debug!("Detach chip"); - self.send_command(commands::control::DetachChip)?; + self.send_command(commands::control::OptEnd)?; self.chip = None; Ok(()) } + fn reattach_chip(&mut self) -> Result<()> { + let current_chip_family = self.chip.as_ref().map(|i| i.chip_family); + self.detach_chip()?; + self.attach_chip(current_chip_family)?; + Ok(()) + } + pub fn read_flash_size_kb(&mut self) -> Result { // Ref: (DS) Chapter 31 Electronic Signature (ESIG) let raw_flash_cap = self.read_memory(0x1FFFF7E0, 4)?; @@ -206,11 +206,11 @@ impl WchLink { if length % 4 != 0 { length = (length / 4 + 1) * 4; } - self.send_command(ReadMemory { + self.send_command(SetReadMemoryRegion { start_addr: address, len: length, })?; - self.send_command(Program::BeginReadMemory)?; + self.send_command(Program::ReadMemory)?; let mut mem = self.device_handle.read_data_endpoint(length as usize)?; // Fix endian @@ -218,6 +218,12 @@ impl WchLink { chunk.reverse(); } + if mem.starts_with(&[0xA9, 0xBD, 0xF9, 0xF3]) { + log::warn!("A9 BD F9 F3 sequence detected!"); + log::warn!("If the chip is just put into debug mode, you should flash the new firmware to the chip first"); + log::warn!("Or else this indicates a reading to invalid location"); + } + println!( "{}", nu_pretty_hex::config_hex( @@ -234,73 +240,131 @@ impl WchLink { Ok(mem) } + /// Clear All Code Flash - By Power off + pub fn erase_flash_by_power_off(&mut self) -> Result<()> { + if self.probe.as_ref().unwrap().variant.support_power_funcs() + && self + .chip + .as_ref() + .unwrap() + .chip_family + .support_special_erase() + { + self.send_command(control::EraseCodeFlash::ByPowerOff)?; + Ok(()) + } else { + Err(Error::Custom(format!( + "Probe or Chip doesn't support power off erase", + ))) + } + } + + /// Erases flash and re-attach pub fn erase_flash(&mut self) -> Result<()> { + if self + .chip + .as_ref() + .unwrap() + .chip_family + .support_flash_protect() + { + let ret = self.send_command(commands::ConfigChip::CheckReadProtect)?; + if ret == commands::ConfigChip::FLAG_PROTECTED { + log::warn!("Flash is protected, unprotecting..."); + self.protect_flash(false)?; + } else if ret == 2 { + self.protect_flash(false)?; + } else { + log::warn!("Unknown flash protect status: {}", ret); + } + } self.send_command(Program::EraseFlash)?; + self.send_command(control::AttachChip)?; + Ok(()) } // wlink_write pub fn write_flash(&mut self, data: &[u8], address: u32) -> Result<()> { - let write_pack_size = self.chip.as_ref().unwrap().chip_family.write_pack_size(); + let chip_family = self.chip.as_ref().unwrap().chip_family; + let write_pack_size = chip_family.write_pack_size(); + let data_packet_size = chip_family.data_packet_size(); - let mut data = data.to_vec(); - if data.len() % 256 != 0 { - data.resize((data.len() / 256 + 1) * 256, 0); - } - log::trace!("Using write pack size {}", write_pack_size); - if data.len() < write_pack_size as usize { - data.resize(write_pack_size as usize, 0xff); + if chip_family.support_flash_protect() { + self.protect_flash(false)?; } - self.send_command(Program::Prepare)?; - self.send_command(SetRamAddress { + let data = data.to_vec(); + + // if data.len() % data_packet_size != 0 { + // data.resize((data.len() / data_packet_size + 1) * data_packet_size, 0xff); + // log::debug!("Data resized to {}", data.len()); + // } + log::debug!( + "Using write pack size {} data pack size {}", + write_pack_size, + data_packet_size + ); + + // wlink_ready_write + // self.send_command(Program::Prepare)?; // no need for CH32V307 + self.send_command(SetWriteMemoryRegion { start_addr: address, len: data.len() as _, })?; - self.send_command(Program::BeginWriteMemory)?; + // if self.chip.as_ref().unwrap().chip_family == RiscvChip::CH32V103 {} + self.send_command(Program::WriteFlashOP)?; // wlink_ramcodewrite - self.device_handle - .write_data_endpoint(self.chip.as_ref().unwrap().chip_family.flash_op())?; + self.device_handle.write_data_endpoint( + self.chip.as_ref().unwrap().chip_family.flash_op(), + data_packet_size, + )?; - log::debug!("Flash op written"); + log::debug!("Flash OP written"); - for i in 0.. { - // check written - if let Ok(n) = self.send_command(Program::ExecMemory) { - if n == 0x07 { - break; - } - } - if i > 10 { - return Err(Error::Custom("Timeout while write flash".into())); - } - sleep(Duration::from_millis(10)); + let n = self.send_command(Program::Unknown07AfterFlashOPWritten)?; + if n != 0x07 { + return Err(Error::Custom( + "Unknown07AfterFlashOPWritten failed".to_string(), + )); } - // wlink_fastprogram - self.send_command(Program::BeginWriteFlash)?; + // wlink_fastprogram + self.send_command(Program::WriteFlash)?; for chunk in data.chunks(write_pack_size as usize) { - self.device_handle.write_data_endpoint(chunk)?; + self.device_handle + .write_data_endpoint(&chunk, data_packet_size)?; let rxbuf = self.device_handle.read_data_endpoint(4)?; - if rxbuf[3] != 0x02 && rxbuf[3] != 0x04 { - return Err(Error::Custom("Error while fastprogram".into())); + // 41 01 01 04 + if rxbuf[3] != 0x04 { + return Err(Error::Custom(format!( + // 0x05 + // 0x18 + // 0xff + "Error while fastprogram: {:02x?}", + rxbuf + ))); } } + log::debug!("Fastprogram done"); + // wlink_endprogram + let _ = self.send_command(Program::End)?; + Ok(()) } pub fn ensure_mcu_halt(&mut self) -> Result<()> { - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if dmstatus.allhalted() && dmstatus.anyhalted() { log::trace!("Already halted, nop"); } else { loop { // Initiate a halt request self.send_command(DmiOp::write(0x10, 0x80000001))?; - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if dmstatus.anyhalted() && dmstatus.allhalted() { break; } else { @@ -319,7 +383,7 @@ impl WchLink { // SingleLineExitPauseMode pub fn ensure_mcu_resume(&mut self) -> Result<()> { self.clear_dmstatus_havereset()?; - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if dmstatus.allrunning() && dmstatus.anyrunning() { log::debug!("Already running, nop"); return Ok(()); @@ -330,7 +394,7 @@ impl WchLink { self.send_command(DmiOp::write(0x10, 0x00000001))?; self.send_command(DmiOp::write(0x10, 0x40000001))?; - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if dmstatus.allresumeack() && dmstatus.anyresumeack() { log::debug!("Resumed"); Ok(()) @@ -346,7 +410,7 @@ impl WchLink { /// So this function will use the register access mode to write a memory word, /// instead of using the memory access mode. pub fn write_memory_word(&mut self, address: u32, data: u32) -> Result<()> { - self.ensure_mcu_halt()?; + // self.ensure_mcu_halt()?; self.send_command(DmiOp::write(0x20, 0x0072a023))?; // sw x7,0(x5) self.send_command(DmiOp::write(0x21, 0x00100073))?; // ebreak @@ -354,7 +418,7 @@ impl WchLink { self.clear_abstractcs_cmderr()?; self.send_command(DmiOp::write(0x17, 0x00231005))?; // x5 <- data0 - let abstractcs = self.dmi_read::()?; + let abstractcs = self.read_dmi_reg::()?; log::trace!("{:?}", abstractcs); if abstractcs.busy() { return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy @@ -366,7 +430,7 @@ impl WchLink { self.send_command(DmiOp::write(0x04, data))?; // data0 <- data self.clear_abstractcs_cmderr()?; self.send_command(DmiOp::write(0x17, 0x00271007))?; // data0 <- x7 - let abstractcs = self.dmi_read::()?; + let abstractcs = self.read_dmi_reg::()?; log::trace!("{:?}", abstractcs); if abstractcs.busy() { return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy @@ -379,18 +443,18 @@ impl WchLink { } fn clear_dmstatus_havereset(&mut self) -> Result<()> { - let mut dmcontrol = self.dmi_read::()?; + let mut dmcontrol = self.read_dmi_reg::()?; dmcontrol.set_ackhavereset(true); - self.dmi_write(dmcontrol)?; + self.write_dmi_reg(dmcontrol)?; Ok(()) } /// Clear cmderror field of abstractcs register. /// write 1 to clean the corresponding bit. fn clear_abstractcs_cmderr(&mut self) -> Result<()> { - let mut abstractcs = self.dmi_read::()?; + let mut abstractcs = self.read_dmi_reg::()?; abstractcs.set_cmderr(0b111); - self.dmi_write(abstractcs)?; + self.write_dmi_reg(abstractcs)?; Ok(()) } @@ -417,7 +481,7 @@ impl WchLink { self.send_command(DmiOp::write(0x10, 0x00000001))?; // clear haltreq self.send_command(DmiOp::write(0x10, 0x00000003))?; // initiate ndmreset - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; println!("{:?}", dmstatus); if dmstatus.allhavereset() && dmstatus.anyhavereset() { // reseted @@ -428,7 +492,7 @@ impl WchLink { // Clear the reset status signal self.send_command(DmiOp::write(0x10, 0x10000001))?; // ackhavereset - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if !dmstatus.allhavereset() && !dmstatus.anyhavereset() { log::debug!("Reset status cleared"); } else { @@ -443,7 +507,7 @@ impl WchLink { // Initiate a core reset request and hold the halt request. self.send_command(DmiOp::write(0x10, 0x80000003))?; - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if dmstatus.allhavereset() && dmstatus.anyhavereset() { log::debug!("Reseted"); } else { @@ -452,7 +516,7 @@ impl WchLink { // Clear the reset status signal and hold the halt request loop { self.send_command(DmiOp::write(0x10, 0x90000001))?; - let dmstatus = self.dmi_read::()?; + let dmstatus = self.read_dmi_reg::()?; if !dmstatus.allhavereset() && !dmstatus.anyhavereset() { log::debug!("Reset status cleared"); break; @@ -503,7 +567,7 @@ impl WchLink { self.send_command(DmiOp::write(0x04, 0x00000000))?; // Clear the Data0 register self.send_command(DmiOp::write(0x17, 0x00220000 | (reg & 0xFFFF)))?; - let abstractcs = self.dmi_read::()?; + let abstractcs = self.read_dmi_reg::()?; if abstractcs.busy() { return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); // resue busy } @@ -523,7 +587,7 @@ impl WchLink { self.send_command(DmiOp::write(0x04, value))?; self.send_command(DmiOp::write(0x17, 0x00230000 | (reg & 0xFFFF)))?; - let abstractcs = self.dmi_read::()?; + let abstractcs = self.read_dmi_reg::()?; if abstractcs.busy() { return Err(Error::AbstractCommandError(AbstractcsCmdErr::Busy)); //resue busy } @@ -541,7 +605,7 @@ impl WchLink { // Write command self.send_command(DmiOp::write(0x10, 0x00000003))?; - let dmcontrol = self.dmi_read::()?; + let dmcontrol = self.read_dmi_reg::()?; if !(dmcontrol.dmactive() && dmcontrol.ndmreset()) { return Err(Error::Custom( "Value not written, DM reset might be not supported".into(), @@ -549,10 +613,9 @@ impl WchLink { } // Write the debug module reset command - self.send_command(DmiOp::write(0x10, 0x00000002))?; - - let dmcontrol = self.dmi_read::()?; + self.dmi_write(0x10, 0x00000002)?; + let dmcontrol = self.read_dmi_reg::()?; if !dmcontrol.ndmreset() { Ok(()) } else { @@ -560,38 +623,6 @@ impl WchLink { Ok(()) } } - - pub fn dmi_read(&mut self) -> Result - where - R: DMReg, - { - let mut n = 0; - loop { - let resp = self.send_command(DmiOp::read(R::ADDR))?; - if resp.op == 0x03 && resp.data == 0xffffffff && resp.addr == 0x7d { - // special code for NotAttached - return Err(Error::NotAttached); - } - if resp.is_success() { - return Ok(R::from(resp.data)); - } else if n > 100 { - return Err(Error::Timeout); - } else if resp.is_busy() { - sleep(Duration::from_millis(10)); - n += 1; - } else { - return Err(Error::DmiFailed); - } - } - } - - pub fn dmi_write(&mut self, reg: R) -> Result<()> - where - R: DMReg, - { - self.send_command(DmiOp::write(R::ADDR, reg.into()))?; - Ok(()) - } } // marchid => dc68d882 diff --git a/src/regs.rs b/src/regs.rs index a13bbbe..19d0106 100644 --- a/src/regs.rs +++ b/src/regs.rs @@ -14,6 +14,23 @@ pub const MCAUSE: u16 = 0x342; pub const MTVAL: u16 = 0x343; pub const DPC: u16 = 0x7b1; +pub const DMDATA0: u8 = 0x04; +pub const DMDATA1: u8 = 0x05; +pub const DMCONTROL: u8 = 0x10; +pub const DMSTATUS: u8 = 0x11; +pub const DMHARTINFO: u8 = 0x12; +pub const DMABSTRACTCS: u8 = 0x16; +pub const DMCOMMAND: u8 = 0x17; +pub const DMABSTRACTAUTO: u8 = 0x18; +pub const DMPROGBUF0: u8 = 0x20; +pub const DMPROGBUF1: u8 = 0x21; +pub const DMPROGBUF2: u8 = 0x22; +pub const DMPROGBUF3: u8 = 0x23; +pub const DMPROGBUF4: u8 = 0x24; +pub const DMPROGBUF5: u8 = 0x25; +pub const DMPROGBUF6: u8 = 0x26; +pub const DMPROGBUF7: u8 = 0x27; + // GPR: 0x1000 - 0x101f pub const GPRS: [(&str, &str, u16); 32] = [ ("x0", "zero", 0x1000), diff --git a/src/transport.rs b/src/transport.rs index 2ee82d5..1d54f68 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -4,13 +4,13 @@ use std::time::Duration; use rusb::DeviceHandle; -use crate::Result; +use crate::{Error, Result}; const ENDPOINT_OUT: u8 = 0x01; const ENDPOINT_IN: u8 = 0x81; -const RAW_ENDPOINT_OUT: u8 = 0x02; -const RAW_ENDPOINT_IN: u8 = 0x82; +const DATA_ENDPOINT_OUT: u8 = 0x02; +const DATA_ENDPOINT_IN: u8 = 0x82; // 1a86:8010 1a86 WCH-Link Serial: 0001A0000000 const USB_TIMEOUT_MS: u64 = 5000; @@ -24,7 +24,7 @@ pub(crate) trait Transport { fn read_data_endpoint(&mut self, n: usize) -> Result>; - fn write_data_endpoint(&mut self, buf: &[u8]) -> Result<()>; + fn write_data_endpoint(&mut self, buf: &[u8], packet_len: usize) -> Result<()>; } impl Transport for DeviceHandle { @@ -55,7 +55,7 @@ impl Transport for DeviceHandle { while bytes_read < n { let mut chunk = vec![0u8; 64]; let chunk_read = self.read_bulk( - RAW_ENDPOINT_IN, + DATA_ENDPOINT_IN, &mut chunk, Duration::from_millis(USB_TIMEOUT_MS), )?; @@ -66,27 +66,31 @@ impl Transport for DeviceHandle { return Err(crate::Error::InvalidPayloadLength); } log::trace!("read data ep {} bytes", bytes_read); - if bytes_read == 4 { - log::trace!("recv data {}", hex::encode(&buf)); + if bytes_read <= 10 { + log::trace!("recv data {}", hex::encode(&buf[..bytes_read])); } - Ok(buf) + if bytes_read != n { + log::warn!("read data ep {} bytes", bytes_read); + return Err(Error::InvalidPayloadLength); + } + Ok(buf[..n].to_vec()) } // pWriteData - fn write_data_endpoint(&mut self, buf: &[u8]) -> Result<()> { - let mut bytes_written = 0; - const CHUNK: usize = 64; - while bytes_written < buf.len() { - let chunk = &buf[bytes_written..(bytes_written + CHUNK).min(buf.len())]; + fn write_data_endpoint(&mut self, buf: &[u8], packet_len: usize) -> Result<()> { + for chunk in buf.chunks(packet_len) { + let mut chunk = chunk.to_vec(); + if chunk.len() < packet_len { + chunk.resize(packet_len, 0xff); + } + log::trace!("write data ep {} bytes", chunk.len()); self.write_bulk( - RAW_ENDPOINT_OUT, - chunk, + DATA_ENDPOINT_OUT, + &chunk, Duration::from_millis(USB_TIMEOUT_MS), )?; - bytes_written += chunk.len(); } - log::trace!("write data ep {} bytes", bytes_written); - + log::trace!("write data ep total {} bytes", buf.len()); Ok(()) } }