From 3e5a905544738bd42ea2e3f3de95cd8635a53888 Mon Sep 17 00:00:00 2001 From: Robert Schauklies Date: Sun, 18 Jan 2026 16:56:54 +0100 Subject: [PATCH] safety commit --- spinnyboy_rust/src/bin/dc_driver/dshot.rs | 41 +++++++++++++++-------- spinnyboy_rust/src/bin/main.rs | 31 ++++++++++++++--- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/spinnyboy_rust/src/bin/dc_driver/dshot.rs b/spinnyboy_rust/src/bin/dc_driver/dshot.rs index 1ac3866..d746a7d 100644 --- a/spinnyboy_rust/src/bin/dc_driver/dshot.rs +++ b/spinnyboy_rust/src/bin/dc_driver/dshot.rs @@ -40,18 +40,27 @@ impl BitTicks { Self { t0_h, t1_h, - t0_l: t1_h, - t1_l: t0_h, + t0_l:t1_h, + t1_l:t0_h, } } - - pub fn from_clk(clk_speed: u32, clk_divider: u8, bit_times: BitTimes) -> Self { + + pub fn from_clk( + clk_speed: u32, + clk_divider: u8, + bit_times: BitTimes, + speed: DShotSpeed, + ) -> Self { let tick_len = (1. / clk_speed as f32) * (clk_divider as f32) * 1_000_000.; + let bit_period_us = speed.bit_period_ns() as f32 / 1000.0; + let bit_ticks = (bit_period_us / tick_len).round() as u16; + let t1_h = (speed.bit_times().t1_h / tick_len).round() as u16; + let t0_h = (speed.bit_times().t0_h / tick_len).round() as u16; + let mut bittick = Self::new(t1_h, t0_h); + bittick.t0_l = bit_ticks -t0_h; + bittick.t1_l = bit_ticks - t1_h; + bittick - let t1_h = (bit_times.t1_h / tick_len).round() as u16; - let t0_h = (bit_times.t0_h / tick_len).round() as u16; - - Self::new(t1_h, t0_h) } } @@ -112,7 +121,6 @@ impl DShotSpeed { } #[allow(dead_code)] -#[derive(Debug)] pub struct DShot<'a> { rx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Rx>, tx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Tx>, @@ -124,14 +132,14 @@ impl<'a> DShot<'a> { pub fn new( rx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Rx>, tx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Tx>, + speed: DShotSpeed, clk_speed: Option, clk_divider: Option, ) -> Self { let clk_speed = clk_speed.unwrap_or(80_000_000); let clk_divider = clk_divider.unwrap_or(1); - - let bit_ticks = BitTicks::from_clk(clk_speed, clk_divider, speed.bit_times()); + let bit_ticks = BitTicks::from_clk(clk_speed, clk_divider, speed.bit_times(),speed); Self { rx_channel: rx_channel, tx_channel: tx_channel, @@ -179,8 +187,13 @@ impl<'a> DShot<'a> { }; } - // Add empty pulse to end of pulses frame - pulses[16] = 0; + pulses[16] = PulseCode::new( + Level::Low, + self.bit_ticks.t1_h * 2, + Level::Low, + 0, + ) + .into(); pulses } @@ -199,7 +212,7 @@ impl<'a> DShot<'a> { pub fn arm(&mut self, delay: &mut Delay) -> Result<(), &'static str> { for _ in 0..100 { self.write_throttle(0, false)?; - delay.delay_millis(20); + delay.delay_millis(50); } Ok(()) diff --git a/spinnyboy_rust/src/bin/main.rs b/spinnyboy_rust/src/bin/main.rs index 5efd3fc..962c731 100644 --- a/spinnyboy_rust/src/bin/main.rs +++ b/spinnyboy_rust/src/bin/main.rs @@ -5,10 +5,8 @@ reason = "mem::forget is generally not safe to do with esp_hal types, especially those \ holding buffers for the duration of a data transfer." )] -use core::fmt::Write; use alloc::string::ToString; use esp_hal::uart::{Config, Uart}; - use esp_hal::clock::CpuClock; use esp_hal::delay::Delay; use esp_hal::main; @@ -18,7 +16,7 @@ use esp_hal::gpio::{Input, InputConfig}; use esp_hal::mcpwm::operator::PwmPinConfig; use esp_hal::mcpwm::timer::PwmWorkingMode; use esp_hal::time::Rate; - +use esp_hal::rmt::{Rmt, TxChannelConfig, TxChannelCreator}; use esp_hal::handler; use core::cell::RefCell; @@ -28,10 +26,19 @@ use esp_hal::time::{Duration, Instant}; use esp_hal::timer::timg::TimerGroup; use rtt_target::rprintln; mod dc_driver; + mod peripherals; + use dc_driver::afroesc::AfroEsc; use peripherals::nextion::Nextion; +//DSHOT via rmt! +use dc_driver::dshot::DShot; +use dc_driver::dshot::DShotSpeed; + +use esp_hal::rmt::RxChannelCreator; +use esp_hal::rmt::RxChannelConfig; +use crate::dc_driver::dshot; use crate::peripherals::ErrCommand; #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { @@ -49,6 +56,7 @@ const DEFAULT_SPIN_TIME: u32 = 10; // This creates a default app-descriptor required by the esp-idf bootloader. // For more information see: esp_bootloader_esp_idf::esp_app_desc!(); +use crate::peripherals::Command; #[main] fn main() -> ! { @@ -74,7 +82,21 @@ fn main() -> ! { .timer_clock_with_frequency(19_999, PwmWorkingMode::Increase, Rate::from_hz(50)) .unwrap(); mcpwm.timer0.start(timer_clock_cfg); - // let mut esc = AfroEsc::new(&mut pwm_pin); + + //setup RMT + let freq = Rate::from_mhz(80); + let rmt = Rmt::new(peripherals.RMT, freq).expect("CAN NOT SET FREQUENCY"); + let rx_config = RxChannelConfig::default().with_clk_divider(1); + let tx_config = TxChannelConfig::default().with_clk_divider(1); + + let mut tx_channel = unsafe{rmt.channel0.configure_tx(peripherals.GPIO11,tx_config ).unwrap()}; + let mut rx_channel = rmt.channel3.configure_rx(peripherals.GPIO12,rx_config).unwrap(); + let mut dshot_esc = dshot::DShot::new(&mut rx_channel, &mut tx_channel, DShotSpeed::DShot600, Some(80_000_000), Some(1)); + rprintln!("SENDING RMT"); + dshot_esc.arm(&mut delay); + dshot_esc.write_throttle(20, false); + rprintln!("RMT SENT!"); + // let mut esc = AfroEsc::new(&mut pwm_pin);; // esc.set_timestamp(1000); // delay.delay_millis(3000); // esc.set_duty_percent(10); @@ -84,7 +106,6 @@ fn main() -> ! { // delay.delay_millis(3000); //gpio 9 is the button let input_config = InputConfig::default().with_pull(esp_hal::gpio::Pull::Up); - use crate::peripherals::Command; //let emergency_button = peripherals.GPIO9; let mut emergency_button = Input::new(peripherals.GPIO9, input_config); critical_section::with(|cs| {