From 5ddac977a9db7e966969ec8e912af0b903f9539d Mon Sep 17 00:00:00 2001 From: spacemeowx2 Date: Thu, 3 Dec 2020 21:47:28 +0800 Subject: [PATCH] Add handshake code --- Cargo.lock | 710 +++++++++++++++++++ README.md | 2 + blflash/Cargo.toml | 19 +- blflash/src/chip/bl602/eflash_loader_40m.bin | Bin 0 -> 29264 bytes blflash/src/chip/bl602/mod.rs | 1 + blflash/src/chip/mod.rs | 1 + blflash/src/config.rs | 34 + blflash/src/connection.rs | 101 +++ blflash/src/error.rs | 50 ++ blflash/src/flasher.rs | 84 +++ blflash/src/lib.rs | 9 + blflash/src/main.rs | 51 +- cargo-blflash/Cargo.toml | 7 +- 13 files changed, 1064 insertions(+), 5 deletions(-) create mode 100644 blflash/src/chip/bl602/eflash_loader_40m.bin create mode 100644 blflash/src/chip/bl602/mod.rs create mode 100644 blflash/src/chip/mod.rs create mode 100644 blflash/src/config.rs create mode 100644 blflash/src/connection.rs create mode 100644 blflash/src/error.rs create mode 100644 blflash/src/flasher.rs create mode 100644 blflash/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 628bfbb..836e1c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,9 +1,719 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitvec" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blflash" version = "0.1.0" +dependencies = [ + "byteorder", + "deku", + "directories-next", + "env_logger", + "indicatif", + "log", + "main_error", + "pico-args", + "serde", + "serial", + "thiserror", + "toml 0.5.7", + "xmas-elf", +] + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "cargo-blflash" version = "0.1.0" +dependencies = [ + "blflash", + "cargo-project", + "main_error", + "pico-args", + "serial", +] + +[[package]] +name = "cargo-project" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b735b1b2cf3bc8eed47b20da5ba5b8b33f343700d367e4e536b6f3054ecbd3a" +dependencies = [ + "failure", + "glob", + "log", + "rustc-cfg", + "serde", + "serde_derive", + "toml 0.4.10", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50aab2529019abfabfa93f1e6c41ef392f91fbf179b347a7e96abb524884a08" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "unicode-width", + "winapi", + "winapi-util", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deku" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58899e303bf5a70317f3458bcea62f62eb485d8a901e52f72b7fab74a735bef" +dependencies = [ + "bitvec", + "deku_derive", +] + +[[package]] +name = "deku_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4fc5c2c06069f7400c2c639b567b0559e72ce79913f6955365cce52e513e6" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "directories-next" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a28ccebc1239c5c57f0c55986e2ac03f49af0d0ca3dff29bfcad39d60a8be56" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99de365f605554ae33f115102a02057d4fc18b01f3284d6870be0938743cfe7d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "env_logger" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "funty" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indicatif" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "regex", +] + +[[package]] +name = "ioctl-rs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d" +dependencies = [ + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "main_error" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb63bb1e282e0b6aba0addb1f0e87cb5181ea68142b2dfd21ba108f8e8088a64" + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "number_prefix" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" + +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + +[[package]] +name = "pico-args" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" + +[[package]] +name = "rustc-cfg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad221fe7cd09334f8735dcc157b1178e343f43dfaefcd1b09d7fd4fc0921b6f" +dependencies = [ + "failure", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + +[[package]] +name = "serde" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serial" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86" +dependencies = [ + "serial-core", + "serial-unix", + "serial-windows", +] + +[[package]] +name = "serial-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581" +dependencies = [ + "libc", +] + +[[package]] +name = "serial-unix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7" +dependencies = [ + "ioctl-rs", + "libc", + "serial-core", + "termios", +] + +[[package]] +name = "serial-windows" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162" +dependencies = [ + "libc", + "serial-core", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "syn" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd2d183bd3fac5f5fe38ddbeb4dc9aec4a39a9d7d59e7491d900302da01cbe1" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "termios" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" +dependencies = [ + "libc", +] + +[[package]] +name = "thiserror" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "toml" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "xmas-elf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74de9a366f6ab8c405fa6b371d9ac24943921fa14b3d64afcb202065c405f11" +dependencies = [ + "zero", +] + +[[package]] +name = "zero" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/README.md b/README.md index aa46a22..6da921f 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,5 @@ BL602 serial flasher Inspired by https://github.com/esp-rs/espflash + +ISP documentation: https://github.com/bouffalolab/bl_docs/tree/main/BL602_ISP diff --git a/blflash/Cargo.toml b/blflash/Cargo.toml index 49ad5c1..be49478 100644 --- a/blflash/Cargo.toml +++ b/blflash/Cargo.toml @@ -4,6 +4,23 @@ version = "0.1.0" authors = ["spacelin "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "blflash" +path = "src/main.rs" + +[lib] [dependencies] +serial = "0.4" +xmas-elf = "0.7.0" +main_error = "0.1.1" +pico-args = "0.3.4" +serde = { version = "1.0", features = ["derive"] } +toml = "0.5" +directories-next = "1.0.1" +thiserror = "1.0.22" +indicatif = "0.15.0" +log = "0.4.11" +env_logger = "0.8.2" +deku = "0.9.1" +byteorder = "1.3.4" diff --git a/blflash/src/chip/bl602/eflash_loader_40m.bin b/blflash/src/chip/bl602/eflash_loader_40m.bin new file mode 100644 index 0000000000000000000000000000000000000000..bc609b19c58884e2a77ff82179402244538a7ec3 GIT binary patch literal 29264 zcmd6Q4OkRcmgudjuBrw_ASIxVCT%xrbQ42pg~XYVZs_h3jf%gRj3#0UXyOlo_>&p4 zKvUgfMo~+|--x1^xI1|nI?^-F8UdkOO-4;3f>~qKRxp_)paEKw2=Ck~y3{1I`}Vzk z?}1-gr|v!X-gD32{i(XA6K#`I2!xO=$;S65P-w=EZfY;ui!`l>@am>DF=Q<2L-Zkj zP5c$TM*N-pJ4vP>0uclv36l61f*yXAl+2nz0(b8e4AB$UC4@*kl;diu+y)6XqveEMabe#EtLrw>2(^>;(I(Irv3JB=|v zo&ap+@2hJu43yMwT8_}zwI`QK>tA118cyh>d?GI=OA}K%4I!x@F;u!1i*hzii;Ibb!UmS2?$4#Xvb%yEp@L0H9kp^BlmVfR;{gi)&+b)5LjPb5_*nx9Y#0KT z5ePryE3fcT6)lkVzk63J0w7RFAPqlbIFKHAer7hIPk<|s_tSd-AE*EHFHpxXr3cFW zSMCqibF_!vK-!Ek5A*L^cwRU5VgBjk2>rjoH9MZrx5KsR8AAWWvxNR6TnolQAAe2g zcf<9}ZwUQ)xU!xj^nDWu{o8O^o>zDfXzvO<|K4;zZGc&U--mljBBB2pE{wY_iO@$| z6u7$QKF6v&-+}v98=;TkmFGa+f%`}QAbsI@=xZ{eFN5nh69|11Tq`CL`mh%W{lCIB zeiEU-4p-h}LO*y4q5m^nGg5FH?>b}G#W_dWg>8(kbRk&By0`BLUG>4{OkqWHFvqrq z8sojFAM2XcjHhCd zM!%PIHF{;5jp7|L0cfs}Y4-QfTmdw<0L?`}vqz=b6QFrrlT0&5JV-M~1ZW;77UcEN zoY4d{?{OOk+(fPh;3anhxn?Ombd|Os%tzPFP9#NXi5fe1LEFR2sl_gbn;h*Be&2`^ zOF0MdGLt2Q+(yJXZgeM>x|l|j5x7~a#eKruOk`bRBk9VFBI2MoZd6;!If0ukP^!ZX zy=m^QE!|KoMKHw04fV%_YYqKD{$0%^r^WJb0{I)8no(&w=!balLTw3kl137Z$Z^|U zB5fA0(!B3R=WXNIdc^S&=-K0LT9!$3)sJcXMYl1PAza(4(8Z0?Wri>|vV?1OBjqY} zBjaqEFba2&RLbBU&IayBR)J16Qngy+P0*y`7INH1;rBO*xb0j&;D2Tl5^`@6T)&p? zxa~&mO|xrt6J?y;1o*CvEG0!zP>-wS4oZZ6HWF2(9D4`)*@%RWMuKB+c2|`q_H#KK z%{5DnncpIAU01g;hb5%hEMZ*DfW{j8QIv6=mXc=mBaGAuGEv&O&9&|%iM6P6J9mL0 zDz^()q9~sfb+IP%UevvfwT$tNE@X^2f^KiixB8YhTw5D;&;?@$Kk!&3*w$g^=yk$& zW^ic+aL?hX74Cp_3Bns0T8;wk%sGLE^2X`SXy-QS41+idxcU~fY!>=b$W@Y#j4#&{ zt^payxbOqyib_XV4~(l$l3WQ`SiW=tD4%^&(N--@33nL6vrV`WNnnaS+guLDYy>T> zWq~gjJfw?hAh`&ZI8`j%X+)k<;YJi-VyL9p*pP|xtp$1Ulq|iB3|TvgX4>YO9Z8up zgzrvjIc!lmkzi5A3pY{aPiY=VF)lH}%r$BWg+31Gb9LSzT@5$LTIS=8F8T;5+^IqV z8ZqP&t4tV2rV;Qk4p+j+G`dw9F|?uhPsigGd%t?}P8xsYxNG}DWNZWu0cS9$xCYSp zm4`@~b4x!!5^$*|pTp8jJtR|Lblw08npFxgWOOu}Tr0s&`f)D<<}9!s#^|UgT{k=g z$P0N&gc}jSCk$=g5aRZI+we75NJq0q>IW9$zKkv8Q?L-(gRVQUbG!YF7IFO$dGsw~ zzsqJJsvjv_uR_A2dgNm3O(h$QV>^&>-9b}=SSzkM;?~L>Z;kvRjZZ&rOuYd1;vp_> z?wd z3VSTDm=3TQs-?SXyKCJ|v$0!Cxtg?8VyJOl1SOTQP?szHIP!qS&_q><1#+IUNbR;d=cBGBREh9%152jg-$6>ol@AOvbS{ppA4> z(FRv3^gY!}7;m(IhpZ<`TyB=o6XA9*tJi-NKZ8u<*sw58Q@59_GxWcTm@~sq8&EqU zYYhy6TEof)xKqhQ!@5InQC1CdYskdbur{8swx(nucRHbuhf5O0=Q!GGYE3~4?x$JJ z98FtVQ>y3Np(MuR=z9E|)*2RL9gkX5Hm#v;`BvK68kRD8y~v3g)H<(>P%uSkLH7y? z|C<){l>Hsl|1!mE&<#wub43-Zss* zd}1N2bQ;*ELJ5@9y(seIQ8{%BN}tODs(!upxRNVE9j4TaZv12phrT5<9>AaF9ziC? zr)rSo^oDY*|NZ!3z?%atCXNd)kAIi zI;d}IJn*w99k?HgOO#}e-YPl$?@OXpuF(+P4m`bL3)E_eIAD@!E4nlhV+ZQiL%(qC z0jwe`Rn8M7nYbpyySLVJV$GYReMk+?r+_voiY6!nPef#LY-ZiXVvMuds$k{H{g-Kc z0rwd3a;bxCSxx+dy&#|$^d$X9!%s73Mi*8Vwx-OpZ03b;N)bngnWjF^X~Il;QQ_-JJ3$DmvNi}DOi4Jv0oMh5mODravYt|S`m7h}ikOT;?6Hv&-}8reO= z5ak_<_Oq3xwM!eS`cNM0hBEOs#XAX8f4J?36*PVkb(XfmD9J-ev5&;inv^VD3*OhrhN+Z zVhZ$P@)$%-E<{w)R%9Q408!)LSG7XwY!Ag+VGtWlagN2PoV-OCsH;Rd^)UgxCd!#K z=yfe}Wb3q7|eEQm1%D>h|#(kY0aew}M1%7Fj2;J{mM2Aq_zo=zX9Ge?nMa zv99W^u{_p=k_^ew`Tp`9%XeXKU^vid8dW#W1M_883Q7UWQcS)Z6`h<0X@mYC&?^O#@aplMi-cY6W283gwFm6MdfQn9sC)>FVi)2o<bxRr@P@yyZQT9Kw1y9C3n{bjjgY^aUqo~ys^M?J9 zrHtlb>_S3*OW&cq(C14OZjFdjv@9_>T()a$(^L}B2vViSMOQz5E!ty#$Qm;OjTFAS$&6sFy?@88)|o zreb){uuO|`@9_KWLCXO|c;o}n=Ps*Hrb~%hjlk}H{e>VBTwDZj62~D#;iGK<6 z8+^JcCX*U5p-kl6rwGtB;5p+*?vc>bqU4l)ys)tyc%L2{ZoQo{f5s;>5?`!*QUB7G zmxf|3nW6zN2{tu38ocBfkOpucdP9w0AonmH#v+OF?voshhGV_^2$%;fLXcH zl^=tztRWtj3yjjHlt&3`(4tmTo1P0QGU+XDpp`Bg4w_V^GisvEryZQ*^hjLS>8-7% z_lD~0hSyF2Ydbx1Nc9$rZ*kF&*lxi7=u;zcDbtYs4vsk`mjL`nxx!?mci{5!Q&BSM zUI6nJvF>-!_AD$XS_6FftuLym%bltNj}Lq=yNm3=Cy6$ZlVv#*)_X^=rD5)hOlh+%3l3ZEZVV`2Uo@+8+M){V9LvX@7ygef~54BKjfzY9HdSmV21L;DdVjYyDs2 zuRIba|J+Z!_v;7zM1kxl`eHxP+IF_J*LezbF8hDMQ#|tj#8aTKSO1ZxFymR(czNDx zdT&@OiV+A)J|FaDg4o)&>@&Ss3Dy{xzc?O9`ZS2Rve+NcvJX+gr;8nnf;t^W$iuXrt!vo_| zrB!dmBdVc{Ed%Oj<^%QS&wIv0pf+p32FnKiMR~@*27ASc`t!p-QRXMpKALq}@rYrO z60DZ+O6gY53JFG0XS-Hn^JrmbyG9*`7Jooq|I@OJ-&k7DuA2tnBuS08P9%31bJ+oAWcPS){85`OW z%q>hHUw2?;Xp(1!Shf$!^C3Bd>}B~f_g4!K&d#u$V{Q7ttgL5bmU2Da%Xi_?d0gFS zkDhy!`zY z-Ddhfnv>T*)Z2ME(AziL(J=5j%idP{I_zhw4hm~C537!!%t$INfw>Ew3m7!8I_mI; z;yJ#uuEVo@&JU{$SRvxM$2fULX`rv0?$2XB#=16CUm&8U8NelE_`sESRM*<@P07Y=?78|y$U08bw;-JUaCNK$aZEQ zkz9sng8R-&U@x4buDcbz_p4Eb5jSuSVa0j*EhEdqt>G5Xw@u)KdaT6?Gn5ExgykDq zQx$JDZ#JfXAa5vZDH~`VXu0bi|OBcU*5=5L6+g+eSaCjpO! zdA^AsYHf|ldXXC&f!6jvyfwESOP)ItjTAo$b+B1kN*ys_%o$uBq%^e#_6ykMkE4V- zu<4Wy)*(>KxoJgK@CY#}({9T)I;VFzK-LZ-c6FjVVZHmJskS&Xui?k zt3bn>XY@eKH~l~CN$Z@^17&>Q|E!W$@x3AJ5Hb)fnsJsBy_*X1aIfQMf{n8En>gqt zp4G;WILC6V)6{e#egw?M*vyFSUIpTZH1$9up5FeUl6L6nrXGkjZa=G}v11JRENVIn zejVBvvV6a?^QEzXhouOu>9cC=SKiG5$tU_zL>OS@BpcjfPgH7a_g<9%DCbBp1Xg6LR@P{|-^HQGYklp(v ztgVJ1J@}|6eN=r2N@Up2C=Lhq1>(-{wWjAHOgk=d?DIZ!6-B;yqZ2 z(4eD-xB0$eyQTKdP+!6IJMK(817?5QYSInIEt+73ifb_q8*GZ@H^VNM;oYn9E>l72 zFt>v3g*Huwr`=eZ=5T#od>x^uMrgX-sg@TR4`^|;p!FkpPLRGf;{LpWo(uN%m>cHK zhQ~EsoYOiNuWp1OKMJ?OuGm~WJ83nY`xP$f=94DIdqMA<@ezi{{au8-3r2+FT}{i2 zcI~VWK0+KtvKDF3+hQ#)_HOd zm=4k$KH70u#F*HNYznP3{c;a}o~l@d!pq^ccn(I?OHQ+R@`M?zGo~+X+b7#;*;0-^ zN4CaPKSslzU~9~K8efRmrPweML>XsZrbHte=U!Pr*fz^)y4MKX1{unGH6ARPV=@>e z=Sr6HJiL#Re`T4{Lf(K7n}~OAW3u3VmRZF0l_g1H{+k$@H%)J;G;Oiqmd(Vn7$o~v z`$2wh5qKG=$t7ZLfL7q0pb>?8so{lt2`l35}2xZZI1;#-D))x70f*!iPD_Z7P94)l)k6u}z25Jn>dg5B+yvIz?R%4jq2 zDK9Hu=6YF*yz+rj>Xi!2Ki#7Ha?9fboUUFJ;52$tk)>`@k8BfLW5RN=O$2NJ=j%UW z&d?UvA&fDl38YBMqf`aVeq*w7gspU#F#kXp)>m`-nh4w{rOqpp6`Jzq#AnVYX_{l% zGNbhn>28UH*(Vz(e0WHU7FW4$>XKWDufc*a(FScJI{W1>0H?2u;&Q`KDX zMmQDklS_qW2l&vH_IeH4%&!KYOWTeW;au>QzaMfHIAV$k#<@7{n4Amvt1)d4zq_E* zfPzUi$IaoGI(U;{s{UuC9$mI_pO^e9GFI&v&>ZXTBQT~A?0aaF7}thPaiJC z&x*$!4IUG`<@}&iO3PU9X?f;~apqfYo6a~UI4YA9lPg3#r+_+_;~IenkdOPHCsdm7 z{KH6>nR0i8(AdA<&(*#1^W0eHD2F-xT?eiqA9LJv>zAX#~qnd z7~8Zkz;P@ec~_$P-NI4wu3=s-yh}IiFDcqE!GXuGEAS>mZ`ooYVIK}thB*M9q7W>_ zlsBFJ2HpZtq^F1%`ua)HmWA@IdMH(vg8$E(N_>-r^r8sf5B$Uw%pt|gV@Tl=&M$)f zEXbd9KOgUW1DD~A0&_us9`AZ%K9{ou9;H{~euEUJSBRX`?7;lR+7Lz`E~Kn@euh?I zj2+KE`K8?py7A`SD9PU#Dtd);8jWH@)>pv3o`C+vq&yv%=iY`MT0zT|+UMC8UF@+% zY;Pldb($Z0%Fcu5$8p(BPu?#}%Vm2ophU{>so>XOKdl;bcn?3S=-tAg{LQp*&r5O| zPd7IU*19pe=cU}b?#;B3jwWbZMM+RTj5N=|dq7ilw6CAo72rMQd{6=4|E59qmP);& z3Sl1`v~S)}Ze}#XqX;)^BSvvJspi`Y%vt^4hJQHOd-?LUOU<8s)immp(M7TA z<7yAD&!5Egsb&%`P&~Yc2^oY!yi#A7|Mz{5l=>i2VpB+g^=s%5q2o!ykoOf5gDL)A zw-~a-FSI{N8S;YB_oi1ZOU2JD6OxZ6kD9P^Lh!`S-)79YFvm8xYHkQf(uab&wxlNP zC=U(l`uMn=4?%Z7m6$B@RcF41V`50b(b!M$clMQF9v~FCM+wEH|0IacC-I6yVxv&a zWx~QmMZ;=|xu-8ZI9|$yeQm0YWLQpwH{I9&OxisxGHRO9u?r%59~0v#IKH+&cL{|V zFblr|Ei}hbJdG085B+rQ%lS5r3S%X09>dXPj6_#!gwRY%NdG${kWpiW#|{m~d>Q!f z95VmgrLUPh0f;H5*xz`gny~vgEw7l8{-S{BUs0=vFio4 zk$F&d!AK18QS5ar*&#=S(5RV0pF9H5&WdEZWQ_)WWKd zjJrf6VLl{$R+Bt*GFgr3aj}0fCsglG{h;<*>JDEe+y|Zz##4#LmW7DCT;LIC_EqkS zyJk*i(^t)A;ddN@&n(PJT~D{O|ox*_c}ZS zzc43-H<>ZQv~whF6C9o~Af26_FJht|G~Yw?LpmB_9=?)xG3^PnR}O`b`*4$@iA zyg#k>$zu}J)y??}(d}yDL(Uo0&BcR-vhnDHY6s8xEriR{N#0JKTWpNKg5utCvEQN( z>aY%(dBO3eUg{WwHr%M-g-@NNk!?3!fDxUe5m~?sxt++62YV$9&G-g3cMZ1;EQ4IW z3U*rAFvw5y_orF8CXnK(LBPfQdcDi(Arj7ImkP70`$&y<%?Wi5eq3?ED+!(>W%r`G z3Px{?D^BoK78mf5Cnr1h+ic=aQCQVY4!Uf+l>OQ3XU2j4x1M`t$2Pt;F?)JKiQPt{ zYqO`loIPbe|H+i{;!nDiGLs$IXI}qk-03$?ww^1#l0EtGy3zL9Dbx7*Q-l|*sY+fd z=D!dg7x9C*8^#x86xRXeNp`1-KBvA>ynlHij&H{^MMcXy9Tj_&R^HvZ)pBnN%U;Ve(^?TlT zX~WDSZ;TIvZ}#SyjPNBQj5V4AdrJ5$c708R6ThbW*VzvC8+iv!8PtA49jQlzst)Fw$WP3wVx+Lc$xJ=vu1Ca8;nSOtpzy$$)h^ zfLorfAU5Ji1z*H|Pxr3$`op#_T3W2>0tT6$zhVim+8BT#8-4g;#v#(ZYmU z?$bMFY&-8HfBA2|sT(g>@V?8=OGc*MG;W(jBMRur^@FBWVNGLw1HGVWOa6*S2p{2x zw#rx^>Hk(B9vC5l8y|-iVzfL$Ab(%s?=3ocgb4S)g{er8Ej_@OeaUmHe4P8o&9-me z$CNE~(AMp+K_8rV8}8NSOXE$`*y0BI5kfXy^$cn2vOX)T3CZ3%=|+ zvrSkvg0OoSm@SkSf7S(*M!35%HfYaQ%_CSZ1cLn$>%_9Qr@rU>{gIKqVluz!V%{fU z^+pzL6mp06%s0TI23_bHRk-}P%&T{>l!T2zeJ6_vwb|7dN0F1a@Cmg`9edncc!k!_ zYr$V?z{ZL_TJV=|dHNc3Zo;4kZ;4yhuypx;^`h{CT3A5PeFX=XlhfKs-z9QjP}C( zzOf5-^Ahon8K6QqikrerR>;qy_IJT z#@}c<$?Una>FKv4(dM|BX?C!m^Jtp;D+FmK@y|fi~_g>o0cJyA_Lci|4v`x9z zduc0f>b3$5?Hv`zVI@1?EyPyfBN1>(R3?*D!7Dy_QzyOahfzJJH>)!`jB zoQ@EA1L{EV9lV-iKr}q}eDAwp8Jz9JFg~+KXDDAt!ztKBInlZ?IDNke>6vi0bK!T< zVR8z5iA>WA;Y@1Acf(@j6gWGDpVOt>_UB7@LF{0J>uwUhlXe2s?$&JJg`y4y&hqW) zV3c<0rGP)5DBA<)J^|-ihjt%)`_-X6$P2sR3?H-$b*_Zdbn`ZAayIoJbMd&y3vYGw zME0p)1oXUes^^Se{W75U<(cxyL^!ec8l0+~JGUo~UIOP6=cM)I)vsA|3v1OAH#12wMz{Micr=HvLQ1TJbAd>i0hLxdkKo$Rs0S2Fk;dFntAX+Mxm z;+PcDs{UwHQIS`IuWf{U_7Q1SG|GpkXmsyGX_ZBWE$9}&g)&@-{sypyz&IM>low!9 zhRK5`0M^K`X3tq}g+?1vC$(#|C0Fn%xJWqLMN6Z0P=-^45JVyT^}TZ9h)yHz4}6~w z-v;9o6H?TR@Vy`_9WC8GrQzQTO0CCnDo(*UM@!-SDhpqT9r%(w)mTspr=1_l-96FF zyO=UWhT(DJBe0u z9qiWyr5BHEH&bt0kvoIXOHm^r-@&>XSt^)@NN;NnZyRadlxX)HMB;dt{}73zbV=@1 zG^ALHVu?i7Y@b^^z%w9me4=2F?DO#%(8iq*4{??M9+%s3kIQ5UE}bUqUJ=Z?h5TSJKJWjzkx)Xw5kQlHXtc83eEB0lOZ&mTw(Jr z7GHHgx9hnb5P>6;rGO&pn0!tS`UqNfxO8ih-Aki*`f4{-Vbf9&`)F;%y{JVSYuS&B zAy(VfwUKM1ZWYgGAy(7=PAzqa(Ngup5UsS=zg}+7UOyI6WXiVI%aj?)njxA4_yo}C zKueszA#`_AP|Nlt4rttd;$8&)8Xo$X;YLkzTGNSNE<-?>HM<@tk&a8O+4Xb$?Me3{ z20zHhk zkDoDJDCi(*s|z9sO7OLRN3lRxpgEu7p12?mn*xc}eBKvX)g`rbhAJsPsmC@rRVZoz zIl4-!(BFy&H{$YAi$7F>`q86H++dTyOOciimu#wem{ai0=;JgRayot$2~iQpYeDj1 z`L_5R5~71>kx^_wYvI&}pUOXrzsQ0w9$6~PP|f2XbnWxD}%8E$GlRY2l=!+Y29z>B3%2jwtxO3oW5v# z?2qzkHw`ikw&2r=$94^_8*DjTI9j~AYwpIdy3Nr8ED~7ajw{kCzkL29o&{X*7C1SB zPl3QUWv25JY2Fxd2x4D$bl=^0{zC|mEdM({aps1T4?Gdp+~TGW!Ph~V-@j6`Ywm`H zU&vBm;EOe|3rN4aHtKHie0uH%Ls^BQ|B#1mMgp%+Sh-d4ZD2=bom!<9IQbdmW`FF) zaVQOsH)`>7y!KA_+5xUkhB!kvY{*~Pv0)PAd9~CCHt23KQSW9o=wdOZ0nVMuZD1Hm z_6??w@vhQCpoRW!W643(QGBY{p!4^|G;*mkkrX)sVcfVkMu7e0V z{UL%*JKAT>w-LN6wb>-TDZ$Zkn*Cs#Z=ky?u0&uK!YO+#qP2IAOAur7xed~)4vMyl zf45s_z)5t7S%IT!z}ZL&&f^=<`>33(BXFAr@;sc>zAm>-Sn)X?usIXmj0QCn&-u^|Pfe+Iei-y* zEXv*G0H4YETe^4DaxGDiMk8sJ8=j<09?2zT8&|%Aj0Y{ix^wCD5;$S%=8-9WM7uol zGv(4vfjm<46h}~2R9IllLH9x|AX$5KszhOG*< zR%9Ajw$(iHgyfF|9^CtZ;)4jOv-1b3aRC|xaf@r2c;IGDK`r#3CmMtJcO9J0!4i9EF>F+1diZ|;{$Wsors%m zM^c0vNlojJblFK57cN9_rub6_;exoQH3iHWJcs1^Wl;tVM7M&79)<{rEeDYR%W+hb zs6XM^2_>xj79z~#K~#tq(+k$v!f}qnh4B4X<3FS^QlasrWvJ~5i1!gQ>LY-F8*PuB z{|9CIvX3ZbaQ^nBtrLUnT!RBi4bUGrW>Jm~fR%&Q6JYV^JUTxS=nCalW+JZ1fjGdD z8UTyb5C-Z1#Lj$Q_6u95Jd~?}TpDs|$kjj{59czF%R(*-xy*UAb^3#44chalTniXM zfD!aQ8hP#f^dWCPL}4&c*as-=0~7{B`P2t<4Sk_}U%&_fjF37+d*fyKgMakalblgYd&iw5OLOFBa_I#0hRZ$SE{PGe`hF9xP zTOr2G7jNPy0B|C|ZOXSr^1ap9SBsyYI=vW2Rcs5rC@T3aU>h_}IeT5f484p`ed3d% z=5RNx2=sN-0e&Cj5xx`A=t6g{95GF_zS>&d`qlkNPWarca>ClOZ?Gv4Z-LHq6}b`k z^djM#FXi=0W%6*xX*eki@dM!$@v^qiZ{#=#P%A`~dNrY>wYvC*K{tkgs58^aL@LR? z@7d+pT1I~odp_>MxTb{95--^<3k)SkUBJ=h=7iyPM>#%lNOT*^(V9~Dg1q{v>lkW1 z_ta)M-3*Wzk7bSV!JEVCf;saW6zqVr;lJlrbwIRS9MSGxRCvCjumxgwc)K2lQFAPm z!Mfr0A`*|FhJS7BGQ5jVhXQBn5oxawyMa3u_1zPysRLp+^-g^^;~8EX&f^kmql5+L zk?^}ypao8t%X_=218{%G+r9QXJTlo2IKyDIn@Q8gh65y=9ZLwwH_oajggY$$dLaCl7vvol&0s8{>dNnpZu}^hkx4t z&wpbx7Cf5~o1Pwlod6n5C)zO)~qPlWrsA@I8uaF2!ZQ{g^i z0HI$F_r-k({XDow|BBG3!95b%jf4B6kRA{B#DVa88E`)X<#gHUD{`}!>VR~V2v^d= zbm6s}+$Fm7?CfRP27q56_eA?0li_^2^I%Z_2Wj&a%L`cicNq=rw%rmRy{3YpG!nmHNB`a2@ zEee&rDmaTXY{st}ih=J?*uuWs8=| zSO~qaENy`c$m!vOUp%c;;FVIt(Jjqg5-_4NWJ3Fp$p*hI zg!!DaCTB(Z5}mMkneZB*Ou}{kR30!FA;RGIZroACP^#QnK-v|^t3s?jkjAT!Q-!=L z#1^V}D&$lluL`lEil;(O74oVO>rnAj$f-hJ6=Iz#o(eft$g4u^Iu-9eR1`?_Ld5U)Z`74oVOyFtZMA*Tv?RfyfF;;E2Rg}f@n7OQwFfm~jNoGRp1A$Ds3LQ6=F-&+|mH#RUvkJAdOccrwVyhh~1&$sgP5Jyeh=* zRPj{EsX|^AVt1){D&$lluL`ldRXi1Ps*qQO*gYzq3OQBCt3vEsDxL~CRmiJC>|Pa5 zg`5Dz4*+{JoK(};G8IpSyeh=*Q*%|wsX|^AV)v_fD&$lluL`l{DxL~CRmcmFLZ9}4 zil;(O74oVOdr-wwA*Tv?Rfw%n@l?pELS7YO52<)61QXJLZ&D%l?LZo@LQWO(su25* zil;(O74oVOdsxL&A*Tv?Rfzo;6;FknD&z&|#pS2ZIWFu!UjflxLcWZrk%42X=@-yY z+8XbMH(7Fgy4T@%DB8YoJ$;IXh__WK!)I)p!MvCb>j}Jy|L1F?3Wt8<=KI5pH!4^t zZijso4#PA=(grvJxpUzih?6BDlK5@k-uCZtOsNSX)cCKHj!U$OejJI{uMEd61;|gT`W+p_7!aHt^=P1z9{n@BOfu~8XzlbnJL-S;s zP&=d21S?=n6Q)N9ZYPy>ACAHUt0SNj(*_awzQKD9U+j0YC~xi`ei=u+jdAvt-I8fh z%F#D*+ADjnx*@>+^XhNrokYZc{F`~`C%>7e>wfq*^Jw_Zy#5Hr!25Mh{jb(p_KS5s zM5pdQuagM;w%^nExBc$Zxrs0_=U7Z9)iXx3`Ks=zkW+=cD#RA3cq-&v7fAD}5L*;T zbE=S6h1m6hTwaBoD&$om_DvN}g`D>xb)@pD5W86|p+Zg-@~RN4j${1&5lDr+D#UJ6 p>r)}83VBtCRmUtIpoir2U)HBzmOXlDKKbC<^8ZE~c+Q6Z{wLlzGHL(- literal 0 HcmV?d00001 diff --git a/blflash/src/chip/bl602/mod.rs b/blflash/src/chip/bl602/mod.rs new file mode 100644 index 0000000..eb2f090 --- /dev/null +++ b/blflash/src/chip/bl602/mod.rs @@ -0,0 +1 @@ +pub const _EFLASH_LOADER: &'static [u8] = include_bytes!("eflash_loader_40m.bin"); diff --git a/blflash/src/chip/mod.rs b/blflash/src/chip/mod.rs new file mode 100644 index 0000000..6b79f9b --- /dev/null +++ b/blflash/src/chip/mod.rs @@ -0,0 +1 @@ +mod bl602; diff --git a/blflash/src/config.rs b/blflash/src/config.rs new file mode 100644 index 0000000..dc64cac --- /dev/null +++ b/blflash/src/config.rs @@ -0,0 +1,34 @@ +use directories_next::ProjectDirs; +use serde::Deserialize; +use std::fs::read; + +#[derive(Debug, Deserialize, Default)] +pub struct Config { + #[serde(default)] + pub connection: Connection, + #[serde(default)] + pub build: Build, +} + +#[derive(Debug, Deserialize, Default)] +pub struct Connection { + pub serial: Option, +} + +#[derive(Debug, Deserialize, Default)] +pub struct Build { + pub tool: Option, +} + +impl Config { + /// Load the config from config file + pub fn load() -> Self { + let dirs = ProjectDirs::from("rs", "esp", "espflash").unwrap(); + let file = dirs.config_dir().join("espflash.toml"); + if let Ok(data) = read(&file) { + toml::from_slice(&data).unwrap() + } else { + Self::default() + } + } +} \ No newline at end of file diff --git a/blflash/src/connection.rs b/blflash/src/connection.rs new file mode 100644 index 0000000..b363c15 --- /dev/null +++ b/blflash/src/connection.rs @@ -0,0 +1,101 @@ +use std::io::{Read, Write, Cursor}; +use std::thread::sleep; +use std::time::Duration; +use crate::{Error, RomError}; +use byteorder::{ReadBytesExt, LittleEndian}; + +use serial::{BaudRate, SerialPort, SerialPortSettings}; + +pub const DEFAULT_BAUDRATE: BaudRate = BaudRate::Baud115200; + +pub struct Connection { + serial: Box, + baud_rate: BaudRate, +} + +impl Connection { + pub fn new(serial: impl SerialPort + 'static) -> Self { + Connection { + serial: Box::new(serial), + baud_rate: DEFAULT_BAUDRATE, + } + } + + pub fn reset_to_flash(&mut self) -> Result<(), Error> { + self.serial.set_rts(true)?; + sleep(Duration::from_millis(50)); + self.serial.set_dtr(true)?; + sleep(Duration::from_millis(50)); + self.serial.set_dtr(false)?; + sleep(Duration::from_millis(50)); + self.serial.set_rts(false)?; + sleep(Duration::from_millis(50)); + + Ok(()) + } + + pub fn set_timeout(&mut self, timeout: Duration) -> Result<(), Error> { + self.serial.set_timeout(timeout)?; + Ok(()) + } + + pub fn set_baud(&mut self, speed: BaudRate) -> Result<(), Error> { + self.baud_rate = speed; + self.serial + .reconfigure(&|setup: &mut dyn SerialPortSettings| setup.set_baud_rate(speed))?; + Ok(()) + } + + pub fn with_timeout Result>( + &mut self, + timeout: Duration, + mut f: F, + ) -> Result { + let old_timeout = self.serial.timeout(); + self.serial.set_timeout(timeout)?; + let result = f(self); + self.serial.set_timeout(old_timeout)?; + result + } + + fn read_exact(&mut self, len: usize) -> Result, Error> { + let mut buf = vec![0u8; len]; + self.serial.read_exact(&mut buf)?; + Ok(buf) + } + + pub fn read_response(&mut self, len: usize) -> Result, Error> { + let resp = self.read_exact(2)?; + log::trace!("read_response {}", String::from_utf8_lossy(&resp).to_string()); + match &resp[0..2] { + // OK + [0x4f, 0x4b] => { + if len > 0 { + self.read_exact(len) + } else { + Ok(vec![]) + } + }, + // FL + [0x46, 0x4c] => { + let code = self.read_exact(2)?; + let mut reader = Cursor::new(code); + let code = reader.read_u16::()?; + Err(Error::RomError(RomError::from(code))) + }, + _ => Err(Error::RespError) + } + } + + pub fn calc_duration_length(&mut self, duration: Duration) -> usize { + self.baud_rate.speed() / 10 / 1000 * (duration.as_millis() as usize) + } + + pub fn write_all(&mut self, buf: &[u8]) -> Result<(), Error> { + Ok(self.serial.write_all(buf)?) + } + + pub fn flush(&mut self) -> Result<(), Error> { + Ok(self.serial.flush()?) + } +} diff --git a/blflash/src/error.rs b/blflash/src/error.rs new file mode 100644 index 0000000..900baf7 --- /dev/null +++ b/blflash/src/error.rs @@ -0,0 +1,50 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[non_exhaustive] +pub enum Error { + #[error("IO error while using serial port: {0}")] + Serial(#[from] serial::core::Error), + #[error("Failed to connect to the device")] + ConnectionFailed, + #[error("Timeout while running command")] + Timeout, + #[error("Invalid response header")] + RespError, + #[error("Packet to large for buffer")] + OverSizedPacket, + #[error("elf image is not valid")] + InvalidElf, + #[error("elf image can not be ran from ram")] + ElfNotRamLoadable, + #[error("chip not recognized")] + UnrecognizedChip, + #[error("flash chip not supported, flash id: {0:#x}")] + UnsupportedFlash(u8), + #[error("ROM error")] + RomError(RomError), + #[error("Parse error")] + ParseError(#[from] deku::error::DekuError), +} + +impl From for Error { + fn from(err: std::io::Error) -> Self { + Self::Serial(serial::core::Error::from(err)) + } +} + +#[derive(Copy, Clone, Debug)] +#[allow(dead_code)] +pub enum RomError { + Success, + Other(u16), +} + +impl From for RomError { + fn from(raw: u16) -> Self { + match raw { + 0x00 => RomError::Success, + _ => RomError::Other(raw), + } + } +} diff --git a/blflash/src/flasher.rs b/blflash/src/flasher.rs new file mode 100644 index 0000000..9e60c00 --- /dev/null +++ b/blflash/src/flasher.rs @@ -0,0 +1,84 @@ +use crate::connection::{Connection, DEFAULT_BAUDRATE}; +use crate::Error; +use serial::{BaudRate, SerialPort}; +use std::time::{Duration, Instant}; +use deku::prelude::*; + +pub struct Flasher { + connection: Connection, + bootrom_info: protocol::BootInfo, +} + +impl Flasher { + pub fn connect( + serial: impl SerialPort + 'static, + speed: Option, + ) -> Result { + let mut flasher = Flasher { + connection: Connection::new(serial), + bootrom_info: protocol::BootInfo::default(), + }; + flasher.connection.set_baud(speed.unwrap_or(DEFAULT_BAUDRATE))?; + flasher.start_connection()?; + flasher.connection.set_timeout(Duration::from_secs(3))?; + flasher.bootrom_info = flasher.get_boot_info()?; + + Ok(flasher) + } + + fn get_boot_info(&mut self) -> Result { + self.connection.write_all(protocol::GET_BOOT_INFO)?; + let data = self.connection.read_response(1 + 1 + 4 + 16)?; + let (_, data) = protocol::BootInfo::from_bytes((&data, 0))?; + Ok(data) + } + + fn handshake(&mut self) -> Result<(), Error> { + self.connection + .with_timeout(Duration::from_millis(200), |connection| { + let len = connection.calc_duration_length(Duration::from_millis(5)); + log::trace!("5ms send count {}", len); + let data: Vec = std::iter::repeat(0x55u8) + .take(len).collect(); + let start = Instant::now(); + connection.write_all(&data)?; + connection.flush()?; + log::trace!("handshake sent elapsed {:?}", start.elapsed()); + for _ in 0..10 { + if connection.read_response(0).is_ok() { + return Ok(()) + } + } + Err(Error::Timeout) + }) + } + + fn start_connection(&mut self) -> Result<(), Error> { + log::info!("Start connection..."); + self.connection.reset_to_flash()?; + for i in 1..=10 { + self.connection.flush()?; + if self.handshake().is_ok() { + log::info!("Connection Succeed"); + return Ok(()); + } else { + log::debug!("Retry {}", i); + } + } + Err(Error::ConnectionFailed) + } + +} + +mod protocol { + use deku::prelude::*; + + pub const GET_BOOT_INFO: &[u8] = &[0x10, 0x00, 0x00, 0x00]; + + #[derive(Debug, DekuRead, Default)] + #[deku(magic = b"\x14\x00")] + pub struct BootInfo { + bootrom_version: u32, + otp_info: [u8; 16], + } +} diff --git a/blflash/src/lib.rs b/blflash/src/lib.rs new file mode 100644 index 0000000..44db28a --- /dev/null +++ b/blflash/src/lib.rs @@ -0,0 +1,9 @@ +mod config; +mod flasher; +mod connection; +mod chip; +mod error; + +pub use config::Config; +pub use flasher::Flasher; +pub use error::{Error, RomError}; diff --git a/blflash/src/main.rs b/blflash/src/main.rs index e7a11a9..1912d4f 100644 --- a/blflash/src/main.rs +++ b/blflash/src/main.rs @@ -1,3 +1,50 @@ -fn main() { - println!("Hello, world!"); +use std::fs::read; + +use blflash::{Config, Flasher}; +use main_error::MainError; +use pico_args::Arguments; +use serial::BaudRate; +use env_logger::Env; + +fn help() -> Result<(), MainError> { + println!("Usage: espflash [--board-info] [--ram] "); + Ok(()) +} + +fn main() -> Result<(), MainError> { + env_logger::Builder::from_env(Env::default().default_filter_or("blflash=trace")).init(); + let mut args = Arguments::from_env(); + let config = Config::load(); + + log::trace!("trace on"); + + if args.contains(["-h", "--help"]) { + return help(); + } + + let _ram = args.contains("--ram"); + + let mut serial: Option = args.free_from_str()?; + let mut elf: Option = args.free_from_str()?; + + if elf.is_none() && config.connection.serial.is_some() { + elf = serial.take(); + serial = config.connection.serial; + } + + let serial: String = match serial { + Some(serial) => serial, + _ => return help(), + }; + + let serial = serial::open(&serial)?; + let _flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(500_000)))?; + + let input: String = match elf { + Some(input) => input, + _ => return help(), + }; + let _input_bytes = read(&input)?; + + Ok(()) } diff --git a/cargo-blflash/Cargo.toml b/cargo-blflash/Cargo.toml index b8c1ce3..aba2f35 100644 --- a/cargo-blflash/Cargo.toml +++ b/cargo-blflash/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" authors = ["spacelin "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +cargo-project = "0.2.4" +blflash = { version = "0.1.0", path = "../blflash" } +main_error = "0.1.1" +pico-args = "0.3.4" +serial = "0.4"