diff options
Diffstat (limited to 'sw/demo1/src/main.rs')
-rw-r--r-- | sw/demo1/src/main.rs | 169 |
1 files changed, 42 insertions, 127 deletions
diff --git a/sw/demo1/src/main.rs b/sw/demo1/src/main.rs index 3f98295..4e6e5c6 100644 --- a/sw/demo1/src/main.rs +++ b/sw/demo1/src/main.rs @@ -25,12 +25,8 @@ #![no_main] #![no_std] -const REF_CLOCK : u32 = 25_000_000; - -use core::convert::TryInto; - use cortex_m_rt::ExceptionFrame; -use cortex_m_semihosting::hio; +use cortex_m_semihosting::hprintln; use panic_semihosting as _; use stm32f1xx_hal::{ @@ -43,75 +39,10 @@ use stm32f1xx_hal::{ use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780}; -use si5351::{Si5351, Si5351Device}; - -use core::fmt::Write; - -fn gcd(x: u32, y: u32) -> u32 { - let mut x = x; - let mut y = y; - while y != 0 { - let t = y; - y = x % y; - x = t; - } - x -} - -fn clock_settings_for_pll(freq: u32, pll: u32) -> (u16, u32, u32) { - let a = pll / freq; - let b = pll - (a * freq); - let gcd = gcd(b, freq); - - let b = b / gcd; - let c = freq / gcd; - (a.try_into().unwrap(), b, c) -} - -fn clock_settings_with_pll_calculation(freq: u32) -> (u16, u8, u32, u32) { - let mut divider : u32 = 900_000_000 / freq; // Calculate the division ratio. 900,000,000 is the maximum internal - - if (divider % 2) == 1 { - divider -= 1 // Ensure an even integer division ratio - } - - let pll_freq = divider * freq; - // mult is an integer that must be in the range 15..90 - let mult = pll_freq / REF_CLOCK; - let l = pll_freq % REF_CLOCK; - - let denom = 1048575; - let num = f64::from(l) * f64::from(denom) / f64::from(REF_CLOCK); - - (divider.try_into().unwrap(), mult.try_into().unwrap(), num as u32, denom) -} - -fn print(step: usize) -> Result<(), core::fmt::Error> { - let mut stdout = match hio::hstdout() { - Ok(fd) => fd, - Err(()) => return Err(core::fmt::Error), - }; - - let language = "Rust"; - let ranking = 1; - - write!(stdout, "{}: {} on embedded is #{}!\n", step, language, ranking)?; - - Ok(()) -} - -fn set_vfo(freq: u32, siclock: &mut dyn Si5351) -{ - let (div, mult, num, denom) = clock_settings_with_pll_calculation(freq); - siclock.setup_pll(si5351::PLL::B, mult, num, denom).unwrap(); - siclock.setup_multisynth_int(si5351::Multisynth::MS0, div, si5351::OutputDivider::Div1).unwrap(); - - siclock.select_clock_pll(si5351::ClockOutput::Clk0, si5351::PLL::B); - siclock.set_clock_enabled(si5351::ClockOutput::Clk0, true); - siclock.flush_clock_control(si5351::ClockOutput::Clk0).unwrap(); -} +use demo1::{si_clock, ui}; +use core::fmt::Write; #[cortex_m_rt::entry] fn main() -> ! { @@ -121,11 +52,23 @@ fn main() -> ! { let mut flash = dp.FLASH.constrain(); let mut rcc = dp.RCC.constrain(); let mut afio = dp.AFIO.constrain(&mut rcc.apb2); - let clocks = rcc.cfgr.freeze(&mut flash.acr); + let clocks = rcc.cfgr + .adcclk(2.mhz()) + .freeze(&mut flash.acr); let mut delay = Delay::new(cp.SYST, clocks); - let gpioa = dp.GPIOA.split(&mut rcc.apb2); + let adc1 = dp.ADC1; + // Buttons as analog inputs (multi-level) let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); + let pb0 = gpiob.pb0.into_analog(&mut gpiob.crl); + let pb1 = gpiob.pb1.into_analog(&mut gpiob.crl); + let pb12 = gpiob.pb12.into_pull_up_input(&mut gpiob.crh); + let pb13 = gpiob.pb13.into_pull_up_input(&mut gpiob.crh); + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + let pc15 = gpioc.pc15.into_pull_up_input(&mut gpioc.crh); + let mut ui = ui::UI::new(pb0, pb1, adc1, &mut rcc.apb2, &clocks, pb12, pb13, pc15); + + let gpioa = dp.GPIOA.split(&mut rcc.apb2); // Configure PB14 as output. (LED) let mut led = gpiob.pb14.into_push_pull_output(&mut gpiob.crh); @@ -197,65 +140,47 @@ fn main() -> ! { lcd.set_cursor_pos(0, &mut delay).unwrap(); lcd.write_str("Hello, world!", &mut delay).unwrap(); - let mut siclock = Si5351Device::new(i2c_busmanager.acquire(), false, REF_CLOCK); - siclock.init(si5351::CrystalLoad::_10).unwrap(); - - // See freqplan.py for Si5351 frequency plan - // CLK1 = 116MHz - let pll_a_mult = 32; - siclock.setup_pll_int(si5351::PLL::A, 32).unwrap(); - - { - let clk1 = 116_000_000; - let (a, b, c) = clock_settings_for_pll(clk1, pll_a_mult * REF_CLOCK); - siclock.setup_multisynth(si5351::Multisynth::MS1, a, b, c, si5351::OutputDivider::Div1).unwrap(); - siclock.select_clock_pll(si5351::ClockOutput::Clk1, si5351::PLL::A); - siclock.set_clock_enabled(si5351::ClockOutput::Clk1, true); - siclock.flush_clock_control(si5351::ClockOutput::Clk1).unwrap(); - } - - { - let clk2 = 4_195_210; - let (a, b, c) = clock_settings_for_pll(clk2, pll_a_mult * REF_CLOCK); - siclock.setup_multisynth(si5351::Multisynth::MS2, a, b, c, si5351::OutputDivider::Div1).unwrap(); - siclock.select_clock_pll(si5351::ClockOutput::Clk2, si5351::PLL::A); - siclock.set_clock_enabled(si5351::ClockOutput::Clk2, true); - siclock.flush_clock_control(si5351::ClockOutput::Clk2).unwrap(); - } - - siclock.reset_pll(si5351::PLL::A).unwrap(); - - set_vfo(23_000_000, &mut siclock); - - siclock.reset_pll(si5351::PLL::B).unwrap(); - - siclock.flush_output_enabled().unwrap(); - + let mut siclock = si_clock::SiClock::new(i2c_busmanager.acquire()); lcd.set_cursor_pos(0, &mut delay).unwrap(); lcd.write_str("Clocks set. ", &mut delay).unwrap(); - let mut step = 0; - print(step).unwrap(); + hprintln!("Main loop\n").unwrap(); let mut last_encoder_count = qei.count(); loop { led.toggle().unwrap(); - lcd.set_cursor_pos(40, &mut delay).unwrap(); let mut string = arrayvec::ArrayString::<[_; 16]>::new(); let encoder_count = qei.count(); if encoder_count != last_encoder_count { let freq = 23_000_000 + encoder_count as u32; - set_vfo(freq, &mut siclock); + siclock.set_vfo(freq); - write!(string, "{} ", freq).unwrap(); + write!(string, "{:15}", freq).unwrap(); + lcd.set_cursor_pos(40, &mut delay).unwrap(); + lcd.write_str(&string, &mut delay).unwrap(); + } + + if let Some(b) = ui.read_buttons() { + let button = match b { + ui::ButtonPress::A => "A", + ui::ButtonPress::B => "B", + ui::ButtonPress::C => "C", + ui::ButtonPress::D => "D", + ui::ButtonPress::E => "E", + ui::ButtonPress::F => "F", + ui::ButtonPress::G => "G", + ui::ButtonPress::ENC => "X", + }; + + lcd.set_cursor_pos(0, &mut delay).unwrap(); + write!(string, "{:15}", button).unwrap(); lcd.write_str(&string, &mut delay).unwrap(); } - last_encoder_count = encoder_count; - step += 1; + last_encoder_count = encoder_count; } } @@ -265,24 +190,14 @@ fn HardFault(ef: &ExceptionFrame) -> ! { let hfsr = periph.SCB.hfsr.read(); let cfsr = periph.SCB.cfsr.read(); - let mut stdout = match hio::hstdout() { - Ok(fd) => fd, - Err(()) => panic!("no stdout"), - }; - - let _ = write!(stdout, "Hardfault {:x} {:x} at {:x}\n", hfsr, cfsr, ef.pc); + hprintln!("Hardfault {:x} {:x} at {:x}\n", hfsr, cfsr, ef.pc).unwrap(); cortex_m::asm::bkpt(); loop { } } #[cortex_m_rt::exception] fn DefaultHandler(irqn: i16) { - let mut stdout = match hio::hstdout() { - Ok(fd) => fd, - Err(()) => panic!("no stdout"), - }; - - let _ = write!(stdout, "Unhandled exception (IRQn = {})", irqn); + hprintln!("Unhandled exception (IRQn = {})", irqn).unwrap(); cortex_m::asm::bkpt(); loop { } } |