Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions ui-app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,21 @@ pub trait Led {
}
}

fn rgb565(r: u8, g: u8, b: u8) -> u16 {
// Discard the low-order bits of the colors
(((r as u16) >> 3) << 11) | (((g as u16) >> 2) << 5) | ((b as u16) >> 3)
}

pub trait Screen {
fn width(&self) -> usize;
fn height(&self) -> usize;
fn fill(&mut self, color: u16);
fn draw(&mut self, left: usize, right: usize, top: usize, bottom: usize, data: &[u16]);
}

pub trait Outputs {
fn status_led(&mut self) -> &mut impl Led;
fn screen(&mut self) -> &mut impl Screen;
fn log(&mut self, message: &str);
}

Expand All @@ -140,7 +153,51 @@ impl App {
}

pub fn start(&mut self, out: &mut impl Outputs) {
// Extinguish the status LED
out.status_led().set_color(Color::Black);

// Draw a test pattern to the screen
const SIZE: usize = 10;
let screen = out.screen();
let mut data = [0_u16; SIZE * SIZE];

// Background
screen.fill(rgb565(0x88, 0x88, 0x88));

// Upper left = R
let (x0, x1, y0, y1) = (SIZE, SIZE + SIZE, SIZE, SIZE + SIZE);
data.fill(rgb565(0xFF, 0x00, 0x00));
screen.draw(x0, x1, y0, y1, &data);

// Upper right = G
let (x0, x1, y0, y1) = (
screen.width() - SIZE - SIZE,
screen.width() - SIZE,
SIZE,
SIZE + SIZE,
);
data.fill(rgb565(0x00, 0xFF, 0x00));
screen.draw(x0, x1, y0, y1, &data);

// Lower left = B
let (x0, x1, y0, y1) = (
SIZE,
SIZE + SIZE,
screen.height() - SIZE - SIZE,
screen.height() - SIZE,
);
data.fill(rgb565(0x00, 0x00, 0xFF));
screen.draw(x0, x1, y0, y1, &data);

// Lower right = Y
let (x0, x1, y0, y1) = (
screen.width() - SIZE - SIZE,
screen.width() - SIZE,
screen.height() - SIZE - SIZE,
screen.height() - SIZE,
);
data.fill(rgb565(0xFF, 0xFF, 0x00));
screen.draw(x0, x1, y0, y1, &data);
}

pub fn handle(&mut self, event: Event, out: &mut impl Outputs) {
Expand Down
27 changes: 27 additions & 0 deletions ui-app/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,32 @@ impl Led for MockLed {
}
}

// TODO: Test screen logic
#[derive(Default)]
struct MockScreen;

impl Screen for MockScreen {
fn width(&self) -> usize {
240
}

fn height(&self) -> usize {
320
}

fn fill(&mut self, _color: u16) {
// TODO: Store pixels
}

fn draw(&mut self, _left: usize, _right: usize, _top: usize, _bottom: usize, _data: &[u16]) {
// TODO: Store pixels
}
}

#[derive(Default)]
struct MockOutputs {
status_led: MockLed,
screen: MockScreen,
last_message: String,
}

Expand All @@ -22,6 +45,10 @@ impl Outputs for MockOutputs {
&mut self.status_led
}

fn screen(&mut self) -> &mut impl Screen {
&mut self.screen
}

fn log(&mut self, message: &str) {
self.last_message = message.into();
}
Expand Down
3 changes: 2 additions & 1 deletion ui-stm32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ defmt-rtt = "1.0.0"

