Skip to main content

lpc55s6x/
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 2025.
4
5//! Chip trait setup.
6use 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}