#![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 = [DMA1_CHANNEL4])] mod app { use cortex_m::singleton; use stm32f1xx_hal::{gpio, pac, prelude::*, serial, timer}; use systick_monotonic::Systick; use crate::dmx::DMX; // 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; 512], } #[local] struct Local { dmx: DMX, delay_us: timer::DelayUs<pac::TIM2>, led: gpio::gpioc::PC13<gpio::Output>, } #[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 gpioc = cx.device.GPIOC.split(); let mut afio = cx.device.AFIO.constrain(); let dma1 = cx.device.DMA1.split(); // 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, ); foo::spawn().unwrap(); ( Shared { buffer: singleton!(: [u8; 512] = [0b01010101; 512]).unwrap(), }, Local { dmx: DMX::new(serial, dma1.4, &clocks), // Configure timer delay_us: cx.device.TIM2.delay_us(&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(&mut gpioc.crh), }, init::Monotonics(mono), ) } #[idle] fn idle(_: idle::Context) -> ! { loop { cortex_m::asm::nop(); } } #[task(local = [dmx, delay_us, led], shared = [&buffer])] fn foo(cx: foo::Context) { cx.local.dmx.send(cx.shared.buffer); cx.local.led.set_low(); cx.local.delay_us.delay(1.secs()); cx.local.led.set_high(); cx.local.delay_us.delay(1.secs()); cx.local.dmx.wait(); foo::spawn().unwrap(); } }