diff --git a/Makefile b/Makefile index b2e242558..12079b89d 100644 --- a/Makefile +++ b/Makefile @@ -62,11 +62,11 @@ format: sdk: cd backend/ && ./install-sdk.sh -embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast +embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep ! test -f embassyos-raspi.img || rm embassyos-raspi.img ./build/raspberry-pi/make-image.sh -lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $(BUILD_SRC) eos.raspberrypi.squashfs +lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $(BUILD_SRC) eos.raspberrypi.squashfs ! test -f lite-upgrade.img || rm lite-upgrade.img ./build/raspberry-pi/make-upgrade-image.sh @@ -176,3 +176,6 @@ backend: $(EMBASSY_BINS) cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast: ./build-cargo-dep.sh nc-broadcast + +cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep: + ./build-cargo-dep.sh pi-beep \ No newline at end of file diff --git a/backend/src/sound.rs b/backend/src/sound.rs index 1874bf43b..0eb383fc1 100644 --- a/backend/src/sound.rs +++ b/backend/src/sound.rs @@ -1,6 +1,5 @@ use std::cmp::Ordering; -use std::path::Path; -use std::time::{Duration, Instant}; +use std::time::Duration; use divrem::DivRem; use proptest_derive::Arbitrary; @@ -8,92 +7,24 @@ use tokio::process::Command; use tracing::instrument; use crate::util::{FileLock, Invoke}; -use crate::{Error, ErrorKind, ResultExt}; +use crate::{Error, ErrorKind}; lazy_static::lazy_static! { static ref SEMITONE_K: f64 = 2f64.powf(1f64 / 12f64); static ref A_4: f64 = 440f64; static ref C_0: f64 = *A_4 / SEMITONE_K.powf(9f64) / 2f64.powf(4f64); - static ref EXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/export"); - static ref UNEXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/unexport"); - static ref PERIOD_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/period"); - static ref DUTY_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/duty_cycle"); - static ref SWITCH_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/enable"); } pub const SOUND_LOCK_FILE: &'static str = "/etc/embassy/sound.lock"; struct SoundInterface { - use_beep: bool, guard: Option, } impl SoundInterface { #[instrument] pub async fn lease() -> Result { let guard = FileLock::new(SOUND_LOCK_FILE, true).await?; - if Command::new("which") - .arg("beep") - .invoke(ErrorKind::NotFound) - .await - .is_ok() - { - Ok(SoundInterface { - use_beep: true, - guard: Some(guard), - }) - } else { - tokio::fs::write(&*EXPORT_FILE, "0") - .await - .or_else(|e| { - if e.raw_os_error() == Some(16) { - Ok(()) - } else { - Err(e) - } - }) - .with_ctx(|_| (ErrorKind::SoundError, EXPORT_FILE.to_string_lossy()))?; - let instant = Instant::now(); - while tokio::fs::metadata(&*PERIOD_FILE).await.is_err() - && instant.elapsed() < Duration::from_secs(1) - { - tokio::time::sleep(Duration::from_millis(1)).await; - } - Ok(SoundInterface { - use_beep: false, - guard: Some(guard), - }) - } - } - #[instrument(skip(self))] - async fn play_pwm(&mut self, note: &Note) -> Result<(), Error> { - let curr_period = tokio::fs::read_to_string(&*PERIOD_FILE) - .await - .with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?; - if curr_period == "0\n" { - tokio::fs::write(&*PERIOD_FILE, "1000") - .await - .with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?; - } - let new_period = ((1.0 / note.frequency()) * 1_000_000_000.0).round() as u64; - tokio::fs::write(&*DUTY_FILE, "0") - .await - .with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?; - tokio::fs::write(&*PERIOD_FILE, format!("{}", new_period)) - .await - .with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?; - tokio::fs::write(&*DUTY_FILE, format!("{}", new_period / 2)) - .await - .with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?; - tokio::fs::write(&*SWITCH_FILE, "1") - .await - .with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy()))?; - Ok(()) - } - #[instrument(skip(self))] - async fn stop_pwm(&mut self) -> Result<(), Error> { - tokio::fs::write(&*SWITCH_FILE, "0") - .await - .with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy())) + Ok(SoundInterface { guard: Some(guard) }) } #[instrument(skip(self))] pub async fn close(mut self) -> Result<(), Error> { @@ -109,29 +40,13 @@ impl SoundInterface { note: &Note, time_slice: &TimeSlice, ) -> Result<(), Error> { - if self.use_beep { - Command::new("beep") - .arg("-f") - .arg(note.frequency().to_string()) - .arg("-l") - .arg(time_slice.to_duration(tempo_qpm).as_millis().to_string()) - .invoke(ErrorKind::SoundError) - .await?; - } else { - if let Err(e) = async { - self.play_pwm(note).await?; - tokio::time::sleep(time_slice.to_duration(tempo_qpm) * 19 / 20).await; - self.stop_pwm().await?; - tokio::time::sleep(time_slice.to_duration(tempo_qpm) / 20).await; - Ok::<_, Error>(()) - } - .await - { - // we could catch this error and propagate but I'd much prefer the original error bubble up - let _mute = self.stop_pwm().await; - return Err(e); - } - } + Command::new("beep") + .arg("-f") + .arg(note.frequency().to_string()) + .arg("-l") + .arg(time_slice.to_duration(tempo_qpm).as_millis().to_string()) + .invoke(ErrorKind::SoundError) + .await?; Ok(()) } } @@ -164,15 +79,8 @@ where impl Drop for SoundInterface { fn drop(&mut self) { - let use_beep = self.use_beep; let guard = self.guard.take(); tokio::spawn(async move { - if !use_beep { - if let Err(e) = tokio::fs::write(&*UNEXPORT_FILE, "0").await { - tracing::error!("Failed to Unexport Sound Interface: {}", e); - tracing::debug!("{:?}", e); - } - } if let Some(guard) = guard { if let Err(e) = guard.unlock().await { tracing::error!("Failed to drop Sound Interface File Lock: {}", e); diff --git a/build/raspberry-pi/033-upgrade.sh b/build/raspberry-pi/033-upgrade.sh index 9dabb99f0..cfe256167 100755 --- a/build/raspberry-pi/033-upgrade.sh +++ b/build/raspberry-pi/033-upgrade.sh @@ -2,10 +2,30 @@ set -e +( + while true; do + beep -r 2 -l 80 -d 20 + sleep 60 + done +) & + if grep 'cb15ae4d-03' /boot/cmdline.txt; then - BLOCK_COUNT=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block count:" | awk '{print $3}') - BLOCK_SIZE=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block size:" | awk '{print $3}') - cat /dev/mmcblk0p3 | head -c $[$BLOCK_COUNT * $BLOCK_SIZE] > /dev/mmcblk0p4 + echo Transfer files across + e2fsck -f -y /dev/mmcblk0p4 + while ! resize2fs /dev/mmcblk0p4; do + e2fsck -f -y /dev/mmcblk0p4 + done + mkdir -p /media/origin + mkdir -p /media/dest + mount -r /dev/mmcblk0p3 /media/origin + mount -w /dev/mmcblk0p4 /media/dest + rsync -acvAXUH --info=progress2 --delete --force /media/origin/ /media/dest/ + umount /media/origin + umount /media/dest + rm -rf /media/origin + rm -rf /media/dest + + echo Setting up boot to use other partition sed -i 's/PARTUUID=cb15ae4d-03/PARTUUID=cb15ae4d-04/g' /boot/cmdline.txt sync reboot diff --git a/build/raspberry-pi/make-upgrade-image.sh b/build/raspberry-pi/make-upgrade-image.sh index 77f453708..79943e5be 100755 --- a/build/raspberry-pi/make-upgrade-image.sh +++ b/build/raspberry-pi/make-upgrade-image.sh @@ -26,9 +26,11 @@ sudo mount $TARGET_NAME $TMPDIR/ sudo mkdir -p $TMPDIR/update sudo unsquashfs -f -d $TMPDIR/update eos.raspberrypi.squashfs +sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep sudo cp ./build/raspberry-pi/033-upgrade.sh $TMPDIR/usr/local/bin/033-upgrade.sh sudo cp ./build/raspberry-pi/033-upgrade.service $TMPDIR/etc/systemd/system/033-upgrade.service sudo ln -s /etc/systemd/system/033-upgrade.service $TMPDIR/etc/systemd/system/multi-user.target.wants/033-upgrade.service +sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin sudo cp ./build/raspberry-pi/nc-broadcast.service $TMPDIR/etc/systemd/system/nc-broadcast.service sudo ln -s /etc/systemd/system/nc-broadcast.service $TMPDIR/etc/systemd/system/multi-user.target.wants/nc-broadcast.service diff --git a/build/raspberry-pi/write-image.sh b/build/raspberry-pi/write-image.sh index 761f217f0..87b301e59 100755 --- a/build/raspberry-pi/write-image.sh +++ b/build/raspberry-pi/write-image.sh @@ -28,6 +28,7 @@ sudo mkdir $TMPDIR/media/embassy/ sudo ENVIRONMENT=$ENVIRONMENT make V=1 install ARCH=aarch64 OS_ARCH=raspberrypi DESTDIR=$TMPDIR --debug sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hostname sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hosts +sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep sudo cp cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin sudo cp backend/*.service $TMPDIR/etc/systemd/system/ sudo mkdir -p $TMPDIR/etc/embassy