1use core::fmt::Write;
7use core::panic;
8
9use cortexm33::{CortexM33, CortexMVariant};
10use kernel::platform::chip::Chip;
11use kernel::platform::chip::InterruptService;
12
13use crate::clocks::Clock;
14use crate::ctimer0::LPCTimer;
15use crate::flexcomm::Flexcomm;
16use crate::gpio::Pins;
17use crate::interrupts;
18use crate::uart::Uart;
19
20#[repr(u8)]
21pub enum Processor {
22 Processor0 = 0,
23 Processor1 = 1,
24}
25
26pub struct Lpc55s69<'a, I: InterruptService + 'a> {
27 mpu: cortexm33::mpu::MPU<8>,
28 userspace_kernel_boundary: cortexm33::syscall::SysCall,
29 interrupt_service: &'a I,
30}
31
32impl<'a, I: InterruptService> Lpc55s69<'a, I> {
33 pub unsafe fn new(interrupt_service: &'a I) -> Self {
34 Self {
35 mpu: cortexm33::mpu::new(),
36 userspace_kernel_boundary: cortexm33::syscall::SysCall::new(),
37 interrupt_service,
38 }
39 }
40}
41
42impl<I: InterruptService> Chip for Lpc55s69<'_, I> {
43 type MPU = cortexm33::mpu::MPU<8>;
44 type UserspaceKernelBoundary = cortexm33::syscall::SysCall;
45 type ThreadIdProvider = cortexm33::thread_id::CortexMThreadIdProvider;
46
47 fn service_pending_interrupts(&self) {
48 unsafe {
49 while let Some(interrupt) = cortexm33::nvic::next_pending() {
50 if !self.interrupt_service.service_interrupt(interrupt) {
51 panic!("unhandled interrupt {}", interrupt);
52 }
53
54 let n = cortexm33::nvic::Nvic::new(interrupt);
55 n.clear_pending();
56 n.enable();
57 }
58 }
59 }
60
61 fn has_pending_interrupts(&self) -> bool {
62 unsafe { cortexm33::nvic::has_pending() }
63 }
64
65 fn mpu(&self) -> &Self::MPU {
66 &self.mpu
67 }
68
69 fn userspace_kernel_boundary(&self) -> &Self::UserspaceKernelBoundary {
70 &self.userspace_kernel_boundary
71 }
72
73 fn sleep(&self) {
74 unsafe {
75 cortexm33::support::wfi();
76 }
77 }
78
79 unsafe fn with_interrupts_disabled<F, R>(&self, f: F) -> R
80 where
81 F: FnOnce() -> R,
82 {
83 cortexm33::support::with_interrupts_disabled(f)
84 }
85
86 unsafe fn print_state(_this: Option<&Self>, writer: &mut dyn Write) {
87 CortexM33::print_cortexm_state(writer);
88 }
89}
90
91pub struct Lpc55s69DefaultPeripheral<'a> {
92 pub pins: Pins<'a>,
93 pub ctimer0: LPCTimer<'a>,
94 pub uart: Uart<'a>,
95}
96
97impl Lpc55s69DefaultPeripheral<'_> {
98 pub fn new(clocks: &'static Clock, flexcomm: &'static Flexcomm) -> Self {
99 Self {
100 pins: Pins::new(),
101 ctimer0: LPCTimer::new(),
102 uart: Uart::new_uart0(clocks, flexcomm),
103 }
104 }
105}
106
107impl InterruptService for Lpc55s69DefaultPeripheral<'_> {
108 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
109 match interrupt {
110 interrupts::GPIO_INT0_IRQ0 => {
111 self.pins.handle_interrupt();
112 true
113 }
114 interrupts::GPIO_INT0_IRQ1 => {
115 self.pins.handle_interrupt();
116 true
117 }
118
119 interrupts::GPIO_INT0_IRQ2 => {
120 self.pins.handle_interrupt();
121 true
122 }
123 interrupts::GPIO_INT0_IRQ3 => {
124 self.pins.handle_interrupt();
125 true
126 }
127 interrupts::GPIO_INT0_IRQ4 => {
128 self.pins.handle_interrupt();
129 true
130 }
131 interrupts::GPIO_INT0_IRQ5 => {
132 self.pins.handle_interrupt();
133 true
134 }
135 interrupts::GPIO_INT0_IRQ6 => {
136 self.pins.handle_interrupt();
137 true
138 }
139 interrupts::GPIO_INT0_IRQ7 => {
140 self.pins.handle_interrupt();
141 true
142 }
143
144 interrupts::CTIMER0 => {
145 self.ctimer0.handle_interrupt();
146 true
147 }
148
149 interrupts::FLEXCOMM0 => {
150 self.uart.handle_interrupt();
151 true
152 }
153
154 _ => true,
155 }
156 }
157}