Menus, pwm, led clock speeds oh my
This commit is contained in:
158
src/main.rs
158
src/main.rs
@@ -1,16 +1,12 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
mod menu;
|
||||||
mod onboard_led;
|
mod onboard_led;
|
||||||
|
|
||||||
use core::u16::MIN;
|
|
||||||
|
|
||||||
use cortex_m::prelude::_embedded_hal_PwmPin;
|
use cortex_m::prelude::_embedded_hal_PwmPin;
|
||||||
|
|
||||||
use defmt::info;
|
|
||||||
use defmt::println;
|
use defmt::println;
|
||||||
use defmt_rtt as _;
|
use defmt_rtt as _;
|
||||||
use embedded_hal::digital::StatefulOutputPin;
|
|
||||||
use panic_probe as _;
|
use panic_probe as _;
|
||||||
|
|
||||||
use rp2040_hal::clocks::ClockSource;
|
use rp2040_hal::clocks::ClockSource;
|
||||||
@@ -21,7 +17,6 @@ use rp2040_hal::gpio::FunctionSioOutput;
|
|||||||
use rp2040_hal::gpio::Pin;
|
use rp2040_hal::gpio::Pin;
|
||||||
use rp2040_hal::gpio::PullDown;
|
use rp2040_hal::gpio::PullDown;
|
||||||
use rp2040_hal::gpio::PullNone;
|
use rp2040_hal::gpio::PullNone;
|
||||||
use rp2040_hal::pll;
|
|
||||||
use rp2040_hal::pll::PLLConfig;
|
use rp2040_hal::pll::PLLConfig;
|
||||||
use rp2040_hal::pll::common_configs::PLL_USB_48MHZ;
|
use rp2040_hal::pll::common_configs::PLL_USB_48MHZ;
|
||||||
// Alias for our HAL crate
|
// Alias for our HAL crate
|
||||||
@@ -35,6 +30,7 @@ use embedded_hal::digital::OutputPin;
|
|||||||
use sh1106_pico_rs::graphics::GraphicsBuf;
|
use sh1106_pico_rs::graphics::GraphicsBuf;
|
||||||
use sh1106_pico_rs::sh1106::SH1106Dev;
|
use sh1106_pico_rs::sh1106::SH1106Dev;
|
||||||
|
|
||||||
|
use crate::menu::Menu;
|
||||||
use crate::onboard_led::OnboardLed;
|
use crate::onboard_led::OnboardLed;
|
||||||
|
|
||||||
/// NB if OVERCLOCKING
|
/// NB if OVERCLOCKING
|
||||||
@@ -95,10 +91,10 @@ fn main() -> ! {
|
|||||||
pac.PLL_SYS,
|
pac.PLL_SYS,
|
||||||
xosc.operating_frequency(),
|
xosc.operating_frequency(),
|
||||||
PLLConfig {
|
PLLConfig {
|
||||||
vco_freq: 1500.MHz(),
|
vco_freq: 1600.MHz(),
|
||||||
refdiv: 1,
|
refdiv: 1,
|
||||||
post_div1: 5,
|
post_div1: 4,
|
||||||
post_div2: 3,
|
post_div2: 2,
|
||||||
},
|
},
|
||||||
&mut clocks,
|
&mut clocks,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
@@ -125,21 +121,27 @@ fn main() -> ! {
|
|||||||
// Init PWMs
|
// Init PWMs
|
||||||
let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS);
|
let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS);
|
||||||
|
|
||||||
|
let mut div_int = 1;
|
||||||
// Configure PWM0
|
// Configure PWM0
|
||||||
let pwm = &mut pwm_slices.pwm7;
|
let pwm = &mut pwm_slices.pwm3;
|
||||||
pwm.set_ph_correct();
|
pwm.clr_ph_correct();
|
||||||
pwm.set_div_int(20);
|
pwm.set_div_int(div_int);
|
||||||
pwm.set_div_frac(0);
|
pwm.set_div_frac(0);
|
||||||
pwm.clear_interrupt();
|
pwm.clear_interrupt();
|
||||||
pwm.enable();
|
pwm.enable();
|
||||||
|
|
||||||
// let mut pwm_pin = pins.gpio15;
|
let mut sink = pins.gpio5.into_push_pull_output();
|
||||||
// pwm_pin.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwelveMilliAmps);
|
sink.set_low();
|
||||||
// pwm.channel_b.output_to(pwm_pin);
|
sink.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwelveMilliAmps);
|
||||||
|
let mut sink = pins.gpio7.into_push_pull_output();
|
||||||
|
sink.set_low();
|
||||||
|
sink.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwelveMilliAmps);
|
||||||
|
let mut pwm_pin = pins.gpio6;
|
||||||
|
pwm_pin.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwoMilliAmps);
|
||||||
|
pwm.channel_a.output_to(pwm_pin);
|
||||||
|
|
||||||
// let mut duty = 0;
|
pwm.set_top(3);
|
||||||
// pwm.set_top(50000);
|
pwm.channel_a.set_duty(2);
|
||||||
// pwm.channel_a.set_duty(duty);
|
|
||||||
|
|
||||||
// let mut on_off_input = pins.gpio15.into_pull_up_input();
|
// let mut on_off_input = pins.gpio15.into_pull_up_input();
|
||||||
|
|
||||||
@@ -165,16 +167,25 @@ fn main() -> ! {
|
|||||||
let sh1106_dev = sh1106_dev;
|
let sh1106_dev = sh1106_dev;
|
||||||
let mut gfx_buf = GraphicsBuf::new();
|
let mut gfx_buf = GraphicsBuf::new();
|
||||||
|
|
||||||
gfx_buf.sprites[0].x = 114;
|
gfx_buf.sprites[0].y = 40;
|
||||||
|
gfx_buf.sprites[0].x = 60;
|
||||||
|
|
||||||
gfx_buf.clear();
|
gfx_buf.clear();
|
||||||
gfx_buf.redraw();
|
gfx_buf.redraw();
|
||||||
|
|
||||||
|
let mut str_buf = [0u8; 12];
|
||||||
|
let str_len = u32_into_str(pll_freq.to_kHz(), &mut str_buf);
|
||||||
|
let khz_str = str::from_utf8(&str_buf[str_buf.len() - str_len..]).unwrap();
|
||||||
|
|
||||||
|
gfx_buf.draw_string(18, 20, "Booted at: ");
|
||||||
|
gfx_buf.draw_string(78, 20, khz_str);
|
||||||
|
gfx_buf.draw_string(78 + (6 * str_len as u8), 20, "kHz");
|
||||||
|
|
||||||
sh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
|
sh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
|
||||||
|
|
||||||
let mut tick: u32 = 0;
|
let mut tick: u32 = 0;
|
||||||
|
|
||||||
let mut led = OnboardLed::new(pins.gpio16.into_push_pull_output().into_dyn_pin());
|
let mut led = OnboardLed::new(pll_freq, pins.gpio16.into_push_pull_output().into_dyn_pin());
|
||||||
|
|
||||||
println!("Booted at {}MHz", pll_freq.to_MHz());
|
println!("Booted at {}MHz", pll_freq.to_MHz());
|
||||||
println!("PWM at {}Hz", pll_freq.to_Hz() / (20 * 2 * 50000));
|
println!("PWM at {}Hz", pll_freq.to_Hz() / (20 * 2 * 50000));
|
||||||
@@ -183,48 +194,103 @@ fn main() -> ! {
|
|||||||
let mut g = 0u8;
|
let mut g = 0u8;
|
||||||
let mut b = 0u8;
|
let mut b = 0u8;
|
||||||
|
|
||||||
const ON_VALUE: u8 = 64;
|
loop {
|
||||||
|
if enter_input.is_low().unwrap() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut menu = Menu::new();
|
||||||
|
|
||||||
|
menu.add_item("Int Div Up");
|
||||||
|
menu.add_item("Int Div Down");
|
||||||
|
menu.add_item("Chichi");
|
||||||
|
menu.add_item("Nyaoha");
|
||||||
|
|
||||||
|
let menu = menu;
|
||||||
|
let mut cursor_pos = 0;
|
||||||
|
let mut cur_selection = 0;
|
||||||
|
|
||||||
|
gfx_buf.sprites[1].visible = true;
|
||||||
|
gfx_buf.sprites[1].x = 10;
|
||||||
|
gfx_buf.sprites[1].y = 12;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tick = tick.wrapping_add(1);
|
tick = tick.wrapping_add(1);
|
||||||
|
|
||||||
let i = (tick % 144) as usize;
|
cortex_m::asm::delay(5_000_000);
|
||||||
// let r = WAVE_TABLE[i] / 2;
|
|
||||||
// let g = WAVE_TABLE[(i + 48) % 128] / 2;
|
|
||||||
// let b = WAVE_TABLE[(i + 96) % 128] / 2;
|
|
||||||
// led.set_color(r, g, b);
|
|
||||||
|
|
||||||
// match i {
|
if right_input.is_low().unwrap() {
|
||||||
// ..48 => led.set_color(128, 0, 0),
|
cursor_pos -= 1;
|
||||||
// 48..96 => led.set_color(0, 128, 0),
|
if cursor_pos < 0 {
|
||||||
// _ => led.set_color(0, 0, 128),
|
cursor_pos = 3;
|
||||||
// }
|
|
||||||
|
|
||||||
cortex_m::asm::delay(10_000_000);
|
|
||||||
|
|
||||||
if left_input.is_low().unwrap() {
|
|
||||||
r = match r {
|
|
||||||
ON_VALUE => 0,
|
|
||||||
_ => ON_VALUE,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if right_input.is_low().unwrap() {
|
if left_input.is_low().unwrap() {
|
||||||
g = match g {
|
cursor_pos = (cursor_pos + 1) % 4;
|
||||||
ON_VALUE => 0,
|
|
||||||
_ => ON_VALUE,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if enter_input.is_low().unwrap() {
|
if enter_input.is_low().unwrap() {
|
||||||
b = match b {
|
cur_selection = cursor_pos;
|
||||||
ON_VALUE => 0,
|
|
||||||
_ => ON_VALUE,
|
match cur_selection {
|
||||||
|
0 => {
|
||||||
|
div_int = 1.max(div_int - 1);
|
||||||
|
pwm.set_div_int(div_int);
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
div_int = div_int.saturating_add(1);
|
||||||
|
pwm.set_div_int(div_int);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match cur_selection {
|
||||||
|
0 => {
|
||||||
|
let i = (tick % 144) as usize;
|
||||||
|
r = WAVE_TABLE[i % 128] / 8;
|
||||||
|
g = WAVE_TABLE[(i + 48) % 128] / 8;
|
||||||
|
b = WAVE_TABLE[(i + 96) % 128] / 8;
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
r = 64;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
r = 0;
|
||||||
|
g = 64;
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = 64;
|
||||||
|
}
|
||||||
|
_ => panic!("Shouldn't be able to select beyond menu"),
|
||||||
|
}
|
||||||
|
|
||||||
led.set_color(r, g, b);
|
led.set_color(r, g, b);
|
||||||
|
|
||||||
|
gfx_buf.clear();
|
||||||
|
gfx_buf.redraw();
|
||||||
|
|
||||||
|
let mut y = 10;
|
||||||
|
menu.get_menu_items().for_each(|mi| {
|
||||||
|
gfx_buf.draw_string(20, y, mi.get_name());
|
||||||
|
y += 12;
|
||||||
|
});
|
||||||
|
|
||||||
|
gfx_buf.sprites[0].y = cursor_pos * 12 + 10;
|
||||||
|
gfx_buf.sprites[1].y = cur_selection * 12 + 10;
|
||||||
|
|
||||||
|
let cur_menu_item = menu.get_item(cursor_pos as usize).unwrap();
|
||||||
|
gfx_buf.sprites[0].x = (gfx_buf.get_string_px_length(cur_menu_item.get_name()) + 28) as i32;
|
||||||
|
|
||||||
|
sh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
|
||||||
|
|
||||||
// pwm.channel_a.set_duty(duty);
|
// pwm.channel_a.set_duty(duty);
|
||||||
|
|
||||||
// gfx_buf.clear();
|
// gfx_buf.clear();
|
||||||
|
|||||||
49
src/menu.rs
Normal file
49
src/menu.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
pub struct Menu {
|
||||||
|
items: [Option<MenuItem>; 8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Menu {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { items: [None; 8] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_item(&mut self, name: &str) {
|
||||||
|
let Some(empty_slot) = self.items.iter_mut().find(|mi| mi.is_none()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
*empty_slot = Some(MenuItem::new(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_menu_items(&self) -> impl Iterator<Item = MenuItem> {
|
||||||
|
self.items.iter().filter_map(|omi| omi.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_item(&self, index: usize) -> Option<MenuItem> {
|
||||||
|
self.items[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct MenuItem {
|
||||||
|
name_buf: [u8; 20],
|
||||||
|
name_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MenuItem {
|
||||||
|
pub fn new(name: &str) -> Self {
|
||||||
|
let mut name_buf = [0u8; 20];
|
||||||
|
let copy_len = name.len().min(20);
|
||||||
|
|
||||||
|
name_buf[0..copy_len].copy_from_slice(&name.as_bytes()[0..copy_len]);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
name_buf,
|
||||||
|
name_len: copy_len,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_name(&self) -> &str {
|
||||||
|
str::from_utf8(&self.name_buf[0..self.name_len]).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
|
use cortex_m::asm::nop;
|
||||||
use embedded_hal::digital::OutputPin;
|
use embedded_hal::digital::OutputPin;
|
||||||
use rp2040_hal::gpio::{DynPinId, FunctionSioOutput, Pin, PullDown};
|
use rp2040_hal::{
|
||||||
|
fugit::HertzU32,
|
||||||
|
gpio::{DynPinId, FunctionSioOutput, Pin, PullDown},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct OnboardLed {
|
pub struct OnboardLed {
|
||||||
|
pll_freq: HertzU32,
|
||||||
led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>,
|
led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OnboardLed {
|
impl OnboardLed {
|
||||||
pub fn new(led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>) -> Self {
|
pub fn new(pll_freq: HertzU32, led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>) -> Self {
|
||||||
Self { led_pin }
|
Self { pll_freq, led_pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_color(&mut self, r: u8, g: u8, b: u8) {
|
pub fn set_color(&mut self, r: u8, g: u8, b: u8) {
|
||||||
@@ -20,17 +25,20 @@ impl OnboardLed {
|
|||||||
for i in 0..24 {
|
for i in 0..24 {
|
||||||
let bit = color & (0x1 << (23 - i));
|
let bit = color & (0x1 << (23 - i));
|
||||||
|
|
||||||
|
let nop_count = self.pll_freq.to_Hz() / 50_000_000;
|
||||||
self.led_pin.set_high().unwrap();
|
self.led_pin.set_high().unwrap();
|
||||||
|
|
||||||
if bit == 0 {
|
if bit == 0 {
|
||||||
cortex_m::asm::nop();
|
for _ in 0..nop_count {
|
||||||
cortex_m::asm::nop();
|
cortex_m::asm::nop();
|
||||||
cortex_m::asm::nop();
|
cortex_m::asm::nop();
|
||||||
|
cortex_m::asm::nop();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cortex_m::asm::delay(60);
|
cortex_m::asm::delay(60 * nop_count);
|
||||||
}
|
}
|
||||||
self.led_pin.set_low().unwrap();
|
self.led_pin.set_low().unwrap();
|
||||||
cortex_m::asm::delay(35);
|
cortex_m::asm::delay(35 * nop_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user