1use 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
31pub 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 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}