1use core::fmt::Write;
8use cortexm4f::{CortexM4F, CortexMVariant};
9use kernel::platform::chip::Chip;
10use kernel::platform::chip::InterruptService;
11
12pub struct Apollo3<I: InterruptService + 'static> {
13 mpu: cortexm4f::mpu::MPU,
14 userspace_kernel_boundary: cortexm4f::syscall::SysCall,
15 interrupt_service: &'static I,
16}
17
18impl<I: InterruptService + 'static> Apollo3<I> {
19 pub unsafe fn new(interrupt_service: &'static I) -> Self {
20 Self {
21 mpu: cortexm4f::mpu::new(),
22 userspace_kernel_boundary: cortexm4f::syscall::SysCall::new(),
23 interrupt_service,
24 }
25 }
26}
27
28pub struct Apollo3DefaultPeripherals {
34 pub stimer: crate::stimer::STimer<'static>,
35 pub uart0: crate::uart::Uart<'static>,
36 pub uart1: crate::uart::Uart<'static>,
37 pub gpio_port: crate::gpio::Port<'static>,
38 pub iom0: crate::iom::Iom<'static>,
39 pub iom1: crate::iom::Iom<'static>,
40 pub iom2: crate::iom::Iom<'static>,
41 pub iom3: crate::iom::Iom<'static>,
42 pub iom4: crate::iom::Iom<'static>,
43 pub iom5: crate::iom::Iom<'static>,
44 pub ios: crate::ios::Ios<'static>,
45 pub ble: crate::ble::Ble<'static>,
46 pub flash_ctrl: crate::flashctrl::FlashCtrl<'static>,
47}
48
49impl Apollo3DefaultPeripherals {
50 pub fn new() -> Self {
51 Self {
52 stimer: crate::stimer::STimer::new(),
53 uart0: crate::uart::Uart::new_uart_0(),
54 uart1: crate::uart::Uart::new_uart_1(),
55 gpio_port: crate::gpio::Port::new(),
56 iom0: crate::iom::Iom::new0(),
57 iom1: crate::iom::Iom::new1(),
58 iom2: crate::iom::Iom::new2(),
59 iom3: crate::iom::Iom::new3(),
60 iom4: crate::iom::Iom::new4(),
61 iom5: crate::iom::Iom::new5(),
62 ios: crate::ios::Ios::new(),
63 ble: crate::ble::Ble::new(),
64 flash_ctrl: crate::flashctrl::FlashCtrl::new(),
65 }
66 }
67
68 pub fn init(&'static self) {
69 kernel::deferred_call::DeferredCallClient::register(&self.flash_ctrl);
70 }
71}
72
73impl kernel::platform::chip::InterruptService for Apollo3DefaultPeripherals {
74 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
75 use crate::nvic;
76 match interrupt {
77 nvic::STIMER..=nvic::STIMER_CMPR7 => self.stimer.handle_interrupt(),
78 nvic::UART0 => self.uart0.handle_interrupt(),
79 nvic::UART1 => self.uart1.handle_interrupt(),
80 nvic::GPIO => self.gpio_port.handle_interrupt(),
81 nvic::IOMSTR0 => self.iom0.handle_interrupt(),
82 nvic::IOMSTR1 => self.iom1.handle_interrupt(),
83 nvic::IOMSTR2 => self.iom2.handle_interrupt(),
84 nvic::IOMSTR3 => self.iom3.handle_interrupt(),
85 nvic::IOMSTR4 => self.iom4.handle_interrupt(),
86 nvic::IOMSTR5 => self.iom5.handle_interrupt(),
87 nvic::IOSLAVE | nvic::IOSLAVEACC => self.ios.handle_interrupt(),
88 nvic::BLE => self.ble.handle_interrupt(),
89 _ => return false,
90 }
91 true
92 }
93}
94
95impl<I: InterruptService + 'static> Chip for Apollo3<I> {
96 type MPU = cortexm4f::mpu::MPU;
97 type UserspaceKernelBoundary = cortexm4f::syscall::SysCall;
98
99 fn service_pending_interrupts(&self) {
100 unsafe {
101 while let Some(interrupt) = cortexm4f::nvic::next_pending() {
102 if !self.interrupt_service.service_interrupt(interrupt) {
103 panic!("unhandled interrupt, {}", interrupt);
104 }
105
106 let n = cortexm4f::nvic::Nvic::new(interrupt);
107 n.clear_pending();
108 n.enable();
109 }
110 }
111 }
112
113 fn has_pending_interrupts(&self) -> bool {
114 unsafe { cortexm4f::nvic::has_pending() }
115 }
116
117 fn mpu(&self) -> &cortexm4f::mpu::MPU {
118 &self.mpu
119 }
120
121 fn userspace_kernel_boundary(&self) -> &cortexm4f::syscall::SysCall {
122 &self.userspace_kernel_boundary
123 }
124
125 fn sleep(&self) {
126 unsafe {
127 cortexm4f::scb::set_sleepdeep();
128 cortexm4f::support::wfi();
129 }
130 }
131
132 unsafe fn atomic<F, R>(&self, f: F) -> R
133 where
134 F: FnOnce() -> R,
135 {
136 cortexm4f::support::atomic(f)
137 }
138
139 unsafe fn print_state(&self, write: &mut dyn Write) {
140 CortexM4F::print_cortexm_state(write);
141 }
142}