+1
-1
.cargo/config.toml
+1
-1
.cargo/config.toml
+10
Cargo.lock
+10
Cargo.lock
···
909
909
"smart-leds",
910
910
"st7789",
911
911
"static_cell",
912
+
"tinybmp",
912
913
"trouble-host",
913
914
"uc8151",
914
915
"usbd-hid",
···
2315
2316
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
2316
2317
dependencies = [
2317
2318
"crunchy",
2319
+
]
2320
+
2321
+
[[package]]
2322
+
name = "tinybmp"
2323
+
version = "0.5.0"
2324
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2325
+
checksum = "197cc000e382175ff15abd9c54c694ef80ef20cb07e7f956c71e3ea97fc8dc60"
2326
+
dependencies = [
2327
+
"embedded-graphics",
2318
2328
]
2319
2329
2320
2330
[[package]]
+1
Cargo.toml
+1
Cargo.toml
images/ferris_w_a_knife.bmp
images/ferris_w_a_knife.bmp
This is a binary file and will not be displayed.
images/repo.bmp
images/repo.bmp
This is a binary file and will not be displayed.
+65
src/image_handler.rs
+65
src/image_handler.rs
···
1
+
use core::sync::atomic::{AtomicBool, AtomicU8};
2
+
3
+
use embedded_graphics::prelude::Point;
4
+
5
+
pub static CURRENT_IMAGE: AtomicU8 = AtomicU8::new(0);
6
+
pub static CHANGE_IMAGE: AtomicBool = AtomicBool::new(true);
7
+
8
+
static NUMBER_OF_IMAGES: u8 = 2;
9
+
static FERRIS_IMG: &[u8; 15722] = include_bytes!("../images/ferris_w_a_knife.bmp");
10
+
static REPO_IMG: &[u8; 11262] = include_bytes!("../images/repo.bmp");
11
+
12
+
pub enum DisplayImage {
13
+
Ferris = 0,
14
+
Repo = 1,
15
+
}
16
+
17
+
pub fn get_current_image() -> DisplayImage {
18
+
DisplayImage::from_u8(CURRENT_IMAGE.load(core::sync::atomic::Ordering::Relaxed)).unwrap()
19
+
}
20
+
21
+
impl DisplayImage {
22
+
pub fn from_u8(value: u8) -> Option<Self> {
23
+
match value {
24
+
0 => Some(Self::Ferris),
25
+
1 => Some(Self::Repo),
26
+
_ => None,
27
+
}
28
+
}
29
+
30
+
pub fn as_u8(&self) -> u8 {
31
+
match self {
32
+
Self::Ferris => 0,
33
+
Self::Repo => 1,
34
+
}
35
+
}
36
+
37
+
pub fn image(&self) -> &'static [u8] {
38
+
match self {
39
+
Self::Ferris => FERRIS_IMG,
40
+
Self::Repo => REPO_IMG,
41
+
}
42
+
}
43
+
44
+
pub fn next(&self) -> Self {
45
+
let image_count = self.as_u8();
46
+
let next_image = (image_count + 1) % NUMBER_OF_IMAGES;
47
+
DisplayImage::from_u8(next_image).unwrap()
48
+
}
49
+
50
+
pub fn previous(&self) -> Self {
51
+
let image_count = self.as_u8();
52
+
if image_count == 0 {
53
+
return DisplayImage::from_u8(NUMBER_OF_IMAGES - 1).unwrap();
54
+
}
55
+
let previous_image = (image_count - 1) % NUMBER_OF_IMAGES;
56
+
DisplayImage::from_u8(previous_image).unwrap()
57
+
}
58
+
59
+
pub fn image_location(&self) -> Point {
60
+
match self {
61
+
Self::Ferris => Point::new(150, 26),
62
+
Self::Repo => Point::new(190, 26),
63
+
}
64
+
}
65
+
}
+88
-53
src/main.rs
+88
-53
src/main.rs
···
5
5
#![no_std]
6
6
#![no_main]
7
7
use core::sync::atomic::AtomicU32;
8
-
9
-
use cyw43_driver::setup_cyw43;
10
8
use defmt::info;
11
9
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
12
10
use embassy_executor::Spawner;
···
18
16
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
19
17
use embassy_sync::mutex::Mutex;
20
18
use embassy_time::{Delay, Duration, Timer};
21
-
use embedded_graphics::primitives::PrimitiveStyleBuilder;
22
-
use embedded_graphics::text::Text;
23
19
use embedded_graphics::{
20
+
image::Image,
24
21
mono_font::{ascii::*, MonoTextStyle},
25
22
pixelcolor::BinaryColor,
26
23
prelude::*,
···
33
30
};
34
31
use gpio::{Level, Output, Pull};
35
32
use heapless::String;
33
+
use image_handler::{get_current_image, DisplayImage, CHANGE_IMAGE, CURRENT_IMAGE};
36
34
use static_cell::StaticCell;
35
+
use tinybmp::Bmp;
37
36
use uc8151::asynch::Uc8151;
38
37
use uc8151::LUT;
39
38
use uc8151::WIDTH;
40
39
use {defmt_rtt as _, panic_probe as _};
40
+
41
41
mod cyw43_driver;
42
+
mod image_handler;
42
43
43
44
type Spi0Bus = Mutex<NoopRawMutex, Spi<'static, SPI0, spi::Async>>;
45
+
44
46
static WIFI_COUNT: AtomicU32 = AtomicU32::new(0);
45
47
46
48
#[embassy_executor::main]
47
49
async fn main(spawner: Spawner) {
48
50
let p = embassy_rp::init(Default::default());
49
-
let (_net_device, mut control) = setup_cyw43(
50
-
p.PIO0, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, spawner,
51
-
)
52
-
.await;
51
+
// let (_net_device, mut control) = setup_cyw43(
52
+
// p.PIO0, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, spawner,
53
+
// )
54
+
// .await;
53
55
54
56
// let input = gpio::Input::new(p.PIN_29, gpio::Pull::Up);
55
57
···
62
64
let reset = p.PIN_21;
63
65
let power = p.PIN_10;
64
66
65
-
let btn_up = p.PIN_15;
66
-
let btn_down = p.PIN_11;
67
-
let btn_a = p.PIN_12;
68
-
let btn_b = p.PIN_13;
69
-
let btn_c = p.PIN_14;
70
-
71
67
let reset = Output::new(reset, Level::Low);
72
68
let _power = Output::new(power, Level::Low);
73
69
···
75
71
let cs = Output::new(cs, Level::High);
76
72
let busy = Input::new(busy, Pull::Up);
77
73
78
-
let mut _btn_up = Input::new(btn_up, Pull::Up);
79
-
let mut _btn_down = Input::new(btn_down, Pull::Up);
80
-
let mut _btn_a = Input::new(btn_a, Pull::Up);
81
-
let mut _btn_b = Input::new(btn_b, Pull::Up);
82
-
let mut _btn_c = Input::new(btn_c, Pull::Up);
74
+
let _btn_up = Input::new(p.PIN_15, Pull::Down);
75
+
let _btn_down = Input::new(p.PIN_11, Pull::Down);
76
+
let _btn_a = Input::new(p.PIN_12, Pull::Down);
77
+
let _btn_b = Input::new(p.PIN_13, Pull::Down);
78
+
let btn_c = Input::new(p.PIN_14, Pull::Down);
79
+
80
+
// let mut btn_c: Debouncer<'_> = Debouncer::new(Input::new(btn_c, Pull::Up), Duration::from_millis(20));
83
81
84
82
let spi = Spi::new(
85
83
p.SPI0,
···
95
93
let spi_bus = SPI_BUS.init(Mutex::new(spi));
96
94
97
95
info!("led on!");
98
-
control.gpio_set(0, true).await;
96
+
// control.gpio_set(0, true).await;
99
97
spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset));
98
+
99
+
//Input loop
100
+
loop {
101
+
//Change Image Button
102
+
if btn_c.is_high() {
103
+
info!("Button C pressed");
104
+
let current_image = CURRENT_IMAGE.load(core::sync::atomic::Ordering::Relaxed);
105
+
let new_image = DisplayImage::from_u8(current_image).unwrap().next();
106
+
CURRENT_IMAGE.store(new_image.as_u8(), core::sync::atomic::Ordering::Relaxed);
107
+
CHANGE_IMAGE.store(true, core::sync::atomic::Ordering::Relaxed);
108
+
Timer::after(Duration::from_millis(500)).await;
109
+
continue;
110
+
}
111
+
Timer::after(Duration::from_millis(100)).await;
112
+
}
100
113
}
101
114
102
115
#[embassy_executor::task]
···
120
133
let character_style = MonoTextStyle::new(&FONT_9X18_BOLD, BinaryColor::Off);
121
134
let textbox_style = TextBoxStyleBuilder::new()
122
135
.height_mode(HeightMode::FitToText)
123
-
.alignment(HorizontalAlignment::Center)
136
+
.alignment(HorizontalAlignment::Left)
124
137
.paragraph_spacing(6)
125
138
.build();
126
139
127
140
// Bounding box for our text. Fill it with the opposite color so we can read the text.
128
-
let bounds = Rectangle::new(Point::new(0, 40), Size::new(WIDTH - 157, 0));
129
-
bounds
141
+
let name_and_detail_bounds = Rectangle::new(Point::new(0, 40), Size::new(WIDTH - 75, 0));
142
+
name_and_detail_bounds
130
143
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
131
144
.draw(&mut display)
132
145
.unwrap();
133
146
134
147
// Create the text box and apply styling options.
135
-
let text = "Written In\nRust!!";
136
-
let text_box = TextBox::with_textbox_style(text, bounds, character_style, textbox_style);
148
+
149
+
let text = "Bailey Townsend\nSoftware Dev";
150
+
// \nWritten in rust\nRunning on a pico w";
151
+
let name_and_detail_box =
152
+
TextBox::with_textbox_style(text, name_and_detail_bounds, character_style, textbox_style);
137
153
138
154
// Draw the text box.
139
-
text_box.draw(&mut display).unwrap();
155
+
name_and_detail_box.draw(&mut display).unwrap();
140
156
141
157
let _ = display.update().await;
142
158
···
145
161
146
162
loop {
147
163
let count = WIFI_COUNT.load(core::sync::atomic::Ordering::Relaxed);
148
-
let _ = core::fmt::write(&mut text, format_args!("Count: {}", count));
149
-
let count_bounds = Rectangle::new(Point::new(0, 0), Size::new(WIDTH, 24));
150
-
count_bounds
151
-
.into_styled(
152
-
PrimitiveStyleBuilder::default()
153
-
.stroke_color(BinaryColor::Off)
154
-
.fill_color(BinaryColor::On)
155
-
.stroke_width(1)
156
-
.build(),
157
-
)
158
-
.draw(&mut display)
159
-
.unwrap();
164
+
// let _ = core::fmt::write(&mut text, format_args!("Count: {}", count));
165
+
// let count_bounds = Rectangle::new(Point::new(0, 0), Size::new(WIDTH, 24));
166
+
// count_bounds
167
+
// .into_styled(
168
+
// PrimitiveStyleBuilder::default()
169
+
// .stroke_color(BinaryColor::Off)
170
+
// .fill_color(BinaryColor::On)
171
+
// .stroke_width(1)
172
+
// .build(),
173
+
// )
174
+
// .draw(&mut display)
175
+
// .unwrap();
160
176
161
-
Text::new(text.as_str(), Point::new(8, 16), character_style)
162
-
.draw(&mut display)
163
-
.unwrap();
177
+
// Text::new(text.as_str(), Point::new(8, 16), character_style)
178
+
// .draw(&mut display)
179
+
// .unwrap();
164
180
165
-
// // Draw the text box.
166
-
let result = display
167
-
.partial_update(count_bounds.try_into().unwrap())
168
-
.await;
169
-
match result {
170
-
Ok(_) => {}
171
-
Err(_) => {
172
-
info!("Error updating display");
173
-
}
174
-
}
175
-
text.clear();
181
+
// // // Draw the text box.
182
+
// let result = display
183
+
// .partial_update(count_bounds.try_into().unwrap())
184
+
// .await;
185
+
// match result {
186
+
// Ok(_) => {}
187
+
// Err(_) => {
188
+
// info!("Error updating display");
189
+
// }
190
+
// }
191
+
// text.clear();
176
192
// let _ = display.clear(Rgb565::WHITE.into());
177
193
// let _ = display.update().await;
178
194
WIFI_COUNT.store(count + 1, core::sync::atomic::Ordering::Relaxed);
179
195
180
-
Timer::after(delay).await;
196
+
if CHANGE_IMAGE.load(core::sync::atomic::Ordering::Relaxed) {
197
+
let current_image = get_current_image();
198
+
let tga: Bmp<BinaryColor> = Bmp::from_slice(¤t_image.image()).unwrap();
199
+
let image = Image::new(&tga, current_image.image_location());
200
+
//clear image location by writing a white rectangle over previous image location
201
+
let clear_bounds = Rectangle::new(
202
+
current_image.previous().image_location(),
203
+
Size::new(157, 91),
204
+
);
205
+
clear_bounds
206
+
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
207
+
.draw(&mut display)
208
+
.unwrap();
209
+
210
+
let _ = image.draw(&mut display);
211
+
let _ = display.update().await;
212
+
CHANGE_IMAGE.store(false, core::sync::atomic::Ordering::Relaxed);
213
+
}
214
+
215
+
Timer::after(Duration::from_millis(500)).await;
181
216
}
182
217
}