Skip to content

Commit 2ac7c9f

Browse files
committed
Allow noncontiguous pins in display
In the micro:bit v2 the LED matrix pins are not placed next to each other. This change updates `display::control` so that it is configured with arrays of pin IDs rather than start and end IDs.
1 parent d97d7db commit 2ac7c9f

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

src/display/control.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,23 @@
77
use crate::pac;
88
use tiny_led_matrix::DisplayControl;
99

10-
const fn bit_range(lo: usize, count: usize) -> u32 {
11-
((1 << count) - 1) << lo
10+
const fn pin_bits(pins: &[usize]) -> u32 {
11+
let mut i: usize = 0;
12+
let mut bits: u32 = 0;
13+
while i < pins.len() {
14+
bits |= 1 << pins[i];
15+
i += 1;
16+
}
17+
bits
1218
}
1319

1420
pub(crate) const MATRIX_COLS: usize = 9;
15-
const FIRST_COL_PIN: usize = 4;
16-
const LAST_COL_PIN: usize = FIRST_COL_PIN + MATRIX_COLS - 1;
17-
const COL_BITS: u32 = bit_range(FIRST_COL_PIN, MATRIX_COLS);
21+
const COLS: [usize; MATRIX_COLS] = [4, 5, 6, 7, 8, 9, 10, 11, 12];
22+
const COL_BITS: u32 = pin_bits(&COLS);
1823

1924
pub(crate) const MATRIX_ROWS: usize = 3;
20-
const FIRST_ROW_PIN: usize = 13;
21-
const LAST_ROW_PIN: usize = FIRST_ROW_PIN + MATRIX_ROWS - 1;
22-
const ROW_BITS: u32 = bit_range(FIRST_ROW_PIN, MATRIX_ROWS);
25+
const ROWS: [usize; MATRIX_ROWS] = [13, 14, 15];
26+
const ROW_BITS: u32 = pin_bits(&ROWS);
2327

2428
/// Wrapper for `nrf51::GPIO` for passing to the display code.
2529
///
@@ -28,9 +32,14 @@ const ROW_BITS: u32 = bit_range(FIRST_ROW_PIN, MATRIX_ROWS);
2832
/// [`DisplayControl`]: tiny_led_matrix::DisplayControl
2933
pub(crate) struct MicrobitGpio<'a>(pub &'a pac::GPIO);
3034

31-
/// Returns the GPIO pin numbers corresponding to the columns in a ColumnSet.
32-
fn column_pins(cols: u32) -> u32 {
33-
cols << FIRST_COL_PIN
35+
/// Returns the GPIO pin numbers corresponding to the columns in a Columnt et.
36+
fn column_pins(mut cols: u32) -> u32 {
37+
let mut result = 0u32;
38+
for pin in COLS.iter() {
39+
result |= (cols & 1) << pin;
40+
cols >>= 1;
41+
}
42+
result
3443
}
3544

3645
/// Implementation of [`DisplayControl`] for the micro:bit's GPIO peripheral.
@@ -44,23 +53,24 @@ fn column_pins(cols: u32) -> u32 {
4453
impl DisplayControl for MicrobitGpio<'_> {
4554
fn initialise_for_display(&mut self) {
4655
let gpio = &self.0;
47-
for ii in FIRST_COL_PIN..=LAST_COL_PIN {
48-
gpio.pin_cnf[ii].write(|w| w.dir().output());
56+
for ii in COLS.iter() {
57+
gpio.pin_cnf[*ii].write(|w| w.dir().output());
4958
}
50-
for ii in FIRST_ROW_PIN..=LAST_ROW_PIN {
51-
gpio.pin_cnf[ii].write(|w| w.dir().output());
59+
for ii in ROWS.iter() {
60+
gpio.pin_cnf[*ii].write(|w| w.dir().output());
5261
}
5362

5463
// Set all cols high.
5564
gpio.outset
56-
.write(|w| unsafe { w.bits((FIRST_COL_PIN..=LAST_COL_PIN).map(|pin| 1 << pin).sum()) });
65+
.write(|w| unsafe { w.bits(COLS.iter().map(|pin| 1 << pin).sum()) });
5766
}
5867

5968
fn display_row_leds(&mut self, row: usize, cols: u32) {
6069
let gpio = &self.0;
6170
// To light an LED, we set the row bit and clear the col bit.
62-
let rows_to_set = 1 << (FIRST_ROW_PIN + row);
71+
let rows_to_set = 1 << ROWS[row];
6372
let rows_to_clear = ROW_BITS ^ rows_to_set;
73+
6474
let cols_to_clear = column_pins(cols);
6575
let cols_to_set = COL_BITS ^ cols_to_clear;
6676

0 commit comments

Comments
 (0)