From cda24154a4b04fb5ef3da749afaac27fc9114d0d Mon Sep 17 00:00:00 2001 From: Justin Moore Date: Sun, 12 Jun 2022 11:55:37 -0500 Subject: [PATCH] Add an example of using PWMs to generate an audio output --- boards/rp-pico/examples/pico_pwm_audio.raw | Bin 0 -> 76161 bytes boards/rp-pico/examples/pico_pwm_audio.rs | 244 +++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 boards/rp-pico/examples/pico_pwm_audio.raw create mode 100644 boards/rp-pico/examples/pico_pwm_audio.rs diff --git a/boards/rp-pico/examples/pico_pwm_audio.raw b/boards/rp-pico/examples/pico_pwm_audio.raw new file mode 100644 index 0000000000000000000000000000000000000000..23662b2ac64e1b02047775fe8aabdcfc0a7c1a62 GIT binary patch literal 76161 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 literal 0 HcmV?d00001 diff --git a/boards/rp-pico/examples/pico_pwm_audio.rs b/boards/rp-pico/examples/pico_pwm_audio.rs new file mode 100644 index 000000000..2841c8ca5 --- /dev/null +++ b/boards/rp-pico/examples/pico_pwm_audio.rs @@ -0,0 +1,244 @@ +//! # Pico PWM Audio Example +//! +//! Drives GPIO0 with PWM to generate an audio signal for use with a speaker. +//! +//! Note that you will need to supply your own speaker. When hooked up to GPIO0, +//! you should hear an audible chime. +//! +//! See the `Cargo.toml` file for Copyright and license details. + +#![no_std] +#![no_main] + +use embedded_hal::digital::v2::OutputPin; +use hal::{ + clocks::{ClocksManager, InitError}, + pac::interrupt, + pll::{common_configs::PLL_USB_48MHZ, PLLConfig}, + pwm::{FreeRunning, Pwm0}, + Watchdog, +}; + +// The macro for our start-up function +use rp_pico::entry; + +// GPIO traits +use embedded_hal::PwmPin; + +// Time handling traits +use embedded_time::rate::*; + +// Ensure we halt the program on panic (if we don't mention this crate it won't +// be linked) +use panic_halt as _; + +// Pull in any important traits +use rp_pico::hal::prelude::*; + +// A shorter alias for the Peripheral Access Crate, which provides low-level +// register access +use rp_pico::hal::pac; + +// A shorter alias for the Hardware Abstraction Layer, which provides +// higher-level drivers. +use rp_pico::hal; + +/// Signed 8-bit raw PCM samples +/// +/// If you want to create your own, use Audacity to create a recording with a +/// sample rate of 32,000 Hz and then export it as raw 8-bit signed PCM with no +/// file header. +const AUDIO: &'static [u8] = include_bytes!("pico_pwm_audio.raw"); + +/// The hardware PWM driver that is shared with the interrupt routine. +static mut PWM: Option> = None; + +// Output from vocalc.py +/// This clock rate is closest to 176,400,000 Hz, which is a multiple of 44,100 Hz. +#[allow(dead_code)] +const PLL_SYS_176MHZ: PLLConfig = PLLConfig { + vco_freq: Megahertz(528), + refdiv: 1, + post_div1: 3, + post_div2: 1, +}; + +/// This clock rate is closest to 131,072,000 Hz, which is a multiple of 32,000 Hz (the audio sample rate). +#[allow(dead_code)] +const PLL_SYS_131MHZ: PLLConfig = PLLConfig { + vco_freq: Megahertz(1572), + refdiv: 1, + post_div1: 6, + post_div2: 2, +}; + +/// Initialize system clocks and PLLs according to specified configs +#[allow(clippy::too_many_arguments)] +fn init_clocks_and_plls_cfg( + xosc_crystal_freq: u32, + xosc_dev: pac::XOSC, + clocks_dev: pac::CLOCKS, + pll_sys_dev: pac::PLL_SYS, + pll_usb_dev: pac::PLL_USB, + pll_sys_cfg: PLLConfig, + pll_usb_cfg: PLLConfig, + resets: &mut pac::RESETS, + watchdog: &mut Watchdog, +) -> Result { + let xosc = hal::xosc::setup_xosc_blocking(xosc_dev, xosc_crystal_freq.Hz()) + .map_err(InitError::XoscErr)?; + + // Configure watchdog tick generation to tick over every microsecond + watchdog.enable_tick_generation((xosc_crystal_freq / 1_000_000) as u8); + + let mut clocks = ClocksManager::new(clocks_dev); + + let pll_sys = hal::pll::setup_pll_blocking( + pll_sys_dev, + xosc.operating_frequency().into(), + pll_sys_cfg, + &mut clocks, + resets, + ) + .map_err(InitError::PllError)?; + let pll_usb = hal::pll::setup_pll_blocking( + pll_usb_dev, + xosc.operating_frequency().into(), + pll_usb_cfg, + &mut clocks, + resets, + ) + .map_err(InitError::PllError)?; + + clocks + .init_default(&xosc, &pll_sys, &pll_usb) + .map_err(InitError::ClockError)?; + Ok(clocks) +} + +/// Entry point to our bare-metal application. +/// +/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function +/// as soon as all global variables are initialised. +/// +/// The function configures the RP2040 peripherals, then outputs an audio signal +/// on GPIO0 in an infinite loop. +#[entry] +fn main() -> ! { + // Grab our singleton objects + let mut pac = pac::Peripherals::take().unwrap(); + let core = pac::CorePeripherals::take().unwrap(); + + // Set up the watchdog driver - needed by the clock setup code + let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); + + // Configure the clocks + // Note that we choose a nonstandard system clock rate, so that we can closely + // control the PWM cycles so that they're (close to) a multiple of the audio sample rate. + let clocks = init_clocks_and_plls_cfg( + rp_pico::XOSC_CRYSTAL_FREQ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + PLL_SYS_131MHZ, + PLL_USB_48MHZ, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + // The single-cycle I/O block controls our GPIO pins + let sio = hal::Sio::new(pac.SIO); + + // Set the pins up according to their function on this particular board + let pins = rp_pico::Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + // The delay object lets us wait for specified amounts of time (in + // milliseconds) + let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer()); + + // Init PWMs + let pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); + + // Setup the LED pin + let mut led_pin = pins.led.into_push_pull_output(); + + // Configure PWM0 + let mut pwm = pwm_slices.pwm0; + pwm.default_config(); + + // 131,000,000 Hz divided by (top * div.int). + // + // fPWM = fSYS / ((TOP + 1) * (CSR_PH_CORRECT + 1) * (DIV_INT + (DIV_FRAC / 16))) + // + // 32kHz ~= 131,000,000 / ((4096 + 1) * 1 * 1) + pwm.set_top(4096); + pwm.set_div_int(1); + + pwm.enable_interrupt(); + pwm.enable(); + + // Output channel A on PWM0 to GPIO0 + pwm.channel_a.output_to(pins.gpio0); + + unsafe { + // Share the PWM with our interrupt routine. + PWM = Some(pwm); + + // Unmask the PWM_IRQ_WRAP interrupt so we start receiving events. + pac::NVIC::unmask(pac::interrupt::PWM_IRQ_WRAP); + } + + // N.B: Note that this would be much more efficiently implemented by using a DMA controller + // to continuously feed audio samples to the PWM straight from memory. The hardware + // is set up in a way where a rollover interrupt from the PWM channel can trigger a DMA + // request for the next byte (or u16) of memory. + // So while this is a good illustration for driving an audio signal from PWM, use DMA instead + // for a real project. + + // Infinite loop, with LED on while audio is playing. + loop { + let _ = led_pin.set_high(); + + for i in AUDIO { + // Rescale from signed i8 numbers to 0..4096 (the TOP register we specified earlier) + // + // The PWM channel will increment an internal counter register, and if the counter is + // above or equal to this number, the PWM will output a logic high signal. + let i = ((*i as u16) << 4).wrapping_add(2048) & 0xFFF; + + cortex_m::interrupt::free(|_| { + // SAFETY: Interrupt cannot currently use this while we're in a critical section. + let channel = &mut unsafe { PWM.as_mut() }.unwrap().channel_a; + channel.set_duty(i); + }); + + // Throttle until the PWM channel delivers us an interrupt saying it's done + // with this cycle (the internal counter wrapped). The interrupt handler will + // clear the interrupt and we'll send out the next sample. + cortex_m::asm::wfi(); + } + + // Flash the LED to let the user know that the audio is looping. + let _ = led_pin.set_low(); + delay.delay_ms(50); + } +} + +#[interrupt] +fn PWM_IRQ_WRAP() { + // SAFETY: This is not used outside of interrupt critical sections in the main thread. + let pwm = unsafe { PWM.as_mut() }.unwrap(); + + // Clear the interrupt (so we don't immediately re-enter this routine) + pwm.clear_interrupt(); +} + +// End of file