1use core::fmt::Write;
8use cortexm4f::{CortexM4F, CortexMVariant};
9use kernel::platform::chip::Chip;
10use kernel::platform::chip::InterruptService;
11
12use crate::nvic;
13
14pub struct Stm32f3xx<'a, I: InterruptService + 'a> {
15 mpu: cortexm4f::mpu::MPU,
16 userspace_kernel_boundary: cortexm4f::syscall::SysCall,
17 interrupt_service: &'a I,
18}
19
20pub struct Stm32f3xxDefaultPeripherals<'a> {
21 pub adc1: crate::adc::Adc<'a>,
22 pub dma: crate::dma::Dma1<'a>,
23 pub exti: &'a crate::exti::Exti<'a>,
24 pub flash: crate::flash::Flash,
25 pub i2c1: crate::i2c::I2C<'a>,
26 pub spi1: crate::spi::Spi<'a>,
27 pub tim2: crate::tim2::Tim2<'a>,
28 pub usart1: crate::usart::Usart<'a>,
29 pub usart2: crate::usart::Usart<'a>,
30 pub usart3: crate::usart::Usart<'a>,
31 pub gpio_ports: crate::gpio::GpioPorts<'a>,
32 pub watchdog: crate::wdt::WindoWdg<'a>,
33}
34
35impl<'a> Stm32f3xxDefaultPeripherals<'a> {
36 pub fn new(rcc: &'a crate::rcc::Rcc, exti: &'a crate::exti::Exti<'a>) -> Self {
37 Self {
38 adc1: crate::adc::Adc::new(rcc),
39 dma: crate::dma::Dma1::new(rcc),
40 exti,
41 flash: crate::flash::Flash::new(),
42 i2c1: crate::i2c::I2C::new_i2c1(rcc),
43 spi1: crate::spi::Spi::new_spi1(rcc),
44 tim2: crate::tim2::Tim2::new(rcc),
45 usart1: crate::usart::Usart::new_usart1(rcc),
46 usart2: crate::usart::Usart::new_usart2(rcc),
47 usart3: crate::usart::Usart::new_usart3(rcc),
48 gpio_ports: crate::gpio::GpioPorts::new(rcc, exti),
49 watchdog: crate::wdt::WindoWdg::new(rcc),
50 }
51 }
52
53 pub fn setup_circular_deps(&'static self) {
55 self.gpio_ports.setup_circular_deps();
56
57 kernel::deferred_call::DeferredCallClient::register(&self.flash);
58 kernel::deferred_call::DeferredCallClient::register(&self.usart1);
59 kernel::deferred_call::DeferredCallClient::register(&self.usart2);
60 kernel::deferred_call::DeferredCallClient::register(&self.usart3);
61 }
62}
63
64impl InterruptService for Stm32f3xxDefaultPeripherals<'_> {
65 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
66 match interrupt {
67 nvic::USART1 => self.usart1.handle_interrupt(),
68 nvic::USART2 => self.usart2.handle_interrupt(),
69 nvic::USART3 => self.usart3.handle_interrupt(),
70
71 nvic::TIM2 => self.tim2.handle_interrupt(),
72
73 nvic::SPI1 => self.spi1.handle_interrupt(),
74
75 nvic::FLASH => self.flash.handle_interrupt(),
76
77 nvic::I2C1_EV => self.i2c1.handle_event(),
78 nvic::I2C1_ER => self.i2c1.handle_error(),
79 nvic::ADC1_2 => self.adc1.handle_interrupt(),
80
81 nvic::EXTI0 => self.exti.handle_interrupt(),
82 nvic::EXTI1 => self.exti.handle_interrupt(),
83 nvic::EXTI2 => self.exti.handle_interrupt(),
84 nvic::EXTI3 => self.exti.handle_interrupt(),
85 nvic::EXTI4 => self.exti.handle_interrupt(),
86 nvic::EXTI9_5 => self.exti.handle_interrupt(),
87 nvic::EXTI15_10 => self.exti.handle_interrupt(),
88 _ => return false,
89 }
90 true
91 }
92}
93
94impl<'a, I: InterruptService + 'a> Stm32f3xx<'a, I> {
95 pub unsafe fn new(interrupt_service: &'a I) -> Self {
96 Self {
97 mpu: cortexm4f::mpu::MPU::new(),
98 userspace_kernel_boundary: cortexm4f::syscall::SysCall::new(),
99 interrupt_service,
100 }
101 }
102}
103
104impl<'a, I: InterruptService + 'a> Chip for Stm32f3xx<'a, I> {
105 type MPU = cortexm4f::mpu::MPU;
106 type UserspaceKernelBoundary = cortexm4f::syscall::SysCall;
107
108 fn service_pending_interrupts(&self) {
109 unsafe {
110 loop {
111 if let Some(interrupt) = cortexm4f::nvic::next_pending() {
112 if !self.interrupt_service.service_interrupt(interrupt) {
113 panic!("unhandled interrupt {}", interrupt);
114 }
115 let n = cortexm4f::nvic::Nvic::new(interrupt);
116 n.clear_pending();
117 n.enable();
118 } else {
119 break;
120 }
121 }
122 }
123 }
124
125 fn has_pending_interrupts(&self) -> bool {
126 unsafe { cortexm4f::nvic::has_pending() }
127 }
128
129 fn mpu(&self) -> &cortexm4f::mpu::MPU {
130 &self.mpu
131 }
132
133 fn userspace_kernel_boundary(&self) -> &cortexm4f::syscall::SysCall {
134 &self.userspace_kernel_boundary
135 }
136
137 fn sleep(&self) {
138 unsafe {
139 cortexm4f::scb::unset_sleepdeep();
140 cortexm4f::support::wfi();
141 }
142 }
143
144 unsafe fn atomic<F, R>(&self, f: F) -> R
145 where
146 F: FnOnce() -> R,
147 {
148 cortexm4f::support::atomic(f)
149 }
150
151 unsafe fn print_state(&self, write: &mut dyn Write) {
152 CortexM4F::print_cortexm_state(write);
153 }
154}