Skip to content

Commit 8cd6014

Browse files
authored
feat: migrate phoenix sound & music to monorepo (#35)
* feat: migrate phoenix sound & music to monorepo Migrated the HAL configuration & setup along with music & sound from the original phoenix code repo. Rewrote some parts to conform with the service-style architecture for uniformity with the rest of the avionics monorepo. * feat: add songs, play songs indefinitely Add some songs inherited from the original phoenix codebase, and create a tasks that runs indefinitely, playing through all the music in `PLAYLIST`. Some additional code cleanups are included. * fix: resolve linker errors and remove dead code Import `defmt_rtt` and match crate versions with argus to fix some linker errors. Additionally removed the heap code from `HAL.rs` since it's entirely unused. * fix(music): correct notes for mario theme The Mario theme should use quarter notes rather than full notes at 120 BPM.
1 parent 692d225 commit 8cd6014

File tree

17 files changed

+381
-0
lines changed

17 files changed

+381
-0
lines changed

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

boards/phoenix/.cargo/config.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2+
runner = "probe-rs run --chip STM32H733VGTx --protocol swd"
3+
rustflags = ["-C", "link-arg=-Tlink.x", "-C", "link-arg=-Tdefmt.x"]
4+
5+
[env]
6+
DEFMT_LOG = "debug"
7+
8+
[build]
9+
target = "thumbv7em-none-eabihf"

boards/phoenix/Cargo.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[package]
2+
name = "phoenix"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[lib]
7+
harness = false
8+
9+
[features]
10+
default = ["music"]
11+
music = []
12+
13+
[dependencies]
14+
cortex-m = { workspace = true }
15+
cortex-m-rt = { workspace = true }
16+
static_cell = "2"
17+
embassy-executor = { version = "0.7.0", features = [
18+
"nightly",
19+
"task-arena-size-10240",
20+
"arch-cortex-m",
21+
"executor-thread",
22+
"executor-interrupt",
23+
"defmt",
24+
] }
25+
embassy-stm32 = { version = "0.2.0", features = [
26+
"defmt",
27+
"stm32h733vg",
28+
"time-driver-tim2",
29+
"exti",
30+
"memory-x",
31+
"unstable-pac",
32+
"chrono",
33+
] }
34+
embassy-sync = { version = "0.6.2", features = ["defmt"] }
35+
embassy-time = { version = "0.4.0", features = [
36+
"defmt",
37+
"defmt-timestamp-uptime",
38+
"tick-hz-32_768",
39+
] }
40+
embedded-alloc = { workspace = true }
41+
defmt = { workspace = true }
42+
defmt-rtt = { workspace = true }
43+
panic-probe = { workspace = true }

boards/phoenix/rust-toolchain.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[toolchain]
2+
channel = "nightly"
3+
targets = ["thumbv7em-none-eabihf"]

boards/phoenix/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_std]
2+
#![feature(impl_trait_in_assoc_type)]
3+
4+
#[cfg(feature = "music")]
5+
pub mod music;
6+
pub mod sound;
7+
pub mod utils;

boards/phoenix/src/main.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#![no_std]
2+
#![no_main]
3+
#![feature(impl_trait_in_assoc_type)]
4+
5+
use defmt::info;
6+
use defmt_rtt as _;
7+
use embassy_executor::Spawner;
8+
use panic_probe as _;
9+
use phoenix::{
10+
sound::service::SoundService,
11+
utils::{hal::configure_hal, types::AsyncMutex},
12+
};
13+
use static_cell::StaticCell;
14+
15+
/// To change the pin used for sound, see [phoenix::sound::types]
16+
static SOUND_SERVICE: StaticCell<AsyncMutex<SoundService>> = StaticCell::new();
17+
#[cfg(feature = "music")]
18+
static MUSIC_SERVICE: StaticCell<AsyncMutex<phoenix::music::service::MusicService>> = StaticCell::new();
19+
20+
#[embassy_executor::main]
21+
async fn main(spawner: Spawner) {
22+
info!("Starting up...");
23+
let p = configure_hal();
24+
25+
let sound = SOUND_SERVICE.init(AsyncMutex::new(SoundService::new(p.TIM3, p.PC6)));
26+
27+
#[cfg(feature = "music")]
28+
{
29+
use defmt::error;
30+
use phoenix::music::{service::MusicService, tasks::play_music_forever};
31+
let music = MUSIC_SERVICE.init(AsyncMutex::new(MusicService::new(sound)));
32+
match spawner.spawn(play_music_forever(music)) {
33+
Ok(_) => (),
34+
Err(e) => error!("Could not spawn music task: {}", e),
35+
}
36+
}
37+
}

