#![no_std]
pub mod audio;
pub mod bsp;
pub mod display;
#[cfg(feature = "env")]
pub mod env;
pub mod imu;
pub mod input;
pub mod power;
pub mod sprite;
pub mod storage;
pub mod touch;
#[cfg(feature = "wifi")]
pub mod wifi;
#[cfg(feature = "wifi")]
use crate::bsp::WifiResources;
use crate::bsp::{
BoardInitError, ButtonLevels, NessoBuzzer, NessoDisplay, NessoI2c, NessoN1, NessoN1Board,
};
use crate::imu::{Acceleration, Bmi270, Gyroscope};
use crate::power::{BatteryStatus, Power};
use crate::storage::EspFlashSettingsStore;
use crate::touch::{Touch, TouchEvent, TouchState};
#[cfg(feature = "wifi")]
use crate::wifi::EspRadioWifi;
use esp_hal::delay::Delay;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NessoError {
Board(BoardInitError),
Touch,
Imu,
Power,
FlashUnavailable,
#[cfg(feature = "wifi")]
WifiUnavailable,
ImuNotInitialized,
Input,
}
pub struct Nesso {
pub display: NessoDisplay,
pub audio: NessoBuzzer,
i2c: NessoI2c,
#[cfg(feature = "wifi")]
wifi: Option<WifiResources>,
flash: Option<esp_hal::peripherals::FLASH<'static>>,
imu_initialized: bool,
previous_touch: TouchState,
}
impl Nesso {
pub fn new(peripherals: esp_hal::peripherals::Peripherals) -> Result<Self, NessoError> {
let parts = NessoN1Board::new(peripherals)
.into_core_parts()
.map_err(NessoError::Board)?;
let nesso = Self {
display: parts.display,
audio: parts.buzzer,
i2c: parts.i2c,
#[cfg(feature = "wifi")]
wifi: Some(parts.wifi),
flash: Some(parts.flash),
imu_initialized: false,
previous_touch: TouchState::default(),
};
Ok(nesso)
}
pub fn init_imu(&mut self) -> Result<(), NessoError> {
Bmi270::new(&mut self.i2c, Delay::new())
.init()
.map_err(|_| NessoError::Imu)?;
self.imu_initialized = true;
Ok(())
}
pub fn touch_state(&mut self) -> Result<TouchState, NessoError> {
Touch::new(&mut self.i2c)
.read_state()
.map_err(|_| NessoError::Touch)
}
pub fn touch_event(&mut self) -> Result<TouchEvent, NessoError> {
let current = self.touch_state()?;
let event = match (self.previous_touch.primary(), current.primary()) {
(None, Some(point)) => TouchEvent::Pressed(point),
(Some(_), None) => TouchEvent::Released,
(Some(previous), Some(point)) if previous != point => TouchEvent::Moved(point),
_ => TouchEvent::Idle,
};
self.previous_touch = current;
Ok(event)
}
pub fn init_buttons(&mut self) -> Result<(), NessoError> {
NessoN1::init_button_inputs(&mut self.i2c).map_err(|_| NessoError::Input)
}
pub fn button_levels(&mut self) -> Result<ButtonLevels, NessoError> {
NessoN1::read_button_levels(&mut self.i2c).map_err(|_| NessoError::Input)
}
pub fn acceleration(&mut self) -> Result<Acceleration, NessoError> {
if !self.imu_initialized {
return Err(NessoError::ImuNotInitialized);
}
Bmi270::new(&mut self.i2c, Delay::new())
.acceleration()
.map_err(|_| NessoError::Imu)
}
pub fn gyroscope(&mut self) -> Result<Gyroscope, NessoError> {
if !self.imu_initialized {
return Err(NessoError::ImuNotInitialized);
}
Bmi270::new(&mut self.i2c, Delay::new())
.gyroscope()
.map_err(|_| NessoError::Imu)
}
pub fn battery_status(&mut self) -> Result<BatteryStatus, NessoError> {
Power::new(&mut self.i2c)
.battery_status()
.map_err(|_| NessoError::Power)
}
#[cfg(feature = "wifi")]
pub fn init_wifi(&mut self) -> Result<EspRadioWifi, NessoError> {
let wifi = self.wifi.take().ok_or(NessoError::WifiUnavailable)?;
Ok(EspRadioWifi::new(wifi))
}
pub fn take_flash_settings(
&mut self,
offset: u32,
) -> Result<EspFlashSettingsStore<'static>, NessoError> {
let flash = self.flash.take().ok_or(NessoError::FlashUnavailable)?;
Ok(EspFlashSettingsStore::from_flash(flash, offset))
}
}