Skip to content

Commit ba48d13

Browse files
authored
Merge pull request #1 from georgik/feature/dma
Feature/dma
2 parents 8fb3c33 + dd30d5a commit ba48d13

File tree

2 files changed

+68
-16
lines changed

2 files changed

+68
-16
lines changed

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "esp32-conways-game-of-life-rs"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
authors = ["Juraj Michálek <juraj.michalek@espressif.com>"]
55
edition = "2021"
66
license = "MIT OR Apache-2.0"
@@ -12,7 +12,9 @@ esp-println = { version = "0.7.0", features = ["esp32s3","log"] }
1212
log = { version = "0.4.18" }
1313
mipidsi = "0.7.1"
1414
embedded-graphics = "0.8.1"
15+
embedded-graphics-framebuf = { version = "0.3.0", git = "https://github.com/georgik/embedded-graphics-framebuf.git", branch = "feature/embedded-graphics-0.8" }
1516
display-interface = "0.4.1"
1617
display-interface-spi = "0.4.1"
17-
heapless = "0.7.16"
18-
18+
heapless = "0.8.0"
19+
embedded-dma = "0.2.0"
20+
spi-dma-displayinterface = { git = "https://github.com/georgik/esp32-spooky-maze-game.git", package = "spi-dma-displayinterface", features = [ "esp32s3" ] }

src/main.rs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
#![no_std]
22
#![no_main]
33

4+
use spi_dma_displayinterface::spi_dma_displayinterface::SPIInterfaceNoCS;
5+
46
use esp_backtrace as _;
57
use esp_println::println;
68
use hal::{
7-
clock::ClockControl,
9+
clock::{ClockControl, CpuClock},
10+
dma::DmaPriority,
11+
gdma::Gdma,
812
peripherals::Peripherals,
913
prelude::*,
10-
spi::{master::Spi, SpiMode},
14+
spi::{
15+
master::{prelude::*, Spi},
16+
SpiMode,
17+
},
1118
Delay, Rng, IO,
1219
};
1320

14-
use display_interface_spi::SPIInterfaceNoCS;
1521
use embedded_graphics::{
1622
mono_font::{ascii::FONT_8X13, MonoTextStyle},
1723
pixelcolor::Rgb565,
@@ -22,6 +28,8 @@ use embedded_graphics::{
2228
Drawable,
2329
};
2430

31+
use embedded_graphics_framebuf::FrameBuf;
32+
2533
// Define grid size
2634
const WIDTH: usize = 64;
2735
const HEIGHT: usize = 48;
@@ -116,12 +124,32 @@ fn draw_grid<D: DrawTarget<Color = Rgb565>>(
116124
display: &mut D,
117125
grid: &[[bool; WIDTH]; HEIGHT],
118126
) -> Result<(), D::Error> {
127+
// Define the border color
128+
let border_color = Rgb565::new(230, 230, 230); // Gray color
129+
119130
for (y, row) in grid.iter().enumerate() {
120131
for (x, &cell) in row.iter().enumerate() {
121-
let color = if cell { Rgb565::WHITE } else { Rgb565::BLACK };
122-
Rectangle::new(Point::new(x as i32 * 5, y as i32 * 5), Size::new(5, 5))
123-
.into_styled(PrimitiveStyle::with_fill(color))
124-
.draw(display)?;
132+
if cell {
133+
// Live cell with border
134+
// Define the size of the cells and borders
135+
let cell_size = Size::new(5, 5);
136+
let border_size = Size::new(7, 7); // Slightly larger for the border
137+
138+
// Draw the border rectangle
139+
Rectangle::new(Point::new(x as i32 * 7, y as i32 * 7), border_size)
140+
.into_styled(PrimitiveStyle::with_fill(border_color))
141+
.draw(display)?;
142+
143+
// Draw the inner cell rectangle (white)
144+
Rectangle::new(Point::new(x as i32 * 7 + 1, y as i32 * 7 + 1), cell_size)
145+
.into_styled(PrimitiveStyle::with_fill(Rgb565::WHITE))
146+
.draw(display)?;
147+
} else {
148+
// Dead cell without border (black)
149+
Rectangle::new(Point::new(x as i32 * 7, y as i32 * 7), Size::new(7, 7))
150+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
151+
.draw(display)?;
152+
}
125153
}
126154
}
127155
Ok(())
@@ -132,29 +160,45 @@ fn main() -> ! {
132160
let peripherals = Peripherals::take();
133161
let system = peripherals.SYSTEM.split();
134162

135-
let clocks = ClockControl::max(system.clock_control).freeze();
163+
// let clocks = ClockControl::max(system.clock_control).freeze();
164+
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
136165
let mut delay = Delay::new(&clocks);
137166

138167
println!("About to initialize the SPI LED driver");
139168
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
140169

141170
let sclk = io.pins.gpio7;
142171
let mosi = io.pins.gpio6;
172+
let cs = io.pins.gpio5;
173+
let miso = io.pins.gpio2;
143174
// let sda = io.pins.gpio8;
144175
// let scl = io.pins.gpio18;
145176
let dc = io.pins.gpio4.into_push_pull_output();
146177
let mut backlight = io.pins.gpio45.into_push_pull_output();
147178
let reset = io.pins.gpio48.into_push_pull_output();
148179

149-
println!("SPI LED driver initialized");
150-
let spi = Spi::new_no_cs_no_miso(
180+
let dma = Gdma::new(peripherals.DMA);
181+
let dma_channel = dma.channel0;
182+
183+
let mut descriptors = [0u32; 8 * 3];
184+
let mut rx_descriptors = [0u32; 8 * 3];
185+
186+
let spi = Spi::new(
151187
peripherals.SPI2,
152188
sclk,
153189
mosi,
190+
miso,
191+
cs,
154192
60u32.MHz(),
155193
SpiMode::Mode0,
156194
&clocks,
157-
);
195+
)
196+
.with_dma(dma_channel.configure(
197+
false,
198+
&mut descriptors,
199+
&mut rx_descriptors,
200+
DmaPriority::Priority0,
201+
));
158202

159203
println!("SPI ready");
160204

@@ -197,12 +241,15 @@ fn main() -> ! {
197241
}
198242
let mut generation_count = 0;
199243

244+
let mut data = [Rgb565::BLACK; 320 * 240];
245+
let mut fbuf = FrameBuf::new(&mut data, 320, 240);
246+
200247
loop {
201248
// Update the game state
202249
update_game_of_life(&mut grid);
203250

204251
// Draw the updated grid on the display
205-
draw_grid(&mut display, &grid).unwrap();
252+
draw_grid(&mut fbuf, &grid).unwrap();
206253

207254
generation_count += 1;
208255

@@ -211,7 +258,10 @@ fn main() -> ! {
211258
generation_count = 0; // Reset the generation counter
212259
}
213260

214-
write_generation(&mut display, generation_count).unwrap();
261+
write_generation(&mut fbuf, generation_count).unwrap();
262+
263+
let pixel_iterator = fbuf.into_iter().map(|p| p.1);
264+
let _ = display.set_pixels(0, 0, 319, 240, pixel_iterator);
215265

216266
// Add a delay to control the simulation speed
217267
delay.delay_ms(100u32);

0 commit comments

Comments
 (0)