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 0000000..bc609b1 Binary files /dev/null and b/blflash/src/chip/bl602/eflash_loader_40m.bin differ 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"