Compare commits
7 Commits
0f1eb8da31
...
42d63292a8
Author | SHA1 | Date | |
---|---|---|---|
|
42d63292a8 | ||
|
0a668af6e4 | ||
|
6e54b54895 | ||
|
4e0d9d82f2 | ||
|
3915ebbd95 | ||
|
6954ce14de | ||
|
f39fa7b354 |
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arduino-hal"
|
name = "arduino-hal"
|
||||||
|
@ -74,9 +74,9 @@ checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.21.0"
|
version = "1.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
|
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -143,36 +143,6 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
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]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
@ -181,18 +151,18 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.79"
|
version = "1.0.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.36"
|
version = "1.0.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -208,9 +178,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.19"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smart-leds"
|
name = "smart-leds"
|
||||||
|
@ -230,6 +200,36 @@ dependencies = [
|
||||||
"rgb",
|
"rgb",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "soft-serial"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduino-hal",
|
||||||
|
"avr-device",
|
||||||
|
"smart-leds",
|
||||||
|
"static_pins",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_pins"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://gitea.doryan04.ru/TheEmbeddedRust/static_pins#e3e619c7abfe9af0c966f970c0aef8b7fb89fb59"
|
||||||
|
dependencies = [
|
||||||
|
"arduino-hal",
|
||||||
|
"static_pins_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_pins_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://gitea.doryan04.ru/TheEmbeddedRust/static_pins#e3e619c7abfe9af0c966f970c0aef8b7fb89fb59"
|
||||||
|
dependencies = [
|
||||||
|
"arduino-hal",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.100",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
@ -243,9 +243,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.58"
|
version = "2.0.100"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -281,9 +281,9 @@ checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.16"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unwrap-infallible"
|
name = "unwrap-infallible"
|
||||||
|
|
32
Cargo.toml
32
Cargo.toml
|
@ -1,28 +1,30 @@
|
||||||
[package]
|
[package]
|
||||||
name = "neopixel_avr"
|
name = "soft-serial"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[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"
|
smart-leds = "0.4.0"
|
||||||
|
|
||||||
[dependencies.neopixel_macros]
|
|
||||||
path = "neopixel_macros"
|
|
||||||
|
|
||||||
[dependencies.avr-device]
|
|
||||||
version = "0.5.4"
|
|
||||||
features = ["atmega32u4"]
|
|
||||||
|
|
||||||
[dependencies.arduino-hal]
|
[dependencies.arduino-hal]
|
||||||
git = "https://github.com/rahix/avr-hal"
|
git = "https://github.com/rahix/avr-hal"
|
||||||
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
|
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||||
features = ["sparkfun-promicro"]
|
features = ["sparkfun-promicro"]
|
||||||
|
|
||||||
[build-dependencies.proc-macro2]
|
[dependencies.static_pins]
|
||||||
version = "=1.0.79"
|
git = "https://gitea.doryan04.ru/TheEmbeddedRust/static_pins"
|
||||||
|
|
||||||
|
[dependencies.avr-device]
|
||||||
|
version = "0.5.4"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
codegen-units = 1
|
||||||
|
debug = true
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
# 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"
|
|
|
@ -1,13 +0,0 @@
|
||||||
[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"
|
|
|
@ -1,4 +0,0 @@
|
||||||
[toolchain]
|
|
||||||
channel = "nightly-2024-03-22"
|
|
||||||
components = [ "rust-src" ]
|
|
||||||
profile = "complete"
|
|
|
@ -1,54 +0,0 @@
|
||||||
#![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!()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2024-06-13"
|
channel = "nightly-2024-06-13"
|
||||||
components = [ "rust-src" ]
|
components = [ "rust-src" ]
|
||||||
profile = "complete"
|
profile = "default"
|
||||||
|
|
95
src/lib.rs
95
src/lib.rs
|
@ -1,46 +1,64 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(asm_experimental_arch)]
|
#![feature(asm_experimental_arch)]
|
||||||
|
|
||||||
extern crate core;
|
use core::{arch::asm, marker::PhantomData};
|
||||||
|
|
||||||
mod macros;
|
use arduino_hal::port::{mode::Output, Pin, PinOps};
|
||||||
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 avr_device::interrupt::free;
|
||||||
use neopixel_macros::impl_static_pin;
|
|
||||||
|
|
||||||
use smart_leds::{SmartLedsWrite, RGB8};
|
use smart_leds::{SmartLedsWrite, RGB8};
|
||||||
|
use static_pins::StaticPinOps;
|
||||||
|
|
||||||
const LAST_BIT: u8 = 0x80;
|
const MSB: u8 = 0x80;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Neopixel<P> {
|
pub struct Neopixel<P> {
|
||||||
_pin: Pin<Output, P>,
|
_pin: PhantomData<Pin<Output, P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> Neopixel<P>
|
impl<P> Neopixel<P>
|
||||||
where
|
where
|
||||||
P: PinOps + StaticPin,
|
P: PinOps + StaticPinOps,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(_pin: Pin<Output, P>) -> Self {
|
pub fn new(_pin: Pin<Output, P>) -> Self {
|
||||||
Self { _pin }
|
Self {
|
||||||
|
_pin: PhantomData {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_color_channel(&self, data: u8) {
|
||||||
|
let (mut data, port_data) = (data, P::read());
|
||||||
|
unsafe {
|
||||||
|
for _ in 0..8 {
|
||||||
|
P::write(port_data | P::PIN_POS);
|
||||||
|
asm!("rjmp +0");
|
||||||
|
if data & MSB == 0 {
|
||||||
|
P::write(port_data & !P::PIN_POS);
|
||||||
|
}
|
||||||
|
asm!(
|
||||||
|
"
|
||||||
|
rjmp +0
|
||||||
|
rjmp +0
|
||||||
|
"
|
||||||
|
);
|
||||||
|
P::write(port_data & !P::PIN_POS);
|
||||||
|
asm!(
|
||||||
|
"
|
||||||
|
rjmp +0
|
||||||
|
rjmp +0
|
||||||
|
rjmp +0
|
||||||
|
"
|
||||||
|
);
|
||||||
|
data <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> SmartLedsWrite for Neopixel<P>
|
impl<P> SmartLedsWrite for Neopixel<P>
|
||||||
where
|
where
|
||||||
P: PinOps + StaticPin,
|
P: PinOps + StaticPinOps,
|
||||||
{
|
{
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Color = smart_leds::RGB<u8>;
|
type Color = smart_leds::RGB<u8>;
|
||||||
|
@ -53,7 +71,7 @@ where
|
||||||
for i in iterator {
|
for i in iterator {
|
||||||
let RGB8 { r, g, b } = i.into();
|
let RGB8 { r, g, b } = i.into();
|
||||||
for value in [g, r, b] {
|
for value in [g, r, b] {
|
||||||
self.priv_write(value);
|
self.write_color_channel(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,36 +79,3 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_static_pins {
|
|
||||||
($($pin:ident),+) => {
|
|
||||||
$(
|
|
||||||
impl_static_pin!($pin);
|
|
||||||
)+
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
mod static_pin;
|
|
||||||
pub(crate) use static_pin::*;
|
|
|
@ -1,16 +0,0 @@
|
||||||
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