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
//! 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), with Shift/Fn layers
//! from [`keys`]. [`Keyboard::wait_for_inputs`] sleeps until the TCA8418
//! signals a key event on its interrupt line.
//! - [`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).
//!
//! Each part's pins come out of esp-hal's `Peripherals` with a macro named
//! after it, [`display_pins!`], [`keyboard_pins!`] and so on; 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::{display_pins, i2c_pins, speaker_pins};
//!
//! let p = esp_hal::init(esp_hal::Config::default());
//! // …start esp-rtos (or another embassy-time driver)…
//! let (mut display, mut backlight) = cardputer_adv::display(display_pins!(p))?;
//! let bus = cardputer_adv::i2c(i2c_pins!(p))?;
//! let mut keyboard = cardputer_adv::keyboard_on(bus, p.GPIO11)?;
//! let mut imu = cardputer_adv::imu(bus)?;
//! // In a task of its own: the speaker, then the codec it clocks.
//! let mut speaker = cardputer_adv::speaker(speaker_pins!(p))?;
//! let mut codec = cardputer_adv::codec(bus)?;
//!
//! 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 ;
/// The keyboard driver and its key types ([cardputer-adv-keyboard]).
///
/// [cardputer-adv-keyboard]: https://crates.io/crates/cardputer-adv-keyboard
pub use cardputer_adv_keyboard as keys;
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 ;