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
//! 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 ;
/// The microSD card's FAT file system and driver, at the version
/// [`SdCard`] uses.
pub use embedded_sdmmc;
pub use Error;
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 ;