Skip to content

Commit 8fbb85b

Browse files
committed
ledmatrix: Allow setting animation frequency
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 88383d0 commit 8fbb85b

File tree

9 files changed

+48
-17
lines changed

9 files changed

+48
-17
lines changed

fl16-inputmodules/src/control.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,14 @@ pub fn parse_module_command(count: usize, buf: &[u8]) -> Option<Command> {
338338
_ => None,
339339
},
340340
Some(CommandVals::GameStatus) => Some(Command::GameStatus),
341+
Some(CommandVals::AnimationPeriod) => {
342+
if count == 3 + 2 {
343+
let period = u16::from_le_bytes([buf[3], buf[4]]);
344+
Some(Command::SetAnimationPeriod(period))
345+
} else {
346+
Some(Command::GetAnimationPeriod)
347+
}
348+
}
341349
_ => None,
342350
}
343351
} else {
@@ -455,7 +463,7 @@ pub fn handle_generic_command(command: &Command) -> Option<[u8; 32]> {
455463
#[cfg(feature = "ledmatrix")]
456464
pub fn handle_command(
457465
command: &Command,
458-
state: &mut State,
466+
state: &mut LedmatrixState,
459467
matrix: &mut Foo,
460468
random: u8,
461469
) -> Option<[u8; 32]> {
@@ -552,6 +560,17 @@ pub fn handle_command(
552560
None
553561
}
554562
Command::GameStatus => None,
563+
Command::SetAnimationPeriod(period) => {
564+
state.animation_period = (*period as u64) * 1_000;
565+
None
566+
}
567+
Command::GetAnimationPeriod => {
568+
// TODO: Doesn't seem to work when the FPS is 16 or higher
569+
let mut response: [u8; 32] = [0; 32];
570+
let period_ms = state.animation_period / 1_000;
571+
response[0..2].copy_from_slice(&(period_ms as u16).to_le_bytes());
572+
Some(response)
573+
}
555574
_ => handle_generic_command(command),
556575
}
557576
}

fl16-inputmodules/src/games/game_of_life.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::control::{GameControlArg, GameOfLifeStartParam};
2-
use crate::matrix::{GameState, Grid, State, HEIGHT, WIDTH};
2+
use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH};
33