embassy-executor = { version = "0.8.0", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
embassy-futures = { version = "0.1.1", features = ["defmt"] }
embassy-stm32 = { version = "0.3.0", features = ["defmt", "stm32f405rg", "memory-x", "time-driver-tim4", "exti", "chrono"] }
embassy-stm32 = { version = "0.3.0", features = ["defmt", "stm32f405rg", "memory-x", "time-driver-tim1", "exti", "chrono"] }
embassy-time = { version = "0.4.0", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }

heapless = { version = "0.8", default-features = false }
panic-probe = { version = "1.0.0", features = ["print-defmt"] }
embassy-sync = { version = "0.7.1", features = ["defmt"] }
num_enum = { version = "0.7.4", default-features = false }

[profile.release]
debug = 2
63 changes: 60 additions & 3 deletions ui-stm32/src/board/ev12.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
use super::{Button, Keyboard, StatusLed};
use super::{Button, Keyboard, Screen, StatusLed};
use embassy_stm32::{
exti::ExtiInput,
gpio::{Input, Level, Output, Pull, Speed},
spi::Spi,
};
use ui_app::{Led, Outputs};

pub struct Board {
status_led: StatusLed,
screen: Screen,
pub ptt_button: Option<Button>,
pub ai_button: Option<Button>,
pub keyboard: Option<Keyboard>,
}

impl Board {
pub fn new() -> Self {
let p = embassy_stm32::init(Default::default());
pub async fn new() -> Self {
let config = {
use embassy_stm32::{rcc::*, time::Hertz};

let mut config = embassy_stm32::Config::default();

config.rcc.hse = Some(Hse {
freq: Hertz(6_000_000),
mode: HseMode::Bypass,
});
config.rcc.sys = Sysclk::PLL1_P;
config.rcc.pll_src = PllSource::HSE;
config.rcc.pll = Some(Pll {
prediv: PllPreDiv::DIV3,
mul: PllMul::MUL168,
divp: Some(PllPDiv::DIV2),
divq: Some(PllQDiv::DIV7),
divr: None,
});

config.rcc.ahb_pre = AHBPrescaler::DIV1;
config.rcc.apb1_pre = APBPrescaler::DIV4;
config.rcc.apb2_pre = APBPrescaler::DIV2;
config.rcc.ls = LsConfig {
rtc: RtcClockSource::LSI,
lsi: true,
lse: None,
};

config
};
let p = embassy_stm32::init(config);

// Status LED
let r = Output::new(p.PA6, Level::Low, Speed::Low);
Expand Down Expand Up @@ -45,8 +77,29 @@ impl Board {
];
let keyboard = Keyboard::new(cols, rows);

// Screen
let chip_select = Output::new(p.PB8, Level::Low, Speed::Low);
let data_command = Output::new(p.PB9, Level::Low, Speed::Low);
let reset = Output::new(p.PC13, Level::Low, Speed::Low);
let backlight = Output::new(p.PC14, Level::Low, Speed::Low);

let config = {
use embassy_stm32::spi::*;
let mut config = Config::default();
config.mode.polarity = Polarity::IdleLow;
config.mode.phase = Phase::CaptureOnFirstTransition;
config.bit_order = BitOrder::MsbFirst;
config
};
let spi1 = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config);
let screen = Screen::new(chip_select, data_command, reset, backlight, spi1).await;

// TODO(RLB): NET UART
// TODO(RLB): MGMT UART

Self {
status_led,
screen,
ptt_button: Some(ptt_button),
ai_button: Some(ai_button),
keyboard: Some(keyboard),
Expand All @@ -59,6 +112,10 @@ impl Outputs for Board {
&mut self.status_led
}

fn screen(&mut self) -> &mut impl ui_app::Screen {
&mut self.screen
}

fn log(&mut self, message: &str) {
defmt::info!("{}", message);
}
Expand Down
31 changes: 29 additions & 2 deletions ui-stm32/src/board/ev13.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
use super::{Button, Keyboard, StatusLed};
use super::{Button, Keyboard, Screen, StatusLed};
use embassy_stm32::{
exti::ExtiInput,
gpio::{Input, Level, Output, Pull, Speed},
spi::Spi,
};
use ui_app::{Led, Outputs};

pub struct Board {
status_led: StatusLed,
screen: Screen,
pub ptt_button: Option<Button>,
pub ai_button: Option<Button>,
pub keyboard: Option<Keyboard>,
}

impl Board {
pub fn new() -> Self {
pub async fn new() -> Self {
let p = embassy_stm32::init(Default::default());

// Status LED
Expand Down Expand Up @@ -45,8 +47,29 @@ impl Board {
];
let keyboard = Keyboard::new(cols, rows);

// Screen
let chip_select = Output::new(p.PB8, Level::Low, Speed::Low);
let data_command = Output::new(p.PB9, Level::Low, Speed::Low);
let reset = Output::new(p.PC13, Level::Low, Speed::Low);
let backlight = Output::new(p.PC14, Level::Low, Speed::Low);

let config = {
use embassy_stm32::spi::*;
let mut config = Config::default();
config.mode.polarity = Polarity::IdleLow;
config.mode.phase = Phase::CaptureOnFirstTransition;
config.bit_order = BitOrder::MsbFirst;
config
};
let spi1 = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config);
let screen = Screen::new(chip_select, data_command, reset, backlight, spi1).await;

// TODO(RLB): NET UART
// TODO(RLB): MGMT UART

Self {
status_led,
screen,
ptt_button: Some(ptt_button),
ai_button: Some(ai_button),
keyboard: Some(keyboard),
Expand All @@ -59,6 +82,10 @@ impl Outputs for Board {
&mut self.status_led
}

fn screen(&mut self) -> &mut impl ui_app::Screen {
&mut self.screen
}

fn log(&mut self, message: &str) {
defmt::info!("{}", message);
}
Expand Down
3 changes: 3 additions & 0 deletions ui-stm32/src/board/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use ui_app::Led;
mod keyboard;
pub use keyboard::Keyboard;

mod screen;
pub use screen::Screen;

struct StatusLed {
r: Output<'static>,
g: Output<'static>,
Expand Down
Loading