-
-
Save nathansamson/8ff4efbcd11043bcfda6a3e7cf2d01ea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "fri3d-badge" | |
version = "0.1.0" | |
authors = ["Nathan Samson <nathan@nathansamson.be>"] | |
edition = "2021" | |
resolver = "2" | |
[profile.release] | |
opt-level = "s" | |
[profile.dev] | |
debug = true # Symbols are nice and they don't increase the size on Flash | |
opt-level = "z" | |
[features] | |
pio = ["esp-idf-sys/pio"] | |
[dependencies] | |
esp-idf-sys = { version = "0.31.6", features = ["binstart"] } | |
esp-idf-hal = "0.38" | |
embedded-hal = "=1.0.0-alpha.8" | |
embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } | |
embedded-graphics = "0.7.1" | |
# mipidsi = "0.2.1" | |
st7789 = { version="0.6.1" } | |
display-interface-spi = "*" | |
smart-leds = "0.3.0" | |
ws2812-esp32-rmt-driver = { version = "0.4.0", features = ["smart-leds-trait"] } | |
[build-dependencies] | |
embuild = "0.29" | |
anyhow = "1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::thread; | |
use embedded_hal_0_2::blocking::delay::DelayMs; | |
use std::{borrow::Borrow, sync::Arc, time::Duration}; | |
use embedded_hal_0_2::digital::v2::OutputPin; | |
use esp_idf_hal::delay::FreeRtos; | |
use esp_idf_hal::ledc::{config::TimerConfig, Channel, Timer}; | |
use esp_idf_hal::peripherals::Peripherals; | |
use esp_idf_hal::prelude::*; | |
use esp_idf_hal::ledc::Resolution::Bits10; | |
use ws2812_esp32_rmt_driver::Ws2812Esp32Rmt; | |
use smart_leds::{RGB, colors}; | |
use embedded_graphics::{ | |
pixelcolor::Rgb565, prelude::*, primitives::{Rectangle, PrimitiveStyleBuilder}, | |
}; | |
use fri3d_badge::effects; | |
use fri3d_badge::led_strip; | |
use fri3d_badge::effects::Effect; | |
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported | |
fn blink_leds() { | |
const N: usize = 5; | |
let mut ws = Ws2812Esp32Rmt::new(0, 2).unwrap(); | |
let mut led_strip_colors = led_strip::LedStrip::<N>::new(); | |
let mut color = led_strip::Color::from(RGB::new(0, 0, 255)); | |
color.set_brightness(50); | |
let mut i: u8 = 0; | |
loop { | |
effects::FillEffect::new(color).apply::<N>(led_strip_colors.get_mut_slice::<N>(0)); | |
led_strip_colors.write(&mut ws); | |
color = led_strip::Color::from(RGB::new(i / 2, i / 2, 255 - i)); | |
color.set_brightness(50); | |
i = (i + 1) % (255); | |
println!("FILLING LED WITH {}", i); | |
FreeRtos.delay_ms(100 as u32); | |
} | |
} | |
fn play_music<T: esp_idf_hal::ledc::HwTimer, C: esp_idf_hal::ledc::HwChannel, P: esp_idf_hal::gpio::OutputPin> | |
(mut ledc_timer: T, mut ledc_channel: C, mut pin32: P) { | |
let max_duty = 0x1FF; | |
let notes = [ 659.25f32, 587.33, 369.99, 415.3, 554.37, 493.88, 293.66, 329.63, 493.88, 440.0, 277.18, 329.63, 440.0 ]; | |
let lengths = [ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 6 ]; | |
loop { | |
for i in 0..13 { | |
let config = TimerConfig::default().frequency(((notes[i]).round() as u32).into()).resolution(Bits10); | |
let timer = Timer::new(ledc_timer, &config).unwrap(); | |
let mut channel = Channel::new(ledc_channel, &timer, pin32).unwrap(); | |
println!("Note {} freq = {}", i, notes[i]); | |
channel.set_duty(255).unwrap(); | |
//channel.enable(); | |
FreeRtos.delay_ms(120 * lengths[i] as u32); | |
(ledc_channel, pin32) = channel.release().unwrap(); | |
ledc_timer = timer.release().unwrap(); | |
} | |
FreeRtos.delay_ms(2000 as u32); | |
} | |
} | |
fn main() { | |
// Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, | |
// or else some patches to the runtime implemented by esp-idf-sys might not link properly. | |
esp_idf_sys::link_patches(); | |
println!("Hello, world!"); | |
println!("Configuring output channel"); | |
let peripherals = Peripherals::take().unwrap(); | |
let mut ledc_timer = peripherals.ledc.timer0; | |
let mut ledc_channel = peripherals.ledc.channel0; | |
let mut pin32 = peripherals.pins.gpio32; | |
let led_threads_handle = thread::spawn(blink_leds); | |
// let music_thread_handle = thread::spawn(move || { play_music(ledc_timer, ledc_channel, pin32); }); | |
let config = <esp_idf_hal::spi::config::Config as Default>::default().baudrate(32.MHz().into()).data_mode(embedded_hal::spi::MODE_0); | |
let spi = esp_idf_hal::spi::Master::<esp_idf_hal::spi::SPI3, _, _, _, esp_idf_hal::gpio::Gpio5<esp_idf_hal::gpio::Unknown>>::new( | |
peripherals.spi3, | |
esp_idf_hal::spi::Pins { | |
sclk: peripherals.pins.gpio18, | |
sdo: peripherals.pins.gpio23, | |
sdi: Some(peripherals.pins.gpio19), | |
cs: None, | |
}, | |
config, | |
) | |
.unwrap(); | |
let lcd_dc = peripherals.pins.gpio33.into_output().unwrap(); | |
let lcd_rst = peripherals.pins.gpio26.into_output().unwrap(); | |
let lcd_cs = peripherals.pins.gpio5.into_output().unwrap(); | |
let mut led_bl = peripherals.pins.gpio12.into_output().unwrap(); | |
led_bl.set_high(); | |
let di = display_interface_spi::SPIInterface::new(spi, lcd_dc, lcd_cs); | |
println!("SPI CONFIG DONE"); | |
// let mut lcd = mipidsi::Display::st7789_without_rst(di); | |
let mut lcd = mipidsi::Display::st7789(di, lcd_rst); | |
let mut delay = esp_idf_hal::delay::Ets; | |
println!("INIT S"); | |
lcd.init( | |
&mut delay, | |
mipidsi::DisplayOptions { | |
orientation: mipidsi::Orientation::PortraitInverted(false), | |
invert_vertical_refresh: false, | |
color_order: Default::default(), | |
invert_horizontal_refresh: false, | |
}, | |
).unwrap(); | |
// let mut lcd = st7789::ST7789::new(di, lcd_rst, 240, 240); | |
// lcd.set_orientation(st7789::Orientation::Portrait).unwrap(); | |
// let mut delay = esp_idf_hal::delay::Ets; | |
// lcd.init(&mut delay).unwrap(); | |
println!("INITED"); | |
lcd.clear(Rgb565::BLUE); | |
println!("CLEAR"); | |
// let Size { width, height } = lcd.size(); | |
// let pattern = (0..height as i32).flat_map(|y| { | |
// (0..width as i32).map(move |x| { | |
// let dx = x - width as i32 / 2; | |
// let dy = y - height as i32 / 2; | |
// if dx * dx * 2 + dy * dy < 40 * 40 { | |
// c1 | |
// } else { | |
// c2 | |
// } | |
// }) | |
// }); | |
// lcd.set_pixels(0, 0, width as u16, height as u16, pattern); | |
let style = PrimitiveStyleBuilder::new() | |
.stroke_color(Rgb565::RED) | |
.stroke_width(3) | |
.fill_color(Rgb565::GREEN) | |
.build(); | |
Rectangle::new(Point::new(30, 20), Size::new(10, 15)) | |
.into_styled(style) | |
.draw(&mut lcd).unwrap(); | |
// Rectangle with translation applied | |
Rectangle::new(Point::new(30, 20), Size::new(10, 15)) | |
.translate(Point::new(-20, -10)) | |
.into_styled(style) | |
.draw(&mut lcd).unwrap(); | |
println!("DONE"); | |
// Since both threads are endless loops its probably not necessary to join both but anyhow | |
// music_thread_handle.join(); | |
led_threads_handle.join(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::thread; | |
use embedded_hal_0_2::blocking::delay::DelayMs; | |
use std::{borrow::Borrow, sync::Arc, time::Duration}; | |
use embedded_hal_0_2::digital::v2::OutputPin; | |
use esp_idf_hal::delay::FreeRtos; | |
use esp_idf_hal::ledc::{config::TimerConfig, Channel, Timer}; | |
use esp_idf_hal::peripherals::Peripherals; | |
use esp_idf_hal::prelude::*; | |
use esp_idf_hal::ledc::Resolution::Bits10; | |
use ws2812_esp32_rmt_driver::Ws2812Esp32Rmt; | |
use smart_leds::{RGB, colors}; | |
use embedded_graphics::{ | |
pixelcolor::Rgb565, prelude::*, primitives::{Rectangle, PrimitiveStyleBuilder}, | |
}; | |
use fri3d_badge::effects; | |
use fri3d_badge::led_strip; | |
use fri3d_badge::effects::Effect; | |
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported | |
fn blink_leds() { | |
const N: usize = 5; | |
let mut ws = Ws2812Esp32Rmt::new(0, 2).unwrap(); | |
let mut led_strip_colors = led_strip::LedStrip::<N>::new(); | |
let mut color = led_strip::Color::from(RGB::new(0, 0, 255)); | |
color.set_brightness(50); | |
let mut i: u8 = 0; | |
loop { | |
effects::FillEffect::new(color).apply::<N>(led_strip_colors.get_mut_slice::<N>(0)); | |
led_strip_colors.write(&mut ws); | |
color = led_strip::Color::from(RGB::new(i / 2, i / 2, 255 - i)); | |
color.set_brightness(50); | |
i = (i + 1) % (255); | |
println!("FILLING LED WITH {}", i); | |
FreeRtos.delay_ms(100 as u32); | |
} | |
} | |
fn play_music<T: esp_idf_hal::ledc::HwTimer, C: esp_idf_hal::ledc::HwChannel, P: esp_idf_hal::gpio::OutputPin> | |
(mut ledc_timer: T, mut ledc_channel: C, mut pin32: P) { | |
let max_duty = 0x1FF; | |
let notes = [ 659.25f32, 587.33, 369.99, 415.3, 554.37, 493.88, 293.66, 329.63, 493.88, 440.0, 277.18, 329.63, 440.0 ]; | |
let lengths = [ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 6 ]; | |
loop { | |
for i in 0..13 { | |
let config = TimerConfig::default().frequency(((notes[i]).round() as u32).into()).resolution(Bits10); | |
let timer = Timer::new(ledc_timer, &config).unwrap(); | |
let mut channel = Channel::new(ledc_channel, &timer, pin32).unwrap(); | |
println!("Note {} freq = {}", i, notes[i]); | |
channel.set_duty(255).unwrap(); | |
//channel.enable(); | |
FreeRtos.delay_ms(120 * lengths[i] as u32); | |
(ledc_channel, pin32) = channel.release().unwrap(); | |
ledc_timer = timer.release().unwrap(); | |
} | |
FreeRtos.delay_ms(2000 as u32); | |
} | |
} | |
fn main() { | |
// Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, | |
// or else some patches to the runtime implemented by esp-idf-sys might not link properly. | |
esp_idf_sys::link_patches(); | |
println!("Hello, world!"); | |
println!("Configuring output channel"); | |
let peripherals = Peripherals::take().unwrap(); | |
let mut ledc_timer = peripherals.ledc.timer0; | |
let mut ledc_channel = peripherals.ledc.channel0; | |
let mut pin32 = peripherals.pins.gpio32; | |
let led_threads_handle = thread::spawn(blink_leds); | |
// let music_thread_handle = thread::spawn(move || { play_music(ledc_timer, ledc_channel, pin32); }); | |
let config = <esp_idf_hal::spi::config::Config as Default>::default().baudrate(32.MHz().into()).data_mode(embedded_hal::spi::MODE_0); | |
let spi = esp_idf_hal::spi::Master::<esp_idf_hal::spi::SPI3, _, _, _, esp_idf_hal::gpio::Gpio5<esp_idf_hal::gpio::Unknown>>::new( | |
peripherals.spi3, | |
esp_idf_hal::spi::Pins { | |
sclk: peripherals.pins.gpio18, | |
sdo: peripherals.pins.gpio23, | |
sdi: Some(peripherals.pins.gpio19), | |
cs: None, | |
}, | |
config, | |
) | |
.unwrap(); | |
let lcd_dc = peripherals.pins.gpio33.into_output().unwrap(); | |
let lcd_rst = peripherals.pins.gpio26.into_output().unwrap(); | |
let lcd_cs = peripherals.pins.gpio5.into_output().unwrap(); | |
let mut led_bl = peripherals.pins.gpio12.into_output().unwrap(); | |
led_bl.set_high(); | |
let di = display_interface_spi::SPIInterface::new(spi, lcd_dc, lcd_cs); | |
println!("SPI CONFIG DONE"); | |
// let mut lcd = mipidsi::Display::st7789_without_rst(di); | |
// let mut lcd = mipidsi::Display::st7789(di, lcd_rst); | |
// let mut delay = esp_idf_hal::delay::Ets; | |
// println!("INIT S"); | |
// lcd.init( | |
// &mut delay, | |
// mipidsi::DisplayOptions { | |
// orientation: mipidsi::Orientation::PortraitInverted(false), | |
// invert_vertical_refresh: false, | |
// color_order: Default::default(), | |
// invert_horizontal_refresh: false, | |
// }, | |
// ).unwrap(); | |
let mut lcd = st7789::ST7789::new(di, lcd_rst, 240, 240); | |
lcd.set_orientation(st7789::Orientation::Portrait).unwrap(); | |
let mut delay = esp_idf_hal::delay::Ets; | |
lcd.init(&mut delay).unwrap(); | |
println!("INITED"); | |
lcd.clear(Rgb565::BLUE); | |
println!("CLEAR"); | |
// let Size { width, height } = lcd.size(); | |
// let pattern = (0..height as i32).flat_map(|y| { | |
// (0..width as i32).map(move |x| { | |
// let dx = x - width as i32 / 2; | |
// let dy = y - height as i32 / 2; | |
// if dx * dx * 2 + dy * dy < 40 * 40 { | |
// c1 | |
// } else { | |
// c2 | |
// } | |
// }) | |
// }); | |
// lcd.set_pixels(0, 0, width as u16, height as u16, pattern); | |
let style = PrimitiveStyleBuilder::new() | |
.stroke_color(Rgb565::RED) | |
.stroke_width(3) | |
.fill_color(Rgb565::GREEN) | |
.build(); | |
Rectangle::new(Point::new(30, 20), Size::new(10, 15)) | |
.into_styled(style) | |
.draw(&mut lcd).unwrap(); | |
// Rectangle with translation applied | |
Rectangle::new(Point::new(30, 20), Size::new(10, 15)) | |
.translate(Point::new(-20, -10)) | |
.into_styled(style) | |
.draw(&mut lcd).unwrap(); | |
println!("DONE"); | |
// Since both threads are endless loops its probably not necessary to join both but anyhow | |
// music_thread_handle.join(); | |
led_threads_handle.join(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment