diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..02a8429 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,27 @@ +[target.'cfg(target_arch = "xtensa")'] +rustflags = [ + # Tell the `core` library that we have atomics, even though it's not + # specified in the target definition + "--cfg", 'target_has_atomic="8"', + "--cfg", 'target_has_atomic="16"', + "--cfg", 'target_has_atomic="32"', + "--cfg", 'target_has_atomic="ptr"', + + "-C", "link-arg=-nostartfiles", + # Enable the atomic codegen option for Xtensa + "-C", "target-feature=+s32c1i", + "-C", "link-arg=-Wl,-Tlinkall.x", +] + +[target.riscv32imac-unknown-none-elf] +rustflags = [ + "-C", "link-arg=-Tlinkall.x", +] + +# Uncomment the target if you'd like to use automatic code hinting in your IDE +# target = "xtensa-esp32-none-elf" +# target = "xtensa-esp32s2-none-elf" +# target = "riscv32imac-unknown-none-elf" + +[unstable] +build-std = ["alloc", "core"] \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73a638b --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.vscode +/.embuild +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e1c6d45 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,78 @@ +[package] +name = "esp-gallery" +version = "0.1.0" +authors = ["Kirill Mikhailov "] +edition = "2021" +license = "MIT OR Apache-2.0" + + +[target.xtensa-esp32-none-elf.dependencies] +xtensa-atomic-emulation-trap = "0.2.0" +esp32-hal = { package = "esp32-hal", git = "https://github.com/esp-rs/esp-hal.git" } +xtensa-lx-rt = { version = "0.13.0", features = ["esp32"], optional = true } +esp-println = { version = "0.3.0", features = ["esp32"] } +esp-backtrace = { git = "https://github.com/esp-rs/esp-backtrace", version = "0.4.0", features = [ + "esp32", + "panic-handler", + "print-uart", +] } + +[target.xtensa-esp32s2-none-elf.dependencies] +xtensa-atomic-emulation-trap = "0.2.0" +esp32s2-hal = "0.4.0" +esp-backtrace = { git = "https://github.com/esp-rs/esp-backtrace", features = [ + "esp32s2", + "panic-handler", + "print-uart", +] } +xtensa-lx-rt = { version = "0.13.0", features = ["esp32s2"], optional = true } +esp-println = { version = "0.2.1", features = [ "esp32s2" ] } + +[target.xtensa-esp32s3-none-elf.dependencies] +xtensa-atomic-emulation-trap = "0.2.0" +esp32s3-hal = "0.4.0" +esp-backtrace = { git = "https://github.com/esp-rs/esp-backtrace", features = [ + "esp32s3", + "panic-handler", + "print-uart", +] } +xtensa-lx-rt = { version = "0.12.0", features = ["esp32s3"], optional = true } +esp-println = { version = "0.2.1", features = [ "esp32s3" ] } + +[target.riscv32imac-unknown-none-elf.dependencies] +esp32c3-hal = { package = "esp32c3-hal", git = "https://github.com/esp-rs/esp-hal.git" } +esp-backtrace = { git = "https://github.com/esp-rs/esp-backtrace", features = [ + "esp32c3", + "panic-handler", + "print-uart", +] } +riscv-rt = { version = "0.8", optional = true } +esp-println = { version = "0.2.1", features = [ "esp32c3" ] } + + +[dependencies] +mipidsi = { git = "https://github.com/almindor/mipidsi" } +display-interface = "0.4" +display-interface-spi = "0.4.1" +embedded-graphics = "0.7.1" +embedded-graphics-core = "0.3.3" +embedded-hal = "0.2.7" +profont = "0.6.1" # font with extended signs and options of sizing (unlike fonts in embedded-graphics) +libm = "0.2.5" + + +[features] +default = [ "rt", "eh1" ] +# rt = ["xtensa-lx-rt"] # for esp32 and esp32s2 chips +rt = ["riscv-rt"] # for esp32c3 chip +# eh1 = ["esp32s3"] +# eh1 = ["esp32-hal/eh1", "esp32"] +# eh1 = ["esp32s2-hal/eh1", "esp32s2"] +eh1 = ["esp32c3-hal/eh1", "esp32c3"] + +esp32 = [] +esp32s2 = [] +esp32s3 = [] +esp32c3 = [] + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..8047470 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# esp-gallery :crab: +Wokwi-example with usage of my colegue's, Samuel Benko's, beautiful graphic examples (check [here]https://github.com/sambenko/esp32s3-box-examples), but adapted for famous `ili9341` display) + +## Instructions + +``` +cargo build --target riscv32imac-unknown-none-elf --release +``` + +### Execution with VSCode Wokwi extension + +Except of extension itself, you will need two files to execute the simulatuion inside of your VSCode IDE: +* wokwi.toml +* diagram.json + +Both of them are already provided in this repo and you can edit them as needed. + +``` +F1 -> Wokwi: Start simulation +``` +In case you will have additional questions - feel free to open an issue :wink: + + + +## Description +There's a short example for newcomers that shows, how 8x8 LED Matrix display is initialised on different Espressif boards (ESP32, ESP32S2, ESP32C3) in bare-metal, this config is for ESP32 in terms of example, you can find brief instructions for other chips below
+ + +>### **P.S.** : Buttons on left are `up` and `down` correspondingly, button on top is `ok`. After image finished rendering press `ok` button to return back to main menu :wink: + +## Tips for other chips +For `esp32` board target (and corresponding changes for paths in `wokwi.toml`) is: +``` +xtensa-esp32-none-elf +``` + +Board type in `diagram.toml` is: +``` +"type": "wokwi-esp32-devkit-v1" +``` +--- +For `esp32s2` board target (and corresponding changes for paths in `wokwi.toml`) is: +``` +xtensa-esp32s2-none-elf +``` + +Board type in `diagram.toml` is: +``` +"type": "board-esp32-s2-devkitm-1"" +``` +--- +For `esp32s3` board target (and corresponding changes for paths in `wokwi.toml`) is: +``` +xtensa-esp32s3-none-elf +``` + +Board type in `diagram.toml` is: +``` +"type": "board-esp32-s3-devkitc-1" +``` + +## Troubleshooting + +* For `xtensa` targets you need to have `esp-idf` exported in your terminal +* In case of errors, related to `esp-hal` driver - try to play with dependencies versions on Cargo.toml. Sometimes there're a lot of breaking or light changes, that can affect building process + diff --git a/diagram.json b/diagram.json new file mode 100644 index 0000000..88ae10b --- /dev/null +++ b/diagram.json @@ -0,0 +1,69 @@ +{ + "version": 1, + "author": "Kirill Mikhailov ", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-c3-devkitm-1", + "id": "esp", + "top": -305.03, + "left": -54.29, + "attrs": { "builder": "rust-nostd-esp" } + }, + { + "type": "wokwi-ili9341", + "id": "lcd1", + "top": -348.99, + "left": -375.2, + "rotate": 270, + "attrs": { "flipVertical": "1" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": -258.77, + "left": -553.08, + "attrs": { "color": "yellow", "bounce": "1" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn2", + "top": -182.69, + "left": -552.83, + "rotate": 180, + "attrs": { "color": "blue" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn3", + "top": -389.75, + "left": -331.23, + "attrs": { "color": "green" } + } + ], + "connections": [ + [ "esp:TX", "$serialMonitor:RX", "", [] ], + [ "esp:RX", "$serialMonitor:TX", "", [] ], + [ "esp:7", "lcd1:MOSI", "white", [ "h25.67", "v-128.97", "h-182.01", "v129.83" ] ], + [ "esp:2", "lcd1:CS", "green", [ "h-48.18", "v59.43" ] ], + [ "esp:10", "lcd1:RST", "yellow", [ "v0" ] ], + [ "esp:3", "lcd1:D/C", "purple", [ "h-21.57", "v47.08" ] ], + [ "esp:6", "lcd1:SCK", "blue", [ "h39.74", "v-150.63", "h-211.92", "v-1.93" ] ], + [ "esp:4", "lcd1:LED", "magenta", [ "v-0.39", "h52.29", "v-184.89", "h-216.27", "v149.17" ] ], + [ "esp:GND.1", "lcd1:GND", "black", [ "v-0.77", "h-35.66", "v130" ] ], + [ "esp:3V3.1", "lcd1:VCC", "limegreen", [ "h-28.99", "v115.64" ] ], + [ "btn1:1.r", "esp:GND.1", "red", [ "v-80.9", "h435.57" ] ], + [ + "btn1:2.r", + "esp:0", + "cyan", + [ "h11.31", "v-83.23", "h170.71", "v-0.21", "h240.01", "v101.48" ] + ], + [ "btn2:1.r", "btn1:1.l", "red", [ "h-88.94", "v-77.41" ] ], + [ "esp:1", "btn2:2.r", "green", [ "h-20.26", "v111.79", "h-496", "v-82" ] ], + [ "btn3:1.r", "esp:8", "yellow", [ "v-12.41", "h375.46", "v151.81" ] ], + [ "btn2:1.l", "btn3:2.l", "red", [ "h29.72", "v-216.06" ] ] + ], + "serialMonitor": { "display": "terminal" }, + "dependencies": {} +} \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..bc18fe3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,666 @@ +#![no_std] +#![no_main] + +#[cfg(feature="esp32")] +use esp32_hal as hal; +#[cfg(feature="esp32s2")] +use esp32s2_hal as hal; +#[cfg(feature="esp32s3")] +use esp32s3_hal as hal; +#[cfg(feature="esp32c3")] +use esp32c3_hal as hal; + +use hal::{ + adc::{AdcConfig, Attenuation, ADC, ADC2}, + clock::ClockControl, + peripherals::Peripherals, + gpio::*, + prelude::*, + spi, + timer::TimerGroup, + Rtc, + IO, + Delay, +}; + +use mipidsi::Orientation; + +use display_interface_spi::SPIInterfaceNoCS; + +use core::f32::consts::PI; +use libm::{sin, cos}; + +use embedded_graphics::{ + prelude::RgbColor, + mono_font::{ + ascii::FONT_10X20, + MonoTextStyleBuilder, + MonoTextStyle, + }, + prelude::*, + text::{Alignment, Text}, + Drawable, + pixelcolor::*, + primitives::{Circle, PrimitiveStyleBuilder, PrimitiveStyle, Rectangle}, + text::*, + image::Image, + geometry::*, + draw_target::DrawTarget, +}; + +use embedded_hal; + +use profont::{PROFONT_24_POINT, PROFONT_18_POINT}; + +use riscv_rt; +use riscv_rt::entry; + +use esp_println::println; +use esp_backtrace as _; + +/* Debouncing algorythm */ +pub enum Event { + Pressed, + Released, + Nothing, +} +pub struct Button { + button: T, + pressed: bool, +} + +impl> Button { + pub fn new(button: T) -> Self { + Button { + button, + pressed: true, + } + } + pub fn check(&mut self){ + self.pressed = !self.button.is_low().unwrap(); + } + + pub fn poll(&mut self, delay :&mut Delay) -> Event { + let pressed_now = !self.button.is_low().unwrap(); + if !self.pressed && pressed_now + { + delay.delay_ms(30 as u32); + self.check(); + if !self.button.is_low().unwrap() { + Event::Pressed + } + else { + Event::Nothing + } + } + else if self.pressed && !pressed_now{ + delay.delay_ms(30 as u32); + self.check(); + if self.button.is_low().unwrap() + { + Event::Released + } + else { + Event::Nothing + } + } + else{ + Event::Nothing + } + + } +} + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take(); + + let mut system = peripherals.SYSTEM.split(); + + let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + // Disable the RTC and TIMG watchdog timers + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + + rtc.rwdt.disable(); + wdt0.disable(); + wdt1.disable(); + + println!("About to initialize the SPI LED driver ILI9341"); + let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + + /* Set corresponding pins */ + let mosi = io.pins.gpio7; + let cs = io.pins.gpio2; + let rst = io.pins.gpio10; + let dc = io.pins.gpio3; + let sck = io.pins.gpio6; + let miso = io.pins.gpio9; + let backlight = io.pins.gpio4; + + /* Then set backlight (set_low() - display lights up when signal is in 0, set_high() - opposite case(for example.)) */ + let mut backlight = backlight.into_push_pull_output(); + //backlight.set_low().unwrap(); + + /* Configure SPI */ + let spi = spi::Spi::new( + peripherals.SPI2, + sck, + mosi, + miso, + cs, + 80u32.MHz(), + spi::SpiMode::Mode0, + &mut system.peripheral_clock_control, + &mut clocks, + ); + + let di = SPIInterfaceNoCS::new(spi, dc.into_push_pull_output()); + let reset = rst.into_push_pull_output(); + let mut delay = Delay::new(&clocks); + + + let mut display = mipidsi::Builder::ili9341_rgb565(di) + .with_display_size(240 as u16, 320 as u16) + .with_framebuffer_size(240 as u16, 320 as u16) + .with_orientation(Orientation::LandscapeInverted(true)) + .init(&mut delay, Some(reset)) + .unwrap(); + + println!("Initialized"); + + display.clear(Rgb565::WHITE); + + let eye_plate_tab = display.bounding_box().center() - Size::new(80, 30); + let lollipop_plate_tab = display.bounding_box().center() - Size::new(80,0); + let garden_plate_tab = display.bounding_box().center() + Size::new(0, 30) - Size::new(80, 0); + + let pointer_offset = Size::new(15, 10); + + + + + let mut button_up = Button::new(io.pins.gpio0.into_pull_up_input()); + let mut button_down = Button::new(io.pins.gpio1.into_pull_up_input()); + let mut button_ok = Button::new(io.pins.gpio8.into_pull_up_input()); + + + Text::new("Eye", + eye_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Lollipop Guy", + lollipop_plate_tab, //- Size::new(0, 15), + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Garden", + garden_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Circle::new(eye_plate_tab - pointer_offset, 10) + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::BLACK) + .stroke_width(1) + .fill_color(Rgb565::BLACK) + .build(), + ) + .draw(&mut display) + .unwrap(); + + + + + let mut pointer_position : u8 = 1; + let mut last_pointer_position : u8 = 1; + + loop { + + if last_pointer_position != pointer_position + { + Rectangle::new( match last_pointer_position { + 1 => eye_plate_tab, + 2 => lollipop_plate_tab, + 3 => garden_plate_tab, + _ => Point::new(0,0), + } - Size::new(17,12), Size::new(15, 15)) + .into_styled( + PrimitiveStyleBuilder::new() + .fill_color(Rgb565::WHITE) + .build(), + ) + .draw(&mut display) + .unwrap(); + + Circle::new(match pointer_position { + 1 => eye_plate_tab, + 2 => lollipop_plate_tab, + 3 => garden_plate_tab, + _ => Point::new(0,0), + } - pointer_offset, 10) + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::BLACK) + .stroke_width(1) + .fill_color(Rgb565::BLACK) + .build(), + ) + .draw(&mut display) + .unwrap(); + + + last_pointer_position = pointer_position + } + + if let Event::Pressed = button_up.poll(&mut delay) + { + println!("pressed up"); + if pointer_position == 1 { pointer_position = 3; } + else{ pointer_position -= 1; } + } + if let Event::Pressed = button_down.poll(&mut delay) + { + println!("pressed down"); + if pointer_position == 3{ pointer_position = 1; } + else{ pointer_position += 1;} + } + + + if let Event::Pressed = button_ok.poll(&mut delay) + { + display.clear(Rgb565::WHITE); + + if pointer_position == 1 + { + let default_style = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(RgbColor::BLACK) + .build(); + + let mut vt; + let mut x; + let mut y; + for i in 0..13200 { + vt = i as f64 / (20.0 * PI as f64); + if i < 8000 { + x = (vt - 50.0) * sin(vt); + } else { + x = (vt + 20.0) * sin(vt); + } + y = (vt - 50.0) * cos(vt); + if i < 8000 { + Text::with_alignment("'", Point::new((x + 160.0) as i32, (y + 125.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } else { + Text::with_alignment("|", Point::new((x + 160.0) as i32, (y + 125.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + } + + loop + { + if let Event::Pressed = button_ok.poll(&mut delay) {break;} + } + display.clear(Rgb565::WHITE); + + + Text::new("Eye", + eye_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Lollipop Guy", + lollipop_plate_tab, //- Size::new(0, 15), + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Garden", + garden_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Circle::new(eye_plate_tab - pointer_offset, 10) + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::BLACK) + .stroke_width(1) + .fill_color(Rgb565::BLACK) + .build(), + ) + .draw(&mut display) + .unwrap(); + + + + pointer_position = 1; + last_pointer_position = 1; + } + else if pointer_position == 2 + { + let default_style = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(RgbColor::BLACK) + .build(); + + let mut vt; + let mut x; + let mut y; + + //body + for i in 0..7000 { + vt = i as f64 / (40.0 * PI as f64); + x = (vt - 50.0) * sin(vt); + y = (vt + 50.0) * cos(vt); + if i < 6500 || i > 6900 { + Text::with_alignment("'", Point::new((x + 220.0) as i32, (y + 200.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + } + + + //head + for i in 0..7000 { + vt = i as f64 / (60.0 * PI as f64); + x = (vt + 50.0) * cos(vt); + y = (vt - 50.0) * sin(vt); + + Text::with_alignment("'", Point::new((x + 220.0) as i32, (y + 60.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + + } + + + //eyes + for i in 0..1300 { + vt = i as f64 / (20.0 * PI as f64); + x = (vt - 15.0) * sin(vt); + y = (vt - 15.0) * cos(vt); + + Text::with_alignment("'", Point::new((x + 200.0) as i32, (y + 60.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + for i in 0..1300 { + vt = i as f64 / (20.0 * PI as f64); + x = (vt - 15.0) * sin(vt); + y = (vt - 15.0) * cos(vt); + + Text::with_alignment("'", Point::new((x + 240.0) as i32, (y + 60.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + //hand + + let mut b; + for a in (125..175).rev() { + b = a; + Text::with_alignment("-", Point::new(a, b), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + //lollipop + + for i in 0..3300 { + vt = i as f64 / (30.0 * PI as f64); + x = (vt - 30.0) * sin(vt); + y = (vt - 30.0) * cos(vt); + + Text::with_alignment("'", Point::new((x + 110.0) as i32, (y + 110.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + loop + { + if let Event::Pressed = button_ok.poll(&mut delay) {break;} + } + display.clear(Rgb565::WHITE); + + Text::new("Eye", + eye_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Lollipop Guy", + lollipop_plate_tab, //- Size::new(0, 15), + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Garden", + garden_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Circle::new(eye_plate_tab - pointer_offset, 10) + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::BLACK) + .stroke_width(1) + .fill_color(Rgb565::BLACK) + .build(), + ) + .draw(&mut display) + .unwrap(); + + + pointer_position = 1; + last_pointer_position = 1; + } + else if pointer_position == 3 + { + let default_style = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(RgbColor::BLACK) + .build(); + + let mut n = 6.0; + let mut d = 71.0; + let mut a; + let mut r; + let mut x; + let mut y; + + for t in 0..361 { + a = t as f64 * d * (PI as f64 / 60.0); + r = 30.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("o", Point::new((x + 35.0) as i32, (y + 180.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + let pos_x = 1; + for pos_y in 0..60 { + Text::with_alignment("|", Point::new(pos_x + 34, pos_y + 180), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + n = 7.0; + d = 19.0; + for t in 0..700 { + a = t as f64 * d * (PI as f64 / 300.0); + r = 30.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("o", Point::new((x + 90.0) as i32, (y + 140.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + for pos_y in 0..100 { + Text::with_alignment("|", Point::new(pos_x + 89, pos_y + 140), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + n = 2.0; + d = 39.0; + for t in 0..500 { + a = t as f64 * d * (PI as f64 / 150.0); + r = 30.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("S", Point::new((x + 140.0) as i32, (y + 190.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + for pos_y in 0..50 { + Text::with_alignment("|", Point::new(pos_x + 139, pos_y + 190), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + n = 8.0; + d = 27.0; + for t in 0..1000 { + a = t as f64 * d * (PI as f64 / 230.0); + r = 30.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("o", Point::new((x + 243.0) as i32, (y + 200.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + for pos_y in 0..85 { + Text::with_alignment("|", Point::new(pos_x + 242, pos_y + 200), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + n = 5.0; + d = 97.0; + for t in 0..700 { + a = t as f64 * d * (PI as f64 / 150.0); + r = 30.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("o", Point::new((x + 290.0) as i32, (y + 155.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + for pos_y in 0..85 { + Text::with_alignment("|", Point::new(pos_x + 289, pos_y + 155), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + n = 6.0; + d = 71.0; + for t in 0..2500 { + a = t as f64 * d * (PI as f64 / 1200.0); + r = 80.0 * sin(n * a); + x = r * cos(a); + y = r * sin(a); + + Text::with_alignment("o", Point::new((x + 200.0) as i32, (y + 90.0) as i32), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + for pos_y in 0..100 { + Text::with_alignment("|", Point::new(pos_x + 199, pos_y + 140), default_style, Alignment::Center) + .draw(&mut display) + .unwrap(); + } + + + loop + { + if let Event::Pressed = button_ok.poll(&mut delay) {break;} + } + display.clear(Rgb565::WHITE); + + Text::new("Eye", + eye_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Lollipop Guy", + lollipop_plate_tab, //- Size::new(0, 15), + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Text::new("Garden", + garden_plate_tab, + MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::BLACK), + ) + .draw(&mut display) + .unwrap(); + + Circle::new(eye_plate_tab - pointer_offset, 10) + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::BLACK) + .stroke_width(1) + .fill_color(Rgb565::BLACK) + .build(), + ) + .draw(&mut display) + .unwrap(); + + + pointer_position = 1; + last_pointer_position = 1; + } + } + } +} \ No newline at end of file diff --git a/wokwi.toml b/wokwi.toml new file mode 100644 index 0000000..d889a9b --- /dev/null +++ b/wokwi.toml @@ -0,0 +1,4 @@ +[wokwi] +version = 1 +elf = "target/riscv32imac-unknown-none-elf/release/esp-gallery" +firmware = "target/riscv32imac-unknown-none-elf/release/esp-gallery" \ No newline at end of file