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