boards/phoenix/src/music/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! Music playback for Phoenix.
2+
//!
3+
//! This module provides functionality for playing music and sound effects using a PWM buzzer.
4+
//! Some provided songs are included in [songs].
5+
6+
pub mod service;
7+
pub mod songs;
8+
pub mod tasks;
9+
pub mod types;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//! Playback of some simple songs with the buzzer
2+
use embassy_time::Timer;
3+
4+
use crate::{
5+
music::types::{Melody, Note},
6+
sound::service::SoundService,
7+
utils::types::AsyncMutex,
8+
};
9+
10+
pub struct MusicService {
11+
sound_service: &'static AsyncMutex<SoundService>,
12+
}
13+
14+
impl MusicService {
15+
pub fn new(sound_service: &'static AsyncMutex<SoundService>) -> Self {
16+
Self { sound_service }
17+
}
18+
19+
pub async fn play_song(
20+
&self,
21+
song: Melody,
22+
tempo: f32,
23+
) {
24+
let beat_length = 60_000f32 / tempo;
25+
let mut sound = self.sound_service.lock().await;
26+
27+
for (note, length) in song {
28+
let duration = (length * beat_length) as u64;
29+
match note {
30+
Note::Pitch(freq) => sound.play_pitch(*freq as u32, duration).await,
31+
Note::Rest => Timer::after_millis(duration).await,
32+
}
33+
}
34+
}
35+
}

boards/phoenix/src/music/songs.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! A bunch of songs to play with the buzzer.
2+
use Note::{Pitch, Rest};
3+
4+
use crate::music::types::Melody;
5+
use crate::music::types::Note;
6+
7+
pub const A4: Note = Pitch(440);
8+
pub const C4: Note = Pitch(262);
9+
pub const D4: Note = Pitch(294);
10+
pub const E4: Note = Pitch(330);
11+
pub const F4: Note = Pitch(349);
12+
pub const G4: Note = Pitch(392);
13+
pub const C5: Note = Pitch(523);
14+
pub const E5: Note = Pitch(659);
15+
pub const G5: Note = Pitch(784);
16+
17+
pub const TEMPO: f32 = 120.0;
18+
pub const PLAYLIST: [Melody; 2] = [MARIO_MELODY, TWINKLE_MELODY];
19+
20+
pub const MARIO_MELODY: Melody = &[
21+
(E5, 0.25),
22+
(E5, 0.25),
23+
(Rest, 0.25),
24+
(E5, 0.25),
25+
(Rest, 0.25),
26+
(C5, 0.25),
27+
(E5, 0.25),
28+
(Rest, 0.25),
29+
(G5, 0.5),
30+
(Rest, 0.5),
31+
(G4, 0.5),
32+
(Rest, 0.5),
33+
];
34+
35+
/// Melody for "Twinkle, Twinkle, Little Star"
36+
pub const TWINKLE_MELODY: Melody = &[
37+
(C4, 1.0),
38+
(C4, 1.0),
39+
(G4, 1.0),
40+
(G4, 1.0),
41+
(A4, 1.0),
42+
(A4, 1.0),
43+
(G4, 2.0),
44+
(Rest, 0.5),
45+
(F4, 1.0),
46+
(F4, 1.0),
47+
(E4, 1.0),
48+
(E4, 1.0),
49+
(D4, 1.0),
50+
(D4, 1.0),
51+
(C4, 2.0),
52+
];

boards/phoenix/src/music/tasks.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use crate::{
2+
music::{
3+
service::MusicService,
4+
songs::{PLAYLIST, TEMPO},
5+
},
6+
utils::types::AsyncMutex,
7+
};
8+
9+
#[embassy_executor::task]
10+
pub async fn play_music_forever(music: &'static AsyncMutex<MusicService>) {
11+
for song in PLAYLIST.iter().cycle() {
12+
let guard = music.lock().await;
13+
guard.play_song(song, TEMPO).await;
14+
}
15+
}

0 commit comments

Comments
 (0)