#![no_std] #![no_main] use cortex_m_rt::entry; use embedded_hal::digital::v2::{InputPin, OutputPin}; use stm32f1xx_hal::{delay::Delay, pac, prelude::*}; // Halt the MCU when panic #[allow(unused_imports)] use panic_halt; mod io; mod seq; pub use seq::{LayerSelect, SeqLayer, Sequencer}; #[entry] fn main() -> ! { // Grab handles for the underlying hardware objects let dp = pac::Peripherals::take().unwrap(); let cp = cortex_m::Peripherals::take().unwrap(); // Initialise GPIOC via the HAL let mut rcc = dp.RCC.constrain(); let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); // Create an LED output let mut led1 = gpioa.pa1.into_push_pull_output(&mut gpioa.crl); let mut led2 = gpioa.pa2.into_push_pull_output(&mut gpioa.crl); let mut led3 = gpioa.pa3.into_push_pull_output(&mut gpioa.crl); let mut led4 = gpioa.pa4.into_push_pull_output(&mut gpioa.crl); // Create a button input let btn1 = gpiob.pb0.into_pull_down_input(&mut gpiob.crl); let btn2 = gpiob.pb1.into_pull_down_input(&mut gpiob.crl); let btn3 = gpiob.pb5.into_pull_down_input(&mut gpiob.crl); let btn4 = gpiob.pb6.into_pull_down_input(&mut gpiob.crl); // Eurorack clock input/ gate output let clk = gpiob.pb7.into_pull_down_input(&mut gpiob.crl); let gate = gpiob.pb8.into_push_pull_output(&mut gpiob.crh); // Setup the I/O states let mut io = io::Io { led1, led2, led3, led4, btn1, btn2, btn3, btn4, btn1_last: false, btn2_last: false, btn3_last: false, btn4_last: false, clk, clk_last: false, gate, }; let mut seq = Sequencer::default(); // Initialize the delay object with the MCU frequency let mut flash = dp.FLASH.constrain(); let clocks = rcc .cfgr .use_hse(8.mhz()) .sysclk(48.mhz()) .pclk1(24.mhz()) .freeze(&mut flash.acr); let mut delay = Delay::new(cp.SYST, clocks); io.startup(&mut delay); loop { // Update sequencer state based on inputs io.update_sequence(&mut seq); // Write out gate CV io.update_cv(&mut seq); // Wait 5ms until we do it again delay.delay_ms(5_u16); } } // #![no_main] // #![no_std] // // // mod io; // // // mod seq; // // // pub use seq::{LayerSelect, SeqLayer, Sequencer}; // use panic_halt as _; // use core::mem::MaybeUninit; // use cortex_m_rt::entry; // use embedded_hal::digital::v2::OutputPin; // use pac::interrupt; // use stm32f1xx_hal::gpio::*; // use stm32f1xx_hal::{pac, prelude::*}; // // These two are owned by the ISR. main() may only access them during the initialization phase, // // where the interrupt is not yet enabled (i.e. no concurrent accesses can occur). // // After enabling the interrupt, main() may not have any references to these objects any more. // // For the sake of minimalism, we do not use RTIC here, which would be the better way. // static mut LED: MaybeUninit>> = // MaybeUninit::uninit(); // static mut INT_PIN: MaybeUninit>> = // MaybeUninit::uninit(); // #[interrupt] // fn EXTI9_5() { // let led = unsafe { &mut *LED.as_mut_ptr() }; // let int_pin = unsafe { &mut *INT_PIN.as_mut_ptr() }; // if int_pin.check_interrupt() { // led.toggle().ok(); // // if we don't clear this bit, the ISR would trigger indefinitely // int_pin.clear_interrupt_pending_bit(); // } // } // #[entry] // fn main() -> ! { // // initialization phase // let p = pac::Peripherals::take().unwrap(); // let _cp = cortex_m::peripheral::Peripherals::take().unwrap(); // { // // the scope ensures that the int_pin reference is dropped before the first ISR can be executed. // let mut rcc = p.RCC.constrain(); // let mut gpioa = p.GPIOA.split(&mut rcc.apb2); // let mut gpiob = p.GPIOB.split(&mut rcc.apb2); // let mut afio = p.AFIO.constrain(&mut rcc.apb2); // let led = unsafe { &mut *LED.as_mut_ptr() }; // *led = gpiob.pb9.into_push_pull_output(&mut gpiob.crh); // let int_pin = unsafe { &mut *INT_PIN.as_mut_ptr() }; // *int_pin = gpioa.pa7.into_pull_down_input(&mut gpioa.crl); // int_pin.make_interrupt_source(&mut afio); // int_pin.trigger_on_edge(&p.EXTI, Edge::RISING); // int_pin.enable_interrupt(&p.EXTI); // } // initialization ends here // unsafe { // pac::NVIC::unmask(pac::Interrupt::EXTI9_5); // } // loop {} // } //// The following code uses RTIC but doesn't work // use panic_halt as _; // use stm32f1xx_hal::{ // gpio::{ // gpiob::{PB7, PB9}, // Edge, ExtiPin, Input, Output, PullDown, PushPull, // }, // pac, // prelude::*, // }; // mod io; // mod seq; // pub use seq::{LayerSelect, SeqLayer, Sequencer}; // #[rtic::app(device = stm32f1xx_hal::stm32, peripherals = true)] // const APP: () = { // struct Resources { // clk: PB7>, // clk_led: PB9>, // } // #[init] // fn init(mut ctx: init::Context) -> init::LateResources { // let mut rcc = ctx.device.RCC.constrain(); // let mut afio = ctx.device.AFIO.constrain(&mut rcc.apb2); // let mut gpiob = ctx.device.GPIOB.split(&mut rcc.apb2); // let mut clk = gpiob.pb7.into_pull_down_input(&mut gpiob.crl); // let clk_led = gpiob.pb9.into_push_pull_output(&mut gpiob.crh); // clk.make_interrupt_source(&mut afio); // clk.enable_interrupt(&mut ctx.device.EXTI); // clk.trigger_on_edge(&mut ctx.device.EXTI, Edge::RISING); // init::LateResources { clk, clk_led } // } // #[task(binds = EXTI0, resources = [clk, clk_led])] // fn clock_in(ctx: clock_in::Context) { // ctx.resources.clk.clear_interrupt_pending_bit(); // ctx.resources.clk_led.toggle().ok(); // } // }; //// Some other code that initialises all our IO and sets up the sequencer // Create an LED output // let led1 = gpioa.pa1.into_push_pull_output(&mut gpioa.crl); // let led2 = gpioa.pa2.into_push_pull_output(&mut gpioa.crl); // let led3 = gpioa.pa3.into_push_pull_output(&mut gpioa.crl); // let led4 = gpioa.pa4.into_push_pull_output(&mut gpioa.crl); // let mut clk_led = gpiob.pb9.into_push_pull_output(&mut gpiob.crh); // Create a button input // let btn1 = gpiob.pb0.into_pull_down_input(&mut gpiob.crl); // let btn2 = gpiob.pb1.into_pull_down_input(&mut gpiob.crl); // let btn3 = gpiob.pb5.into_pull_down_input(&mut gpiob.crl); // let btn4 = gpiob.pb6.into_pull_down_input(&mut gpiob.crl); // Eurorack clock input/ gate output // let clk = gpiob.pb7.into_pull_down_input(&mut gpiob.crl); // let gate = gpiob.pb8.into_push_pull_output(&mut gpiob.crh); // let mut clk_last = false; // Setup the I/O states // let mut io = io::Io { // led1, // led2, // led3, // led4, // btn1, // btn2, // btn3, // btn4, // btn1_last: false, // btn2_last: false, // btn3_last: false, // btn4_last: false, // clk, // clk_last: false, // clk_led, // gate, // }; // let mut seq = Sequencer::default(); // loop { // let s = clk.is_high().ok().unwrap(); // if s && !clk_last { // clk_led.set_high().ok(); // clk_last = true; // } else { // clk_led.set_low().ok(); // clk_last = false; // } // delay.delay_ms(1_u16); // Update sequencer state based on inputs // io.update_sequence(&mut seq); // Write out gate CV // io.update_cv(&mut seq); // } // } // #[interrupt] // fn EXTI0() {}