Skip to content
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

Add fast rectangle fill impl and RTIC DVD example #28

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 6 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
target_steps: &target_steps
docker:
- image: circleci/rust:1.42.0
- image: cimg/rust:1.50.0
steps:
- checkout
- restore_cache:
key: v1-sh1106-{{ .Environment.CIRCLE_JOB }}-{{ checksum "Cargo.toml" }}
- run: sudo apt install -qq linkchecker
- run: rustup install 1.57.0 --profile minimal
- run: cargo +1.57.0 install cargo-deadlinks --target x86_64-unknown-linux-gnu
- run: rustup default ${RUST_VERSION:-stable}
# For docs gen
- run: rustup target add thumbv7m-none-eabi
- run: rustup target add thumbv7em-none-eabihf
- run: rustup component add rustfmt
- run: |
SYSROOT=$(rustc --print sysroot)
Expand Down
45 changes: 31 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
# Changelog

[`sh1106`](https://crates.io/crates/sh1106) is a Rust driver for the SH1106 OLED display. It supports
[embedded-graphics](https://crates.io/crates/embedded-graphics) or raw pixel drawing modes and works
with the [embedded-hal](crates.io/crates/embedded-hal) traits for maximum portability.
[`sh1106`](https://crates.io/crates/sh1106) is a Rust driver for the SH1106 OLED display. It
supports [embedded-graphics](https://crates.io/crates/embedded-graphics) or raw pixel drawing modes
and works with the [embedded-hal](crates.io/crates/embedded-hal) traits for maximum portability.

<!-- next-header -->

## [Unreleased] - ReleaseDate

### Changed

- **(breaking)** [#28](https://github.com/jamwaffles/sh1106/pull/28) Upgrade MSRV to 1.50.0, add a
faster implementation of `DrawTarget::fill_solid`.

## [0.4.0] - 2021-07-11

### Changed

- **(breaking)** [#25](https://github.com/jamwaffles/sh1106/pull/25) Upgrade to `embedded-graphics` 0.7.
- **(breaking)** [#25](https://github.com/jamwaffles/sh1106/pull/25) Upgrade to `embedded-graphics`
0.7.

## [0.3.4] - 2020-12-28

### Fixed

- [#23](https://github.com/jamwaffles/sh1106/pull/23) Fixed command bytes for `PreChargePeriod` and `VcomhDeselect`.
- [#23](https://github.com/jamwaffles/sh1106/pull/23) Fixed command bytes for `PreChargePeriod` and
`VcomhDeselect`.

## [0.3.3] - 2020-06-09

### Added

- [#22](https://github.com/jamwaffles/sh1106/pull/22) Add `DisplaySize::Display128x64NoOffset` variant for 128x64 displays that don't use a 132x64 buffer internally.
- [#22](https://github.com/jamwaffles/sh1106/pull/22) Add `DisplaySize::Display128x64NoOffset`
variant for 128x64 displays that don't use a 132x64 buffer internally.

## [0.3.2] - 2020-04-30

### Added

- [#20](https://github.com/jamwaffles/sh1106/pull/20) Add `set_contrast` method to set the display contrast/brightness.
- [#20](https://github.com/jamwaffles/sh1106/pull/20) Add `set_contrast` method to set the display
contrast/brightness.

## [0.3.1] - 2020-03-21

Expand All @@ -46,7 +55,8 @@ with the [embedded-hal](crates.io/crates/embedded-hal) traits for maximum portab

### Changed

- **(breaking)** [#18](https://github.com/jamwaffles/sh1106/pull/18) Upgrade to embedded-graphics 0.6.0
- **(breaking)** [#18](https://github.com/jamwaffles/sh1106/pull/18) Upgrade to embedded-graphics
0.6.0

## [0.3.0-alpha.4]

Expand All @@ -58,7 +68,8 @@ with the [embedded-hal](crates.io/crates/embedded-hal) traits for maximum portab

### Added

- Added the `NoOutputPin` dummy pin type for SPI cases when no Chip Select pin is required. Use it like this:
- Added the `NoOutputPin` dummy pin type for SPI cases when no Chip Select pin is required. Use it
like this:

```rust
let spi = Spi::spi1(
Expand All @@ -72,23 +83,29 @@ let mut disp: GraphicsMode<_> = sh1106::Builder::new()

## 0.3.0-alpha.2

Upgrade to new embedded-graphics `0.6.0-alpha.2` release. Please see the [embedded-graphics changelog](https://github.com/jamwaffles/embedded-graphics/blob/c0ed1700635f307a4c5114fec1769147878fd584/CHANGELOG.md) for more information.
Upgrade to new embedded-graphics `0.6.0-alpha.2` release. Please see the
[embedded-graphics changelog](https://github.com/jamwaffles/embedded-graphics/blob/c0ed1700635f307a4c5114fec1769147878fd584/CHANGELOG.md)
for more information.

### Changed

- **(breaking)** #11 Upgraded to [embedded-graphics](https://crates.io/crates/embedded-graphics) 0.6.0-alpha.2
- **(breaking)** #11 Upgraded to [embedded-graphics](https://crates.io/crates/embedded-graphics)
0.6.0-alpha.2

## 0.3.0-alpha.1

Upgrade to new embedded-graphics `0.6.0-alpha.1` release. Please see the [embedded-graphics changelog](https://github.com/jamwaffles/embedded-graphics/blob/embedded-graphics-v0.6.0-alpha.1/CHANGELOG.md) for more information.
Upgrade to new embedded-graphics `0.6.0-alpha.1` release. Please see the
[embedded-graphics changelog](https://github.com/jamwaffles/embedded-graphics/blob/embedded-graphics-v0.6.0-alpha.1/CHANGELOG.md)
for more information.

### Changed

- **(breaking)** #9 Upgraded to [embedded-graphics](https://crates.io/crates/embedded-graphics) 0.6.0-alpha.1
- **(breaking)** #9 Upgraded to [embedded-graphics](https://crates.io/crates/embedded-graphics)
0.6.0-alpha.1

<!-- next-url -->
[unreleased]: https://github.com/jamwaffles/sh1106/compare/v0.4.0...HEAD

[unreleased]: https://github.com/jamwaffles/sh1106/compare/v0.4.0...HEAD
[0.4.0]: https://github.com/jamwaffles/sh1106/compare/v0.3.4...v0.4.0
[0.3.4]: https://github.com/jamwaffles/sh1106/compare/v0.3.3...v0.3.4
[0.3.3]: https://github.com/jamwaffles/sh1106/compare/v0.3.2...v0.3.3
Expand Down
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ circle-ci = { repository = "jamwaffles/sh1106", branch = "master" }
[dependencies]
embedded-hal = "0.2.3"
embedded-graphics-core = { version = "0.3.2", optional = true }
# packed-display-buffer = { git = "https://github.com/embedded-graphics/packed-display-buffer.git", rev = "3741342d43c78fc8984db6ea316e7b13270ec4b7" }
packed-display-buffer = { path = "../embedded-graphics/packed-display-buffer" }

[dev-dependencies]
cortex-m = "0.7.3"
Expand All @@ -44,5 +46,5 @@ incremental = false

[profile.release]
codegen-units = 1
debug = true
debug = 2
lto = true
5 changes: 2 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#!/bin/sh

set -e
set -ex

cargo build --target $TARGET --all-features --release

if [ -z $DISABLE_EXAMPLES ]; then
cargo build --target $TARGET --all-features --examples
fi

cargo test --lib --target x86_64-unknown-linux-gnu
cargo test --doc --target x86_64-unknown-linux-gnu
cargo deadlinks --ignore-fragments
192 changes: 192 additions & 0 deletions examples/bench-fill.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
//! Meant for development use only. Prints the time taken to draw a bunch of rectangles to the
//! display. Originally created to benchmark the `fill_solid` method.

#![no_std]
#![no_main]

use core::fmt::Write;
use embedded_graphics::{
geometry::Point,
mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
pixelcolor::BinaryColor,
prelude::*,
primitives::{PrimitiveStyle, Rectangle},
text::{Baseline, Text},
};
use heapless::String;
use panic_semihosting as _;
use rtic::app;
use sh1106::{prelude::*, Builder};
use stm32f1xx_hal::{
gpio,
i2c::{BlockingI2c, DutyCycle, Mode},
pac::{self, I2C1},
prelude::*,
timer::{CountDownTimer, Event, Timer},
};

type Display = GraphicsMode<
I2cInterface<
BlockingI2c<
I2C1,
(
gpio::gpiob::PB8<gpio::Alternate<gpio::OpenDrain>>,
gpio::gpiob::PB9<gpio::Alternate<gpio::OpenDrain>>,
),
>,
>,
>;

#[inline(always)]
fn stopwatch<F>(f: F) -> u32
where
F: FnOnce() -> (),
{
let start: u32 = pac::DWT::cycle_count();
f();
let end: u32 = pac::DWT::cycle_count();
end.wrapping_sub(start)
}

#[app(device = stm32f1xx_hal::pac, peripherals = true)]
const APP: () = {
struct Resources {
display: Display,
timer: CountDownTimer<pac::TIM1>,
#[init(0)]
frame: u32,
}

#[init]
fn init(cx: init::Context) -> init::LateResources {
let dp = cx.device;
let mut cp = cx.core;

cp.DCB.enable_trace();
cp.DWT.enable_cycle_counter();

let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();

let clocks = rcc
.cfgr
.use_hse(8.mhz())
.sysclk(72.mhz())
.pclk1(36.mhz())
.freeze(&mut flash.acr);

let mut afio = dp.AFIO.constrain(&mut rcc.apb2);

let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);

let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh);
let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh);

let i2c = BlockingI2c::i2c1(
dp.I2C1,
(scl, sda),
&mut afio.mapr,
Mode::Fast {
frequency: 400_000.hz(),
duty_cycle: DutyCycle::Ratio2to1,
},
clocks,
&mut rcc.apb1,
1000,
10,
1000,
1000,
);

let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c).into();

display.init().unwrap();
display.flush().unwrap();

// Update framerate
let fps = 1;

let mut timer = Timer::tim1(dp.TIM1, &clocks, &mut rcc.apb2).start_count_down(fps.hz());

timer.listen(Event::Update);

// Init the static resources to use them later through RTIC
init::LateResources { timer, display }
}

#[idle()]
fn idle(_: idle::Context) -> ! {
loop {
// Fix default wfi() behaviour breaking debug probe
core::hint::spin_loop();
}
}

#[task(binds = TIM1_UP, resources = [display, timer, frame])]
fn update(cx: update::Context) {
let update::Resources {
display,
timer,
frame,
..
} = cx.resources;

display.clear();
display.flush().unwrap();

let center = display.bounding_box().center();

// Only bench time taken to draw rectangles
let time = stopwatch(|| {
for x in 0i32..64 {
// Square squares in center
Rectangle::with_center(center, Size::new(x as u32, x as u32))
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(display)
.unwrap();
}

for x in 0i32..64 {
// Tall rectangles
Rectangle::with_center(Point::new(x * 5, 20), Size::new(4, x as u32))
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(display)
.unwrap();

// Wide rectangles
Rectangle::with_center(Point::new(0, x * 2), Size::new(x as u32, 4))
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(display)
.unwrap();
}
});

// Convert time to ms by dividing by sysclk * 1000
let time = time / 72_000;

let mut s: String<32> = String::new();

write!(s, "{}ms", time).ok();

let text_style = MonoTextStyleBuilder::new()
.font(&FONT_6X10)
.text_color(BinaryColor::On)
.background_color(BinaryColor::Off)
.build();

Text::with_baseline(&s, Point::zero(), text_style, Baseline::Top)
.draw(display)
.unwrap();

display.flush().unwrap();

*frame += 1;

// Clears the update flag
timer.clear_update_interrupt_flag();
}

extern "C" {
fn EXTI0();
}
};
6 changes: 4 additions & 2 deletions examples/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use embedded_graphics::{
primitives::{Circle, Line, PrimitiveStyle, Rectangle},
};
use panic_semihosting as _;
use sh1106::{prelude::*, Builder};
use sh1106::{mode::graphics::Clear, prelude::*, Builder};
use stm32f1xx_hal::{
i2c::{BlockingI2c, DutyCycle, Mode},
prelude::*,
Expand Down Expand Up @@ -66,7 +66,9 @@ fn main() -> ! {
let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c).into();

display.init().unwrap();
display.flush().unwrap();
display.clear(Clear::BufferAndDisplay).unwrap();

display.set_rotation(DisplayRotation::Rotate90).unwrap();

Line::new(Point::new(8, 16 + 16), Point::new(8 + 16, 16 + 16))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
Expand Down
4 changes: 2 additions & 2 deletions examples/rotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use embedded_graphics::{
prelude::*,
};
use panic_semihosting as _;
use sh1106::{prelude::*, Builder};
use sh1106::{mode::graphics::Clear, prelude::*, Builder};
use stm32f1xx_hal::{
i2c::{BlockingI2c, DutyCycle, Mode},
prelude::*,
Expand Down Expand Up @@ -76,7 +76,7 @@ fn main() -> ! {
.into();

display.init().unwrap();
display.flush().unwrap();
display.clear(Clear::BufferAndDisplay).unwrap();

// Contrived example to test builder and instance methods. Sets rotation to 270 degress
// or 90 degress counterclockwise
Expand Down
Loading