Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ jobs:
echo 'rustflags = ["-D", "warnings"]' >> .cargo/config.toml
make -j2 setup
make -j2 test
make demos
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/nightly/target
/target
/demos/*/target
/demos/*/*/target
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ members = [
"apis/storage/key_value",
"demos/st7789",
"demos/st7789-slint",
"libraries/embedded_graphics_libtock",
"panic_handlers/debug_panic",
"panic_handlers/small_panic",
"platform",
Expand Down
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ examples: toolchain
# Used when we need to build a crate for the host OS, as libtock_runtime only
# supports running on Tock.
EXCLUDE_RUNTIME := --exclude libtock --exclude libtock_runtime \
--exclude libtock_debug_panic --exclude libtock_small_panic
--exclude libtock_debug_panic --exclude libtock_small_panic --exclude embedded_graphics_libtock

# Arguments to pass to cargo to exclude demo crates.
EXCLUDE_RUNTIME := $(EXCLUDE_RUNTIME) --exclude st7789 --exclude st7789-slint
Expand Down Expand Up @@ -242,6 +242,11 @@ $(eval $(call platform_build,msp432,thumbv7em-none-eabi))
$(eval $(call platform_build,clue_nrf52840,thumbv7em-none-eabi))
$(eval $(call platform_flash,clue_nrf52840,thumbv7em-none-eabi))

.PHONY: demos
demos:
$(MAKE) -C demos/embedded_graphics/spin
$(MAKE) -C demos/embedded_graphics/buttons

# clean cannot safely be invoked concurrently with other actions, so we don't
# need to depend on toolchain. We also manually remove the nightly toolchain's
# target directory, in case the user doesn't want to install the nightly
Expand Down
22 changes: 22 additions & 0 deletions demos/embedded_graphics/buttons/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "buttons"
version = "0.1.0"
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
license = "Apache-2.0 OR MIT"
edition = "2021"
repository = "https://www.github.com/tock/libtock-rs"
rust-version = "1.87"
description = "libtock-rs button app with embedded graphics"

[dependencies]
embedded-graphics = "0.8.1"
libm = "0.2.15"

libtock = { path = "../../../", version = "0.1.0" }
libtock_platform = { path = "../../../platform" }
embedded_graphics_libtock = { path = "../../../libraries/embedded_graphics_libtock", version = "0.1.0" }

[build-dependencies]
libtock_build_scripts = { path = "../../../build_scripts" }

[workspace]
20 changes: 20 additions & 0 deletions demos/embedded_graphics/buttons/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Makefile for the demo app.

# Crate name of the demo app
DEMO := buttons

all: tab

include ../../../Targets.mk

$(ELF_TARGETS):
LIBTOCK_LINKER_FLASH=$(F) LIBTOCK_LINKER_RAM=$(R) cargo build --target=$(T) --release
@mkdir -p target/$(A).$(F).$(R)/
@cp target/$(T)/release/$(DEMO) target/$(A).$(F).$(R)/
$(eval ELF_LIST += target/$(A).$(F).$(R)/$(DEMO),$(A).$(F).$(R))

# This target (`make tab`) is not parallel-safe
.PHONY: tab
tab: $(ELF_TARGETS)
@mkdir -p target/tab
elf2tab --kernel-major 2 --kernel-minor 1 -n $(DEMO) -o target/tab/$(DEMO).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST)
5 changes: 5 additions & 0 deletions demos/embedded_graphics/buttons/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Buttons Demo Using Embedded Graphics
====================================

Draws buttons as circles on the screen. When a button is pressed the
corresponding circle is filled in.
3 changes: 3 additions & 0 deletions demos/embedded_graphics/buttons/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
libtock_build_scripts::auto_layout();
}
120 changes: 120 additions & 0 deletions demos/embedded_graphics/buttons/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#![no_main]
#![no_std]
use core::cell::Cell;
use core::fmt::Write;
use libtock::buttons::{ButtonListener, ButtonState, Buttons};
use libtock::console::Console;
use libtock::runtime::{set_main, stack_size, TockSyscalls};
use libtock_platform::share;
use libtock_platform::ErrorCode;
use libtock_platform::Syscalls;

use embedded_graphics_libtock::tock_screen::TockMonochromeScreen;

use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::Point;
use embedded_graphics::prelude::Primitive;
use embedded_graphics::primitives::{Circle, PrimitiveStyle};
use embedded_graphics::Drawable;

set_main! {main}
stack_size! {4000}

fn run() -> Result<(), ErrorCode> {
let mut screen = TockMonochromeScreen::new();

let width = screen.get_width();
let height = screen.get_height();

let button_count = Buttons::count()?;
writeln!(Console::writer(), "[BUTTONS] Count: {}", button_count).unwrap();

// Calculate where the buttons should be drawn.
let button_padding_px = (button_count - 1) * 2;
let max_x = (width - button_padding_px) / button_count;
let max_y = height - 2;
let diameter = core::cmp::min(max_x, max_y);
let buttons_width = (diameter * button_count) + button_padding_px;
let padding_left_px = (width - buttons_width) / 2;
let y = (height / 2) - (diameter / 2);

// Draw the initial button outlines.
for i in 0..button_count {
let x = padding_left_px + ((diameter + 2) * i);

let _ = Circle::new(Point::new(x as i32, y as i32), diameter)
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut screen);
}
let _ = screen.flush();

// Now wait for button presses. Record what happened in the upcall.
let buttons: [Cell<ButtonState>; 10] = [const { Cell::new(ButtonState::Released) }; 10];
let changed: Cell<bool> = Cell::new(false);

