embedded_platform/specs/
feather.rs

1use crate::gpio;
2use crate::i2c;
3use crate::platform;
4
5/// A platform that conforms to the [Adafruit Feather specification](https://learn.adafruit.com/adafruit-feather/feather-specification).
6///
7/// Any platform conforming to the specification must use 3.3V as the core voltage.
8///
9/// # Pins
10///
11///   * `D0-D8` are general purpose GPIO pins (digital input and output).  `D0` and `D1` double as
12///     `SDA`/`SCL` so that is their primary name, but the trait will have associated type defaults
13///     once that enters stable rust.
14///   * `A0-A5` are capable of analog input in addition to GPIO.  The exception is the ESP8266
15///     feather, which only has a working `A0`.  Hence analog traits are not required by the other
16///     pins, while in practice most boards will actually implement them.
17///   * `RX`/`TX` are bound to a hardware UART.
18///   * `SDA`/`SCL` are bound to the main I²C bus.
19///   * `SCK`/`MOSI`/`MISO` are bound to the main SPI bus.
20///   * `P0` is mapped to something custom depending on the specific feather, usually a GPIO.
21///
22/// Additionally, it is guaranteed that there is one main LED bound to a pin, but which one it is
23/// is left unspecified.
24///
25/// The pins are placed roughly according to this illustration:
26///
27/// ```text
28///      ┌──────────────────┐
29///  RST │ ○                │
30///  3V3 │ ○                │
31/// VREF │ ○                │
32///  GND │ ○                │
33///   A0 │ ○              ○ │ BAT
34///   A1 │ ○              ○ │ EN
35///   A2 │ ○              ○ │ USB
36///   A3 │ ○              ○ │ D8
37///   A4 │ ○              ○ │ D7
38///   A5 │ ○              ○ │ D6
39///  SCK │ ○              ○ │ D5
40/// MOSI │ ○              ○ │ D4
41/// MISO │ ○              ○ │ D3
42///   RX │ ○              ○ │ D2
43///   TX │ ○              ○ │ SCL / D1
44///   P0 │ ○              ○ │ SDA / D0
45///      └──────────────────┘
46/// ```
47pub trait Feather: platform::Platform {
48    type MainLed: gpio::IntoPushPullOutputPin<Error = Self::Error>;
49    type MainI2cMapping: i2c::I2cBusMapping<Self::SDA, Self::SCL>;
50
51    type SDA: gpio::IntoOpenDrainOutputPin<Error = Self::Error>
52        + gpio::IntoFloatingInputPin<Error = Self::Error>;
53    type SCL: gpio::IntoPushPullOutputPin<Error = Self::Error>;
54    type D2: gpio::IntoPushPullOutputPin<Error = Self::Error>;
55    type D3: gpio::IntoPushPullOutputPin<Error = Self::Error>;
56    type D4: gpio::IntoPushPullOutputPin<Error = Self::Error>;
57    type D5: gpio::IntoPushPullOutputPin<Error = Self::Error>;
58    type D6: gpio::IntoPushPullOutputPin<Error = Self::Error>;
59    type D7: gpio::IntoPushPullOutputPin<Error = Self::Error>;
60    type D8: gpio::IntoPushPullOutputPin<Error = Self::Error>;
61
62    type P0;
63    type TX: gpio::IntoPushPullOutputPin<Error = Self::Error>;
64    type RX: gpio::IntoFloatingInputPin<Error = Self::Error>;
65    type MISO: gpio::IntoFloatingInputPin<Error = Self::Error>;
66    type MOSI: gpio::IntoPushPullOutputPin<Error = Self::Error>;
67    type SCK: gpio::IntoPushPullOutputPin<Error = Self::Error>;
68    type A5: gpio::IntoFloatingInputPin<Error = Self::Error>;
69    type A4: gpio::IntoFloatingInputPin<Error = Self::Error>;
70    type A3: gpio::IntoFloatingInputPin<Error = Self::Error>;
71    type A2: gpio::IntoFloatingInputPin<Error = Self::Error>;
72    type A1: gpio::IntoFloatingInputPin<Error = Self::Error>;
73    type A0: gpio::IntoFloatingInputPin<Error = Self::Error>;
74
75    fn take_main_led(&mut self) -> Self::MainLed;
76
77    fn take_main_i2c(
78        &mut self,
79    ) -> <Self::MainI2cMapping as i2c::I2cBusMapping<Self::SDA, Self::SCL>>::Bus;
80
81    fn take_sda(&mut self) -> Self::SDA;
82    fn take_scl(&mut self) -> Self::SCL;
83    fn take_d2(&mut self) -> Self::D2;
84    fn take_d3(&mut self) -> Self::D3;
85    fn take_d4(&mut self) -> Self::D4;
86    fn take_d5(&mut self) -> Self::D5;
87    fn take_d6(&mut self) -> Self::D6;
88    fn take_d7(&mut self) -> Self::D7;
89    fn take_d8(&mut self) -> Self::D8;
90    fn take_p0(&mut self) -> Self::P0;
91    fn take_tx(&mut self) -> Self::TX;
92    fn take_rx(&mut self) -> Self::RX;
93    fn take_miso(&mut self) -> Self::MISO;
94    fn take_mosi(&mut self) -> Self::MOSI;
95    fn take_sck(&mut self) -> Self::SCK;
96    fn take_a5(&mut self) -> Self::A5;
97    fn take_a4(&mut self) -> Self::A4;
98    fn take_a3(&mut self) -> Self::A3;
99    fn take_a2(&mut self) -> Self::A2;
100    fn take_a1(&mut self) -> Self::A1;
101    fn take_a0(&mut self) -> Self::A0;
102}