From 95924c04ab3fb4409d98f18247ad73d4e05dc1ad Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 05:45:41 -0800 Subject: [PATCH 1/8] Reduce code duplication in `build.rs`, define some configuration symbols --- build.rs | 149 ++++++++++++++++++++++--------------------------------- 1 file changed, 58 insertions(+), 91 deletions(-) diff --git a/build.rs b/build.rs index 33c1fe5..2be48ca 100644 --- a/build.rs +++ b/build.rs @@ -1,106 +1,73 @@ -use std::{env, fs, path::PathBuf}; - -fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - println!("cargo:rustc-link-search)={}", out_dir.display()); - - #[cfg(feature = "esp32")] +use std::{env, error::Error, fs, path::PathBuf}; + +fn main() -> Result<(), Box> { + let out = PathBuf::from(env::var("OUT_DIR").unwrap()); + println!("cargo:rustc-link-search)={}", out.display()); + + let chip = if cfg!(feature = "esp32") { + "esp32" + } else if cfg!(feature = "esp32c2") { + "esp32c2" + } else if cfg!(feature = "esp32c3") { + "esp32c3" + } else if cfg!(feature = "esp32c6") { + "esp32c6" + } else if cfg!(feature = "esp32h2") { + "esp32h2" + } else if cfg!(feature = "esp32s2") { + "esp32s2" + } else if cfg!(feature = "esp32s3") { + "esp32s3" + } else { + panic!("Must select exactly one chip feature!") + }; + + let arch = match chip { + "esp32" | "esp32s2" | "esp32s3" => "xtensa", + _ => "riscv32", + }; + + // Define configuration symbols: + + println!("cargo:rustc-cfg={chip}"); + println!("cargo:rustc-cfg={arch}"); + + // Define any USB-related configuration symbols, if required: + + if cfg!(feature = "esp32c3") + || cfg!(feature = "esp32c6") + || cfg!(feature = "esp32h2") + || cfg!(feature = "esp32s3") { - fs::copy("ld/esp32_stub.x", out_dir.join("esp32_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32_stub.x"); - - fs::copy("ld/esp32_rom.x", out_dir.join("esp32_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32_rom.x"); + println!("cargo:rustc-cfg=usb_device"); } - #[cfg(feature = "esp32c2")] - { - fs::copy("ld/esp32c2_stub.x", out_dir.join("esp32c2_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32c2_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c2_stub.x"); - - fs::copy("ld/esp32c2_rom.x", out_dir.join("esp32c2_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32c2_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c2_rom.x"); - - println!("cargo:rustc-link-arg=-Thal-defaults.x"); - } - - #[cfg(feature = "esp32c3")] - { - fs::copy("ld/esp32c3_stub.x", out_dir.join("esp32c3_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32c3_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c3_stub.x"); - - fs::copy("ld/esp32c3_rom.x", out_dir.join("esp32c3_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32c3_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c3_rom.x"); - - println!("cargo:rustc-link-arg=-Thal-defaults.x"); + if cfg!(feature = "esp32s2") || cfg!(feature = "esp32s3") { + println!("cargo:rustc-cfg=usb0"); } - #[cfg(feature = "esp32c6")] - { - fs::copy("ld/esp32c6_stub.x", out_dir.join("esp32c6_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32c6_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c6_stub.x"); + // Copy required linker scripts to the `out` path: - fs::copy("ld/esp32c6_rom.x", out_dir.join("esp32c6_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32c6_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32c6_rom.x"); + let ld_path = PathBuf::from("ld"); - println!("cargo:rustc-link-arg=-Thal-defaults.x"); - } + let stub_x = format!("{}_stub.x", chip); + fs::copy(ld_path.join(&stub_x), out.join(&stub_x))?; + println!("cargo:rerun-if-changed=ld/{stub_x}"); + println!("cargo:rustc-link-arg=-Tld/{stub_x}"); - #[cfg(feature = "esp32h2")] - { - fs::copy("ld/esp32h2_stub.x", out_dir.join("esp32h2_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32h2_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32h2_stub.x"); + let rom_x = format!("{}_rom.x", chip); + fs::copy(ld_path.join(&rom_x), out.join(&rom_x))?; + println!("cargo:rerun-if-changed=ld/{rom_x}"); + println!("cargo:rustc-link-arg=-Tld/{rom_x}"); - fs::copy("ld/esp32h2_rom.x", out_dir.join("esp32h2_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32h2_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32h2_rom.x"); + // The RISC-V devices additionally require the `hal-defaults.x` linker + // script from `esp-hal`, to avoid interrupt-related linker errors: + if arch == "riscv32" { println!("cargo:rustc-link-arg=-Thal-defaults.x"); } - #[cfg(feature = "esp32s2")] - { - fs::copy("ld/esp32s2_stub.x", out_dir.join("esp32s2_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32s2_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32s2_stub.x"); - - fs::copy("ld/esp32s2_rom.x", out_dir.join("esp32s2_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32s2_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32s2_rom.x"); - } - - #[cfg(feature = "esp32s3")] - { - fs::copy("ld/esp32s3_stub.x", out_dir.join("esp32s3_stub.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/esp32s3_stub.x"); - println!("cargo:rustc-link-arg=-Tld/esp32s3_stub.x"); - - fs::copy("ld/esp32s3_rom.x", out_dir.join("esp32s3_rom.x")).unwrap(); - println!("cargo:rerun-if-changed=ld/ld/esp32s3_rom.x"); - println!("cargo:rustc-link-arg=-Tld/esp32s3_rom.x"); - } - - emit_cfg(); -} + // Done! -fn emit_cfg() { - #[cfg(any( - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2", - feature = "esp32s3", - ))] - println!("cargo:rustc-cfg=usb_device"); - - #[cfg(any(feature = "esp32s2", feature = "esp32s3"))] - println!("cargo:rustc-cfg=usb0"); + Ok(()) } From 360d27d69ee290b1d1808d09668e0d9418478e9a Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 05:49:14 -0800 Subject: [PATCH 2/8] Reorganize and clean up the `io` module a bit --- src/{io.rs => io/mod.rs} | 16 +++++++--------- src/io/uart.rs | 15 ++++++++++----- src/io/usb_serial_jtag.rs | 11 +++++++---- 3 files changed, 24 insertions(+), 18 deletions(-) rename src/{io.rs => io/mod.rs} (79%) diff --git a/src/io.rs b/src/io/mod.rs similarity index 79% rename from src/io.rs rename to src/io/mod.rs index 7f66dc7..f67ec8e 100644 --- a/src/io.rs +++ b/src/io/mod.rs @@ -1,7 +1,5 @@ use core::marker::PhantomData; -use heapless::Deque; - use crate::protocol::InputIO; pub mod uart; @@ -10,12 +8,16 @@ pub mod usb_serial_jtag; const RX_QUEUE_SIZE: usize = crate::targets::MAX_WRITE_BLOCK + 0x400; -static mut RX_QUEUE: Deque = Deque::new(); +static mut RX_QUEUE: heapless::Deque = heapless::Deque::new(); trait UartMarker: InputIO {} trait UsbSerialJtagMarker: InputIO {} trait UsbOtgMarker: InputIO {} +impl UartMarker for &mut T where T: UartMarker {} +impl UsbSerialJtagMarker for &mut T where T: UsbSerialJtagMarker {} +impl UsbOtgMarker for &mut T where T: UsbOtgMarker {} + #[non_exhaustive] pub enum Transport { Uart(S), @@ -38,7 +40,7 @@ where Transport::Uart(s) => s.recv(), #[cfg(usb_device)] Transport::UsbSerialJtag(j) => j.recv(), - _ => todo!(), + _ => unimplemented!(), } } @@ -47,7 +49,7 @@ where Transport::Uart(s) => s.send(data), #[cfg(usb_device)] Transport::UsbSerialJtag(j) => j.send(data), - _ => todo!(), + _ => unimplemented!(), } } } @@ -67,7 +69,3 @@ impl InputIO for Noop { impl UartMarker for Noop {} impl UsbSerialJtagMarker for Noop {} impl UsbOtgMarker for Noop {} - -impl UartMarker for &mut T {} -impl UsbSerialJtagMarker for &mut T {} -impl UsbOtgMarker for &mut T {} diff --git a/src/io/uart.rs b/src/io/uart.rs index 0179abe..512a1d1 100644 --- a/src/io/uart.rs +++ b/src/io/uart.rs @@ -1,13 +1,18 @@ use super::{UartMarker, RX_QUEUE}; use crate::{ - hal::{peripherals::UART0, prelude::*, uart::Instance, Uart}, + hal::{macros::interrupt, peripherals::UART0, uart::Instance, Uart}, protocol::InputIO, }; -impl InputIO for Uart<'_, T> { +impl InputIO for Uart<'_, T> +where + T: Instance, +{ fn recv(&mut self) -> u8 { - unsafe { while critical_section::with(|_| RX_QUEUE.is_empty()) {} } - unsafe { critical_section::with(|_| RX_QUEUE.pop_front().unwrap()) } + unsafe { + while critical_section::with(|_| RX_QUEUE.is_empty()) {} + critical_section::with(|_| RX_QUEUE.pop_front().unwrap()) + } } fn send(&mut self, bytes: &[u8]) { @@ -15,7 +20,7 @@ impl InputIO for Uart<'_, T> { } } -impl UartMarker for Uart<'_, T> {} +impl UartMarker for Uart<'_, T> where T: Instance {} #[interrupt] fn UART0() { diff --git a/src/io/usb_serial_jtag.rs b/src/io/usb_serial_jtag.rs index 3931f9a..0606c5b 100644 --- a/src/io/usb_serial_jtag.rs +++ b/src/io/usb_serial_jtag.rs @@ -1,7 +1,8 @@ use super::{UsbSerialJtagMarker, RX_QUEUE}; use crate::{ hal::{ - prelude::*, + peripherals::USB_DEVICE, + prelude::interrupt, usb_serial_jtag::{Instance, UsbSerialJtag}, }, protocol::InputIO, @@ -9,8 +10,10 @@ use crate::{ impl InputIO for UsbSerialJtag<'_> { fn recv(&mut self) -> u8 { - unsafe { while critical_section::with(|_| RX_QUEUE.is_empty()) {} } - unsafe { critical_section::with(|_| RX_QUEUE.pop_front().unwrap()) } + unsafe { + while critical_section::with(|_| RX_QUEUE.is_empty()) {} + critical_section::with(|_| RX_QUEUE.pop_front().unwrap()) + } } fn send(&mut self, bytes: &[u8]) { @@ -22,7 +25,7 @@ impl UsbSerialJtagMarker for UsbSerialJtag<'_> {} #[interrupt] unsafe fn USB_DEVICE() { - let usj = crate::hal::peripherals::USB_DEVICE::steal(); + let usj = USB_DEVICE::steal(); let reg_block = usj.register_block(); while reg_block From bc5430db3c79ae7dd7b5abaddef06af0f9c2358f Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 05:52:20 -0800 Subject: [PATCH 3/8] Clean up re-exports, correctly alias target with capitalized name --- src/lib.rs | 51 ++++++++++++++++++++++++++----------------------- src/protocol.rs | 2 +- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 16ab812..04f33ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,35 +1,20 @@ #![no_std] -// Re-export the correct HAL based on which feature is active -#[cfg(feature = "esp32")] -pub use esp32_hal as hal; -#[cfg(feature = "esp32c2")] -pub use esp32c2_hal as hal; -#[cfg(feature = "esp32c3")] -pub use esp32c3_hal as hal; -#[cfg(feature = "esp32c6")] -pub use esp32c6_hal as hal; -#[cfg(feature = "esp32h2")] -pub use esp32h2_hal as hal; -#[cfg(feature = "esp32s2")] -pub use esp32s2_hal as hal; -#[cfg(feature = "esp32s3")] -pub use esp32s3_hal as hal; // Re-export the correct target based on which feature is active #[cfg(feature = "esp32")] -pub use targets::Esp32 as target; +pub use targets::Esp32 as Target; #[cfg(feature = "esp32c2")] -pub use targets::Esp32c2 as target; +pub use targets::Esp32c2 as Target; #[cfg(feature = "esp32c3")] -pub use targets::Esp32c3 as target; +pub use targets::Esp32c3 as Target; #[cfg(feature = "esp32c6")] -pub use targets::Esp32c6 as target; +pub use targets::Esp32c6 as Target; #[cfg(feature = "esp32h2")] -pub use targets::Esp32h2 as target; +pub use targets::Esp32h2 as Target; #[cfg(feature = "esp32s2")] -pub use targets::Esp32s2 as target; +pub use targets::Esp32s2 as Target; #[cfg(feature = "esp32s3")] -pub use targets::Esp32s3 as target; +pub use targets::Esp32s3 as Target; pub mod commands; pub mod dprint; @@ -38,6 +23,24 @@ pub mod miniz_types; pub mod protocol; pub mod targets; +// Re-export the correct HAL based on which feature is active +pub mod hal { + #[cfg(feature = "esp32")] + pub use esp32_hal::*; + #[cfg(feature = "esp32c2")] + pub use esp32c2_hal::*; + #[cfg(feature = "esp32c3")] + pub use esp32c3_hal::*; + #[cfg(feature = "esp32c6")] + pub use esp32c6_hal::*; + #[cfg(feature = "esp32h2")] + pub use esp32h2_hal::*; + #[cfg(feature = "esp32s2")] + pub use esp32s2_hal::*; + #[cfg(feature = "esp32s3")] + pub use esp32s3_hal::*; +} + #[derive(Debug)] pub enum TransportMethod { Uart, @@ -75,9 +78,9 @@ pub fn detect_transport() -> TransportMethod { let num = unsafe { (*device).buff_uart_no }; match num { #[cfg(usb_device)] - target::USB_SERIAL_JTAG_ID => TransportMethod::UsbSerialJtag, + Target::USB_SERIAL_JTAG_ID => TransportMethod::UsbSerialJtag, #[cfg(usb0)] - target::USB_OTG_ID => TransportMethod::UsbOtg, + Target::USB_OTG_ID => TransportMethod::UsbOtg, _ => TransportMethod::Uart, } } diff --git a/src/protocol.rs b/src/protocol.rs index 13fc8c9..19fa8b9 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -40,7 +40,7 @@ pub struct Stub { decompressor: tinfl_decompressor, last_error: Option, in_flash_mode: bool, - target: crate::target, + target: crate::Target, } fn slice_to_struct(slice: &[u8]) -> Result { From 6d14401b07f3b8e9cec821c19833c39b6cefa60c Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 06:05:58 -0800 Subject: [PATCH 4/8] Move `Transport` type into library, extract some functions --- src/lib.rs | 88 ++++++++++++++++++++++++++++++--------------- src/main.rs | 102 ++++++++++++++++++++++++++-------------------------- 2 files changed, 110 insertions(+), 80 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 04f33ae..1667cea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,11 @@ pub mod hal { pub use esp32s3_hal::*; } +use self::{ + hal::{Uart, peripherals::UART0}, + io::Noop, +}; + #[derive(Debug)] pub enum TransportMethod { Uart, @@ -50,37 +55,62 @@ pub enum TransportMethod { UsbOtg, } -pub fn detect_transport() -> TransportMethod { - #[cfg(usb0)] - use crate::targets::EspUsbOtgId as _; - #[cfg(usb_device)] - use crate::targets::EspUsbSerialJtagId as _; +impl TransportMethod { + pub fn detect() -> Self { + #[cfg(usb0)] + use crate::targets::EspUsbOtgId as _; + #[cfg(usb_device)] + use crate::targets::EspUsbSerialJtagId as _; - #[repr(C)] - struct Uart { - baud_rate: u32, - data_bits: u32, - exist_parity: u32, - parity: u32, - stop_bits: u32, - flow_ctrl: u32, - buff_uart_no: u8, - rcv_buff: [u32; 2], // PAD - rcv_state: u32, - received: u32, - } + extern "C" { + fn esp_flasher_rom_get_uart() -> *const Uart; + } - extern "C" { - fn esp_flasher_rom_get_uart() -> *const Uart; - } + #[repr(C)] + struct Uart { + baud_rate: u32, + data_bits: u32, + exist_parity: u32, + parity: u32, + stop_bits: u32, + flow_ctrl: u32, + buff_uart_no: u8, + rcv_buff: [u32; 2], // PAD + rcv_state: u32, + received: u32, + } - let device = unsafe { esp_flasher_rom_get_uart() }; - let num = unsafe { (*device).buff_uart_no }; - match num { - #[cfg(usb_device)] - Target::USB_SERIAL_JTAG_ID => TransportMethod::UsbSerialJtag, - #[cfg(usb0)] - Target::USB_OTG_ID => TransportMethod::UsbOtg, - _ => TransportMethod::Uart, + let device = unsafe { esp_flasher_rom_get_uart() }; + let num = unsafe { (*device).buff_uart_no }; + + match num { + #[cfg(usb_device)] + Target::USB_SERIAL_JTAG_ID => TransportMethod::UsbSerialJtag, + #[cfg(usb0)] + Target::USB_OTG_ID => TransportMethod::UsbOtg, + _ => TransportMethod::Uart, + } } } + +// TODO this sucks, but default generic parameters are not used when inference +// fails, meaning that we _have_ to specifiy the types here Seems like work on this has stalled: https://github.com/rust-lang/rust/issues/27336, note that I tried the feature and it didn't work. +#[cfg(not(any(usb_device, usb0)))] +pub type Transport = io::Transport<&'static mut Uart<'static, UART0>, Noop, Noop>; + +#[cfg(all(usb_device, not(usb0)))] +pub type Transport = io::Transport< + &'static mut Uart<'static, UART0>, + &'static mut crate::hal::UsbSerialJtag<'static>, + Noop, +>; + +#[cfg(all(not(usb_device), usb0))] +pub type Transport = io::Transport<&'static mut Uart<'static, UART0>, Noop, Noop>; // TODO replace Noop with usb type later + +#[cfg(all(usb_device, usb0))] +pub type Transport = io::Transport< + &'static mut Uart<'static, UART0>, + &'static mut crate::hal::UsbSerialJtag<'static>, + Noop, // TODO replace Noop with usb type later +>; diff --git a/src/main.rs b/src/main.rs index 9a0c6a5..29122d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,51 +2,32 @@ #![no_std] #[cfg(feature = "dprint")] -use flasher_stub::hal::uart::{ - config::{Config, DataBits, Parity, StopBits}, - TxRxPins, +use flasher_stub::hal::{ + gpio::IO, + uart::{ + config::{Config, DataBits, Parity, StopBits}, + TxRxPins, + }, }; use flasher_stub::{ dprintln, hal::{ - clock::ClockControl, + clock::{ClockControl, Clocks}, entry, interrupt::{self, Priority}, peripherals::{self, Interrupt, Peripherals}, prelude::*, Uart, }, - io::{self, Noop}, protocol::Stub, targets, + Transport, TransportMethod, }; use static_cell::StaticCell; const MSG_BUFFER_SIZE: usize = targets::MAX_WRITE_BLOCK + 0x400; -// TODO this sucks, but default generic parameters are not used when inference -// fails, meaning that we _have_ to specifiy the types here Seems like work on this has stalled: https://github.com/rust-lang/rust/issues/27336, note that I tried the feature and it didn't work. -#[cfg(not(any(usb_device, usb0)))] -type Transport = io::Transport<&'static mut Uart<'static, crate::peripherals::UART0>, Noop, Noop>; - -#[cfg(all(usb_device, not(usb0)))] -type Transport = io::Transport< - &'static mut Uart<'static, crate::peripherals::UART0>, - &'static mut flasher_stub::hal::UsbSerialJtag<'static>, - Noop, ->; - -#[cfg(all(not(usb_device), usb0))] -type Transport = io::Transport<&'static mut Uart<'static, crate::peripherals::UART0>, Noop, Noop>; // TODO replace Noop with usb type later - -#[cfg(all(usb_device, usb0))] -type Transport = io::Transport< - &'static mut Uart<'static, crate::peripherals::UART0>, - &'static mut flasher_stub::hal::UsbSerialJtag<'static>, - Noop, // TODO replace Noop with usb type later ->; - #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { dprintln!("STUB Panic: {:?}", _info); @@ -59,18 +40,21 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::max(system.clock_control).freeze(); + // If the `dprint` feature is enabled, configure/initialize the debug console, + // which prints via UART1: + #[cfg(feature = "dprint")] let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); #[cfg(feature = "dprint")] let _ = Uart::new_with_config( peripherals.UART1, - Some(Config { - baudrate: 115200, + Config { + baudrate: 115_200, data_bits: DataBits::DataBits8, parity: Parity::ParityNone, stop_bits: StopBits::STOP1, - }), + }, Some(TxRxPins::new_tx_rx( io.pins.gpio2.into_push_pull_output(), io.pins.gpio0.into_floating_input(), @@ -78,39 +62,30 @@ fn main() -> ! { &clocks, ); - let transport = flasher_stub::detect_transport(); + // Detect the transport method being used, and configure/initialize the + // corresponding peripheral: + + let transport = TransportMethod::detect(); dprintln!("Stub init! Transport detected: {:?}", transport); let transport = match transport { - TransportMethod::Uart => { - let mut serial = Uart::new(peripherals.UART0, &clocks); - serial.listen_rx_fifo_full(); - interrupt::enable(Interrupt::UART0, Priority::Priority1).unwrap(); - - static mut TRANSPORT: StaticCell> = - StaticCell::new(); - - Transport::Uart(unsafe { TRANSPORT.init(serial) }) - } + TransportMethod::Uart => transport_uart(peripherals.UART0, &clocks), #[cfg(usb_device)] - TransportMethod::UsbSerialJtag => { - let mut usb_serial = flasher_stub::hal::UsbSerialJtag::new(peripherals.USB_DEVICE); - usb_serial.listen_rx_packet_recv_interrupt(); - interrupt::enable(Interrupt::USB_DEVICE, Priority::Priority1).unwrap(); - - static mut TRANSPORT: StaticCell> = - StaticCell::new(); - - Transport::UsbSerialJtag(unsafe { TRANSPORT.init(usb_serial) }) - } + TransportMethod::UsbSerialJtag => transport_usb_serial_jtag(peripherals.USB_DEVICE), #[cfg(usb0)] TransportMethod::UsbOtg => unimplemented!(), }; + // With the transport initialized we can move on to initializing the stub + // itself: + let mut stub = Stub::new(transport); dprintln!("Stub sending greeting!"); stub.send_greeting(); + // With the stub initialized and the greeting sent, all that's left to do is to + // wait for commands to process: + let mut buffer: [u8; MSG_BUFFER_SIZE] = [0; MSG_BUFFER_SIZE]; loop { dprintln!("Waiting for command"); @@ -119,3 +94,28 @@ fn main() -> ! { stub.process_command(data); } } + +// Initialize the UART0 peripheral as the `Transport`. +fn transport_uart(uart0: peripherals::UART0, clocks: &Clocks<'_>) -> Transport { + let mut serial = Uart::new(uart0, &clocks); + serial.listen_rx_fifo_full(); + interrupt::enable(Interrupt::UART0, Priority::Priority1).unwrap(); + + static mut TRANSPORT: StaticCell> = StaticCell::new(); + + Transport::Uart(unsafe { TRANSPORT.init(serial) }) +} + +// Initialize the USB Serial JTAG peripheral as the `Transport`. +#[cfg(usb_device)] +fn transport_usb_serial_jtag(usb_device: peripherals::USB_DEVICE) -> Transport { + use flasher_stub::hal::UsbSerialJtag; + + let mut usb_serial = UsbSerialJtag::new(usb_device); + usb_serial.listen_rx_packet_recv_interrupt(); + interrupt::enable(Interrupt::USB_DEVICE, Priority::Priority1).unwrap(); + + static mut TRANSPORT: StaticCell> = StaticCell::new(); + + Transport::UsbSerialJtag(unsafe { TRANSPORT.init(usb_serial) }) +} From a8cf64de6274d4bd34d2c94715046632d8758985 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 06:12:07 -0800 Subject: [PATCH 5/8] Change type of `tinfl_decompressor` struct's `bit_buf` field from u64 to u32 --- src/miniz_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miniz_types.rs b/src/miniz_types.rs index 4f09413..36fe10b 100644 --- a/src/miniz_types.rs +++ b/src/miniz_types.rs @@ -43,7 +43,7 @@ pub struct tinfl_decompressor { counter: u32, num_extra: u32, table_sizes: [u32; TINFL_MAX_HUFF_TABLES], - bit_buf: u64, + bit_buf: u32, dist_from_out_buf_start: u32, tables: [tinfl_huff_table; TINFL_MAX_HUFF_TABLES], raw_header: [u8; 4], From b6b1709a5598f1811338820dbafad0a7f3fe590f Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 06:12:25 -0800 Subject: [PATCH 6/8] We can now build using `opt-level = "z"`! --- Cargo.lock | 64 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 12 +++++----- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03ded20..63e7c26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" [[package]] name = "assert2" @@ -161,7 +161,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -172,7 +172,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -207,7 +207,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -289,7 +289,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "esp-hal-common" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2d2f804adbc3a7dfd5459a73e6848fd2297740fdaf5daca4ffce4682deba31" +checksum = "30e9f181669edeb35ef6d6c5518c9941900dbf2133348673eebb4b33fb73ac62" dependencies = [ "basic-toml", "bitfield", @@ -359,7 +359,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -407,9 +407,9 @@ dependencies = [ [[package]] name = "esp32c2" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c72611ab241be78492f5bf7c469f7a43f858e6bdfd840cce0ea3837da74439c3" +checksum = "2ad287b8cbc78f61fa7c81202e8bb7b1e438715ca0dc9654fc5c326458e9ba5d" dependencies = [ "critical-section", "vcell", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "esp32c3" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3535f040004d5ac0d13f3fa601945b16616a365ffda4c09f4baff8b77eabe59" +checksum = "398875eca3b0a51216110bd988bc72f79e564a0039fc93d81c10113c3e5f1a55" dependencies = [ "critical-section", "vcell", @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "esp32c6" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7278204469d03bf14a325f9933f8e5e72a1c2e6c1385fcbb024d7bc4a2b7c892" +checksum = "9683d47088fa94123072f0d8fc6dbdad0ecd2fb013d2095170179a5bec4e09d2" dependencies = [ "critical-section", "vcell", @@ -465,9 +465,9 @@ dependencies = [ [[package]] name = "esp32h2" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82fba2eaa874763ddd53c4f1a80a14c00394ff357a3913b6b39757382debb1d" +checksum = "f8cb744fe4793cf793355162551bbee5a1e07cb121004931e02847a6059b2c51" dependencies = [ "critical-section", "vcell", @@ -767,9 +767,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a978c8292954bcb9347a4e28772c0a0621166a1598fc1be28ac0076a4bb810e" +checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" dependencies = [ "cfg-if", "downcast", @@ -782,14 +782,14 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad2765371d0978ba4ace4ebef047baa62fc068b431e468444b5610dd441c639b" +checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -801,7 +801,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -842,7 +842,7 @@ checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -1093,7 +1093,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -1170,7 +1170,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -1186,9 +1186,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.40" +version = "2.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" dependencies = [ "proc-macro2", "quote", @@ -1218,7 +1218,7 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] @@ -1417,9 +1417,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5" dependencies = [ "memchr", ] @@ -1457,7 +1457,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.42", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c67f704..2973e7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,21 +21,21 @@ static_cell = "2.0.0" [dev-dependencies] assert2 = "0.3.11" matches = "0.1.10" -mockall = "0.12.0" -mockall_double = "0.3.0" +mockall = "0.12.1" +mockall_double = "0.3.1" [features] esp32 = ["esp32-hal"] -esp32s2 = ["esp32s2-hal"] -esp32s3 = ["esp32s3-hal"] +esp32c2 = ["esp32c2-hal"] esp32c3 = ["esp32c3-hal"] esp32c6 = ["esp32c6-hal"] esp32h2 = ["esp32h2-hal"] -esp32c2 = ["esp32c2-hal"] +esp32s2 = ["esp32s2-hal"] +esp32s3 = ["esp32s3-hal"] dprint = [] [profile.release] -opt-level = "s" # See: https://github.com/llvm/llvm-project/issues/57988 +opt-level = "z" codegen-units = 1 lto = true panic = "abort" From 2bdb3af7e4f67460f4f0e9f51592ff2eabf263e8 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 06:13:38 -0800 Subject: [PATCH 7/8] Update `README.md`, rustfmt --- README.md | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index db587f0..a729a07 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # esp-flasher-stub [![GitHub Workflow Status](https://github.com/esp-rs/esp-println/actions/workflows/ci.yml/badge.svg)](https://github.com/esp-rs/esp-println/actions/workflows/ci.yml) -![MSRV](https://img.shields.io/badge/MSRV-1.65-blue?labelColor=1C2C2E&logo=Rust&style=flat-square) +![MSRV](https://img.shields.io/badge/MSRV-1.67-blue?labelColor=1C2C2E&logo=Rust&style=flat-square) [![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&color=BEC5C9&labelColor=1C2C2E&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org) Rust implementation of flasher stub located in [esptool](https://github.com/espressif/esptool/). diff --git a/src/lib.rs b/src/lib.rs index 1667cea..3687134 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ pub mod hal { } use self::{ - hal::{Uart, peripherals::UART0}, + hal::{peripherals::UART0, Uart}, io::Noop, }; From f192813d8465a700a951c9dee8319ef4d8446b35 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Fri, 22 Dec 2023 06:52:33 -0800 Subject: [PATCH 8/8] Tweak symbol name for RISC-V in build script --- build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 2be48ca..307c6d2 100644 --- a/build.rs +++ b/build.rs @@ -24,7 +24,7 @@ fn main() -> Result<(), Box> { let arch = match chip { "esp32" | "esp32s2" | "esp32s3" => "xtensa", - _ => "riscv32", + _ => "riscv", }; // Define configuration symbols: @@ -63,7 +63,7 @@ fn main() -> Result<(), Box> { // The RISC-V devices additionally require the `hal-defaults.x` linker // script from `esp-hal`, to avoid interrupt-related linker errors: - if arch == "riscv32" { + if arch == "riscv" { println!("cargo:rustc-link-arg=-Thal-defaults.x"); }