diff --git a/.gitignore b/.gitignore index 4713399..3bf03d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -/*/output.log \ No newline at end of file +/*/output.log +*.bin \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 5a45f58..d29716f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -320,6 +320,42 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "dfu-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c3fb34e94bedc8bbd76dfc9f6774896fadbbedac6108fa8a3c46a0125bde188" +dependencies = [ + "bytes", + "displaydoc", + "log", + "pretty-hex", + "thiserror", +] + +[[package]] +name = "dfu-libusb" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e20ae81db46fd54fede9e71d06c06a382926212831cfd2f758b888e00a321d1" +dependencies = [ + "dfu-core", + "libusb1-sys", + "rusb", + "thiserror", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "document-features" version = "0.2.10" @@ -741,6 +777,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libusb1-sys" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6bace2f39082e9787c851afce469e7b2fe0f1cc64bbc68ca96653b63d8f17" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "litrs" version = "0.4.1" @@ -1065,6 +1113,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "pretty-hex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1157,12 +1211,15 @@ version = "0.1.0" dependencies = [ "anyhow", "axum", + "dfu-libusb", "fern", "humantime", + "libusb1-sys", "log", "nom", "postcard", "radomctl-protocol", + "rusb", "serde_json", "serialport", "tokio", @@ -1256,6 +1313,16 @@ dependencies = [ "rtic-common", ] +[[package]] +name = "rusb" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45fff149b6033f25e825cbb7b2c625a11ee8e6dac09264d49beb125e39aa97bf" +dependencies = [ + "libc", + "libusb1-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1821,6 +1888,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index bdcee7f..f08edfe 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -19,3 +19,6 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" radomctl-protocol = { path = "../protocol" } postcard = {version = "1.0.10", features = ["use-std"]} +dfu-libusb = "0.3.0" +libusb1-sys = "0.6" +rusb = "0.9" diff --git a/daemon/src/bin/trigger-dfu.rs b/daemon/src/bin/trigger-dfu.rs index 472f081..f229d73 100644 --- a/daemon/src/bin/trigger-dfu.rs +++ b/daemon/src/bin/trigger-dfu.rs @@ -1,10 +1,16 @@ -use std::time::Duration; +use std::{ + io::{self, Seek}, + thread, + time::{self, Duration}, +}; +use anyhow::Context; +use dfu_libusb::{Dfu, DfuLibusb}; use postcard::{from_bytes_cobs, to_stdvec_cobs}; use radomctl_protocol::*; use radomctld::logger::setup_logger; -pub fn main() -> () { +pub fn main() -> anyhow::Result<()> { let mut port = serialport::new("/dev/ttyACM0", 115_200) .timeout(Duration::from_millis(10)) .open() @@ -13,4 +19,28 @@ pub fn main() -> () { let host_msg = HostMessage::TriggerDFUBootloader; let msg_bytes = to_stdvec_cobs(&host_msg).unwrap(); port.write_all(&msg_bytes).unwrap(); + drop(port); + + let context = rusb::Context::new()?; + let mut file = std::fs::File::open("../../firmware/radomctl-firmware.bin") + .context("firmware file not found")?; + + thread::sleep(time::Duration::from_millis(1000)); + + let file_size = + u32::try_from(file.seek(io::SeekFrom::End(0))?).context("the firmware file is too big")?; + file.seek(io::SeekFrom::Start(0))?; + + let vid = 0x0483; + let pid = 0xdf11; + let intf = 0; + let alt = 0; + let mut device: Dfu = + DfuLibusb::open(&context, vid, pid, intf, alt).context("could not open device")?; + + device + .download(file, file_size) + .context("could not write firmware to the device")?; + + Ok(()) } diff --git a/firmware/flash-dfu.sh b/firmware/flash-dfu.sh new file mode 100755 index 0000000..9f1f583 --- /dev/null +++ b/firmware/flash-dfu.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cargo build --release && \ +arm-none-eabi-objcopy -O binary ../target/thumbv7em-none-eabihf/release/radomctl-firmware radomctl-firmware.bin && \ +dfu-util --alt 0 -s 0x08000000:leave -D radomctl-firmware.bin \ No newline at end of file