#![deny(unsafe_code)] #![no_std] #![no_main] // mod i2c_reg_slave; // mod i2c_slave; mod dmx; // extern crate panic_halt; extern crate panic_semihosting; #[rtic::app(device = stm32f1xx_hal::pac, dispatchers = [SPI1, SPI2, SPI3])] mod app { use crate::dmx::DMX; use cortex_m::singleton; use stm32f1xx_hal::{gpio, pac, prelude::*, serial, timer}; use systick_monotonic::Systick; const DMX_LEN: usize = 512; // A monotonic timer to enable scheduling in RTIC #[monotonic(binds = SysTick, default = true)] type MyMono = Systick<100>; // 100 Hz / 10 ms granularity #[shared] struct Shared { buffer: &'static mut [u8], delay_us: timer::DelayUs<pac::TIM2>, } #[local] struct Local { dmx: DMX<DMX_LEN>, led: gpio::gpioc::PC13<gpio::Output<gpio::PushPull>>, int_led: gpio::gpiob::PB0<gpio::Output<gpio::OpenDrain>>, } #[init] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { // Take ownership over the raw flash and rcc devices and convert them into the corresponding // HAL structs let mut flash = cx.device.FLASH.constrain(); let rcc = cx.device.RCC.constrain(); // Freeze the configuration of all the clocks in the system and store the frozen frequencies in // `clocks` let clocks = rcc .cfgr // hf external quartz frequency .use_hse(8.MHz()) // system clock frequency .sysclk(72.MHz()) .freeze(&mut flash.acr); // Initialize the monotonic let mono = Systick::new(cx.core.SYST, clocks.sysclk().to_Hz()); // Acquire the peripherals let mut gpioa = cx.device.GPIOA.split(); let mut gpiob = cx.device.GPIOB.split(); let mut gpioc = cx.device.GPIOC.split(); let mut afio = cx.device.AFIO.constrain(); let dma1 = cx.device.DMA1.split(); cx.device.EXTI.imr.write(|w| w.mr1().set_bit()); let _ = gpiob.pb10.into_pull_up_input(&mut gpiob.crh); // Serial config let serial = serial::Serial::new( cx.device.USART1, ( gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh), gpioa.pa10, //.into_pull_up_input(&mut gpioa.crh), ), &mut afio.mapr, serial::Config::default(), &clocks, ); // rtic::pend(pac::Interrupt::DMA1_CHANNEL4); // ??? foo::spawn().unwrap(); ( Shared { buffer: singleton!(: [u8; DMX_LEN] = [0b01010101; DMX_LEN]).unwrap(), // Configure timer delay_us: cx.device.TIM2.delay_us(&clocks), }, Local { dmx: DMX::new(serial, dma1.4, &clocks), // Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function // in order to configure the port. For pins 0-7, crl should be passed instead. led: gpioc .pc13 .into_push_pull_output_with_state(&mut gpioc.crh, gpio::PinState::High), int_led: gpiob .pb0 .into_open_drain_output_with_state(&mut gpiob.crl, gpio::PinState::Low), }, init::Monotonics(mono), ) } #[idle] fn idle(_: idle::Context) -> ! { loop { rtic::export::wfi(); } } #[task(local = [dmx, led], shared = [&buffer, delay_us])] fn foo(mut cx: foo::Context) { cx.local.dmx.send(cx.shared.buffer); cx.local.led.toggle(); cx.shared.delay_us.lock(|d| d.delay(1.secs())); // cx.local.dmx.wait(); foo::spawn().unwrap(); } #[task(binds=EXTI0, local = [int_led], shared = [delay_us])] fn bar(mut cx: bar::Context) { cx.local.int_led.toggle(); cx.shared.delay_us.lock(|d| d.delay(1.secs())); } }