stm32f303xc/
chip.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Chip trait setup.
6
7use 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    // Setup any circular dependencies and register deferred calls
54    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}