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 fn new(pm: &'static crate::pm::PowerManager, interrupt_service: &'static I) -> Self {
22 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
34pub 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 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}