diff --git a/Cargo.toml b/Cargo.toml index 86df9fe..6f27af4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = ["testsuite"] [dependencies] cortex-m = "~0.7.1" cortex-m-rt = "~0.6.13" +cortex-m-rtic = "1.0.0" defmt = "~0.2.0" defmt-rtt = "~0.2.0" panic-probe = { version = "~0.2.0", features = ["print-defmt"] } diff --git a/src/application/setup.rs b/src/application/setup.rs index 87b0f70..4e84d43 100644 --- a/src/application/setup.rs +++ b/src/application/setup.rs @@ -14,6 +14,22 @@ use crate::application::App; use crate::time; pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> App { + // Take ownership over the raw flash and rcc devices and convert them into the corresponding + // HAL structs + let mut flash = dp.FLASH.constrain(); + let mut rcc = dp.RCC.constrain(); + + // Freeze the configuration of all the clocks in the system and store the frozen frequencies in + // `clocks` + let clocks = rcc + .cfgr + .use_hse(8.mhz()) + .sysclk(72.mhz()) + .pclk1(36.mhz()) + .freeze(&mut flash.acr); + + defmt::info!("Clock Setup done"); + // Take ownership over the raw flash and rcc devices and convert them into the corresponding // HAL structs let mut flash = dp.FLASH.constrain(); diff --git a/src/lib.rs b/src/lib.rs index d79e00d..4d9e893 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,10 @@ +#![no_main] #![no_std] use defmt_rtt as _; // global logger use panic_probe as _; use stm32f1xx_hal as _; -pub mod application; -pub mod loc; -mod si5153; -pub mod time; -pub mod wspr; - // same panicking *behavior* as `panic-probe` but doesn't print a panic message // this prevents the panic message being printed *twice* when `defmt::panic` is invoked #[defmt::panic_handler] @@ -17,14 +12,197 @@ fn panic() -> ! { cortex_m::asm::udf() } -defmt::timestamp!("{=u32}", { - // NOTE(no-CAS) `timestamps` runs with interrupts disabled - time::get_timestamp() -}); +use rtic::app; -/// Terminates the application and makes `probe-run` exit with exit-code = 0 -pub fn exit() -> ! { - loop { - cortex_m::asm::bkpt(); +mod si5153; + +#[app(device = stm32f1xx_hal::pac)] +mod app { + use stm32f1xx_hal::{ + delay::Delay, + gpio::{gpiob, gpioc, Alternate, Floating, Input, OpenDrain, Output, PushPull}, + i2c, + i2c::BlockingI2c, + pac::I2C1, + pac::{self, Interrupt}, + prelude::*, + prelude::*, + serial::{Config, Serial}, + stm32, + timer::{Event, Timer}, + }; + + use nmea0183::{datetime::Time, ParseResult, Parser}; + + use crate::si5153::Si5153; + + type AppI2C1 = BlockingI2c< + I2C1, + ( + gpiob::PB6>, + gpiob::PB7>, + ), + >; + + #[shared] + struct Shared { + i2c: AppI2C1, + time: Time, + } + + #[local] + struct Local { + gps_parser: Parser, + usart: Serial< + stm32::USART3, + ( + gpiob::PB10>, + gpiob::PB11>, + ), + >, + board_led: gpioc::PC13>, + pll: Si5153, + } + + #[init] + fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { + // Get access to the core peripherals from the cortex-m crate + let cp = cortex_m::Peripherals::take().unwrap(); + // Get access to the device specific peripherals from the peripheral access crate + let dp = pac::Peripherals::take().unwrap(); + + // Take ownership over the raw flash and rcc devices and convert them into the corresponding + // HAL structs + let mut flash = dp.FLASH.constrain(); + + let mut rcc = dp.RCC.constrain(); + + // Freeze the configuration of all the clocks in the system and store the frozen frequencies in + // `clocks` + let clocks = rcc + .cfgr + .use_hse(8.mhz()) + .sysclk(72.mhz()) + .pclk1(36.mhz()) + .freeze(&mut flash.acr); + + defmt::info!("Clock Setup done"); + + let mut timer = Timer::tim2(dp.TIM2, &clocks, &mut rcc.apb1).start_count_down(1.khz()); + // Generate an interrupt when the timer expires + timer.listen(Event::Update); + + // Acquire the GPIOC peripheral + let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + + let mut afio = dp.AFIO.constrain(&mut rcc.apb2); + + let board_led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); + + // USART3 + // Configure pb10 as a push_pull output, this will be the tx pin + let tx = gpiob.pb10.into_alternate_push_pull(&mut gpiob.crh); + // Take ownership over pb11 + let rx = gpiob.pb11; + + // Set up the usart device. Taks ownership over the USART register and tx/rx pins. The rest of + // the registers are used to enable and configure the device. + let usart = Serial::usart3( + dp.USART3, + (tx, rx), + &mut afio.mapr, + Config::default().baudrate(9600.bps()), + clocks, + &mut rcc.apb1, + ); + + let gps_parser = Parser::new(); + + let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl); + let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl); + let i2c = i2c::BlockingI2c::i2c1( + dp.I2C1, + (scl, sda), + &mut afio.mapr, + i2c::Mode::Standard { + frequency: 400_000.hz(), + }, + clocks, + &mut rcc.apb1, + 5, + 1, + 5, + 5, + ); + + let pll = Si5153::new(&i2c); + + let time = Time { + hours: 0, + minutes: 0, + seconds: 0.0, + }; + + ( + Shared { i2c, time }, + Local { + gps_parser, + usart, + board_led, + pll, + }, + init::Monotonics(), + ) + } + + #[task(binds = USART3, local=[usart, board_led, gps_parser], shared=[time])] + fn usart3(mut ctx: usart3::Context) { + match ctx.local.usart.read() { + Ok(byte) => { + ctx.local.board_led.toggle().unwrap(); + if let Some(result) = ctx.local.gps_parser.parse_from_byte(byte) { + match result { + Ok(ParseResult::GGA(Some(gga))) => { + ctx.shared.time.lock(|time| { + time.hours = gga.time.hours; + time.minutes = gga.time.minutes; + time.seconds = gga.time.seconds; + }); + /* + self.locator = loc::locator_from_coordinates( + gga.latitude.as_f64(), + gga.longitude.as_f64(), + ); + defmt::info!("Got GGA. New locator: {}", self.locator.as_str()); + */ + } + Ok(_) => {} // Some other sentences.. + Err(_) => {} // Got parse error + } + } + } + Err(nb::Error::WouldBlock) => {} + Err(nb::Error::Other(_)) => {} + } + } + + #[task(binds = TIM2, shared=[time])] + fn tim2(mut ctx: tim2::Context) { + ctx.shared.time.lock(|time| { + time.seconds += 0.001; + + if time.seconds >= 60.0 { + time.seconds -= 60.0; + time.minutes += 1; + } + if time.minutes == 60 { + time.minutes = 0; + time.hours += 1; + } + if time.hours == 24 { + time.hours = 0; + } + }); } } diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index a540bbf..0000000 --- a/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![no_std] -#![no_main] - -use stm32f1xx_hal::pac; - -use wspr_beacon::application; - -#[cortex_m_rt::entry] -fn main() -> ! { - // Get access to the core peripherals from the cortex-m crate - let cp = cortex_m::Peripherals::take().unwrap(); - // Get access to the device specific peripherals from the peripheral access crate - let dp = pac::Peripherals::take().unwrap(); - - let app = application::setup(cp, dp); - app.run() -}