Skip to content

WIP: Persistent configuration #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
286 changes: 170 additions & 116 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions fl16-inputmodules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ tinybmp = { workspace = true, optional = true }
smart-leds = { workspace = true, optional = true }
ws2812-pio = { workspace = true, optional = true }

# Persistent configuration
rp2040-flash = "0.3.1"
#serde = { version = "1.0.183", default-features = false, features = ["derive"]}
serde = { default-features = false, features = [
"derive",
], version = "1.0" } ##it = "file:///home/zoid/clone/reference/serde", branch = "array-34-100" }
#serde_derive = { default-features = false, features = [
#], git = "file:///home/zoid/clone/reference/serde", branch = "array-34" }
#serde-big-array = "0.5.1"
#serde_arrays = { version = "0.1.0", default-features = false, git = "https://github.com/jaredwolff/serde_arrays.git", features = [
# "no-std",
#] }
postcard = "1.0.0"

[features]
default = []
ledmatrix = ["is31fl3741"]
Expand Down
9 changes: 8 additions & 1 deletion fl16-inputmodules/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ use is31fl3741::PwmFreq;
#[cfg(feature = "c1minimal")]
use smart_leds::{SmartLedsWrite, RGB8};

use serde::{Deserialize, Serialize};

#[repr(u8)]
#[derive(num_derive::FromPrimitive)]
/// All available commands
Expand Down Expand Up @@ -68,6 +70,7 @@ pub enum CommandVals {
SetFps = 0x1A,
SetPowerMode = 0x1B,
AnimationPeriod = 0x1C,
Save = 0x1D,
PwmFreq = 0x1E,
Version = 0x20,
}
Expand Down Expand Up @@ -129,7 +132,7 @@ pub enum DisplayMode {
}

#[cfg(feature = "ledmatrix")]
#[derive(Copy, Clone, num_derive::FromPrimitive)]
#[derive(Copy, Clone, num_derive::FromPrimitive, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum PwmFreqArg {
/// 29kHz
P29k = 0x00,
Expand Down Expand Up @@ -202,6 +205,7 @@ pub enum Command {
GetPowerMode,
SetAnimationPeriod(u16),
GetAnimationPeriod,
Save,
#[cfg(feature = "ledmatrix")]
SetPwmFreq(PwmFreqArg),
GetPwmFreq,
Expand Down Expand Up @@ -378,6 +382,7 @@ pub fn parse_module_command(count: usize, buf: &[u8]) -> Option<Command> {
Some(Command::GetAnimationPeriod)
}
}
Some(CommandVals::Save) => Some(Command::Save),
Some(CommandVals::PwmFreq) => {
if let Some(freq) = arg {
FromPrimitive::from_u8(freq).map(Command::SetPwmFreq)
Expand Down Expand Up @@ -604,6 +609,8 @@ pub fn handle_command(
response[0..2].copy_from_slice(&(period_ms as u16).to_le_bytes());
Some(response)
}
// TODO
// Command::Save => None,
Command::SetPwmFreq(arg) => {
state.pwm_freq = *arg;
matrix.device.set_pwm_freq(state.pwm_freq.into()).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions fl16-inputmodules/src/games/game_of_life.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::control::{GameControlArg, GameOfLifeStartParam};
use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH};

#[derive(Clone, Copy, num_derive::FromPrimitive)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, num_derive::FromPrimitive)]
pub enum Cell {
Dead = 0,
Alive = 1,
}

#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GameOfLifeState {
cells: [[Cell; WIDTH]; HEIGHT],
}
Expand Down
6 changes: 3 additions & 3 deletions fl16-inputmodules/src/games/pong.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH};

const PADDLE_WIDTH: usize = 5;

#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
struct Score {
_upper: u8,
_lower: u8,
Expand All @@ -12,14 +12,14 @@ struct Score {
type Position = (usize, usize);
type Velocity = (i8, i8);

#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
struct Ball {
pos: Position,
// Not a position, more like a directional vector
direction: Velocity,
}

#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PongState {
// TODO: Properly calculate score and display it
_score: Score,
Expand Down
4 changes: 2 additions & 2 deletions fl16-inputmodules/src/games/snake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use heapless::Vec;
// Wrap around the edges
const WRAP_ENABLE: bool = false;

#[derive(Clone, Debug, Copy)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HeadDirection {
Up,
Down,
Expand All @@ -16,7 +16,7 @@ pub enum HeadDirection {

type Position = (i8, i8);

#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SnakeState {
head: Position,
pub direction: HeadDirection,
Expand Down
73 changes: 68 additions & 5 deletions fl16-inputmodules/src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,101 @@ use crate::games::game_of_life::GameOfLifeState;
use crate::games::pong::PongState;
use crate::games::snake::SnakeState;

use core::ops::Deref;
use heapless::Vec;
use postcard::{from_bytes, to_vec};
use serde::{Deserialize, Serialize};
use rp2040_flash::flash;

pub const WIDTH: usize = 9;
pub const HEIGHT: usize = 34;
pub const LEDS: usize = WIDTH * HEIGHT;

#[derive(Clone)]
pub struct Grid(pub [[u8; HEIGHT]; WIDTH]);
//#[derive(Clone, Copy, Debug, PartialEq, Eq)]
//pub struct Col( pub [u8; HEIGHT]);
//#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
//pub struct Grid(
// pub [Col; WIDTH],
//);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Grid(pub Vec<Vec<u8, HEIGHT>, WIDTH>);
impl Default for Grid {
fn default() -> Self {
Grid([[0; HEIGHT]; WIDTH])
let mut vec: Vec<Vec<u8, HEIGHT>, WIDTH> = Vec::new();
for _ in 0..WIDTH {
let mut col = Vec::new();
for _ in 0..HEIGHT {
col.push(0).unwrap();
}
vec.push(col).unwrap();
}
Grid(vec)
}
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct LedmatrixState {
pub rev: u16,
pub grid: Grid,
#[serde(skip)]
pub col_buffer: Grid,
pub animate: bool,
pub brightness: u8,
pub sleeping: SleepState,
#[serde(skip)]
pub game: Option<GameState>,
pub animation_period: u64,
pub pwm_freq: PwmFreqArg,
}

unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
::core::slice::from_raw_parts(
(p as *const T) as *const u8,
::core::mem::size_of::<T>(),
)
}

impl LedmatrixState {
pub fn save(&self) {
//let foo: Vec<u8, {core::mem::size_of::<Grid>()}> = to_vec(&self.grid).unwrap();
let foo: &[u8] = unsafe {any_as_u8_slice(&self.grid)};
let mut data: Vec<u8, 4096> = Vec::new();
for _ in 0..4096 {
data.push(0);
}
data[0..{core::mem::size_of::<Grid>()}].copy_from_slice(foo);
let addr = 0xfe000; // 2nd to last 4K sector
cortex_m::interrupt::free(|_cs| {
unsafe {flash::flash_range_erase_and_program(addr, &data, true)};
});
}
pub fn restore() -> Grid {
let addr = 0xfe000 + 0x10000000; // 2nd to last 4K sector
unsafe {
//let bytes = *(&*(addr as *const &[u8; 4096]));
//let g: *const Grid = (bytes as *const u8) as *const Grid;
//let g = &*(addr as *const &Grid);
//(*g).clone()
//from_bytes(bytes).unwrap()
}
Grid::default()
}
}

#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum SleepState {
Awake,
Sleeping((Grid, u8)),
}
//impl Default for SleepState {
// fn default() -> Self {
// SleepState::Awake
// }
//}

#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GameState {
Snake(SnakeState),
Pong(PongState),
Expand Down
Loading