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 crate::music::{MusicCommand, Name, COMMANDS};
use super::MUSIC;
use embassy_net::{IpEndpoint, Ipv4Address}; use embassy_net::{IpEndpoint, Ipv4Address};
use embassy_time::Duration; use embassy_time::Duration;
@ -13,7 +12,22 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Receiver; use embassy_sync::channel::Receiver;
use embedded_io_async::Write; use embedded_io_async::Write;
use log::*; 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] #[embassy_executor::task]
pub(crate) async fn send_badge(channel: Receiver<'static,CriticalSectionRawMutex,u64,1>,stack: embassy_net::Stack<'static>) -> ! { 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 { loop {
let card = channel.receive().await; let card = channel.receive().await;
let mut rng = RoscRng; let name = Name::from_badge(card);
let num = (RoscRng::next_u32(&mut rng) % 5) + 1; COMMANDS.send(MusicCommand::Introduce(name, name.authorized())).await;
let name = match card {
0x2c55dc3f5 => "evan", // this is also checked on the backend (TODO)
0x3161dc3f7 => "andy", if !name.authorized() {
_ => "d", continue;
}; }
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
socket.set_timeout(Some(Duration::from_secs(10))); socket.set_timeout(Some(Duration::from_secs(10)));
@ -57,8 +71,5 @@ pub(crate) async fn send_badge(channel: Receiver<'static,CriticalSectionRawMutex
socket.close(); socket.close();
info!("disconnected"); 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_rp::usb::Driver;
use embassy_time::{Timer}; use embassy_time::{Timer};
use embedded_io_async::{Read, ReadReady, Write}; use embedded_io_async::{Read, ReadReady, Write};
use music::{music_manager, MUSIC}; use music::{music_manager, COMMANDS};
use rand::RngCore; use rand::RngCore;
use reqwless::response; use reqwless::response;
use scanner::{data_extractor, spawn_poller}; 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); let mut button = Input::new(pin, embassy_rp::gpio::Pull::Up);
loop { loop {
button.wait_for_rising_edge().await; 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; Timer::after_millis(800).await;
} }
} }

View file

@ -1,9 +1,11 @@
use embassy_rp::clocks::RoscRng;
use embassy_rp::uart; use embassy_rp::uart;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_time::Timer; use embassy_time::Timer;
use embedded_io_async::Read; use embedded_io_async::Read;
use embedded_io_async::Write; use embedded_io_async::Write;
use rand::RngCore;
use super::WAGS; use super::WAGS;
@ -18,10 +20,10 @@ use super::Irqs;
use embassy_rp::peripherals::UART1; use embassy_rp::peripherals::UART1;
use log::*; 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, Andy,
Evan, Evan,
Felix, Felix,
@ -38,7 +40,56 @@ enum Name {
Unknown, 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 /// play a random clip for name, accepted if true
Introduce(Name, bool), Introduce(Name, bool),
/// 0-30 /// 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 uart = BufferedUart::new(uart, irqs, txp, rxp, &mut tx, &mut rx, config);
let mut rng = RoscRng;
loop { loop {
let song = MUSIC.receive().await; let command = COMMANDS.receive().await;
play_song(song.0, Some(song.1), &mut uart).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());
},
}
} }
} }