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