From 24d6ca51f7a97e6dcb8c2eeddffdc20596af72b9 Mon Sep 17 00:00:00 2001 From: sebastian-nae Date: Fri, 31 Mar 2023 20:46:55 +0300 Subject: [PATCH 01/10] Added Buzzer --- Cargo.toml | 2 + apis/buzzer/Cargo.toml | 14 +++ apis/buzzer/src/lib.rs | 160 ++++++++++++++++++++++++++++++ apis/buzzer/src/tests.rs | 32 ++++++ examples/music.rs | 101 +++++++++++++++++++ src/lib.rs | 6 ++ unittest/src/fake/buzzer/mod.rs | 71 +++++++++++++ unittest/src/fake/buzzer/tests.rs | 20 ++++ unittest/src/fake/mod.rs | 2 + 9 files changed, 408 insertions(+) create mode 100644 apis/buzzer/Cargo.toml create mode 100644 apis/buzzer/src/lib.rs create mode 100644 apis/buzzer/src/tests.rs create mode 100644 examples/music.rs create mode 100644 unittest/src/fake/buzzer/mod.rs create mode 100644 unittest/src/fake/buzzer/tests.rs diff --git a/Cargo.toml b/Cargo.toml index aefbca93..c5766c92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ libtock_low_level_debug = { path = "apis/low_level_debug" } libtock_platform = { path = "platform" } libtock_runtime = { path = "runtime" } libtock_temperature = { path = "apis/temperature" } +libtock_buzzer = {path = "apis/buzzer"} [profile.dev] panic = "abort" @@ -34,6 +35,7 @@ debug = true [workspace] exclude = ["tock"] members = [ + "apis/buzzer", "apis/alarm", "apis/gpio", "apis/buttons", diff --git a/apis/buzzer/Cargo.toml b/apis/buzzer/Cargo.toml new file mode 100644 index 00000000..09f460da --- /dev/null +++ b/apis/buzzer/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "libtock_buzzer" +version = "0.1.0" +authors = ["Tock Project Developers "] +license = "MIT/Apache-2.0" +edition = "2021" +repository = "https://www.github.com/tock/libtock-rs" +description = "libtock buzzer driver" + +[dependencies] +libtock_platform = { path = "../../platform" } + +[dev-dependencies] +libtock_unittest = { path = "../../unittest" } diff --git a/apis/buzzer/src/lib.rs b/apis/buzzer/src/lib.rs new file mode 100644 index 00000000..252deca5 --- /dev/null +++ b/apis/buzzer/src/lib.rs @@ -0,0 +1,160 @@ +#![no_std] + +use core::cell::Cell; + +use libtock_platform::{ + share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, +}; +pub struct Buzzer(S); + +impl Buzzer { + pub fn exists() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() + } + pub fn tone(freq: u32, duration: u32) -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, BUZZER_ON, freq, duration).to_result() + } + pub fn register_listener<'share, F: Fn(i32)>( + listener: &'share BuzzerListener, + subscribe: share::Handle>, + ) -> Result<(), ErrorCode> { + S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) + } + + pub fn unregister_listener() { + S::unsubscribe(DRIVER_NUM, 0) + } + + pub fn tone_sync(freq: u32, duration: u32) -> Result<(), ErrorCode> { + let buzzer_cell: Cell> = Cell::new(None); + let listener = BuzzerListener(|buzzer_val| { + buzzer_cell.set(Some(buzzer_val)); + }); + share::scope(|subscribe| { + if let Ok(()) = Self::register_listener(&listener, subscribe) { + if let Ok(()) = Self::tone(freq, duration) { + while buzzer_cell.get() == None { + S::yield_wait(); + } + } + } + }); + + match buzzer_cell.get() { + None => Err(ErrorCode::Busy), + Some(_buzzer_val) => Ok(()), + } + } +} + +pub struct BuzzerListener(pub F); +impl Upcall> for BuzzerListener { + fn upcall(&self, _arg0: u32, _arg1: u32, _arg2: u32) { + (self.0)(_arg0 as i32); + } +} + +#[cfg(test)] +mod tests; +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x90000; + +// Command IDs +const EXISTS: u32 = 0; +const BUZZER_ON: u32 = 1; + +#[allow(unused)] +pub mod note { + pub const B0: u32 = 31; + pub const C1: u32 = 33; + pub const CS1: u32 = 35; + pub const D1: u32 = 37; + pub const DS1: u32 = 39; + pub const E1: u32 = 41; + pub const F1: u32 = 44; + pub const FS1: u32 = 46; + pub const G1: u32 = 49; + pub const GS1: u32 = 52; + pub const A1: u32 = 55; + pub const AS1: u32 = 58; + pub const B1: u32 = 62; + pub const C2: u32 = 65; + pub const CS2: u32 = 69; + pub const D2: u32 = 73; + pub const DS2: u32 = 78; + pub const E2: u32 = 82; + pub const F2: u32 = 87; + pub const FS2: u32 = 93; + pub const G2: u32 = 98; + pub const GS2: u32 = 104; + pub const A2: u32 = 110; + pub const AS2: u32 = 117; + pub const B2: u32 = 123; + pub const C3: u32 = 131; + pub const CS3: u32 = 139; + pub const D3: u32 = 147; + pub const DS3: u32 = 156; + pub const E3: u32 = 165; + pub const F3: u32 = 175; + pub const FS3: u32 = 185; + pub const G3: u32 = 196; + pub const GS3: u32 = 208; + pub const A3: u32 = 220; + pub const AS3: u32 = 233; + pub const B3: u32 = 247; + pub const C4: u32 = 262; + pub const CS4: u32 = 277; + pub const D4: u32 = 294; + pub const DS4: u32 = 311; + pub const E4: u32 = 330; + pub const F4: u32 = 349; + pub const FS4: u32 = 370; + pub const G4: u32 = 392; + pub const GS4: u32 = 415; + pub const A4: u32 = 440; + pub const AS4: u32 = 466; + pub const B4: u32 = 494; + pub const C5: u32 = 523; + pub const CS5: u32 = 554; + pub const D5: u32 = 587; + pub const DS5: u32 = 622; + pub const E5: u32 = 659; + pub const F5: u32 = 698; + pub const FS5: u32 = 740; + pub const G5: u32 = 784; + pub const GS5: u32 = 831; + pub const A5: u32 = 880; + pub const AS5: u32 = 932; + pub const B5: u32 = 988; + pub const C6: u32 = 1047; + pub const CS6: u32 = 1109; + pub const D6: u32 = 1175; + pub const DS6: u32 = 1245; + pub const E6: u32 = 1319; + pub const F6: u32 = 1397; + pub const FS6: u32 = 1480; + pub const G6: u32 = 1568; + pub const GS6: u32 = 1661; + pub const A6: u32 = 1760; + pub const AS6: u32 = 1865; + pub const B6: u32 = 1976; + pub const C7: u32 = 2093; + pub const CS7: u32 = 2217; + pub const D7: u32 = 2349; + pub const DS7: u32 = 2489; + pub const E7: u32 = 2637; + pub const F7: u32 = 2794; + pub const FS7: u32 = 2960; + pub const G7: u32 = 3136; + pub const GS7: u32 = 3322; + pub const A7: u32 = 3520; + pub const AS7: u32 = 3729; + pub const B7: u32 = 3951; + pub const C8: u32 = 4186; + pub const CS8: u32 = 4435; + pub const D8: u32 = 4699; + pub const DS8: u32 = 4978; +} diff --git a/apis/buzzer/src/tests.rs b/apis/buzzer/src/tests.rs new file mode 100644 index 00000000..3fe945e1 --- /dev/null +++ b/apis/buzzer/src/tests.rs @@ -0,0 +1,32 @@ +use libtock_platform::ErrorCode; +use libtock_unittest::fake; + +type Buzzer = super::Buzzer; + +#[test] +fn no_driver() { + let _kernel = fake::Kernel::new(); + assert_eq!(Buzzer::exists(), Err(ErrorCode::NoDevice)); +} + +#[test] +fn driver_check() { + let kernel = fake::Kernel::new(); + let driver = fake::Buzzer::new(); + kernel.add_driver(&driver); + + assert_eq!(Buzzer::exists(), Ok(())); +} + +#[test] +fn tone() { + let kernel = fake::Kernel::new(); + let driver = fake::Buzzer::new(); + kernel.add_driver(&driver); + + assert_eq!(Buzzer::tone(1000, 100), Ok(())); + assert!(driver.is_busy()); + + assert_eq!(Buzzer::tone(1000, 100), Err(ErrorCode::Busy)); + assert_eq!(Buzzer::tone_sync(1000, 100), Err(ErrorCode::Busy)); +} diff --git a/examples/music.rs b/examples/music.rs new file mode 100644 index 00000000..6b72a6eb --- /dev/null +++ b/examples/music.rs @@ -0,0 +1,101 @@ +//! A simple libtock-rs example. Plays Ode of Joy using the buzzer. +#![no_main] +#![no_std] + +use core::fmt::Write; +use libtock::buzzer::{note, Buzzer}; +use libtock::console::Console; +use libtock::runtime::{set_main, stack_size}; + +set_main! {main} +stack_size! {0x200} + +// Adapted from https://github.com/robsoncouto/arduino-songs + +// Notes in the form of (note_frequency, note_delay in musical terms) +const MELODY: [(u32, i32); 62] = [ + (note::E4, 4), + (note::E4, 4), + (note::F4, 4), + (note::G4, 4), + (note::G4, 4), + (note::F4, 4), + (note::E4, 4), + (note::D4, 4), + (note::C4, 4), + (note::C4, 4), + (note::D4, 4), + (note::E4, 4), + (note::E4, -4), + (note::D4, 8), + (note::D4, 2), + (note::E4, 4), + (note::E4, 4), + (note::F4, 4), + (note::G4, 4), + (note::G4, 4), + (note::F4, 4), + (note::E4, 4), + (note::D4, 4), + (note::C4, 4), + (note::C4, 4), + (note::D4, 4), + (note::E4, 4), + (note::D4, -4), + (note::C4, 8), + (note::C4, 2), + (note::D4, 4), + (note::D4, 4), + (note::E4, 4), + (note::C4, 4), + (note::D4, 4), + (note::E4, 8), + (note::F4, 8), + (note::E4, 4), + (note::C4, 4), + (note::D4, 4), + (note::E4, 8), + (note::F4, 8), + (note::E4, 4), + (note::D4, 4), + (note::C4, 4), + (note::D4, 4), + (note::G3, 2), + (note::E4, 4), + (note::E4, 4), + (note::F4, 4), + (note::G4, 4), + (note::G4, 4), + (note::F4, 4), + (note::E4, 4), + (note::D4, 4), + (note::C4, 4), + (note::C4, 4), + (note::D4, 4), + (note::E4, 4), + (note::D4, -4), + (note::C4, 8), + (note::C4, 2), +]; + +const TEMPO: u32 = 114; +const WHOLE_NOTE: u32 = (60000 * 4) / TEMPO; + +fn main() { + if let Err(_) = Buzzer::exists() { + writeln!(Console::writer(), "There is no available buzzer").unwrap(); + return; + } + + writeln!(Console::writer(), "Ode to Joy").unwrap(); + + for (frequency, duration) in MELODY.iter() { + let mut note_duration = WHOLE_NOTE / duration.unsigned_abs(); + if duration < &0 { + note_duration = note_duration * 15 / 10; + } + + let note_duration = note_duration * 9 / 10; + Buzzer::tone_sync(frequency * 3, note_duration).unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index c13b39db..33645a70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,3 +44,9 @@ pub mod temperature { pub type Temperature = temperature::Temperature; pub use temperature::TemperatureListener; } + +pub mod buzzer { + use libtock_buzzer as buzzer; + pub type Buzzer = buzzer::Buzzer; + pub use buzzer::note; +} diff --git a/unittest/src/fake/buzzer/mod.rs b/unittest/src/fake/buzzer/mod.rs new file mode 100644 index 00000000..6fa1e530 --- /dev/null +++ b/unittest/src/fake/buzzer/mod.rs @@ -0,0 +1,71 @@ +use crate::{DriverInfo, DriverShareRef}; +use core::cell::Cell; +use libtock_platform::{CommandReturn, ErrorCode}; + +pub struct Buzzer { + busy: Cell, + upcall_on_command: [Cell>; 2], + share_ref: DriverShareRef, +} + +impl Buzzer { + pub fn new() -> std::rc::Rc { + std::rc::Rc::new(Buzzer { + busy: Cell::new(false), + upcall_on_command: [Cell::new(None), Cell::new(None)], + share_ref: Default::default(), + }) + } + + pub fn is_busy(&self) -> bool { + self.busy.get() + } + + pub fn set_tone(&self, freq: i32, duration: i32) { + if self.busy.get() { + self.share_ref + .schedule_upcall(0, (freq as u32, duration as u32, 0)) + .expect("Unable to schedule upcall"); + self.busy.set(false); + } + } + + pub fn set_tone_sync(&self, freq: i32, duration: i32) { + self.upcall_on_command[0].set(Some(freq)); + self.upcall_on_command[1].set(Some(duration)); + } +} + +impl crate::fake::SyscallDriver for Buzzer { + fn info(&self) -> DriverInfo { + DriverInfo::new(DRIVER_NUM) + } + + fn command(&self, command_num: u32, argument0: u32, argument1: u32) -> CommandReturn { + match command_num { + DRIVER_CHECK => crate::command_return::success(), + BUZZER_ON => { + if self.busy.get() { + return crate::command_return::failure(ErrorCode::Busy); + } + self.busy.set(true); + self.set_tone(argument0 as i32, argument1 as i32); + crate::command_return::success() + } + _ => crate::command_return::failure(ErrorCode::NoSupport), + } + } +} + +#[cfg(test)] +mod tests; + +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x90000; + +// Command IDs +const DRIVER_CHECK: u32 = 0; +const BUZZER_ON: u32 = 1; diff --git a/unittest/src/fake/buzzer/tests.rs b/unittest/src/fake/buzzer/tests.rs new file mode 100644 index 00000000..108fdb9e --- /dev/null +++ b/unittest/src/fake/buzzer/tests.rs @@ -0,0 +1,20 @@ +use crate::fake; +use fake::buzzer::*; +use libtock_platform::ErrorCode; + +#[test] +fn command() { + use fake::SyscallDriver; + let buzzer = Buzzer::new(); + let value = buzzer.command(DRIVER_CHECK, 1, 2); + assert_eq!(value.get_success_u32(), Some(1)); + assert_eq!( + buzzer.command(BUZZER_ON, 0, 0).get_failure(), + Some(ErrorCode::Invalid) + ); + assert_eq!(buzzer.get_buzzer(), false); + assert!(buzzer.command(BUZZER_ON, 1, 1).is_success()); + assert_eq!(buzzer.get_buzzer(), true); + assert!(buzzer.command(BUZZER_OFF, 0, 0).is_success()); + assert_eq!(buzzer.get_buzzer(), false); +} diff --git a/unittest/src/fake/mod.rs b/unittest/src/fake/mod.rs index bf29e4ff..1ad0fdea 100644 --- a/unittest/src/fake/mod.rs +++ b/unittest/src/fake/mod.rs @@ -11,6 +11,7 @@ mod alarm; mod buttons; +mod buzzer; mod console; mod gpio; mod kernel; @@ -22,6 +23,7 @@ mod temperature; pub use alarm::Alarm; pub use buttons::Buttons; +pub use buzzer::Buzzer; pub use console::Console; pub use gpio::{Gpio, GpioMode, InterruptEdge, PullMode}; pub use kernel::Kernel; From 144308de7d3198b2b17d5f39aca0e1c852dd32ef Mon Sep 17 00:00:00 2001 From: sebastian-nae Date: Fri, 31 Mar 2023 21:28:04 +0300 Subject: [PATCH 02/10] Finished Unittests --- apis/buzzer/src/tests.rs | 10 +++++ unittest/src/fake/buzzer/mod.rs | 24 ++++++++---- unittest/src/fake/buzzer/tests.rs | 64 +++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 20 deletions(-) diff --git a/apis/buzzer/src/tests.rs b/apis/buzzer/src/tests.rs index 3fe945e1..9b4913e4 100644 --- a/apis/buzzer/src/tests.rs +++ b/apis/buzzer/src/tests.rs @@ -30,3 +30,13 @@ fn tone() { assert_eq!(Buzzer::tone(1000, 100), Err(ErrorCode::Busy)); assert_eq!(Buzzer::tone_sync(1000, 100), Err(ErrorCode::Busy)); } + +#[test] +fn tone_sync() { + let kernel = fake::Kernel::new(); + let driver = fake::Buzzer::new(); + kernel.add_driver(&driver); + + driver.set_tone_sync(1000, 100); + assert_eq!(Buzzer::tone_sync(1000, 100), Ok(())); +} diff --git a/unittest/src/fake/buzzer/mod.rs b/unittest/src/fake/buzzer/mod.rs index 6fa1e530..531de113 100644 --- a/unittest/src/fake/buzzer/mod.rs +++ b/unittest/src/fake/buzzer/mod.rs @@ -1,6 +1,6 @@ use crate::{DriverInfo, DriverShareRef}; -use core::cell::Cell; use libtock_platform::{CommandReturn, ErrorCode}; +use std::cell::Cell; pub struct Buzzer { busy: Cell, @@ -38,18 +38,26 @@ impl Buzzer { impl crate::fake::SyscallDriver for Buzzer { fn info(&self) -> DriverInfo { - DriverInfo::new(DRIVER_NUM) + DriverInfo::new(DRIVER_NUM).upcall_count(1) } - fn command(&self, command_num: u32, argument0: u32, argument1: u32) -> CommandReturn { + fn register(&self, share_ref: DriverShareRef) { + self.share_ref.replace(share_ref); + } + + fn command(&self, command_num: u32, _argument0: u32, _argument1: u32) -> CommandReturn { match command_num { - DRIVER_CHECK => crate::command_return::success(), - BUZZER_ON => { + EXISTS => crate::command_return::success(), + TONE => { if self.busy.get() { return crate::command_return::failure(ErrorCode::Busy); } self.busy.set(true); - self.set_tone(argument0 as i32, argument1 as i32); + if let Some(freq) = self.upcall_on_command[0].take() { + if let Some(duration) = self.upcall_on_command[1].take() { + self.set_tone(freq, duration); + } + } crate::command_return::success() } _ => crate::command_return::failure(ErrorCode::NoSupport), @@ -67,5 +75,5 @@ mod tests; const DRIVER_NUM: u32 = 0x90000; // Command IDs -const DRIVER_CHECK: u32 = 0; -const BUZZER_ON: u32 = 1; +const EXISTS: u32 = 0; +const TONE: u32 = 1; diff --git a/unittest/src/fake/buzzer/tests.rs b/unittest/src/fake/buzzer/tests.rs index 108fdb9e..cce17322 100644 --- a/unittest/src/fake/buzzer/tests.rs +++ b/unittest/src/fake/buzzer/tests.rs @@ -1,20 +1,60 @@ -use crate::fake; +use crate::fake::{self, SyscallDriver}; use fake::buzzer::*; -use libtock_platform::ErrorCode; +use libtock_platform::{share, DefaultConfig, YieldNoWaitReturn}; #[test] fn command() { - use fake::SyscallDriver; let buzzer = Buzzer::new(); - let value = buzzer.command(DRIVER_CHECK, 1, 2); - assert_eq!(value.get_success_u32(), Some(1)); + assert!(buzzer.command(EXISTS, 1, 2).is_success()); + assert!(buzzer.command(TONE, 0, 0).is_success()); + + assert_eq!( + buzzer.command(TONE, 0, 0).get_failure(), + Some(ErrorCode::Busy) + ); + + buzzer.set_tone(100, 100); + assert!(buzzer.command(TONE, 0, 1).is_success()); + buzzer.set_tone(100, 100); + + buzzer.set_tone_sync(100, 100); + assert!(buzzer.command(TONE, 0, 1).is_success()); + assert!(buzzer.command(TONE, 0, 1).is_success()); +} + +#[test] +fn kernel_integration() { + use libtock_platform::Syscalls; + let kernel = fake::Kernel::new(); + let buzzer = Buzzer::new(); + kernel.add_driver(&buzzer); + + assert!(fake::Syscalls::command(DRIVER_NUM, EXISTS, 1, 2).is_success()); + assert!(fake::Syscalls::command(DRIVER_NUM, TONE, 0, 0).is_success()); assert_eq!( - buzzer.command(BUZZER_ON, 0, 0).get_failure(), - Some(ErrorCode::Invalid) + fake::Syscalls::command(DRIVER_NUM, TONE, 0, 0).get_failure(), + Some(ErrorCode::Busy) ); - assert_eq!(buzzer.get_buzzer(), false); - assert!(buzzer.command(BUZZER_ON, 1, 1).is_success()); - assert_eq!(buzzer.get_buzzer(), true); - assert!(buzzer.command(BUZZER_OFF, 0, 0).is_success()); - assert_eq!(buzzer.get_buzzer(), false); + buzzer.set_tone(100, 100); + assert!(fake::Syscalls::command(DRIVER_NUM, TONE, 0, 1).is_success()); + + let listener = Cell::>::new(None); + share::scope(|subscribe| { + assert_eq!( + fake::Syscalls::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, &listener), + Ok(()) + ); + + buzzer.set_tone(100, 100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(listener.get(), Some((100,))); + + buzzer.set_tone(200, 100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + + assert!(fake::Syscalls::command(DRIVER_NUM, TONE, 0, 1).is_success()); + buzzer.set_tone(200, 100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(listener.get(), Some((200,))); + }); } From f2c7096529321b7729e689e06316aae2ddec65a2 Mon Sep 17 00:00:00 2001 From: sebastian-nae Date: Sat, 1 Apr 2023 23:28:04 +0300 Subject: [PATCH 03/10] Added comments and give credit --- apis/buzzer/src/lib.rs | 13 +++++++++++++ examples/music.rs | 1 + unittest/src/fake/buzzer/mod.rs | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/apis/buzzer/src/lib.rs b/apis/buzzer/src/lib.rs index 252deca5..9d9a1c87 100644 --- a/apis/buzzer/src/lib.rs +++ b/apis/buzzer/src/lib.rs @@ -1,3 +1,5 @@ +//! Implementation started by : https://github.com/teodorobert +//! Continued and modified by : https://github.com/SheepSeb #![no_std] use core::cell::Cell; @@ -8,12 +10,18 @@ use libtock_platform::{ pub struct Buzzer(S); impl Buzzer { + /// Returns Ok() if the driver was present.This does not necessarily mean + /// that the driver is working. pub fn exists() -> Result<(), ErrorCode> { S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() } + + /// Initiate a tone pub fn tone(freq: u32, duration: u32) -> Result<(), ErrorCode> { S::command(DRIVER_NUM, BUZZER_ON, freq, duration).to_result() } + + /// Register an events listener pub fn register_listener<'share, F: Fn(i32)>( listener: &'share BuzzerListener, subscribe: share::Handle>, @@ -21,10 +29,13 @@ impl Buzzer { S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) } + /// Unregister the events listener pub fn unregister_listener() { S::unsubscribe(DRIVER_NUM, 0) } + /// Initiate a synchronous tone + /// Returns Ok() if the operation was successful pub fn tone_sync(freq: u32, duration: u32) -> Result<(), ErrorCode> { let buzzer_cell: Cell> = Cell::new(None); let listener = BuzzerListener(|buzzer_val| { @@ -56,6 +67,7 @@ impl Upcall> for BuzzerListener { #[cfg(test)] mod tests; + // ----------------------------------------------------------------------------- // Driver number and command IDs // ----------------------------------------------------------------------------- @@ -66,6 +78,7 @@ const DRIVER_NUM: u32 = 0x90000; const EXISTS: u32 = 0; const BUZZER_ON: u32 = 1; +/// The notes that can be played by the buzzer #[allow(unused)] pub mod note { pub const B0: u32 = 31; diff --git a/examples/music.rs b/examples/music.rs index 6b72a6eb..15bb57e9 100644 --- a/examples/music.rs +++ b/examples/music.rs @@ -1,3 +1,4 @@ +//! Implementation done by : https://github.com/teodorobert //! A simple libtock-rs example. Plays Ode of Joy using the buzzer. #![no_main] #![no_std] diff --git a/unittest/src/fake/buzzer/mod.rs b/unittest/src/fake/buzzer/mod.rs index 531de113..f408d33e 100644 --- a/unittest/src/fake/buzzer/mod.rs +++ b/unittest/src/fake/buzzer/mod.rs @@ -1,7 +1,16 @@ +//! Fake implementation of the Buzzer API, documented here: +//! +//! Like the real API, `Buzzer` controls a fake buzzer. It provides +//! a function `set_tone` used to immediately call an upcall with a tone set by the buzzer +//! and a function 'set_tone_sync' used to call the upcall when the tone command is received. + use crate::{DriverInfo, DriverShareRef}; use libtock_platform::{CommandReturn, ErrorCode}; use std::cell::Cell; +// The `upcall_on_command` field is set to Some(value) if an upcall(with value as its argument) should be called when tone command is received, +// or None otherwise. It was needed for testing `tone_sync` library function which simulates a synchronous tone set, +// because it was impossible to schedule an upcall during the `synchronous` tone set in other ways. pub struct Buzzer { busy: Cell, upcall_on_command: [Cell>; 2], From 28a07e7c8142c947386835bf4b7ef2b3ac9d13e1 Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Fri, 21 Apr 2023 12:50:52 +0300 Subject: [PATCH 04/10] Added some changes to the Listener --- apis/buzzer/src/lib.rs | 33 +++++++++++---------------------- apis/buzzer/src/tests.rs | 12 +++++++----- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/apis/buzzer/src/lib.rs b/apis/buzzer/src/lib.rs index 9d9a1c87..840951cf 100644 --- a/apis/buzzer/src/lib.rs +++ b/apis/buzzer/src/lib.rs @@ -3,10 +3,9 @@ #![no_std] use core::cell::Cell; +use core::time::Duration; -use libtock_platform::{ - share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, -}; +use libtock_platform::{share, DefaultConfig, ErrorCode, Subscribe, Syscalls}; pub struct Buzzer(S); impl Buzzer { @@ -17,13 +16,13 @@ impl Buzzer { } /// Initiate a tone - pub fn tone(freq: u32, duration: u32) -> Result<(), ErrorCode> { - S::command(DRIVER_NUM, BUZZER_ON, freq, duration).to_result() + pub fn tone(freq: u32, duration: Duration) -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, BUZZER_ON, freq, duration.as_millis() as u32).to_result() } /// Register an events listener - pub fn register_listener<'share, F: Fn(i32)>( - listener: &'share BuzzerListener, + pub fn register_listener<'share>( + listener: &'share Cell>, subscribe: share::Handle>, ) -> Result<(), ErrorCode> { S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) @@ -36,35 +35,25 @@ impl Buzzer { /// Initiate a synchronous tone /// Returns Ok() if the operation was successful - pub fn tone_sync(freq: u32, duration: u32) -> Result<(), ErrorCode> { - let buzzer_cell: Cell> = Cell::new(None); - let listener = BuzzerListener(|buzzer_val| { - buzzer_cell.set(Some(buzzer_val)); - }); + pub fn tone_sync(freq: u32, duration: Duration) -> Result { + let listener = Cell::new(Some((0,))); share::scope(|subscribe| { if let Ok(()) = Self::register_listener(&listener, subscribe) { if let Ok(()) = Self::tone(freq, duration) { - while buzzer_cell.get() == None { + while listener.get() == None { S::yield_wait(); } } } }); - match buzzer_cell.get() { + match listener.get() { None => Err(ErrorCode::Busy), - Some(_buzzer_val) => Ok(()), + Some(buzzer_val) => Ok(buzzer_val.0), } } } -pub struct BuzzerListener(pub F); -impl Upcall> for BuzzerListener { - fn upcall(&self, _arg0: u32, _arg1: u32, _arg2: u32) { - (self.0)(_arg0 as i32); - } -} - #[cfg(test)] mod tests; diff --git a/apis/buzzer/src/tests.rs b/apis/buzzer/src/tests.rs index 9b4913e4..606fe792 100644 --- a/apis/buzzer/src/tests.rs +++ b/apis/buzzer/src/tests.rs @@ -1,3 +1,4 @@ +use core::time::Duration; use libtock_platform::ErrorCode; use libtock_unittest::fake; @@ -23,12 +24,11 @@ fn tone() { let kernel = fake::Kernel::new(); let driver = fake::Buzzer::new(); kernel.add_driver(&driver); - - assert_eq!(Buzzer::tone(1000, 100), Ok(())); + let duration = Duration::from_millis(100); + assert_eq!(Buzzer::tone(1000, duration), Ok(())); assert!(driver.is_busy()); - assert_eq!(Buzzer::tone(1000, 100), Err(ErrorCode::Busy)); - assert_eq!(Buzzer::tone_sync(1000, 100), Err(ErrorCode::Busy)); + assert_eq!(Buzzer::tone(1000, duration), Err(ErrorCode::Busy)); } #[test] @@ -37,6 +37,8 @@ fn tone_sync() { let driver = fake::Buzzer::new(); kernel.add_driver(&driver); + let duration = Duration::from_millis(100); + driver.set_tone_sync(1000, 100); - assert_eq!(Buzzer::tone_sync(1000, 100), Ok(())); + assert_eq!(Buzzer::tone_sync(1000, duration), Ok(0)); } From ed85a80739f48bb586ad033d9a908ba946a70f14 Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Fri, 21 Apr 2023 13:02:11 +0300 Subject: [PATCH 05/10] Changed duration in fake --- unittest/src/fake/buzzer/mod.rs | 7 ++++--- unittest/src/fake/buzzer/tests.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/unittest/src/fake/buzzer/mod.rs b/unittest/src/fake/buzzer/mod.rs index f408d33e..a8551256 100644 --- a/unittest/src/fake/buzzer/mod.rs +++ b/unittest/src/fake/buzzer/mod.rs @@ -5,6 +5,7 @@ //! and a function 'set_tone_sync' used to call the upcall when the tone command is received. use crate::{DriverInfo, DriverShareRef}; +use core::time::Duration; use libtock_platform::{CommandReturn, ErrorCode}; use std::cell::Cell; @@ -30,10 +31,10 @@ impl Buzzer { self.busy.get() } - pub fn set_tone(&self, freq: i32, duration: i32) { + pub fn set_tone(&self, freq: i32, duration: Duration) { if self.busy.get() { self.share_ref - .schedule_upcall(0, (freq as u32, duration as u32, 0)) + .schedule_upcall(0, (freq as u32, duration.as_millis() as u32, 0)) .expect("Unable to schedule upcall"); self.busy.set(false); } @@ -64,7 +65,7 @@ impl crate::fake::SyscallDriver for Buzzer { self.busy.set(true); if let Some(freq) = self.upcall_on_command[0].take() { if let Some(duration) = self.upcall_on_command[1].take() { - self.set_tone(freq, duration); + self.set_tone(freq, Duration::from_millis(duration as u64)); } } crate::command_return::success() diff --git a/unittest/src/fake/buzzer/tests.rs b/unittest/src/fake/buzzer/tests.rs index cce17322..b556ff1f 100644 --- a/unittest/src/fake/buzzer/tests.rs +++ b/unittest/src/fake/buzzer/tests.rs @@ -13,9 +13,9 @@ fn command() { Some(ErrorCode::Busy) ); - buzzer.set_tone(100, 100); + buzzer.set_tone(100, Duration::from_millis(100)); assert!(buzzer.command(TONE, 0, 1).is_success()); - buzzer.set_tone(100, 100); + buzzer.set_tone(100, Duration::from_millis(100)); buzzer.set_tone_sync(100, 100); assert!(buzzer.command(TONE, 0, 1).is_success()); @@ -35,7 +35,7 @@ fn kernel_integration() { fake::Syscalls::command(DRIVER_NUM, TONE, 0, 0).get_failure(), Some(ErrorCode::Busy) ); - buzzer.set_tone(100, 100); + buzzer.set_tone(100, Duration::from_millis(100)); assert!(fake::Syscalls::command(DRIVER_NUM, TONE, 0, 1).is_success()); let listener = Cell::>::new(None); @@ -45,15 +45,15 @@ fn kernel_integration() { Ok(()) ); - buzzer.set_tone(100, 100); + buzzer.set_tone(100, Duration::from_millis(100)); assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); assert_eq!(listener.get(), Some((100,))); - buzzer.set_tone(200, 100); + buzzer.set_tone(200, Duration::from_millis(100)); assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); assert!(fake::Syscalls::command(DRIVER_NUM, TONE, 0, 1).is_success()); - buzzer.set_tone(200, 100); + buzzer.set_tone(200, Duration::from_millis(100)); assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); assert_eq!(listener.get(), Some((200,))); }); From 9719a9a09745b94d6ba52492b7884038c5f706fc Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Fri, 5 May 2023 12:49:36 +0300 Subject: [PATCH 06/10] Changes mod to enum --- apis/buzzer/src/lib.rs | 215 ++++++++++++++++++++------------------- apis/buzzer/src/tests.rs | 2 +- examples/music.rs | 133 ++++++++++++------------ src/lib.rs | 2 +- 4 files changed, 182 insertions(+), 170 deletions(-) diff --git a/apis/buzzer/src/lib.rs b/apis/buzzer/src/lib.rs index 840951cf..94e74cfd 100644 --- a/apis/buzzer/src/lib.rs +++ b/apis/buzzer/src/lib.rs @@ -5,7 +5,9 @@ use core::cell::Cell; use core::time::Duration; -use libtock_platform::{share, DefaultConfig, ErrorCode, Subscribe, Syscalls}; +use libtock_platform::{ + share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, +}; pub struct Buzzer(S); impl Buzzer { @@ -35,22 +37,28 @@ impl Buzzer { /// Initiate a synchronous tone /// Returns Ok() if the operation was successful - pub fn tone_sync(freq: u32, duration: Duration) -> Result { + pub fn tone_sync(freq: u32, duration: Duration) -> Result<(), ErrorCode> { let listener = Cell::new(Some((0,))); - share::scope(|subscribe| { - if let Ok(()) = Self::register_listener(&listener, subscribe) { - if let Ok(()) = Self::tone(freq, duration) { - while listener.get() == None { - S::yield_wait(); - } - } + let result_err: Result<(), ErrorCode> = share::scope(|subscribe| { + Self::register_listener(&listener, subscribe)?; + Self::tone(freq, duration)?; + while listener.get() == None { + S::yield_wait(); + } + match listener.get() { + None => Err(ErrorCode::Fail), + Some(_) => Ok(()), } }); - match listener.get() { - None => Err(ErrorCode::Busy), - Some(buzzer_val) => Ok(buzzer_val.0), - } + result_err + } +} + +pub struct BuzzerListener(pub F); +impl Upcall> for BuzzerListener { + fn upcall(&self, _arg0: u32, _arg1: u32, _arg2: u32) { + (self.0)(_arg0); } } @@ -69,94 +77,95 @@ const BUZZER_ON: u32 = 1; /// The notes that can be played by the buzzer #[allow(unused)] -pub mod note { - pub const B0: u32 = 31; - pub const C1: u32 = 33; - pub const CS1: u32 = 35; - pub const D1: u32 = 37; - pub const DS1: u32 = 39; - pub const E1: u32 = 41; - pub const F1: u32 = 44; - pub const FS1: u32 = 46; - pub const G1: u32 = 49; - pub const GS1: u32 = 52; - pub const A1: u32 = 55; - pub const AS1: u32 = 58; - pub const B1: u32 = 62; - pub const C2: u32 = 65; - pub const CS2: u32 = 69; - pub const D2: u32 = 73; - pub const DS2: u32 = 78; - pub const E2: u32 = 82; - pub const F2: u32 = 87; - pub const FS2: u32 = 93; - pub const G2: u32 = 98; - pub const GS2: u32 = 104; - pub const A2: u32 = 110; - pub const AS2: u32 = 117; - pub const B2: u32 = 123; - pub const C3: u32 = 131; - pub const CS3: u32 = 139; - pub const D3: u32 = 147; - pub const DS3: u32 = 156; - pub const E3: u32 = 165; - pub const F3: u32 = 175; - pub const FS3: u32 = 185; - pub const G3: u32 = 196; - pub const GS3: u32 = 208; - pub const A3: u32 = 220; - pub const AS3: u32 = 233; - pub const B3: u32 = 247; - pub const C4: u32 = 262; - pub const CS4: u32 = 277; - pub const D4: u32 = 294; - pub const DS4: u32 = 311; - pub const E4: u32 = 330; - pub const F4: u32 = 349; - pub const FS4: u32 = 370; - pub const G4: u32 = 392; - pub const GS4: u32 = 415; - pub const A4: u32 = 440; - pub const AS4: u32 = 466; - pub const B4: u32 = 494; - pub const C5: u32 = 523; - pub const CS5: u32 = 554; - pub const D5: u32 = 587; - pub const DS5: u32 = 622; - pub const E5: u32 = 659; - pub const F5: u32 = 698; - pub const FS5: u32 = 740; - pub const G5: u32 = 784; - pub const GS5: u32 = 831; - pub const A5: u32 = 880; - pub const AS5: u32 = 932; - pub const B5: u32 = 988; - pub const C6: u32 = 1047; - pub const CS6: u32 = 1109; - pub const D6: u32 = 1175; - pub const DS6: u32 = 1245; - pub const E6: u32 = 1319; - pub const F6: u32 = 1397; - pub const FS6: u32 = 1480; - pub const G6: u32 = 1568; - pub const GS6: u32 = 1661; - pub const A6: u32 = 1760; - pub const AS6: u32 = 1865; - pub const B6: u32 = 1976; - pub const C7: u32 = 2093; - pub const CS7: u32 = 2217; - pub const D7: u32 = 2349; - pub const DS7: u32 = 2489; - pub const E7: u32 = 2637; - pub const F7: u32 = 2794; - pub const FS7: u32 = 2960; - pub const G7: u32 = 3136; - pub const GS7: u32 = 3322; - pub const A7: u32 = 3520; - pub const AS7: u32 = 3729; - pub const B7: u32 = 3951; - pub const C8: u32 = 4186; - pub const CS8: u32 = 4435; - pub const D8: u32 = 4699; - pub const DS8: u32 = 4978; +#[repr(u32)] +pub enum Note { + B0 = 31, + C1 = 33, + CS1 = 35, + D1 = 37, + DS1 = 39, + E1 = 41, + F1 = 44, + FS1 = 46, + G1 = 49, + GS1 = 52, + A1 = 55, + AS1 = 58, + B1 = 62, + C2 = 65, + CS2 = 69, + D2 = 73, + DS2 = 78, + E2 = 82, + F2 = 87, + FS2 = 93, + G2 = 98, + GS2 = 104, + A2 = 110, + AS2 = 117, + B2 = 123, + C3 = 131, + CS3 = 139, + D3 = 147, + DS3 = 156, + E3 = 165, + F3 = 175, + FS3 = 185, + G3 = 196, + GS3 = 208, + A3 = 220, + AS3 = 233, + B3 = 247, + C4 = 262, + CS4 = 277, + D4 = 294, + DS4 = 311, + E4 = 330, + F4 = 349, + FS4 = 370, + G4 = 392, + GS4 = 415, + A4 = 440, + AS4 = 466, + B4 = 494, + C5 = 523, + CS5 = 554, + D5 = 587, + DS5 = 622, + E5 = 659, + F5 = 698, + FS5 = 740, + G5 = 784, + GS5 = 831, + A5 = 880, + AS5 = 932, + B5 = 988, + C6 = 1047, + CS6 = 1109, + D6 = 1175, + DS6 = 1245, + E6 = 1319, + F6 = 1397, + FS6 = 1480, + G6 = 1568, + GS6 = 1661, + A6 = 1760, + AS6 = 1865, + B6 = 1976, + C7 = 2093, + CS7 = 2217, + D7 = 2349, + DS7 = 2489, + E7 = 2637, + F7 = 2794, + FS7 = 2960, + G7 = 3136, + GS7 = 3322, + A7 = 3520, + AS7 = 3729, + B7 = 3951, + C8 = 4186, + CS8 = 4435, + D8 = 4699, + DS8 = 4978, } diff --git a/apis/buzzer/src/tests.rs b/apis/buzzer/src/tests.rs index 606fe792..176b9782 100644 --- a/apis/buzzer/src/tests.rs +++ b/apis/buzzer/src/tests.rs @@ -40,5 +40,5 @@ fn tone_sync() { let duration = Duration::from_millis(100); driver.set_tone_sync(1000, 100); - assert_eq!(Buzzer::tone_sync(1000, duration), Ok(0)); + assert_eq!(Buzzer::tone_sync(1000, duration), Ok(())); } diff --git a/examples/music.rs b/examples/music.rs index 15bb57e9..6fef9de5 100644 --- a/examples/music.rs +++ b/examples/music.rs @@ -4,7 +4,8 @@ #![no_std] use core::fmt::Write; -use libtock::buzzer::{note, Buzzer}; +use core::time::Duration; +use libtock::buzzer::{Buzzer, Note}; use libtock::console::Console; use libtock::runtime::{set_main, stack_size}; @@ -14,69 +15,69 @@ stack_size! {0x200} // Adapted from https://github.com/robsoncouto/arduino-songs // Notes in the form of (note_frequency, note_delay in musical terms) -const MELODY: [(u32, i32); 62] = [ - (note::E4, 4), - (note::E4, 4), - (note::F4, 4), - (note::G4, 4), - (note::G4, 4), - (note::F4, 4), - (note::E4, 4), - (note::D4, 4), - (note::C4, 4), - (note::C4, 4), - (note::D4, 4), - (note::E4, 4), - (note::E4, -4), - (note::D4, 8), - (note::D4, 2), - (note::E4, 4), - (note::E4, 4), - (note::F4, 4), - (note::G4, 4), - (note::G4, 4), - (note::F4, 4), - (note::E4, 4), - (note::D4, 4), - (note::C4, 4), - (note::C4, 4), - (note::D4, 4), - (note::E4, 4), - (note::D4, -4), - (note::C4, 8), - (note::C4, 2), - (note::D4, 4), - (note::D4, 4), - (note::E4, 4), - (note::C4, 4), - (note::D4, 4), - (note::E4, 8), - (note::F4, 8), - (note::E4, 4), - (note::C4, 4), - (note::D4, 4), - (note::E4, 8), - (note::F4, 8), - (note::E4, 4), - (note::D4, 4), - (note::C4, 4), - (note::D4, 4), - (note::G3, 2), - (note::E4, 4), - (note::E4, 4), - (note::F4, 4), - (note::G4, 4), - (note::G4, 4), - (note::F4, 4), - (note::E4, 4), - (note::D4, 4), - (note::C4, 4), - (note::C4, 4), - (note::D4, 4), - (note::E4, 4), - (note::D4, -4), - (note::C4, 8), - (note::C4, 2), +const MELODY: [(Note, i32); 62] = [ + (Note::E4, 4), + (Note::E4, 4), + (Note::F4, 4), + (Note::G4, 4), + (Note::G4, 4), + (Note::F4, 4), + (Note::E4, 4), + (Note::D4, 4), + (Note::C4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::E4, 4), + (Note::E4, -4), + (Note::D4, 8), + (Note::D4, 2), + (Note::E4, 4), + (Note::E4, 4), + (Note::F4, 4), + (Note::G4, 4), + (Note::G4, 4), + (Note::F4, 4), + (Note::E4, 4), + (Note::D4, 4), + (Note::C4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::E4, 4), + (Note::D4, -4), + (Note::C4, 8), + (Note::C4, 2), + (Note::D4, 4), + (Note::D4, 4), + (Note::E4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::E4, 8), + (Note::F4, 8), + (Note::E4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::E4, 8), + (Note::F4, 8), + (Note::E4, 4), + (Note::D4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::G3, 2), + (Note::E4, 4), + (Note::E4, 4), + (Note::F4, 4), + (Note::G4, 4), + (Note::G4, 4), + (Note::F4, 4), + (Note::E4, 4), + (Note::D4, 4), + (Note::C4, 4), + (Note::C4, 4), + (Note::D4, 4), + (Note::E4, 4), + (Note::D4, -4), + (Note::C4, 8), + (Note::C4, 2), ]; const TEMPO: u32 = 114; @@ -91,7 +92,9 @@ fn main() { writeln!(Console::writer(), "Ode to Joy").unwrap(); for (frequency, duration) in MELODY.iter() { - let mut note_duration = WHOLE_NOTE / duration.unsigned_abs(); + let note_duration: Duration = + Duration::from_millis((WHOLE_NOTE / duration.unsigned_abs()) as u64); + // let mut note_duration = WHOLE_NOTE / duration.unsigned_abs(); if duration < &0 { note_duration = note_duration * 15 / 10; } diff --git a/src/lib.rs b/src/lib.rs index 33645a70..5b18befe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,5 +48,5 @@ pub mod temperature { pub mod buzzer { use libtock_buzzer as buzzer; pub type Buzzer = buzzer::Buzzer; - pub use buzzer::note; + pub use buzzer::Note; } From 920f7e487bd3ccd90d590c59d009d11998817d7e Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Fri, 5 May 2023 13:12:02 +0300 Subject: [PATCH 07/10] Changed the example and the lib --- apis/buzzer/src/lib.rs | 20 +++++++++++--------- examples/music.rs | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apis/buzzer/src/lib.rs b/apis/buzzer/src/lib.rs index 94e74cfd..a540b789 100644 --- a/apis/buzzer/src/lib.rs +++ b/apis/buzzer/src/lib.rs @@ -23,8 +23,8 @@ impl Buzzer { } /// Register an events listener - pub fn register_listener<'share>( - listener: &'share Cell>, + pub fn register_listener<'share, F: Fn(u32)>( + listener: &'share BuzzerListener, subscribe: share::Handle>, ) -> Result<(), ErrorCode> { S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) @@ -38,20 +38,21 @@ impl Buzzer { /// Initiate a synchronous tone /// Returns Ok() if the operation was successful pub fn tone_sync(freq: u32, duration: Duration) -> Result<(), ErrorCode> { - let listener = Cell::new(Some((0,))); - let result_err: Result<(), ErrorCode> = share::scope(|subscribe| { + let buzzer_cell: Cell> = Cell::new(None); + let listener = BuzzerListener(|buzzer_val| { + buzzer_cell.set(Some(buzzer_val)); + }); + share::scope(|subscribe| { Self::register_listener(&listener, subscribe)?; Self::tone(freq, duration)?; - while listener.get() == None { + while buzzer_cell.get() == None { S::yield_wait(); } - match listener.get() { + match buzzer_cell.get() { None => Err(ErrorCode::Fail), Some(_) => Ok(()), } - }); - - result_err + }) } } @@ -78,6 +79,7 @@ const BUZZER_ON: u32 = 1; /// The notes that can be played by the buzzer #[allow(unused)] #[repr(u32)] +#[derive(Copy, Clone, Debug)] pub enum Note { B0 = 31, C1 = 33, diff --git a/examples/music.rs b/examples/music.rs index 6fef9de5..5a854911 100644 --- a/examples/music.rs +++ b/examples/music.rs @@ -10,7 +10,7 @@ use libtock::console::Console; use libtock::runtime::{set_main, stack_size}; set_main! {main} -stack_size! {0x200} +stack_size! {0x800} // Adapted from https://github.com/robsoncouto/arduino-songs @@ -92,7 +92,7 @@ fn main() { writeln!(Console::writer(), "Ode to Joy").unwrap(); for (frequency, duration) in MELODY.iter() { - let note_duration: Duration = + let mut note_duration: Duration = Duration::from_millis((WHOLE_NOTE / duration.unsigned_abs()) as u64); // let mut note_duration = WHOLE_NOTE / duration.unsigned_abs(); if duration < &0 { @@ -100,6 +100,6 @@ fn main() { } let note_duration = note_duration * 9 / 10; - Buzzer::tone_sync(frequency * 3, note_duration).unwrap(); + Buzzer::tone_sync(*frequency as u32 * 3, note_duration).unwrap(); } } From fb549ce1c76985fb29ed0b6a8bd50c196732a55f Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Mon, 8 May 2023 14:12:24 +0300 Subject: [PATCH 08/10] Cargo toml in alphabetical order --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c5766c92..98554c4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ version = "0.1.0" [dependencies] libtock_alarm = { path = "apis/alarm" } libtock_buttons = { path = "apis/buttons" } +libtock_buzzer = {path = "apis/buzzer"} libtock_console = { path = "apis/console" } libtock_debug_panic = { path = "panic_handlers/debug_panic" } libtock_gpio = { path = "apis/gpio" } @@ -20,7 +21,6 @@ libtock_low_level_debug = { path = "apis/low_level_debug" } libtock_platform = { path = "platform" } libtock_runtime = { path = "runtime" } libtock_temperature = { path = "apis/temperature" } -libtock_buzzer = {path = "apis/buzzer"} [profile.dev] panic = "abort" @@ -35,7 +35,6 @@ debug = true [workspace] exclude = ["tock"] members = [ - "apis/buzzer", "apis/alarm", "apis/gpio", "apis/buttons", From e86089c475f63a6e5543847af82acd3b1d43b354 Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Mon, 8 May 2023 14:14:44 +0300 Subject: [PATCH 09/10] apis/button in members --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 98554c4c..001f8768 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ members = [ "apis/alarm", "apis/gpio", "apis/buttons", + "apis/buzzer", "apis/console", "apis/leds", "apis/low_level_debug", From fe66077fbfa21a60568712c3d75a39a71f0a4808 Mon Sep 17 00:00:00 2001 From: Sebastian Nae Date: Wed, 17 May 2023 21:18:50 +0300 Subject: [PATCH 10/10] Reorder in lib.rs --- src/lib.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2dab408b..8634a018 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,11 @@ pub mod buttons { pub type Buttons = buttons::Buttons; pub use buttons::{ButtonListener, ButtonState}; } +pub mod buzzer { + use libtock_buzzer as buzzer; + pub type Buzzer = buzzer::Buzzer; + pub use buzzer::Note; +} pub mod console { use libtock_console as console; pub type Console = console::Console; @@ -47,9 +52,3 @@ pub mod temperature { pub type Temperature = temperature::Temperature; pub use temperature::TemperatureListener; } - -pub mod buzzer { - use libtock_buzzer as buzzer; - pub type Buzzer = buzzer::Buzzer; - pub use buzzer::Note; -}