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::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 loop {
102 if let Some(interrupt) = cortexm4f::nvic::next_pending() {
103 if !self.interrupt_service.service_interrupt(interrupt) {
104 panic!("unhandled interrupt, {}", interrupt);
105 }
106
107 let n = cortexm4f::nvic::Nvic::new(interrupt);
108 n.clear_pending();
109 n.enable();
110 } else {
111 break;
112 }
113 }
114 }
115 }
116
117 fn has_pending_interrupts(&self) -> bool {
118 unsafe { cortexm4f::nvic::has_pending() }
119 }
120
121 fn mpu(&self) -> &cortexm4f::mpu::MPU {
122 &self.mpu
123 }
124
125 fn userspace_kernel_boundary(&self) -> &cortexm4f::syscall::SysCall {
126 &self.userspace_kernel_boundary
127 }
128
129 fn sleep(&self) {
130 unsafe {
131 cortexm4f::scb::set_sleepdeep();
132 cortexm4f::support::wfi();
133 }
134 }
135
136 unsafe fn atomic<F, R>(&self, f: F) -> R
137 where
138 F: FnOnce() -> R,
139 {
140 cortexm4f::support::atomic(f)
141 }
142
143 unsafe fn print_state(&self, write: &mut dyn Write) {
144 CortexM4F::print_cortexm_state(write);
145 }
146}