mod audio;
mod buttons;
mod config;
mod display;
mod error;
mod imu;
mod led;
mod log;
mod power;
mod rtc;
mod system;
mod touch;
pub use audio::{Mic, MicConfig, Speaker};
pub use buttons::{Button, ButtonId, Buttons};
pub use config::{ExternalDisplayConfig, ExternalSpeakerConfig, M5UnifiedConfig};
pub use display::{
colors, Color565, Display, DisplayKind, DisplayRef, Point, Rect, Size, TextDatum,
};
pub use error::Error;
pub use imu::{Imu, ImuData, ImuKind, Vec3};
pub use led::{Led, LedColor};
pub use log::{Log, LogLevel};
pub use power::{Axp2101, Axp2101IrqStatus, Power};
pub use rtc::{DateTime, Rtc};
pub use system::{Board, PinName};
pub use touch::{Touch, TouchDetail, TouchPoint};
#[derive(Debug)]
pub struct M5Unified {
pub display: Display,
pub buttons: Buttons,
pub mic: Mic,
pub speaker: Speaker,
pub imu: Imu,
pub touch: Touch,
pub rtc: Rtc,
pub power: Power,
pub led: Led,
pub log: Log,
}
impl M5Unified {
pub fn begin() -> Result<Self, Error> {
let ok = unsafe { m5unified_sys::m5u_begin() };
Self::from_begin_result(ok)
}
pub fn begin_with_config(config: &M5UnifiedConfig) -> Result<Self, Error> {
let raw = config.to_raw();
let ok = unsafe { m5unified_sys::m5u_begin_with_config(&raw) };
Self::from_begin_result(ok)
}
fn from_begin_result(ok: bool) -> Result<Self, Error> {
if !ok {
return Err(Error::BeginFailed);
}
Ok(Self {
display: Display,
buttons: Buttons,
mic: Mic,
speaker: Speaker,
imu: Imu,
touch: Touch,
rtc: Rtc,
power: Power,
led: Led,
log: Log,
})
}
pub fn update(&mut self) {
unsafe { m5unified_sys::m5u_update() }
}
pub fn delay_ms(&self, ms: u32) {
unsafe { m5unified_sys::m5u_delay_ms(ms) }
}
}
pub fn sd_begin() -> bool {
unsafe { m5unified_sys::m5u_sd_begin() }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_dimensions_are_available_on_host_stubs() {
let m5 = M5Unified::begin().expect("host stub begin should succeed");
assert!(m5.display.width() > 0);
assert!(m5.display.height() > 0);
}
#[test]
fn invalid_strings_are_rejected_before_ffi() {
let mut m5 = M5Unified::begin().expect("host stub begin should succeed");
assert_eq!(m5.display.print("bad\0string"), Err(Error::InvalidString));
}
#[test]
fn mic_rms_uses_recorded_buffer() {
let mut m5 = M5Unified::begin().expect("host stub begin should succeed");
let mut buffer = [0_i16; 8];
assert_eq!(m5.mic.rms(&mut buffer), Some(0.0));
}
#[test]
fn led_host_stub_reports_disabled() {
let mut m5 = M5Unified::begin().expect("host stub begin should succeed");
assert!(!m5.led.is_enabled());
assert_eq!(m5.led.count(), 0);
m5.led.set_all_color(LedColor::RED);
}
#[test]
fn system_host_stub_reports_unknown_board_and_no_pins() {
let mut m5 = M5Unified::begin().expect("host stub begin should succeed");
assert_eq!(m5.board(), Board::Unknown);
assert_eq!(m5.get_pin(PinName::PORT_A_SDA), None);
assert!(m5.set_primary_display(0));
assert!(!m5.set_primary_display_type(DisplayKind::ModuleDisplay));
m5.set_touch_button_height(32);
assert_eq!(m5.touch_button_height(), 0);
}
#[test]
fn begin_with_config_uses_host_stub() {
let config = M5UnifiedConfig {
led_brightness: 32,
external_imu: true,
external_rtc: true,
..M5UnifiedConfig::default()
};
let m5 = M5Unified::begin_with_config(&config).expect("host stub begin should succeed");
assert_eq!(m5.display.width(), 320);
}
}