device-envoy-esp 0.1.0

Build ESP32 applications with composable device abstractions
Documentation
// @generated by cargo xtask generate-board-examples
//!
//! Wiring:
//! - Audio data pin (`DIN`) -> GPIO21
//! - Audio bit clock pin (`BCLK`) -> GPIO4
//! - Audio word select pin (`LRC` / `LRCLK`) -> GPIO5
//! - Button -> GPIO0 to GND
#![no_std]
#![no_main]

use core::convert::Infallible;
use core::time::Duration as StdDuration;

use embassy_executor::Spawner;
use esp_backtrace as _;
use log::info;

use device_envoy_esp::{Result, init_and_start};
use device_envoy_esp::{
    audio_player::{
        AtEnd, AudioPlayer, Playable, SilenceClip, VOICE_22050_HZ, Volume, audio_player,
    },
    button::{Button as _, ButtonEsp, PressedTo},
    tone,
};

esp_bootloader_esp_idf::esp_app_desc!();

audio_player! {
    AudioPlayerBoard {
        data_pin: GPIO21,
        bit_clock_pin: GPIO4,
        word_select_pin: GPIO5,
        sample_rate_hz: VOICE_22050_HZ,
        dma: DMA_I2S0,
        max_volume: Volume::percent(50),
    }
}

const SAMPLE_RATE_HZ: u32 = VOICE_22050_HZ;

fn play_mary_phrase(audio_player: &impl AudioPlayer<SAMPLE_RATE_HZ>) {
    type PlayableRef = &'static dyn Playable<SAMPLE_RATE_HZ>;

    const REST: PlayableRef = &SilenceClip::new(StdDuration::from_millis(80));
    const NOTE_DURATION: StdDuration = StdDuration::from_millis(220);
    const NOTE_E4: PlayableRef = &tone!(330, SAMPLE_RATE_HZ, NOTE_DURATION);
    const NOTE_D4: PlayableRef = &tone!(294, SAMPLE_RATE_HZ, NOTE_DURATION);
    const NOTE_C4: PlayableRef = &tone!(262, SAMPLE_RATE_HZ, NOTE_DURATION);

    audio_player.play(
        [
            NOTE_E4, REST, NOTE_D4, REST, NOTE_C4, REST, NOTE_D4, REST, NOTE_E4, REST, NOTE_E4,
            REST, NOTE_E4,
        ],
        AtEnd::Stop,
    );
}

#[esp_rtos::main]
async fn main(spawner: Spawner) -> ! {
    let err = inner_main(spawner).await.unwrap_err();
    panic!("{err:?}");
}

async fn inner_main(spawner: Spawner) -> Result<Infallible> {
    init_and_start!(p);
    esp_println::logger::init_logger(log::LevelFilter::Info);

    let mut button = ButtonEsp::new(p.GPIO0, PressedTo::Ground);

    let audio_player_board =
        AudioPlayerBoard::new(p.GPIO21, p.GPIO4, p.GPIO5, p.I2S0, p.DMA_I2S0, spawner)?;

    loop {
        play_mary_phrase(audio_player_board);
        info!("Press the button to play again.");
        button.wait_for_press().await;
    }
}