HAL
This commit is contained in:
parent
0bab1d52a5
commit
c90c10cf7a
6 changed files with 165 additions and 70 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
|
@ -767,6 +767,7 @@ dependencies = [
|
|||
"mipidsi",
|
||||
"panic-probe",
|
||||
"rgb",
|
||||
"tinytga",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -808,6 +809,12 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "mipidsi"
|
||||
version = "0.9.0"
|
||||
|
|
@ -841,6 +848,16 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
@ -1271,6 +1288,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytga"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "477839bd612acb4d0551915eaf6eef8cc1b3a9dd58e18e9c2b746c78614a25d5"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
|
|
|
|||
|
|
@ -48,3 +48,4 @@ embedded-hal-bus = "0.3.0"
|
|||
embassy-futures = "0.1.2"
|
||||
heapless = "0.8.0"
|
||||
rgb = "0.8.52"
|
||||
tinytga = "0.5.0"
|
||||
|
|
|
|||
27
firmware/src/art.rs
Normal file
27
firmware/src/art.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use embedded_graphics::{image::Image, pixelcolor::Rgb888, prelude::*};
|
||||
use tinytga::Tga;
|
||||
|
||||
pub struct Hal {
|
||||
image_data: Tga<'static, Rgb888>,
|
||||
}
|
||||
|
||||
impl Hal {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
image_data: Tga::from_slice(include_bytes!("assets/hal.tga")).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drawable for Hal {
|
||||
type Color = Rgb888;
|
||||
|
||||
type Output = ();
|
||||
|
||||
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
|
||||
where
|
||||
D: DrawTarget<Color = Self::Color>,
|
||||
{
|
||||
Image::new(&self.image_data, Point::zero()).draw(target)
|
||||
}
|
||||
}
|
||||
BIN
firmware/src/assets/hal.tga
Normal file
BIN
firmware/src/assets/hal.tga
Normal file
Binary file not shown.
101
firmware/src/led_matrix.rs
Normal file
101
firmware/src/led_matrix.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
use core::convert::Infallible;
|
||||
|
||||
use embassy_rp::{peripherals::PIO0, pio_programs::ws2812::PioWs2812};
|
||||
use embedded_graphics::{
|
||||
Pixel,
|
||||
pixelcolor::Rgb888,
|
||||
prelude::{DrawTarget, OriginDimensions, Point, RgbColor, Size},
|
||||
};
|
||||
use rgb::RGB8;
|
||||
|
||||
// Sourced from the `smart-leds` crate
|
||||
const GAMMA8: [u8; 256] = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14,
|
||||
14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27,
|
||||
27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72,
|
||||
73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104,
|
||||
105, 107, 109, 110, 112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137,
|
||||
138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
|
||||
177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218, 220,
|
||||
223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255,
|
||||
];
|
||||
|
||||
pub fn gamma(color: Rgb888) -> Rgb888 {
|
||||
Rgb888::new(
|
||||
GAMMA8[color.r() as usize],
|
||||
GAMMA8[color.g() as usize],
|
||||
GAMMA8[color.b() as usize],
|
||||
)
|
||||
}
|
||||
|
||||
pub struct Serpentine {
|
||||
pub size: Size,
|
||||
}
|
||||
|
||||
impl Serpentine {
|
||||
fn map(&self, mut p: Point) -> Option<usize> {
|
||||
if p.x < 0 || p.x as u32 >= self.size.width || p.y < 0 || p.y as u32 >= self.size.height {
|
||||
return None;
|
||||
}
|
||||
|
||||
if p.y % 2 == 0 {
|
||||
p.x = self.size.width as i32 - 1 - p.x;
|
||||
}
|
||||
|
||||
Some(p.y as usize * self.size.width as usize + p.x as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LedMatrix<'d> {
|
||||
buffer: [RGB8; 320],
|
||||
layout: Serpentine,
|
||||
pio: PioWs2812<'d, PIO0, 0, 320>,
|
||||
}
|
||||
|
||||
impl<'d> LedMatrix<'d> {
|
||||
pub fn new(layout: Serpentine, pio: PioWs2812<'d, PIO0, 0, 320>) -> Self {
|
||||
Self {
|
||||
buffer: [RGB8::default(); 320],
|
||||
layout,
|
||||
pio,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sync(&mut self) {
|
||||
self.pio.write(&self.buffer).await;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> DrawTarget for LedMatrix<'d> {
|
||||
type Color = Rgb888;
|
||||
|
||||
type Error = Infallible;
|
||||
|
||||
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
|
||||
where
|
||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||
{
|
||||
for Pixel(point, color) in pixels {
|
||||
if let Some(x) = self.layout.map(point).and_then(|i| self.buffer.get_mut(i)) {
|
||||
let color = gamma(color);
|
||||
// Map to 0-64 for brightness limiting
|
||||
*x = RGB8::new(
|
||||
color.r().div_ceil(2),
|
||||
color.g().div_ceil(2),
|
||||
color.b().div_ceil(2),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> OriginDimensions for LedMatrix<'d> {
|
||||
fn size(&self) -> Size {
|
||||
self.layout.size
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::convert::Infallible;
|
||||
mod art;
|
||||
mod led_matrix;
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::select::select_array;
|
||||
|
|
@ -19,7 +20,9 @@ use heapless::String;
|
|||
use mipidsi::interface::SpiInterface;
|
||||
use mipidsi::models::ST7789;
|
||||
use mipidsi::options::Orientation;
|
||||
use rgb::RGB8;
|
||||
|
||||
use crate::art::Hal;
|
||||
use crate::led_matrix::{LedMatrix, Serpentine};
|
||||
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
|
|
@ -128,6 +131,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||
),
|
||||
);
|
||||
led_surface.clear(Rgb888::BLACK).ok();
|
||||
/*
|
||||
Rectangle::new(Point::zero(), led_surface.size())
|
||||
.into_styled(
|
||||
PrimitiveStyleBuilder::new()
|
||||
|
|
@ -138,6 +142,9 @@ async fn main(spawner: Spawner) -> ! {
|
|||
)
|
||||
.draw(&mut led_surface)
|
||||
.ok();
|
||||
*/
|
||||
let hal = Hal::new();
|
||||
hal.draw(&mut led_surface).ok();
|
||||
led_surface.sync().await;
|
||||
|
||||
let mut render = |f_keys: [bool; 4]| {
|
||||
|
|
@ -184,71 +191,3 @@ async fn dfu_button(mut btn_y: Input<'static>) {
|
|||
btn_y.wait_for_falling_edge().await;
|
||||
reset_to_usb_boot(0, 0);
|
||||
}
|
||||
|
||||
struct Serpentine {
|
||||
size: Size,
|
||||
}
|
||||
|
||||
impl Serpentine {
|
||||
fn map(&self, mut p: Point) -> Option<usize> {
|
||||
if p.x < 0 || p.x as u32 >= self.size.width || p.y < 0 || p.y as u32 >= self.size.height {
|
||||
return None;
|
||||
}
|
||||
|
||||
if p.y % 2 == 0 {
|
||||
p.x = self.size.width as i32 - 1 - p.x;
|
||||
}
|
||||
|
||||
Some(p.y as usize * self.size.width as usize + p.x as usize)
|
||||
}
|
||||
}
|
||||
|
||||
struct LedMatrix<'d> {
|
||||
buffer: [RGB8; 320],
|
||||
layout: Serpentine,
|
||||
pio: PioWs2812<'d, PIO0, 0, 320>,
|
||||
}
|
||||
|
||||
impl<'d> LedMatrix<'d> {
|
||||
fn new(layout: Serpentine, pio: PioWs2812<'d, PIO0, 0, 320>) -> Self {
|
||||
Self {
|
||||
buffer: [RGB8::default(); 320],
|
||||
layout,
|
||||
pio,
|
||||
}
|
||||
}
|
||||
|
||||
async fn sync(&mut self) {
|
||||
self.pio.write(&self.buffer).await;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> DrawTarget for LedMatrix<'d> {
|
||||
type Color = Rgb888;
|
||||
|
||||
type Error = Infallible;
|
||||
|
||||
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
|
||||
where
|
||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||
{
|
||||
for Pixel(point, color) in pixels {
|
||||
if let Some(x) = self.layout.map(point).and_then(|i| self.buffer.get_mut(i)) {
|
||||
// Map to 0-64 for brightness limiting
|
||||
*x = RGB8::new(
|
||||
color.r().div_ceil(4),
|
||||
color.g().div_ceil(4),
|
||||
color.b().div_ceil(4),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> OriginDimensions for LedMatrix<'d> {
|
||||
fn size(&self) -> Size {
|
||||
self.layout.size
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue