From 9e862774cbc67a64b777aa0ba4f6a5b7d8ab5284 Mon Sep 17 00:00:00 2001 From: JP Stringham Date: Thu, 12 Feb 2026 21:23:35 -0500 Subject: [PATCH] lol I am very dumb saturating add on tick instead of wrapping --- .cargo/config.toml | 2 +- Cargo.lock | 4 +- Cargo.toml | 2 +- src/main.rs | 136 ++++++++++++++++++++++++++++++--------------- 4 files changed, 95 insertions(+), 49 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index a492de7..a984432 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -32,7 +32,7 @@ rustflags = [ # This runner will find a supported SWD debug probe and flash your RP2040 over # SWD: -runner = "probe-rs run --chip RP2040 --protocol swd" +runner = "probe-rs run --chip RP2040 --protocol swd --speed 150" [env] DEFMT_RTT_BUFFER_SIZE = { value = "4096", force = true } diff --git a/Cargo.lock b/Cargo.lock index 2cb63e9..67c829e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -586,9 +586,9 @@ checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "usb-device" diff --git a/Cargo.toml b/Cargo.toml index dab4cc8..a943192 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" cortex-m = { version = "0.7.7", features = [ "critical-section-single-core" ] } cortex-m-rt = "0.7.5" defmt = "1.0.1" -defmt-rtt = "1.0.0" +defmt-rtt = "1.1.0" embedded-hal = "1.0.0" panic-probe = { version = "1.0.0", features = [ "print-rtt" ]} rp2040-boot2 = "0.3.0" diff --git a/src/main.rs b/src/main.rs index 4e60274..d252563 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,33 +2,31 @@ #![no_main] use cortex_m::prelude::_embedded_hal_PwmPin; -use defmt::info; -use defmt::{println, write}; +use defmt::info; +use defmt::println; use defmt_rtt as _; use panic_probe as _; +use rp2040_hal::pll::PLLConfig; +use rp2040_hal::pll::common_configs::PLL_USB_48MHZ; // Alias for our HAL crate use rp2040_hal as hal; -// A shorter alias for the Peripheral Access Crate, which provides low-level -// register access use hal::fugit::RateExtU32; use hal::pac; -// Some traits we need +use embedded_hal::digital::InputPin; use embedded_hal::digital::OutputPin; -use embedded_hal::digital::{InputPin, StatefulOutputPin}; use sh1106_pico_rs::graphics::GraphicsBuf; use sh1106_pico_rs::sh1106::SH1106Dev; -/// The linker will place this boot block at the start of our program image. We -/// need this to help the ROM bootloader get our code up and running. -/// Note: This boot block is not necessary when using a rp-hal based BSP -/// as the BSPs already perform this step. +/// NB if OVERCLOCKING +/// you MUST use a BOOT_LOADER which can tolerate the OC +/// the GENERIC_03H one cannot (unsure why) but W25Q080 has been solid for me #[unsafe(link_section = ".boot_loader")] #[used] -pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H; +pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; /// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust /// if your board has a different frequency @@ -41,21 +39,51 @@ fn main() -> ! { 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); + // let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); + + hal::vreg::set_voltage( + &mut pac.VREG_AND_CHIP_RESET, + pac::vreg_and_chip_reset::vreg::VSEL_A::VOLTAGE1_30, + ); + // settle + // cortex_m::asm::delay(3_000_000); + + let xosc = hal::xosc::setup_xosc_blocking_custom_delay(pac.XOSC, XTAL_FREQ_HZ.Hz(), 128) + .map_err(|_x| false) + .unwrap(); + + // watchdog.enable_tick_generation((XTAL_FREQ_HZ / 1_000_000) as u8); // Configure the clocks - let clocks = hal::clocks::init_clocks_and_plls( - XTAL_FREQ_HZ, - pac.XOSC, - pac.CLOCKS, - pac.PLL_SYS, + let mut clocks = hal::clocks::ClocksManager::new(pac.CLOCKS); + + let pll_usb = rp2040_hal::pll::setup_pll_blocking( pac.PLL_USB, + xosc.operating_frequency(), + PLL_USB_48MHZ, + &mut clocks, &mut pac.RESETS, - &mut watchdog, ) .unwrap(); - let mut delay = cortex_m::delay::Delay::new(core.SYST, 133_000_000u32); + let pll_sys = hal::pll::setup_pll_blocking( + pac.PLL_SYS, + xosc.operating_frequency(), + PLLConfig { + vco_freq: 1500.MHz(), + refdiv: 1, + post_div1: 5, + post_div2: 1, + }, + &mut clocks, + &mut pac.RESETS, + ) + .unwrap(); + + clocks.init_default(&xosc, &pll_sys, &pll_usb).unwrap(); + + // let mut delay = cortex_m::delay::Delay::new(core.SYST, 200_000_000); + // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); @@ -67,14 +95,6 @@ fn main() -> ! { &mut pac.RESETS, ); - let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS); - let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26.into_floating_input()).unwrap(); - let mut adc_fifo = adc - .build_fifo() - .set_channel(&mut adc_pin) - .clock_divider(47999, 0) - .start_paused(); - let mut led_pin = pins.gpio25.into_push_pull_output(); led_pin.set_high(); @@ -83,11 +103,15 @@ fn main() -> ! { // Configure PWM0 let pwm0 = &mut pwm_slices.pwm0; - pwm0.set_ph_correct(); + pwm0.clr_ph_correct(); + pwm0.set_div_int(1); pwm0.set_div_frac(0); - pwm0.disable(); + pwm0.clear_interrupt(); + pwm0.enable(); - pwm0.channel_a.output_to(pins.gpio16); + let mut pwm_pin = pins.gpio16; + pwm_pin.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwelveMilliAmps); + pwm0.channel_a.output_to(pwm_pin); let mut on_off_input = pins.gpio15.into_pull_up_input(); @@ -99,7 +123,7 @@ fn main() -> ! { let mut broadcast_on = false; - let mut current_tune = 12; + let mut current_tune = 10; const MAX_TUNE: u16 = 350u16; const MIN_TUNE: u16 = 4u16; @@ -117,30 +141,36 @@ fn main() -> ! { &clocks.system_clock, ); + let mut delay = cortex_m::delay::Delay::new(core.SYST, 200_000); + let mut sh1106_dev = SH1106Dev::new(&mut delay, &mut i2c); sh1106_dev.set_vertical_flip(&mut i2c, true); let sh1106_dev = sh1106_dev; let mut gfx_buf = GraphicsBuf::new(); - let mut last_gfx_update = 0u32; - // Infinite loop, fading LED up and down loop { - tick = tick.saturating_add(1); + tick = tick.wrapping_add(1); - if tick.wrapping_sub(last_gfx_update) > 1_000_000 { + if tick.wrapping_sub(last_gfx_update) > 500_000 { gfx_buf.clear(); gfx_buf.draw_string(20, 14, "Hello Radio!"); - let tuned_freq = 125_000u32 / (current_tune * 2) as u32; + let tuned_freq = 272_000u32 / (current_tune as u32); let mut tune_str_buf = [0u8; 5]; - u16_into_str(tuned_freq as u16, &mut tune_str_buf); - let tune_str = str::from_utf8(&tune_str_buf).unwrap(); - info!("{}, {}", tune_str, tune_str.len()); + let len = u32_into_str(tuned_freq, &mut tune_str_buf); + let tune_str = str::from_utf8(&tune_str_buf[tune_str_buf.len() - len..]).unwrap(); + // info!("val {}, len {}", tuned_freq, len); + // info!("{}, {}", tune_str, tune_str.len()); gfx_buf.draw_string(20, 28, tune_str); + gfx_buf.sprites[0].y = match gfx_buf.sprites[0].y { + 32 => 33, + _ => 32, + }; - u16_into_str(current_tune, &mut tune_str_buf); - let tune_str = str::from_utf8(&tune_str_buf).unwrap(); + let len = u32_into_str(current_tune as u32, &mut tune_str_buf); + let tune_str = str::from_utf8(&tune_str_buf[tune_str_buf.len() - len..]).unwrap(); + // info!("len {}", len); gfx_buf.draw_string(64, 28, tune_str); @@ -159,6 +189,7 @@ fn main() -> ! { } if on_off_input.is_low().unwrap() { + info!("Broadcast toggle"); last_input = tick; broadcast_on = !broadcast_on; @@ -170,6 +201,7 @@ fn main() -> ! { } if tune_up_input.is_low().unwrap() { + info!("Tune UP"); last_input = tick; current_tune = MAX_TUNE.min(current_tune + 2); pwm0.set_top(current_tune); @@ -178,6 +210,7 @@ fn main() -> ! { } if tune_dn_input.is_low().unwrap() { + info!("Tune DOWN"); last_input = tick; current_tune = MIN_TUNE.max(current_tune - 2); pwm0.set_top(current_tune); @@ -186,10 +219,23 @@ fn main() -> ! { } } -fn u16_into_str(mut value: u16, str_buf: &mut [u8; 5]) { - for i in 0..5 { - str_buf[4 - i] = b'0' + (value % 10) as u8; +// returns the length of the final str removing leading zeroes +fn u32_into_str(mut value: u32, str_buf: &mut [u8]) -> usize { + let mut len = str_buf.len(); + + // info!("val {}", value); + for i in 0..len { + // info!("val {}, i {}, digit {}", value, i, value % 10); + str_buf[len - i - 1] = b'0' + (value % 10) as u8; value /= 10; + + if value <= 0 { + // info!("Ran out of digits at {}", i); + len = i + 1; + break; + } } - info!("utf8 buf {}", str_buf); + // info!("utf8 buf {}, len {}", str_buf, len); + + len }