From c50d8733345549d7216622c5474687a0471d43b0 Mon Sep 17 00:00:00 2001 From: Ole Bauck Date: Tue, 2 Jun 2026 15:50:09 +0200 Subject: [PATCH 1/2] Add cargo clippy github workflow --- .github/workflows/clippy.yml | 22 ++++++++++++++++++++++ Makefile | 6 ++++++ 2 files changed, 28 insertions(+) create mode 100755 .github/workflows/clippy.yml create mode 100644 Makefile diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml new file mode 100755 index 0000000..716b681 --- /dev/null +++ b/.github/workflows/clippy.yml @@ -0,0 +1,22 @@ +on: push +name: Clippy check + +# Make sure CI fails on all warnings, including Clippy lints +env: + RUSTFLAGS: "-Dwarnings" + +jobs: + clippy_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Add targets + run: | + rustup component add --toolchain nightly-x86_64-unknown-linux-gnu clippy && \ + rustup target add thumbv8m.main-none-eabihf && \ + rustup target add thumbv7em-none-eabihf && \ + rustup target add thumbv7em-none-eabi && \ + rustup target add thumbv6m-none-eabi + + - name: Run Clippy + run: make clippy diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9dd0610 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +CRATES := common ob-dap ch32v203 ch32v305 rp235x stm32c071 stm32g431 + +clippy: $(addprefix clippy-,$(CRATES)) + +clippy-%: + cd $(CURDIR)/$* && cargo clippy \ No newline at end of file From 73c9c787773986b9ead078f948f64742824ecd25 Mon Sep 17 00:00:00 2001 From: Ole Bauck Date: Tue, 2 Jun 2026 15:51:33 +0200 Subject: [PATCH 2/2] make clippy happy --- ch32v203/src/bin/usb_dap.rs | 3 +- ch32v203/src/bin/usb_dap_ppk2_uart.rs | 9 +- ch32v203/src/bin/usb_ppk2.rs | 16 +- ch32v203/src/bin/usb_serial_echo.rs | 10 +- ch32v203/src/bin/usb_uart.rs | 10 +- ch32v203/src/lib.rs | 29 --- ch32v203/src/usb_dap_task.rs | 6 +- ch32v203/src/usb_ppk2_task.rs | 4 +- ch32v203/src/usb_uart_task.rs | 56 +++--- ch32v305/src/bin/usb_dap.rs | 3 +- ch32v305/src/bin/usb_multi_ppk2.rs | 19 +- ch32v305/src/bin/usb_serial_echo.rs | 12 +- ch32v305/src/lib.rs | 29 --- ch32v305/src/usb_dap_task.rs | 6 +- common/src/lib.rs | 29 +++ common/src/usb_ppk2_dfu.rs | 7 + common/src/usb_uart.rs | 2 +- ob-dap/src/lib.rs | 26 +-- rp235x/src/bin/usb_dap.rs | 6 +- stm32c071/Cargo.toml | 2 - stm32c071/src/bin/usb_dap.rs | 10 +- stm32c071/src/bin/usb_dap_2.rs | 247 -------------------------- stm32c071/src/bin/usb_ppk2.rs | 6 +- stm32g431/src/bin/usb_dap.rs | 6 +- stm32g431/src/bin/usb_ppk2.rs | 6 +- 25 files changed, 129 insertions(+), 430 deletions(-) delete mode 100644 stm32c071/src/bin/usb_dap_2.rs diff --git a/ch32v203/src/bin/usb_dap.rs b/ch32v203/src/bin/usb_dap.rs index 5119f27..3e162b6 100644 --- a/ch32v203/src/bin/usb_dap.rs +++ b/ch32v203/src/bin/usb_dap.rs @@ -9,8 +9,9 @@ use hal::bind_interrupts; use hal::gpio::{Flex, Level, Output, Speed}; use hal::usbd::Driver; +use ch32v203::my_println; use ch32v203::usb_dap_task::dap_task; -use ch32v203::{bytes_to_hex, my_println}; +use rust_link_common::bytes_to_hex; use static_cell::StaticCell; diff --git a/ch32v203/src/bin/usb_dap_ppk2_uart.rs b/ch32v203/src/bin/usb_dap_ppk2_uart.rs index f2b7411..88df908 100644 --- a/ch32v203/src/bin/usb_dap_ppk2_uart.rs +++ b/ch32v203/src/bin/usb_dap_ppk2_uart.rs @@ -11,11 +11,12 @@ use hal::gpio::{Flex, Level, Output, Speed}; use hal::usart::{Config as UartConfig, Uart}; use hal::usbd::Driver; +use ch32v203::my_println; use ch32v203::usb_dap_task::dap_task; use ch32v203::usb_ppk2_task::ppk2_task; use ch32v203::usb_uart_task::{usb_rx_uart_tx_task, usb_tx_uart_rx_task}; -use ch32v203::{bytes_to_hex, my_println}; +use rust_link_common::bytes_to_hex; use rust_link_common::usb_ppk2_dfu::{Ppk2DfuClass, State as DfuState}; use static_cell::StaticCell; @@ -43,8 +44,10 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { - let mut config = hal::Config::default(); - config.rcc = hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI; + let mut config = hal::Config { + rcc: hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI, + ..Default::default() + }; config.rcc.apb2_pre = ch32_hal::rcc::APBPrescaler::DIV2; let p = hal::init(config); diff --git a/ch32v203/src/bin/usb_ppk2.rs b/ch32v203/src/bin/usb_ppk2.rs index c9e96c3..4c34ea3 100644 --- a/ch32v203/src/bin/usb_ppk2.rs +++ b/ch32v203/src/bin/usb_ppk2.rs @@ -12,17 +12,11 @@ use rust_link_common::usb_ppk2_dfu::{Ppk2DfuClass, State as DfuState}; use static_cell::StaticCell; -#[macro_export] -macro_rules! my_println { - ($($arg:tt)*) => { - () - }; -} - // Println fucks up because it is blocking // When no debugger is connected, the fw just hangs // TODO: Switch to ringbuffer + defmt (see defmt_rtt crate for inspiration or use this: https://crates.io/crates/defmt-bbq) -use my_println as println; +// use hal::println; +use ch32v203::my_println as println; bind_interrupts!(struct Irqs { USB_LP_CAN1_RX0 => hal::usbd::InterruptHandler; @@ -41,8 +35,10 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { hal::debug::SDIPrint::enable(); - let mut config = hal::Config::default(); - config.rcc = hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI; + let mut config = hal::Config { + rcc: hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI, + ..Default::default() + }; config.rcc.apb2_pre = ch32_hal::rcc::APBPrescaler::DIV2; let p = hal::init(config); diff --git a/ch32v203/src/bin/usb_serial_echo.rs b/ch32v203/src/bin/usb_serial_echo.rs index 6577483..e5a35d2 100644 --- a/ch32v203/src/bin/usb_serial_echo.rs +++ b/ch32v203/src/bin/usb_serial_echo.rs @@ -11,17 +11,11 @@ use hal::peripherals::USBD; use hal::usbd::Driver; use static_cell::StaticCell; -#[macro_export] -macro_rules! my_println { - ($($arg:tt)*) => { - () - }; -} - // Println fucks up because it is blocking // When no debugger is connected, the fw just hangs // TODO: Switch to ringbuffer + defmt (see defmt_rtt crate for inspiration or use this: https://crates.io/crates/defmt-bbq) -use my_println as println; +// use hal::println; +use ch32v203::my_println as println; bind_interrupts!(struct Irqs { USB_LP_CAN1_RX0 => hal::usbd::InterruptHandler; diff --git a/ch32v203/src/bin/usb_uart.rs b/ch32v203/src/bin/usb_uart.rs index f417aff..2703798 100644 --- a/ch32v203/src/bin/usb_uart.rs +++ b/ch32v203/src/bin/usb_uart.rs @@ -11,17 +11,11 @@ use static_cell::StaticCell; use ch32v203::usb_uart_task::{usb_rx_uart_tx_task, usb_tx_uart_rx_task}; -#[macro_export] -macro_rules! my_println { - ($($arg:tt)*) => { - () - }; -} - // Println fucks up because it is blocking // When no debugger is connected, the fw just hangs // TODO: Switch to ringbuffer + defmt (see defmt_rtt crate for inspiration or use this: https://crates.io/crates/defmt-bbq) -use my_println as println; +// use hal::println; +use ch32v203::my_println as println; bind_interrupts!(struct Irqs { USB_LP_CAN1_RX0 => hal::usbd::InterruptHandler; diff --git a/ch32v203/src/lib.rs b/ch32v203/src/lib.rs index 7a80be2..1f16992 100644 --- a/ch32v203/src/lib.rs +++ b/ch32v203/src/lib.rs @@ -11,32 +11,3 @@ macro_rules! my_println { () }; } - -pub fn bytes_to_hex<'a>(bytes: &[u8], out: &'a mut [u8]) -> Result<&'a str, ()> { - // Need exactly 2 chars per byte - if out.len() < bytes.len() * 2 { - return Err(()); - } - - let mut i = 0; - for &b in bytes { - let hi = b >> 4; - let lo = b & 0x0F; - - out[i] = hex_char(hi); - out[i + 1] = hex_char(lo); - i += 2; - } - - // SAFETY: we only write valid ASCII hex characters - Ok(core::str::from_utf8(&out[..i]).unwrap()) -} - -#[inline] -const fn hex_char(n: u8) -> u8 { - match n { - 0..=9 => b'0' + n, - 10..=15 => b'A' + (n - 10), - _ => b'?', - } -} diff --git a/ch32v203/src/usb_dap_task.rs b/ch32v203/src/usb_dap_task.rs index 64e438a..05b4071 100644 --- a/ch32v203/src/usb_dap_task.rs +++ b/ch32v203/src/usb_dap_task.rs @@ -86,7 +86,7 @@ impl MyDelay { fn delay_micros(&self, mut us: u32) { while us > 0x1fff { let ticks = (us & 0x1fff) * self.ticks_per_us; - self.delay_ticks(ticks as u32); + self.delay_ticks(ticks); us -= us & 0x1fff; } } @@ -151,11 +151,11 @@ impl<'a> DebuggerPin<'a> { } impl<'a> DbgPin for DebuggerPin<'a> { - fn into_input(&mut self) { + fn set_as_input(&mut self) { self.pin.set_as_input(self.pull_input); self.is_output = false; } - fn into_output_in_state(&mut self, state: PinState) { + fn set_as_output_with_state(&mut self, state: PinState) { match state { PinState::High => self.pin.set_high(), PinState::Low => self.pin.set_low(), diff --git a/ch32v203/src/usb_ppk2_task.rs b/ch32v203/src/usb_ppk2_task.rs index d15865f..a2ed44f 100644 --- a/ch32v203/src/usb_ppk2_task.rs +++ b/ch32v203/src/usb_ppk2_task.rs @@ -13,7 +13,7 @@ use embassy_usb::class::cdc_acm::CdcAcmClass; use ch32_hal::{self as hal, pac, Peri}; use hal::adc::{AdcChannel, AnyAdcChannel, SampleTime}; -use hal::dma::{ReadableRingBuffer, Request, TransferOptions}; +use hal::dma::{ReadableRingBuffer, TransferOptions}; use hal::gpio::{Level, Output, Speed}; use hal::peripherals::{ADC1, DMA1_CH1, PA6, PB4, TIM3, USBD}; use hal::time::Hertz; @@ -124,7 +124,7 @@ fn dma_setup<'d>( let mut ring_buf = unsafe { ReadableRingBuffer::new( dma_channel, - Request::default(), + (), pac::ADC1.rdatar().as_ptr() as *mut u16, adc_buffer, dma_options, diff --git a/ch32v203/src/usb_uart_task.rs b/ch32v203/src/usb_uart_task.rs index 2fd6f70..a08a7ff 100644 --- a/ch32v203/src/usb_uart_task.rs +++ b/ch32v203/src/usb_uart_task.rs @@ -22,29 +22,27 @@ pub async fn usb_tx_uart_rx_task( ) -> ! { let mut buf = [0; 64]; + usb_tx.wait_connection().await; + println!("Usb tx Connected"); loop { - usb_tx.wait_connection().await; - println!("Usb tx Connected"); - loop { - match select( - usb_control.control_changed(), - uart_rx.read_until_idle(&mut buf), - ) - .await - { - Either::First(_) => { - let baud = usb_tx.line_coding().data_rate(); - println!("Setting baud to: {}", baud); - uart_config.baudrate = baud; - if let Err(_err) = uart_rx.set_config(&uart_config) { - println!("Uart config error: {:?}", _err); - } + match select( + usb_control.control_changed(), + uart_rx.read_until_idle(&mut buf), + ) + .await + { + Either::First(_) => { + let baud = usb_tx.line_coding().data_rate(); + println!("Setting baud to: {}", baud); + uart_config.baudrate = baud; + if let Err(_err) = uart_rx.set_config(&uart_config) { + println!("Uart config error: {:?}", _err); } - Either::Second(Err(_err)) => println!("uart rx error! {:?}", _err), - Either::Second(Ok(n)) => { - if let Err(_err) = usb_tx.write_packet(&buf[..n]).await { - println!("Usb tx error! {:?}", _err) - } + } + Either::Second(Err(_err)) => println!("uart rx error! {:?}", _err), + Either::Second(Ok(n)) => { + if let Err(_err) = usb_tx.write_packet(&buf[..n]).await { + println!("Usb tx error! {:?}", _err) } } } @@ -57,18 +55,16 @@ pub async fn usb_rx_uart_tx_task( mut uart_tx: UartTx<'static, peripherals::USART2, Async>, ) -> ! { let mut buf = [0; 64]; + usb_rx.wait_connection().await; + println!("Usb rx Connected"); loop { - usb_rx.wait_connection().await; - println!("Usb rx Connected"); - loop { - match usb_rx.read_packet(&mut buf).await { - Ok(n) => { - if let Err(_err) = uart_tx.write(&buf[..n]).await { - println!("uart tx error! {:?}", _err); - } + match usb_rx.read_packet(&mut buf).await { + Ok(n) => { + if let Err(_err) = uart_tx.write(&buf[..n]).await { + println!("uart tx error! {:?}", _err); } - Err(_err) => println!("Usb rx error: {:?}", _err), } + Err(_err) => println!("Usb rx error: {:?}", _err), } } } diff --git a/ch32v305/src/bin/usb_dap.rs b/ch32v305/src/bin/usb_dap.rs index 086638d..f74bde3 100644 --- a/ch32v305/src/bin/usb_dap.rs +++ b/ch32v305/src/bin/usb_dap.rs @@ -11,7 +11,8 @@ use hal::usb::EndpointDataBuffer512; use hal::usbhs::{Driver, InterruptHandler, WakeupInterruptHandler}; use ch32v305::usb_dap_task::dap_task; -use ch32v305::{bytes_to_hex, my_println}; +use ch32v305::{my_println}; +use rust_link_common::bytes_to_hex; use static_cell::StaticCell; diff --git a/ch32v305/src/bin/usb_multi_ppk2.rs b/ch32v305/src/bin/usb_multi_ppk2.rs index 7456d4f..583a4fe 100644 --- a/ch32v305/src/bin/usb_multi_ppk2.rs +++ b/ch32v305/src/bin/usb_multi_ppk2.rs @@ -14,13 +14,6 @@ use rust_link_common::usb_ppk2::{run as ppk2_run, Adc}; use rust_link_common::usb_ppk2_dfu::{Ppk2DfuClass, State as DfuState}; use static_cell::StaticCell; -#[macro_export] -macro_rules! my_println { - ($($arg:tt)*) => { - () - }; -} - const MAX_NR_OF_ENPOINTS: usize = 8; const PPK2_ENDPOINT_DATA_BUFFER_SIZE: usize = 64; type Ppk2EndpointDataBuffer = EndpointDataBuffer; @@ -29,7 +22,7 @@ type Ppk2EndpointDataBuffer = EndpointDataBuffer // When no debugger is connected, the fw just hangs // TODO: Switch to ringbuffer + defmt (see defmt_rtt crate for inspiration or use this: https://crates.io/crates/defmt-bbq) // use hal::println; -use my_println as println; +use ch32v305::my_println as println; bind_interrupts!(struct Irqs { USBHS => InterruptHandler; @@ -67,7 +60,7 @@ impl Adc for DummyAdc { return self.buffer; } Timer::at(self.next_send_time).await; - self.next_send_time = self.next_send_time + Duration::from_micros(ADC_SEND_INTERVAL_US); + self.next_send_time += Duration::from_micros(ADC_SEND_INTERVAL_US); let first_value = self.buffer.last().unwrap().wrapping_add(1); for i in 0..self.buffer.len() { self.buffer[i] = first_value.wrapping_add(i as u16); @@ -168,8 +161,8 @@ async fn main(spawner: Spawner) { let power_out_enable = Output::new(p.PC9, Level::High, Speed::Low); static ADC_BUFFER_1: StaticCell<[u16; ADC_BUFFER_SIZE]> = StaticCell::new(); let buffer = ADC_BUFFER_1.init([0; ADC_BUFFER_SIZE]); - for i in 0..buffer.len() { - buffer[i] = i as u16; + for (i, val) in buffer.iter_mut().enumerate() { + *val = i as u16; } spawner @@ -193,8 +186,8 @@ async fn main(spawner: Spawner) { let power_out_enable = Output::new(p.PC8, Level::High, Speed::Low); static ADC_BUFFER_2: StaticCell<[u16; ADC_BUFFER_SIZE]> = StaticCell::new(); let buffer = ADC_BUFFER_2.init([0; ADC_BUFFER_SIZE]); - for i in 0..buffer.len() { - buffer[i] = i as u16; + for (i, val) in buffer.iter_mut().enumerate() { + *val = i as u16; } spawner diff --git a/ch32v305/src/bin/usb_serial_echo.rs b/ch32v305/src/bin/usb_serial_echo.rs index 1154470..c88f39a 100644 --- a/ch32v305/src/bin/usb_serial_echo.rs +++ b/ch32v305/src/bin/usb_serial_echo.rs @@ -12,19 +12,11 @@ use hal::bind_interrupts; use hal::usbhs::{InterruptHandler, WakeupInterruptHandler, Driver}; use static_cell::StaticCell; -// use hal::println; - -#[macro_export] -macro_rules! my_println { - ($($arg:tt)*) => { - () - }; -} - // Println fucks up because it is blocking // When no debugger is connected, the fw just hangs // TODO: Switch to ringbuffer + defmt (see defmt_rtt crate for inspiration or use this: https://crates.io/crates/defmt-bbq) -use my_println as println; +// use hal::println; +use ch32v305::my_println as println; bind_interrupts!(struct Irqs { USBHS => InterruptHandler; diff --git a/ch32v305/src/lib.rs b/ch32v305/src/lib.rs index d9875f6..bb5c2be 100644 --- a/ch32v305/src/lib.rs +++ b/ch32v305/src/lib.rs @@ -13,35 +13,6 @@ macro_rules! my_println { }; } -pub fn bytes_to_hex<'a>(bytes: &[u8], out: &'a mut [u8]) -> Result<&'a str, ()> { - // Need exactly 2 chars per byte - if out.len() < bytes.len() * 2 { - return Err(()); - } - - let mut i = 0; - for &b in bytes { - let hi = b >> 4; - let lo = b & 0x0F; - - out[i] = hex_char(hi); - out[i + 1] = hex_char(lo); - i += 2; - } - - // SAFETY: we only write valid ASCII hex characters - Ok(core::str::from_utf8(&out[..i]).unwrap()) -} - -#[inline] -const fn hex_char(n: u8) -> u8 { - match n { - 0..=9 => b'0' + n, - 10..=15 => b'A' + (n - 10), - _ => b'?', - } -} - // This is the config for using external crystal of WCH LinkE (blue pcb) pub const SYSCLK_FREQ_144MHZ_HSE_12MHZ: rcc::Config = { rcc::Config { diff --git a/ch32v305/src/usb_dap_task.rs b/ch32v305/src/usb_dap_task.rs index f694642..62b439b 100644 --- a/ch32v305/src/usb_dap_task.rs +++ b/ch32v305/src/usb_dap_task.rs @@ -86,7 +86,7 @@ impl MyDelay { fn delay_micros(&self, mut us: u32) { while us > 0x1fff { let ticks = (us & 0x1fff) * self.ticks_per_us; - self.delay_ticks(ticks as u32); + self.delay_ticks(ticks); us -= us & 0x1fff; } } @@ -151,11 +151,11 @@ impl<'a> DebuggerPin<'a> { } impl<'a> DbgPin for DebuggerPin<'a> { - fn into_input(&mut self) { + fn set_as_input(&mut self) { self.pin.set_as_input(self.pull_input); self.is_output = false; } - fn into_output_in_state(&mut self, state: PinState) { + fn set_as_output_with_state(&mut self, state: PinState) { match state { PinState::High => self.pin.set_high(), PinState::Low => self.pin.set_low(), diff --git a/common/src/lib.rs b/common/src/lib.rs index 280c794..80c7fc2 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -4,3 +4,32 @@ pub mod usb_ppk2; pub mod usb_ppk2_dfu; pub mod usb_uart; + +#[derive(Debug)] +pub struct BufferTooSmall; + +pub fn bytes_to_hex<'a>(bytes: &[u8], out: &'a mut [u8]) -> Result<&'a str, BufferTooSmall> { + let out = out.get_mut(..bytes.len() * 2).ok_or(BufferTooSmall)?; + + let mut i = 0; + for &b in bytes { + let hi = b >> 4; + let lo = b & 0x0F; + + out[i] = hex_char(hi); + out[i + 1] = hex_char(lo); + i += 2; + } + + // SAFETY: we only write valid ASCII hex characters + Ok(core::str::from_utf8(&out[..bytes.len() * 2]).unwrap()) +} + +#[inline] +const fn hex_char(n: u8) -> u8 { + match n { + 0..=9 => b'0' + n, + 10..=15 => b'A' + (n - 10), + _ => b'?', + } +} diff --git a/common/src/usb_ppk2_dfu.rs b/common/src/usb_ppk2_dfu.rs index 943bc52..f10c51b 100644 --- a/common/src/usb_ppk2_dfu.rs +++ b/common/src/usb_ppk2_dfu.rs @@ -16,11 +16,18 @@ impl State { } } +impl Default for State { + fn default() -> Self { + Self::new() + } +} + pub struct Ppk2DfuClass<'d, D: Driver<'d>> { _marker: &'d PhantomData, } impl<'d, D: Driver<'d>> Ppk2DfuClass<'d, D> { + #[allow(clippy::new_ret_no_self)] pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State) { const USB_CLASS_APPN_SPEC: u8 = 0xFF; const APPN_SPEC_SUBCLASS_DFU: u8 = 0x01; diff --git a/common/src/usb_uart.rs b/common/src/usb_uart.rs index 2e64e90..b101096 100644 --- a/common/src/usb_uart.rs +++ b/common/src/usb_uart.rs @@ -26,7 +26,7 @@ mod rp { } } impl super::UartBaud for embassy_rp::uart::BufferedUartTx { - fn set_baud(&mut self, baudrate: u32) { + fn set_baud(&mut self, _baudrate: u32) { // Uncomment when this PR is merged: https://github.com/embassy-rs/embassy/pull/5159 // let _ = self.set_baudrate(baudrate); } diff --git a/ob-dap/src/lib.rs b/ob-dap/src/lib.rs index c3caca7..ec00ef6 100644 --- a/ob-dap/src/lib.rs +++ b/ob-dap/src/lib.rs @@ -5,8 +5,8 @@ use dap_rs::{swj::Dependencies, *}; use embedded_hal::digital::PinState; pub trait DbgPin { - fn into_input(&mut self); - fn into_output_in_state(&mut self, state: PinState); + fn set_as_input(&mut self); + fn set_as_output_with_state(&mut self, state: PinState); fn set_low(&mut self); fn set_high(&mut self); fn is_high(&self) -> bool; @@ -41,19 +41,19 @@ impl core::fmt::Debug for Context { impl Context { fn swdio_to_input(&mut self) { - self.swdio.into_input(); + self.swdio.set_as_input(); } fn swdio_to_output(&mut self) { - self.swdio.into_output_in_state(PinState::High); + self.swdio.set_as_output_with_state(PinState::High); } fn swclk_to_input(&mut self) { - self.swclk.into_input(); + self.swclk.set_as_input(); } fn swclk_to_output(&mut self) { - self.swclk.into_output_in_state(PinState::High); + self.swclk.set_as_output_with_state(PinState::High); } pub fn from_pins(swdio: P, swclk: P, nreset: P, cpu_frequency: u32, delay: D) -> Self { @@ -95,9 +95,9 @@ impl swj::Dependencies, Jtag> for Contex if mask.contains(swj::Pins::NRESET) { if output.contains(swj::Pins::NRESET) { // "open drain disconnect" - self.nreset.into_input(); + self.nreset.set_as_input(); } else { - self.nreset.into_output_in_state(PinState::Low); + self.nreset.set_as_output_with_state(PinState::Low); } } @@ -130,7 +130,7 @@ impl swj::Dependencies, Jtag> for Contex ret.set(swj::Pins::SWCLK, self.swclk.is_high()); self.swdio_to_input(); ret.set(swj::Pins::SWDIO, self.swdio.is_high()); - self.nreset.into_input(); + self.nreset.set_as_input(); ret.set(swj::Pins::NRESET, self.nreset.is_high()); ret @@ -177,7 +177,7 @@ impl swj::Dependencies, Jtag> for Contex fn high_impedance_mode(&mut self) { self.swdio_to_input(); self.swclk_to_input(); - self.nreset.into_input(); + self.nreset.set_as_input(); } } @@ -220,7 +220,7 @@ impl From> for Swd { // Maybe this should go to some `Swd::new` value.swdio_to_output(); value.swclk_to_output(); - value.nreset.into_input(); + value.nreset.set_as_input(); Self(value) } @@ -237,7 +237,7 @@ impl swd::Swd> for Swd { // Read ack, 1 clock for turnaround and 3 for ACK let ack = self.rx4() >> 1; - match swd::Ack::try_ok(ack as u8) { + match swd::Ack::try_ok(ack) { Ok(_) => (), Err(e) => { // On non-OK ACK, target has released the bus but @@ -270,7 +270,7 @@ impl swd::Swd> for Swd { // Read ack, 1 clock for turnaround and 3 for ACK and 1 for turnaround let ack = (self.rx5() >> 1) & 0b111; - match swd::Ack::try_ok(ack as u8) { + match swd::Ack::try_ok(ack) { Ok(_) => (), Err(e) => { // On non-OK ACK, target has released the bus but diff --git a/rp235x/src/bin/usb_dap.rs b/rp235x/src/bin/usb_dap.rs index 2f36602..1b14e25 100644 --- a/rp235x/src/bin/usb_dap.rs +++ b/rp235x/src/bin/usb_dap.rs @@ -155,7 +155,7 @@ impl MyDelay { fn delay_micros(&self, mut us: u32) { while us > 0x1fff { let ticks = (us & 0x1fff) * self.ticks_per_us; - self.delay_ticks(ticks as u32); + self.delay_ticks(ticks); us -= us & 0x1fff; } } @@ -218,11 +218,11 @@ impl<'a> DebuggerPin<'a> { } impl<'a> DbgPin for DebuggerPin<'a> { - fn into_input(&mut self) { + fn set_as_input(&mut self) { self.pin.set_as_input(); self.is_output = false; } - fn into_output_in_state(&mut self, state: PinState) { + fn set_as_output_with_state(&mut self, state: PinState) { match state { PinState::High => self.pin.set_high(), PinState::Low => self.pin.set_low(), diff --git a/stm32c071/Cargo.toml b/stm32c071/Cargo.toml index 03817c8..cc32d67 100644 --- a/stm32c071/Cargo.toml +++ b/stm32c071/Cargo.toml @@ -30,8 +30,6 @@ static_cell = "2.1" portable-atomic = {version = "1.3", features = ["unsafe-assume-single-core"]} dap-rs = {version = "0.2", features = ["defmt"]} -# dap-rs = { git = "https://github.com/bugadani/dap-rs", rev = "e9aa3c3", features = ["defmt"] } -# bitbang-dap = { git = "https://github.com/bugadani/bitbang-dap", rev = "138717a", features = ["defmt"] } ob-dap = { path = "../ob-dap" } rust-link-common = {path = "../common", features = ["stm32", "defmt"]} diff --git a/stm32c071/src/bin/usb_dap.rs b/stm32c071/src/bin/usb_dap.rs index 6e555bb..aa296c3 100644 --- a/stm32c071/src/bin/usb_dap.rs +++ b/stm32c071/src/bin/usb_dap.rs @@ -1,13 +1,13 @@ #![no_std] #![no_main] -use cortex_m::peripheral::{Peripherals as CorePeripherals, SYST, syst::SystClkSource}; +use cortex_m::peripheral::{syst::SystClkSource, Peripherals as CorePeripherals, SYST}; use dap_rs::dap::{Dap, DapLeds, DelayNs, HostStatus}; use defmt::{error, info}; use embassy_executor::Spawner; use embassy_stm32::gpio::{Flex, Level, Output, Pull, Speed}; use embassy_stm32::usb::{self, Driver}; -use embassy_stm32::{Config, bind_interrupts, peripherals}; +use embassy_stm32::{bind_interrupts, peripherals, Config}; use embassy_usb::class::cmsis_dap_v2::{CmsisDapV2Class, State}; use embassy_usb::msos::windows_version; use embedded_hal::digital::PinState; @@ -172,7 +172,7 @@ impl MyDelay { fn delay_micros(&self, mut us: u32) { while us > 0x1fff { let ticks = (us & 0x1fff) * self.ticks_per_us; - self.delay_ticks(ticks as u32); + self.delay_ticks(ticks); us -= us & 0x1fff; } } @@ -237,11 +237,11 @@ impl<'a> DebuggerPin<'a> { } impl<'a> DbgPin for DebuggerPin<'a> { - fn into_input(&mut self) { + fn set_as_input(&mut self) { self.pin.set_as_input(self.pull_input); self.is_output = false; } - fn into_output_in_state(&mut self, state: PinState) { + fn set_as_output_with_state(&mut self, state: PinState) { match state { PinState::High => self.pin.set_high(), PinState::Low => self.pin.set_low(), diff --git a/stm32c071/src/bin/usb_dap_2.rs b/stm32c071/src/bin/usb_dap_2.rs deleted file mode 100644 index e08825a..0000000 --- a/stm32c071/src/bin/usb_dap_2.rs +++ /dev/null @@ -1,247 +0,0 @@ -#![no_std] -#![no_main] - -use defmt::{error, info}; -use embassy_executor::Spawner; -use embassy_stm32::gpio::{Flex, Pull, Speed}; -use embassy_stm32::usb::{self, Driver}; -use embassy_stm32::{Config, bind_interrupts, peripherals}; -use embassy_usb::class::cmsis_dap_v2::{CmsisDapV2Class, State}; -use embassy_usb::msos::windows_version; -use {defmt_rtt as _, panic_probe as _}; - -use bitbang_dap::{BitbangAdapter, DelayCycles, InputOutputPin}; -use dap_rs::dap::{self, Dap, DapLeds, DelayNs}; -use dap_rs::jtag::TapConfig; -use dap_rs::swo::Swo; - -use static_cell::{ConstStaticCell, StaticCell}; - -bind_interrupts!(struct Irqs { - USB_DRD_FS => usb::InterruptHandler; -}); - -const CPU_FREQUENCY: u32 = 48_000_000; -const MAX_SCAN_CHAIN_LENGTH: usize = 8; - -#[embassy_executor::task] -async fn dap_task( - mut class: CmsisDapV2Class<'static, Driver<'static, peripherals::USB>>, - deps: BitbangAdapter, BitDelay>, -) -> ! { - let mut dap = Dap::new( - deps, - LedSignals, - BitDelay, - None::, - concat!("2.1.0, Adaptor version ", env!("CARGO_PKG_VERSION")), - ); - - let mut report = [0; 64]; - let mut resp_buf = [0; 64]; - - loop { - class.wait_connection().await; - info!("Connected"); - loop { - let n = match class.read_packet(&mut report).await { - Ok(val) => val, - Err(_) => { - error!("Error!"); - break; - } - }; - let len = dap.process_command(&report[..n], &mut resp_buf, dap_rs::dap::DapVersion::V2); - if len > 0 { - if let Err(_err) = class.write_packet(&resp_buf[..len]).await { - info!("Error!"); - break; - } - } - } - info!("Disconnected"); - } -} - -#[embassy_executor::main] -async fn main(spawner: Spawner) { - let mut config = Config::default(); - { - use embassy_stm32::rcc::*; - config.rcc.hsi48 = Some(Hsi48Config { - sync_from_usb: true, - }); - config.rcc.hsi = Some(Hsi { - sys_div: HsiSysDiv::DIV1, - ker_div: HsiKerDiv::DIV3, - }); - config.rcc.mux.usbsel = mux::Usbsel::HSI48; - } - let p = embassy_stm32::init(config); - - let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); - - // Create embassy-usb Config - let mut config = embassy_usb::Config::new(0x1a86, 0x7021); - config.manufacturer = Some("Bauck"); - config.product = Some("Rust-link-STM32C071 (CMSIS-DAP v2)"); // Need to have "CMSIS-DAP" in the product name to make probe-rs recognize it - config.serial_number = Some("12345678"); - - config.max_power = 100; - config.max_packet_size_0 = 64; - config.device_class = 0xEF; - config.device_sub_class = 0x02; - config.device_protocol = 0x01; - config.composite_with_iads = true; - - let mut builder = { - static CONFIG_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); - static BOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); - static MSOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); - static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); - - let builder = embassy_usb::Builder::new( - driver, - config, - CONFIG_DESCRIPTOR.init([0; 256]), - BOS_DESCRIPTOR.init([0; 256]), - MSOS_DESCRIPTOR.init([0; 256]), - CONTROL_BUF.init([0; 128]), - ); - builder - }; - - builder.msos_descriptor(windows_version::WIN8_1, 0); - - let class = { - static STATE: StaticCell = StaticCell::new(); - let state = STATE.init(State::new()); - CmsisDapV2Class::new(&mut builder, state, 64, false) - }; - - // Build the builder. - let mut usb = builder.build(); - - static SCAN_CHAIN: ConstStaticCell<[TapConfig; MAX_SCAN_CHAIN_LENGTH]> = - ConstStaticCell::new([TapConfig::INIT; MAX_SCAN_CHAIN_LENGTH]); - - let deps = BitbangAdapter::new( - IoPin::new(Flex::new(p.PA1)), - IoPin::new(Flex::new(p.PA6)), - IoPin::new(Flex::new(p.PA2)), - IoPin::new(Flex::new(p.PA3)), - IoPin::new(Flex::new(p.PA7)), - BitDelay, - SCAN_CHAIN.take(), - ); - - spawner.spawn(dap_task(class, deps)).unwrap(); - - usb.run().await; -} - -struct LedSignals; - -impl DapLeds for LedSignals { - fn react_to_host_status(&mut self, _host_status: dap::HostStatus) {} -} - -struct BitDelay; - -impl DelayNs for BitDelay { - fn delay_ns(&mut self, ns: u32) { - self.delay_cycles((ns as u64 * self.cpu_clock() as u64 / 1_000_000_000_u64) as u32); - } -} - -impl DelayCycles for BitDelay { - fn delay_cycles(&mut self, cycles: u32) { - cortex_m::asm::delay(cycles); - } - - fn cpu_clock(&self) -> u32 { - // This function is used to calculate the number of cycles to wait in a SWD/JTAG clock - // cycle, so we don't actually have to return the real CPU frequency. - // cortex_m __delay divides by 2 and Cortex-M0+ needs 4 CPU cycles per delay loop iteration. - CPU_FREQUENCY / 2 - } -} - -struct IoPin<'a> { - pin: Flex<'a>, -} - -impl<'a> IoPin<'a> { - fn new(pin: Flex<'a>) -> Self { - Self { pin } - } -} - -impl InputOutputPin for IoPin<'_> { - fn set_as_output(&mut self) { - self.pin.set_as_output(Speed::High); - } - - fn set_high(&mut self, high: bool) { - match high { - true => self.pin.set_high(), - false => self.pin.set_low(), - } - } - - fn set_as_input(&mut self) { - self.pin.set_as_input(Pull::None); - } - - fn is_high(&mut self) -> bool { - self.pin.is_high() - } -} - -struct NoSwo; - -impl Swo for NoSwo { - fn set_transport(&mut self, _transport: dap_rs::swo::SwoTransport) { - todo!() - } - - fn set_mode(&mut self, _mode: dap_rs::swo::SwoMode) { - todo!() - } - - fn set_baudrate(&mut self, _baudrate: u32) -> u32 { - todo!() - } - - fn set_control(&mut self, _control: dap_rs::swo::SwoControl) { - todo!() - } - - fn polling_data(&mut self, _buf: &mut [u8]) -> u32 { - todo!() - } - - fn streaming_data(&mut self) { - todo!() - } - - fn is_active(&self) -> bool { - todo!() - } - - fn bytes_available(&self) -> u32 { - todo!() - } - - fn buffer_size(&self) -> u32 { - todo!() - } - - fn support(&self) -> dap_rs::swo::SwoSupport { - todo!() - } - - fn status(&mut self) -> dap_rs::swo::SwoStatus { - todo!() - } -} diff --git a/stm32c071/src/bin/usb_ppk2.rs b/stm32c071/src/bin/usb_ppk2.rs index 7b12ece..748f0c8 100644 --- a/stm32c071/src/bin/usb_ppk2.rs +++ b/stm32c071/src/bin/usb_ppk2.rs @@ -46,7 +46,7 @@ impl Adc for DummyAdc { return self.buffer; } Timer::at(self.next_send_time).await; - self.next_send_time = self.next_send_time + Duration::from_micros(ADC_SEND_INTERVAL_US); + self.next_send_time += Duration::from_micros(ADC_SEND_INTERVAL_US); let first_value = self.buffer.last().unwrap().wrapping_add(1); for i in 0..self.buffer.len() { self.buffer[i] = first_value.wrapping_add(i as u16); @@ -68,8 +68,8 @@ async fn usb_ppk2_task( ) -> ! { static ADC_BUFFER: StaticCell<[u16; ADC_BUFFER_SIZE]> = StaticCell::new(); let buffer = ADC_BUFFER.init([0; ADC_BUFFER_SIZE]); - for i in 0..buffer.len() { - buffer[i] = i as u16; + for (i, val) in buffer.iter_mut().enumerate() { + *val = i as u16; } let adc = DummyAdc::new(buffer); ppk2_run(class, adc, power_out_enable, 1, 12).await; diff --git a/stm32g431/src/bin/usb_dap.rs b/stm32g431/src/bin/usb_dap.rs index 34a0eef..a3125ac 100644 --- a/stm32g431/src/bin/usb_dap.rs +++ b/stm32g431/src/bin/usb_dap.rs @@ -180,7 +180,7 @@ impl MyDelay { fn delay_micros(&self, mut us: u32) { while us > 0x1fff { let ticks = (us & 0x1fff) * self.ticks_per_us; - self.delay_ticks(ticks as u32); + self.delay_ticks(ticks); us -= us & 0x1fff; } } @@ -245,11 +245,11 @@ impl<'a> DebuggerPin<'a> { } impl<'a> DbgPin for DebuggerPin<'a> { - fn into_input(&mut self) { + fn set_as_input(&mut self) { self.pin.set_as_input(self.pull_input); self.is_output = false; } - fn into_output_in_state(&mut self, state: PinState) { + fn set_as_output_with_state(&mut self, state: PinState) { match state { PinState::High => self.pin.set_high(), PinState::Low => self.pin.set_low(), diff --git a/stm32g431/src/bin/usb_ppk2.rs b/stm32g431/src/bin/usb_ppk2.rs index d5143b6..c8fdf2c 100644 --- a/stm32g431/src/bin/usb_ppk2.rs +++ b/stm32g431/src/bin/usb_ppk2.rs @@ -43,7 +43,7 @@ impl Adc for DummyAdc { return self.buffer; } Timer::at(self.next_send_time).await; - self.next_send_time = self.next_send_time + Duration::from_micros(ADC_SEND_INTERVAL_US); + self.next_send_time += Duration::from_micros(ADC_SEND_INTERVAL_US); let first_value = self.buffer.last().unwrap().wrapping_add(1); for i in 0..self.buffer.len() { self.buffer[i] = first_value.wrapping_add(i as u16); @@ -65,8 +65,8 @@ async fn usb_ppk2_task( ) -> ! { static ADC_BUFFER: StaticCell<[u16; ADC_BUFFER_SIZE]> = StaticCell::new(); let buffer = ADC_BUFFER.init([0; ADC_BUFFER_SIZE]); - for i in 0..buffer.len() { - buffer[i] = i as u16; + for (i, val) in buffer.iter_mut().enumerate() { + *val = i as u16; } let adc = DummyAdc::new(buffer); ppk2_run(class, adc, power_out_enable, 1, 12).await;