1use core::fmt::Write;
8use cortexm4f::{CortexM4F, CortexMVariant};
9use kernel::platform::chip::Chip;
10use kernel::platform::chip::InterruptService;
11
12use crate::dma;
13use crate::nvic;
14
15use crate::chip_specific::chip_specs::ChipSpecs as ChipSpecsTrait;
16
17pub struct Stm32f4xx<'a, I: InterruptService + 'a> {
18 mpu: cortexm4f::mpu::MPU,
19 userspace_kernel_boundary: cortexm4f::syscall::SysCall,
20 interrupt_service: &'a I,
21}
22
23pub struct Stm32f4xxDefaultPeripherals<'a, ChipSpecs> {
24 pub adc1: crate::adc::Adc<'a>,
25 pub dac: crate::dac::Dac<'a>,
26 pub dma1_streams: [crate::dma::Stream<'a, dma::Dma1<'a>>; 8],
27 pub dma2_streams: [crate::dma::Stream<'a, dma::Dma2<'a>>; 8],
28 pub exti: &'a crate::exti::Exti<'a>,
29 pub flash: crate::flash::Flash<ChipSpecs>,
30 pub fsmc: crate::fsmc::Fsmc<'a>,
31 pub gpio_ports: crate::gpio::GpioPorts<'a>,
32 pub i2c1: crate::i2c::I2C<'a>,
33 pub clocks: &'a crate::clocks::Clocks<'a, ChipSpecs>,
34 pub spi3: crate::spi::Spi<'a>,
35 pub tim2: crate::tim2::Tim2<'a>,
36 pub usart1: crate::usart::Usart<'a, dma::Dma2<'a>>,
37 pub usart2: crate::usart::Usart<'a, dma::Dma1<'a>>,
38 pub usart3: crate::usart::Usart<'a, dma::Dma1<'a>>,
39}
40
41impl<'a, ChipSpecs: ChipSpecsTrait> Stm32f4xxDefaultPeripherals<'a, ChipSpecs> {
42 pub fn new(
43 clocks: &'a crate::clocks::Clocks<'a, ChipSpecs>,
44 exti: &'a crate::exti::Exti<'a>,
45 dma1: &'a dma::Dma1<'a>,
46 dma2: &'a dma::Dma2<'a>,
47 ) -> Self {
48 Self {
49 adc1: crate::adc::Adc::new(clocks),
50 clocks,
51 dac: crate::dac::Dac::new(clocks),
52 dma1_streams: dma::new_dma1_stream(dma1),
53 dma2_streams: dma::new_dma2_stream(dma2),
54 exti,
55 flash: crate::flash::Flash::new(),
56 fsmc: crate::fsmc::Fsmc::new(
57 [
58 Some(crate::fsmc::FSMC_BANK1),
59 None,
60 Some(crate::fsmc::FSMC_BANK3),
61 None,
62 ],
63 clocks,
64 ),
65 gpio_ports: crate::gpio::GpioPorts::new(clocks, exti),
66 i2c1: crate::i2c::I2C::new(clocks),
67 spi3: crate::spi::Spi::new(
68 crate::spi::SPI3_BASE,
69 crate::spi::SpiClock(crate::clocks::phclk::PeripheralClock::new(
70 crate::clocks::phclk::PeripheralClockType::APB1(
71 crate::clocks::phclk::PCLK1::SPI3,
72 ),
73 clocks,
74 )),
75 dma::Dma1Peripheral::SPI3_TX,
76 dma::Dma1Peripheral::SPI3_RX,
77 ),
78 tim2: crate::tim2::Tim2::new(clocks),
79 usart1: crate::usart::Usart::new_usart1(clocks),
80 usart2: crate::usart::Usart::new_usart2(clocks),
81 usart3: crate::usart::Usart::new_usart3(clocks),
82 }
83 }
84
85 pub fn setup_circular_deps(&'static self) {
87 self.clocks.set_flash(&self.flash);
88 self.gpio_ports.setup_circular_deps();
89
90 kernel::deferred_call::DeferredCallClient::register(&self.usart1);
93 kernel::deferred_call::DeferredCallClient::register(&self.usart2);
94 kernel::deferred_call::DeferredCallClient::register(&self.usart3);
95 kernel::deferred_call::DeferredCallClient::register(&self.fsmc);
96 }
97}
98
99impl<ChipSpecs: ChipSpecsTrait> InterruptService for Stm32f4xxDefaultPeripherals<'_, ChipSpecs> {
100 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
101 match interrupt {
102 nvic::DMA1_Stream1 => self.dma1_streams
103 [dma::Dma1Peripheral::USART3_RX.get_stream_idx()]
104 .handle_interrupt(),
105 nvic::DMA1_Stream2 => {
106 self.dma1_streams[dma::Dma1Peripheral::SPI3_RX.get_stream_idx()].handle_interrupt()
107 }
108 nvic::DMA1_Stream3 => self.dma1_streams
109 [dma::Dma1Peripheral::USART3_TX.get_stream_idx()]
110 .handle_interrupt(),
111 nvic::DMA1_Stream5 => self.dma1_streams
112 [dma::Dma1Peripheral::USART2_RX.get_stream_idx()]
113 .handle_interrupt(),
114 nvic::DMA1_Stream6 => self.dma1_streams
115 [dma::Dma1Peripheral::USART2_TX.get_stream_idx()]
116 .handle_interrupt(),
117 nvic::DMA1_Stream7 => {
118 self.dma1_streams[dma::Dma1Peripheral::SPI3_TX.get_stream_idx()].handle_interrupt()
119 }
120
121 nvic::DMA2_Stream5 => self.dma2_streams
122 [dma::Dma2Peripheral::USART1_RX.get_stream_idx()]
123 .handle_interrupt(),
124 nvic::DMA2_Stream7 => self.dma2_streams
125 [dma::Dma2Peripheral::USART1_TX.get_stream_idx()]
126 .handle_interrupt(),
127
128 nvic::USART1 => self.usart1.handle_interrupt(),
129 nvic::USART2 => self.usart2.handle_interrupt(),
130 nvic::USART3 => self.usart3.handle_interrupt(),
131
132 nvic::ADC => self.adc1.handle_interrupt(),
133
134 nvic::I2C1_EV => self.i2c1.handle_event(),
135 nvic::I2C1_ER => self.i2c1.handle_error(),
136
137 nvic::SPI3 => self.spi3.handle_interrupt(),
138
139 nvic::EXTI0 => self.exti.handle_interrupt(),
140 nvic::EXTI1 => self.exti.handle_interrupt(),
141 nvic::EXTI2 => self.exti.handle_interrupt(),
142 nvic::EXTI3 => self.exti.handle_interrupt(),
143 nvic::EXTI4 => self.exti.handle_interrupt(),
144 nvic::EXTI9_5 => self.exti.handle_interrupt(),
145 nvic::EXTI15_10 => self.exti.handle_interrupt(),
146
147 nvic::TIM2 => self.tim2.handle_interrupt(),
148
149 _ => return false,
150 }
151 true
152 }
153}
154
155impl<'a, I: InterruptService + 'a> Stm32f4xx<'a, I> {
156 pub unsafe fn new(interrupt_service: &'a I) -> Self {
157 Self {
158 mpu: cortexm4f::mpu::MPU::new(),
159 userspace_kernel_boundary: cortexm4f::syscall::SysCall::new(),
160 interrupt_service,
161 }
162 }
163}
164
165impl<'a, I: InterruptService + 'a> Chip for Stm32f4xx<'a, I> {
166 type MPU = cortexm4f::mpu::MPU;
167 type UserspaceKernelBoundary = cortexm4f::syscall::SysCall;
168
169 fn service_pending_interrupts(&self) {
170 unsafe {
171 loop {
172 if let Some(interrupt) = cortexm4f::nvic::next_pending() {
173 if !self.interrupt_service.service_interrupt(interrupt) {
174 panic!("unhandled interrupt {}", interrupt);
175 }
176
177 let n = cortexm4f::nvic::Nvic::new(interrupt);
178 n.clear_pending();
179 n.enable();
180 } else {
181 break;
182 }
183 }
184 }
185 }
186
187 fn has_pending_interrupts(&self) -> bool {
188 unsafe { cortexm4f::nvic::has_pending() }
189 }
190
191 fn mpu(&self) -> &cortexm4f::mpu::MPU {
192 &self.mpu
193 }
194
195 fn userspace_kernel_boundary(&self) -> &cortexm4f::syscall::SysCall {
196 &self.userspace_kernel_boundary
197 }
198
199 fn sleep(&self) {
200 unsafe {
201 cortexm4f::scb::unset_sleepdeep();
202 cortexm4f::support::wfi();
203 }
204 }
205
206 unsafe fn atomic<F, R>(&self, f: F) -> R
207 where
208 F: FnOnce() -> R,
209 {
210 cortexm4f::support::atomic(f)
211 }
212
213 unsafe fn print_state(&self, write: &mut dyn Write) {
214 CortexM4F::print_cortexm_state(write);
215 }
216}