1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Board support for the M5Stack Cardputer ADV on esp-hal.
//!
//! - [`display`]: the 1.14" ST7789V2 LCD as a 240×135 RGB565
//! embedded-graphics `DrawTarget` (landscape, keyboard below), and its
//! [`Backlight`], dimmable by PWM. [`frame_display`] feeds it from a
//! [`Frame`] by DMA instead.
//! - [`keyboard`]: the 56-key keyboard (TCA8418 on I2C). [`Keyboard::wait_for_inputs`]
//! sleeps until the TCA8418 signals a key event on its interrupt line,
//! and returns what the keys type, with Shift and Fn applied ([`keys`]).
//! - [`imu`]: the BMI270 motion sensor: its accelerometer, in milli-g, and
//! its gyroscope, in milli-degrees a second.
//! - [`speaker`]: the speaker, fed with samples over I2S (the ES8311 codec,
//! then an NS4150B amplifier). [`audio`] starts it with the microphone,
//! as an [`Audio`]. [`codec`] turns the codec on and returns the
//! [`Codec`], which sets its level, and turns its output and the
//! microphone off and on.
//! - [`i2c`]: the I2C bus the keyboard, the codec and the motion sensor
//! share. Only needed to use more than the keyboard; [`keyboard`] alone
//! sets it up itself.
//! - [`battery`]: the battery voltage, and the charge left as a percentage.
//! The board can't tell whether it's charging.
//! - [`button`]: the G0 button.
//! - [`rmt`]: the RMT peripheral, for the [`rgb_led`] (a WS2812) and the
//! [`ir_transmitter`] (NEC codes).
//! - `sd_card` (with the `sd-card` feature): the microSD card, through
//! [embedded-sdmmc](https://crates.io/crates/embedded-sdmmc).
//!
//! [`board!`] sets the whole board up in one call, as a [`Board`]: the
//! parts with nothing to choose, ready, and the pins of the display and the
//! audio. Or part by part: each part's pins come out of esp-hal's
//! `Peripherals` with a macro named after it, [`display_pins!`],
//! [`keyboard_pins!`] and so on. Either way only those fields move, so the
//! rest stays usable.
//!
//! The async parts need an embassy-time driver, such as esp-rtos's.
//!
//! # Quick start
//!
//! ```ignore
//! use cardputer_adv::Board;
//!
//! let p = esp_hal::init(esp_hal::Config::default());
//! // …start esp-rtos (or another embassy-time driver)…
//! let Board { display, mut keyboard, bus, audio, .. } = cardputer_adv::board!(p).await?;
//! let (mut display, mut backlight) = cardputer_adv::display(display)?;
//! let mut imu = cardputer_adv::imu(bus).await?;
//! // In a task of its own: the speaker, then the codec it clocks.
//! let mut speaker = cardputer_adv::speaker(audio.speaker)?;
//! let mut codec = cardputer_adv::codec(bus).await?;
//!
//! for key in keyboard.wait_for_inputs().await? { /* … */ }
//! ```
//!
//! # Features
//!
//! - `sd-card`: the microSD card (`sd_card`), through embedded-sdmmc.
//! - `defmt`: `defmt::Format` for [`Error`].
//!
//! # Pins
//!
//! From the ADV schematic, M5Unified and working firmware:
//!
//! | Function | GPIO |
//! |---|---|
//! | LCD SCK / MOSI / CS / DC / RST | 36 / 35 / 37 / 34 / 33 |
//! | LCD backlight, PWM on LEDC (also powers the RGB LED) | 38 |
//! | I2C SDA / SCL (keyboard, ES8311, BMI270) | 8 / 9 |
//! | Keyboard interrupt | 11 |
//! | Battery voltage (ADC1, through a 2:1 divider) | 10 |
//! | I2S BCLK / WS / DOUT / DIN (the ES8311; no MCLK) | 41 / 43 / 42 / 46 |
//! | G0 button | 0 |
//! | RGB LED (WS2812) | 21 |
//! | IR LED | 44 |
//! | microSD SCK / MOSI / MISO / CS | 40 / 14 / 39 / 12 |
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use battery_percent;
pub use ;
/// The microSD card's FAT file system and driver, at the version
/// [`SdCard`] uses.
pub use embedded_sdmmc;
pub use Error;
pub use Frame;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// The display driver [`Display`] comes from, so its types can be named
/// without matching its version.
pub use mipidsi;
pub use ;
pub use ;
pub use ;
pub use Repeat;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;