44
#[derive(Clone, Copy, num_derive::FromPrimitive)]
55
pub enum Cell {
@@ -12,19 +12,19 @@ pub struct GameOfLifeState {
1212
cells: [[Cell; WIDTH]; HEIGHT],
1313
}
1414

15-
pub fn start_game(state: &mut State, _random: u8, param: GameOfLifeStartParam) {
15+
pub fn start_game(state: &mut LedmatrixState, _random: u8, param: GameOfLifeStartParam) {
1616
let gol = GameOfLifeState::new(param, &state.grid);
1717
state.grid = gol.draw_matrix();
1818
state.game = Some(GameState::GameOfLife(gol));
1919
}
20-
pub fn handle_control(state: &mut State, arg: &GameControlArg) {
20+
pub fn handle_control(state: &mut LedmatrixState, arg: &GameControlArg) {
2121
if let Some(GameState::GameOfLife(ref mut _gol_state)) = state.game {
2222
if let GameControlArg::Exit = arg {
2323
state.game = None
2424
}
2525
}
2626
}
27-
pub fn game_step(state: &mut State, _random: u8) {
27+
pub fn game_step(state: &mut LedmatrixState, _random: u8) {
2828
if let Some(GameState::GameOfLife(ref mut gol_state)) = state.game {
2929
gol_state.tick();
3030
state.grid = gol_state.draw_matrix();

fl16-inputmodules/src/games/pong.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::control::GameControlArg;
2-
use crate::matrix::{GameState, Grid, State, HEIGHT, WIDTH};
2+
use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH};
33

44
const PADDLE_WIDTH: usize = 5;
55

@@ -28,7 +28,7 @@ pub struct PongState {
2828
pub speed: u64,
2929
}
3030

31-
pub fn start_game(state: &mut State, _random: u8) {
31+
pub fn start_game(state: &mut LedmatrixState, _random: u8) {
3232
state.game = Some(GameState::Pong(PongState {
3333
_score: Score {
3434
_upper: 0,
@@ -42,7 +42,7 @@ pub fn start_game(state: &mut State, _random: u8) {
4242
speed: 0,
4343
}))
4444
}
45-
pub fn handle_control(state: &mut State, arg: &GameControlArg) {
45+
pub fn handle_control(state: &mut LedmatrixState, arg: &GameControlArg) {
4646
if let Some(GameState::Pong(ref mut pong_state)) = state.game {
4747
match arg {
4848
GameControlArg::Left => {
@@ -96,7 +96,7 @@ fn hit_paddle(ball: Position, paddles: (usize, usize)) -> Option<usize> {
9696
}
9797
}
9898

99-
pub fn game_step(state: &mut State, _random: u8) {
99+
pub fn game_step(state: &mut LedmatrixState, _random: u8) {
100100
if let Some(GameState::Pong(ref mut pong_state)) = state.game {
101101
pong_state.ball.pos = {
102102
let (vx, vy) = pong_state.ball.direction;

fl16-inputmodules/src/games/snake.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::control::GameControlArg;
2-
use crate::matrix::{GameState, Grid, State, HEIGHT, LEDS, WIDTH};
2+
use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, LEDS, WIDTH};
33

44
use heapless::Vec;
55

@@ -33,7 +33,7 @@ fn place_food(random: u8) -> Position {
3333
(x as i8, y as i8)
3434
}
3535

36-
pub fn start_game(state: &mut State, random: u8) {
36+
pub fn start_game(state: &mut LedmatrixState, random: u8) {
3737
state.game = Some(GameState::Snake(SnakeState {
3838
head: (4, 0),
3939
direction: HeadDirection::Down,
@@ -42,7 +42,7 @@ pub fn start_game(state: &mut State, random: u8) {
4242
food: place_food(random),
4343
}));
4444
}
45-
pub fn handle_control(state: &mut State, arg: &GameControlArg) {
45+
pub fn handle_control(state: &mut LedmatrixState, arg: &GameControlArg) {
4646
if let Some(GameState::Snake(ref mut snake_state)) = state.game {
4747
match arg {
4848
GameControlArg::Up => snake_state.direction = HeadDirection::Up,
@@ -55,7 +55,7 @@ pub fn handle_control(state: &mut State, arg: &GameControlArg) {
5555
}
5656
}
5757

58-
pub fn game_step(state: &mut State, random: u8) -> (HeadDirection, bool, usize, Position) {
58+
pub fn game_step(state: &mut LedmatrixState, random: u8) -> (HeadDirection, bool, usize, Position) {
5959
if let Some(GameState::Snake(ref mut snake_state)) = state.game {
6060
if snake_state.game_over {
6161
return (

fl16-inputmodules/src/matrix.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ impl Default for Grid {
1414
}
1515
}
1616

17-
pub struct State {
17+
pub struct LedmatrixState {
1818
pub grid: Grid,
1919
pub col_buffer: Grid,
2020
pub animate: bool,
2121
pub brightness: u8,
2222
pub sleeping: SleepState,
2323
pub game: Option<GameState>,
24+
pub animation_period: u64,
2425
}
2526

2627
#[allow(clippy::large_enum_variant)]

inputmodule-control/src/inputmodule.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ pub fn serial_commands(args: &crate::ClapCli) {
213213
start_game_cmd(serialdev, game, ledmatrix_args.game_param);
214214
}
215215

216+
if let Some(fps) = ledmatrix_args.animation_fps {
217+
animation_fps_cmd(serialdev, fps);
218+
}
219+
216220
if ledmatrix_args.stop_game {
217221
simple_cmd(
218222
serialdev,

inputmodule-control/src/ledmatrix.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ pub struct LedMatrixSubcommand {
117117
#[clap(value_enum)]
118118
pub stop_game: bool,
119119

120+
/// Set/get animation FPS
121+
#[arg(long)]
122+
pub animation_fps: Option<Option<u16>>,
123+
120124
/// Crash the firmware (TESTING ONLY!)
121125
#[arg(long)]
122126
pub panic: bool,

ledmatrix/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Options:
6464
Paramater for starting the game. Required for some games [possible values: current-matrix, pattern1, blinker, toad, beacon, glider]
6565
--stop-game
6666
Stop the currently running game
67+
--animation-fps [<ANIMATION_FPS>]
68+
Set/get animation FPS
6769
--panic
6870
Crash the firmware (TESTING ONLY!)
6971
-v, --version

ledmatrix/src/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,14 @@ fn main() -> ! {
189189
&clocks.peripheral_clock,
190190
);
191191

192-
let mut state = State {
192+
let mut state = LedmatrixState {
193193
grid: percentage(0),
194194
col_buffer: Grid::default(),
195195
animate: false,
196196
brightness: 120,
197197
sleeping: SleepState::Awake,
198198
game: None,
199+
animation_period: 31_250, // 32 FPS
199200
};
200201

201202
let mut matrix = LedMatrix::configure(i2c);
@@ -228,7 +229,7 @@ fn main() -> ! {
228229
//);
229230

230231
// Handle period display updates. Don't do it too often
231-
if timer.get_counter().ticks() > prev_timer + 20_000 {
232+
if timer.get_counter().ticks() > prev_timer + state.animation_period {
232233
// On startup slowly turn the screen on - it's a pretty effect :)
233234
match startup_percentage {
234235
Some(p) if p <= 100 => {
@@ -357,7 +358,7 @@ fn get_random_byte(rosc: &RingOscillator<Enabled>) -> u8 {
357358

358359
fn handle_sleep(
359360
go_sleeping: bool,
360-
state: &mut State,
361+
state: &mut LedmatrixState,
361362
matrix: &mut Foo,
362363
delay: &mut Delay,
363364
led_enable: &mut gpio::Pin<Gpio29, gpio::Output<gpio::PushPull>>,

0 commit comments

Comments
 (0)