diff --git a/spinnyboy_rust/src/bin/dc_driver/afroesc.rs b/spinnyboy_rust/src/bin/dc_driver/afroesc.rs index 8469ca0..9dcf89d 100644 --- a/spinnyboy_rust/src/bin/dc_driver/afroesc.rs +++ b/spinnyboy_rust/src/bin/dc_driver/afroesc.rs @@ -1,59 +1,56 @@ -use crate::dc_driver::EscState; -use esp_hal::delay::Delay; use esp_hal::mcpwm::operator::PwmPin; -pub struct AfroEsc<'a> { - pub pwm_pin: &'a mut PwmPin<'a, esp_hal::peripherals::MCPWM0<'a>, 0, true>, - state: crate::dc_driver::EscState, -} -const ARMING_SEQUENCE: u16 = 1055; -const MIN_THROTTLE: u16 = 1121; -const MAX_THROTTLE: u16 = 1421; -const GAP: u16 = (MAX_THROTTLE - MIN_THROTTLE) / 100; +use esp_hal::delay::Delay; +use crate::dc_driver::EscState; +pub struct AfroEsc<'a>{ + pub pwm_pin: &'a mut PwmPin<'a, esp_hal::peripherals::MCPWM0<'a>, 0,true>, + state: crate::dc_driver::EscState, -impl AfroEsc<'_> { - //this is a little hacky tbh - pub fn new<'a>( - pwm_pin: &'a mut PwmPin<'a, esp_hal::peripherals::MCPWM0<'a>, 0, true>, - ) -> AfroEsc<'a> { - let mut esc = AfroEsc { - pwm_pin: pwm_pin, - state: EscState::Starting, - }; - let delay = Delay::new(); - esc.send_arming_sequence(); - delay.delay_millis(3000); - esc - } - pub fn set_timestamp(&mut self, value: u16) { - self.pwm_pin.set_timestamp(value); - } - //range is from 1121 till 1421 - pub fn set_duty_percent(&mut self, value: u16) { - if value > 100 { - // failsafe! - self.pwm_pin.set_timestamp(1055); - } - let new_timestamp = MIN_THROTTLE + value * GAP; - self.pwm_pin.set_timestamp(new_timestamp); - } - pub fn send_arming_sequence(&mut self) { - self.set_timestamp(1055); - } - fn set_state(&mut self, state: EscState) { - self.state = state; - } - pub fn get_state(self) -> EscState { - self.state - } - pub fn map_duty(&mut self, x: i32) { - if x <= 0 { - self.pwm_pin.set_timestamp(1055); - } else { - let duty: u16 = - crate::dc_driver::arduino_map(x, 0, 100, MIN_THROTTLE.into(), MAX_THROTTLE.into()) - .try_into() - .expect("INTEGER TOO LARGE"); - self.pwm_pin.set_timestamp(duty); - } - } } +const ARMING_SEQUENCE:u16 = 1055; +const MIN_THROTTLE:u16 = 1121; +const MAX_THROTTLE:u16 = 1421; +const GAP:u16 = (MAX_THROTTLE - MIN_THROTTLE)/100; + +impl AfroEsc<'_>{ + //this is a little hacky tbh + pub fn new<'a>(pwm_pin:&'a mut PwmPin<'a, esp_hal::peripherals::MCPWM0<'a>, 0,true>)-> AfroEsc<'a> { + let mut esc = AfroEsc{pwm_pin:pwm_pin,state:EscState::Starting}; + let delay = Delay::new(); + esc.send_arming_sequence(); + delay.delay_millis(3000); + esc + } + pub fn set_timestamp(&mut self,value:u16){ + + self.pwm_pin.set_timestamp(value); + } + //range is from 1121 till 1421 + pub fn set_duty_percent(&mut self,value:u16){ + if value > 100 { + // failsafe! + self.pwm_pin.set_timestamp(1055); + } + let new_timestamp = MIN_THROTTLE+value*GAP; + self.pwm_pin.set_timestamp(new_timestamp); + } + pub fn send_arming_sequence(&mut self){ + self.set_timestamp(1055); + } + fn set_state(&mut self, state:EscState){ + self.state = state; + } + pub fn get_state(self) -> EscState{ + self.state + } + pub fn map_duty(&mut self, x:i32){ + if x <=0 { + self.pwm_pin.set_timestamp(1055); + } + else{ + let duty:u16 = crate::dc_driver::arduino_map(x, 0, 100, MIN_THROTTLE.into(), MAX_THROTTLE.into()).try_into().expect("INTEGER TOO LARGE"); + self.pwm_pin.set_timestamp(duty); + + } + } + +} \ No newline at end of file diff --git a/spinnyboy_rust/src/bin/dc_driver/dshot.rs b/spinnyboy_rust/src/bin/dc_driver/dshot.rs index b6a2f42..54dc764 100644 --- a/spinnyboy_rust/src/bin/dc_driver/dshot.rs +++ b/spinnyboy_rust/src/bin/dc_driver/dshot.rs @@ -1,18 +1,12 @@ // use embedded_hal_async::delay::DelayNs; use esp_hal::{ - delay::{self, Delay}, + delay::Delay, gpio::Level, - rmt::{Channel, PulseCode, SingleShotTxTransaction}, + rmt::{Channel, PulseCode, Rx, Tx, TxChannelCreator}, }; -use core::{cell::{Ref, RefCell}, ops::Index}; use num_traits::float::FloatCore; use rtt_target::{rprint, rprintln}; -fn calculate_crc(frame: u16) -> u16 { - (0xffff ^ (frame ^ (frame >> 4) ^ (frame >> 8))) & 0xF -} - - #[allow(dead_code)] #[allow(non_camel_case_types)] #[derive(Debug)] @@ -47,14 +41,15 @@ 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, speed: DShotSpeed, ) -> Self { let tick_len = (1. / clk_speed as f32) * (clk_divider as f32) * 1_000_000.; @@ -62,10 +57,11 @@ impl BitTicks { 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; + let mut bittick = Self::new(t1_h, t0_h); + bittick.t0_l = bit_ticks -t0_h; bittick.t1_l = bit_ticks - t1_h; bittick + } } @@ -83,7 +79,6 @@ impl BitTimes { } #[derive(Debug, Clone, Copy)] -#[allow(dead_code)] pub enum DShotSpeed { DShot150, DShot300, @@ -114,93 +109,24 @@ impl DShotSpeed { Self::DShot1200 => BitTimes::new(0.625, 0.313), } } -} -fn decode_bidi_telemetry(pulses: &[PulseCode]) -> Option { - // Convert to simple list of edges. - let mut edges = [(false, 0u32); 64]; - let mut nedges = 0usize; - let mut time = 0u32; - let mut plength = 0u32; - for (i, p) in pulses.iter().enumerate() { - if p.length1() == 0 { - break; - } else { - nedges += 1; - edges[i*2] = (p.level1() == Level::High, time + plength); - time += plength; - plength = p.length1() as u32; - } - if p.length2() == 0 { - break; - } else { - nedges += 1; - edges[i*2+1] = (p.level2() == Level::High, time + plength); - time += plength; - plength = p.length2() as u32; + /// These are for an 80 MHz clock with a clock divider setting of 1 + pub fn default_bit_ticks(&self) -> BitTicks { + match &self { + Self::DShot150 => BitTicks::new(400, 200), + Self::DShot300 => BitTicks::new(200, 100), + Self::DShot600 => BitTicks::new(100, 50), + Self::DShot1200 => BitTicks::new(50, 25), } } - edges[nedges] = (!edges[nedges-1].0, time + plength); - nedges += 1; - - // Process edges. - // TODO: strip until we find the first negative edge. - assert_eq!(edges[0].0, false); - - // Approximate. Should be calculated instead, in practice these pulses are - // around 1.34us. - let period = 104u32; - - // Grad middle of each period, find latest applying period. Shitty - // algorithm. - let mut res = [false; 22]; - for i in 0..res.len() { - let pos = (i as u32)*period + period/2; - let mut level = edges[0].0; - for edge in edges[..nedges].iter() { - if edge.1 > pos { - break; - } - level = edge.0; - } - res[i] = level; - } - - let mut gcr_diff = 0u32; - for i in 0..21 { - gcr_diff |= (res[20-i] as u32) << i; - } - - let gcr = (gcr_diff>>1) ^ gcr_diff; - - // Shitty LUT decode for GCR; - let lut: [u8; 16] = [ - 0x19, 0x1b, 0x12, 0x13, 0x1d, 0x15, 0x16, 0x17, 0x1a, 0x09, 0x0a, 0x0b, - 0x1e, 0x0d, 0x0e, 0x0f, - ]; - - let mut res = 0u16; - for i in 0..4 { - let fibble = ((gcr >> (i*5)) & 0b11111) as u8; - if let Some(nibble) = lut.iter().position(|&v| v == fibble) { - res |= (nibble as u16) << (i*4); - } else { - return None; - } - } - Some(res) } #[allow(dead_code)] pub struct DShot<'a> { - rx_channel: RefCell<&'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Rx>>, + 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, bit_ticks: BitTicks, - - pulses: RefCell<[u32; 17]>, - requested_throttle: RefCell, - current_tx: RefCell>>, - current_tx_done_at: RefCell>, } impl<'a> DShot<'a> { @@ -214,151 +140,82 @@ impl<'a> DShot<'a> { ) -> 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); - - let txc = tx_channel.reborrow().transmit(&[0u32]).unwrap(); + let bit_ticks = BitTicks::from_clk(clk_speed, clk_divider, speed.bit_times(),speed); + rprint!("bit_ticks.t1_h:{},t1_l:{},t0_h:{},t0_l{}",bit_ticks.t1_h,bit_ticks.t1_l,bit_ticks.t0_h,bit_ticks.t0_l); Self { - rx_channel: RefCell::new(rx_channel), + rx_channel: rx_channel, + tx_channel: tx_channel, speed, bit_ticks, - - pulses: RefCell::new([0u32; 17]), - requested_throttle: RefCell::new(0), - current_tx: RefCell::new(Some(txc)), - current_tx_done_at: RefCell::new(None), } } + pub fn calculate_crc(frame: u16) -> u16 { + (frame ^ (frame >> 4) ^ (frame >> 8)) & 0xF + } + pub fn create_frame(value: u16, telemetry: bool) -> u16 { // Mask to 11 bits (0-2047 range) and set telemetry bit let frame = ((value & 0x07FF) << 1) | telemetry as u16; - let crc = calculate_crc(frame); + let crc = Self::calculate_crc(frame); (frame << 4) | crc } #[allow(clippy::needless_range_loop)] - pub fn create_pulses(&self, throttle_value: u16, telemetry: bool) -> [u32; 17] { + pub fn create_pulses(&mut self, throttle_value: u16, telemetry: bool) -> [u32; 17] { let frame = Self::create_frame(throttle_value, telemetry); let mut pulses = [0; 17]; + rprintln!("CREATING NEW FRAME!"); + rprintln!("--------------------"); for i in 0..16 { let bit = (frame >> (15 - i)) & 1; - + pulses[i] = if bit == 1 { + rprint!("1"); PulseCode::new( - Level::Low, - self.bit_ticks.t1_h, Level::High, + self.bit_ticks.t1_h, + Level::Low, self.bit_ticks.t1_l, ) .into() } else { + rprint!("0"); PulseCode::new( - Level::Low, - self.bit_ticks.t0_h, Level::High, + self.bit_ticks.t0_h, + Level::Low, self.bit_ticks.t0_l, ) .into() }; } + rprintln!(""); + rprintln!("--------------------"); - pulses[16] = 0; + pulses[16] =0; pulses } - pub fn process(&'a self) { - let mut rc = self.current_tx.borrow_mut(); - if let Some(current) = rc.as_mut() { - if current.poll() { - // We're done - but we might still be waiting for a response over bidi. - let mut ended = self.current_tx_done_at.borrow_mut(); - if ended.is_none() { - let start = esp_hal::time::Instant::now(); - *ended = Some(start); - - // Try to receive a response for up to 100us. - let mut rx = self.rx_channel.borrow_mut(); - let rx = rx.reborrow(); - let mut buf = [PulseCode::default(); 32]; - { - let mut rxt = rx.receive(&mut buf).unwrap(); - while start.elapsed().as_micros() < 100 { - // Got something within this time. - if rxt.poll() { - // Receive it fully. - let (len, _) = rxt.wait().unwrap(); + pub fn write_throttle(&mut self, throttle: u16, telemetry: bool) -> Result<(), &'static str> { + let pulses = self.create_pulses(throttle, telemetry); + let tx_chann = self.tx_channel.reborrow(); + let transaction = tx_chann + .transmit(&pulses) + .unwrap_or(return Err("Failed to send frame")) + .wait() + .unwrap_or(return Err("Waiting failed!")); - // Parse out telemetry data. - if len != 0 { - // Decode to a 16 bit value. - if let Some(frame) = decode_bidi_telemetry(&buf[..len]) { - // Check CRC. - let data = frame >> 4; - let crc = calculate_crc(data); - if data != 0xfff && crc == (frame&0b1111) { - // Fucking got it. - let exp = data >> 9; - let mantissa = data & 0b111111111; - let rpm = mantissa << exp; - rprintln!("RPM: {}", rpm); - } - } - } - break; - } - } - } - } - - let ended_at = *ended.as_ref().unwrap(); - - if ended_at.elapsed().as_millis() > 1 { - // Schedule new transaction - let tx_chann = rc.take().unwrap().wait().unwrap(); - let mut pulses = self.pulses.borrow_mut(); - let throttle = self.requested_throttle.borrow(); - *pulses = self.create_pulses(*throttle, false); - let pulses = pulses.as_ref(); - // SAFETY: eat shit, rust - let pulses = unsafe { - core::mem::transmute(pulses) - }; - let m = tx_chann - .transmit(pulses) - .unwrap(); - - *rc = Some(m); - *ended = None; - } else{ - // Wait for bidi dshot data. - } - } - } else { - // Nothing to do, twiddle our thumbs. - } + Ok(()) } - pub fn set_throttle(&self, v: u16) { - *self.requested_throttle.borrow_mut() = v; - } - - #[allow(dead_code)] - pub fn arm(&'a self) -> Result<(), &'static str> { - let start = esp_hal::time::Instant::now(); - - rprintln!("ARM: Sending pre-throttle..."); - while start.elapsed().as_secs() < 2 { - self.set_throttle(100); - self.process(); + pub fn arm(&mut self, delay: &mut Delay) -> Result<(), &'static str> { + for _ in 0..100 { + self.write_throttle(0, false)?; + delay.delay_millis(50); } - rprintln!("ARM: Sending 0..."); - while start.elapsed().as_secs() < 4 { - self.set_throttle(0); - self.process(); - } - rprintln!("ARM: Done."); Ok(()) } diff --git a/spinnyboy_rust/src/bin/dc_driver/mod.rs b/spinnyboy_rust/src/bin/dc_driver/mod.rs index 564bce8..40e125f 100644 --- a/spinnyboy_rust/src/bin/dc_driver/mod.rs +++ b/spinnyboy_rust/src/bin/dc_driver/mod.rs @@ -1,2 +1,17 @@ -//pub mod afroesc; +pub mod afroesc; pub mod dshot; +pub enum EscState { + Starting, + Running, + Stopping, + Stop + +} +//taken from: https://docs.arduino.cc/language-reference/en/functions/math/map/ +//used for the ramp up of the spincoater +pub fn arduino_map(x:i32, in_min:i32, in_max:i32, out_min:i32, out_max:i32) -> i32 { + + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + +} + diff --git a/spinnyboy_rust/src/bin/main.rs b/spinnyboy_rust/src/bin/main.rs index 6c043f1..61589fb 100644 --- a/spinnyboy_rust/src/bin/main.rs +++ b/spinnyboy_rust/src/bin/main.rs @@ -5,37 +5,41 @@ 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 alloc::boxed::Box; use alloc::string::ToString; +use esp_hal::uart::{Config, Uart}; use esp_hal::clock::CpuClock; use esp_hal::delay::Delay; -use esp_hal::{gpio, main}; -use esp_hal::uart::{Config, Uart}; +use esp_hal::main; -use esp_hal::gpio::{Event, OutputConfig}; +use esp_hal::gpio::Event; use esp_hal::gpio::{Input, InputConfig}; -use esp_hal::handler; -use esp_hal::rmt::{Rmt, TxChannelConfig, TxChannelCreator}; +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; -use core::mem::forget; use critical_section::Mutex; use esp_backtrace as _; +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; -use esp_hal::rmt::RxChannelConfig; -use esp_hal::rmt::RxChannelCreator; #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { rprintln!("PANIC!"); @@ -53,6 +57,9 @@ const DEFAULT_SPIN_TIME: u32 = 10; // For more information see: esp_bootloader_esp_idf::esp_app_desc!(); use crate::peripherals::Command; +use esp_hal::gpio::Output; +use esp_hal::gpio::Level; +use esp_hal::gpio::OutputConfig; #[main] fn main() -> ! { @@ -62,46 +69,40 @@ fn main() -> ! { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); - let delay = Delay::new(); + let system = peripherals.SYSTEM; + let mut delay = Delay::new(); esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 65536); + let clock_config = + esp_hal::mcpwm::PeripheralClockConfig::with_frequency(Rate::from_mhz(32)).unwrap(); + let mut mcpwm = esp_hal::mcpwm::McPwm::new(peripherals.MCPWM0, clock_config); + mcpwm.operator0.set_timer(&mcpwm.timer0); + let mut pwm_pin = mcpwm + .operator0 + .with_pin_a(peripherals.GPIO18, PwmPinConfig::UP_ACTIVE_HIGH); + let timer_clock_cfg = clock_config + .timer_clock_with_frequency(19_999, PwmWorkingMode::Increase, Rate::from_hz(50)) + .unwrap(); + mcpwm.timer0.start(timer_clock_cfg); + //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 toggle_pin = Output::new(peripherals.GPIO2, Level::Low, OutputConfig::default()); + let mut tx_channel = rmt.channel0.configure_tx(peripherals.GPIO23,tx_config ).expect("creation of TX_CHANNEL FAILED!"); + let mut rx_channel = rmt.channel3.configure_rx(peripherals.GPIO14,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"); + loop{ + delay.delay_millis(1000); + toggle_pin.set_high(); + dshot_esc.write_throttle(2047,true); + toggle_pin.set_low(); - let rx_config = RxChannelConfig::default().with_clk_divider(1).with_idle_threshold(1000); - let tx_config = TxChannelConfig::default().with_clk_divider(1).with_idle_output(true).with_idle_output_level(esp_hal::gpio::Level::High); - let oc = OutputConfig::default().with_drive_mode(esp_hal::gpio::DriveMode::OpenDrain); - let ic = InputConfig::default(); - let rx_pin = gpio::Input::new(unsafe { peripherals.GPIO23.clone_unchecked() }, ic); - let tx_pin = gpio::Output::new(peripherals.GPIO23, esp_hal::gpio::Level::High, oc); - let mut tx_channel = rmt - .channel0 - .configure_tx(tx_pin, tx_config) - .expect("creation of TX_CHANNEL FAILED!"); - let mut rx_channel = rmt - .channel3 - .configure_rx(rx_pin, rx_config) - .unwrap(); - let dshot_esc = dshot::DShot::new( - &mut rx_channel, - &mut tx_channel, - DShotSpeed::DShot600, - Some(80_000_000), - Some(1), - ); - let dshot_esc = Box::new(dshot_esc); - let dshot_esc = Box::leak(dshot_esc); - - //dshot_esc.arm(&delay).unwrap(); - - dshot_esc.arm(); - loop { - dshot_esc.process(); - dshot_esc.set_throttle(150); } - // rprintln!("RMT SENT!"); // let mut esc = AfroEsc::new(&mut pwm_pin);; // esc.set_timestamp(1000); @@ -137,41 +138,41 @@ fn main() -> ! { let mut display = Nextion::new(&mut uart0); display.send_command(b"page page0"); - let mut _rpm = DEFAULT_TARGET_RPM; - let mut _timer = DEFAULT_SPIN_TIME; + let mut rpm = DEFAULT_TARGET_RPM; + let mut timer = DEFAULT_SPIN_TIME; let mut started = false; loop { if display.read_ready() { match display.read_command() { - Ok(Command::CommandSuccess) => { - rprintln!("COMMAND SUCCESSFULLY executed"); - } - Ok(Command::Start) => { - rprintln!("START"); - started = true; - } - Ok(Command::Stop) => { - rprintln!("STOP"); - started = false; - // spincoater.stop(); - } - Ok(Command::SetRpm(x)) => { - rprintln!("SET_RPM with {}", x); - _rpm = x; - } - Ok(Command::SetTimer(x)) => { - rprintln!("SETTING TIMER {}", x); - _timer = x; - } - Ok(Command::SendConfig) => { - rprintln!("SEND CONFIG"); - let command = format!("rpm.val={}", DEFAULT_TARGET_RPM); - display.send_command(command.to_string().as_bytes()); - } + Ok(Command::CommandSuccess) => { + rprintln!("COMMAND SUCCESSFULLY executed"); + } + Ok(Command::Start) => { + rprintln!("START"); + started = true; + }, + Ok(Command::Stop) => { + rprintln!("STOP"); + started = false; + // spincoater.stop(); + }, + Ok(Command::SetRpm(x)) => { + rprintln!("SET_RPM with {}", x); + rpm = x; + }, + Ok(Command::SetTimer(x)) => { + rprintln!("SETTING TIMER {}", x); + timer = x; + }, + Ok(Command::SendConfig) => { + rprintln!("SEND CONFIG"); + let command = format!("rpm.val={}",DEFAULT_TARGET_RPM); + display.send_command(command.to_string().as_bytes()); + }, Err(ErrCommand::NoValidCmd) => { rprintln!(" NOT A VALID CMD!"); - } - Err(ErrCommand::ReadError) => { + }, + Err(ErrCommand::ReadError) =>{ rprintln!("READ FAILED!"); } } @@ -181,7 +182,30 @@ fn main() -> ! { // spincoater.armed(); rprintln!("STARTING!") } + //display.send_command(b"page page0"); + //uart0.write(b"page page0\xff\xff\xff"); } + // Example: Ramp from 0% to 50% throttle + //the afro esc starts turning at roughly setup gets a PWM at + //loop{ + // for pulse in 1120..1500 { + // rprintln!("pulse:{}",pulse); + // pwm_pin.set_timestamp(pulse); + // Timer::after_millis(3000).await; + // } + + // Timer::after_millis(1000).await; + + // // Return to idle + // pwm_pin.set_timestamp(1000); + // Timer::after_millis(1000).await; + // } + loop { + rprintln!("Hello world!"); + delay.delay_millis(3000); + } + + // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0/examples/src/bin } #[handler] @@ -189,7 +213,7 @@ fn main() -> ! { fn handler() { critical_section::with(|cs| { let mut binding = EMERGENCY_BUTTON.borrow_ref_mut(cs); - let button = binding.as_mut().unwrap(); + let mut button = binding.as_mut().unwrap(); if button.is_interrupt_set() { // do the thing rprintln!("BUTTON1 WAS PRESSED!"); diff --git a/spinnyboy_rust/src/bin/peripherals/mod.rs b/spinnyboy_rust/src/bin/peripherals/mod.rs index 5998a6e..fa7fc3a 100644 --- a/spinnyboy_rust/src/bin/peripherals/mod.rs +++ b/spinnyboy_rust/src/bin/peripherals/mod.rs @@ -1,16 +1,15 @@ pub mod nextion; #[derive(Debug)] -pub enum Command { +pub enum Command{ SetRpm(u32), SetTimer(u32), Start, Stop, SendConfig, - CommandSuccess, + CommandSuccess } #[derive(Debug)] -pub enum ErrCommand { +pub enum ErrCommand{ NoValidCmd, - #[allow(dead_code)] - ReadError, -} + ReadError +} \ No newline at end of file diff --git a/spinnyboy_rust/src/bin/peripherals/nextion.rs b/spinnyboy_rust/src/bin/peripherals/nextion.rs index b25ae65..4827b0e 100644 --- a/spinnyboy_rust/src/bin/peripherals/nextion.rs +++ b/spinnyboy_rust/src/bin/peripherals/nextion.rs @@ -1,9 +1,9 @@ -use esp_hal::Blocking; use esp_hal::uart::RxError; -use esp_hal::uart::Uart; +use esp_hal::uart::{Uart}; +use esp_hal::{Blocking }; use rtt_target::rprintln; -use crate::peripherals::{Command, ErrCommand}; +use crate::peripherals::{ErrCommand,Command}; enum UartStatemachine { WaitingP, @@ -93,32 +93,42 @@ impl<'a> Nextion<'a> { } } } - pub fn read_command(&mut self) -> Result { - let mut buf: [u8; 8] = [0; 8]; - let _read_bytes = match self.read_frame(&mut buf) { + pub fn read_command(&mut self) -> Result{ + let mut buf:[u8;8] = [0;8]; + let _read_bytes = match self.read_frame(&mut buf){ Ok(x) => x, - Err(_e) => { - rprintln!("ERROR while reading"); - return Err(ErrCommand::NoValidCmd); - } + Err(e) => {rprintln!("ERROR while reading"); + return Err(ErrCommand::NoValidCmd); + } }; - rprintln!("READ SUCCESS!:{:?}", buf); - match buf[0] { - 01 => Ok(Command::Start), - 02 => Ok(Command::Stop), + rprintln!("READ SUCCESS!:{:?}",buf); + match buf[0]{ + + 01 => {Ok(Command::Start)}, + 02 =>{Ok(Command::Stop)}, 03 => { let rpm = u32::from_le_bytes(buf[1..5].try_into().expect("failed to parse rpm!")); Ok(Command::SetRpm(rpm)) - } + }, 04 => { let time = u32::from_le_bytes(buf[1..5].try_into().expect("failed to parse time!")); - Ok(Command::SetTimer(time)) + Ok(Command::SetTimer(time)) } - 05 => Ok(Command::SendConfig), - 00 => Ok(Command::CommandSuccess), - _ => Err(ErrCommand::NoValidCmd), - } + 05 =>{ + Ok(Command::SendConfig) + } + 00 => { + Ok(Command::CommandSuccess) + }, + _ => { + Err(ErrCommand::NoValidCmd) + } + } + + + + } pub fn read_ready(&mut self) -> bool { self.interface.read_ready() diff --git a/spinnyboy_rust/src/lib.rs b/spinnyboy_rust/src/lib.rs index 0c9ac1a..2e7f0d4 100644 --- a/spinnyboy_rust/src/lib.rs +++ b/spinnyboy_rust/src/lib.rs @@ -1 +1 @@ -#![no_std] +#![no_std] \ No newline at end of file