|
3 | 3 |
|
4 | 4 | use neotron_bmc as _; |
5 | 5 |
|
6 | | -use hal::{i2c, pac, prelude::*, serial, spi}; |
7 | | -use stm32f0xx_hal as hal; |
| 6 | +use neotron_bmc::monotonic::{Tim6Monotonic, U16Ext}; |
8 | 7 |
|
9 | | -static VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/version.txt")); |
10 | | - |
11 | | -/// Holds all the I/O pins in our system |
12 | | -#[allow(unused)] |
13 | | -struct Pins { |
14 | | - // spi_clk: hal::gpio::gpioa::PA5<hal::gpio::Alternate<hal::gpio::AF0>>, |
15 | | - // spi_cipo: hal::gpio::gpioa::PA6<hal::gpio::Alternate<hal::gpio::AF0>>, |
16 | | - // spi_copi: hal::gpio::gpioa::PA7<hal::gpio::Alternate<hal::gpio::AF0>>, |
17 | | - // i2c_scl: hal::gpio::gpiob::PB6<hal::gpio::Alternate<hal::gpio::AF4>>, |
18 | | - // i2c_sda: hal::gpio::gpiob::PB7<hal::gpio::Alternate<hal::gpio::AF4>>, |
19 | | - uart_tx: hal::gpio::gpioa::PA9<hal::gpio::Alternate<hal::gpio::AF1>>, |
20 | | - uart_rx: hal::gpio::gpioa::PA10<hal::gpio::Alternate<hal::gpio::AF1>>, |
21 | | - uart_cts: hal::gpio::gpioa::PA11<hal::gpio::Alternate<hal::gpio::AF1>>, |
22 | | - uart_rts: hal::gpio::gpioa::PA12<hal::gpio::Alternate<hal::gpio::AF1>>, |
23 | | - led_power: hal::gpio::gpiob::PB0<hal::gpio::Output<hal::gpio::PushPull>>, |
24 | | - led_status: hal::gpio::gpiob::PB1<hal::gpio::Output<hal::gpio::PushPull>>, |
25 | | -} |
26 | | - |
27 | | -#[cortex_m_rt::entry] |
28 | | -fn main() -> ! { |
29 | | - defmt::info!("Neotron BMC version {:?} booting", VERSION); |
30 | | - |
31 | | - let p = pac::Peripherals::take().unwrap(); |
32 | | - |
33 | | - // Configure the clocks. |
34 | | - // We have no external crystal, and instead run from the High Speed Internal Oscillator. |
35 | | - let mut flash = p.FLASH; |
36 | | - let mut rcc = p |
37 | | - .RCC |
38 | | - .configure() |
39 | | - .hclk(48.mhz()) |
40 | | - .pclk(48.mhz()) |
41 | | - .sysclk(48.mhz()) |
42 | | - .freeze(&mut flash); |
43 | | - |
44 | | - defmt::info!("Clocks are clocked"); |
45 | | - |
46 | | - let gpioa = p.GPIOA.split(&mut rcc); |
47 | | - let gpiob = p.GPIOB.split(&mut rcc); |
48 | | - |
49 | | - let mut pins: Pins = cortex_m::interrupt::free(move |cs| { |
50 | | - Pins { |
51 | | - // SPI pins |
52 | | - // spi_clk: gpioa.pa5.into_alternate_af0(cs), |
53 | | - // spi_cipo: gpioa.pa6.into_alternate_af0(cs), |
54 | | - // spi_copi: gpioa.pa7.into_alternate_af0(cs), |
55 | | - // I²C pins |
56 | | - // i2c_scl: gpiob.pb6.into_alternate_af4(cs), |
57 | | - // i2c_sda: gpiob.pb7.into_alternate_af4(cs), |
58 | | - // USART pins |
59 | | - uart_tx: gpioa.pa9.into_alternate_af1(cs), |
60 | | - uart_rx: gpioa.pa10.into_alternate_af1(cs), |
61 | | - uart_cts: gpioa.pa11.into_alternate_af1(cs), |
62 | | - uart_rts: gpioa.pa12.into_alternate_af1(cs), |
63 | | - // LED pins |
64 | | - led_power: gpiob.pb0.into_push_pull_output(cs), |
65 | | - led_status: gpiob.pb1.into_push_pull_output(cs), |
66 | | - } |
67 | | - }); |
68 | | - |
69 | | - // // Configure UART. Pick some default baud rate - we can change it later |
70 | | - let mut serial = serial::Serial::usart1( |
71 | | - p.USART1, |
72 | | - (pins.uart_tx, pins.uart_rx), |
73 | | - 115_200.bps(), |
74 | | - &mut rcc, |
75 | | - ); |
76 | | - |
77 | | - use core::fmt::Write; |
78 | | - |
79 | | - loop { |
80 | | - serial.write_str("Hello, world!\r\n").unwrap(); |
81 | | - |
82 | | - defmt::info!("Off Off"); |
83 | | - |
84 | | - pins.led_power.set_low().unwrap(); |
85 | | - pins.led_status.set_low().unwrap(); |
| 8 | +use cortex_m_rt::exception; |
86 | 9 |
|
87 | | - cortex_m::asm::delay(6_000_000); |
| 10 | +use rtic::app; |
88 | 11 |
|
89 | | - defmt::info!("Off On"); |
| 12 | +use stm32f0xx_hal::{ |
| 13 | + gpio::gpioa::{PA10, PA11, PA12, PA9}, |
| 14 | + gpio::gpiob::{PB0, PB1}, |
| 15 | + gpio::{Alternate, Output, PushPull, AF1}, |
| 16 | + pac, |
| 17 | + prelude::*, |
| 18 | + serial, |
| 19 | +}; |
90 | 20 |
|
91 | | - pins.led_power.set_low().unwrap(); |
92 | | - pins.led_status.set_high().unwrap(); |
| 21 | +use cortex_m::interrupt::free as disable_interrupts; |
93 | 22 |
|
94 | | - cortex_m::asm::delay(6_000_000); |
| 23 | +static VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/version.txt")); |
95 | 24 |
|
96 | | - defmt::info!("On Off"); |
| 25 | +const PERIOD_MS: u16 = 1000; |
97 | 26 |
|
98 | | - pins.led_power.set_high().unwrap(); |
99 | | - pins.led_status.set_low().unwrap(); |
| 27 | +#[app(device = crate::pac, peripherals = true, monotonic = crate::Tim6Monotonic)] |
| 28 | +const APP: () = { |
| 29 | + struct Resources { |
| 30 | + uart_cts: PA11<Alternate<AF1>>, |
| 31 | + uart_rts: PA12<Alternate<AF1>>, |
| 32 | + led_power: PB0<Output<PushPull>>, |
| 33 | + led_status: PB1<Output<PushPull>>, |
| 34 | + serial: serial::Serial<pac::USART1, PA9<Alternate<AF1>>, PA10<Alternate<AF1>>>, |
| 35 | + } |
100 | 36 |
|
101 | | - cortex_m::asm::delay(6_000_000); |
| 37 | + #[init(spawn = [blinker])] |
| 38 | + fn init(ctx: init::Context) -> init::LateResources { |
| 39 | + defmt::info!("Neotron BMC version {:?} booting", VERSION); |
| 40 | + |
| 41 | + let dp: pac::Peripherals = ctx.device; |
| 42 | + |
| 43 | + let mut flash = dp.FLASH; |
| 44 | + let mut rcc = dp |
| 45 | + .RCC |
| 46 | + .configure() |
| 47 | + .hclk(48.mhz()) |
| 48 | + .pclk(48.mhz()) |
| 49 | + .sysclk(48.mhz()) |
| 50 | + .freeze(&mut flash); |
| 51 | + |
| 52 | + defmt::info!("Configuring TIM6 at 7.8125 kHz..."); |
| 53 | + crate::Tim6Monotonic::initialize(dp.TIM6); |
| 54 | + |
| 55 | + defmt::info!("Creating pins..."); |
| 56 | + let gpioa = dp.GPIOA.split(&mut rcc); |
| 57 | + let gpiob = dp.GPIOB.split(&mut rcc); |
| 58 | + let (uart_tx, uart_rx, uart_cts, uart_rts, mut led_power, led_status) = |
| 59 | + disable_interrupts(|cs| { |
| 60 | + ( |
| 61 | + gpioa.pa9.into_alternate_af1(cs), |
| 62 | + gpioa.pa10.into_alternate_af1(cs), |
| 63 | + gpioa.pa11.into_alternate_af1(cs), |
| 64 | + gpioa.pa12.into_alternate_af1(cs), |
| 65 | + gpiob.pb0.into_push_pull_output(cs), |
| 66 | + gpiob.pb1.into_push_pull_output(cs), |
| 67 | + ) |
| 68 | + }); |
| 69 | + |
| 70 | + defmt::info!("Creating UART..."); |
| 71 | + |
| 72 | + let serial = serial::Serial::usart1(dp.USART1, (uart_tx, uart_rx), 115_200.bps(), &mut rcc); |
| 73 | + |
| 74 | + ctx.spawn.blinker().unwrap(); |
| 75 | + |
| 76 | + led_power.set_high().unwrap(); |
| 77 | + |
| 78 | + defmt::info!("Init complete!"); |
| 79 | + |
| 80 | + init::LateResources { |
| 81 | + serial, |
| 82 | + uart_cts, |
| 83 | + uart_rts, |
| 84 | + led_power, |
| 85 | + led_status, |
| 86 | + } |
| 87 | + } |
102 | 88 |
|
103 | | - defmt::info!("On On"); |
| 89 | + #[idle(resources = [])] |
| 90 | + fn idle(_: idle::Context) -> ! { |
| 91 | + defmt::info!("Idle is running..."); |
| 92 | + loop { |
| 93 | + cortex_m::asm::nop(); |
| 94 | + // defmt::info!("Idle is asleep..."); |
| 95 | + // cortex_m::asm::wfi(); |
| 96 | + // defmt::info!("Idle is awake..."); |
| 97 | + } |
| 98 | + } |
104 | 99 |
|
105 | | - pins.led_power.set_high().unwrap(); |
106 | | - pins.led_status.set_high().unwrap(); |
| 100 | + // #[task(binds = USART1, resources=[serial])] |
| 101 | + // fn usart1_interrupt(ctx: usart1_interrupt::Context) { |
| 102 | + // defmt::info!("USART1 IRQ!"); |
| 103 | + // // Reading the register clears the RX-Not-Empty-Interrupt flag. |
| 104 | + // match ctx.resources.serial.read() |
| 105 | + // { |
| 106 | + // Ok(b) => { |
| 107 | + // defmt::info!("Read byte {:x}", b); |
| 108 | + // } |
| 109 | + // Err(_) => { |
| 110 | + // defmt::warn!("No byte available?"); |
| 111 | + // } |
| 112 | + // } |
| 113 | + // } |
| 114 | + |
| 115 | + #[task(resources = [led_status], schedule = [blinker])] |
| 116 | + fn blinker(ctx: blinker::Context) { |
| 117 | + // Use the safe local `static mut` of RTIC |
| 118 | + static mut LED_STATE: bool = false; |
| 119 | + |
| 120 | + if *LED_STATE { |
| 121 | + ctx.resources.led_status.set_low().unwrap(); |
| 122 | + *LED_STATE = false; |
| 123 | + } else { |
| 124 | + ctx.resources.led_status.set_high().unwrap(); |
| 125 | + *LED_STATE = true; |
| 126 | + } |
| 127 | + //ctx.schedule.blinker(ctx.scheduled + PERIOD_MS.millis()).unwrap(); |
| 128 | + } |
107 | 129 |
|
108 | | - cortex_m::asm::delay(6_000_000); |
| 130 | + // Let it use the USB interrupt as a generic software interrupt. |
| 131 | + extern "C" { |
| 132 | + fn USB(); |
109 | 133 | } |
| 134 | +}; |
| 135 | + |
| 136 | +#[exception] |
| 137 | +unsafe fn DefaultHandler(value: i16) { |
| 138 | + defmt::panic!("DefaultHandler({})", value); |
110 | 139 | } |
| 140 | + |
| 141 | +// SPI pins |
| 142 | +// spi_clk: gpioa.pa5.into_alternate_af0(cs), |
| 143 | +// spi_cipo: gpioa.pa6.into_alternate_af0(cs), |
| 144 | +// spi_copi: gpioa.pa7.into_alternate_af0(cs), |
| 145 | +// I²C pins |
| 146 | +// i2c_scl: gpiob.pb6.into_alternate_af4(cs), |
| 147 | +// i2c_sda: gpiob.pb7.into_alternate_af4(cs), |
0 commit comments