Write generic "get me a working Neopixel output pin" code for Gemma M0
This commit is contained in:
parent
9c7ffe2125
commit
0d07cd4abd
2 changed files with 96 additions and 0 deletions
12
gemma_m0_lights/Cargo.toml
Normal file
12
gemma_m0_lights/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "gemma_m0_lights"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Tangent 128 <Tangent128@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cortex-m = { version = "0.5.8", features = ["inline-asm"] }
|
||||||
|
embedded-hal = "0.2.2"
|
||||||
|
gemma_m0 = "0.2.1"
|
||||||
|
lights = { path = "../lights" }
|
||||||
|
panic-halt = "0.2"
|
84
gemma_m0_lights/src/lib.rs
Normal file
84
gemma_m0_lights/src/lib.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cortex_m;
|
||||||
|
extern crate embedded_hal;
|
||||||
|
extern crate gemma_m0 as hal;
|
||||||
|
extern crate panic_halt;
|
||||||
|
|
||||||
|
pub use cortex_m::asm::delay;
|
||||||
|
pub use hal::entry;
|
||||||
|
|
||||||
|
use core::u8;
|
||||||
|
use embedded_hal::digital::OutputPin;
|
||||||
|
use hal::{
|
||||||
|
clock::GenericClockController,
|
||||||
|
Peripherals
|
||||||
|
};
|
||||||
|
use lights::{
|
||||||
|
gamma::CorrectedRgb,
|
||||||
|
Lights
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn boot() -> impl Lights<Pixel = CorrectedRgb> {
|
||||||
|
let mut peripherals = Peripherals::take().unwrap();
|
||||||
|
let _clock = GenericClockController::with_internal_32kosc(
|
||||||
|
peripherals.GCLK,
|
||||||
|
&mut peripherals.PM,
|
||||||
|
&mut peripherals.SYSCTRL,
|
||||||
|
&mut peripherals.NVMCTRL
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut pins = hal::Pins::new(peripherals.PORT);
|
||||||
|
|
||||||
|
NeopixelLights {
|
||||||
|
out: pins.d1.into_push_pull_output(&mut pins.port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// approx. 20ns per clock cycle;
|
||||||
|
const ZERO_HIGH_CYCLES: u32 = 11; // smidge above 200ns
|
||||||
|
const ONE_HIGH_CYCLES: u32 = 35; // about 700ns
|
||||||
|
const DATA_LOW_CYCLES: u32 = 25; // about 500ns
|
||||||
|
const LATCH_CYCLES: u32 = 300; // about 6000ns
|
||||||
|
//const FRAME_DELAY_CYCLES: u32 = 1_000_000; // about 20ms, but doesn't count the time for the other operations
|
||||||
|
|
||||||
|
pub struct NeopixelLights<T: OutputPin> {
|
||||||
|
out: T
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: OutputPin> NeopixelLights<T> {
|
||||||
|
#[inline]
|
||||||
|
fn write(&mut self, bit: bool) {
|
||||||
|
self.out.set_high();
|
||||||
|
delay(if bit { ONE_HIGH_CYCLES } else { ZERO_HIGH_CYCLES });
|
||||||
|
self.out.set_low();
|
||||||
|
delay(DATA_LOW_CYCLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn byte(&mut self, byte: u8) {
|
||||||
|
self.write(byte & 0x80 != 0);
|
||||||
|
self.write(byte & 0x40 != 0);
|
||||||
|
self.write(byte & 0x20 != 0);
|
||||||
|
self.write(byte & 0x10 != 0);
|
||||||
|
self.write(byte & 0x08 != 0);
|
||||||
|
self.write(byte & 0x04 != 0);
|
||||||
|
self.write(byte & 0x02 != 0);
|
||||||
|
self.write(byte & 0x01 != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: OutputPin> Lights for NeopixelLights<T> {
|
||||||
|
type Pixel = CorrectedRgb;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn render(&mut self, rgb: &CorrectedRgb) {
|
||||||
|
// GRB pixel order
|
||||||
|
self.byte(rgb.1);
|
||||||
|
self.byte(rgb.0);
|
||||||
|
self.byte(rgb.2);
|
||||||
|
}
|
||||||
|
fn latch(&mut self) {
|
||||||
|
delay(LATCH_CYCLES);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue