use crate::nrf51;
use tiny_led_matrix::DisplayControl;
use crate::gpio::DisplayPins;
use pin_constants::*;
pub mod pin_constants {
const fn bit_range(lo: usize, count: usize) -> u32 {
((1<<count) - 1) << lo
}
pub const MATRIX_COLS : usize = 9;
pub const FIRST_COL_PIN : usize = 4;
pub const LAST_COL_PIN : usize = FIRST_COL_PIN + MATRIX_COLS - 1;
pub const COL_PINS_MASK : u32 = bit_range(FIRST_COL_PIN, MATRIX_COLS);
pub const MATRIX_ROWS : usize = 3;
pub const FIRST_ROW_PIN : usize = 13;
pub const LAST_ROW_PIN : usize = FIRST_ROW_PIN + MATRIX_ROWS - 1;
pub const ROW_PINS_MASK : u32 = bit_range(FIRST_ROW_PIN, MATRIX_ROWS);
pub const fn col_pin_number(col: usize) -> u32 {
(FIRST_COL_PIN + col) as u32
}
pub const fn row_pin_number(row: usize) -> u32 {
(FIRST_ROW_PIN + row) as u32
}
}
pub struct DisplayPort(DisplayPins);
impl DisplayPort {
pub fn new(pins: DisplayPins) -> DisplayPort {
let mut port = DisplayPort(pins);
port.reset();
port.blank();
port
}
pub fn free(self) -> DisplayPins {
self.0
}
fn reset(&mut self) {
unsafe {
let gpio = &*nrf51::GPIO::ptr();
for ii in FIRST_COL_PIN ..= LAST_COL_PIN {
gpio.pin_cnf[ii].write(|w| w.dir().output());
}
for ii in FIRST_ROW_PIN ..= LAST_ROW_PIN {
gpio.pin_cnf[ii].write(|w| w.dir().output());
}
}
}
pub fn set(&mut self, pins: u32) {
let to_set = pins & (ROW_PINS_MASK | COL_PINS_MASK);
unsafe {
let gpio = &*nrf51::GPIO::ptr();
gpio.outset.write(|w| { w.bits(to_set) });
}
}
pub fn clear(&mut self, pins: u32) {
let to_clear = pins & (ROW_PINS_MASK | COL_PINS_MASK);
unsafe {
let gpio = &*nrf51::GPIO::ptr();
gpio.outclr.write(|w| { w.bits(to_clear) });
}
}
pub fn blank(&mut self) {
self.clear(ROW_PINS_MASK | COL_PINS_MASK);
}
}
impl DisplayControl for DisplayPort {
fn initialise_for_display(&mut self) {
}
fn display_row_leds(&mut self, row: usize, cols: u32) {
let rows_to_set = 1<<(FIRST_ROW_PIN+row);
let rows_to_clear = ROW_PINS_MASK ^ rows_to_set;
let cols_to_clear = cols << FIRST_COL_PIN;
let cols_to_set = COL_PINS_MASK ^ cols_to_clear;
self.set(rows_to_set | cols_to_set);
self.clear(rows_to_clear | cols_to_clear);
}
fn light_current_row_leds(&mut self, cols: u32) {
self.clear(cols << FIRST_COL_PIN)
}
}