let listener = ButtonListener(|button, state| {
// If the button state changed, record it.
if buttons[button as usize].get() != state {
buttons[button as usize].set(state);
changed.set(true);
}
});
share::scope(|subscribe| {
// Subscribe to the button callback.
Buttons::register_listener(&listener, subscribe).unwrap();

// Enable interrupts for each button press.
for i in 0..button_count {
Buttons::enable_interrupts(i).unwrap();
}

// Wait for buttons to be pressed.
loop {
TockSyscalls::yield_wait();

// If a button state changed, re-draw the buttons.
if changed.get() {
changed.set(false);

let mut screen = TockMonochromeScreen::new();

// Draw Circles
for i in 0..button_count {
let x = padding_left_px + ((diameter + 2) * i);

// Draw outer circle
let _ = Circle::new(Point::new(x as i32, y as i32), diameter)
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut screen);

match buttons[i as usize].get() {
ButtonState::Pressed => {
let _ =
Circle::new(Point::new(x as i32 + 1, y as i32 + 1), diameter - 2)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(&mut screen);
}
ButtonState::Released => {
let _ =
Circle::new(Point::new(x as i32 + 1, y as i32 + 1), diameter - 2)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::Off))
.draw(&mut screen);
}
}
}
let _ = screen.flush();
}
}
});

Ok(())
}

fn main() {
match run() {
Ok(()) => {}
Err(_e) => {
writeln!(Console::writer(), "[BUTTONS] Err could not run app").unwrap();
}
}
}
21 changes: 21 additions & 0 deletions demos/embedded_graphics/spin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "spin"
version = "0.1.0"
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
license = "Apache-2.0 OR MIT"
edition = "2021"
repository = "https://www.github.com/tock/libtock-rs"
rust-version = "1.87"
description = "libtock-rs spin app with embedded graphics"

[dependencies]
embedded-graphics = "0.8.1"
libm = "0.2.15"

libtock = { path = "../../../", version = "0.1.0" }
embedded_graphics_libtock = { path = "../../../libraries/embedded_graphics_libtock", version = "0.1.0" }

[build-dependencies]
libtock_build_scripts = { path = "../../../build_scripts" }

[workspace]
20 changes: 20 additions & 0 deletions demos/embedded_graphics/spin/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Makefile for the demo app.

# Crate name of the demo app
DEMO := spin

all: tab

include ../../../Targets.mk

$(ELF_TARGETS):
LIBTOCK_LINKER_FLASH=$(F) LIBTOCK_LINKER_RAM=$(R) cargo build --target=$(T) --release
@mkdir -p target/$(A).$(F).$(R)/
@cp target/$(T)/release/$(DEMO) target/$(A).$(F).$(R)/
$(eval ELF_LIST += target/$(A).$(F).$(R)/$(DEMO),$(A).$(F).$(R))

# This target (`make tab`) is not parallel-safe
.PHONY: tab
tab: $(ELF_TARGETS)
@mkdir -p target/tab
elf2tab --kernel-major 2 --kernel-minor 1 -n $(DEMO) -o target/tab/$(DEMO).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST)
5 changes: 5 additions & 0 deletions demos/embedded_graphics/spin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Spin Demo Using Embedded Graphics
=================================

This demo spins a line on a screen. It was tested using the SSD1306 screen on
the nRF52840dk.
3 changes: 3 additions & 0 deletions demos/embedded_graphics/spin/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
libtock_build_scripts::auto_layout();
}
53 changes: 53 additions & 0 deletions demos/embedded_graphics/spin/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#![no_main]
#![no_std]
use libtock::alarm::Alarm;
use libtock::alarm::Milliseconds;
use libtock::runtime::{set_main, stack_size};

use embedded_graphics_libtock::tock_screen::TockMonochromeScreen;

use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::Point;
use embedded_graphics::prelude::Primitive;
use embedded_graphics::primitives::{Line, PrimitiveStyle};
use embedded_graphics::Drawable;

set_main! {main}
stack_size! {4000}

fn main() {
let mut screen = TockMonochromeScreen::new();

let width = screen.get_width() as i32;
let height = screen.get_height() as i32;

let center_x = width / 2;
let center_y = height / 2;
let radius = if width < height {
center_x - 1
} else {
center_y - 1
};

let mut rot: usize = 0;

loop {
let _ = screen.clear(BinaryColor::Off);

let angle = (rot as f32 / 100.0) * (2.0 * core::f32::consts::PI);

let x = (center_x as f32 + (radius as f32 * libm::cosf(angle))) as i32;
let y = (center_y as f32 + (radius as f32 * libm::sinf(angle))) as i32;

let _ = Line::new(Point::new(center_x, center_y), Point::new(x, y))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut screen);

let _ = screen.flush();

Alarm::sleep_for(Milliseconds(200)).unwrap();

rot = (rot + 1) % 100;
}
}
15 changes: 15 additions & 0 deletions libraries/embedded_graphics_libtock/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "embedded_graphics_libtock"
version = "0.1.0"
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
license = "Apache-2.0 OR MIT"
edition = "2018"
repository = "https://www.github.com/tock/libtock-rs"
rust-version.workspace = true
description = "libtock-rs port of embedded graphics"

[dependencies]
embedded-graphics = "0.8.1"

libtock = { path = "../../" }
libtock_platform = { path = "../../platform" }
8 changes: 8 additions & 0 deletions libraries/embedded_graphics_libtock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Embedded Graphics - Libtock
===========================

This crate connects the
[Embedded Graphics library](https://crates.io/crates/embedded-graphics) to
libtock-rs. Specifically, this implements the
[DrawTarget trait](https://docs.rs/embedded-graphics/latest/embedded_graphics/draw_target/trait.DrawTarget.html)
using the Tock `screen` systemcall.
3 changes: 3 additions & 0 deletions libraries/embedded_graphics_libtock/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#![no_std]
Comment thread
alevy marked this conversation as resolved.

pub mod tock_screen;
Loading