From 3594c103608aebd31f52d06ac2678dd3c4fef185 Mon Sep 17 00:00:00 2001 From: Matthew Woodcraft Date: Thu, 1 Feb 2024 20:59:34 +0000 Subject: [PATCH] Double the non-blocking display refresh frequency for the micro:bit V2 --- CHANGELOG.md | 1 + microbit-common/src/display/nonblocking/mod.rs | 18 +++++++++++------- .../src/display/nonblocking/timer.rs | 14 ++++++++++++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09e027a..2b2cffa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Double the non-blocking display refresh frequency for the micro:bit V2 - Fix faulty doc test in `blocking.rs` - Update the non-blocking display documentation to better explain when methods should be called from within a critical section diff --git a/microbit-common/src/display/nonblocking/mod.rs b/microbit-common/src/display/nonblocking/mod.rs index ea96a0f..bdcd275 100644 --- a/microbit-common/src/display/nonblocking/mod.rs +++ b/microbit-common/src/display/nonblocking/mod.rs @@ -117,17 +117,21 @@ //! The [`Display`] expects to control a single timer. It can use the //! micro:bit's `TIMER0`, `TIMER1`, or `TIMER2`. //! -//! This uses a 6ms period to light each of the three internal LED rows, so -//! that the entire display is updated every 18ms. +//! For the micro:bit v1 this uses a 6ms period to light each of the three +//! internal LED rows, so that the entire display is updated every 18ms. +//! +//! For the micro:bit v2 this uses a 3ms period to light each of the five +//! internal LED rows, so that the entire display is updated every 15ms. //! //! When rendering greyscale images, the `Display` requests extra interrupts -//! within each 6ms period. It only requests interrupts for the greyscale -//! levels which are actually required for what's currently being displayed. +//! within each 6ms or 3ms period. It only requests interrupts for the +//! greyscale levels which are actually required for what's currently being +//! displayed. //! //! ### Technical details //! -//! The timer is set to 16-bit mode, using a 62.5kHz clock (16 µs ticks). It -//! resets every 375 ticks. +//! The timer is set to 16-bit mode, using a 62.5kHz or 135Khz clock (16 µs or +//! 8µs ticks). It resets every 375 ticks. //! //! ## Usage //! @@ -137,7 +141,7 @@ //! - create a [`Display`] struct passing the timer and //! [`gpio::DisplayPins`](crate::gpio::DisplayPins) to [`Display::new()`]. //! -//! In an interrupt handler forthe timer call [`.handle_display_event()`](Display::handle_display_event) +//! In an interrupt handler for the timer call [`.handle_display_event()`](Display::handle_display_event) //! //! To change what's displayed; pass an image ([`GreyscaleImage`] or [`BitImage`]) to [`Display::show`]. //! diff --git a/microbit-common/src/display/nonblocking/timer.rs b/microbit-common/src/display/nonblocking/timer.rs index 3589cf6..0673ce5 100644 --- a/microbit-common/src/display/nonblocking/timer.rs +++ b/microbit-common/src/display/nonblocking/timer.rs @@ -10,9 +10,14 @@ use crate::hal::timer::Instance; /// /// `MicrobitDisplayTimer` instances implement the [`DisplayTimer`] trait. /// -/// The timer is set to 16-bit mode, using a 62.5kHz clock (16 µs ticks). +/// The timer is set to 16-bit mode. +/// +/// For micro:bit v1: uses a 62.5kHz clock clock (16 µs ticks). /// The primary cycle takes 6ms. /// +/// For micro:bit v2: uses a 135kHz clock (8 µs ticks). +/// The primary cycle takes 3ms. +/// /// Uses CC0 for the primary cycle and CC1 for the secondary alarm. Uses the /// CC0_CLEAR shortcut to implement the primary cycle. /// @@ -43,8 +48,13 @@ impl DisplayTimer for MicrobitDisplayTimer { // set as 16 bits timer0.bitmode.write(|w| w.bitmode()._16bit()); + #[cfg(feature = "v1")] // set frequency to 62500Hz - timer0.prescaler.write(|w| unsafe { w.bits(8) }); + let prescaler = 8; + #[cfg(feature = "v2")] + // set frequency to 135000Hz + let prescaler = 7; + timer0.prescaler.write(|w| unsafe { w.bits(prescaler) }); // set compare register timer0.cc[0].write(|w| unsafe { w.bits(ticks.into()) });