]> patrickod personal git archive - tincan.git/blob - rs-lorachat/src/lib.rs
import 0.12 (?) usb_echo wholesale
[tincan.git] / rs-lorachat / src / lib.rs
1 #![no_std]
2
3 extern crate atsamd_hal as hal;
4
5 #[cfg(feature = "rt")]
6 extern crate cortex_m_rt;
7 #[cfg(feature = "rt")]
8 pub use cortex_m_rt::entry;
9
10 use hal::prelude::*;
11 use hal::*;
12
13 pub use hal::common::*;
14 pub use hal::samd21::*;
15 pub use hal::target_device as pac;
16
17 use gpio::{Floating, Input, PfC, Port};
18 use hal::clock::GenericClockController;
19 use hal::sercom::{I2CMaster3, PadPin, SPIMaster4, UART0};
20 use hal::time::Hertz;
21
22 #[cfg(feature = "usb")]
23 use hal::usb::usb_device::bus::UsbBusAllocator;
24 #[cfg(feature = "usb")]
25 pub use hal::usb::UsbBus;
26
27 define_pins!(
28     /// Maps the pins to their arduino names and
29     /// the numbers printed on the board.
30     struct Pins,
31     target_device: target_device,
32
33     /// AREF pin - has 1uF capacitor to ground
34     pin aref = a3,
35
36     /// Analog pin 0.  Can act as a true analog output
37     /// as it has a DAC (which is not currently supported
38     /// by this hal) as well as input.
39     pin a0 = a2,
40
41     /// Analog Pin 1
42     pin a1 = b8,
43     /// Analog Pin 2
44     pin a2 = b9,
45     /// Analog Pin 3
46     pin a3 = a4,
47     /// Analog Pin 4
48     pin a4 = a5,
49     /// Analog Pin 5
50     pin a5 = b2,
51
52     /// Pin 0, rx
53     pin d0 = a11,
54     /// Pin 1, tx
55     pin d1 = a10,
56     /// Pin 5, PWM capable
57     pin d5 = a15,
58     /// Pin 6, PWM capable
59     pin d6 = a20,
60     /// Pin 9, PWM capable.  Also analog input (A7)
61     pin d9 = a7,
62     /// Pin 10, PWM capable
63     pin d10 = a18,
64     /// Pin 11, PWM capable
65     pin d11 = a16,
66     /// Pin 12, PWM capable
67     pin d12 = a19,
68     /// Pin 13, which is also attached to
69     /// the red LED.  PWM capable.
70     pin d13 = a17,
71
72     /// The I2C data line
73     pin sda = a22,
74     /// The I2C clock line
75     pin scl = a23,
76
77     /// The SPI SCK
78     pin sck = b11,
79     /// The SPI MOSI
80     pin mosi = b10,
81     /// The SPI MISO
82     pin miso = a12,
83
84     /// The USB D- pad
85     pin usb_dm = a24,
86     /// The USB D+ pad
87     pin usb_dp = a25,
88
89     /// SPI chip select for the RFM module
90     #[cfg(feature = "rfm")]
91     pin rfm_cs = a6,
92
93     /// Reset for the RFM module
94     #[cfg(feature = "rfm")]
95     pin rfm_reset = a8,
96
97     /// Interrupt from the RFM module
98     #[cfg(feature = "rfm")]
99     pin rfm_irq = a9,
100
101     /// Neopixel data
102     #[cfg(feature = "express")]
103     pin neopixel = a6,
104
105     /// SPI clock for the external flash
106     #[cfg(feature = "express")]
107     pin flash_sck = a9,
108
109     /// SPI MOSI for the external flash
110     #[cfg(feature = "express")]
111     pin flash_mosi = a8,
112
113     /// SPI MISO for the external flash
114     #[cfg(feature = "express")]
115     pin flash_miso = a14,
116
117     /// SPI chip select for the external flash
118     #[cfg(feature = "express")]
119     pin flash_cs = a13,
120 );
121
122 /// Convenience for setting up the labelled SPI peripheral.
123 /// This powers up SERCOM4 and configures it for use as an
124 /// SPI Master in SPI Mode 0.
125 pub fn spi_master<F: Into<Hertz>>(
126     clocks: &mut GenericClockController,
127     bus_speed: F,
128     sercom4: pac::SERCOM4,
129     pm: &mut pac::PM,
130     sck: gpio::Pb11<Input<Floating>>,
131     mosi: gpio::Pb10<Input<Floating>>,
132     miso: gpio::Pa12<Input<Floating>>,
133     port: &mut Port,
134 ) -> SPIMaster4<
135     hal::sercom::Sercom4Pad0<gpio::Pa12<gpio::PfD>>,
136     hal::sercom::Sercom4Pad2<gpio::Pb10<gpio::PfD>>,
137     hal::sercom::Sercom4Pad3<gpio::Pb11<gpio::PfD>>,
138 > {
139     let gclk0 = clocks.gclk0();
140     SPIMaster4::new(
141         &clocks.sercom4_core(&gclk0).unwrap(),
142         bus_speed.into(),
143         hal::hal::spi::Mode {
144             phase: hal::hal::spi::Phase::CaptureOnFirstTransition,
145             polarity: hal::hal::spi::Polarity::IdleLow,
146         },
147         sercom4,
148         pm,
149         (miso.into_pad(port), mosi.into_pad(port), sck.into_pad(port)),
150     )
151 }
152
153 /// Convenience for setting up the labelled SDA, SCL pins to
154 /// operate as an I2C master running at the specified frequency.
155 pub fn i2c_master<F: Into<Hertz>>(
156     clocks: &mut GenericClockController,
157     bus_speed: F,
158     sercom3: pac::SERCOM3,
159     pm: &mut pac::PM,
160     sda: gpio::Pa22<Input<Floating>>,
161     scl: gpio::Pa23<Input<Floating>>,
162     port: &mut Port,
163 ) -> I2CMaster3<
164     hal::sercom::Sercom3Pad0<hal::gpio::Pa22<hal::gpio::PfC>>,
165     hal::sercom::Sercom3Pad1<hal::gpio::Pa23<hal::gpio::PfC>>,
166 > {
167     let gclk0 = clocks.gclk0();
168     I2CMaster3::new(
169         &clocks.sercom3_core(&gclk0).unwrap(),
170         bus_speed.into(),
171         sercom3,
172         pm,
173         sda.into_pad(port),
174         scl.into_pad(port),
175     )
176 }
177
178 /// Convenience for setting up the labelled RX, TX pins to
179 /// operate as a UART device running at the specified baud.
180 pub fn uart<F: Into<Hertz>>(
181     clocks: &mut GenericClockController,
182     baud: F,
183     sercom0: pac::SERCOM0,
184     pm: &mut pac::PM,
185     d0: gpio::Pa11<Input<Floating>>,
186     d1: gpio::Pa10<Input<Floating>>,
187     port: &mut Port,
188 ) -> UART0<
189     hal::sercom::Sercom0Pad3<gpio::Pa11<PfC>>,
190     hal::sercom::Sercom0Pad2<gpio::Pa10<PfC>>,
191     (),
192     (),
193 > {
194     let gclk0 = clocks.gclk0();
195
196     UART0::new(
197         &clocks.sercom0_core(&gclk0).unwrap(),
198         baud.into(),
199         sercom0,
200         pm,
201         (d0.into_pad(port), d1.into_pad(port)),
202     )
203 }
204
205 #[cfg(feature = "usb")]
206 pub fn usb_allocator(
207     usb: pac::USB,
208     clocks: &mut GenericClockController,
209     pm: &mut pac::PM,
210     dm: gpio::Pa24<Input<Floating>>,
211     dp: gpio::Pa25<Input<Floating>>,
212     port: &mut Port,
213 ) -> UsbBusAllocator<UsbBus> {
214     use gpio::IntoFunction;
215
216     let gclk0 = clocks.gclk0();
217     let usb_clock = &clocks.usb(&gclk0).unwrap();
218
219     UsbBusAllocator::new(UsbBus::new(
220         usb_clock,
221         pm,
222         dm.into_function(port),
223         dp.into_function(port),
224         usb,
225     ))
226 }