diff --git a/Cargo.lock b/Cargo.lock index 0b6773f..454ca00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,12 @@ dependencies = [ "regex", ] +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -21,6 +27,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "arrayvec" version = "0.7.6" @@ -75,6 +87,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bisync" version = "0.3.0" @@ -180,6 +198,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "cfg-if" version = "1.0.1" @@ -246,6 +270,15 @@ dependencies = [ "debug-helper", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "critical-section" version = "1.2.0" @@ -698,6 +731,19 @@ dependencies = [ "defmt 0.3.100", ] +[[package]] +name = "embedded-graphics-simulator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31606a4fb7d9d3a79a38d27bc2954cfa98682c8fea4b22c09a442785a80424e" +dependencies = [ + "base64", + "embedded-graphics", + "image", + "ouroboros", + "sdl2", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -805,6 +851,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + [[package]] name = "fixed" version = "1.29.0" @@ -829,6 +884,16 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "float-cmp" version = "0.9.0" @@ -983,6 +1048,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -1005,10 +1076,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "2.9.0" +name = "image" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "num-traits", + "png", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -1181,6 +1264,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "nb" version = "0.1.3" @@ -1258,6 +1351,30 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.104", +] + [[package]] name = "panic-probe" version = "0.3.2" @@ -1351,12 +1468,14 @@ dependencies = [ "embassy-sync 0.7.0", "embassy-time", "embedded-graphics", + "embedded-graphics-simulator", "embedded-hal 0.2.7", "embedded-hal-async", "embedded-hal-bus", "embedded-sdmmc", "panic-probe", "portable-atomic", + "shared", "spin", "st7365p-lcd", "static_cell", @@ -1464,6 +1583,19 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "portable-atomic" version = "1.11.1" @@ -1534,6 +1666,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "quote" version = "1.0.40" @@ -1668,6 +1813,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sdl2" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b498da7d14d1ad6c839729bd4ad6fc11d90a57583605f3b4df2cd709a9cd380" +dependencies = [ + "bitflags 1.3.2", + "lazy_static", + "libc", + "sdl2-sys", +] + +[[package]] +name = "sdl2-sys" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951deab27af08ed9c6068b7b0d05a93c91f0a8eb16b6b816a5e73452a43521d3" +dependencies = [ + "cfg-if", + "libc", + "version-compare", +] + [[package]] name = "semver" version = "0.9.0" @@ -1699,6 +1867,28 @@ dependencies = [ "keccak", ] +[[package]] +name = "shared" +version = "0.1.0" +dependencies = [ + "embedded-graphics", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simulator" +version = "0.1.0" +dependencies = [ + "embedded-graphics", + "embedded-graphics-simulator", + "shared", +] + [[package]] name = "siphasher" version = "1.0.1" @@ -1741,6 +1931,7 @@ dependencies = [ [[package]] name = "st7365p-lcd" version = "0.10.0" +source = "git+https://github.com/legitcamper/st7365p-lcd-rs?branch=async#9f8da568ff695a00afb6b8b8cf9573fad408a66f" dependencies = [ "embedded-graphics-core", "embedded-hal 1.0.0", @@ -1754,6 +1945,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "static_cell" version = "2.1.1" @@ -1964,6 +2161,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "version_check" version = "0.9.5" @@ -2163,6 +2366,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zerocopy" version = "0.8.26" diff --git a/Cargo.toml b/Cargo.toml index 7595054..ee0f1a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ -[package] -name = "picocalc-os-rs" -version = "0.1.0" -edition = "2024" +[workspace] +resolver = "3" +members = ["pico", "shared", "simulator"] + [profile.release] debug = 2 @@ -9,72 +9,3 @@ debug = 2 [profile.dev] lto = true opt-level = "z" - -[features] -default = ["rp235x", "defmt"] -rp2040 = ["embassy-rp/rp2040"] -rp235x = ["embassy-rp/rp235xb"] -trouble = ["dep:bt-hci", "dep:cyw43", "dep:cyw43-pio", "dep:trouble-host"] -defmt = [ - "dep:defmt", - "panic-probe/print-defmt", - "embassy-executor/defmt", - "embassy-time/defmt", - "embassy-time/defmt-timestamp-uptime", - "embassy-rp/defmt", - "embassy-sync/defmt", - "embedded-graphics/defmt", - "embedded-sdmmc/defmt-log", - # "bt-hci/defmt", - # "cyw43/defmt", - # "cyw43-pio/defmt", -] - -[dependencies] -embassy-executor = { version = "0.7", features = [ - "arch-cortex-m", - "executor-interrupt", - "executor-thread", - "nightly", -] } -embassy-rp = { version = "0.4.0", features = [ - "critical-section-impl", - "unstable-pac", - "time-driver", - "binary-info", -] } -embassy-futures = "0.1.1" -embassy-time = "0.4.0" -embassy-embedded-hal = "0.3.0" -embassy-sync = { version = "0.7" } -trouble-host = { version = "0.1", features = [ - "derive", - "scan", -], optional = true } -bt-hci = { version = "0.2", default-features = false, optional = true } -cyw43 = { version = "0.3.0", features = [ - "firmware-logs", - "bluetooth", -], optional = true } -cyw43-pio = { version = "0.3.0", optional = true } - -embedded-hal-bus = { version = "0.3.0", features = ["async"] } -embedded-hal = "0.2.7" -embedded-hal-async = "1.0.0" -cortex-m = { version = "0.7.7" } -cortex-m-rt = "0.7.5" -panic-probe = "0.3" -portable-atomic = { version = "1.11", features = ["critical-section"] } - -defmt = { version = "0.3", optional = true } -defmt-rtt = "0.4.2" - -embedded-graphics = { version = "0.8.1" } -embedded-sdmmc = { git = "https://github.com/Be-ing/embedded-sdmmc-rs", branch = "bisync", default-features = false } -# st7365p-lcd = { git = "https://github.com/legitcamper/st7365p-lcd-rs" } -st7365p-lcd = { path = "../ST7365P-lcd-rs" } - -static_cell = "2.1.1" -bitflags = "2.9.1" -talc = "4.4.3" -spin = "0.10.0" diff --git a/pico/Cargo.toml b/pico/Cargo.toml new file mode 100644 index 0000000..f7558e9 --- /dev/null +++ b/pico/Cargo.toml @@ -0,0 +1,76 @@ +[package] +name = "picocalc-os-rs" +version = "0.1.0" +edition = "2024" + +[features] +default = ["rp235x", "defmt"] +rp2040 = ["embassy-rp/rp2040"] +rp235x = ["embassy-rp/rp235xb"] +trouble = ["dep:bt-hci", "dep:cyw43", "dep:cyw43-pio", "dep:trouble-host"] +defmt = [ + "dep:defmt", + "panic-probe/print-defmt", + "embassy-executor/defmt", + "embassy-time/defmt", + "embassy-time/defmt-timestamp-uptime", + "embassy-rp/defmt", + "embassy-sync/defmt", + "embedded-graphics/defmt", + "embedded-sdmmc/defmt-log", + # "bt-hci/defmt", + # "cyw43/defmt", + # "cyw43-pio/defmt", +] + +[dev-dependencies] +embedded-graphics-simulator = { version = "0.7.0", default-features = false } + +[dependencies] +embassy-executor = { version = "0.7", features = [ + "arch-cortex-m", + "executor-interrupt", + "executor-thread", + "nightly", +] } +embassy-rp = { version = "0.4.0", features = [ + "critical-section-impl", + "unstable-pac", + "time-driver", + "binary-info", +] } +embassy-futures = "0.1.1" +embassy-time = "0.4.0" +embassy-embedded-hal = "0.3.0" +embassy-sync = { version = "0.7" } +trouble-host = { version = "0.1", features = [ + "derive", + "scan", +], optional = true } +bt-hci = { version = "0.2", default-features = false, optional = true } +cyw43 = { version = "0.3.0", features = [ + "firmware-logs", + "bluetooth", +], optional = true } +cyw43-pio = { version = "0.3.0", optional = true } + +embedded-hal-bus = { version = "0.3.0", features = ["async"] } +embedded-hal = "0.2.7" +embedded-hal-async = "1.0.0" +cortex-m = { version = "0.7.7" } +cortex-m-rt = "0.7.5" +panic-probe = "0.3" +portable-atomic = { version = "1.11", features = ["critical-section"] } + +defmt = { version = "0.3", optional = true } +defmt-rtt = "0.4.2" + +embedded-graphics = { version = "0.8.1" } +embedded-sdmmc = { git = "https://github.com/Be-ing/embedded-sdmmc-rs", branch = "bisync", default-features = false } +st7365p-lcd = { git = "https://github.com/legitcamper/st7365p-lcd-rs", branch = "async" } +shared = { path = "../shared" } + +static_cell = "2.1.1" +bitflags = "2.9.1" +talc = "4.4.3" +spin = "0.10.0" diff --git a/build.rs b/pico/build.rs similarity index 100% rename from build.rs rename to pico/build.rs diff --git a/memory.x b/pico/memory.x similarity index 100% rename from memory.x rename to pico/memory.x diff --git a/pico/src/display.rs b/pico/src/display.rs new file mode 100644 index 0000000..c2e453b --- /dev/null +++ b/pico/src/display.rs @@ -0,0 +1,61 @@ +use defmt::info; +use embassy_rp::{ + gpio::{Level, Output}, + peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, + spi::{Async, Spi}, +}; +use embassy_time::{Delay, Timer}; +use embedded_graphics::{ + Drawable, + mono_font::{MonoFont, MonoTextStyle, ascii::FONT_10X20}, + pixelcolor::Rgb565, + prelude::{Point, WebColors}, + text::{Baseline, Text, TextStyle}, +}; +use embedded_hal_bus::spi::ExclusiveDevice; +use st7365p_lcd::{FrameBuffer, ST7365P}; + +use shared::{SCREEN_HEIGHT, SCREEN_WIDTH, TextBuffer}; + +type SPI = Spi<'static, SPI1, Async>; + +type FRAMEBUFFER = FrameBuffer< + SCREEN_WIDTH, + SCREEN_HEIGHT, + ExclusiveDevice, Output<'static>, Delay>, + Output<'static>, + Output<'static>, +>; + +#[embassy_executor::task] +pub async fn display_task(spi: SPI, cs: PIN_13, data: PIN_14, reset: PIN_15) { + let spi_device = ExclusiveDevice::new(spi, Output::new(cs, Level::Low), Delay).unwrap(); + let display = ST7365P::new( + spi_device, + Output::new(data, Level::Low), + Some(Output::new(reset, Level::High)), + false, + true, + SCREEN_WIDTH as u32, + SCREEN_HEIGHT as u32, + ); + let mut framebuffer: FRAMEBUFFER = FrameBuffer::new(display); + + framebuffer.init(&mut Delay).await.unwrap(); + framebuffer.display.set_offset(0, 0); + framebuffer + .display + .set_custom_orientation(0x60) + .await + .unwrap(); + + let mut textbuffer = TextBuffer::new(); + textbuffer.fill('A'); + textbuffer.draw(&mut framebuffer); + info!("finished rendering"); + + loop { + framebuffer.draw().await.unwrap(); + Timer::after_millis(500).await; + } +} diff --git a/src/main.rs b/pico/src/main.rs similarity index 100% rename from src/main.rs rename to pico/src/main.rs diff --git a/src/peripherals/keyboard.rs b/pico/src/peripherals/keyboard.rs similarity index 100% rename from src/peripherals/keyboard.rs rename to pico/src/peripherals/keyboard.rs diff --git a/src/peripherals/mod.rs b/pico/src/peripherals/mod.rs similarity index 100% rename from src/peripherals/mod.rs rename to pico/src/peripherals/mod.rs diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 923eda9..66a4127 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] channel = "nightly-2025-06-18" components = ["rust-src", "rustfmt", "rust-analyzer"] -targets = ["thumbv6m-none-eabi"] +targets = ["thumbv6m-none-eabi", "x86_64-unknown-linux-gnu"] diff --git a/shared/Cargo.toml b/shared/Cargo.toml new file mode 100644 index 0000000..24e73ca --- /dev/null +++ b/shared/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared" +version = "0.1.0" +edition = "2024" + +[dependencies] +embedded-graphics = "0.8.1" diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..71b9bf4 --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1,97 @@ +#![feature(ascii_char)] + +use embedded_graphics::{ + mono_font::{ + MonoFont, MonoTextStyle, + ascii::{FONT_6X9, FONT_10X20}, + }, + pixelcolor::{BinaryColor, Rgb565}, + prelude::{Point, WebColors, *}, + primitives::{Circle, Line, PrimitiveStyle, Rectangle}, + text::{Alignment, Baseline, Text, TextStyle}, +}; + +pub const SCREEN_WIDTH: usize = 320; +pub const SCREEN_HEIGHT: usize = 320; +const SCREEN_ROWS: usize = 15; +const SCREEN_COLS: usize = 31; +const FONT: MonoFont = FONT_10X20; +const COLOR: Rgb565 = Rgb565::CSS_LAWN_GREEN; + +pub struct Cursor { + x: u16, + y: u16, +} + +impl Cursor { + fn new(x: u16, y: u16) -> Self { + Self { x, y } + } +} + +pub struct TextBuffer { + grid: [[Option; SCREEN_COLS]; SCREEN_ROWS], + cursor: Cursor, +} + +impl TextBuffer { + pub fn new() -> Self { + Self { + grid: [[None; SCREEN_COLS]; SCREEN_ROWS], + cursor: Cursor { x: 0, y: 0 }, + } + } + + /// writes char at cursor + pub fn write_char(&mut self, ch: char) { + for (i, row) in self.grid.iter_mut().enumerate() { + for (j, col) in row.iter_mut().enumerate() { + if i as u16 == self.cursor.x && j as u16 == self.cursor.y { + *col = Some(ch) + } + } + } + } + + /// fills text buffer with char + pub fn fill(&mut self, ch: char) { + for i in 0..SCREEN_ROWS { + for j in 0..SCREEN_COLS { + self.cursor = Cursor::new(i as u16, j as u16); + self.write_char(ch); + } + } + } + + pub fn scroll_up(&mut self) { + let (top, bottom) = self.grid.split_at_mut(SCREEN_ROWS - 1); + for (dest, src) in top.iter_mut().zip(&bottom[1..]) { + dest.copy_from_slice(src); + } + + self.grid[SCREEN_ROWS - 1].fill(None); + } + + pub fn draw>(&mut self, target: &mut D) { + let style = MonoTextStyle::new(&FONT, COLOR); + + for (i, row) in self.grid.iter().enumerate() { + for (j, col) in row[1..].iter().enumerate() { + if let Some(ch) = col { + let pos = Point::new( + (j as i32) * FONT.character_size.width as i32, + (i as i32) * FONT.character_size.height as i32, + ); + + let _ = Text::with_baseline( + ch.as_ascii().unwrap().as_str(), + pos, + style, + Baseline::Top, + ) + .draw(target); + } + } + } + } +} diff --git a/simulator/Cargo.toml b/simulator/Cargo.toml new file mode 100644 index 0000000..1743861 --- /dev/null +++ b/simulator/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "simulator" +version = "0.1.0" +edition = "2024" + +[dependencies] +embedded-graphics = "0.8.1" +embedded-graphics-simulator = "0.7.0" +shared = { path = "../shared" } diff --git a/simulator/src/main.rs b/simulator/src/main.rs new file mode 100644 index 0000000..9ef62c9 --- /dev/null +++ b/simulator/src/main.rs @@ -0,0 +1,32 @@ +#![feature(ascii_char)] + +use embedded_graphics::{ + geometry::Size, + mono_font::{ + MonoFont, MonoTextStyle, + ascii::{FONT_6X9, FONT_10X20}, + }, + pixelcolor::{BinaryColor, Rgb565}, + prelude::{Point, WebColors, *}, + primitives::{Circle, Line, PrimitiveStyle, Rectangle}, + text::{Alignment, Baseline, Text, TextStyle}, +}; +use embedded_graphics_simulator::{ + BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, Window, +}; + +use shared::{SCREEN_HEIGHT, SCREEN_WIDTH, TextBuffer}; + +fn main() -> Result<(), core::convert::Infallible> { + let mut display = + SimulatorDisplay::::new(Size::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)); + + let mut textbuffer = TextBuffer::new(); + textbuffer.fill('A'); + textbuffer.draw(&mut display); + + let output_settings = OutputSettingsBuilder::new().build(); + Window::new("Hello World", &output_settings).show_static(&display); + + Ok(()) +} diff --git a/src/display.rs b/src/display.rs deleted file mode 100644 index 113ac94..0000000 --- a/src/display.rs +++ /dev/null @@ -1,141 +0,0 @@ -use defmt::info; -use embassy_rp::{ - gpio::{Level, Output}, - peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, - spi::{Async, Spi}, -}; -use embassy_time::{Delay, Timer}; -use embedded_graphics::{ - Drawable, - mono_font::{MonoFont, MonoTextStyle, ascii::FONT_10X20}, - pixelcolor::Rgb565, - prelude::{Point, WebColors}, - text::{Baseline, Text, TextStyle}, -}; -use embedded_hal_bus::spi::ExclusiveDevice; -use st7365p_lcd::{FrameBuffer, ST7365P}; - -type SPI = Spi<'static, SPI1, Async>; - -type FRAMEBUFFER = FrameBuffer< - SCREEN_WIDTH, - SCREEN_HEIGHT, - ExclusiveDevice, Output<'static>, Delay>, - Output<'static>, - Output<'static>, ->; - -const SCREEN_WIDTH: usize = 320; -const SCREEN_HEIGHT: usize = 320; -const SCREEN_ROWS: usize = 15; -const SCREEN_COLS: usize = 31; -const FONT: MonoFont = FONT_10X20; -const COLOR: Rgb565 = Rgb565::CSS_LAWN_GREEN; - -#[embassy_executor::task] -pub async fn display_task(spi: SPI, cs: PIN_13, data: PIN_14, reset: PIN_15) { - let spi_device = ExclusiveDevice::new(spi, Output::new(cs, Level::Low), Delay).unwrap(); - let display = ST7365P::new( - spi_device, - Output::new(data, Level::Low), - Some(Output::new(reset, Level::High)), - false, - true, - SCREEN_WIDTH as u32, - SCREEN_HEIGHT as u32, - ); - let mut framebuffer: FRAMEBUFFER = FrameBuffer::new(display); - - framebuffer.init(&mut Delay).await.unwrap(); - framebuffer.display.set_offset(0, 0); - framebuffer - .display - .set_custom_orientation(0x60) - .await - .unwrap(); - - let mut textbuffer = TextBuffer::new(); - textbuffer.fill('A'); - textbuffer.draw(&mut framebuffer); - info!("finished rendering"); - - loop { - framebuffer.draw().await.unwrap(); - Timer::after_millis(500).await; - } -} - -pub struct Cursor { - x: u16, - y: u16, -} - -impl Cursor { - fn new(x: u16, y: u16) -> Self { - Self { x, y } - } -} - -pub struct TextBuffer { - grid: [[Option; SCREEN_COLS]; SCREEN_ROWS], - cursor: Cursor, -} - -impl TextBuffer { - pub fn new() -> Self { - Self { - grid: [[None; SCREEN_COLS]; SCREEN_ROWS], - cursor: Cursor { x: 0, y: 0 }, - } - } - - /// writes char at cursor - pub fn write_char(&mut self, ch: char) { - for (i, row) in self.grid.iter_mut().enumerate() { - for (j, col) in row.iter_mut().enumerate() { - if i as u16 == self.cursor.x && j as u16 == self.cursor.y { - *col = Some(ch) - } - } - } - } - - /// fills text buffer with char - pub fn fill(&mut self, ch: char) { - for i in 0..SCREEN_ROWS { - for j in 0..SCREEN_COLS { - self.cursor = Cursor::new(i as u16, j as u16); - self.write_char(ch); - } - } - } - - pub fn scroll_up(&mut self) { - let (top, bottom) = self.grid.split_at_mut(SCREEN_ROWS - 1); - for (dest, src) in top.iter_mut().zip(&bottom[1..]) { - dest.copy_from_slice(src); - } - - self.grid[SCREEN_ROWS - 1].fill(None); - } - - pub fn draw(&mut self, target: &mut FRAMEBUFFER) { - let baseline = TextStyle::with_baseline(Baseline::Top); - let style = MonoTextStyle::new(&FONT, COLOR); - - for (i, row) in self.grid.iter().enumerate() { - for (j, cell) in row.iter().enumerate() { - if let Some(ch) = cell { - let pos = Point::new( - (j as i32) * FONT.character_size.width as i32, - (i as i32) * FONT.character_size.height as i32 + baseline.baseline as i32, - ); - - Text::new(ch.as_ascii().unwrap().as_str(), pos, style) - .draw(target) - .unwrap(); - } - } - } - } -}