diff --git a/boards/stm32f3discovery/src/io.rs b/boards/stm32f3discovery/src/io.rs index f4a303cec0..62cb913d5f 100644 --- a/boards/stm32f3discovery/src/io.rs +++ b/boards/stm32f3discovery/src/io.rs @@ -38,7 +38,8 @@ impl Write for Writer { impl IoWrite for Writer { fn write(&mut self, buf: &[u8]) { - let uart = unsafe { &mut stm32f303xc::usart::USART1 }; + let rcc = stm32f303xc::rcc::Rcc::new(); + let uart = stm32f303xc::usart::Usart::new_usart1(&rcc); if !self.initialized { self.initialized = true; @@ -63,7 +64,14 @@ impl IoWrite for Writer { #[panic_handler] pub unsafe extern "C" fn panic_fmt(info: &PanicInfo) -> ! { // User LD3 is connected to PE09 - let led = &mut led::LedHigh::new(PinId::PE09.get_pin_mut().as_mut().unwrap()); + // Have to reinitialize several peripherals because otherwise can't access them here. + let rcc = stm32f303xc::rcc::Rcc::new(); + let syscfg = stm32f303xc::syscfg::Syscfg::new(&rcc); + let exti = stm32f303xc::exti::Exti::new(&syscfg); + let mut pin = stm32f303xc::gpio::Pin::new(PinId::PE09, &exti); + let gpio_ports = stm32f303xc::gpio::GpioPorts::new(&rcc, &exti); + pin.set_ports_ref(&gpio_ports); + let led = &mut led::LedHigh::new(&mut pin); let writer = &mut WRITER; debug::panic( diff --git a/boards/stm32f3discovery/src/main.rs b/boards/stm32f3discovery/src/main.rs index 26e36925aa..6a2d82960c 100644 --- a/boards/stm32f3discovery/src/main.rs +++ b/boards/stm32f3discovery/src/main.rs @@ -20,6 +20,7 @@ use kernel::hil::gpio::Output; use kernel::hil::time::Counter; use kernel::Platform; use kernel::{create_capability, debug, static_init}; +use stm32f303xc::chip::Stm32f3xxDefaultPeripherals; /// Support routines for debugging I/O. pub mod io; @@ -38,7 +39,7 @@ static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROC [None, None, None, None]; // Static reference to chip for panic dumps. -static mut CHIP: Option<&'static stm32f303xc::chip::Stm32f3xx> = None; +static mut CHIP: Option<&'static stm32f303xc::chip::Stm32f3xx> = None; // How should the kernel respond when a process faults. const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic; @@ -93,27 +94,32 @@ impl Platform for STM32F3Discovery { } /// Helper function called during bring-up that configures multiplexed I/O. -unsafe fn set_pin_primary_functions() { - use stm32f303xc::exti::{LineId, EXTI}; - use stm32f303xc::gpio::{AlternateFunction, Mode, PinId, PortId, PORT}; - use stm32f303xc::syscfg::SYSCFG; - - SYSCFG.enable_clock(); - - PORT[PortId::A as usize].enable_clock(); - PORT[PortId::B as usize].enable_clock(); - PORT[PortId::C as usize].enable_clock(); - PORT[PortId::D as usize].enable_clock(); - PORT[PortId::E as usize].enable_clock(); - PORT[PortId::F as usize].enable_clock(); - - PinId::PE14.get_pin().as_ref().map(|pin| { +unsafe fn set_pin_primary_functions( + syscfg: &stm32f303xc::syscfg::Syscfg, + exti: &stm32f303xc::exti::Exti, + spi1: &stm32f303xc::spi::Spi, + i2c1: &stm32f303xc::i2c::I2C, + gpio_ports: &'static stm32f303xc::gpio::GpioPorts<'static>, +) { + use stm32f303xc::exti::LineId; + use stm32f303xc::gpio::{AlternateFunction, Mode, PinId, PortId}; + + syscfg.enable_clock(); + + gpio_ports.get_port_from_port_id(PortId::A).enable_clock(); + gpio_ports.get_port_from_port_id(PortId::B).enable_clock(); + gpio_ports.get_port_from_port_id(PortId::C).enable_clock(); + gpio_ports.get_port_from_port_id(PortId::D).enable_clock(); + gpio_ports.get_port_from_port_id(PortId::E).enable_clock(); + gpio_ports.get_port_from_port_id(PortId::F).enable_clock(); + + gpio_ports.get_pin(PinId::PE14).map(|pin| { pin.make_output(); pin.set(); }); // User LD3 is connected to PE09. Configure PE09 as `debug_gpio!(0, ...)` - PinId::PE09.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE09).map(|pin| { pin.make_output(); // Configure kernel debug gpios as early as possible @@ -121,43 +127,43 @@ unsafe fn set_pin_primary_functions() { }); // pc4 and pc5 (USART1) is connected to ST-LINK virtual COM port - PinId::PC04.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PC04).map(|pin| { pin.set_mode(Mode::AlternateFunctionMode); // AF7 is USART1_TX pin.set_alternate_function(AlternateFunction::AF7); }); - PinId::PC05.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PC05).map(|pin| { pin.set_mode(Mode::AlternateFunctionMode); // AF7 is USART1_RX pin.set_alternate_function(AlternateFunction::AF7); }); // button is connected on pa00 - PinId::PA00.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA00).map(|pin| { // By default, upon reset, the pin is in input mode, with no internal // pull-up, no internal pull-down (i.e., floating). // // Only set the mapping between EXTI line and the Pin and let capsule do // the rest. - EXTI.associate_line_gpiopin(LineId::Exti0, pin); + exti.associate_line_gpiopin(LineId::Exti0, &pin); }); cortexm4::nvic::Nvic::new(stm32f303xc::nvic::EXTI0).enable(); // SPI1 has the l3gd20 sensor connected - PinId::PA06.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA06).map(|pin| { pin.set_mode(Mode::AlternateFunctionMode); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); // AF5 is SPI1/SPI2 pin.set_alternate_function(AlternateFunction::AF5); }); - PinId::PA07.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA07).map(|pin| { pin.make_output(); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); pin.set_mode(Mode::AlternateFunctionMode); // AF5 is SPI1/SPI2 pin.set_alternate_function(AlternateFunction::AF5); }); - PinId::PA05.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA05).map(|pin| { pin.make_output(); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); pin.set_mode(Mode::AlternateFunctionMode); @@ -165,22 +171,22 @@ unsafe fn set_pin_primary_functions() { pin.set_alternate_function(AlternateFunction::AF5); }); // PE03 is the chip select pin from the l3gd20 sensor - PinId::PE03.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE03).map(|pin| { pin.make_output(); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); pin.set(); }); - stm32f303xc::spi::SPI1.enable_clock(); + spi1.enable_clock(); // I2C1 has the LSM303DLHC sensor connected - PinId::PB06.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB06).map(|pin| { pin.set_mode(Mode::AlternateFunctionMode); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); // AF4 is I2C pin.set_alternate_function(AlternateFunction::AF4); }); - PinId::PB07.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB07).map(|pin| { pin.make_output(); pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); pin.set_mode(Mode::AlternateFunctionMode); @@ -189,95 +195,93 @@ unsafe fn set_pin_primary_functions() { }); // ADC1 - PinId::PA00.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA00).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA01.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA01).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA02.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA02).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA03.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA03).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PF04.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PF04).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); // ADC2 - PinId::PA04.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA04).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA05.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA05).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA06.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA06).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PA07.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PA07).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); // ADC3 - PinId::PB01.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB01).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PE09.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE09).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PE13.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE13).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PB13.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB13).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); // ADC4 - PinId::PE14.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE14).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PE15.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PE15).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PB12.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB12).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PB14.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB14).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - PinId::PB15.get_pin().as_ref().map(|pin| { + gpio_ports.get_pin(PinId::PB15).map(|pin| { pin.set_mode(stm32f303xc::gpio::Mode::AnalogMode); }); - stm32f303xc::i2c::I2C1.enable_clock(); - stm32f303xc::i2c::I2C1.set_speed(stm32f303xc::i2c::I2CSpeed::Speed400k, 8); + i2c1.enable_clock(); + i2c1.set_speed(stm32f303xc::i2c::I2CSpeed::Speed400k, 8); } /// Helper function for miscellaneous peripheral functions -unsafe fn setup_peripherals() { - use stm32f303xc::tim2::TIM2; - +unsafe fn setup_peripherals(tim2: &stm32f303xc::tim2::Tim2) { // USART1 IRQn is 37 cortexm4::nvic::Nvic::new(stm32f303xc::nvic::USART1).enable(); // TIM2 IRQn is 28 - TIM2.enable_clock(); - TIM2.start(); + tim2.enable_clock(); + tim2.start(); cortexm4::nvic::Nvic::new(stm32f303xc::nvic::TIM2).enable(); } @@ -293,9 +297,30 @@ pub unsafe fn reset_handler() { // We use the default HSI 8Mhz clock - set_pin_primary_functions(); + let rcc = static_init!(stm32f303xc::rcc::Rcc, stm32f303xc::rcc::Rcc::new()); + let syscfg = static_init!( + stm32f303xc::syscfg::Syscfg, + stm32f303xc::syscfg::Syscfg::new(rcc) + ); + let exti = static_init!( + stm32f303xc::exti::Exti, + stm32f303xc::exti::Exti::new(syscfg) + ); - setup_peripherals(); + let peripherals = static_init!( + Stm32f3xxDefaultPeripherals, + Stm32f3xxDefaultPeripherals::new(rcc, exti) + ); + set_pin_primary_functions( + syscfg, + &peripherals.exti, + &peripherals.spi1, + &peripherals.i2c1, + &peripherals.gpio_ports, + ); + + setup_peripherals(&peripherals.tim2); + peripherals.setup_circular_deps(); let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); let dynamic_deferred_call_clients = @@ -307,17 +332,17 @@ pub unsafe fn reset_handler() { DynamicDeferredCall::set_global_instance(dynamic_deferred_caller); let chip = static_init!( - stm32f303xc::chip::Stm32f3xx, - stm32f303xc::chip::Stm32f3xx::new() + stm32f303xc::chip::Stm32f3xx, + stm32f303xc::chip::Stm32f3xx::new(peripherals, rcc) ); CHIP = Some(chip); // UART // Create a shared UART channel for kernel debug. - stm32f303xc::usart::USART1.enable_clock(); + peripherals.usart1.enable_clock(); let uart_mux = components::console::UartMuxComponent::new( - &stm32f303xc::usart::USART1, + &peripherals.usart1, 115200, dynamic_deferred_caller, ) @@ -366,35 +391,59 @@ pub unsafe fn reset_handler() { let led = components::led::LedsComponent::new(components::led_component_helper!( stm32f303xc::gpio::Pin<'static>, ( - stm32f303xc::gpio::PinId::PE09.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE09) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE08.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE08) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE10.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE10) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE15.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE15) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE11.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE11) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE14.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE14) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE12.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE12) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ), ( - stm32f303xc::gpio::PinId::PE13.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PE13) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh ) )) @@ -408,7 +457,10 @@ pub unsafe fn reset_handler() { components::button_component_helper!( stm32f303xc::gpio::Pin<'static>, ( - stm32f303xc::gpio::PinId::PA00.get_pin().as_ref().unwrap(), + &peripherals + .gpio_ports + .get_pin(stm32f303xc::gpio::PinId::PA00) + .unwrap(), kernel::hil::gpio::ActivationMode::ActiveHigh, kernel::hil::gpio::FloatingState::PullNone ) @@ -420,7 +472,7 @@ pub unsafe fn reset_handler() { // ALARM - let tim2 = &stm32f303xc::tim2::TIM2; + let tim2 = &peripherals.tim2; let mux_alarm = components::alarm::AlarmMuxComponent::new(tim2).finalize( components::alarm_mux_component_helper!(stm32f303xc::tim2::Tim2), ); @@ -428,102 +480,103 @@ pub unsafe fn reset_handler() { let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm) .finalize(components::alarm_component_helper!(stm32f303xc::tim2::Tim2)); + let gpio_ports = &peripherals.gpio_ports; // GPIO let gpio = GpioComponent::new( board_kernel, components::gpio_component_helper!( stm32f303xc::gpio::Pin<'static>, // Left outer connector - 0 => stm32f303xc::gpio::PinId::PC01.get_pin().as_ref().unwrap(), - 1 => stm32f303xc::gpio::PinId::PC03.get_pin().as_ref().unwrap(), - // 2 => stm32f303xc::gpio::PinId::PA01.get_pin().as_ref().unwrap(), - // 3 => stm32f303xc::gpio::PinId::PA03.get_pin().as_ref().unwrap(), - // 4 => stm32f303xc::gpio::PinId::PF04.get_pin().as_ref().unwrap(), - // 5 => stm32f303xc::gpio::PinId::PA05.get_pin().as_ref().unwrap(), - // 6 => stm32f303xc::gpio::PinId::PA07.get_pin().as_ref().unwrap(), - // 7 => stm32f303xc::gpio::PinId::PC05.get_pin().as_ref().unwrap(), - // 8 => stm32f303xc::gpio::PinId::PB01.get_pin().as_ref().unwrap(), - 9 => stm32f303xc::gpio::PinId::PE07.get_pin().as_ref().unwrap(), - // 10 => stm32f303xc::gpio::PinId::PE09.get_pin().as_ref().unwrap(), - 11 => stm32f303xc::gpio::PinId::PE11.get_pin().as_ref().unwrap(), - // 12 => stm32f303xc::gpio::PinId::PE13.get_pin().as_ref().unwrap(), - // 13 => stm32f303xc::gpio::PinId::PE15.get_pin().as_ref().unwrap(), - 14 => stm32f303xc::gpio::PinId::PB11.get_pin().as_ref().unwrap(), - // 15 => stm32f303xc::gpio::PinId::PB13.get_pin().as_ref().unwrap(), - // 16 => stm32f303xc::gpio::PinId::PB15.get_pin().as_ref().unwrap(), - 17 => stm32f303xc::gpio::PinId::PD09.get_pin().as_ref().unwrap(), - 18 => stm32f303xc::gpio::PinId::PD11.get_pin().as_ref().unwrap(), - 19 => stm32f303xc::gpio::PinId::PD13.get_pin().as_ref().unwrap(), - 20 => stm32f303xc::gpio::PinId::PD15.get_pin().as_ref().unwrap(), - 21 => stm32f303xc::gpio::PinId::PC06.get_pin().as_ref().unwrap(), + 0 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC01).unwrap(), + 1 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC03).unwrap(), + // 2 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA01).unwrap(), + // 3 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA03).unwrap(), + // 4 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF04).unwrap(), + // 5 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA05).unwrap(), + // 6 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA07).unwrap(), + // 7 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC05).unwrap(), + // 8 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB01).unwrap(), + 9 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE07).unwrap(), + // 10 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE09).unwrap(), + 11 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE11).unwrap(), + // 12 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE13).unwrap(), + // 13 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE15).unwrap(), + 14 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB11).unwrap(), + // 15 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB13).unwrap(), + // 16 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB15).unwrap(), + 17 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD09).unwrap(), + 18 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD11).unwrap(), + 19 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD13).unwrap(), + 20 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD15).unwrap(), + 21 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC06).unwrap(), // Left inner connector - 22 => stm32f303xc::gpio::PinId::PC00.get_pin().as_ref().unwrap(), - 23 => stm32f303xc::gpio::PinId::PC02.get_pin().as_ref().unwrap(), - 24 => stm32f303xc::gpio::PinId::PF02.get_pin().as_ref().unwrap(), - // 25 => stm32f303xc::gpio::PinId::PA00.get_pin().as_ref().unwrap(), - // 26 => stm32f303xc::gpio::PinId::PA02.get_pin().as_ref().unwrap(), - // 27 => stm32f303xc::gpio::PinId::PA04.get_pin().as_ref().unwrap(), - // 28 => stm32f303xc::gpio::PinId::PA06.get_pin().as_ref().unwrap(), - // 29 => stm32f303xc::gpio::PinId::PC04.get_pin().as_ref().unwrap(), - 30 => stm32f303xc::gpio::PinId::PB00.get_pin().as_ref().unwrap(), - 31 => stm32f303xc::gpio::PinId::PB02.get_pin().as_ref().unwrap(), - 32 => stm32f303xc::gpio::PinId::PE08.get_pin().as_ref().unwrap(), - 33 => stm32f303xc::gpio::PinId::PE10.get_pin().as_ref().unwrap(), - 34 => stm32f303xc::gpio::PinId::PE12.get_pin().as_ref().unwrap(), - // 35 => stm32f303xc::gpio::PinId::PE14.get_pin().as_ref().unwrap(), - 36 => stm32f303xc::gpio::PinId::PB10.get_pin().as_ref().unwrap(), - // 37 => stm32f303xc::gpio::PinId::PB12.get_pin().as_ref().unwrap(), - // 38 => stm32f303xc::gpio::PinId::PB14.get_pin().as_ref().unwrap(), - 39 => stm32f303xc::gpio::PinId::PD08.get_pin().as_ref().unwrap(), - 40 => stm32f303xc::gpio::PinId::PD10.get_pin().as_ref().unwrap(), - 41 => stm32f303xc::gpio::PinId::PD12.get_pin().as_ref().unwrap(), - 42 => stm32f303xc::gpio::PinId::PD14.get_pin().as_ref().unwrap(), - 43 => stm32f303xc::gpio::PinId::PC07.get_pin().as_ref().unwrap(), + 22 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC00).unwrap(), + 23 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC02).unwrap(), + 24 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF02).unwrap(), + // 25 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA00).unwrap(), + // 26 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA02).unwrap(), + // 27 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA04).unwrap(), + // 28 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA06).unwrap(), + // 29 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC04).unwrap(), + 30 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB00).unwrap(), + 31 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB02).unwrap(), + 32 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE08).unwrap(), + 33 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE10).unwrap(), + 34 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE12).unwrap(), + // 35 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE14).unwrap(), + 36 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB10).unwrap(), + // 37 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB12).unwrap(), + // 38 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB14).unwrap(), + 39 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD08).unwrap(), + 40 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD10).unwrap(), + 41 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD12).unwrap(), + 42 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD14).unwrap(), + 43 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC07).unwrap(), // Right inner connector - 44 => stm32f303xc::gpio::PinId::PF09.get_pin().as_ref().unwrap(), - 45 => stm32f303xc::gpio::PinId::PF00.get_pin().as_ref().unwrap(), - 46 => stm32f303xc::gpio::PinId::PC14.get_pin().as_ref().unwrap(), - 47 => stm32f303xc::gpio::PinId::PE06.get_pin().as_ref().unwrap(), - 48 => stm32f303xc::gpio::PinId::PE04.get_pin().as_ref().unwrap(), - 49 => stm32f303xc::gpio::PinId::PE02.get_pin().as_ref().unwrap(), - 50 => stm32f303xc::gpio::PinId::PE00.get_pin().as_ref().unwrap(), - 51 => stm32f303xc::gpio::PinId::PB08.get_pin().as_ref().unwrap(), - // 52 => stm32f303xc::gpio::PinId::PB06.get_pin().as_ref().unwrap(), - 53 => stm32f303xc::gpio::PinId::PB04.get_pin().as_ref().unwrap(), - 54 => stm32f303xc::gpio::PinId::PD07.get_pin().as_ref().unwrap(), - 55 => stm32f303xc::gpio::PinId::PD05.get_pin().as_ref().unwrap(), - 56 => stm32f303xc::gpio::PinId::PD03.get_pin().as_ref().unwrap(), - 57 => stm32f303xc::gpio::PinId::PD01.get_pin().as_ref().unwrap(), - 58 => stm32f303xc::gpio::PinId::PC12.get_pin().as_ref().unwrap(), - 59 => stm32f303xc::gpio::PinId::PC10.get_pin().as_ref().unwrap(), - 60 => stm32f303xc::gpio::PinId::PA14.get_pin().as_ref().unwrap(), - 61 => stm32f303xc::gpio::PinId::PF06.get_pin().as_ref().unwrap(), - 62 => stm32f303xc::gpio::PinId::PA12.get_pin().as_ref().unwrap(), - 63 => stm32f303xc::gpio::PinId::PA10.get_pin().as_ref().unwrap(), - 64 => stm32f303xc::gpio::PinId::PA08.get_pin().as_ref().unwrap(), - 65 => stm32f303xc::gpio::PinId::PC08.get_pin().as_ref().unwrap(), + 44 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF09).unwrap(), + 45 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF00).unwrap(), + 46 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC14).unwrap(), + 47 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE06).unwrap(), + 48 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE04).unwrap(), + 49 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE02).unwrap(), + 50 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE00).unwrap(), + 51 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB08).unwrap(), + // 52 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB06).unwrap(), + 53 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB04).unwrap(), + 54 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD07).unwrap(), + 55 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD05).unwrap(), + 56 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD03).unwrap(), + 57 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD01).unwrap(), + 58 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC12).unwrap(), + 59 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC10).unwrap(), + 60 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA14).unwrap(), + 61 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF06).unwrap(), + 62 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA12).unwrap(), + 63 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA10).unwrap(), + 64 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA08).unwrap(), + 65 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC08).unwrap(), // Right outer connector - 66 => stm32f303xc::gpio::PinId::PF10.get_pin().as_ref().unwrap(), - 67 => stm32f303xc::gpio::PinId::PF01.get_pin().as_ref().unwrap(), - 68 => stm32f303xc::gpio::PinId::PC15.get_pin().as_ref().unwrap(), - 69 => stm32f303xc::gpio::PinId::PC13.get_pin().as_ref().unwrap(), - 70 => stm32f303xc::gpio::PinId::PE05.get_pin().as_ref().unwrap(), - 71 => stm32f303xc::gpio::PinId::PE03.get_pin().as_ref().unwrap(), - 72 => stm32f303xc::gpio::PinId::PE01.get_pin().as_ref().unwrap(), - 73 => stm32f303xc::gpio::PinId::PB09.get_pin().as_ref().unwrap(), - // 74 => stm32f303xc::gpio::PinId::PB07.get_pin().as_ref().unwrap(), - 75 => stm32f303xc::gpio::PinId::PB05.get_pin().as_ref().unwrap(), - 76 => stm32f303xc::gpio::PinId::PB03.get_pin().as_ref().unwrap(), - 77 => stm32f303xc::gpio::PinId::PD06.get_pin().as_ref().unwrap(), - 78 => stm32f303xc::gpio::PinId::PD04.get_pin().as_ref().unwrap(), - 79 => stm32f303xc::gpio::PinId::PD02.get_pin().as_ref().unwrap(), - 80 => stm32f303xc::gpio::PinId::PD00.get_pin().as_ref().unwrap(), - 81 => stm32f303xc::gpio::PinId::PC11.get_pin().as_ref().unwrap(), - 82 => stm32f303xc::gpio::PinId::PA15.get_pin().as_ref().unwrap(), - 83 => stm32f303xc::gpio::PinId::PA13.get_pin().as_ref().unwrap(), - 84 => stm32f303xc::gpio::PinId::PA11.get_pin().as_ref().unwrap(), - 85 => stm32f303xc::gpio::PinId::PA09.get_pin().as_ref().unwrap(), - 86 => stm32f303xc::gpio::PinId::PC09.get_pin().as_ref().unwrap() + 66 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF10).unwrap(), + 67 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PF01).unwrap(), + 68 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC15).unwrap(), + 69 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC13).unwrap(), + 70 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE05).unwrap(), + 71 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE03).unwrap(), + 72 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE01).unwrap(), + 73 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB09).unwrap(), + // 74 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB07).unwrap(), + 75 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB05).unwrap(), + 76 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PB03).unwrap(), + 77 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD06).unwrap(), + 78 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD04).unwrap(), + 79 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD02).unwrap(), + 80 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PD00).unwrap(), + 81 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC11).unwrap(), + 82 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA15).unwrap(), + 83 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA13).unwrap(), + 84 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA11).unwrap(), + 85 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PA09).unwrap(), + 86 => &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PC09).unwrap() ), ) .finalize(components::gpio_component_buf!( @@ -531,7 +584,7 @@ pub unsafe fn reset_handler() { )); // L3GD20 sensor - let spi_mux = components::spi::SpiMuxComponent::new(&stm32f303xc::spi::SPI1) + let spi_mux = components::spi::SpiMuxComponent::new(&peripherals.spi1) .finalize(components::spi_mux_component_helper!(stm32f303xc::spi::Spi)); let l3gd20 = components::l3gd20::L3gd20SpiComponent::new().finalize( @@ -539,7 +592,7 @@ pub unsafe fn reset_handler() { // spi type stm32f303xc::spi::Spi, // chip select - stm32f303xc::gpio::PinId::PE03, + &gpio_ports.get_pin(stm32f303xc::gpio::PinId::PE03).unwrap(), // spi mux spi_mux ), @@ -559,12 +612,9 @@ pub unsafe fn reset_handler() { // LSM303DLHC - let mux_i2c = components::i2c::I2CMuxComponent::new( - &stm32f303xc::i2c::I2C1, - None, - dynamic_deferred_caller, - ) - .finalize(components::i2c_mux_component_helper!()); + let mux_i2c = + components::i2c::I2CMuxComponent::new(&peripherals.i2c1, None, dynamic_deferred_caller) + .finalize(components::i2c_mux_component_helper!()); let lsm303dlhc = components::lsm303dlhc::Lsm303dlhcI2CComponent::new() .finalize(components::lsm303dlhc_i2c_component_helper!(mux_i2c)); @@ -582,7 +632,7 @@ pub unsafe fn reset_handler() { let ninedof = components::ninedof::NineDofComponent::new(board_kernel) .finalize(components::ninedof_component_helper!(l3gd20, lsm303dlhc)); - let adc_mux = components::adc::AdcMuxComponent::new(&stm32f303xc::adc::ADC1) + let adc_mux = components::adc::AdcMuxComponent::new(&peripherals.adc1) .finalize(components::adc_mux_component_helper!(stm32f303xc::adc::Adc)); // Uncomment this if you want to use ADC MCU temp sensor @@ -649,7 +699,7 @@ pub unsafe fn reset_handler() { let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( board_kernel, - &stm32f303xc::flash::FLASH, + &peripherals.flash, 0x08038000, // Start address for userspace accesible region 0x8000, // Length of userspace accesible region (16 pages) &_sstorage as *const u8 as usize, diff --git a/chips/stm32f303xc/src/adc.rs b/chips/stm32f303xc/src/adc.rs index badc1203ac..4b598980bf 100644 --- a/chips/stm32f303xc/src/adc.rs +++ b/chips/stm32f303xc/src/adc.rs @@ -497,10 +497,10 @@ enum ADCStatus { Continuous, } -pub struct Adc { +pub struct Adc<'a> { registers: StaticRef, common_registers: StaticRef, - clock: AdcClock, + clock: AdcClock<'a>, status: Cell, client: OptionalCell<&'static dyn hil::adc::Client>, requested: Cell, @@ -508,14 +508,15 @@ pub struct Adc { sc_enabled: Cell, } -pub static mut ADC1: Adc = Adc::new(); - -impl Adc { - const fn new() -> Adc { - Adc { +impl<'a> Adc<'a> { + pub const fn new(rcc: &'a rcc::Rcc) -> Self { + Self { registers: ADC1_BASE, common_registers: ADC12_COMMON_BASE, - clock: AdcClock(rcc::PeripheralClock::AHB(rcc::HCLK::ADC1)), + clock: AdcClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::ADC1), + rcc, + )), status: Cell::new(ADCStatus::Off), client: OptionalCell::empty(), requested: Cell::new(ADCStatus::Idle), @@ -664,9 +665,9 @@ impl Adc { } } -struct AdcClock(rcc::PeripheralClock); +struct AdcClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for AdcClock { +impl ClockInterface for AdcClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } @@ -680,7 +681,7 @@ impl ClockInterface for AdcClock { } } -impl hil::adc::Adc for Adc { +impl hil::adc::Adc for Adc<'_> { type Channel = Channel; fn sample(&self, channel: &Self::Channel) -> ReturnCode { @@ -725,7 +726,7 @@ impl hil::adc::Adc for Adc { } /// Not yet supported -impl hil::adc::AdcHighSpeed for Adc { +impl hil::adc::AdcHighSpeed for Adc<'_> { /// Capture buffered samples from the ADC continuously at a given /// frequency, calling the client whenever a buffer fills up. The client is /// then expected to either stop sampling or provide an additional buffer diff --git a/chips/stm32f303xc/src/chip.rs b/chips/stm32f303xc/src/chip.rs index abe173fb06..880d3c4c81 100644 --- a/chips/stm32f303xc/src/chip.rs +++ b/chips/stm32f303xc/src/chip.rs @@ -4,32 +4,99 @@ use core::fmt::Write; use cortexm4; use kernel::common::deferred_call; use kernel::Chip; +use kernel::InterruptService; -use crate::adc; use crate::deferred_call_tasks::DeferredCallTask; -use crate::exti; -use crate::flash; -use crate::i2c; use crate::nvic; -use crate::spi; -use crate::tim2; -use crate::usart; use crate::wdt; -pub struct Stm32f3xx { +pub struct Stm32f3xx<'a, I: InterruptService + 'a> { mpu: cortexm4::mpu::MPU, userspace_kernel_boundary: cortexm4::syscall::SysCall, scheduler_timer: cortexm4::systick::SysTick, - watchdog: wdt::WindoWdg, + watchdog: wdt::WindoWdg<'a>, + interrupt_service: &'a I, } -impl Stm32f3xx { - pub unsafe fn new() -> Stm32f3xx { - Stm32f3xx { +pub struct Stm32f3xxDefaultPeripherals<'a> { + pub adc1: crate::adc::Adc<'a>, + pub dma: crate::dma::Dma1<'a>, + pub exti: &'a crate::exti::Exti<'a>, + pub flash: crate::flash::Flash, + pub i2c1: crate::i2c::I2C<'a>, + pub spi1: crate::spi::Spi<'a>, + pub tim2: crate::tim2::Tim2<'a>, + pub usart1: crate::usart::Usart<'a>, + pub usart2: crate::usart::Usart<'a>, + pub usart3: crate::usart::Usart<'a>, + pub gpio_ports: crate::gpio::GpioPorts<'a>, +} + +impl<'a> Stm32f3xxDefaultPeripherals<'a> { + pub fn new(rcc: &'a crate::rcc::Rcc, exti: &'a crate::exti::Exti<'a>) -> Self { + Self { + adc1: crate::adc::Adc::new(rcc), + dma: crate::dma::Dma1::new(rcc), + exti, + flash: crate::flash::Flash::new(), + i2c1: crate::i2c::I2C::new_i2c1(rcc), + spi1: crate::spi::Spi::new_spi1(rcc), + tim2: crate::tim2::Tim2::new(rcc), + usart1: crate::usart::Usart::new_usart1(rcc), + usart2: crate::usart::Usart::new_usart2(rcc), + usart3: crate::usart::Usart::new_usart3(rcc), + gpio_ports: crate::gpio::GpioPorts::new(rcc, exti), + } + } + + pub fn setup_circular_deps(&'a self) { + self.gpio_ports.setup_circular_deps(); + } +} + +impl<'a> InterruptService for Stm32f3xxDefaultPeripherals<'a> { + unsafe fn service_interrupt(&self, interrupt: u32) -> bool { + match interrupt { + nvic::USART1 => self.usart1.handle_interrupt(), + + nvic::TIM2 => self.tim2.handle_interrupt(), + + nvic::SPI1 => self.spi1.handle_interrupt(), + + nvic::FLASH => self.flash.handle_interrupt(), + + nvic::I2C1_EV => self.i2c1.handle_event(), + nvic::I2C1_ER => self.i2c1.handle_error(), + nvic::ADC1_2 => self.adc1.handle_interrupt(), + + nvic::EXTI0 => self.exti.handle_interrupt(), + nvic::EXTI1 => self.exti.handle_interrupt(), + nvic::EXTI2 => self.exti.handle_interrupt(), + nvic::EXTI3 => self.exti.handle_interrupt(), + nvic::EXTI4 => self.exti.handle_interrupt(), + nvic::EXTI9_5 => self.exti.handle_interrupt(), + nvic::EXTI15_10 => self.exti.handle_interrupt(), + _ => return false, + } + true + } + + unsafe fn service_deferred_call(&self, task: DeferredCallTask) -> bool { + match task { + DeferredCallTask::Flash => self.flash.handle_interrupt(), + } + true + } +} + +impl<'a, I: InterruptService + 'a> Stm32f3xx<'a, I> { + pub unsafe fn new(interrupt_service: &'a I, rcc: &'a crate::rcc::Rcc) -> Self { + Self { mpu: cortexm4::mpu::MPU::new(), userspace_kernel_boundary: cortexm4::syscall::SysCall::new(), scheduler_timer: cortexm4::systick::SysTick::new(), - watchdog: wdt::WindoWdg::new(), + watchdog: wdt::WindoWdg::new(rcc), + interrupt_service, } } @@ -38,46 +105,23 @@ impl Stm32f3xx { } } -impl Chip for Stm32f3xx { +impl<'a, I: InterruptService + 'a> Chip for Stm32f3xx<'a, I> { type MPU = cortexm4::mpu::MPU; type UserspaceKernelBoundary = cortexm4::syscall::SysCall; type SchedulerTimer = cortexm4::systick::SysTick; - type WatchDog = wdt::WindoWdg; + type WatchDog = wdt::WindoWdg<'a>; fn service_pending_interrupts(&self) { unsafe { loop { if let Some(task) = deferred_call::DeferredCall::next_pending() { - match task { - DeferredCallTask::Flash => flash::FLASH.handle_interrupt(), + if !self.interrupt_service.service_deferred_call(task) { + panic!("unhandled deferred call"); } } else if let Some(interrupt) = cortexm4::nvic::next_pending() { - match interrupt { - nvic::USART1 => usart::USART1.handle_interrupt(), - - nvic::TIM2 => tim2::TIM2.handle_interrupt(), - - nvic::SPI1 => spi::SPI1.handle_interrupt(), - - nvic::FLASH => flash::FLASH.handle_interrupt(), - - nvic::I2C1_EV => i2c::I2C1.handle_event(), - nvic::I2C1_ER => i2c::I2C1.handle_error(), - nvic::ADC1_2 => adc::ADC1.handle_interrupt(), - - nvic::EXTI0 => exti::EXTI.handle_interrupt(), - nvic::EXTI1 => exti::EXTI.handle_interrupt(), - nvic::EXTI2 => exti::EXTI.handle_interrupt(), - nvic::EXTI3 => exti::EXTI.handle_interrupt(), - nvic::EXTI4 => exti::EXTI.handle_interrupt(), - nvic::EXTI9_5 => exti::EXTI.handle_interrupt(), - nvic::EXTI15_10 => exti::EXTI.handle_interrupt(), - - _ => { - panic!("unhandled interrupt {}", interrupt); - } + if !self.interrupt_service.service_interrupt(interrupt) { + panic!("unhandled interrupt {}", interrupt); } - let n = cortexm4::nvic::Nvic::new(interrupt); n.clear_pending(); n.enable(); diff --git a/chips/stm32f303xc/src/dma.rs b/chips/stm32f303xc/src/dma.rs index 5291ad7ac4..0cfb44aa0b 100644 --- a/chips/stm32f303xc/src/dma.rs +++ b/chips/stm32f303xc/src/dma.rs @@ -291,7 +291,9 @@ enum Size { Word = 0b10, } +#[allow(unused)] struct Msize(Size); +#[allow(unused)] struct Psize(Size); /// List of peripherals managed by DMA1 @@ -303,18 +305,19 @@ pub enum Dma1Peripheral { USART1_RX, } -pub struct Dma1 { - registers: StaticRef, - clock: Dma1Clock, +pub struct Dma1<'a> { + _registers: StaticRef, + clock: Dma1Clock<'a>, } -pub static mut DMA1: Dma1 = Dma1::new(); - -impl Dma1 { - const fn new() -> Dma1 { - Dma1 { - registers: DMA1_BASE, - clock: Dma1Clock(rcc::PeripheralClock::AHB(rcc::HCLK::DMA1)), +impl<'a> Dma1<'a> { + pub const fn new(rcc: &'a rcc::Rcc) -> Self { + Self { + _registers: DMA1_BASE, + clock: Dma1Clock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::DMA1), + rcc, + )), } } @@ -331,9 +334,9 @@ impl Dma1 { } } -struct Dma1Clock(rcc::PeripheralClock); +struct Dma1Clock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for Dma1Clock { +impl ClockInterface for Dma1Clock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/exti.rs b/chips/stm32f303xc/src/exti.rs index 2d6e0da9d2..1637e89923 100644 --- a/chips/stm32f303xc/src/exti.rs +++ b/chips/stm32f303xc/src/exti.rs @@ -502,17 +502,16 @@ enum_from_primitive! { // // `line_gpiopin_map` is used to call `handle_interrupt()` on the pin. pub struct Exti<'a> { registers: StaticRef, - clock: ExtiClock, - line_gpiopin_map: [OptionalCell<&'a gpio::Pin<'a>>; 16], + clock: ExtiClock<'a>, + line_gpiopin_map: [OptionalCell<&'static gpio::Pin<'static>>; 16], + syscfg: &'a syscfg::Syscfg<'a>, } -pub static mut EXTI: Exti<'static> = Exti::new(); - impl<'a> Exti<'a> { - const fn new() -> Exti<'a> { + pub const fn new(syscfg: &'a syscfg::Syscfg<'a>) -> Exti<'a> { Exti { registers: EXTI_BASE, - clock: ExtiClock(), + clock: ExtiClock(syscfg), line_gpiopin_map: [ OptionalCell::empty(), OptionalCell::empty(), @@ -531,6 +530,7 @@ impl<'a> Exti<'a> { OptionalCell::empty(), OptionalCell::empty(), ], + syscfg, } } @@ -546,11 +546,9 @@ impl<'a> Exti<'a> { self.clock.disable(); } - pub fn associate_line_gpiopin(&self, lineid: LineId, pin: &'a gpio::Pin<'a>) { + pub fn associate_line_gpiopin(&self, lineid: LineId, pin: &'static gpio::Pin<'static>) { self.line_gpiopin_map[usize::from(lineid as u8)].set(pin); - unsafe { - syscfg::SYSCFG.configure_interrupt(pin.get_pinid()); - } + self.syscfg.configure_interrupt(pin.get_pinid()); pin.set_exti_lineid(lineid); // By default, all interrupts are masked. But, this will ensure that it @@ -766,22 +764,18 @@ impl<'a> Exti<'a> { /// The configuration registers for Exti is in Syscfg, so we need to /// enable clock to Syscfg, when using Exti. -struct ExtiClock(); +struct ExtiClock<'a>(&'a syscfg::Syscfg<'a>); -impl ClockInterface for ExtiClock { +impl ClockInterface for ExtiClock<'_> { fn is_enabled(&self) -> bool { - unsafe { syscfg::SYSCFG.is_enabled_clock() } + self.0.is_enabled_clock() } fn enable(&self) { - unsafe { - syscfg::SYSCFG.enable_clock(); - } + self.0.enable_clock(); } fn disable(&self) { - unsafe { - syscfg::SYSCFG.disable_clock(); - } + self.0.disable_clock(); } } diff --git a/chips/stm32f303xc/src/flash.rs b/chips/stm32f303xc/src/flash.rs index 27aa47290e..9aabaaf2bd 100644 --- a/chips/stm32f303xc/src/flash.rs +++ b/chips/stm32f303xc/src/flash.rs @@ -280,8 +280,6 @@ pub enum FlashState { EraseOption, // Option bytes erase procedure. } -pub static mut FLASH: Flash = Flash::new(); - pub struct Flash { registers: StaticRef, client: OptionalCell<&'static dyn hil::flash::Client>, diff --git a/chips/stm32f303xc/src/gpio.rs b/chips/stm32f303xc/src/gpio.rs index 72038e5c55..cfb9db9541 100644 --- a/chips/stm32f303xc/src/gpio.rs +++ b/chips/stm32f303xc/src/gpio.rs @@ -458,45 +458,34 @@ pub enum PinId { PF12 = 0b1011100, PF13 = 0b1011101, PF14 = 0b1011110, PF15 = 0b1011111, } -impl PinId { - pub fn get_pin(&self) -> &Option> { - let mut port_num: u8 = *self as u8; +impl<'a> GpioPorts<'a> { + pub fn get_pin(&self, pinid: PinId) -> Option<&Pin<'a>> { + let mut port_num: u8 = pinid as u8; // Right shift p by 4 bits, so we can get rid of pin bits port_num >>= 4; - let mut pin_num: u8 = *self as u8; + let mut pin_num: u8 = pinid as u8; // Mask top 3 bits, so can get only the suffix pin_num &= 0b0001111; - unsafe { &PIN[usize::from(port_num)][usize::from(pin_num)] } + self.pins[usize::from(port_num)][usize::from(pin_num)].as_ref() } - #[allow(clippy::mut_from_ref)] - // This function is inherently unsafe, but no more unsafe than multiple accesses - // to `pub static mut PIN` made directly, so okay to ignore this clippy lint - // so long as the function is marked unsafe. - pub unsafe fn get_pin_mut(&self) -> &mut Option> { - let mut port_num: u8 = *self as u8; + pub fn get_port(&self, pinid: PinId) -> &Port { + let mut port_num: u8 = pinid as u8; // Right shift p by 4 bits, so we can get rid of pin bits port_num >>= 4; - - let mut pin_num: u8 = *self as u8; - // Mask top 3 bits, so can get only the suffix - pin_num &= 0b0001111; - - &mut PIN[usize::from(port_num)][usize::from(pin_num)] + &self.ports[usize::from(port_num)] } - pub fn get_port(&self) -> &Port { - let mut port_num: u8 = *self as u8; - - // Right shift p by 4 bits, so we can get rid of pin bits - port_num >>= 4; - unsafe { &PORT[usize::from(port_num)] } + pub fn get_port_from_port_id(&self, portid: PortId) -> &Port { + &self.ports[portid as usize] } +} +impl PinId { // extract the last 4 bits. [3:0] is the pin number, [6:4] is the port // number pub fn get_pin_number(&self) -> u8 { @@ -575,39 +564,128 @@ enum_from_primitive! { } } -pub struct Port { - registers: StaticRef, - clock: PortClock, +macro_rules! declare_gpio_pins { + ($($pin:ident)*, $exti:expr) => { + [ + $(Some(Pin::new(PinId::$pin, $exti)), )* + ] + } } -pub static mut PORT: [Port; 6] = [ - Port { - registers: GPIOA_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOA)), - }, - Port { - registers: GPIOB_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOB)), - }, - Port { - registers: GPIOC_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOC)), - }, - Port { - registers: GPIOD_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOD)), - }, - Port { - registers: GPIOE_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOE)), - }, - Port { - registers: GPIOF_BASE, - clock: PortClock(rcc::PeripheralClock::AHB(rcc::HCLK::GPIOF)), - }, -]; +// Note: This would probably be better structured as each port holding +// the pins associated with it, but here they are kept separate for +// historical reasons. If writing new GPIO code, look elsewhere for +// a template on how to structure the relationship between ports and pins. +pub struct GpioPorts<'a> { + ports: [Port<'a>; 6], + pins: [[Option>; 16]; 6], +} + +impl<'a> GpioPorts<'a> { + pub fn new(rcc: &'a rcc::Rcc, exti: &'a exti::Exti<'a>) -> Self { + Self { + ports: [ + Port { + registers: GPIOA_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOA), + rcc, + )), + }, + Port { + registers: GPIOB_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOB), + rcc, + )), + }, + Port { + registers: GPIOC_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOC), + rcc, + )), + }, + Port { + registers: GPIOD_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOD), + rcc, + )), + }, + Port { + registers: GPIOE_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOE), + rcc, + )), + }, + Port { + registers: GPIOF_BASE, + clock: PortClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOF), + rcc, + )), + }, + ], + pins: [ + declare_gpio_pins! { + PA00 PA01 PA02 PA03 PA04 PA05 PA06 PA07 + PA08 PA09 PA10 PA11 PA12 PA13 PA14 PA15, exti + }, + declare_gpio_pins! { + PB00 PB01 PB02 PB03 PB04 PB05 PB06 PB07 + PB08 PB09 PB10 PB11 PB12 PB13 PB14 PB15, exti + }, + declare_gpio_pins! { + PC00 PC01 PC02 PC03 PC04 PC05 PC06 PC07 + PC08 PC09 PC10 PC11 PC12 PC13 PC14 PC15, exti + }, + declare_gpio_pins! { + PD00 PD01 PD02 PD03 PD04 PD05 PD06 PD07 + PD08 PD09 PD10 PD11 PD12 PD13 PD14 PD15, exti + }, + declare_gpio_pins! { + PE00 PE01 PE02 PE03 PE04 PE05 PE06 PE07 + PE08 PE09 PE10 PE11 PE12 PE13 PE14 PE15, exti + }, + [ + Some(Pin::new(PinId::PF00, exti)), + Some(Pin::new(PinId::PF01, exti)), + Some(Pin::new(PinId::PF02, exti)), + Some(Pin::new(PinId::PF03, exti)), + Some(Pin::new(PinId::PF04, exti)), + Some(Pin::new(PinId::PF05, exti)), + Some(Pin::new(PinId::PF06, exti)), + Some(Pin::new(PinId::PF07, exti)), + Some(Pin::new(PinId::PF08, exti)), + Some(Pin::new(PinId::PF09, exti)), + Some(Pin::new(PinId::PF10, exti)), + None, + None, + None, + None, + None, + ], + ], + } + } + + pub fn setup_circular_deps(&'a self) { + for pin_group in self.pins.iter() { + for pin in pin_group { + pin.as_ref().map(|p| p.set_ports_ref(self)); + } + } + } +} -impl Port { +pub struct Port<'a> { + registers: StaticRef, + clock: PortClock<'a>, +} + +impl<'a> Port<'a> { pub fn is_enabled_clock(&self) -> bool { self.clock.is_enabled() } @@ -621,9 +699,9 @@ impl Port { } } -struct PortClock(rcc::PeripheralClock); +struct PortClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for PortClock { +impl ClockInterface for PortClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } @@ -640,70 +718,27 @@ impl ClockInterface for PortClock { // `exti_lineid` is used to configure EXTI settings for the Pin. pub struct Pin<'a> { pinid: PinId, + ports_ref: OptionalCell<&'a GpioPorts<'a>>, + exti: &'a exti::Exti<'a>, client: OptionalCell<&'a dyn hil::gpio::Client>, exti_lineid: OptionalCell, } -macro_rules! declare_gpio_pins { - ($($pin:ident)*) => { - [ - $(Some(Pin::new(PinId::$pin)), )* - ] - } -} - -// We need to use `Option`, instead of just `Pin` because GPIOH has -// only ten pins - PF00 and PF10, rather than the usual sixteen pins. -pub static mut PIN: [[Option>; 16]; 6] = [ - declare_gpio_pins! { - PA00 PA01 PA02 PA03 PA04 PA05 PA06 PA07 - PA08 PA09 PA10 PA11 PA12 PA13 PA14 PA15 - }, - declare_gpio_pins! { - PB00 PB01 PB02 PB03 PB04 PB05 PB06 PB07 - PB08 PB09 PB10 PB11 PB12 PB13 PB14 PB15 - }, - declare_gpio_pins! { - PC00 PC01 PC02 PC03 PC04 PC05 PC06 PC07 - PC08 PC09 PC10 PC11 PC12 PC13 PC14 PC15 - }, - declare_gpio_pins! { - PD00 PD01 PD02 PD03 PD04 PD05 PD06 PD07 - PD08 PD09 PD10 PD11 PD12 PD13 PD14 PD15 - }, - declare_gpio_pins! { - PE00 PE01 PE02 PE03 PE04 PE05 PE06 PE07 - PE08 PE09 PE10 PE11 PE12 PE13 PE14 PE15 - }, - [ - Some(Pin::new(PinId::PF00)), - Some(Pin::new(PinId::PF01)), - Some(Pin::new(PinId::PF02)), - Some(Pin::new(PinId::PF03)), - Some(Pin::new(PinId::PF04)), - Some(Pin::new(PinId::PF05)), - Some(Pin::new(PinId::PF06)), - Some(Pin::new(PinId::PF07)), - Some(Pin::new(PinId::PF08)), - Some(Pin::new(PinId::PF09)), - Some(Pin::new(PinId::PF10)), - None, - None, - None, - None, - None, - ], -]; - impl<'a> Pin<'a> { - const fn new(pinid: PinId) -> Pin<'a> { - Pin { - pinid: pinid, + pub const fn new(pinid: PinId, exti: &'a exti::Exti<'a>) -> Self { + Self { + pinid, + ports_ref: OptionalCell::empty(), + exti, client: OptionalCell::empty(), exti_lineid: OptionalCell::empty(), } } + pub fn set_ports_ref(&self, ports: &'a GpioPorts<'a>) { + self.ports_ref.set(ports); + } + pub fn set_client(&self, client: &'a dyn hil::gpio::Client) { self.client.set(client); } @@ -713,7 +748,7 @@ impl<'a> Pin<'a> { } pub fn get_mode(&self) -> Mode { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("Err").get_port(self.pinid); let val = match self.pinid.get_pin_number() { 0b0000 => port.registers.moder.read(MODER::MODER0), @@ -739,7 +774,7 @@ impl<'a> Pin<'a> { } pub fn set_mode(&self, mode: Mode) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.moder.modify(MODER::MODER0.val(mode as u32)), @@ -763,7 +798,7 @@ impl<'a> Pin<'a> { } pub fn set_alternate_function(&self, af: AlternateFunction) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.afrl.modify(AFRL::AFRL0.val(af as u32)), @@ -795,7 +830,7 @@ impl<'a> Pin<'a> { } fn set_mode_output_pushpull(&self) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.otyper.modify(OTYPER::OT0::CLEAR), @@ -819,7 +854,7 @@ impl<'a> Pin<'a> { } fn get_pullup_pulldown(&self) -> PullUpPullDown { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); let val = match self.pinid.get_pin_number() { 0b0000 => port.registers.pupdr.read(PUPDR::PUPDR0), @@ -845,7 +880,7 @@ impl<'a> Pin<'a> { } fn set_pullup_pulldown(&self, pupd: PullUpPullDown) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.pupdr.modify(PUPDR::PUPDR0.val(pupd as u32)), @@ -869,7 +904,7 @@ impl<'a> Pin<'a> { } fn set_output_high(&self) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.bsrr.write(BSRR::BS0::SET), @@ -893,7 +928,7 @@ impl<'a> Pin<'a> { } fn set_output_low(&self) { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.bsrr.write(BSRR::BR0::SET), @@ -917,7 +952,7 @@ impl<'a> Pin<'a> { } fn is_output_high(&self) -> bool { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.odr.is_set(ODR::ODR0), @@ -951,7 +986,7 @@ impl<'a> Pin<'a> { } fn read_input(&self) -> bool { - let port = self.pinid.get_port(); + let port = self.ports_ref.expect("").get_port(self.pinid); match self.pinid.get_pin_number() { 0b0000 => port.registers.idr.is_set(IDR::IDR0), @@ -1078,25 +1113,25 @@ impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> { let l = lineid.clone(); // disable the interrupt - exti::EXTI.mask_interrupt(l); - exti::EXTI.clear_pending(l); + self.exti.mask_interrupt(l); + self.exti.clear_pending(l); match mode { hil::gpio::InterruptEdge::EitherEdge => { - exti::EXTI.select_rising_trigger(l); - exti::EXTI.select_falling_trigger(l); + self.exti.select_rising_trigger(l); + self.exti.select_falling_trigger(l); } hil::gpio::InterruptEdge::RisingEdge => { - exti::EXTI.select_rising_trigger(l); - exti::EXTI.deselect_falling_trigger(l); + self.exti.select_rising_trigger(l); + self.exti.deselect_falling_trigger(l); } hil::gpio::InterruptEdge::FallingEdge => { - exti::EXTI.deselect_rising_trigger(l); - exti::EXTI.select_falling_trigger(l); + self.exti.deselect_rising_trigger(l); + self.exti.select_falling_trigger(l); } } - exti::EXTI.unmask_interrupt(l); + self.exti.unmask_interrupt(l); }); }); } @@ -1107,8 +1142,8 @@ impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> { atomic(|| { self.exti_lineid.map(|lineid| { let l = lineid.clone(); - exti::EXTI.mask_interrupt(l); - exti::EXTI.clear_pending(l); + self.exti.mask_interrupt(l); + self.exti.clear_pending(l); }); }); } @@ -1119,9 +1154,7 @@ impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> { } fn is_pending(&self) -> bool { - unsafe { - self.exti_lineid - .map_or(false, |&mut lineid| exti::EXTI.is_pending(lineid)) - } + self.exti_lineid + .map_or(false, |&mut lineid| self.exti.is_pending(lineid)) } } diff --git a/chips/stm32f303xc/src/i2c.rs b/chips/stm32f303xc/src/i2c.rs index caefffa9e1..1f0f843a27 100644 --- a/chips/stm32f303xc/src/i2c.rs +++ b/chips/stm32f303xc/src/i2c.rs @@ -231,7 +231,7 @@ const I2C1_BASE: StaticRef = pub struct I2C<'a> { registers: StaticRef, - clock: I2CClock, + clock: I2CClock<'a>, // I2C slave support not yet implemented master_client: OptionalCell<&'a dyn hil::i2c::I2CHwMasterClient>, @@ -256,13 +256,8 @@ enum I2CStatus { Reading, } -pub static mut I2C1: I2C = I2C::new( - I2C1_BASE, - I2CClock(rcc::PeripheralClock::APB1(rcc::PCLK1::I2C1)), -); - -impl I2C<'_> { - const fn new(base_addr: StaticRef, clock: I2CClock) -> Self { +impl<'a> I2C<'a> { + const fn new(base_addr: StaticRef, clock: I2CClock<'a>) -> Self { Self { registers: base_addr, clock, @@ -282,6 +277,16 @@ impl I2C<'_> { } } + pub const fn new_i2c1(rcc: &'a rcc::Rcc) -> Self { + Self::new( + I2C1_BASE, + I2CClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB1(rcc::PCLK1::I2C1), + rcc, + )), + ) + } + pub fn set_speed(&self, speed: I2CSpeed, system_clock_in_mhz: usize) { self.disable(); match speed { @@ -511,9 +516,9 @@ impl i2c::I2CMaster for I2C<'_> { } } -struct I2CClock(rcc::PeripheralClock); +struct I2CClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for I2CClock { +impl ClockInterface for I2CClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/lib.rs b/chips/stm32f303xc/src/lib.rs index 3018da46e7..34fa301b31 100644 --- a/chips/stm32f303xc/src/lib.rs +++ b/chips/stm32f303xc/src/lib.rs @@ -13,6 +13,7 @@ pub mod nvic; // Peripherals pub mod adc; +pub mod dma; pub mod exti; pub mod flash; pub mod gpio; diff --git a/chips/stm32f303xc/src/rcc.rs b/chips/stm32f303xc/src/rcc.rs index 971f38a9c9..3f86e2e165 100644 --- a/chips/stm32f303xc/src/rcc.rs +++ b/chips/stm32f303xc/src/rcc.rs @@ -385,10 +385,8 @@ pub struct Rcc { registers: StaticRef, } -pub static mut RCC: Rcc = Rcc::new(); - impl Rcc { - const fn new() -> Rcc { + pub const fn new() -> Rcc { Rcc { registers: RCC_BASE, } @@ -646,6 +644,11 @@ pub enum CPUClock { PLLCLK, } +pub struct PeripheralClock<'a> { + pub clock: PeripheralClockType, + rcc: &'a Rcc, +} + /// Bus + Clock name for the peripherals /// /// Not yet implemented clocks: @@ -654,7 +657,7 @@ pub enum CPUClock { /// AHB3(HCLK3) /// APB1(PCLK1), /// APB2(PCLK2), -pub enum PeripheralClock { +pub enum PeripheralClockType { AHB(HCLK), APB2(PCLK2), APB1(PCLK1), @@ -693,156 +696,162 @@ pub enum PCLK2 { SPI1, } -impl ClockInterface for PeripheralClock { +impl<'a> PeripheralClock<'a> { + pub const fn new(clock: PeripheralClockType, rcc: &'a Rcc) -> Self { + Self { clock, rcc } + } +} + +impl<'a> ClockInterface for PeripheralClock<'a> { fn is_enabled(&self) -> bool { - match self { - &PeripheralClock::AHB(ref v) => match v { - HCLK::ADC1 | HCLK::ADC2 => unsafe { RCC.is_enabled_adc12_clock() }, - HCLK::ADC3 | HCLK::ADC4 => unsafe { RCC.is_enabled_adc34_clock() }, - HCLK::DMA1 => unsafe { RCC.is_enabled_dma1_clock() }, - HCLK::GPIOF => unsafe { RCC.is_enabled_gpiof_clock() }, - HCLK::GPIOE => unsafe { RCC.is_enabled_gpioe_clock() }, - HCLK::GPIOD => unsafe { RCC.is_enabled_gpiod_clock() }, - HCLK::GPIOC => unsafe { RCC.is_enabled_gpioc_clock() }, - HCLK::GPIOB => unsafe { RCC.is_enabled_gpiob_clock() }, - HCLK::GPIOA => unsafe { RCC.is_enabled_gpioa_clock() }, + match self.clock { + PeripheralClockType::AHB(ref v) => match v { + HCLK::ADC1 | HCLK::ADC2 => self.rcc.is_enabled_adc12_clock(), + HCLK::ADC3 | HCLK::ADC4 => self.rcc.is_enabled_adc34_clock(), + HCLK::DMA1 => self.rcc.is_enabled_dma1_clock(), + HCLK::GPIOF => self.rcc.is_enabled_gpiof_clock(), + HCLK::GPIOE => self.rcc.is_enabled_gpioe_clock(), + HCLK::GPIOD => self.rcc.is_enabled_gpiod_clock(), + HCLK::GPIOC => self.rcc.is_enabled_gpioc_clock(), + HCLK::GPIOB => self.rcc.is_enabled_gpiob_clock(), + HCLK::GPIOA => self.rcc.is_enabled_gpioa_clock(), }, - &PeripheralClock::APB1(ref v) => match v { - PCLK1::TIM2 => unsafe { RCC.is_enabled_tim2_clock() }, - PCLK1::USART2 => unsafe { RCC.is_enabled_usart2_clock() }, - PCLK1::USART3 => unsafe { RCC.is_enabled_usart3_clock() }, - PCLK1::I2C1 => unsafe { RCC.is_enabled_i2c1_clock() }, - PCLK1::WWDG => unsafe { RCC.is_enabled_wwdg_clock() }, + PeripheralClockType::APB1(ref v) => match v { + PCLK1::TIM2 => self.rcc.is_enabled_tim2_clock(), + PCLK1::USART2 => self.rcc.is_enabled_usart2_clock(), + PCLK1::USART3 => self.rcc.is_enabled_usart3_clock(), + PCLK1::I2C1 => self.rcc.is_enabled_i2c1_clock(), + PCLK1::WWDG => self.rcc.is_enabled_wwdg_clock(), }, - &PeripheralClock::APB2(ref v) => match v { - PCLK2::SPI1 => unsafe { RCC.is_enabled_spi1_clock() }, - PCLK2::SYSCFG => unsafe { RCC.is_enabled_syscfg_clock() }, - PCLK2::USART1 => unsafe { RCC.is_enabled_usart1_clock() }, + PeripheralClockType::APB2(ref v) => match v { + PCLK2::SPI1 => self.rcc.is_enabled_spi1_clock(), + PCLK2::SYSCFG => self.rcc.is_enabled_syscfg_clock(), + PCLK2::USART1 => self.rcc.is_enabled_usart1_clock(), }, } } fn enable(&self) { - match self { - &PeripheralClock::AHB(ref v) => match v { - HCLK::ADC1 | HCLK::ADC2 => unsafe { - RCC.enable_adc12_clock(); - }, - HCLK::ADC3 | HCLK::ADC4 => unsafe { - RCC.enable_adc34_clock(); - }, - HCLK::DMA1 => unsafe { - RCC.enable_dma1_clock(); - }, - HCLK::GPIOF => unsafe { - RCC.enable_gpiof_clock(); - }, - HCLK::GPIOE => unsafe { - RCC.enable_gpioe_clock(); - }, - HCLK::GPIOD => unsafe { - RCC.enable_gpiod_clock(); - }, - HCLK::GPIOC => unsafe { - RCC.enable_gpioc_clock(); - }, - HCLK::GPIOB => unsafe { - RCC.enable_gpiob_clock(); - }, - HCLK::GPIOA => unsafe { - RCC.enable_gpioa_clock(); - }, + match self.clock { + PeripheralClockType::AHB(ref v) => match v { + HCLK::ADC1 | HCLK::ADC2 => { + self.rcc.enable_adc12_clock(); + } + HCLK::ADC3 | HCLK::ADC4 => { + self.rcc.enable_adc34_clock(); + } + HCLK::DMA1 => { + self.rcc.enable_dma1_clock(); + } + HCLK::GPIOF => { + self.rcc.enable_gpiof_clock(); + } + HCLK::GPIOE => { + self.rcc.enable_gpioe_clock(); + } + HCLK::GPIOD => { + self.rcc.enable_gpiod_clock(); + } + HCLK::GPIOC => { + self.rcc.enable_gpioc_clock(); + } + HCLK::GPIOB => { + self.rcc.enable_gpiob_clock(); + } + HCLK::GPIOA => { + self.rcc.enable_gpioa_clock(); + } }, - &PeripheralClock::APB1(ref v) => match v { - PCLK1::TIM2 => unsafe { - RCC.enable_tim2_clock(); - }, - PCLK1::USART2 => unsafe { - RCC.enable_usart2_clock(); - }, - PCLK1::USART3 => unsafe { - RCC.enable_usart3_clock(); - }, - PCLK1::I2C1 => unsafe { - RCC.enable_i2c1_clock(); - RCC.reset_i2c1(); - }, - PCLK1::WWDG => unsafe { - RCC.enable_wwdg_clock(); - }, + PeripheralClockType::APB1(ref v) => match v { + PCLK1::TIM2 => { + self.rcc.enable_tim2_clock(); + } + PCLK1::USART2 => { + self.rcc.enable_usart2_clock(); + } + PCLK1::USART3 => { + self.rcc.enable_usart3_clock(); + } + PCLK1::I2C1 => { + self.rcc.enable_i2c1_clock(); + self.rcc.reset_i2c1(); + } + PCLK1::WWDG => { + self.rcc.enable_wwdg_clock(); + } }, - &PeripheralClock::APB2(ref v) => match v { - PCLK2::SYSCFG => unsafe { - RCC.enable_syscfg_clock(); - }, - PCLK2::USART1 => unsafe { - RCC.enable_usart1_clock(); - }, - PCLK2::SPI1 => unsafe { - RCC.enable_spi1_clock(); - }, + PeripheralClockType::APB2(ref v) => match v { + PCLK2::SYSCFG => { + self.rcc.enable_syscfg_clock(); + } + PCLK2::USART1 => { + self.rcc.enable_usart1_clock(); + } + PCLK2::SPI1 => { + self.rcc.enable_spi1_clock(); + } }, } } fn disable(&self) { - match self { - &PeripheralClock::AHB(ref v) => match v { - HCLK::ADC1 | HCLK::ADC2 => unsafe { - RCC.disable_adc12_clock(); - }, - HCLK::ADC3 | HCLK::ADC4 => unsafe { - RCC.disable_adc34_clock(); - }, - HCLK::DMA1 => unsafe { - RCC.disable_dma1_clock(); - }, - HCLK::GPIOF => unsafe { - RCC.disable_gpiof_clock(); - }, - HCLK::GPIOE => unsafe { - RCC.disable_gpioe_clock(); - }, - HCLK::GPIOD => unsafe { - RCC.disable_gpiod_clock(); - }, - HCLK::GPIOC => unsafe { - RCC.disable_gpioc_clock(); - }, - HCLK::GPIOB => unsafe { - RCC.disable_gpiob_clock(); - }, - HCLK::GPIOA => unsafe { - RCC.disable_gpioa_clock(); - }, + match self.clock { + PeripheralClockType::AHB(ref v) => match v { + HCLK::ADC1 | HCLK::ADC2 => { + self.rcc.disable_adc12_clock(); + } + HCLK::ADC3 | HCLK::ADC4 => { + self.rcc.disable_adc34_clock(); + } + HCLK::DMA1 => { + self.rcc.disable_dma1_clock(); + } + HCLK::GPIOF => { + self.rcc.disable_gpiof_clock(); + } + HCLK::GPIOE => { + self.rcc.disable_gpioe_clock(); + } + HCLK::GPIOD => { + self.rcc.disable_gpiod_clock(); + } + HCLK::GPIOC => { + self.rcc.disable_gpioc_clock(); + } + HCLK::GPIOB => { + self.rcc.disable_gpiob_clock(); + } + HCLK::GPIOA => { + self.rcc.disable_gpioa_clock(); + } }, - &PeripheralClock::APB1(ref v) => match v { - PCLK1::TIM2 => unsafe { - RCC.disable_tim2_clock(); - }, - PCLK1::USART2 => unsafe { - RCC.disable_usart2_clock(); - }, - PCLK1::USART3 => unsafe { - RCC.disable_usart3_clock(); - }, - PCLK1::I2C1 => unsafe { - RCC.disable_i2c1_clock(); - }, - PCLK1::WWDG => unsafe { - RCC.disable_wwdg_clock(); - }, + PeripheralClockType::APB1(ref v) => match v { + PCLK1::TIM2 => { + self.rcc.disable_tim2_clock(); + } + PCLK1::USART2 => { + self.rcc.disable_usart2_clock(); + } + PCLK1::USART3 => { + self.rcc.disable_usart3_clock(); + } + PCLK1::I2C1 => { + self.rcc.disable_i2c1_clock(); + } + PCLK1::WWDG => { + self.rcc.disable_wwdg_clock(); + } }, - &PeripheralClock::APB2(ref v) => match v { - PCLK2::SYSCFG => unsafe { - RCC.disable_syscfg_clock(); - }, - PCLK2::USART1 => unsafe { - RCC.disable_usart1_clock(); - }, - PCLK2::SPI1 => unsafe { - RCC.disable_spi1_clock(); - }, + PeripheralClockType::APB2(ref v) => match v { + PCLK2::SYSCFG => { + self.rcc.disable_syscfg_clock(); + } + PCLK2::USART1 => { + self.rcc.disable_usart1_clock(); + } + PCLK2::SPI1 => { + self.rcc.disable_spi1_clock(); + } }, } } diff --git a/chips/stm32f303xc/src/spi.rs b/chips/stm32f303xc/src/spi.rs index 1c33f6f78f..e4df657c32 100644 --- a/chips/stm32f303xc/src/spi.rs +++ b/chips/stm32f303xc/src/spi.rs @@ -9,7 +9,6 @@ use kernel::hil::gpio::Output; use kernel::hil::spi::{self, ClockPhase, ClockPolarity, SpiMasterClient}; use kernel::{ClockInterface, ReturnCode}; -use crate::gpio::PinId; use crate::rcc; const SPI_READ_IN_PROGRESS: u8 = 0b001; @@ -182,12 +181,12 @@ const SPI1_BASE: StaticRef = pub struct Spi<'a> { registers: StaticRef, - clock: SpiClock, + clock: SpiClock<'a>, // SPI slave support not yet implemented master_client: OptionalCell<&'a dyn hil::spi::SpiMasterClient>, - active_slave: OptionalCell, + active_slave: OptionalCell<&'a crate::gpio::Pin<'a>>, tx_buffer: TakeCell<'static, [u8]>, tx_position: Cell, @@ -201,13 +200,8 @@ pub struct Spi<'a> { active_after: Cell, } -pub static mut SPI1: Spi = Spi::new( - SPI1_BASE, - SpiClock(rcc::PeripheralClock::APB2(rcc::PCLK2::SPI1)), -); - -impl Spi<'_> { - const fn new(base_addr: StaticRef, clock: SpiClock) -> Self { +impl<'a> Spi<'a> { + const fn new(base_addr: StaticRef, clock: SpiClock<'a>) -> Self { Self { registers: base_addr, clock, @@ -229,6 +223,16 @@ impl Spi<'_> { } } + pub const fn new_spi1(rcc: &'a rcc::Rcc) -> Self { + Self::new( + SPI1_BASE, + SpiClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB2(rcc::PCLK2::SPI1), + rcc, + )), + ) + } + pub fn is_enabled_clock(&self) -> bool { self.clock.is_enabled() } @@ -279,9 +283,7 @@ impl Spi<'_> { // initiate another SPI transfer right away if !self.active_after.get() { self.active_slave.map(|p| { - p.get_pin().as_ref().map(|pin| { - pin.set(); - }); + p.set(); }); } self.transfers.set(SPI_IDLE); @@ -294,7 +296,7 @@ impl Spi<'_> { } } - fn set_active_slave(&self, slave_pin: PinId) { + fn set_active_slave(&self, slave_pin: &'a crate::gpio::Pin<'a>) { self.active_slave.set(slave_pin); } @@ -354,9 +356,7 @@ impl Spi<'_> { if self.transfers.get() == 0 { self.registers.cr2.modify(CR2::RXNEIE::CLEAR); self.active_slave.map(|p| { - p.get_pin().as_ref().map(|pin| { - pin.clear(); - }); + p.clear(); }); self.transfers.set(self.transfers.get() | SPI_IN_PROGRESS); @@ -402,8 +402,8 @@ impl Spi<'_> { } } -impl spi::SpiMaster for Spi<'_> { - type ChipSelect = PinId; +impl<'a> spi::SpiMaster for Spi<'a> { + type ChipSelect = &'a crate::gpio::Pin<'a>; fn set_client(&self, client: &'static dyn SpiMasterClient) { self.master_client.set(client); @@ -527,9 +527,9 @@ impl spi::SpiMaster for Spi<'_> { } } -struct SpiClock(rcc::PeripheralClock); +struct SpiClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for SpiClock { +impl ClockInterface for SpiClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/syscfg.rs b/chips/stm32f303xc/src/syscfg.rs index b2b8b18eef..61df3a4961 100644 --- a/chips/stm32f303xc/src/syscfg.rs +++ b/chips/stm32f303xc/src/syscfg.rs @@ -114,18 +114,19 @@ enum_from_primitive! { } } -pub struct Syscfg { +pub struct Syscfg<'a> { registers: StaticRef, - clock: SyscfgClock, + clock: SyscfgClock<'a>, } -pub static mut SYSCFG: Syscfg = Syscfg::new(); - -impl Syscfg { - const fn new() -> Syscfg { +impl<'a> Syscfg<'a> { + pub const fn new(rcc: &'a rcc::Rcc) -> Syscfg { Syscfg { registers: SYSCFG_BASE, - clock: SyscfgClock(rcc::PeripheralClock::APB2(rcc::PCLK2::SYSCFG)), + clock: SyscfgClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB2(rcc::PCLK2::SYSCFG), + rcc, + )), } } @@ -224,9 +225,9 @@ impl Syscfg { } } -struct SyscfgClock(rcc::PeripheralClock); +struct SyscfgClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for SyscfgClock { +impl ClockInterface for SyscfgClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/tim2.rs b/chips/stm32f303xc/src/tim2.rs index 3fab0d833c..c58d94fe46 100644 --- a/chips/stm32f303xc/src/tim2.rs +++ b/chips/stm32f303xc/src/tim2.rs @@ -311,18 +311,19 @@ const TIM2_BASE: StaticRef = pub struct Tim2<'a> { registers: StaticRef, - clock: Tim2Clock, + clock: Tim2Clock<'a>, client: OptionalCell<&'a dyn AlarmClient>, irqn: u32, } -pub static mut TIM2: Tim2<'static> = Tim2::new(); - -impl Tim2<'_> { - const fn new() -> Self { +impl<'a> Tim2<'a> { + pub const fn new(rcc: &'a rcc::Rcc) -> Self { Self { registers: TIM2_BASE, - clock: Tim2Clock(rcc::PeripheralClock::APB1(rcc::PCLK1::TIM2)), + clock: Tim2Clock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB1(rcc::PCLK1::TIM2), + rcc, + )), client: OptionalCell::empty(), irqn: nvic::TIM2, } @@ -442,9 +443,9 @@ impl<'a> Alarm<'a> for Tim2<'a> { } } -struct Tim2Clock(rcc::PeripheralClock); +struct Tim2Clock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for Tim2Clock { +impl ClockInterface for Tim2Clock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/usart.rs b/chips/stm32f303xc/src/usart.rs index a94a56db0d..a011fe4ac6 100644 --- a/chips/stm32f303xc/src/usart.rs +++ b/chips/stm32f303xc/src/usart.rs @@ -290,7 +290,7 @@ enum USARTStateRX { pub struct Usart<'a> { registers: StaticRef, - clock: UsartClock, + clock: UsartClock<'a>, tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>, rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>, @@ -306,23 +306,8 @@ pub struct Usart<'a> { rx_status: Cell, } -pub static mut USART1: Usart = Usart::new( - USART1_BASE, - UsartClock(rcc::PeripheralClock::APB2(rcc::PCLK2::USART1)), -); - -pub static mut USART2: Usart = Usart::new( - USART2_BASE, - UsartClock(rcc::PeripheralClock::APB1(rcc::PCLK1::USART2)), -); - -pub static mut USART3: Usart = Usart::new( - USART3_BASE, - UsartClock(rcc::PeripheralClock::APB1(rcc::PCLK1::USART3)), -); - -impl Usart<'_> { - const fn new(base_addr: StaticRef, clock: UsartClock) -> Self { +impl<'a> Usart<'a> { + const fn new(base_addr: StaticRef, clock: UsartClock<'a>) -> Self { Self { registers: base_addr, clock: clock, @@ -342,6 +327,36 @@ impl Usart<'_> { } } + pub const fn new_usart1(rcc: &'a rcc::Rcc) -> Self { + Self::new( + USART1_BASE, + UsartClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB2(rcc::PCLK2::USART1), + rcc, + )), + ) + } + + pub const fn new_usart2(rcc: &'a rcc::Rcc) -> Self { + Self::new( + USART2_BASE, + UsartClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB1(rcc::PCLK1::USART2), + rcc, + )), + ) + } + + pub const fn new_usart3(rcc: &'a rcc::Rcc) -> Self { + Self::new( + USART3_BASE, + UsartClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB1(rcc::PCLK1::USART3), + rcc, + )), + ) + } + pub fn is_enabled_clock(&self) -> bool { self.clock.is_enabled() } @@ -607,9 +622,9 @@ impl<'a> hil::uart::Receive<'a> for Usart<'a> { impl<'a> hil::uart::UartData<'a> for Usart<'a> {} impl<'a> hil::uart::Uart<'a> for Usart<'a> {} -struct UsartClock(rcc::PeripheralClock); +struct UsartClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for UsartClock { +impl ClockInterface for UsartClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } diff --git a/chips/stm32f303xc/src/wdt.rs b/chips/stm32f303xc/src/wdt.rs index 338efc8965..41006fd360 100644 --- a/chips/stm32f303xc/src/wdt.rs +++ b/chips/stm32f303xc/src/wdt.rs @@ -59,17 +59,20 @@ register_bitfields![u32, ] ]; -pub struct WindoWdg { +pub struct WindoWdg<'a> { registers: StaticRef, - clock: WdgClock, + clock: WdgClock<'a>, enabled: Cell, } -impl WindoWdg { - pub const fn new() -> WindoWdg { - WindoWdg { +impl<'a> WindoWdg<'a> { + pub const fn new(rcc: &'a rcc::Rcc) -> Self { + Self { registers: WINDOW_WATCHDOG_BASE, - clock: WdgClock(rcc::PeripheralClock::APB1(rcc::PCLK1::WWDG)), + clock: WdgClock(rcc::PeripheralClock::new( + rcc::PeripheralClockType::APB1(rcc::PCLK1::WWDG), + rcc, + )), enabled: Cell::new(false), } } @@ -121,9 +124,9 @@ impl WindoWdg { } } -struct WdgClock(rcc::PeripheralClock); +struct WdgClock<'a>(rcc::PeripheralClock<'a>); -impl ClockInterface for WdgClock { +impl ClockInterface for WdgClock<'_> { fn is_enabled(&self) -> bool { self.0.is_enabled() } @@ -137,7 +140,7 @@ impl ClockInterface for WdgClock { } } -impl kernel::watchdog::WatchDog for WindoWdg { +impl<'a> kernel::watchdog::WatchDog for WindoWdg<'a> { fn setup(&self) { if self.enabled.get() { self.start();