basic game loop and some ic2 and display stuff
This commit is contained in:
parent
54e54a90e7
commit
5d33f358d6
6 changed files with 337 additions and 60 deletions
183
Cargo.lock
generated
183
Cargo.lock
generated
|
@ -14,6 +14,12 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byte-slice-cast"
|
||||
version = "0.3.5"
|
||||
|
@ -26,6 +32,21 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "display-interface"
|
||||
version = "0.4.1"
|
||||
|
@ -53,6 +74,16 @@ dependencies = [
|
|||
"embedded-hal 0.2.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ds323x"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5157c16c530fa971b40f2b591edd86b9ce300ec1e5c267a4d6df6ee7df890a6"
|
||||
dependencies = [
|
||||
"embedded-hal 0.2.7",
|
||||
"rtcc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-graphics"
|
||||
version = "0.8.1"
|
||||
|
@ -111,12 +142,37 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "game-loop"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f565189f0b27943213411d9d1c2df8b5d066e14d2e75f041d3b53c13b24ac80"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "micromath"
|
||||
version = "2.1.0"
|
||||
|
@ -148,12 +204,27 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "pipod"
|
||||
version = "0.1.0"
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"rppal",
|
||||
"ssd1306",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -171,6 +242,26 @@ dependencies = [
|
|||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtcc"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95973c3a0274adc4f3c5b70d2b5b85618d6de9559a6737d3293ecae9a2fc0839"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sojourn"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ds323x",
|
||||
"embedded-graphics",
|
||||
"game-loop",
|
||||
"rppal",
|
||||
"ssd1306",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin_sleep"
|
||||
version = "1.2.1"
|
||||
|
@ -193,12 +284,94 @@ dependencies = [
|
|||
"embedded-hal 0.2.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
[package]
|
||||
name = "pipod"
|
||||
name = "sojourn"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ds323x = "0.5.1"
|
||||
embedded-graphics = "0.8.1"
|
||||
game-loop = "1.2.0"
|
||||
rppal = { version = "0.19.0", features = ["hal"] }
|
||||
ssd1306 = "0.8.4"
|
||||
|
|
13
cmd
13
cmd
|
@ -19,13 +19,13 @@ else
|
|||
fi
|
||||
|
||||
ssh_run_cmd() {
|
||||
ssh -i "$SSH_KEY" "$SSH_HOST" "$@"
|
||||
ssh -i "$SSH_KEY" -t "$SSH_HOST" "$@"
|
||||
}
|
||||
|
||||
copy_and_run() {
|
||||
file=$1
|
||||
scp -i "$SSH_KEY" "$file" "$SSH_HOST":"$SSH_DEST_DIR"
|
||||
ssh_run_cmd "${SSH_DEST_DIR:-.}/pipod"
|
||||
ssh_run_cmd "${SSH_DEST_DIR:-.}/sojourn"
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -34,9 +34,12 @@ copy_and_run() {
|
|||
"clean") cargo clean;;
|
||||
"build") cargo build --target arm-unknown-linux-gnueabihf;;
|
||||
"release") cargo build --release --target arm-unknown-linux-gnueabihf;;
|
||||
"debug") ./cmd build && copy_and_run ./target/arm-unknown-linux-gnueabihf/debug/pipod;;
|
||||
"run") ./cmd release && copy_and_run ./target/arm-unknown-linux-gnueabihf/release/pipod;;
|
||||
"remote-clean") ssh_run_cmd rm -f "${SSH_DEST_DIR:-.}/pipod";;
|
||||
"debug") ./cmd build && copy_and_run ./target/arm-unknown-linux-gnueabihf/debug/sojourn;;
|
||||
"run") ./cmd release && copy_and_run ./target/arm-unknown-linux-gnueabihf/release/sojourn;;
|
||||
"remote-clean")
|
||||
ssh_run_cmd killall sojourn
|
||||
ssh_run_cmd rm -f "${SSH_DEST_DIR:-.}/sojourn"
|
||||
;;
|
||||
"help")
|
||||
echo "Usage: ./cmd [task]"
|
||||
echo "Tasks: clean, build, release, debug, run, remote-clean, help"
|
||||
|
|
135
src/game.rs
Normal file
135
src/game.rs
Normal file
|
@ -0,0 +1,135 @@
|
|||
use crate::strings;
|
||||
use embedded_graphics::{
|
||||
mono_font::{ascii::FONT_4X6, MonoTextStyleBuilder, MonoTextStyle},
|
||||
pixelcolor::BinaryColor,
|
||||
image::{Image, ImageRaw},
|
||||
prelude::*,
|
||||
primitives::{PrimitiveStyleBuilder, PrimitiveStyle, Line},
|
||||
text::{Baseline, Text},
|
||||
};
|
||||
use rppal::i2c::I2c;
|
||||
use ssd1306::{
|
||||
prelude::{
|
||||
I2CInterface as SsdRtc,
|
||||
DisplaySize128x64,
|
||||
DisplayRotation,
|
||||
},
|
||||
mode::{
|
||||
BufferedGraphicsMode,
|
||||
DisplayConfig,
|
||||
},
|
||||
I2CDisplayInterface,
|
||||
Ssd1306,
|
||||
};
|
||||
use ds323x::{
|
||||
ic::DS3231,
|
||||
interface::I2cInterface as RtcI2c,
|
||||
Ds323x,
|
||||
DateTimeAccess,
|
||||
NaiveDateTime,
|
||||
};
|
||||
|
||||
const ADDR_PISUGAR: u16 = 0x57;
|
||||
const BATT_POLL_SECONDS: u64 = 3;
|
||||
const REG_PERCENT: u8 = 0x2a;
|
||||
|
||||
const BAT_DATA: &'static [u8] = &[
|
||||
0b11111110,
|
||||
0b10000010,
|
||||
0b10000001,
|
||||
0b10000001,
|
||||
0b10000010,
|
||||
0b11111110,
|
||||
];
|
||||
|
||||
pub struct Game<'a> {
|
||||
batt_i2c: I2c,
|
||||
display: Ssd1306<SsdRtc<I2c>, DisplaySize128x64, BufferedGraphicsMode<DisplaySize128x64>>,
|
||||
rtc: Ds323x<RtcI2c<I2c>, DS3231>,
|
||||
style: PrimitiveStyle<BinaryColor>,
|
||||
text_style: MonoTextStyle<'a, BinaryColor>,
|
||||
last_batt_poll: Option<NaiveDateTime>,
|
||||
batt_pct: u8,
|
||||
title: String,
|
||||
}
|
||||
|
||||
impl Game<'_> {
|
||||
|
||||
pub fn new() -> Game<'static> {
|
||||
let display_i2c = I2c::new().unwrap();
|
||||
let interface = I2CDisplayInterface::new(display_i2c);
|
||||
let rtc_i2c = I2c::new().unwrap();
|
||||
let mut game: Game = Game {
|
||||
batt_i2c: I2c::new().unwrap(),
|
||||
display: Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
|
||||
.into_buffered_graphics_mode(),
|
||||
rtc: Ds323x::new_ds3231(rtc_i2c),
|
||||
style: PrimitiveStyleBuilder::new()
|
||||
.stroke_width(1)
|
||||
.stroke_color(BinaryColor::On)
|
||||
.build(),
|
||||
text_style: MonoTextStyleBuilder::new()
|
||||
.font(&FONT_4X6)
|
||||
.text_color(BinaryColor::On)
|
||||
.build(),
|
||||
last_batt_poll: None,
|
||||
batt_pct: 0,
|
||||
title: format!("{} v{}", strings::SOJOURN, strings::VERSION),
|
||||
};
|
||||
game.batt_i2c.set_slave_address(ADDR_PISUGAR).unwrap();
|
||||
game.display.init().unwrap();
|
||||
return game;
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
let dt = self.rtc.datetime().unwrap();
|
||||
if !self.last_batt_poll.is_some() || (dt - self.last_batt_poll.unwrap())
|
||||
.num_seconds().unsigned_abs() > BATT_POLL_SECONDS {
|
||||
self.read_batt_pct();
|
||||
self.last_batt_poll = Some(dt);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&mut self) {
|
||||
self.draw_status();
|
||||
self.display.flush().unwrap();
|
||||
}
|
||||
|
||||
fn read_batt_pct(&mut self) {
|
||||
let mut buf = [0u8; 1];
|
||||
self.batt_i2c.block_read(REG_PERCENT, &mut buf).unwrap();
|
||||
self.batt_pct = buf[0];
|
||||
}
|
||||
|
||||
fn draw_status(&mut self) {
|
||||
self.display.clear_buffer();
|
||||
|
||||
Line::new(Point::new(0, 8), Point::new(127, 8))
|
||||
.into_styled(self.style)
|
||||
.draw(&mut self.display)
|
||||
.unwrap();
|
||||
|
||||
Text::with_baseline(
|
||||
&format!("{: >3}%", self.batt_pct),
|
||||
Point::new(111, 0),
|
||||
self.text_style,
|
||||
Baseline::Top,
|
||||
)
|
||||
.draw(&mut self.display)
|
||||
.unwrap();
|
||||
|
||||
let raw_image = ImageRaw::<BinaryColor>::new(BAT_DATA, 8);
|
||||
let image = Image::new(&raw_image, Point::new(102, 0));
|
||||
image.draw(&mut self.display).unwrap();
|
||||
|
||||
// 24 chars for title max
|
||||
Text::with_baseline(
|
||||
&self.title,
|
||||
Point::new(0, 0),
|
||||
self.text_style,
|
||||
Baseline::Top,
|
||||
)
|
||||
.draw(&mut self.display)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
60
src/main.rs
60
src/main.rs
|
@ -1,53 +1,15 @@
|
|||
use embedded_graphics::{
|
||||
mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle},
|
||||
text::{Baseline, Text},
|
||||
};
|
||||
use rppal::i2c::I2c;
|
||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||
mod game;
|
||||
mod strings;
|
||||
mod display;
|
||||
|
||||
const ADDR_PISUGAR: u16 = 0x57;
|
||||
const REG_PERCENT: u8 = 0x2a;
|
||||
const REG_RTC: u8 = 0x68;
|
||||
use game::Game;
|
||||
use game_loop::game_loop;
|
||||
|
||||
fn main() {
|
||||
let mut batt_i2c = I2c::new().unwrap();
|
||||
batt_i2c.set_slave_address(ADDR_PISUGAR);
|
||||
|
||||
let mut buf = [0u8; 1];
|
||||
batt_i2c.block_read(REG_PERCENT, &mut buf).unwrap();
|
||||
|
||||
let display_i2c = I2c::new().unwrap();
|
||||
let interface = I2CDisplayInterface::new(display_i2c);
|
||||
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
|
||||
.into_buffered_graphics_mode();
|
||||
display.init().unwrap();
|
||||
|
||||
/*let style = PrimitiveStyleBuilder::new()
|
||||
.stroke_width(1)
|
||||
.stroke_color(BinaryColor::On)
|
||||
.build();
|
||||
|
||||
Rectangle::new(Point::new(0, 0), Size::new(127, 63))
|
||||
.into_styled(style)
|
||||
.draw(&mut display)
|
||||
.unwrap();
|
||||
|
||||
let text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_6X10)
|
||||
.text_color(BinaryColor::On)
|
||||
.build();
|
||||
|
||||
Text::with_baseline(
|
||||
&format!("Battery: {}%", buf[0]),
|
||||
Point::new(2, 2),
|
||||
text_style,
|
||||
Baseline::Top,
|
||||
)
|
||||
.draw(&mut display)
|
||||
.unwrap();*/
|
||||
|
||||
display.flush().unwrap();
|
||||
let game = Game::new();
|
||||
game_loop(game, 60, 0.1, |g| {
|
||||
g.game.update();
|
||||
}, |g| {
|
||||
g.game.draw();
|
||||
});
|
||||
}
|
||||
|
|
2
src/strings.rs
Normal file
2
src/strings.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub const SOJOURN: &str = "sojourn";
|
||||
pub const VERSION: &str = "0.1.0";
|
Loading…
Reference in a new issue