1use core::fmt::Write;
8use cortexm7::{CortexM7, CortexMVariant};
9use kernel::debug;
10use kernel::platform::chip::{Chip, InterruptService};
11
12use crate::nvic;
13
14pub struct Imxrt10xx<I: InterruptService + 'static> {
15 mpu: cortexm7::mpu::MPU,
16 userspace_kernel_boundary: cortexm7::syscall::SysCall,
17 interrupt_service: &'static I,
18}
19
20impl<I: InterruptService + 'static> Imxrt10xx<I> {
21 pub unsafe fn new(interrupt_service: &'static I) -> Self {
22 Imxrt10xx {
23 mpu: cortexm7::mpu::new(),
24 userspace_kernel_boundary: cortexm7::syscall::SysCall::new(),
25 interrupt_service,
26 }
27 }
28}
29
30pub struct Imxrt10xxDefaultPeripherals {
31 pub iomuxc: crate::iomuxc::Iomuxc,
32 pub iomuxc_snvs: crate::iomuxc_snvs::IomuxcSnvs,
33 pub ccm: &'static crate::ccm::Ccm,
34 pub dcdc: crate::dcdc::Dcdc<'static>,
35 pub dma: crate::dma::Dma<'static>,
36 pub ccm_analog: crate::ccm_analog::CcmAnalog,
37 pub ports: crate::gpio::Ports<'static>,
38 pub lpi2c1: crate::lpi2c::Lpi2c<'static>,
39 pub lpuart1: crate::lpuart::Lpuart<'static>,
40 pub lpuart2: crate::lpuart::Lpuart<'static>,
41 pub gpt1: crate::gpt::Gpt1<'static>,
42 pub gpt2: crate::gpt::Gpt2<'static>,
43}
44
45impl Imxrt10xxDefaultPeripherals {
46 pub fn new(ccm: &'static crate::ccm::Ccm) -> Self {
47 Self {
48 iomuxc: crate::iomuxc::Iomuxc::new(),
49 iomuxc_snvs: crate::iomuxc_snvs::IomuxcSnvs::new(),
50 ccm,
51 dcdc: crate::dcdc::Dcdc::new(ccm),
52 dma: crate::dma::Dma::new(ccm),
53 ccm_analog: crate::ccm_analog::CcmAnalog::new(),
54 ports: crate::gpio::Ports::new(ccm),
55 lpi2c1: crate::lpi2c::Lpi2c::new_lpi2c1(ccm),
56 lpuart1: crate::lpuart::Lpuart::new_lpuart1(ccm),
57 lpuart2: crate::lpuart::Lpuart::new_lpuart2(ccm),
58 gpt1: crate::gpt::Gpt1::new_gpt1(ccm),
59 gpt2: crate::gpt::Gpt2::new_gpt2(ccm),
60 }
61 }
62}
63
64impl InterruptService for Imxrt10xxDefaultPeripherals {
65 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
66 match interrupt {
67 nvic::LPUART1 => self.lpuart1.handle_interrupt(),
68 nvic::LPUART2 => self.lpuart2.handle_interrupt(),
69 nvic::LPI2C1 => self.lpi2c1.handle_event(),
70 nvic::GPT1 => self.gpt1.handle_interrupt(),
71 nvic::GPT2 => self.gpt2.handle_interrupt(),
72 nvic::GPIO1_1 => self.ports.gpio1.handle_interrupt(),
73 nvic::GPIO1_2 => self.ports.gpio1.handle_interrupt(),
74 nvic::GPIO2_1 => self.ports.gpio2.handle_interrupt(),
75 nvic::GPIO2_2 => self.ports.gpio2.handle_interrupt(),
76 nvic::GPIO3_1 => self.ports.gpio3.handle_interrupt(),
77 nvic::GPIO3_2 => self.ports.gpio3.handle_interrupt(),
78 nvic::GPIO4_1 => self.ports.gpio4.handle_interrupt(),
79 nvic::GPIO4_2 => self.ports.gpio4.handle_interrupt(),
80 nvic::GPIO5_1 => self.ports.gpio5.handle_interrupt(),
81 nvic::GPIO5_2 => self.ports.gpio5.handle_interrupt(),
82 nvic::SNVS_LP_WRAPPER => debug!("Interrupt: SNVS_LP_WRAPPER"),
83 nvic::DMA0_16..=nvic::DMA15_31 => {
84 let low = (interrupt - nvic::DMA0_16) as usize;
85 let high = low + 16;
86 for channel in [&self.dma.channels[low], &self.dma.channels[high]] {
87 if channel.is_interrupt() | channel.is_error() {
88 channel.handle_interrupt();
89 }
90 }
91 }
92 nvic::DMA_ERROR => {
93 while let Some(channel) = self.dma.error_channel() {
94 channel.handle_interrupt();
95 }
96 }
97 _ => {
98 return false;
99 }
100 }
101 true
102 }
103}
104
105impl<I: InterruptService + 'static> Chip for Imxrt10xx<I> {
106 type MPU = cortexm7::mpu::MPU;
107 type UserspaceKernelBoundary = cortexm7::syscall::SysCall;
108
109 fn service_pending_interrupts(&self) {
110 unsafe {
111 while let Some(interrupt) = cortexm7::nvic::next_pending() {
112 let handled = self.interrupt_service.service_interrupt(interrupt);
113 assert!(handled, "Unhandled interrupt number {}", interrupt);
114 let n = cortexm7::nvic::Nvic::new(interrupt);
115 n.clear_pending();
116 n.enable();
117 }
118 }
119 }
120
121 fn has_pending_interrupts(&self) -> bool {
122 unsafe { cortexm7::nvic::has_pending() }
123 }
124
125 fn mpu(&self) -> &cortexm7::mpu::MPU {
126 &self.mpu
127 }
128
129 fn userspace_kernel_boundary(&self) -> &cortexm7::syscall::SysCall {
130 &self.userspace_kernel_boundary
131 }
132
133 fn sleep(&self) {
134 unsafe {
135 cortexm7::scb::unset_sleepdeep();
136 cortexm7::support::wfi();
137 }
138 }
139
140 unsafe fn with_interrupts_disabled<F, R>(&self, f: F) -> R
141 where
142 F: FnOnce() -> R,
143 {
144 cortexm7::support::with_interrupts_disabled(f)
145 }
146
147 unsafe fn print_state(&self, write: &mut dyn Write) {
148 CortexM7::print_cortexm_state(write);
149 }
150}