1#![no_std]
2#![deny(nonstandard_style)]
3#![deny(rust_2018_idioms)]
4
5pub use atsamd_hal as hal;
23pub use hal::pac;
24
25use hal::bsp_pins;
26use hal::clock::GenericClockController;
27use hal::sercom::v2::spi;
28use hal::sercom::v2::uart::{self, BaudMode, Oversampling};
29use hal::sercom::v2::{Sercom0, Sercom2};
30use hal::sercom::I2CMaster1;
31use hal::time::Hertz;
32
33#[cfg(feature = "rt")]
34pub use cortex_m_rt::entry;
35
36#[cfg(feature = "usb")]
37use hal::usb::UsbBus;
38#[cfg(feature = "usb")]
39use usb_device::bus::UsbBusAllocator;
40
41bsp_pins! {
42 PA02 {
44 name: a0
45 aliases: {
46 Reset: A0Reset
47 }
48 }
49 PA03 {
50 name: a1
51 aliases: {
52 Reset: A1Reset
53 }
54 }
55 PA04 {
56 name: a2
57 aliases: {
58 Reset: A2Reset
59 }
60 }
61 PA05 {
62 name: a3
63 aliases: {
64 Reset: A3Reset
65 }
66 }
67
68 PA06 {
70 name: tx
71 aliases: {
72 AlternateD: UartTx,
73 Reset: UartTxReset
74 }
75 },
76 PA07 {
77 name: rx
78 aliases: {
79 AlternateD: UartRx,
80 Reset: UartRxReset
81 }
82 }
83
84 PA09 {
86 name: miso
87 aliases: {
88 AlternateD: SpiMiso,
89 Reset: MisoReset
90 }
91 }
92 PA10 {
93 name: mosi
94 aliases: {
95 AlternateD: SpiMosi,
96 Reset: MosiReset
97 }
98 }
99 PA11 {
100 name: sclk
101 aliases: {
102 AlternateD: SpiSck,
103 Reset: SckReset
104 }
105 }
106
107 PA16 {
109 name: sda
110 aliases: {
111 AlternateC: I2cSda,
112 Reset: I2cSdaReset
113 }
114 }
115 PA17 {
116 name: scl
117 aliases: {
118 AlternateC: I2cScl,
119 Reset: I2cSclReset
120 }
121 }
122
123 PA15 {
125 name: neopixel_power
126 aliases: {
127 PushPullOutput: NeopixelPower,
128 Reset: NeopixelPowerReset
129 }
130 }
131 PA18 {
132 name: neopixel_data
133 aliases: {
134 PushPullOutput: NeopixelData,
135 Reset: NeopixelDataReset
136 }
137 }
138
139 PA24 {
141 name: usb_dm,
142 aliases: {
143 AlternateG: UsbDm,
144 Reset: UsbDmReset
145 }
146 }
147 PA25 {
148 name: usb_dp,
149 aliases: {
150 AlternateG: UsbDp,
151 Reset: UsbDpReset
152 }
153 }
154
155 PA08 {
157 name: flash_cs
158 aliases: {
159 PushPullOutput: FlashCs,
160 Reset: FlashCsReset
161 }
162 }
163 PA19 {
164 name: flash_miso
165 aliases: {
166 AlternateD: FlashMiso,
167 Reset: FlashMisoReset
168 }
169 }
170 PA22 {
171 name: flash_mosi
172 aliases: {
173 AlternateC: FlashMosi,
174 Reset: FlashMosiReset
175 }
176 }
177 PA23 {
178 name: flash_sclk
179 aliases: {
180 AlternateC: FlashSck,
181 Reset: FlashSckReset
182 }
183 }
184}
185
186impl Pins {
187 pub fn split(self) -> Sets {
189 let analog = Analog {
190 a0: self.a0,
191 a1: self.a1,
192 a2: self.a2,
193 a3: self.a3,
194 };
195 let uart = Uart {
196 tx: self.tx,
197 rx: self.rx,
198 };
199 let spi = Spi {
200 miso: self.miso,
201 mosi: self.mosi,
202 sclk: self.sclk,
203 };
204 let i2c = I2c {
205 sda: self.sda,
206 scl: self.scl,
207 };
208 let neopixel = Neopixel {
209 power: self.neopixel_power,
210 data: self.neopixel_data,
211 };
212 let usb = Usb {
213 dm: self.usb_dm,
214 dp: self.usb_dp,
215 };
216 Sets {
217 analog,
218 uart,
219 spi,
220 i2c,
221 neopixel,
222 usb,
223 }
224 }
225}
226
227pub struct Sets {
229 pub analog: Analog,
231 pub uart: Uart,
233 pub spi: Spi,
235 pub i2c: I2c,
237 pub neopixel: Neopixel,
239 pub usb: Usb,
241}
242
243pub struct Analog {
246 pub a0: A0Reset,
248 pub a1: A1Reset,
250 pub a2: A2Reset,
252 pub a3: A3Reset,
254}
255
256pub struct Uart {
258 pub tx: UartTxReset,
260 pub rx: UartRxReset,
262}
263
264pub type UartPads = uart::Pads<Sercom0, UartRx, UartTx>;
266
267pub type UartConfig = uart::Uart<uart::Config<UartPads>, uart::Duplex>;
269
270impl Uart {
271 pub fn init(
273 self,
274 clocks: &mut GenericClockController,
275 freq: impl Into<Hertz>,
276 sercom0: pac::SERCOM0,
277 pm: &mut pac::PM,
278 ) -> UartConfig {
279 let gclk0 = clocks.gclk0();
280 let clock = &clocks.sercom0_core(&gclk0).unwrap();
281 let rx: UartRx = self.rx.into();
282 let tx: UartTx = self.tx.into();
283 let pads = uart::Pads::default().rx(rx).tx(tx);
284 uart::Config::new(pm, sercom0, pads, clock.freq())
285 .baud(freq.into(), BaudMode::Fractional(Oversampling::Bits16))
286 .enable()
287 }
288}
289
290pub struct Spi {
292 pub miso: MisoReset,
294 pub mosi: MosiReset,
296 pub sclk: SckReset,
298}
299
300type SpiPads = spi::Pads<Sercom2, SpiMiso, SpiMosi, SpiSck>;
301
302pub type SpiConfig = spi::Spi<spi::Config<SpiPads>, spi::Duplex>;
304
305impl Spi {
306 pub fn init(
309 self,
310 clocks: &mut GenericClockController,
311 baud: impl Into<Hertz>,
312 sercom2: pac::SERCOM2,
313 pm: &mut pac::PM,
314 ) -> SpiConfig {
315 let gclk0 = clocks.gclk0();
316 let clock = clocks.sercom2_core(&gclk0).unwrap();
317 let pads = spi::Pads::default()
318 .data_in(self.miso)
319 .data_out(self.mosi)
320 .sclk(self.sclk);
321 spi::Config::new(pm, sercom2, pads, clock.freq())
322 .spi_mode(spi::MODE_0)
323 .baud(baud)
324 .enable()
325 }
326}
327
328pub struct I2c {
330 pub sda: I2cSdaReset,
332 pub scl: I2cSclReset,
334}
335
336impl I2c {
337 pub fn init(
339 self,
340 clocks: &mut GenericClockController,
341 freq: impl Into<Hertz>,
342 sercom1: pac::SERCOM1,
343 pm: &mut pac::PM,
344 ) -> I2CMaster1<I2cSda, I2cScl> {
345 let gclk0 = clocks.gclk0();
346 let clock = &clocks.sercom1_core(&gclk0).unwrap();
347 I2CMaster1::new(
348 clock,
349 freq.into(),
350 sercom1,
351 pm,
352 self.sda.into(),
353 self.scl.into(),
354 )
355 }
356}
357
358pub struct Neopixel {
360 pub power: NeopixelPowerReset,
363 pub data: NeopixelDataReset,
365}
366
367pub struct Usb {
369 pub dm: UsbDmReset,
371 pub dp: UsbDpReset,
373}
374
375impl Usb {
376 #[cfg(feature = "usb")]
378 pub fn init(
379 self,
380 usb: pac::USB,
381 clocks: &mut GenericClockController,
382 pm: &mut pac::PM,
383 ) -> UsbBusAllocator<UsbBus> {
384 let gclk0 = clocks.gclk0();
385 let usb_clock = &clocks.usb(&gclk0).unwrap();
386 let (dm, dp): (UsbDm, UsbDp) = (self.dm.into(), self.dp.into());
387 UsbBusAllocator::new(UsbBus::new(usb_clock, pm, dm, dp, usb))
388 }
389}