Skip to main content

sam4l/
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 2022.
4
5//! Interrupt mapping and DMA channel setup.
6
7use crate::pm;
8
9use core::fmt::Write;
10use cortexm4::{CortexM4, CortexMVariant};
11use kernel::platform::chip::{Chip, InterruptService};
12
13pub struct Sam4l<I: InterruptService + 'static> {
14    mpu: cortexm4::mpu::MPU,
15    userspace_kernel_boundary: cortexm4::syscall::SysCall,
16    pub pm: &'static crate::pm::PowerManager,
17    interrupt_service: &'static I,
18}
19
20impl<I: InterruptService + 'static> Sam4l<I> {
21    pub fn new(pm: &'static crate::pm::PowerManager, interrupt_service: &'static I) -> Self {
22        // SAFETY: All SAM4L chips are Cortex-M4 cores with valid MPU hardware.
23        let mpu = unsafe { cortexm4::mpu::new() };
24
25        Self {
26            mpu,
27            userspace_kernel_boundary: cortexm4::syscall::SysCall::new(),
28            pm,
29            interrupt_service,
30        }
31    }
32}
33
34/// This struct, when initialized, instantiates all peripheral drivers for the apollo3.
35///
36/// If a board wishes to use only a subset of these peripherals, this
37/// should not be used or imported, and a modified version should be
38/// constructed manually in main.rs.
39pub struct Sam4lDefaultPeripherals {
40    pub acifc: crate::acifc::Acifc<'static>,
41    pub adc: crate::adc::Adc<'static>,
42    pub aes: crate::aes::Aes<'static>,
43    pub ast: crate::ast::Ast<'static>,
44    pub crccu: crate::crccu::Crccu<'static>,
45    pub dac: crate::dac::Dac,
46    pub dma_channels: [crate::dma::DMAChannel; 16],
47    pub eic: crate::eic::Eic<'static>,
48    pub flash_controller: crate::flashcalw::FLASHCALW,
49    pub gloc: crate::gloc::Gloc,
50    pub pa: crate::gpio::Port<'static>,
51    pub pb: crate::gpio::Port<'static>,
52    pub pc: crate::gpio::Port<'static>,
53    pub i2c0: crate::i2c::I2CHw<'static>,
54    pub i2c1: crate::i2c::I2CHw<'static>,
55    pub i2c2: crate::i2c::I2CHw<'static>,
56    pub i2c3: crate::i2c::I2CHw<'static>,
57    pub spi: crate::spi::SpiHw<'static>,
58    pub trng: crate::trng::Trng<'static>,
59    pub usart0: crate::usart::USART<'static>,
60    pub usart1: crate::usart::USART<'static>,
61    pub usart2: crate::usart::USART<'static>,
62    pub usart3: crate::usart::USART<'static>,
63    pub usbc: crate::usbc::Usbc<'static>,
64}
65
66impl Sam4lDefaultPeripherals {
67    pub fn new(pm: &'static crate::pm::PowerManager) -> Self {
68        use crate::dma::{DMAChannel, DMAChannelNum};
69        Self {
70            acifc: crate::acifc::Acifc::new(),
71            adc: crate::adc::Adc::new(crate::dma::DMAPeripheral::ADCIFE_RX, pm),
72            aes: crate::aes::Aes::new(),
73            ast: crate::ast::Ast::new(),
74            crccu: crate::crccu::Crccu::new(crate::crccu::BASE_ADDRESS),
75            dac: crate::dac::Dac::new(),
76            dma_channels: [
77                DMAChannel::new(DMAChannelNum::DMAChannel00),
78                DMAChannel::new(DMAChannelNum::DMAChannel01),
79                DMAChannel::new(DMAChannelNum::DMAChannel02),
80                DMAChannel::new(DMAChannelNum::DMAChannel03),
81                DMAChannel::new(DMAChannelNum::DMAChannel04),
82                DMAChannel::new(DMAChannelNum::DMAChannel05),
83                DMAChannel::new(DMAChannelNum::DMAChannel06),
84                DMAChannel::new(DMAChannelNum::DMAChannel07),
85                DMAChannel::new(DMAChannelNum::DMAChannel08),
86                DMAChannel::new(DMAChannelNum::DMAChannel09),
87                DMAChannel::new(DMAChannelNum::DMAChannel10),
88                DMAChannel::new(DMAChannelNum::DMAChannel11),
89                DMAChannel::new(DMAChannelNum::DMAChannel12),
90                DMAChannel::new(DMAChannelNum::DMAChannel13),
91                DMAChannel::new(DMAChannelNum::DMAChannel14),
92                DMAChannel::new(DMAChannelNum::DMAChannel15),
93            ],
94            eic: crate::eic::Eic::new(),
95            flash_controller: crate::flashcalw::FLASHCALW::new(
96                crate::pm::HSBClock::FLASHCALW,
97                crate::pm::HSBClock::FLASHCALWP,
98                crate::pm::PBBClock::FLASHCALW,
99            ),
100            gloc: crate::gloc::Gloc::new(),
101            pa: crate::gpio::Port::new_port_a(),
102            pb: crate::gpio::Port::new_port_b(),
103            pc: crate::gpio::Port::new_port_c(),
104            i2c0: crate::i2c::I2CHw::new_i2c0(pm),
105            i2c1: crate::i2c::I2CHw::new_i2c1(pm),
106            i2c2: crate::i2c::I2CHw::new_i2c2(pm),
107            i2c3: crate::i2c::I2CHw::new_i2c3(pm),
108            spi: crate::spi::SpiHw::new(pm),
109            trng: crate::trng::Trng::new(),
110            usart0: crate::usart::USART::new_usart0(pm),
111            usart1: crate::usart::USART::new_usart1(pm),
112            usart2: crate::usart::USART::new_usart2(pm),
113            usart3: crate::usart::USART::new_usart3(pm),
114            usbc: crate::usbc::Usbc::new(pm),
115        }
116    }
117
118    pub fn setup_circular_deps(&'static self) {
119        use crate::dma;
120        self.usart0
121            .set_dma(&self.dma_channels[0], &self.dma_channels[1]);
122        self.dma_channels[0].initialize(&self.usart0, dma::DMAWidth::Width8Bit);
123        self.dma_channels[1].initialize(&self.usart0, dma::DMAWidth::Width8Bit);
124
125        self.usart1
126            .set_dma(&self.dma_channels[2], &self.dma_channels[3]);
127        self.dma_channels[2].initialize(&self.usart1, dma::DMAWidth::Width8Bit);
128        self.dma_channels[3].initialize(&self.usart1, dma::DMAWidth::Width8Bit);
129
130        self.usart2
131            .set_dma(&self.dma_channels[4], &self.dma_channels[5]);
132        self.dma_channels[4].initialize(&self.usart2, dma::DMAWidth::Width8Bit);
133        self.dma_channels[5].initialize(&self.usart2, dma::DMAWidth::Width8Bit);
134
135        self.usart3
136            .set_dma(&self.dma_channels[6], &self.dma_channels[7]);
137        self.dma_channels[6].initialize(&self.usart3, dma::DMAWidth::Width8Bit);
138        self.dma_channels[7].initialize(&self.usart3, dma::DMAWidth::Width8Bit);
139
140        self.spi
141            .set_dma(&self.dma_channels[8], &self.dma_channels[9]);
142        self.dma_channels[8].initialize(&self.spi, dma::DMAWidth::Width8Bit);
143        self.dma_channels[9].initialize(&self.spi, dma::DMAWidth::Width8Bit);
144
145        self.i2c0.set_dma(&self.dma_channels[10]);
146        self.dma_channels[10].initialize(&self.i2c0, dma::DMAWidth::Width8Bit);
147
148        self.i2c1.set_dma(&self.dma_channels[11]);
149        self.dma_channels[11].initialize(&self.i2c1, dma::DMAWidth::Width8Bit);
150
151        self.i2c2.set_dma(&self.dma_channels[12]);
152        self.dma_channels[12].initialize(&self.i2c2, dma::DMAWidth::Width8Bit);
153
154        self.adc.set_dma(&self.dma_channels[13]);
155        self.dma_channels[13].initialize(&self.adc, dma::DMAWidth::Width16Bit);
156
157        // REGISTER ALL PERIPHERALS WITH DEFERRED CALLS
158        kernel::deferred_call::DeferredCallClient::register(&self.crccu);
159        kernel::deferred_call::DeferredCallClient::register(&self.flash_controller);
160        kernel::deferred_call::DeferredCallClient::register(&self.usart0);
161        kernel::deferred_call::DeferredCallClient::register(&self.usart1);
162        kernel::deferred_call::DeferredCallClient::register(&self.usart2);
163        kernel::deferred_call::DeferredCallClient::register(&self.usart3);
164    }
165}
166impl InterruptService for Sam4lDefaultPeripherals {
167    fn service_interrupt(&self, interrupt: u32) -> bool {
168        use crate::nvic;
169        match interrupt {
170            nvic::ASTALARM => self.ast.handle_interrupt(),
171
172            nvic::USART0 => self.usart0.handle_interrupt(),
173            nvic::USART1 => self.usart1.handle_interrupt(),
174            nvic::USART2 => self.usart2.handle_interrupt(),
175            nvic::USART3 => self.usart3.handle_interrupt(),
176
177            nvic::PDCA0 => self.dma_channels[0].handle_interrupt(),
178            nvic::PDCA1 => self.dma_channels[1].handle_interrupt(),
179            nvic::PDCA2 => self.dma_channels[2].handle_interrupt(),
180            nvic::PDCA3 => self.dma_channels[3].handle_interrupt(),
181            nvic::PDCA4 => self.dma_channels[4].handle_interrupt(),
182            nvic::PDCA5 => self.dma_channels[5].handle_interrupt(),
183            nvic::PDCA6 => self.dma_channels[6].handle_interrupt(),
184            nvic::PDCA7 => self.dma_channels[7].handle_interrupt(),
185            nvic::PDCA8 => self.dma_channels[8].handle_interrupt(),
186            nvic::PDCA9 => self.dma_channels[9].handle_interrupt(),
187            nvic::PDCA10 => self.dma_channels[10].handle_interrupt(),
188            nvic::PDCA11 => self.dma_channels[11].handle_interrupt(),
189            nvic::PDCA12 => self.dma_channels[12].handle_interrupt(),
190            nvic::PDCA13 => self.dma_channels[13].handle_interrupt(),
191            nvic::PDCA14 => self.dma_channels[14].handle_interrupt(),
192            nvic::PDCA15 => self.dma_channels[15].handle_interrupt(),
193
194            nvic::CRCCU => self.crccu.handle_interrupt(),
195            nvic::USBC => self.usbc.handle_interrupt(),
196
197            nvic::GPIO0 => self.pa.handle_interrupt(),
198            nvic::GPIO1 => self.pa.handle_interrupt(),
199            nvic::GPIO2 => self.pa.handle_interrupt(),
200            nvic::GPIO3 => self.pa.handle_interrupt(),
201            nvic::GPIO4 => self.pb.handle_interrupt(),
202            nvic::GPIO5 => self.pb.handle_interrupt(),
203            nvic::GPIO6 => self.pb.handle_interrupt(),
204            nvic::GPIO7 => self.pb.handle_interrupt(),
205            nvic::GPIO8 => self.pc.handle_interrupt(),
206            nvic::GPIO9 => self.pc.handle_interrupt(),
207            nvic::GPIO10 => self.pc.handle_interrupt(),
208            nvic::GPIO11 => self.pc.handle_interrupt(),
209
210            nvic::SPI => self.spi.handle_interrupt(),
211
212            nvic::TWIM0 => self.i2c0.handle_interrupt(),
213            nvic::TWIM1 => self.i2c1.handle_interrupt(),
214            nvic::TWIM2 => self.i2c2.handle_interrupt(),
215            nvic::TWIM3 => self.i2c3.handle_interrupt(),
216            nvic::TWIS0 => self.i2c0.handle_slave_interrupt(),
217            nvic::TWIS1 => self.i2c1.handle_slave_interrupt(),
218
219            nvic::HFLASHC => self.flash_controller.handle_interrupt(),
220            nvic::ADCIFE => self.adc.handle_interrupt(),
221            nvic::DACC => self.dac.handle_interrupt(),
222            nvic::ACIFC => self.acifc.handle_interrupt(),
223
224            nvic::TRNG => self.trng.handle_interrupt(),
225            nvic::AESA => self.aes.handle_interrupt(),
226
227            nvic::EIC1 => self.eic.handle_interrupt(&crate::eic::Line::Ext1),
228            nvic::EIC2 => self.eic.handle_interrupt(&crate::eic::Line::Ext2),
229            nvic::EIC3 => self.eic.handle_interrupt(&crate::eic::Line::Ext3),
230            nvic::EIC4 => self.eic.handle_interrupt(&crate::eic::Line::Ext4),
231            nvic::EIC5 => self.eic.handle_interrupt(&crate::eic::Line::Ext5),
232            nvic::EIC6 => self.eic.handle_interrupt(&crate::eic::Line::Ext6),
233            nvic::EIC7 => self.eic.handle_interrupt(&crate::eic::Line::Ext7),
234            nvic::EIC8 => self.eic.handle_interrupt(&crate::eic::Line::Ext8),
235            _ => return false,
236        }
237        true
238    }
239}
240
241impl<I: InterruptService + 'static> Chip for Sam4l<I> {
242    type MPU = cortexm4::mpu::MPU;
243    type UserspaceKernelBoundary = cortexm4::syscall::SysCall;
244    type ThreadIdProvider = cortexm4::thread_id::CortexMThreadIdProvider;
245
246    fn init() {
247        cortexm4::nvic::disable_all();
248        cortexm4::nvic::clear_all_pending();
249        cortexm4::nvic::enable_all();
250    }
251
252    fn service_pending_interrupts(&self) {
253        while let Some(interrupt) = cortexm4::nvic::next_pending() {
254            match self.interrupt_service.service_interrupt(interrupt) {
255                true => {}
256                false => panic!("unhandled interrupt"),
257            }
258            let n = cortexm4::nvic::Nvic::new(interrupt);
259            n.clear_pending();
260            n.enable();
261        }
262    }
263
264    fn has_pending_interrupts(&self) -> bool {
265        cortexm4::nvic::has_pending()
266    }
267
268    fn mpu(&self) -> &cortexm4::mpu::MPU {
269        &self.mpu
270    }
271
272    fn userspace_kernel_boundary(&self) -> &cortexm4::syscall::SysCall {
273        &self.userspace_kernel_boundary
274    }
275
276    fn sleep(&self) {
277        let cap = kernel::create_capability!(kernel::capabilities::CpuStateControlCapability);
278        if pm::deep_sleep_ready() {
279            cortexm4::scb::set_sleepdeep(&cap);
280        } else {
281            cortexm4::scb::unset_sleepdeep(&cap);
282        }
283        cortexm4::support::wfi(&cap);
284    }
285
286    fn with_interrupts_disabled<F, R>(&self, f: F) -> R
287    where
288        F: FnOnce() -> R,
289    {
290        cortexm4::support::with_interrupts_disabled(f)
291    }
292
293    unsafe fn print_state(_this: Option<&Self>, writer: &mut dyn Write) {
294        CortexM4::print_cortexm_state(writer);
295    }
296}