feat(neopixel): first commit
This commit is contained in:
commit
0f1eb8da31
|
@ -0,0 +1 @@
|
|||
target
|
|
@ -0,0 +1,304 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arduino-hal"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rahix/avr-hal?rev=3e362624547462928a219c40f9ea8e3a64f21e5f#3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||
dependencies = [
|
||||
"atmega-hal",
|
||||
"avr-device",
|
||||
"avr-hal-generic",
|
||||
"cfg-if 1.0.0",
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-hal 1.0.0",
|
||||
"ufmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atmega-hal"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rahix/avr-hal?rev=3e362624547462928a219c40f9ea8e3a64f21e5f#3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||
dependencies = [
|
||||
"avr-device",
|
||||
"avr-hal-generic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "avr-device"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "546b09da5e933d18b790ccb5aae351371c6c4f8094a7b011dcd7c7e7fb69cc94"
|
||||
dependencies = [
|
||||
"avr-device-macros",
|
||||
"bare-metal",
|
||||
"cfg-if 1.0.0",
|
||||
"vcell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "avr-device-macros"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b108541dc1ea060dfa9b824acbded94f658f8daecca549144d05a4d01e65b6f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "avr-hal-generic"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rahix/avr-hal?rev=3e362624547462928a219c40f9ea8e3a64f21e5f#3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||
dependencies = [
|
||||
"avr-device",
|
||||
"cfg-if 0.1.10",
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-hal 1.0.0",
|
||||
"embedded-hal-bus",
|
||||
"embedded-storage",
|
||||
"nb 1.1.0",
|
||||
"paste",
|
||||
"rustversion",
|
||||
"ufmt",
|
||||
"unwrap-infallible",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bare-metal"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
||||
dependencies = [
|
||||
"nb 0.1.3",
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal-bus"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57b4e6ede84339ebdb418cd986e6320a34b017cdf99b5cc3efceec6450b06886"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"embedded-hal 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-storage"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "723dce4e9f25b6e6c5f35628e144794e5b459216ed7da97b7c4b66cdb3fa82ca"
|
||||
|
||||
[[package]]
|
||||
name = "nb"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
|
||||
dependencies = [
|
||||
"nb 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nb"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
||||
|
||||
[[package]]
|
||||
name = "neopixel_avr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arduino-hal",
|
||||
"avr-device",
|
||||
"embedded-hal 1.0.0",
|
||||
"nb 1.1.0",
|
||||
"neopixel_macros",
|
||||
"panic-halt",
|
||||
"proc-macro2",
|
||||
"smart-leds",
|
||||
"smart-leds-trait",
|
||||
"ufmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neopixel_macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic-halt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||
|
||||
[[package]]
|
||||
name = "smart-leds"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0"
|
||||
dependencies = [
|
||||
"smart-leds-trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smart-leds-trait"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edeb89c73244414bb0568611690dd095b2358b3fda5bae65ad784806cca00157"
|
||||
dependencies = [
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ufmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a64846ec02b57e9108d6469d98d1648782ad6bb150a95a9baac26900bbeab9d"
|
||||
dependencies = [
|
||||
"ufmt-macros",
|
||||
"ufmt-write",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ufmt-macros"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ufmt-write"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "unwrap-infallible"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb"
|
||||
|
||||
[[package]]
|
||||
name = "vcell"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "neopixel_avr"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
panic-halt = "0.2.0"
|
||||
ufmt = "0.2.0"
|
||||
nb = "1.1.0"
|
||||
embedded-hal = "1.0"
|
||||
smart-leds-trait = "0.3.1"
|
||||
smart-leds = "0.4.0"
|
||||
|
||||
[dependencies.neopixel_macros]
|
||||
path = "neopixel_macros"
|
||||
|
||||
[dependencies.avr-device]
|
||||
version = "0.5.4"
|
||||
features = ["atmega32u4"]
|
||||
|
||||
[dependencies.arduino-hal]
|
||||
git = "https://github.com/rahix/avr-hal"
|
||||
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||
features = ["sparkfun-promicro"]
|
||||
|
||||
[build-dependencies.proc-macro2]
|
||||
version = "=1.0.79"
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "neopixel_macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "neopixel_macros"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc_macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "2.0.58"
|
||||
|
||||
[build-dependencies.proc-macro2]
|
||||
version = "=1.0.79"
|
|
@ -0,0 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2024-03-22"
|
||||
components = [ "rust-src" ]
|
||||
profile = "complete"
|
|
@ -0,0 +1,54 @@
|
|||
#![feature(proc_macro_quote)]
|
||||
#![no_std]
|
||||
|
||||
use core::str::FromStr;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use proc_macro::{quote, TokenStream};
|
||||
use syn::parse;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn impl_static_pin(pin: TokenStream) -> TokenStream {
|
||||
let parsing_result = parse::<syn::Ident>(pin.clone());
|
||||
|
||||
if let Ok(ident) = parsing_result {
|
||||
let pin = TokenStream::from_str(ident.to_string().as_str()).unwrap();
|
||||
let mut identifier = ident.to_string();
|
||||
identifier.insert_str(1, "ORT");
|
||||
|
||||
let pin_num = identifier.pop().unwrap();
|
||||
|
||||
if pin_num.is_ascii_digit() {
|
||||
let pin_num = TokenStream::from_str(&pin_num.to_string()).unwrap();
|
||||
|
||||
let port_field = TokenStream::from_str(&identifier.to_ascii_lowercase()).unwrap();
|
||||
|
||||
let port_ident = TokenStream::from_str(identifier.as_str()).unwrap();
|
||||
let trait_ident = TokenStream::from_str("StaticPin").unwrap();
|
||||
|
||||
quote! {
|
||||
impl $trait_ident for $pin {
|
||||
type Port = $port_ident;
|
||||
const PIN_NUM: u8 = $pin_num;
|
||||
|
||||
fn write(data: u8) {
|
||||
unsafe {
|
||||
(*Self::Port::ptr())
|
||||
.$port_field
|
||||
.write(|w| w.bits(data));
|
||||
}
|
||||
}
|
||||
fn read() -> u8 {
|
||||
unsafe { (*Self::Port::ptr()).$port_field.read().bits() }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2024-06-13"
|
||||
components = [ "rust-src" ]
|
||||
profile = "complete"
|
|
@ -0,0 +1,96 @@
|
|||
#![no_std]
|
||||
#![feature(asm_experimental_arch)]
|
||||
|
||||
extern crate core;
|
||||
|
||||
mod macros;
|
||||
mod types;
|
||||
|
||||
use types::*;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use arduino_hal::{
|
||||
delay_us,
|
||||
hal::port::{PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7},
|
||||
pac::PORTD,
|
||||
port::{mode::Output, Pin, PinOps},
|
||||
};
|
||||
use avr_device::interrupt::free;
|
||||
use neopixel_macros::impl_static_pin;
|
||||
|
||||
use smart_leds::{SmartLedsWrite, RGB8};
|
||||
|
||||
const LAST_BIT: u8 = 0x80;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Neopixel<P> {
|
||||
_pin: Pin<Output, P>,
|
||||
}
|
||||
|
||||
impl<P> Neopixel<P>
|
||||
where
|
||||
P: PinOps + StaticPin,
|
||||
{
|
||||
#[inline]
|
||||
pub const fn new(_pin: Pin<Output, P>) -> Self {
|
||||
Self { _pin }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> SmartLedsWrite for Neopixel<P>
|
||||
where
|
||||
P: PinOps + StaticPin,
|
||||
{
|
||||
type Error = ();
|
||||
type Color = smart_leds::RGB<u8>;
|
||||
fn write<T, I>(&mut self, iterator: T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: IntoIterator<Item = I>,
|
||||
I: Into<Self::Color>,
|
||||
{
|
||||
free(|_cs| {
|
||||
for i in iterator {
|
||||
let RGB8 { r, g, b } = i.into();
|
||||
for value in [g, r, b] {
|
||||
self.priv_write(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Neopixel<P>
|
||||
where
|
||||
P: PinOps + StaticPin,
|
||||
{
|
||||
fn priv_write(&self, data: u8) {
|
||||
let (mut count, mut data, port_data, pin_data) = (8, data, P::read(), 1 << P::PIN_NUM);
|
||||
unsafe {
|
||||
while count > 0 {
|
||||
P::write(port_data | pin_data);
|
||||
asm!("rjmp +0");
|
||||
if data & LAST_BIT == 0 {
|
||||
P::write(port_data & !pin_data);
|
||||
}
|
||||
asm!(
|
||||
"
|
||||
rjmp +0
|
||||
rjmp +0
|
||||
"
|
||||
);
|
||||
P::write(port_data & !pin_data);
|
||||
asm!(
|
||||
"
|
||||
rjmp +0
|
||||
rjmp +0
|
||||
rjmp +0
|
||||
"
|
||||
);
|
||||
data <<= 1;
|
||||
count -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#[macro_export]
|
||||
macro_rules! impl_static_pins {
|
||||
($($pin:ident),+) => {
|
||||
$(
|
||||
impl_static_pin!($pin);
|
||||
)+
|
||||
};
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
mod static_pin;
|
||||
pub(crate) use static_pin::*;
|
|
@ -0,0 +1,16 @@
|
|||
use arduino_hal::{hal::port::*, pac::*};
|
||||
|
||||
use crate::{impl_static_pin, impl_static_pins};
|
||||
|
||||
pub trait StaticPin {
|
||||
type Port;
|
||||
const PIN_NUM: u8;
|
||||
|
||||
fn write(data: u8);
|
||||
fn read() -> u8;
|
||||
}
|
||||
|
||||
impl_static_pins!(
|
||||
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PC6, PC7, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PE2,
|
||||
PE6, PF0, PF1, PF4, PF5, PF6, PF7
|
||||
);
|
Loading…
Reference in New Issue