command framework for music subsystem

This commit is contained in:
Andy Killorin 2024-12-05 16:15:13 -05:00
parent 7c3d07d563
commit a8973025d5
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
3 changed files with 123 additions and 21 deletions

View file

@ -1,5 +1,4 @@
use super::MUSIC;
use crate::music::{MusicCommand, Name, COMMANDS};
use embassy_net::{IpEndpoint, Ipv4Address};
use embassy_time::Duration;
@ -13,7 +12,22 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Receiver;
use embedded_io_async::Write;
use log::*;
use rand::RngCore;
trait Authorized {
/// allowed to open door
fn authorized(&self) -> bool;
}
impl Authorized for Name {
fn authorized(&self) -> bool {
match self {
Name::Andy => true,
Name::Evan => true,
Name::Michael => true,
_ => false,
}
}
}
#[embassy_executor::task]
pub(crate) async fn send_badge(channel: Receiver<'static,CriticalSectionRawMutex,u64,1>,stack: embassy_net::Stack<'static>) -> ! {
@ -22,13 +36,13 @@ pub(crate) async fn send_badge(channel: Receiver<'static,CriticalSectionRawMutex
loop {
let card = channel.receive().await;
let mut rng = RoscRng;
let num = (RoscRng::next_u32(&mut rng) % 5) + 1;
let name = match card {
0x2c55dc3f5 => "evan",
0x3161dc3f7 => "andy",
_ => "d",
};
let name = Name::from_badge(card);
COMMANDS.send(MusicCommand::Introduce(name, name.authorized())).await;
// this is also checked on the backend (TODO)
if !name.authorized() {
continue;
}
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
socket.set_timeout(Some(Duration::from_secs(10)));
@ -57,8 +71,5 @@ pub(crate) async fn send_badge(channel: Receiver<'static,CriticalSectionRawMutex
socket.close();
info!("disconnected");
MUSIC.send(("a",num as u8)).await;
MUSIC.send((name,num as u8)).await;
}
}

View file

@ -42,7 +42,7 @@ use embassy_rp::pio::{InterruptHandler, Pio};
use embassy_rp::usb::Driver;
use embassy_time::{Timer};
use embedded_io_async::{Read, ReadReady, Write};
use music::{music_manager, MUSIC};
use music::{music_manager, COMMANDS};
use rand::RngCore;
use reqwless::response;
use scanner::{data_extractor, spawn_poller};
@ -168,7 +168,7 @@ async fn button_manager(pin: PIN_22) -> ! {
let mut button = Input::new(pin, embassy_rp::gpio::Pull::Up);
loop {
button.wait_for_rising_edge().await;
MUSIC.send(("d",5)).await;
COMMANDS.send(music::MusicCommand::Play("d5")).await; // TODO: record
Timer::after_millis(800).await;
}
}

View file

@ -1,9 +1,11 @@
use embassy_rp::clocks::RoscRng;
use embassy_rp::uart;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;
use embassy_time::Timer;
use embedded_io_async::Read;
use embedded_io_async::Write;
use rand::RngCore;
use super::WAGS;
@ -18,10 +20,10 @@ use super::Irqs;
use embassy_rp::peripherals::UART1;
use log::*;
pub static MUSIC: Channel<CriticalSectionRawMutex, (&'static str, u8), 3> = Channel::new();
pub static COMMANDS: Channel<CriticalSectionRawMutex, (MusicCommand), 3> = Channel::new();
pub static COMMANDS: Channel<CriticalSectionRawMutex, MusicCommand, 3> = Channel::new();
enum Name {
#[derive(Clone, Copy)]
pub enum Name {
Andy,
Evan,
Felix,
@ -38,7 +40,56 @@ enum Name {
Unknown,
}
enum MusicCommand {
impl Name {
fn tracks(&self) -> u8 {
match self {
Name::Andy => 7,
Name::Evan => 7,
Name::Felix => 12,
Name::Phil => 6,
Name::Tess => 4,
Name::Amaia => 5,
Name::Prueky => 1,
Name::David => 2,
Name::Nathaniel => 1,
Name::Thia => 7,
Name::Michael => 0,
Name::Zoey => 1,
Name::Coke => todo!(),
Name::Unknown => 0,
}
}
fn prefix(&self) -> &'static str {
match self {
Name::Andy => "andy",
Name::Evan => "evan",
Name::Felix => "felix",
Name::Phil => "phil",
Name::Tess => "tess",
Name::Amaia => "amaia",
Name::Prueky => "prueky",
Name::David => "david",
Name::Nathaniel => "nathaniel1",
Name::Thia => "thia",
Name::Michael => "michael",
Name::Zoey => "zoey",
Name::Coke => "button",
Name::Unknown => "",
}
}
pub fn from_badge(badge: u64) -> Self {
match badge {
_ => Name::Unknown,
}
}
}
static ACCEPTED_SUFFIXABLE: [bool; 6] = [false, false, false, false, false, true];
static DENIED_SUFFIXABLE: [bool; 6] = [false, false, false, false, false, true];
pub enum MusicCommand {
/// play a random clip for name, accepted if true
Introduce(Name, bool),
/// 0-30
@ -55,9 +106,49 @@ pub(crate) async fn music_manager(uart: UART1, irqs: Irqs, txp: PIN_20, rxp: PIN
let mut uart = BufferedUart::new(uart, irqs, txp, rxp, &mut tx, &mut rx, config);
let mut rng = RoscRng;
loop {
let song = MUSIC.receive().await;
play_song(song.0, Some(song.1), &mut uart).await;
let command = COMMANDS.receive().await;
match command {
MusicCommand::Introduce(name, accepted) => {
let call: bool;
if accepted {
let index = rng.next_u32() % ACCEPTED_SUFFIXABLE.len() as u32;
play_song("a", Some((index+1) as u8), &mut uart).await;
call = ACCEPTED_SUFFIXABLE[index as usize];
} else {
let index = rng.next_u32() % DENIED_SUFFIXABLE.len() as u32;
play_song("d", Some((index+1) as u8), &mut uart).await;
call = DENIED_SUFFIXABLE[index as usize];
}
if call {
match name.tracks() {
0 => {},
1 => {
play_song(&name.prefix(), None, &mut uart).await;
},
tracks => {
let index = rng.next_u32() % tracks as u32;
play_song(&name.prefix(), Some((index+1) as u8), &mut uart).await;
}
}
}
},
MusicCommand::Play(song) => {
play_song(song, None, &mut uart).await
},
MusicCommand::SetVolume(vol) => {
uart.write_all(b"AT+VOL=").await.unwrap();
uart.write_all(itoa::Buffer::new().format(vol).as_bytes()).await.unwrap();
uart.write_all(b"\r\n").await.unwrap();
let mut buffer = [0;512];
info!("set volume to {vol}, returned: {}",read_line(&mut buffer, &mut uart).await.trim());
},
}
}
}