mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-29 21:30:39 +00:00
GPIO Refactoring (#1542)
* GPIO Refactoring * CHANGELOG.md * Addressed review comments * Use `Level` instead of plain bool in public API * Let drivers enable analog functions
This commit is contained in:
parent
68628fc008
commit
2faa2654cb
@ -74,7 +74,12 @@ mod embassy;
|
|||||||
mod enum_dispatch;
|
mod enum_dispatch;
|
||||||
#[cfg(feature = "interrupt")]
|
#[cfg(feature = "interrupt")]
|
||||||
mod interrupt;
|
mod interrupt;
|
||||||
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
#[cfg(any(
|
||||||
|
feature = "is-lp-core",
|
||||||
|
feature = "is-ulp-core",
|
||||||
|
feature = "has-lp-core",
|
||||||
|
feature = "has-ulp-core"
|
||||||
|
))]
|
||||||
mod lp_core;
|
mod lp_core;
|
||||||
|
|
||||||
#[cfg(feature = "ram")]
|
#[cfg(feature = "ram")]
|
||||||
@ -318,283 +323,15 @@ pub fn make_gpio_enum_dispatch_macro(input: TokenStream) -> TokenStream {
|
|||||||
#[cfg(any(feature = "has-lp-core", feature = "has-ulp-core"))]
|
#[cfg(any(feature = "has-lp-core", feature = "has-ulp-core"))]
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn load_lp_code(input: TokenStream) -> TokenStream {
|
pub fn load_lp_code(input: TokenStream) -> TokenStream {
|
||||||
use std::{fs, path::Path};
|
lp_core::load_lp_code(input)
|
||||||
|
|
||||||
use litrs::StringLit;
|
|
||||||
use object::{File, Object, ObjectSection, ObjectSymbol, Section, SectionKind};
|
|
||||||
use parse::Error;
|
|
||||||
use proc_macro::Span;
|
|
||||||
use proc_macro_crate::{crate_name, FoundCrate};
|
|
||||||
use quote::quote;
|
|
||||||
use syn::{parse, Ident};
|
|
||||||
|
|
||||||
let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) {
|
|
||||||
crate_name("esp-lp-hal")
|
|
||||||
} else {
|
|
||||||
crate_name("esp-hal")
|
|
||||||
};
|
|
||||||
|
|
||||||
let hal_crate = if let Ok(FoundCrate::Name(ref name)) = hal_crate {
|
|
||||||
let ident = Ident::new(&name, Span::call_site().into());
|
|
||||||
quote!( #ident )
|
|
||||||
} else {
|
|
||||||
quote!(crate)
|
|
||||||
};
|
|
||||||
|
|
||||||
let first_token = match input.into_iter().next() {
|
|
||||||
Some(token) => token,
|
|
||||||
None => {
|
|
||||||
return Error::new(
|
|
||||||
Span::call_site().into(),
|
|
||||||
"You need to give the path to an ELF file",
|
|
||||||
)
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let arg = match StringLit::try_from(&first_token) {
|
|
||||||
Ok(arg) => arg,
|
|
||||||
Err(_) => {
|
|
||||||
return Error::new(
|
|
||||||
Span::call_site().into(),
|
|
||||||
"You need to give the path to an ELF file",
|
|
||||||
)
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let elf_file = arg.value();
|
|
||||||
|
|
||||||
if !Path::new(elf_file).exists() {
|
|
||||||
return Error::new(Span::call_site().into(), "File not found")
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let bin_data = fs::read(elf_file).unwrap();
|
|
||||||
let obj_file = File::parse(&*bin_data).unwrap();
|
|
||||||
let sections = obj_file.sections();
|
|
||||||
|
|
||||||
let mut sections: Vec<Section> = sections
|
|
||||||
.into_iter()
|
|
||||||
.filter(|section| match section.kind() {
|
|
||||||
SectionKind::Text
|
|
||||||
| SectionKind::ReadOnlyData
|
|
||||||
| SectionKind::Data
|
|
||||||
| SectionKind::UninitializedData => true,
|
|
||||||
_ => false,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
sections.sort_by(|a, b| a.address().partial_cmp(&b.address()).unwrap());
|
|
||||||
|
|
||||||
let mut binary: Vec<u8> = Vec::new();
|
|
||||||
let mut last_address = if cfg!(feature = "has-lp-core") {
|
|
||||||
0x5000_0000
|
|
||||||
} else {
|
|
||||||
0x0
|
|
||||||
};
|
|
||||||
|
|
||||||
for section in sections {
|
|
||||||
if section.address() > last_address {
|
|
||||||
for _ in 0..(section.address() - last_address) {
|
|
||||||
binary.push(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.extend_from_slice(section.data().unwrap());
|
|
||||||
last_address = section.address() + section.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
let magic_symbol = obj_file
|
|
||||||
.symbols()
|
|
||||||
.find(|s| s.name().unwrap().starts_with("__ULP_MAGIC_"));
|
|
||||||
|
|
||||||
if let None = magic_symbol {
|
|
||||||
return Error::new(
|
|
||||||
Span::call_site().into(),
|
|
||||||
"Given file doesn't seem to be an LP/ULP core application.",
|
|
||||||
)
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let magic_symbol = magic_symbol.unwrap().name().unwrap();
|
|
||||||
|
|
||||||
let magic_symbol = magic_symbol.trim_start_matches("__ULP_MAGIC_");
|
|
||||||
let args: Vec<proc_macro2::TokenStream> = magic_symbol
|
|
||||||
.split("$")
|
|
||||||
.into_iter()
|
|
||||||
.map(|t| {
|
|
||||||
let t = t.replace("GpioPin", "LowPowerPin");
|
|
||||||
t.parse().unwrap()
|
|
||||||
})
|
|
||||||
.filter(|v: &proc_macro2::TokenStream| !v.is_empty())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
#[cfg(feature = "has-lp-core")]
|
|
||||||
let imports = quote! {
|
|
||||||
use #hal_crate::lp_core::LpCore;
|
|
||||||
use #hal_crate::lp_core::LpCoreWakeupSource;
|
|
||||||
use #hal_crate::gpio::lp_io::LowPowerPin;
|
|
||||||
use #hal_crate::gpio::*;
|
|
||||||
use #hal_crate::uart::lp_uart::LpUart;
|
|
||||||
use #hal_crate::i2c::lp_i2c::LpI2c;
|
|
||||||
};
|
|
||||||
#[cfg(feature = "has-ulp-core")]
|
|
||||||
let imports = quote! {
|
|
||||||
use #hal_crate::ulp_core::UlpCore as LpCore;
|
|
||||||
use #hal_crate::ulp_core::UlpCoreWakeupSource as LpCoreWakeupSource;
|
|
||||||
use #hal_crate::gpio::*;
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "has-lp-core")]
|
|
||||||
let rtc_code_start = quote! { _rtc_fast_data_start };
|
|
||||||
#[cfg(feature = "has-ulp-core")]
|
|
||||||
let rtc_code_start = quote! { _rtc_slow_data_start };
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
{
|
|
||||||
#imports
|
|
||||||
|
|
||||||
struct LpCoreCode {}
|
|
||||||
|
|
||||||
static LP_CODE: &[u8] = &[#(#binary),*];
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static #rtc_code_start: u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
core::ptr::copy_nonoverlapping(LP_CODE as *const _ as *const u8, &#rtc_code_start as *const u32 as *mut u8, LP_CODE.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LpCoreCode {
|
|
||||||
pub fn run(
|
|
||||||
&self,
|
|
||||||
lp_core: &mut LpCore,
|
|
||||||
wakeup_source: LpCoreWakeupSource,
|
|
||||||
#(_: #args),*
|
|
||||||
) {
|
|
||||||
lp_core.run(wakeup_source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LpCoreCode {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Marks the entry function of a LP core / ULP program.
|
||||||
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
||||||
#[proc_macro_error::proc_macro_error]
|
#[proc_macro_error::proc_macro_error]
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
use proc_macro2::{Ident, Span};
|
lp_core::entry(args, input)
|
||||||
use proc_macro_crate::{crate_name, FoundCrate};
|
|
||||||
use quote::{format_ident, quote};
|
|
||||||
use syn::{
|
|
||||||
parse::{self, Error},
|
|
||||||
parse_macro_input,
|
|
||||||
spanned::Spanned,
|
|
||||||
FnArg,
|
|
||||||
ItemFn,
|
|
||||||
};
|
|
||||||
|
|
||||||
use self::lp_core::{extract_pin, get_simplename, make_magic_symbol_name};
|
|
||||||
|
|
||||||
let found_crate = crate_name("esp-lp-hal").expect("esp-lp-hal is present in `Cargo.toml`");
|
|
||||||
let hal_crate = match found_crate {
|
|
||||||
FoundCrate::Itself => quote!(esp_lp_hal),
|
|
||||||
FoundCrate::Name(name) => {
|
|
||||||
let ident = Ident::new(&name, Span::call_site());
|
|
||||||
quote!( #ident )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if !args.is_empty() {
|
|
||||||
return Error::new(Span::call_site(), "This attribute accepts no arguments")
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let f = parse_macro_input!(input as ItemFn);
|
|
||||||
|
|
||||||
let mut argument_types = Vec::new();
|
|
||||||
let mut create_peripheral = Vec::new();
|
|
||||||
|
|
||||||
let mut used_pins: Vec<u8> = Vec::new();
|
|
||||||
|
|
||||||
for (num, arg) in f.sig.inputs.iter().enumerate() {
|
|
||||||
let param_name = format_ident!("param{}", num);
|
|
||||||
match arg {
|
|
||||||
FnArg::Receiver(_) => {
|
|
||||||
return Error::new(arg.span(), "invalid argument")
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
FnArg::Typed(t) => {
|
|
||||||
match get_simplename(&t.ty).as_str() {
|
|
||||||
"GpioPin" => {
|
|
||||||
let pin = extract_pin(&t.ty);
|
|
||||||
if used_pins.contains(&pin) {
|
|
||||||
return Error::new(arg.span(), "duplicate pin")
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
used_pins.push(pin);
|
|
||||||
create_peripheral.push(quote!(
|
|
||||||
let mut #param_name = unsafe { the_hal::gpio::conjure().unwrap() };
|
|
||||||
));
|
|
||||||
}
|
|
||||||
"LpUart" => {
|
|
||||||
create_peripheral.push(quote!(
|
|
||||||
let mut #param_name = unsafe { the_hal::uart::conjure() };
|
|
||||||
));
|
|
||||||
}
|
|
||||||
"LpI2c" => {
|
|
||||||
create_peripheral.push(quote!(
|
|
||||||
let mut #param_name = unsafe { the_hal::i2c::conjure() };
|
|
||||||
));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Error::new(arg.span(), "invalid argument to main")
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argument_types.push(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let magic_symbol_name = make_magic_symbol_name(&argument_types);
|
|
||||||
|
|
||||||
let param_names: Vec<Ident> = argument_types
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(num, _)| format_ident!("param{}", num))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
quote!(
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[export_name = "main"]
|
|
||||||
pub fn __risc_v_rt__main() -> ! {
|
|
||||||
#[export_name = #magic_symbol_name]
|
|
||||||
static ULP_MAGIC: [u32; 0] = [0u32; 0];
|
|
||||||
|
|
||||||
unsafe { ULP_MAGIC.as_ptr().read_volatile(); }
|
|
||||||
|
|
||||||
use #hal_crate as the_hal;
|
|
||||||
#(
|
|
||||||
#create_peripheral;
|
|
||||||
)*
|
|
||||||
|
|
||||||
main(#(#param_names),*);
|
|
||||||
}
|
|
||||||
|
|
||||||
#f
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `executor` instance and declares an application entry point
|
/// Creates a new `executor` instance and declares an application entry point
|
||||||
|
@ -1,71 +1,375 @@
|
|||||||
|
#[allow(unused)]
|
||||||
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{GenericArgument, PatType, PathArguments, Type};
|
|
||||||
|
|
||||||
pub(crate) fn make_magic_symbol_name(args: &Vec<&PatType>) -> String {
|
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
||||||
let mut res = String::from("__ULP_MAGIC_");
|
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
for &a in args {
|
use proc_macro2::{Ident, Span};
|
||||||
let t = &a.ty;
|
use proc_macro_crate::{crate_name, FoundCrate};
|
||||||
let quoted = to_string(&t);
|
use quote::{format_ident, quote};
|
||||||
res.push_str("ed);
|
use syn::{
|
||||||
res.push_str("$");
|
parse::Error,
|
||||||
|
parse_macro_input,
|
||||||
|
spanned::Spanned,
|
||||||
|
FnArg,
|
||||||
|
GenericArgument,
|
||||||
|
ItemFn,
|
||||||
|
PatType,
|
||||||
|
PathArguments,
|
||||||
|
Type,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) fn make_magic_symbol_name(args: &Vec<&PatType>) -> String {
|
||||||
|
let mut res = String::from("__ULP_MAGIC_");
|
||||||
|
for &a in args {
|
||||||
|
let t = &a.ty;
|
||||||
|
let quoted = to_string(&t);
|
||||||
|
res.push_str("ed);
|
||||||
|
res.push_str("$");
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
pub(crate) fn get_simplename(t: &Type) -> String {
|
||||||
}
|
String::from(match t {
|
||||||
|
Type::Path(p) => String::from(&p.path.segments.last().unwrap().ident.to_string()),
|
||||||
|
_ => String::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_simplename(t: &Type) -> String {
|
pub(crate) fn extract_pin(ty: &Type) -> u8 {
|
||||||
String::from(match t {
|
let mut res = 255u8;
|
||||||
Type::Path(p) => String::from(&p.path.segments.last().unwrap().ident.to_string()),
|
if let Type::Path(p) = ty {
|
||||||
_ => String::new(),
|
let segment = p.path.segments.last().unwrap();
|
||||||
})
|
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
||||||
}
|
for arg in &g.args {
|
||||||
|
match arg {
|
||||||
pub(crate) fn extract_pin(ty: &Type) -> u8 {
|
GenericArgument::Type(t) => {
|
||||||
let mut res = 255u8;
|
res = extract_pin(t);
|
||||||
if let Type::Path(p) = ty {
|
}
|
||||||
let segment = p.path.segments.last().unwrap();
|
GenericArgument::Const(c) => {
|
||||||
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
res = ("e! { #c }.to_string()).parse().unwrap();
|
||||||
for arg in &g.args {
|
}
|
||||||
match arg {
|
_ => (),
|
||||||
GenericArgument::Type(t) => {
|
|
||||||
res = extract_pin(t);
|
|
||||||
}
|
}
|
||||||
GenericArgument::Const(c) => {
|
|
||||||
res = ("e! { #c }.to_string()).parse().unwrap();
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
// This is a specialized implementation - won't fit other use-cases
|
||||||
}
|
fn to_string(ty: &Type) -> String {
|
||||||
|
let mut res = String::new();
|
||||||
|
if let Type::Path(p) = ty {
|
||||||
|
let segment = p.path.segments.last().unwrap();
|
||||||
|
res.push_str(&segment.ident.to_string());
|
||||||
|
|
||||||
// This is a specialized implementation - won't fit other use-cases
|
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
||||||
fn to_string(ty: &Type) -> String {
|
res.push_str("<");
|
||||||
let mut res = String::new();
|
let mut pushed = false;
|
||||||
if let Type::Path(p) = ty {
|
for arg in &g.args {
|
||||||
let segment = p.path.segments.last().unwrap();
|
if pushed {
|
||||||
res.push_str(&segment.ident.to_string());
|
|
||||||
|
|
||||||
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
|
||||||
res.push_str("<");
|
|
||||||
for arg in &g.args {
|
|
||||||
match arg {
|
|
||||||
GenericArgument::Type(t) => {
|
|
||||||
res.push_str(&to_string(t));
|
|
||||||
}
|
|
||||||
GenericArgument::Const(c) => {
|
|
||||||
res.push_str(",");
|
res.push_str(",");
|
||||||
res.push_str("e! { #c }.to_string());
|
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
|
match arg {
|
||||||
|
GenericArgument::Type(t) => {
|
||||||
|
pushed = true;
|
||||||
|
res.push_str(&to_string(t));
|
||||||
|
}
|
||||||
|
GenericArgument::Const(c) => {
|
||||||
|
pushed = true;
|
||||||
|
res.push_str("e! { #c }.to_string());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
res.push_str(">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
let found_crate = crate_name("esp-lp-hal").expect("esp-lp-hal is present in `Cargo.toml`");
|
||||||
|
let hal_crate = match found_crate {
|
||||||
|
FoundCrate::Itself => quote!(esp_lp_hal),
|
||||||
|
FoundCrate::Name(name) => {
|
||||||
|
let ident = Ident::new(&name, Span::call_site());
|
||||||
|
quote!( #ident )
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !args.is_empty() {
|
||||||
|
return Error::new(Span::call_site(), "This attribute accepts no arguments")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let f = parse_macro_input!(input as ItemFn);
|
||||||
|
|
||||||
|
let mut argument_types = Vec::new();
|
||||||
|
let mut create_peripheral = Vec::new();
|
||||||
|
|
||||||
|
let mut used_pins: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
|
for (num, arg) in f.sig.inputs.iter().enumerate() {
|
||||||
|
let param_name = format_ident!("param{}", num);
|
||||||
|
match arg {
|
||||||
|
FnArg::Receiver(_) => {
|
||||||
|
return Error::new(arg.span(), "invalid argument")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
FnArg::Typed(t) => {
|
||||||
|
match get_simplename(&t.ty).as_str() {
|
||||||
|
"Output" => {
|
||||||
|
let pin = extract_pin(&t.ty);
|
||||||
|
if used_pins.contains(&pin) {
|
||||||
|
return Error::new(arg.span(), "duplicate pin")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
used_pins.push(pin);
|
||||||
|
create_peripheral.push(quote!(
|
||||||
|
let mut #param_name = unsafe { the_hal::gpio::conjure_output().unwrap() };
|
||||||
|
));
|
||||||
|
}
|
||||||
|
"Input" => {
|
||||||
|
let pin = extract_pin(&t.ty);
|
||||||
|
if used_pins.contains(&pin) {
|
||||||
|
return Error::new(arg.span(), "duplicate pin")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
used_pins.push(pin);
|
||||||
|
create_peripheral.push(quote!(
|
||||||
|
let mut #param_name = unsafe { the_hal::gpio::conjure_input().unwrap() };
|
||||||
|
));
|
||||||
|
}
|
||||||
|
"LpUart" => {
|
||||||
|
create_peripheral.push(quote!(
|
||||||
|
let mut #param_name = unsafe { the_hal::uart::conjure() };
|
||||||
|
));
|
||||||
|
}
|
||||||
|
"LpI2c" => {
|
||||||
|
create_peripheral.push(quote!(
|
||||||
|
let mut #param_name = unsafe { the_hal::i2c::conjure() };
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Error::new(arg.span(), "invalid argument to main")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argument_types.push(t);
|
||||||
}
|
}
|
||||||
res.push_str(">");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
let magic_symbol_name = make_magic_symbol_name(&argument_types);
|
||||||
|
|
||||||
|
let param_names: Vec<Ident> = argument_types
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(num, _)| format_ident!("param{}", num))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
quote!(
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[export_name = "main"]
|
||||||
|
pub fn __risc_v_rt__main() -> ! {
|
||||||
|
#[export_name = #magic_symbol_name]
|
||||||
|
static ULP_MAGIC: [u32; 0] = [0u32; 0];
|
||||||
|
|
||||||
|
unsafe { ULP_MAGIC.as_ptr().read_volatile(); }
|
||||||
|
|
||||||
|
use #hal_crate as the_hal;
|
||||||
|
#(
|
||||||
|
#create_peripheral;
|
||||||
|
)*
|
||||||
|
|
||||||
|
main(#(#param_names),*);
|
||||||
|
}
|
||||||
|
|
||||||
|
#f
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "has-lp-core", feature = "has-ulp-core"))]
|
||||||
|
pub fn load_lp_code(input: TokenStream) -> TokenStream {
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
|
use litrs::StringLit;
|
||||||
|
use object::{File, Object, ObjectSection, ObjectSymbol, Section, SectionKind};
|
||||||
|
use parse::Error;
|
||||||
|
use proc_macro::Span;
|
||||||
|
use proc_macro_crate::{crate_name, FoundCrate};
|
||||||
|
use syn::{parse, Ident};
|
||||||
|
|
||||||
|
let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) {
|
||||||
|
crate_name("esp-lp-hal")
|
||||||
|
} else {
|
||||||
|
crate_name("esp-hal")
|
||||||
|
};
|
||||||
|
|
||||||
|
let hal_crate = if let Ok(FoundCrate::Name(ref name)) = hal_crate {
|
||||||
|
let ident = Ident::new(&name, Span::call_site().into());
|
||||||
|
quote!( #ident )
|
||||||
|
} else {
|
||||||
|
quote!(crate)
|
||||||
|
};
|
||||||
|
|
||||||
|
let first_token = match input.into_iter().next() {
|
||||||
|
Some(token) => token,
|
||||||
|
None => {
|
||||||
|
return Error::new(
|
||||||
|
Span::call_site().into(),
|
||||||
|
"You need to give the path to an ELF file",
|
||||||
|
)
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let arg = match StringLit::try_from(&first_token) {
|
||||||
|
Ok(arg) => arg,
|
||||||
|
Err(_) => {
|
||||||
|
return Error::new(
|
||||||
|
Span::call_site().into(),
|
||||||
|
"You need to give the path to an ELF file",
|
||||||
|
)
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let elf_file = arg.value();
|
||||||
|
|
||||||
|
if !Path::new(elf_file).exists() {
|
||||||
|
return Error::new(Span::call_site().into(), "File not found")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let bin_data = fs::read(elf_file).unwrap();
|
||||||
|
let obj_file = File::parse(&*bin_data).unwrap();
|
||||||
|
let sections = obj_file.sections();
|
||||||
|
|
||||||
|
let mut sections: Vec<Section> = sections
|
||||||
|
.into_iter()
|
||||||
|
.filter(|section| match section.kind() {
|
||||||
|
SectionKind::Text
|
||||||
|
| SectionKind::ReadOnlyData
|
||||||
|
| SectionKind::Data
|
||||||
|
| SectionKind::UninitializedData => true,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
sections.sort_by(|a, b| a.address().partial_cmp(&b.address()).unwrap());
|
||||||
|
|
||||||
|
let mut binary: Vec<u8> = Vec::new();
|
||||||
|
let mut last_address = if cfg!(feature = "has-lp-core") {
|
||||||
|
0x5000_0000
|
||||||
|
} else {
|
||||||
|
0x0
|
||||||
|
};
|
||||||
|
|
||||||
|
for section in sections {
|
||||||
|
if section.address() > last_address {
|
||||||
|
for _ in 0..(section.address() - last_address) {
|
||||||
|
binary.push(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.extend_from_slice(section.data().unwrap());
|
||||||
|
last_address = section.address() + section.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
let magic_symbol = obj_file
|
||||||
|
.symbols()
|
||||||
|
.find(|s| s.name().unwrap().starts_with("__ULP_MAGIC_"));
|
||||||
|
|
||||||
|
if let None = magic_symbol {
|
||||||
|
return Error::new(
|
||||||
|
Span::call_site().into(),
|
||||||
|
"Given file doesn't seem to be an LP/ULP core application.",
|
||||||
|
)
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let magic_symbol = magic_symbol.unwrap().name().unwrap();
|
||||||
|
|
||||||
|
let magic_symbol = magic_symbol.trim_start_matches("__ULP_MAGIC_");
|
||||||
|
let args: Vec<proc_macro2::TokenStream> = magic_symbol
|
||||||
|
.split("$")
|
||||||
|
.into_iter()
|
||||||
|
.map(|t| {
|
||||||
|
let t = if t.contains("OutputOpenDrain") {
|
||||||
|
t.replace("OutputOpenDrain", "LowPowerOutputOpenDrain")
|
||||||
|
} else {
|
||||||
|
t.replace("Output", "LowPowerOutput")
|
||||||
|
};
|
||||||
|
let t = t.replace("Input", "LowPowerInput");
|
||||||
|
t.parse().unwrap()
|
||||||
|
})
|
||||||
|
.filter(|v: &proc_macro2::TokenStream| !v.is_empty())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
#[cfg(feature = "has-lp-core")]
|
||||||
|
let imports = quote! {
|
||||||
|
use #hal_crate::lp_core::LpCore;
|
||||||
|
use #hal_crate::lp_core::LpCoreWakeupSource;
|
||||||
|
use #hal_crate::gpio::lp_io::LowPowerOutput;
|
||||||
|
use #hal_crate::gpio::*;
|
||||||
|
use #hal_crate::uart::lp_uart::LpUart;
|
||||||
|
use #hal_crate::i2c::lp_i2c::LpI2c;
|
||||||
|
};
|
||||||
|
#[cfg(feature = "has-ulp-core")]
|
||||||
|
let imports = quote! {
|
||||||
|
use #hal_crate::ulp_core::UlpCore as LpCore;
|
||||||
|
use #hal_crate::ulp_core::UlpCoreWakeupSource as LpCoreWakeupSource;
|
||||||
|
use #hal_crate::gpio::*;
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "has-lp-core")]
|
||||||
|
let rtc_code_start = quote! { _rtc_fast_data_start };
|
||||||
|
#[cfg(feature = "has-ulp-core")]
|
||||||
|
let rtc_code_start = quote! { _rtc_slow_data_start };
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
{
|
||||||
|
#imports
|
||||||
|
|
||||||
|
struct LpCoreCode {}
|
||||||
|
|
||||||
|
static LP_CODE: &[u8] = &[#(#binary),*];
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static #rtc_code_start: u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping(LP_CODE as *const _ as *const u8, &#rtc_code_start as *const u32 as *mut u8, LP_CODE.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LpCoreCode {
|
||||||
|
pub fn run(
|
||||||
|
&self,
|
||||||
|
lp_core: &mut LpCore,
|
||||||
|
wakeup_source: LpCoreWakeupSource,
|
||||||
|
#(_: #args),*
|
||||||
|
) {
|
||||||
|
lp_core.run(wakeup_source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LpCoreCode {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Removed the `embassy-executor-thread` and `embassy-executor-interrupt` features, they are now enabled by default when `embassy` is enabled. (#1485)
|
- Removed the `embassy-executor-thread` and `embassy-executor-interrupt` features, they are now enabled by default when `embassy` is enabled. (#1485)
|
||||||
- Software interrupt 3 is now used instead of software interrupt 0 on the thread aware executor on multicore systems (#1485)
|
- Software interrupt 3 is now used instead of software interrupt 0 on the thread aware executor on multicore systems (#1485)
|
||||||
- Timer abstraction: refactor `systimer` and `timer` modules into a common `timer` module (#1527)
|
- Timer abstraction: refactor `systimer` and `timer` modules into a common `timer` module (#1527)
|
||||||
|
- Refactoring of GPIO module, have drivers for Input,Output,OutputOpenDrain, all drivers setup their GPIOs correctly (#1542)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ bitfield = "0.15.0"
|
|||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
critical-section = "1.1.2"
|
critical-section = "1.1.2"
|
||||||
defmt = { version = "0.3.6", optional = true }
|
defmt = { version = "0.3.6", optional = true }
|
||||||
|
delegate = "0.12.0"
|
||||||
document-features = "0.2.8"
|
document-features = "0.2.8"
|
||||||
embassy-executor = { version = "0.5.0", optional = true }
|
embassy-executor = { version = "0.5.0", optional = true }
|
||||||
embassy-futures = { version = "0.1.1", optional = true }
|
embassy-futures = { version = "0.1.1", optional = true }
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let mut adc1_config = AdcConfig::new();
|
//! let mut adc1_config = AdcConfig::new();
|
||||||
//! let mut adc1 = ADC::<ADC1>::new(peripherals.ADC1, adc1_config);
|
//! let mut adc1 = ADC::<ADC1>::new(peripherals.ADC1, adc1_config);
|
||||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2, Attenuation::Attenuation11dB);
|
||||||
//!
|
//!
|
||||||
//! let mut delay = Delay::new(&clocks);
|
//! let mut delay = Delay::new(&clocks);
|
||||||
//!
|
//!
|
||||||
@ -24,6 +24,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
pub use self::implementation::*;
|
pub use self::implementation::*;
|
||||||
|
use crate::gpio::AnalogPin;
|
||||||
|
|
||||||
#[cfg_attr(esp32, path = "esp32.rs")]
|
#[cfg_attr(esp32, path = "esp32.rs")]
|
||||||
#[cfg_attr(riscv, path = "riscv.rs")]
|
#[cfg_attr(riscv, path = "riscv.rs")]
|
||||||
@ -93,8 +94,10 @@ impl<ADCI> AdcConfig<ADCI> {
|
|||||||
/// Enable the specified pin with the given attenuation
|
/// Enable the specified pin with the given attenuation
|
||||||
pub fn enable_pin<PIN>(&mut self, pin: PIN, attenuation: Attenuation) -> AdcPin<PIN, ADCI>
|
pub fn enable_pin<PIN>(&mut self, pin: PIN, attenuation: Attenuation) -> AdcPin<PIN, ADCI>
|
||||||
where
|
where
|
||||||
PIN: AdcChannel,
|
PIN: AdcChannel + AnalogPin,
|
||||||
{
|
{
|
||||||
|
// TODO revert this on drop
|
||||||
|
pin.set_analog(crate::private::Internal);
|
||||||
self.attenuations[PIN::CHANNEL as usize] = Some(attenuation);
|
self.attenuations[PIN::CHANNEL as usize] = Some(attenuation);
|
||||||
|
|
||||||
AdcPin {
|
AdcPin {
|
||||||
@ -104,7 +107,7 @@ impl<ADCI> AdcConfig<ADCI> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable the specified pin with the given attentuation and calibration
|
/// Enable the specified pin with the given attenuation and calibration
|
||||||
/// scheme
|
/// scheme
|
||||||
#[cfg(not(esp32))]
|
#[cfg(not(esp32))]
|
||||||
pub fn enable_pin_with_cal<PIN, CS>(
|
pub fn enable_pin_with_cal<PIN, CS>(
|
||||||
@ -114,9 +117,11 @@ impl<ADCI> AdcConfig<ADCI> {
|
|||||||
) -> AdcPin<PIN, ADCI, CS>
|
) -> AdcPin<PIN, ADCI, CS>
|
||||||
where
|
where
|
||||||
ADCI: CalibrationAccess,
|
ADCI: CalibrationAccess,
|
||||||
PIN: AdcChannel,
|
PIN: AdcChannel + AnalogPin,
|
||||||
CS: AdcCalScheme<ADCI>,
|
CS: AdcCalScheme<ADCI>,
|
||||||
{
|
{
|
||||||
|
// TODO revert this on drop
|
||||||
|
pin.set_analog(crate::private::Internal);
|
||||||
self.attenuations[PIN::CHANNEL as usize] = Some(attenuation);
|
self.attenuations[PIN::CHANNEL as usize] = Some(attenuation);
|
||||||
|
|
||||||
AdcPin {
|
AdcPin {
|
||||||
@ -206,12 +211,12 @@ macro_rules! impl_adc_interface {
|
|||||||
$( ($pin:ident, $channel:expr) ,)+
|
$( ($pin:ident, $channel:expr) ,)+
|
||||||
]) => {
|
]) => {
|
||||||
$(
|
$(
|
||||||
impl $crate::analog::adc::AdcChannel for crate::gpio::$pin<crate::gpio::Analog> {
|
impl $crate::analog::adc::AdcChannel for crate::gpio::$pin {
|
||||||
const CHANNEL: u8 = $channel;
|
const CHANNEL: u8 = $channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl embedded_hal_02::adc::Channel<crate::peripherals::$adc> for crate::gpio::$pin<crate::gpio::Analog> {
|
impl embedded_hal_02::adc::Channel<crate::peripherals::$adc> for crate::gpio::$pin {
|
||||||
type ID = u8;
|
type ID = u8;
|
||||||
|
|
||||||
fn channel() -> u8 { $channel }
|
fn channel() -> u8 { $channel }
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//! let gpio25 = io.pins.gpio25.into_analog();
|
//! let gpio25 = io.pins.gpio25;
|
||||||
//! let gpio26 = io.pins.gpio26.into_analog();
|
//! let gpio26 = io.pins.gpio26;
|
||||||
//!
|
//!
|
||||||
//! let mut dac1 = Dac1::new(peripherals.DAC1, gpio25);
|
//! let mut dac1 = Dac1::new(peripherals.DAC1, gpio25);
|
||||||
//! let mut dac2 = Dac2::new(peripherals.DAC2, gpio26);
|
//! let mut dac2 = Dac2::new(peripherals.DAC2, gpio26);
|
||||||
@ -37,18 +37,18 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gpio,
|
gpio::{self, AnalogPin},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals,
|
peripherals,
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(esp32)] {
|
if #[cfg(esp32)] {
|
||||||
type Dac1Gpio = gpio::Gpio25<gpio::Analog>;
|
type Dac1Gpio = gpio::Gpio25;
|
||||||
type Dac2Gpio = gpio::Gpio26<gpio::Analog>;
|
type Dac2Gpio = gpio::Gpio26;
|
||||||
} else if #[cfg(esp32s2)] {
|
} else if #[cfg(esp32s2)] {
|
||||||
type Dac1Gpio = gpio::Gpio17<gpio::Analog>;
|
type Dac1Gpio = gpio::Gpio17;
|
||||||
type Dac2Gpio = gpio::Gpio18<gpio::Analog>;
|
type Dac2Gpio = gpio::Gpio18;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +59,10 @@ pub struct Dac1<'d> {
|
|||||||
|
|
||||||
impl<'d> Dac1<'d> {
|
impl<'d> Dac1<'d> {
|
||||||
/// Constructs a new DAC instance.
|
/// Constructs a new DAC instance.
|
||||||
pub fn new(dac: impl Peripheral<P = peripherals::DAC1> + 'd, _pin: Dac1Gpio) -> Self {
|
pub fn new(dac: impl Peripheral<P = peripherals::DAC1> + 'd, pin: Dac1Gpio) -> Self {
|
||||||
crate::into_ref!(dac);
|
crate::into_ref!(dac);
|
||||||
|
// TODO revert this on drop
|
||||||
|
pin.set_analog(crate::private::Internal);
|
||||||
|
|
||||||
#[cfg(esp32s2)]
|
#[cfg(esp32s2)]
|
||||||
unsafe { &*peripherals::SENS::PTR }
|
unsafe { &*peripherals::SENS::PTR }
|
||||||
@ -96,8 +98,10 @@ pub struct Dac2<'d> {
|
|||||||
|
|
||||||
impl<'d> Dac2<'d> {
|
impl<'d> Dac2<'d> {
|
||||||
/// Constructs a new DAC instance.
|
/// Constructs a new DAC instance.
|
||||||
pub fn new(dac: impl Peripheral<P = peripherals::DAC2> + 'd, _pin: Dac2Gpio) -> Self {
|
pub fn new(dac: impl Peripheral<P = peripherals::DAC2> + 'd, pin: Dac2Gpio) -> Self {
|
||||||
crate::into_ref!(dac);
|
crate::into_ref!(dac);
|
||||||
|
// TODO revert this on drop
|
||||||
|
pin.set_analog(crate::private::Internal);
|
||||||
|
|
||||||
#[cfg(esp32s2)]
|
#[cfg(esp32s2)]
|
||||||
unsafe { &*peripherals::SENS::PTR }
|
unsafe { &*peripherals::SENS::PTR }
|
||||||
|
286
esp-hal/src/gpio/any_pin.rs
Normal file
286
esp-hal/src/gpio/any_pin.rs
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
//! Type-erased wrappers for GPIO pins.
|
||||||
|
//! These are useful to pass them into peripheral drivers.
|
||||||
|
//!
|
||||||
|
//! If you want a generic pin for GPIO input/output look into
|
||||||
|
//! [Output],[OutputOpenDrain] and [Input]
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum Inverted {
|
||||||
|
NonInverted,
|
||||||
|
Inverted,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Inverted {
|
||||||
|
fn is_inverted(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Inverted::NonInverted => false,
|
||||||
|
Inverted::Inverted => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic pin wrapper for pins which can be Output or Input.
|
||||||
|
pub struct AnyPin<'d> {
|
||||||
|
pin: ErasedPin,
|
||||||
|
inverted: Inverted,
|
||||||
|
_phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> AnyPin<'d> {
|
||||||
|
/// Create wrapper for the given pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn new<P: OutputPin + InputPin + CreateErasedPin>(
|
||||||
|
pin: impl crate::peripheral::Peripheral<P = P> + 'd,
|
||||||
|
) -> Self {
|
||||||
|
crate::into_ref!(pin);
|
||||||
|
let pin = pin.erased_pin(private::Internal);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pin,
|
||||||
|
inverted: Inverted::NonInverted,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create wrapper for the given pin. The peripheral signal will be
|
||||||
|
/// inverted.
|
||||||
|
#[inline]
|
||||||
|
pub fn new_inverted<P: OutputPin + InputPin + CreateErasedPin>(
|
||||||
|
pin: impl crate::peripheral::Peripheral<P = P> + 'd,
|
||||||
|
) -> Self {
|
||||||
|
crate::into_ref!(pin);
|
||||||
|
let pin = pin.erased_pin(private::Internal);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pin,
|
||||||
|
inverted: Inverted::Inverted,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> crate::peripheral::Peripheral for AnyPin<'d> {
|
||||||
|
type P = Self;
|
||||||
|
|
||||||
|
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||||
|
Self {
|
||||||
|
pin: unsafe { self.pin.clone_unchecked() },
|
||||||
|
inverted: self.inverted,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> private::Sealed for AnyPin<'d> {}
|
||||||
|
|
||||||
|
impl<'d> Pin for AnyPin<'d> {
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.pin {
|
||||||
|
fn number(&self, _internal: private::Internal) -> u8;
|
||||||
|
fn sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal);
|
||||||
|
fn is_listening(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn listen_with_options(
|
||||||
|
&mut self,
|
||||||
|
event: Event,
|
||||||
|
int_enable: bool,
|
||||||
|
nmi_enable: bool,
|
||||||
|
wake_up_from_light_sleep: bool,
|
||||||
|
_internal: private::Internal,
|
||||||
|
);
|
||||||
|
fn unlisten(&mut self, _internal: private::Internal);
|
||||||
|
fn is_interrupt_set(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn clear_interrupt(&mut self, _internal: private::Internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> OutputPin for AnyPin<'d> {
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.pin {
|
||||||
|
fn set_to_open_drain_output(&mut self, _internal: private::Internal);
|
||||||
|
fn set_to_push_pull_output(&mut self, _internal: private::Internal);
|
||||||
|
fn enable_output(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn set_output_high(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn set_drive_strength(&mut self, strength: DriveStrength, _internal: private::Internal);
|
||||||
|
fn enable_open_drain(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn internal_pull_up(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn internal_pull_down(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn disconnect_peripheral_from_output(&mut self, _internal: private::Internal);
|
||||||
|
fn is_set_high(&self, _internal: private::Internal) -> bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _internal: private::Internal) {
|
||||||
|
self.pin.connect_peripheral_to_output_with_options(
|
||||||
|
signal,
|
||||||
|
self.inverted.is_inverted(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
self.inverted.is_inverted(),
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_peripheral_to_output_with_options(
|
||||||
|
&mut self,
|
||||||
|
signal: OutputSignal,
|
||||||
|
invert: bool,
|
||||||
|
invert_enable: bool,
|
||||||
|
enable_from_gpio: bool,
|
||||||
|
force_via_gpio_mux: bool,
|
||||||
|
_internal: private::Internal,
|
||||||
|
) {
|
||||||
|
if self.inverted.is_inverted() {
|
||||||
|
self.pin.connect_peripheral_to_output_with_options(
|
||||||
|
signal,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.pin.connect_peripheral_to_output_with_options(
|
||||||
|
signal,
|
||||||
|
invert,
|
||||||
|
invert_enable,
|
||||||
|
enable_from_gpio,
|
||||||
|
force_via_gpio_mux,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> InputPin for AnyPin<'d> {
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.pin {
|
||||||
|
fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal);
|
||||||
|
fn set_to_input(&mut self, _internal: private::Internal);
|
||||||
|
fn enable_input(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _internal: private::Internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_input_to_peripheral(&mut self, signal: InputSignal, _internal: private::Internal) {
|
||||||
|
self.pin.connect_input_to_peripheral_with_options(
|
||||||
|
signal,
|
||||||
|
self.inverted.is_inverted(),
|
||||||
|
self.inverted.is_inverted(),
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_input_to_peripheral_with_options(
|
||||||
|
&mut self,
|
||||||
|
signal: InputSignal,
|
||||||
|
invert: bool,
|
||||||
|
force_via_gpio_mux: bool,
|
||||||
|
_internal: private::Internal,
|
||||||
|
) {
|
||||||
|
if self.inverted.is_inverted() {
|
||||||
|
self.pin.connect_input_to_peripheral_with_options(
|
||||||
|
signal,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.pin.connect_input_to_peripheral_with_options(
|
||||||
|
signal,
|
||||||
|
invert,
|
||||||
|
force_via_gpio_mux,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic pin wrapper for pins which can only be Input.
|
||||||
|
pub struct AnyInputOnlyPin<'d> {
|
||||||
|
pin: ErasedPin,
|
||||||
|
inverted: Inverted,
|
||||||
|
_phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> AnyInputOnlyPin<'d> {
|
||||||
|
/// Create wrapper for the given pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn new<P: InputPin + CreateErasedPin>(
|
||||||
|
pin: impl crate::peripheral::Peripheral<P = P> + 'd,
|
||||||
|
) -> Self {
|
||||||
|
crate::into_ref!(pin);
|
||||||
|
let pin = pin.erased_pin(private::Internal);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pin,
|
||||||
|
inverted: Inverted::NonInverted,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> crate::peripheral::Peripheral for AnyInputOnlyPin<'d> {
|
||||||
|
type P = Self;
|
||||||
|
|
||||||
|
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||||
|
Self {
|
||||||
|
pin: unsafe { self.pin.clone_unchecked() },
|
||||||
|
inverted: self.inverted,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> private::Sealed for AnyInputOnlyPin<'d> {}
|
||||||
|
|
||||||
|
impl<'d> Pin for AnyInputOnlyPin<'d> {
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.pin {
|
||||||
|
fn number(&self, _internal: private::Internal) -> u8;
|
||||||
|
fn sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal);
|
||||||
|
fn is_listening(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn listen_with_options(
|
||||||
|
&mut self,
|
||||||
|
event: Event,
|
||||||
|
int_enable: bool,
|
||||||
|
nmi_enable: bool,
|
||||||
|
wake_up_from_light_sleep: bool,
|
||||||
|
_internal: private::Internal,
|
||||||
|
);
|
||||||
|
fn unlisten(&mut self, _internal: private::Internal);
|
||||||
|
fn is_interrupt_set(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn clear_interrupt(&mut self, _internal: private::Internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> InputPin for AnyInputOnlyPin<'d> {
|
||||||
|
delegate::delegate! {
|
||||||
|
to self.pin {
|
||||||
|
fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal);
|
||||||
|
fn set_to_input(&mut self, _internal: private::Internal);
|
||||||
|
fn enable_input(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||||
|
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||||
|
fn connect_input_to_peripheral(&mut self, signal: InputSignal, _internal: private::Internal);
|
||||||
|
fn connect_input_to_peripheral_with_options(
|
||||||
|
&mut self,
|
||||||
|
signal: InputSignal,
|
||||||
|
invert: bool,
|
||||||
|
force_via_gpio_mux: bool,
|
||||||
|
_internal: private::Internal,
|
||||||
|
);
|
||||||
|
fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _internal: private::Internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,11 +23,24 @@
|
|||||||
//!
|
//!
|
||||||
//! ## Example
|
//! ## Example
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
//! let led_task = gpio_ext.channel0_task.toggle(
|
||||||
//! let button_event = gpio_ext.channel0_event.falling_edge(button);
|
//! &mut led,
|
||||||
|
//! GpioEtmOutputConfig {
|
||||||
|
//! open_drain: false,
|
||||||
|
//! pull: Pull::None,
|
||||||
|
//! initial_state: false,
|
||||||
|
//! },
|
||||||
|
//! );
|
||||||
|
//! let button_event = gpio_ext
|
||||||
|
//! .channel0_event
|
||||||
|
//! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
use crate::{
|
||||||
|
gpio::Pull,
|
||||||
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
private,
|
||||||
|
};
|
||||||
|
|
||||||
/// All the GPIO ETM channels
|
/// All the GPIO ETM channels
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
@ -79,6 +92,20 @@ impl<'d> GpioEtmChannels<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configuration for an ETM controlled GPIO input pin
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct GpioEtmInputConfig {
|
||||||
|
/// Configuration for the internal pull-up resistors
|
||||||
|
pub pull: Pull,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GpioEtmInputConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { pull: Pull::None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An ETM controlled GPIO event
|
/// An ETM controlled GPIO event
|
||||||
pub struct GpioEtmEventChannel<const C: u8> {}
|
pub struct GpioEtmEventChannel<const C: u8> {}
|
||||||
|
|
||||||
@ -87,12 +114,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
|||||||
pub fn rising_edge<'d, PIN>(
|
pub fn rising_edge<'d, PIN>(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = PIN> + 'd,
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmInputConfig,
|
||||||
) -> GpioEtmEventChannelRising<'d, PIN, C>
|
) -> GpioEtmEventChannelRising<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::InputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_event_channel(C, pin.number());
|
|
||||||
|
pin.init_input(
|
||||||
|
pin_config.pull == Pull::Down,
|
||||||
|
pin_config.pull == Pull::Up,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
|
enable_event_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmEventChannelRising { _pin: pin }
|
GpioEtmEventChannelRising { _pin: pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,12 +135,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
|||||||
pub fn falling_edge<'d, PIN>(
|
pub fn falling_edge<'d, PIN>(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = PIN> + 'd,
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmInputConfig,
|
||||||
) -> GpioEtmEventChannelFalling<'d, PIN, C>
|
) -> GpioEtmEventChannelFalling<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::InputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_event_channel(C, pin.number());
|
|
||||||
|
pin.init_input(
|
||||||
|
pin_config.pull == Pull::Down,
|
||||||
|
pin_config.pull == Pull::Up,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
|
enable_event_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmEventChannelFalling { _pin: pin }
|
GpioEtmEventChannelFalling { _pin: pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,12 +156,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
|||||||
pub fn any_edge<'d, PIN>(
|
pub fn any_edge<'d, PIN>(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = PIN> + 'd,
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmInputConfig,
|
||||||
) -> GpioEtmEventChannelAny<'d, PIN, C>
|
) -> GpioEtmEventChannelAny<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::InputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_event_channel(C, pin.number());
|
|
||||||
|
pin.init_input(
|
||||||
|
pin_config.pull == Pull::Down,
|
||||||
|
pin_config.pull == Pull::Up,
|
||||||
|
private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
|
enable_event_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmEventChannelAny { _pin: pin }
|
GpioEtmEventChannelAny { _pin: pin }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,7 +183,7 @@ where
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmEventChannelRising<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmEventChannelRising<'d, PIN, C> where
|
||||||
PIN: super::Pin
|
PIN: super::Pin
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -155,7 +206,7 @@ where
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmEventChannelFalling<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmEventChannelFalling<'d, PIN, C> where
|
||||||
PIN: super::Pin
|
PIN: super::Pin
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -178,7 +229,7 @@ where
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmEventChannelAny<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmEventChannelAny<'d, PIN, C> where
|
||||||
PIN: super::Pin
|
PIN: super::Pin
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -192,6 +243,28 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configuration for an ETM controlled GPIO output pin
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct GpioEtmOutputConfig {
|
||||||
|
/// Set to open-drain output
|
||||||
|
pub open_drain: bool,
|
||||||
|
/// Only used when open-drain
|
||||||
|
pub pull: Pull,
|
||||||
|
/// Initial pin state
|
||||||
|
pub initial_state: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GpioEtmOutputConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
open_drain: false,
|
||||||
|
pull: Pull::None,
|
||||||
|
initial_state: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An ETM controlled GPIO task
|
/// An ETM controlled GPIO task
|
||||||
pub struct GpioEtmTaskChannel<const C: u8> {}
|
pub struct GpioEtmTaskChannel<const C: u8> {}
|
||||||
|
|
||||||
@ -202,22 +275,50 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
|||||||
// number is the pin-count
|
// number is the pin-count
|
||||||
|
|
||||||
/// Task to set a high level
|
/// Task to set a high level
|
||||||
pub fn set<'d, PIN>(self, pin: impl Peripheral<P = PIN> + 'd) -> GpioEtmTaskSet<'d, PIN, C>
|
pub fn set<'d, PIN>(
|
||||||
|
self,
|
||||||
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmOutputConfig,
|
||||||
|
) -> GpioEtmTaskSet<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::OutputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_task_channel(C, pin.number());
|
|
||||||
|
pin.set_output_high(pin_config.initial_state, private::Internal);
|
||||||
|
if pin_config.open_drain {
|
||||||
|
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||||
|
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||||
|
pin.set_to_open_drain_output(private::Internal);
|
||||||
|
} else {
|
||||||
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_task_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmTaskSet { _pin: pin }
|
GpioEtmTaskSet { _pin: pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Task to set a low level
|
/// Task to set a low level
|
||||||
pub fn clear<'d, PIN>(self, pin: impl Peripheral<P = PIN> + 'd) -> GpioEtmTaskClear<'d, PIN, C>
|
pub fn clear<'d, PIN>(
|
||||||
|
self,
|
||||||
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmOutputConfig,
|
||||||
|
) -> GpioEtmTaskClear<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::OutputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_task_channel(C, pin.number());
|
|
||||||
|
pin.set_output_high(pin_config.initial_state, private::Internal);
|
||||||
|
if pin_config.open_drain {
|
||||||
|
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||||
|
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||||
|
pin.set_to_open_drain_output(private::Internal);
|
||||||
|
} else {
|
||||||
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_task_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmTaskClear { _pin: pin }
|
GpioEtmTaskClear { _pin: pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,12 +326,23 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
|||||||
pub fn toggle<'d, PIN>(
|
pub fn toggle<'d, PIN>(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = PIN> + 'd,
|
pin: impl Peripheral<P = PIN> + 'd,
|
||||||
|
pin_config: GpioEtmOutputConfig,
|
||||||
) -> GpioEtmTaskToggle<'d, PIN, C>
|
) -> GpioEtmTaskToggle<'d, PIN, C>
|
||||||
where
|
where
|
||||||
PIN: super::Pin,
|
PIN: super::OutputPin,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
enable_task_channel(C, pin.number());
|
|
||||||
|
pin.set_output_high(pin_config.initial_state, private::Internal);
|
||||||
|
if pin_config.open_drain {
|
||||||
|
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||||
|
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||||
|
pin.set_to_open_drain_output(private::Internal);
|
||||||
|
} else {
|
||||||
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_task_channel(C, pin.number(private::Internal));
|
||||||
GpioEtmTaskToggle { _pin: pin }
|
GpioEtmTaskToggle { _pin: pin }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,10 +356,7 @@ where
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskSet<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskSet<'d, PIN, C> where PIN: super::Pin {}
|
||||||
PIN: super::Pin
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskSet<'d, PIN, C>
|
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskSet<'d, PIN, C>
|
||||||
where
|
where
|
||||||
@ -264,10 +373,7 @@ pub struct GpioEtmTaskClear<'d, PIN, const C: u8> {
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskClear<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskClear<'d, PIN, C> where PIN: super::Pin {}
|
||||||
PIN: super::Pin
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskClear<'d, PIN, C>
|
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskClear<'d, PIN, C>
|
||||||
where
|
where
|
||||||
@ -284,10 +390,7 @@ pub struct GpioEtmTaskToggle<'d, PIN, const C: u8> {
|
|||||||
_pin: PeripheralRef<'d, PIN>,
|
_pin: PeripheralRef<'d, PIN>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskToggle<'d, PIN, C> where
|
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskToggle<'d, PIN, C> where PIN: super::Pin {}
|
||||||
PIN: super::Pin
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskToggle<'d, PIN, C>
|
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskToggle<'d, PIN, C>
|
||||||
where
|
where
|
||||||
|
@ -17,23 +17,111 @@
|
|||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//! // configure GPIO 1 as LP output pin
|
//! // configure GPIO 1 as LP output pin
|
||||||
//! let lp_pin = io.pins.gpio1.into_low_power().into_push_pull_output();
|
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[cfg(esp32c6)]
|
/// A GPIO output pin configured for low power operation
|
||||||
use super::OpenDrain;
|
pub struct LowPowerOutput<'d, const PIN: u8> {
|
||||||
use super::{Floating, Input, Output, PullDown, PullUp, PushPull, Unknown};
|
phantom: PhantomData<&'d ()>,
|
||||||
|
|
||||||
/// A GPIO pin configured for low power operation
|
|
||||||
pub struct LowPowerPin<MODE, const PIN: u8> {
|
|
||||||
pub(crate) private: PhantomData<MODE>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MODE, const PIN: u8> LowPowerPin<MODE, PIN> {
|
impl<'d, const PIN: u8> LowPowerOutput<'d, PIN> {
|
||||||
#[doc(hidden)]
|
/// Create a new output pin for use by the low-power core
|
||||||
pub fn output_enable(&self, enable: bool) {
|
pub fn new<P>(_pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
|
where
|
||||||
|
P: super::OutputPin + RtcPin,
|
||||||
|
{
|
||||||
|
crate::gpio::lp_io::init_low_power_pin(PIN);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
this.output_enable(true);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_enable(&self, enable: bool) {
|
||||||
|
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
||||||
|
if enable {
|
||||||
|
lp_io
|
||||||
|
.out_enable_w1ts()
|
||||||
|
.write(|w| unsafe { w.enable_w1ts().bits(1 << PIN) });
|
||||||
|
} else {
|
||||||
|
lp_io
|
||||||
|
.out_enable_w1tc()
|
||||||
|
.write(|w| unsafe { w.enable_w1tc().bits(1 << PIN) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A GPIO input pin configured for low power operation
|
||||||
|
pub struct LowPowerInput<'d, const PIN: u8> {
|
||||||
|
phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, const PIN: u8> LowPowerInput<'d, PIN> {
|
||||||
|
/// Create a new input pin for use by the low-power core
|
||||||
|
pub fn new<P>(_pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
|
where
|
||||||
|
P: super::InputPin + RtcPin,
|
||||||
|
{
|
||||||
|
crate::gpio::lp_io::init_low_power_pin(PIN);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
this.input_enable(true);
|
||||||
|
this.pullup_enable(false);
|
||||||
|
this.pulldown_enable(false);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pull-up enable for the pin
|
||||||
|
pub fn pullup_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.fun_wpu().bit(enable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pull-down enable for the pin
|
||||||
|
pub fn pulldown_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.fun_wpd().bit(enable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A GPIO open-drain output pin configured for low power operation
|
||||||
|
pub struct LowPowerOutputOpenDrain<'d, const PIN: u8> {
|
||||||
|
phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
|
||||||
|
/// Create a new output pin for use by the low-power core
|
||||||
|
pub fn new<P>(_pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
|
where
|
||||||
|
P: super::InputPin + super::OutputPin + RtcPin,
|
||||||
|
{
|
||||||
|
crate::gpio::lp_io::init_low_power_pin(PIN);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.set_open_drain_output(true);
|
||||||
|
this.input_enable(true);
|
||||||
|
this.pullup_enable(true);
|
||||||
|
this.pulldown_enable(false);
|
||||||
|
this.output_enable(true);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_enable(&self, enable: bool) {
|
||||||
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
||||||
if enable {
|
if enable {
|
||||||
lp_io
|
lp_io
|
||||||
@ -50,88 +138,22 @@ impl<MODE, const PIN: u8> LowPowerPin<MODE, PIN> {
|
|||||||
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pullup_enable(&self, enable: bool) {
|
/// Sets pull-up enable for the pin
|
||||||
|
pub fn pullup_enable(&self, enable: bool) {
|
||||||
get_pin_reg(PIN).modify(|_, w| w.fun_wpu().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.fun_wpu().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pulldown_enable(&self, enable: bool) {
|
/// Sets pull-down enable for the pin
|
||||||
|
pub fn pulldown_enable(&self, enable: bool) {
|
||||||
get_pin_reg(PIN).modify(|_, w| w.fun_wpd().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.fun_wpd().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
fn set_open_drain_output(&self, enable: bool) {
|
||||||
pub fn set_level(&mut self, level: bool) {
|
|
||||||
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
|
||||||
if level {
|
|
||||||
lp_io
|
|
||||||
.out_data_w1ts()
|
|
||||||
.write(|w| unsafe { w.out_data_w1ts().bits(1 << PIN) });
|
|
||||||
} else {
|
|
||||||
lp_io
|
|
||||||
.out_data_w1tc()
|
|
||||||
.write(|w| unsafe { w.out_data_w1tc().bits(1 << PIN) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn get_level(&self) -> bool {
|
|
||||||
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
|
||||||
(lp_io.in_().read().data_next().bits() & 1 << PIN) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an input with the internal pull-up resistor
|
|
||||||
/// enabled.
|
|
||||||
pub fn into_pull_up_input(self) -> LowPowerPin<Input<PullUp>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(true);
|
|
||||||
self.pulldown_enable(false);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an input with the internal pull-down resistor
|
|
||||||
/// enabled.
|
|
||||||
pub fn into_pull_down_input(self) -> LowPowerPin<Input<PullDown>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(false);
|
|
||||||
self.pulldown_enable(true);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as a floating input pin.
|
|
||||||
pub fn into_floating_input(self) -> LowPowerPin<Input<Floating>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(false);
|
|
||||||
self.pulldown_enable(false);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as a push-pull output pin.
|
|
||||||
pub fn into_push_pull_output(self) -> LowPowerPin<Output<PushPull>, PIN> {
|
|
||||||
self.output_enable(true);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an open-drain output pin.
|
|
||||||
pub fn into_open_drain_output(self) -> LowPowerPin<OpenDrain, PIN> {
|
|
||||||
use crate::peripherals::GPIO;
|
use crate::peripherals::GPIO;
|
||||||
|
|
||||||
let gpio = unsafe { &*GPIO::PTR };
|
let gpio = unsafe { &*GPIO::PTR };
|
||||||
|
|
||||||
gpio.pin(PIN as usize)
|
gpio.pin(PIN as usize)
|
||||||
.modify(|_, w| w.pad_driver().bit(true));
|
.modify(|_, w| w.pad_driver().bit(enable));
|
||||||
self.pulldown_enable(false);
|
|
||||||
self.into_pull_up_input().into_push_pull_output();
|
|
||||||
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,12 +179,6 @@ fn get_pin_reg(pin: u8) -> &'static crate::peripherals::lp_io::GPIO0 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configures a pin for use as a low power pin
|
|
||||||
pub trait IntoLowPowerPin<const PIN: u8> {
|
|
||||||
/// Converts the pin into a low power pin
|
|
||||||
fn into_low_power(self) -> LowPowerPin<Unknown, { PIN }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! lp_gpio {
|
macro_rules! lp_gpio {
|
||||||
@ -171,16 +187,7 @@ macro_rules! lp_gpio {
|
|||||||
) => {
|
) => {
|
||||||
paste::paste!{
|
paste::paste!{
|
||||||
$(
|
$(
|
||||||
impl<MODE> $crate::gpio::lp_io::IntoLowPowerPin<$gpionum> for GpioPin<MODE, $gpionum> {
|
impl $crate::gpio::RtcPin for GpioPin<$gpionum> {
|
||||||
fn into_low_power(self) -> $crate::gpio::lp_io::LowPowerPin<Unknown, $gpionum> {
|
|
||||||
$crate::gpio::lp_io::init_low_power_pin($gpionum);
|
|
||||||
$crate::gpio::lp_io::LowPowerPin {
|
|
||||||
private: core::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<MODE> $crate::gpio::RtcPin for GpioPin<MODE, $gpionum> {
|
|
||||||
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) {
|
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) {
|
||||||
let lp_io = &*$crate::peripherals::LP_IO::ptr();
|
let lp_io = &*$crate::peripherals::LP_IO::ptr();
|
||||||
lp_io.[< pin $gpionum >]().modify(|_, w| {
|
lp_io.[< pin $gpionum >]().modify(|_, w| {
|
||||||
@ -232,7 +239,7 @@ macro_rules! lp_gpio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MODE> $crate::gpio::RtcPinWithResistors for GpioPin<MODE, $gpionum> {
|
impl $crate::gpio::RtcPinWithResistors for GpioPin<$gpionum> {
|
||||||
fn rtcio_pullup(&mut self, enable: bool) {
|
fn rtcio_pullup(&mut self, enable: bool) {
|
||||||
let lp_io = unsafe { &*$crate::peripherals::LP_IO::ptr() };
|
let lp_io = unsafe { &*$crate::peripherals::LP_IO::ptr() };
|
||||||
lp_io.[< gpio $gpionum >]().modify(|_, w| w.fun_wpu().bit(enable));
|
lp_io.[< gpio $gpionum >]().modify(|_, w| w.fun_wpu().bit(enable));
|
||||||
@ -249,3 +256,5 @@ macro_rules! lp_gpio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use lp_gpio;
|
pub(crate) use lp_gpio;
|
||||||
|
|
||||||
|
use super::RtcPin;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,29 +17,120 @@
|
|||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//! // configure GPIO 1 as ULP output pin
|
//! // configure GPIO 1 as ULP output pin
|
||||||
//! let lp_pin = io.pins.gpio1.into_low_power().into_push_pull_output();
|
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[cfg(esp32c6)]
|
#[cfg(esp32c6)]
|
||||||
use super::OpenDrain;
|
use super::OpenDrain;
|
||||||
use super::{Floating, Input, Output, PullDown, PullUp, PushPull, Unknown};
|
use super::RtcPin;
|
||||||
|
use crate::into_ref;
|
||||||
|
|
||||||
/// A GPIO pin configured for low power operation
|
/// A GPIO output pin configured for low power operation
|
||||||
pub struct LowPowerPin<MODE, const PIN: u8> {
|
pub struct LowPowerOutput<'d, const PIN: u8> {
|
||||||
pub(crate) private: PhantomData<MODE>,
|
phantom: PhantomData<&'d ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configures a pin for use as a low power pin
|
impl<'d, const PIN: u8> LowPowerOutput<'d, PIN> {
|
||||||
pub trait IntoLowPowerPin<const PIN: u8> {
|
/// Create a new output pin for use by the low-power core
|
||||||
/// Convert into low power pin
|
pub fn new<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
fn into_low_power(self) -> LowPowerPin<Unknown, { PIN }>;
|
where
|
||||||
|
P: super::OutputPin + RtcPin,
|
||||||
|
{
|
||||||
|
into_ref!(pin);
|
||||||
|
pin.rtc_set_config(false, true, crate::gpio::RtcFunction::Rtc);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
this.output_enable(true);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_enable(&self, enable: bool) {
|
||||||
|
let rtc_io = unsafe { crate::peripherals::RTC_IO::steal() };
|
||||||
|
|
||||||
|
if enable {
|
||||||
|
rtc_io
|
||||||
|
.rtc_gpio_enable_w1ts()
|
||||||
|
.write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << PIN) });
|
||||||
|
} else {
|
||||||
|
rtc_io
|
||||||
|
.enable_w1tc()
|
||||||
|
.write(|w| unsafe { w.enable_w1tc().bits(1 << PIN) });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MODE, const PIN: u8> LowPowerPin<MODE, PIN> {
|
/// A GPIO input pin configured for low power operation
|
||||||
#[doc(hidden)]
|
pub struct LowPowerInput<'d, const PIN: u8> {
|
||||||
pub fn output_enable(&self, enable: bool) {
|
phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, const PIN: u8> LowPowerInput<'d, PIN> {
|
||||||
|
/// Create a new input pin for use by the low-power core
|
||||||
|
pub fn new<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
|
where
|
||||||
|
P: super::InputPin + RtcPin,
|
||||||
|
{
|
||||||
|
into_ref!(pin);
|
||||||
|
pin.rtc_set_config(true, true, crate::gpio::RtcFunction::Rtc);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
this.input_enable(true);
|
||||||
|
this.pullup_enable(false);
|
||||||
|
this.pulldown_enable(false);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pull-up enable for the pin
|
||||||
|
pub fn pullup_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.rue().bit(enable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pull-down enable for the pin
|
||||||
|
pub fn pulldown_enable(&self, enable: bool) {
|
||||||
|
get_pin_reg(PIN).modify(|_, w| w.rde().bit(enable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A GPIO open-drain output pin configured for low power operation
|
||||||
|
pub struct LowPowerOutputOpenDrain<'d, const PIN: u8> {
|
||||||
|
phantom: PhantomData<&'d ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
|
||||||
|
/// Create a new output pin for use by the low-power core
|
||||||
|
pub fn new<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||||
|
where
|
||||||
|
P: super::InputPin + super::OutputPin + RtcPin,
|
||||||
|
{
|
||||||
|
into_ref!(pin);
|
||||||
|
pin.rtc_set_config(true, true, crate::gpio::RtcFunction::Rtc);
|
||||||
|
|
||||||
|
let this = Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.set_open_drain_output(true);
|
||||||
|
this.input_enable(true);
|
||||||
|
this.pullup_enable(true);
|
||||||
|
this.pulldown_enable(false);
|
||||||
|
this.output_enable(true);
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_enable(&self, enable: bool) {
|
||||||
let rtc_io = unsafe { crate::peripherals::RTC_IO::steal() };
|
let rtc_io = unsafe { crate::peripherals::RTC_IO::steal() };
|
||||||
|
|
||||||
if enable {
|
if enable {
|
||||||
@ -57,90 +148,22 @@ impl<MODE, const PIN: u8> LowPowerPin<MODE, PIN> {
|
|||||||
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.fun_ie().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pullup_enable(&self, enable: bool) {
|
/// Sets pull-up enable for the pin
|
||||||
|
pub fn pullup_enable(&self, enable: bool) {
|
||||||
get_pin_reg(PIN).modify(|_, w| w.rue().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.rue().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pulldown_enable(&self, enable: bool) {
|
/// Sets pull-down enable for the pin
|
||||||
|
pub fn pulldown_enable(&self, enable: bool) {
|
||||||
get_pin_reg(PIN).modify(|_, w| w.rde().bit(enable));
|
get_pin_reg(PIN).modify(|_, w| w.rde().bit(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
fn set_open_drain_output(&self, enable: bool) {
|
||||||
pub fn set_level(&mut self, level: bool) {
|
|
||||||
let rtc_io = unsafe { &*crate::peripherals::RTC_IO::PTR };
|
|
||||||
|
|
||||||
if level {
|
|
||||||
rtc_io
|
|
||||||
.rtc_gpio_out_w1ts()
|
|
||||||
.write(|w| unsafe { w.rtc_gpio_out_data_w1ts().bits(1 << PIN) });
|
|
||||||
} else {
|
|
||||||
rtc_io
|
|
||||||
.rtc_gpio_out_w1tc()
|
|
||||||
.write(|w| unsafe { w.rtc_gpio_out_data_w1tc().bits(1 << PIN) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn get_level(&self) -> bool {
|
|
||||||
let rtc_io = unsafe { &*crate::peripherals::RTC_IO::PTR };
|
|
||||||
(rtc_io.rtc_gpio_in().read().bits() & 1 << PIN) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an input with the internal pull-up resistor
|
|
||||||
/// enabled.
|
|
||||||
pub fn into_pull_up_input(self) -> LowPowerPin<Input<PullUp>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(true);
|
|
||||||
self.pulldown_enable(false);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an input with the internal pull-down resistor
|
|
||||||
/// enabled.
|
|
||||||
pub fn into_pull_down_input(self) -> LowPowerPin<Input<PullDown>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(false);
|
|
||||||
self.pulldown_enable(true);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as a floating input pin.
|
|
||||||
pub fn into_floating_input(self) -> LowPowerPin<Input<Floating>, PIN> {
|
|
||||||
self.input_enable(true);
|
|
||||||
self.pullup_enable(false);
|
|
||||||
self.pulldown_enable(false);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the pin as an output pin.
|
|
||||||
pub fn into_push_pull_output(self) -> LowPowerPin<Output<PushPull>, PIN> {
|
|
||||||
self.output_enable(true);
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(esp32c6)]
|
|
||||||
/// Configures the pin as an pullup input and a push pull output pin.
|
|
||||||
pub fn into_open_drain_output(self) -> LowPowerPin<OpenDrain, PIN> {
|
|
||||||
self.into_pull_up_input();
|
|
||||||
self.into_push_pull_output();
|
|
||||||
use crate::peripherals::GPIO;
|
use crate::peripherals::GPIO;
|
||||||
|
|
||||||
let gpio = unsafe { &*GPIO::PTR };
|
let gpio = unsafe { &*GPIO::PTR };
|
||||||
|
|
||||||
gpio.pin(PIN).modify(|_, w| w.pad_driver().bit(true));
|
gpio.pin(PIN as usize)
|
||||||
self.pulldown_enable(false);
|
.modify(|_, w| w.pad_driver().bit(enable));
|
||||||
|
|
||||||
LowPowerPin {
|
|
||||||
private: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,20 +432,32 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
// avoid SCL/SDA going low during configuration
|
// avoid SCL/SDA going low during configuration
|
||||||
scl.set_output_high(true);
|
scl.set_output_high(true, crate::private::Internal);
|
||||||
sda.set_output_high(true);
|
sda.set_output_high(true, crate::private::Internal);
|
||||||
|
|
||||||
scl.set_to_open_drain_output()
|
scl.set_to_open_drain_output(crate::private::Internal);
|
||||||
.enable_input(true)
|
scl.enable_input(true, crate::private::Internal);
|
||||||
.internal_pull_up(true)
|
scl.internal_pull_up(true, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(i2c.peripheral.scl_output_signal())
|
scl.connect_peripheral_to_output(
|
||||||
.connect_input_to_peripheral(i2c.peripheral.scl_input_signal());
|
i2c.peripheral.scl_output_signal(),
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
scl.connect_input_to_peripheral(
|
||||||
|
i2c.peripheral.scl_input_signal(),
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
sda.set_to_open_drain_output()
|
sda.set_to_open_drain_output(crate::private::Internal);
|
||||||
.enable_input(true)
|
sda.enable_input(true, crate::private::Internal);
|
||||||
.internal_pull_up(true)
|
sda.internal_pull_up(true, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(i2c.peripheral.sda_output_signal())
|
sda.connect_peripheral_to_output(
|
||||||
.connect_input_to_peripheral(i2c.peripheral.sda_input_signal());
|
i2c.peripheral.sda_output_signal(),
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
sda.connect_input_to_peripheral(
|
||||||
|
i2c.peripheral.sda_input_signal(),
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
i2c.peripheral.setup(frequency, clocks, timeout);
|
i2c.peripheral.setup(frequency, clocks, timeout);
|
||||||
|
|
||||||
@ -2017,7 +2029,7 @@ pub mod lp_i2c {
|
|||||||
use fugit::HertzU32;
|
use fugit::HertzU32;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gpio::{lp_io::LowPowerPin, OpenDrain},
|
gpio::lp_io::LowPowerOutputOpenDrain,
|
||||||
peripherals::{LP_CLKRST, LP_I2C0},
|
peripherals::{LP_CLKRST, LP_I2C0},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2217,8 +2229,8 @@ pub mod lp_i2c {
|
|||||||
impl LpI2c {
|
impl LpI2c {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
i2c: LP_I2C0,
|
i2c: LP_I2C0,
|
||||||
_sda: LowPowerPin<OpenDrain, 6>,
|
_sda: LowPowerOutputOpenDrain<6>,
|
||||||
_scl: LowPowerPin<OpenDrain, 7>,
|
_scl: LowPowerOutputOpenDrain<7>,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let me = Self { i2c };
|
let me = Self { i2c };
|
||||||
|
@ -578,8 +578,8 @@ where
|
|||||||
|
|
||||||
pub fn with_mclk<P: OutputPin>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
|
pub fn with_mclk<P: OutputPin>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(I::mclk_signal());
|
pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -907,6 +907,7 @@ mod private {
|
|||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
into_ref,
|
into_ref,
|
||||||
peripherals::I2S0,
|
peripherals::I2S0,
|
||||||
|
private,
|
||||||
system::Peripheral,
|
system::Peripheral,
|
||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
@ -937,8 +938,8 @@ mod private {
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(T::bclk_signal());
|
pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -947,8 +948,8 @@ mod private {
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(T::ws_signal());
|
pin.connect_peripheral_to_output(T::ws_signal(), private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,8 +958,8 @@ mod private {
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(T::dout_signal());
|
pin.connect_peripheral_to_output(T::dout_signal(), private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -989,8 +990,8 @@ mod private {
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(T::bclk_rx_signal());
|
pin.connect_peripheral_to_output(T::bclk_rx_signal(), crate::private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -999,8 +1000,8 @@ mod private {
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(T::ws_rx_signal());
|
pin.connect_peripheral_to_output(T::ws_rx_signal(), crate::private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,8 +1010,8 @@ mod private {
|
|||||||
P: InputPin,
|
P: InputPin,
|
||||||
{
|
{
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
pin.set_to_input()
|
pin.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(T::din_signal());
|
pin.connect_input_to_peripheral(T::din_signal(), crate::private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,8 +221,8 @@ impl<'d, RX: Rx> Camera<'d, RX> {
|
|||||||
|
|
||||||
pub fn with_master_clock<MCLK: OutputPin>(self, mclk: impl Peripheral<P = MCLK> + 'd) -> Self {
|
pub fn with_master_clock<MCLK: OutputPin>(self, mclk: impl Peripheral<P = MCLK> + 'd) -> Self {
|
||||||
crate::into_ref!(mclk);
|
crate::into_ref!(mclk);
|
||||||
mclk.set_to_push_pull_output()
|
mclk.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::CAM_CLK);
|
mclk.connect_peripheral_to_output(OutputSignal::CAM_CLK, crate::private::Internal);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,14 +236,12 @@ impl<'d, RX: Rx> Camera<'d, RX> {
|
|||||||
crate::into_ref!(h_enable);
|
crate::into_ref!(h_enable);
|
||||||
crate::into_ref!(pclk);
|
crate::into_ref!(pclk);
|
||||||
|
|
||||||
vsync
|
vsync.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_V_SYNC);
|
h_enable.set_to_input(crate::private::Internal);
|
||||||
h_enable
|
h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal);
|
||||||
.set_to_input()
|
pclk.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE);
|
pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal);
|
||||||
pclk.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_PCLK);
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -425,30 +423,22 @@ impl RxEightBits {
|
|||||||
crate::into_ref!(pin_6);
|
crate::into_ref!(pin_6);
|
||||||
crate::into_ref!(pin_7);
|
crate::into_ref!(pin_7);
|
||||||
|
|
||||||
pin_0
|
pin_0.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_0);
|
pin_1.set_to_input(crate::private::Internal);
|
||||||
pin_1
|
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_2.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_1);
|
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||||
pin_2
|
pin_3.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_2);
|
pin_4.set_to_input(crate::private::Internal);
|
||||||
pin_3
|
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_5.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_3);
|
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||||
pin_4
|
pin_6.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_4);
|
pin_7.set_to_input(crate::private::Internal);
|
||||||
pin_5
|
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_5);
|
|
||||||
pin_6
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_6);
|
|
||||||
pin_7
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_7);
|
|
||||||
|
|
||||||
Self { _pins: () }
|
Self { _pins: () }
|
||||||
}
|
}
|
||||||
@ -517,54 +507,38 @@ impl RxSixteenBits {
|
|||||||
crate::into_ref!(pin_14);
|
crate::into_ref!(pin_14);
|
||||||
crate::into_ref!(pin_15);
|
crate::into_ref!(pin_15);
|
||||||
|
|
||||||
pin_0
|
pin_0.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_0);
|
pin_1.set_to_input(crate::private::Internal);
|
||||||
pin_1
|
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_2.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_1);
|
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||||
pin_2
|
pin_3.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_2);
|
pin_4.set_to_input(crate::private::Internal);
|
||||||
pin_3
|
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_5.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_3);
|
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||||
pin_4
|
pin_6.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_4);
|
pin_7.set_to_input(crate::private::Internal);
|
||||||
pin_5
|
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_8.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_5);
|
pin_8.connect_input_to_peripheral(InputSignal::CAM_DATA_8, crate::private::Internal);
|
||||||
pin_6
|
pin_9.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_9.connect_input_to_peripheral(InputSignal::CAM_DATA_9, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_6);
|
pin_10.set_to_input(crate::private::Internal);
|
||||||
pin_7
|
pin_10.connect_input_to_peripheral(InputSignal::CAM_DATA_10, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_11.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_7);
|
pin_11.connect_input_to_peripheral(InputSignal::CAM_DATA_11, crate::private::Internal);
|
||||||
pin_8
|
pin_12.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_12.connect_input_to_peripheral(InputSignal::CAM_DATA_12, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_8);
|
pin_13.set_to_input(crate::private::Internal);
|
||||||
pin_9
|
pin_13.connect_input_to_peripheral(InputSignal::CAM_DATA_13, crate::private::Internal);
|
||||||
.set_to_input()
|
pin_14.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_9);
|
pin_14.connect_input_to_peripheral(InputSignal::CAM_DATA_14, crate::private::Internal);
|
||||||
pin_10
|
pin_15.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
pin_15.connect_input_to_peripheral(InputSignal::CAM_DATA_15, crate::private::Internal);
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_10);
|
|
||||||
pin_11
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_11);
|
|
||||||
pin_12
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_12);
|
|
||||||
pin_13
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_13);
|
|
||||||
pin_14
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_14);
|
|
||||||
pin_15
|
|
||||||
.set_to_input()
|
|
||||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_15);
|
|
||||||
|
|
||||||
Self { _pins: () }
|
Self { _pins: () }
|
||||||
}
|
}
|
||||||
|
@ -254,8 +254,8 @@ where
|
|||||||
|
|
||||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||||
crate::into_ref!(cs);
|
crate::into_ref!(cs);
|
||||||
cs.set_to_push_pull_output()
|
cs.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_CS);
|
cs.connect_peripheral_to_output(OutputSignal::LCD_CS, crate::private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -268,11 +268,11 @@ where
|
|||||||
crate::into_ref!(dc);
|
crate::into_ref!(dc);
|
||||||
crate::into_ref!(wrx);
|
crate::into_ref!(wrx);
|
||||||
|
|
||||||
dc.set_to_push_pull_output()
|
dc.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DC);
|
dc.connect_peripheral_to_output(OutputSignal::LCD_DC, crate::private::Internal);
|
||||||
|
|
||||||
wrx.set_to_push_pull_output()
|
wrx.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_PCLK);
|
wrx.connect_peripheral_to_output(OutputSignal::LCD_PCLK, crate::private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -610,30 +610,30 @@ where
|
|||||||
type Word = u8;
|
type Word = u8;
|
||||||
|
|
||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
|
self.pin_0.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_0
|
self.pin_0
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0);
|
self.pin_1.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_1
|
self.pin_1
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1);
|
self.pin_2.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_2
|
self.pin_2
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2);
|
self.pin_3.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_3
|
self.pin_3
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3);
|
self.pin_4.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_4
|
self.pin_4
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4);
|
self.pin_5.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_5
|
self.pin_5
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5);
|
self.pin_6.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_6
|
self.pin_6
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6);
|
self.pin_7.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_7
|
self.pin_7
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,54 +755,60 @@ where
|
|||||||
{
|
{
|
||||||
type Word = u16;
|
type Word = u16;
|
||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
|
self.pin_0.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_0
|
self.pin_0
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0);
|
self.pin_1.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_1
|
self.pin_1
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1);
|
self.pin_2.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_2
|
self.pin_2
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2);
|
self.pin_3.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_3
|
self.pin_3
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3);
|
self.pin_4.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_4
|
self.pin_4
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4);
|
self.pin_5.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_5
|
self.pin_5
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5);
|
self.pin_6.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_6
|
self.pin_6
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6);
|
self.pin_7.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_7
|
self.pin_7
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7);
|
self.pin_8.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_8
|
self.pin_8
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_8, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_8);
|
self.pin_9.set_to_push_pull_output(crate::private::Internal);
|
||||||
self.pin_9
|
self.pin_9
|
||||||
.set_to_push_pull_output()
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_9, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_9);
|
|
||||||
self.pin_10
|
self.pin_10
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_10);
|
self.pin_10
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_10, crate::private::Internal);
|
||||||
self.pin_11
|
self.pin_11
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_11);
|
self.pin_11
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_11, crate::private::Internal);
|
||||||
self.pin_12
|
self.pin_12
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_12);
|
self.pin_12
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_12, crate::private::Internal);
|
||||||
self.pin_13
|
self.pin_13
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_13);
|
self.pin_13
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_13, crate::private::Internal);
|
||||||
self.pin_14
|
self.pin_14
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_14);
|
self.pin_14
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_14, crate::private::Internal);
|
||||||
self.pin_15
|
self.pin_15
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_15);
|
self.pin_15
|
||||||
|
.connect_peripheral_to_output(OutputSignal::LCD_DATA_15, crate::private::Internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,8 +536,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
match cfg {
|
match cfg {
|
||||||
config::PinConfig::PushPull => self.output_pin.set_to_push_pull_output(),
|
config::PinConfig::PushPull => self
|
||||||
config::PinConfig::OpenDrain => self.output_pin.set_to_open_drain_output(),
|
.output_pin
|
||||||
|
.set_to_push_pull_output(crate::private::Internal),
|
||||||
|
config::PinConfig::OpenDrain => self
|
||||||
|
.output_pin
|
||||||
|
.set_to_open_drain_output(crate::private::Internal),
|
||||||
};
|
};
|
||||||
|
|
||||||
let timer_number = timer.get_number() as u8;
|
let timer_number = timer.get_number() as u8;
|
||||||
@ -585,7 +589,8 @@ where
|
|||||||
#[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))]
|
#[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))]
|
||||||
Number::Channel7 => OutputSignal::LEDC_LS_SIG7,
|
Number::Channel7 => OutputSignal::LEDC_LS_SIG7,
|
||||||
};
|
};
|
||||||
self.output_pin.connect_peripheral_to_output(signal);
|
self.output_pin
|
||||||
|
.connect_peripheral_to_output(signal, crate::private::Internal);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Timer);
|
return Err(Error::Timer);
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,8 @@ impl crate::private::Sealed for Async {}
|
|||||||
|
|
||||||
pub(crate) mod private {
|
pub(crate) mod private {
|
||||||
pub trait Sealed {}
|
pub trait Sealed {}
|
||||||
|
|
||||||
|
pub struct Internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Available CPU cores
|
/// Available CPU cores
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # use esp_hal::{mcpwm, prelude::*};
|
//! # use esp_hal::{mcpwm, prelude::*};
|
||||||
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, PeripheralClockConfig, MCPWM};
|
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, McPwm, PeripheralClockConfig};
|
||||||
//!
|
//!
|
||||||
//! // initialize peripheral
|
//! // initialize peripheral
|
||||||
//! let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();
|
//! let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();
|
||||||
|
@ -16,6 +16,7 @@ use crate::{
|
|||||||
gpio::OutputPin,
|
gpio::OutputPin,
|
||||||
mcpwm::{timer::Timer, PwmPeripheral},
|
mcpwm::{timer::Timer, PwmPeripheral},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
private,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Input/Output Stream descriptor for each channel
|
/// Input/Output Stream descriptor for each channel
|
||||||
@ -302,8 +303,8 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
|||||||
|
|
||||||
let output_signal = PWM::output_signal::<OP, IS_A>();
|
let output_signal = PWM::output_signal::<OP, IS_A>();
|
||||||
pin.pin
|
pin.pin
|
||||||
.connect_peripheral_to_output(output_signal)
|
.connect_peripheral_to_output(output_signal, private::Internal);
|
||||||
.enable_output(true);
|
pin.pin.enable_output(true, private::Internal);
|
||||||
pin
|
pin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,9 +331,11 @@ where
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
self.pin
|
self.pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.set_to_push_pull_output()
|
self.pin.connect_peripheral_to_output(
|
||||||
.connect_peripheral_to_output(crate::gpio::OutputSignal::PARL_TX_CLK);
|
crate::gpio::OutputSignal::PARL_TX_CLK,
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,9 +365,11 @@ where
|
|||||||
pcr.parl_clk_tx_conf()
|
pcr.parl_clk_tx_conf()
|
||||||
.modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
.modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
||||||
|
|
||||||
self.pin
|
self.pin.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
self.pin.connect_input_to_peripheral(
|
||||||
.connect_input_to_peripheral(crate::gpio::InputSignal::PARL_TX_CLK);
|
crate::gpio::InputSignal::PARL_TX_CLK,
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,9 +400,11 @@ where
|
|||||||
pcr.parl_clk_rx_conf()
|
pcr.parl_clk_rx_conf()
|
||||||
.modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
.modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
||||||
|
|
||||||
self.pin
|
self.pin.set_to_input(crate::private::Internal);
|
||||||
.set_to_input()
|
self.pin.connect_input_to_peripheral(
|
||||||
.connect_input_to_peripheral(crate::gpio::InputSignal::PARL_RX_CLK);
|
crate::gpio::InputSignal::PARL_RX_CLK,
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
Instance::set_rx_clk_edge_sel(self.sample_edge);
|
Instance::set_rx_clk_edge_sel(self.sample_edge);
|
||||||
}
|
}
|
||||||
@ -441,8 +447,11 @@ where
|
|||||||
fn configure(&mut self) -> Result<(), Error> {
|
fn configure(&mut self) -> Result<(), Error> {
|
||||||
self.tx_pins.configure()?;
|
self.tx_pins.configure()?;
|
||||||
self.valid_pin
|
self.valid_pin
|
||||||
.set_to_push_pull_output()
|
.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(Instance::tx_valid_pin_signal());
|
self.valid_pin.connect_peripheral_to_output(
|
||||||
|
Instance::tx_valid_pin_signal(),
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
Instance::set_tx_hw_valid_en(true);
|
Instance::set_tx_hw_valid_en(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -516,9 +525,8 @@ macro_rules! tx_pins {
|
|||||||
{
|
{
|
||||||
fn configure(&mut self) -> Result<(), Error>{
|
fn configure(&mut self) -> Result<(), Error>{
|
||||||
$(
|
$(
|
||||||
self.[< pin_ $pin:lower >]
|
self.[< pin_ $pin:lower >].set_to_push_pull_output(crate::private::Internal);
|
||||||
.set_to_push_pull_output()
|
self.[< pin_ $pin:lower >].connect_peripheral_to_output(crate::gpio::OutputSignal::$signal, crate::private::Internal);
|
||||||
.connect_peripheral_to_output(crate::gpio::OutputSignal::$signal);
|
|
||||||
)+
|
)+
|
||||||
|
|
||||||
private::Instance::set_tx_bit_width( private::WidSel::[< Bits $width >]);
|
private::Instance::set_tx_bit_width( private::WidSel::[< Bits $width >]);
|
||||||
@ -659,9 +667,9 @@ where
|
|||||||
{
|
{
|
||||||
fn configure(&mut self) -> Result<(), Error> {
|
fn configure(&mut self) -> Result<(), Error> {
|
||||||
self.rx_pins.configure()?;
|
self.rx_pins.configure()?;
|
||||||
|
self.valid_pin.set_to_input(crate::private::Internal);
|
||||||
self.valid_pin
|
self.valid_pin
|
||||||
.set_to_input()
|
.connect_input_to_peripheral(Instance::rx_valid_pin_signal(), crate::private::Internal);
|
||||||
.connect_input_to_peripheral(Instance::rx_valid_pin_signal());
|
|
||||||
Instance::set_rx_sw_en(false);
|
Instance::set_rx_sw_en(false);
|
||||||
if let Some(sel) = self.enable_mode.pulse_submode_sel() {
|
if let Some(sel) = self.enable_mode.pulse_submode_sel() {
|
||||||
Instance::set_rx_pulse_submode_sel(sel);
|
Instance::set_rx_pulse_submode_sel(sel);
|
||||||
@ -763,9 +771,8 @@ macro_rules! rx_pins {
|
|||||||
{
|
{
|
||||||
fn configure(&mut self) -> Result<(), Error> {
|
fn configure(&mut self) -> Result<(), Error> {
|
||||||
$(
|
$(
|
||||||
self.[< pin_ $pin:lower >]
|
self.[< pin_ $pin:lower >].set_to_input($crate::private::Internal);
|
||||||
.set_to_input()
|
self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, $crate::private::Internal);
|
||||||
.connect_input_to_peripheral(crate::gpio::InputSignal::$signal);
|
|
||||||
)+
|
)+
|
||||||
|
|
||||||
private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);
|
private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);
|
||||||
|
@ -10,11 +10,25 @@
|
|||||||
|
|
||||||
use super::unit;
|
use super::unit;
|
||||||
use crate::{
|
use crate::{
|
||||||
gpio::{InputPin, InputSignal, ONE_INPUT, ZERO_INPUT},
|
gpio::{InputPin, InputSignal, Pull, ONE_INPUT, ZERO_INPUT},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Configuration for an PCNT input pin
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct PcntInputConfig {
|
||||||
|
/// Configuration for the internal pull-up resistors
|
||||||
|
pub pull: Pull,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PcntInputConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { pull: Pull::None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Channel number
|
/// Channel number
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
pub enum Number {
|
pub enum Number {
|
||||||
@ -59,10 +73,20 @@ pub struct PcntSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PcntSource {
|
impl PcntSource {
|
||||||
pub fn from_pin<'a, P: InputPin>(pin: impl Peripheral<P = P> + 'a) -> Self {
|
pub fn from_pin<'a, P: InputPin>(
|
||||||
|
pin: impl Peripheral<P = P> + 'a,
|
||||||
|
pin_config: PcntInputConfig,
|
||||||
|
) -> Self {
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
|
|
||||||
|
pin.init_input(
|
||||||
|
pin_config.pull == Pull::Down,
|
||||||
|
pin_config.pull == Pull::Up,
|
||||||
|
crate::private::Internal,
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
source: pin.number(),
|
source: pin.number(crate::private::Internal),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn always_high() -> Self {
|
pub fn always_high() -> Self {
|
||||||
|
@ -47,12 +47,12 @@
|
|||||||
//! println!("setup channel 0");
|
//! println!("setup channel 0");
|
||||||
//! let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
//! let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//! let mut pin_a = io.pins.gpio5.into_pull_up_input();
|
//! let mut pin_a = io.pins.gpio5;
|
||||||
//! let mut pin_b = io.pins.gpio6.into_pull_up_input();
|
//! let mut pin_b = io.pins.gpio6;
|
||||||
//!
|
//!
|
||||||
//! ch0.configure(
|
//! ch0.configure(
|
||||||
//! PcntSource::from_pin(&mut pin_a),
|
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||||
//! PcntSource::from_pin(&mut pin_b),
|
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||||
//! channel::Config {
|
//! channel::Config {
|
||||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||||
@ -66,8 +66,8 @@
|
|||||||
//! println!("setup channel 1");
|
//! println!("setup channel 1");
|
||||||
//! let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
//! let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
||||||
//! ch1.configure(
|
//! ch1.configure(
|
||||||
//! PcntSource::from_pin(&mut pin_b),
|
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||||
//! PcntSource::from_pin(&mut pin_a),
|
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||||
//! channel::Config {
|
//! channel::Config {
|
||||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||||
|
@ -317,8 +317,8 @@ where
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(T::output_signal());
|
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||||
T::set_divider(config.clk_divider);
|
T::set_divider(config.clk_divider);
|
||||||
T::set_carrier(
|
T::set_carrier(
|
||||||
config.carrier_modulation,
|
config.carrier_modulation,
|
||||||
@ -349,8 +349,8 @@ where
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
pin.set_to_push_pull_output()
|
pin.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(T::output_signal());
|
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||||
T::set_divider(config.clk_divider);
|
T::set_divider(config.clk_divider);
|
||||||
T::set_carrier(
|
T::set_carrier(
|
||||||
config.carrier_modulation,
|
config.carrier_modulation,
|
||||||
@ -394,8 +394,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
pin.set_to_input()
|
pin.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(T::input_signal());
|
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||||
T::set_divider(config.clk_divider);
|
T::set_divider(config.clk_divider);
|
||||||
T::set_carrier(
|
T::set_carrier(
|
||||||
config.carrier_modulation,
|
config.carrier_modulation,
|
||||||
@ -441,8 +441,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
pin.set_to_input()
|
pin.set_to_input(crate::private::Internal);
|
||||||
.connect_input_to_peripheral(T::input_signal());
|
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||||
T::set_divider(config.clk_divider);
|
T::set_divider(config.clk_divider);
|
||||||
T::set_carrier(
|
T::set_carrier(
|
||||||
config.carrier_modulation,
|
config.carrier_modulation,
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
efuse::Efuse,
|
efuse::Efuse,
|
||||||
gpio::{Pins, RtcFunction},
|
gpio::{Pins, RtcFunction},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
|
private,
|
||||||
rtc_cntl::{
|
rtc_cntl::{
|
||||||
rtc::{
|
rtc::{
|
||||||
rtc_clk_cpu_freq_set_xtal,
|
rtc_clk_cpu_freq_set_xtal,
|
||||||
@ -64,7 +65,7 @@ impl Ext1WakeupSource<'_, '_> {
|
|||||||
use crate::gpio::RtcPin;
|
use crate::gpio::RtcPin;
|
||||||
|
|
||||||
fn uninit_pin(pin: &mut impl RtcPin, wakeup_pins: u8) {
|
fn uninit_pin(pin: &mut impl RtcPin, wakeup_pins: u8) {
|
||||||
if wakeup_pins & (1 << pin.number()) != 0 {
|
if wakeup_pins & (1 << pin.number(private::Internal)) != 0 {
|
||||||
pin.rtcio_pad_hold(false);
|
pin.rtcio_pad_hold(false);
|
||||||
pin.rtc_set_config(false, false, RtcFunction::Rtc);
|
pin.rtc_set_config(false, false, RtcFunction::Rtc);
|
||||||
}
|
}
|
||||||
@ -92,9 +93,9 @@ impl WakeSource for Ext1WakeupSource<'_, '_> {
|
|||||||
let mut pin_mask = 0u8;
|
let mut pin_mask = 0u8;
|
||||||
let mut level_mask = 0u8;
|
let mut level_mask = 0u8;
|
||||||
for (pin, level) in pins.iter_mut() {
|
for (pin, level) in pins.iter_mut() {
|
||||||
pin_mask |= 1 << pin.number();
|
pin_mask |= 1 << pin.number(private::Internal);
|
||||||
level_mask |= match level {
|
level_mask |= match level {
|
||||||
WakeupLevel::High => 1 << pin.number(),
|
WakeupLevel::High => 1 << pin.number(private::Internal),
|
||||||
WakeupLevel::Low => 0,
|
WakeupLevel::Low => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -197,12 +197,14 @@ impl<'a, 'b> RtcioWakeupSource<'a, 'b> {
|
|||||||
|
|
||||||
pin.rtc_set_config(true, true, RtcFunction::Rtc);
|
pin.rtc_set_config(true, true, RtcFunction::Rtc);
|
||||||
|
|
||||||
rtcio.pin(pin.number() as usize).modify(|_, w| unsafe {
|
rtcio
|
||||||
w.wakeup_enable().set_bit().int_type().bits(match level {
|
.pin(pin.number(crate::private::Internal) as usize)
|
||||||
WakeupLevel::Low => 4,
|
.modify(|_, w| unsafe {
|
||||||
WakeupLevel::High => 5,
|
w.wakeup_enable().set_bit().int_type().bits(match level {
|
||||||
})
|
WakeupLevel::Low => 4,
|
||||||
});
|
WakeupLevel::High => 5,
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@ use crate::{
|
|||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
InterruptStatusRegisterAccessBank1,
|
InterruptStatusRegisterAccessBank1,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
Cpu,
|
Cpu,
|
||||||
|
@ -45,7 +45,6 @@ use crate::{
|
|||||||
GpioPin,
|
GpioPin,
|
||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
|
@ -46,7 +46,6 @@ use crate::{
|
|||||||
GpioPin,
|
GpioPin,
|
||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
|
@ -46,7 +46,6 @@ use crate::{
|
|||||||
GpioPin,
|
GpioPin,
|
||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
|
@ -46,7 +46,6 @@ use crate::{
|
|||||||
GpioPin,
|
GpioPin,
|
||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
|
@ -59,7 +59,6 @@ use crate::{
|
|||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
InterruptStatusRegisterAccessBank1,
|
InterruptStatusRegisterAccessBank1,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
@ -556,5 +555,5 @@ impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// implement marker traits on USB pins
|
// implement marker traits on USB pins
|
||||||
impl<T> crate::otg_fs::UsbDp for Gpio19<T> {}
|
impl crate::otg_fs::UsbDp for Gpio19 {}
|
||||||
impl<T> crate::otg_fs::UsbDm for Gpio20<T> {}
|
impl crate::otg_fs::UsbDm for Gpio20 {}
|
||||||
|
@ -47,7 +47,6 @@ use crate::{
|
|||||||
InterruptStatusRegisterAccess,
|
InterruptStatusRegisterAccess,
|
||||||
InterruptStatusRegisterAccessBank0,
|
InterruptStatusRegisterAccessBank0,
|
||||||
InterruptStatusRegisterAccessBank1,
|
InterruptStatusRegisterAccessBank1,
|
||||||
Unknown,
|
|
||||||
},
|
},
|
||||||
peripherals::GPIO,
|
peripherals::GPIO,
|
||||||
};
|
};
|
||||||
@ -490,5 +489,5 @@ impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// implement marker traits on USB pins
|
// implement marker traits on USB pins
|
||||||
impl<T> crate::otg_fs::UsbDp for Gpio19<T> {}
|
impl crate::otg_fs::UsbDp for Gpio19 {}
|
||||||
impl<T> crate::otg_fs::UsbDm for Gpio20<T> {}
|
impl crate::otg_fs::UsbDm for Gpio20 {}
|
||||||
|
@ -75,6 +75,7 @@ use crate::{
|
|||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
|
private,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralClockControl,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -452,32 +453,32 @@ where
|
|||||||
|
|
||||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||||
crate::into_ref!(sck);
|
crate::into_ref!(sck);
|
||||||
sck.set_to_push_pull_output()
|
sck.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_mosi<MOSI: OutputPin>(self, mosi: impl Peripheral<P = MOSI> + 'd) -> Self {
|
pub fn with_mosi<MOSI: OutputPin>(self, mosi: impl Peripheral<P = MOSI> + 'd) -> Self {
|
||||||
crate::into_ref!(mosi);
|
crate::into_ref!(mosi);
|
||||||
mosi.set_to_push_pull_output()
|
mosi.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.mosi_signal());
|
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_miso<MISO: InputPin>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
|
pub fn with_miso<MISO: InputPin>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
|
||||||
crate::into_ref!(miso);
|
crate::into_ref!(miso);
|
||||||
miso.set_to_input()
|
miso.set_to_input(private::Internal);
|
||||||
.connect_input_to_peripheral(self.spi.miso_signal());
|
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||||
crate::into_ref!(cs);
|
crate::into_ref!(cs);
|
||||||
cs.set_to_push_pull_output()
|
cs.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -503,26 +504,26 @@ where
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
if let Some(sck) = sck {
|
if let Some(sck) = sck {
|
||||||
crate::into_ref!(sck);
|
crate::into_ref!(sck);
|
||||||
sck.set_to_push_pull_output()
|
sck.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mosi) = mosi {
|
if let Some(mosi) = mosi {
|
||||||
crate::into_ref!(mosi);
|
crate::into_ref!(mosi);
|
||||||
mosi.set_to_push_pull_output()
|
mosi.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.mosi_signal());
|
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(miso) = miso {
|
if let Some(miso) = miso {
|
||||||
crate::into_ref!(miso);
|
crate::into_ref!(miso);
|
||||||
miso.set_to_input()
|
miso.set_to_input(private::Internal);
|
||||||
.connect_input_to_peripheral(self.spi.miso_signal());
|
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cs) = cs {
|
if let Some(cs) = cs {
|
||||||
crate::into_ref!(cs);
|
crate::into_ref!(cs);
|
||||||
cs.set_to_push_pull_output()
|
cs.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -572,8 +573,8 @@ where
|
|||||||
|
|
||||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||||
crate::into_ref!(sck);
|
crate::into_ref!(sck);
|
||||||
sck.set_to_push_pull_output()
|
sck.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -583,10 +584,10 @@ where
|
|||||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(mosi);
|
crate::into_ref!(mosi);
|
||||||
mosi.enable_output(true);
|
mosi.enable_output(true, private::Internal);
|
||||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal());
|
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||||
mosi.enable_input(true);
|
mosi.enable_input(true, private::Internal);
|
||||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal());
|
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -596,10 +597,10 @@ where
|
|||||||
miso: impl Peripheral<P = MISO> + 'd,
|
miso: impl Peripheral<P = MISO> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(miso);
|
crate::into_ref!(miso);
|
||||||
miso.enable_output(true);
|
miso.enable_output(true, private::Internal);
|
||||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal());
|
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||||
miso.enable_input(true);
|
miso.enable_input(true, private::Internal);
|
||||||
miso.connect_input_to_peripheral(self.spi.miso_signal());
|
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -609,10 +610,10 @@ where
|
|||||||
sio2: impl Peripheral<P = SIO2> + 'd,
|
sio2: impl Peripheral<P = SIO2> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(sio2);
|
crate::into_ref!(sio2);
|
||||||
sio2.enable_output(true);
|
sio2.enable_output(true, private::Internal);
|
||||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal());
|
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||||
sio2.enable_input(true);
|
sio2.enable_input(true, private::Internal);
|
||||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal());
|
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -622,18 +623,18 @@ where
|
|||||||
sio3: impl Peripheral<P = SIO3> + 'd,
|
sio3: impl Peripheral<P = SIO3> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(sio3);
|
crate::into_ref!(sio3);
|
||||||
sio3.enable_output(true);
|
sio3.enable_output(true, private::Internal);
|
||||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal());
|
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||||
sio3.enable_input(true);
|
sio3.enable_input(true, private::Internal);
|
||||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal());
|
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||||
crate::into_ref!(cs);
|
crate::into_ref!(cs);
|
||||||
cs.set_to_push_pull_output()
|
cs.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -660,46 +661,46 @@ where
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
if let Some(sck) = sck {
|
if let Some(sck) = sck {
|
||||||
crate::into_ref!(sck);
|
crate::into_ref!(sck);
|
||||||
sck.set_to_push_pull_output()
|
sck.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mosi) = mosi {
|
if let Some(mosi) = mosi {
|
||||||
crate::into_ref!(mosi);
|
crate::into_ref!(mosi);
|
||||||
mosi.enable_output(true);
|
mosi.enable_output(true, private::Internal);
|
||||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal());
|
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||||
mosi.enable_input(true);
|
mosi.enable_input(true, private::Internal);
|
||||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal());
|
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(miso) = miso {
|
if let Some(miso) = miso {
|
||||||
crate::into_ref!(miso);
|
crate::into_ref!(miso);
|
||||||
miso.enable_output(true);
|
miso.enable_output(true, private::Internal);
|
||||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal());
|
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||||
miso.enable_input(true);
|
miso.enable_input(true, private::Internal);
|
||||||
miso.connect_input_to_peripheral(self.spi.miso_signal());
|
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sio2) = sio2 {
|
if let Some(sio2) = sio2 {
|
||||||
crate::into_ref!(sio2);
|
crate::into_ref!(sio2);
|
||||||
sio2.enable_output(true);
|
sio2.enable_output(true, private::Internal);
|
||||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal());
|
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||||
sio2.enable_input(true);
|
sio2.enable_input(true, private::Internal);
|
||||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal());
|
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sio3) = sio3 {
|
if let Some(sio3) = sio3 {
|
||||||
crate::into_ref!(sio3);
|
crate::into_ref!(sio3);
|
||||||
sio3.enable_output(true);
|
sio3.enable_output(true, private::Internal);
|
||||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal());
|
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||||
sio3.enable_input(true);
|
sio3.enable_input(true, private::Internal);
|
||||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal());
|
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cs) = cs {
|
if let Some(cs) = cs {
|
||||||
crate::into_ref!(cs);
|
crate::into_ref!(cs);
|
||||||
cs.set_to_push_pull_output()
|
cs.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -2135,7 +2136,7 @@ pub trait ExtendedInstance: Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait Instance: crate::private::Sealed {
|
pub trait Instance: private::Sealed {
|
||||||
fn register_block(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
|
||||||
fn sclk_signal(&self) -> OutputSignal;
|
fn sclk_signal(&self) -> OutputSignal;
|
||||||
|
@ -54,6 +54,7 @@ use crate::{
|
|||||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
|
private,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralClockControl,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,17 +93,17 @@ where
|
|||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, T, FullDuplexMode> {
|
) -> Spi<'d, T, FullDuplexMode> {
|
||||||
crate::into_ref!(spi, sck, mosi, miso, cs);
|
crate::into_ref!(spi, sck, mosi, miso, cs);
|
||||||
sck.set_to_input()
|
sck.set_to_input(private::Internal);
|
||||||
.connect_input_to_peripheral(spi.sclk_signal());
|
sck.connect_input_to_peripheral(spi.sclk_signal(), private::Internal);
|
||||||
|
|
||||||
mosi.set_to_input()
|
mosi.set_to_input(private::Internal);
|
||||||
.connect_input_to_peripheral(spi.mosi_signal());
|
mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal);
|
||||||
|
|
||||||
miso.set_to_push_pull_output()
|
miso.set_to_push_pull_output(private::Internal);
|
||||||
.connect_peripheral_to_output(spi.miso_signal());
|
miso.connect_peripheral_to_output(spi.miso_signal(), private::Internal);
|
||||||
|
|
||||||
cs.set_to_input()
|
cs.set_to_input(private::Internal);
|
||||||
.connect_input_to_peripheral(spi.cs_signal());
|
cs.connect_input_to_peripheral(spi.cs_signal(), private::Internal);
|
||||||
|
|
||||||
Self::new_internal(spi, mode)
|
Self::new_internal(spi, mode)
|
||||||
}
|
}
|
||||||
@ -736,7 +737,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait Instance: crate::private::Sealed {
|
pub trait Instance: private::Sealed {
|
||||||
fn register_block(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
|
||||||
fn sclk_signal(&self) -> InputSignal;
|
fn sclk_signal(&self) -> InputSignal;
|
||||||
|
@ -42,7 +42,7 @@ pub struct SystemTimer<'d, DM: crate::Mode> {
|
|||||||
pub alarm0: Alarm<Target, DM, 0>,
|
pub alarm0: Alarm<Target, DM, 0>,
|
||||||
pub alarm1: Alarm<Target, DM, 1>,
|
pub alarm1: Alarm<Target, DM, 1>,
|
||||||
pub alarm2: Alarm<Target, DM, 2>,
|
pub alarm2: Alarm<Target, DM, 2>,
|
||||||
_phantom: &'d PhantomData<()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> SystemTimer<'d, crate::Blocking> {
|
impl<'d> SystemTimer<'d, crate::Blocking> {
|
||||||
@ -67,7 +67,7 @@ impl<'d> SystemTimer<'d, crate::Blocking> {
|
|||||||
alarm0: Alarm::new(),
|
alarm0: Alarm::new(),
|
||||||
alarm1: Alarm::new(),
|
alarm1: Alarm::new(),
|
||||||
alarm2: Alarm::new(),
|
alarm2: Alarm::new(),
|
||||||
_phantom: &PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ impl<'d> SystemTimer<'d, crate::Async> {
|
|||||||
alarm0: Alarm::new(),
|
alarm0: Alarm::new(),
|
||||||
alarm1: Alarm::new(),
|
alarm1: Alarm::new(),
|
||||||
alarm2: Alarm::new(),
|
alarm2: Alarm::new(),
|
||||||
_phantom: &PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,14 +646,18 @@ where
|
|||||||
clocks: &Clocks,
|
clocks: &Clocks,
|
||||||
baud_rate: BaudRate,
|
baud_rate: BaudRate,
|
||||||
interrupt: Option<InterruptHandler>,
|
interrupt: Option<InterruptHandler>,
|
||||||
|
no_transceiver: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Enable the peripheral clock for the TWAI peripheral.
|
// Enable the peripheral clock for the TWAI peripheral.
|
||||||
T::enable_peripheral();
|
T::enable_peripheral();
|
||||||
|
|
||||||
// Set up the GPIO pins.
|
// Set up the GPIO pins.
|
||||||
crate::into_ref!(tx_pin, rx_pin);
|
crate::into_ref!(tx_pin, rx_pin);
|
||||||
tx_pin.connect_peripheral_to_output(T::OUTPUT_SIGNAL);
|
if no_transceiver {
|
||||||
rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL);
|
tx_pin.set_to_open_drain_output(crate::private::Internal);
|
||||||
|
}
|
||||||
|
tx_pin.connect_peripheral_to_output(T::OUTPUT_SIGNAL, crate::private::Internal);
|
||||||
|
rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal);
|
||||||
|
|
||||||
let mut cfg = TwaiConfiguration {
|
let mut cfg = TwaiConfiguration {
|
||||||
peripheral: PhantomData,
|
peripheral: PhantomData,
|
||||||
@ -775,6 +779,9 @@ impl<'d, T> TwaiConfiguration<'d, T, crate::Blocking>
|
|||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
|
/// Create a new instance of [TwaiConfiguration]
|
||||||
|
///
|
||||||
|
/// You will need to use a transceiver to connect to the TWAI bus
|
||||||
pub fn new<TX: OutputPin, RX: InputPin>(
|
pub fn new<TX: OutputPin, RX: InputPin>(
|
||||||
peripheral: impl Peripheral<P = T> + 'd,
|
peripheral: impl Peripheral<P = T> + 'd,
|
||||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||||
@ -783,7 +790,27 @@ where
|
|||||||
baud_rate: BaudRate,
|
baud_rate: BaudRate,
|
||||||
interrupt: Option<InterruptHandler>,
|
interrupt: Option<InterruptHandler>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_internal(peripheral, tx_pin, rx_pin, clocks, baud_rate, interrupt)
|
Self::new_internal(
|
||||||
|
peripheral, tx_pin, rx_pin, clocks, baud_rate, interrupt, false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new instance of [TwaiConfiguration] meant to connect two ESP32s
|
||||||
|
/// directly
|
||||||
|
///
|
||||||
|
/// You don't need a transceiver by following the description in the
|
||||||
|
/// `twai.rs` example
|
||||||
|
pub fn new_no_transceiver<TX: OutputPin, RX: InputPin>(
|
||||||
|
peripheral: impl Peripheral<P = T> + 'd,
|
||||||
|
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||||
|
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||||
|
clocks: &Clocks,
|
||||||
|
baud_rate: BaudRate,
|
||||||
|
interrupt: Option<InterruptHandler>,
|
||||||
|
) -> Self {
|
||||||
|
Self::new_internal(
|
||||||
|
peripheral, tx_pin, rx_pin, clocks, baud_rate, interrupt, true,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,6 +819,9 @@ impl<'d, T> TwaiConfiguration<'d, T, crate::Async>
|
|||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
|
/// Create a new instance of [TwaiConfiguration] in async mode
|
||||||
|
///
|
||||||
|
/// You will need to use a transceiver to connect to the TWAI bus
|
||||||
pub fn new_async<TX: OutputPin, RX: InputPin>(
|
pub fn new_async<TX: OutputPin, RX: InputPin>(
|
||||||
peripheral: impl Peripheral<P = T> + 'd,
|
peripheral: impl Peripheral<P = T> + 'd,
|
||||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||||
@ -807,6 +837,31 @@ where
|
|||||||
clocks,
|
clocks,
|
||||||
baud_rate,
|
baud_rate,
|
||||||
Some(interrupt),
|
Some(interrupt),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new instance of [TwaiConfiguration] meant to connect two ESP32s
|
||||||
|
/// directly in async mode
|
||||||
|
///
|
||||||
|
/// You don't need a transceiver by following the description in the
|
||||||
|
/// `twai.rs` example
|
||||||
|
pub fn new_async_no_transceiver<TX: OutputPin, RX: InputPin>(
|
||||||
|
peripheral: impl Peripheral<P = T> + 'd,
|
||||||
|
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||||
|
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||||
|
clocks: &Clocks,
|
||||||
|
baud_rate: BaudRate,
|
||||||
|
) -> Self {
|
||||||
|
let interrupt = T::async_handler();
|
||||||
|
Self::new_internal(
|
||||||
|
peripheral,
|
||||||
|
tx_pin,
|
||||||
|
rx_pin,
|
||||||
|
clocks,
|
||||||
|
baud_rate,
|
||||||
|
Some(interrupt),
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,7 @@
|
|||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//! let pins = TxRxPins::new_tx_rx(
|
//! let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2);
|
||||||
//! io.pins.gpio1.into_push_pull_output(),
|
|
||||||
//! io.pins.gpio2.into_floating_input(),
|
|
||||||
//! );
|
|
||||||
//!
|
//!
|
||||||
//! let mut uart1 =
|
//! let mut uart1 =
|
||||||
//! Uart::new_with_config(peripherals.UART1, Config::default(), Some(pins), &clocks);
|
//! Uart::new_with_config(peripherals.UART1, Config::default(), Some(pins), &clocks);
|
||||||
@ -332,21 +329,23 @@ impl<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> UartPins
|
|||||||
rts_signal: OutputSignal,
|
rts_signal: OutputSignal,
|
||||||
) {
|
) {
|
||||||
if let Some(ref mut tx) = self.tx {
|
if let Some(ref mut tx) = self.tx {
|
||||||
tx.set_to_push_pull_output()
|
tx.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(tx_signal);
|
tx.connect_peripheral_to_output(tx_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut rx) = self.rx {
|
if let Some(ref mut rx) = self.rx {
|
||||||
rx.set_to_input().connect_input_to_peripheral(rx_signal);
|
rx.set_to_input(crate::private::Internal);
|
||||||
|
rx.connect_input_to_peripheral(rx_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut cts) = self.cts {
|
if let Some(ref mut cts) = self.cts {
|
||||||
cts.set_to_input().connect_input_to_peripheral(cts_signal);
|
cts.set_to_input(crate::private::Internal);
|
||||||
|
cts.connect_input_to_peripheral(cts_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut rts) = self.rts {
|
if let Some(ref mut rts) = self.rts {
|
||||||
rts.set_to_push_pull_output()
|
rts.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(rts_signal);
|
rts.connect_peripheral_to_output(rts_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,12 +378,14 @@ impl<TX: OutputPin, RX: InputPin> UartPins for TxRxPins<'_, TX, RX> {
|
|||||||
_rts_signal: OutputSignal,
|
_rts_signal: OutputSignal,
|
||||||
) {
|
) {
|
||||||
if let Some(ref mut tx) = self.tx {
|
if let Some(ref mut tx) = self.tx {
|
||||||
tx.set_to_push_pull_output()
|
tx.set_to_push_pull_output(crate::private::Internal);
|
||||||
.connect_peripheral_to_output(tx_signal);
|
tx.set_output_high(true, crate::private::Internal);
|
||||||
|
tx.connect_peripheral_to_output(tx_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut rx) = self.rx {
|
if let Some(ref mut rx) = self.rx {
|
||||||
rx.set_to_input().connect_input_to_peripheral(rx_signal);
|
rx.set_to_input(crate::private::Internal);
|
||||||
|
rx.connect_input_to_peripheral(rx_signal, crate::private::Internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,10 +587,16 @@ where
|
|||||||
.modify(|_, w| w.err_wr_mask().set_bit());
|
.modify(|_, w| w.err_wr_mask().set_bit());
|
||||||
|
|
||||||
// Reset Tx/Rx FIFOs
|
// Reset Tx/Rx FIFOs
|
||||||
serial.txfifo_reset();
|
|
||||||
serial.rxfifo_reset();
|
serial.rxfifo_reset();
|
||||||
|
serial.txfifo_reset();
|
||||||
crate::rom::ets_delay_us(15);
|
crate::rom::ets_delay_us(15);
|
||||||
|
|
||||||
|
// Make sure we are starting in a "clean state" - previous operations might have
|
||||||
|
// run into error conditions
|
||||||
|
T::register_block()
|
||||||
|
.int_clr()
|
||||||
|
.write(|w| unsafe { w.bits(u32::MAX) });
|
||||||
|
|
||||||
serial
|
serial
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,9 +2117,9 @@ mod asynch {
|
|||||||
#[cfg(lp_uart)]
|
#[cfg(lp_uart)]
|
||||||
pub mod lp_uart {
|
pub mod lp_uart {
|
||||||
use crate::{
|
use crate::{
|
||||||
gpio::{lp_io::LowPowerPin, Floating, Input, Output, PushPull},
|
gpio::lp_io::{LowPowerInput, LowPowerOutput},
|
||||||
peripherals::{LP_CLKRST, LP_UART},
|
peripherals::{LP_CLKRST, LP_UART},
|
||||||
uart::{config, config::Config},
|
uart::config::{self, Config},
|
||||||
};
|
};
|
||||||
/// LP-UART driver
|
/// LP-UART driver
|
||||||
///
|
///
|
||||||
@ -2124,11 +2131,7 @@ pub mod lp_uart {
|
|||||||
impl LpUart {
|
impl LpUart {
|
||||||
/// Initialize the UART driver using the default configuration
|
/// Initialize the UART driver using the default configuration
|
||||||
// TODO: CTS and RTS pins
|
// TODO: CTS and RTS pins
|
||||||
pub fn new(
|
pub fn new(uart: LP_UART, _tx: LowPowerOutput<5>, _rx: LowPowerInput<4>) -> Self {
|
||||||
uart: LP_UART,
|
|
||||||
_tx: LowPowerPin<Output<PushPull>, 5>,
|
|
||||||
_rx: LowPowerPin<Input<Floating>, 4>,
|
|
||||||
) -> Self {
|
|
||||||
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
let lp_io = unsafe { &*crate::peripherals::LP_IO::PTR };
|
||||||
let lp_aon = unsafe { &*crate::peripherals::LP_AON::PTR };
|
let lp_aon = unsafe { &*crate::peripherals::LP_AON::PTR };
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
[alias]
|
||||||
|
esp32c6 = "build --release --examples --features=esp32c6 --target riscv32imac-unknown-none-elf"
|
||||||
|
esp32s2 = "build --release --example=blinky --features=esp32s2 --target riscv32imc-unknown-none-elf"
|
||||||
|
esp32s3 = "build --release --example=blinky --features=esp32s3 --target riscv32imc-unknown-none-elf"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
# target = "riscv32imc-unknown-none-elf" # ESP32-S2 + ESP32-S3
|
# target = "riscv32imc-unknown-none-elf" # ESP32-S2 + ESP32-S3
|
||||||
target = "riscv32imac-unknown-none-elf" # ESP32-C6
|
target = "riscv32imac-unknown-none-elf" # ESP32-C6
|
||||||
|
|
||||||
[target.'cfg(target_arch = "riscv32")']
|
[target.'cfg(target_arch = "riscv32")']
|
||||||
runner = "espflash flash --monitor"
|
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Tlink.x",
|
||||||
]
|
]
|
||||||
|
@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Renamed to `esp-ulp-riscv-hal` (#916)
|
- Renamed to `esp-ulp-riscv-hal` (#916)
|
||||||
|
- Remove 2nd level generics from GPIO pin (#1526)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -11,11 +11,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::{blocking::delay::DelayMs, digital::v2::OutputPin};
|
use embedded_hal_02::{blocking::delay::DelayMs, digital::v2::OutputPin};
|
||||||
use esp_lp_hal::{
|
use esp_lp_hal::{delay::Delay, gpio::Output, prelude::*};
|
||||||
delay::Delay,
|
|
||||||
gpio::{GpioPin, Output, PushPull},
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
@ -27,7 +23,7 @@ cfg_if::cfg_if! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main(mut gpio1: GpioPin<Output<PushPull>, 1>) -> ! {
|
fn main(mut gpio1: Output<1>) -> ! {
|
||||||
let mut i: u32 = 0;
|
let mut i: u32 = 0;
|
||||||
|
|
||||||
let ptr = ADDRESS as *mut u32;
|
let ptr = ADDRESS as *mut u32;
|
||||||
|
@ -2,42 +2,24 @@
|
|||||||
//!
|
//!
|
||||||
//! It's assumed that GPIOs are already configured correctly by the HP core.
|
//! It's assumed that GPIOs are already configured correctly by the HP core.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
#[cfg(feature = "esp32c6")]
|
#[cfg(feature = "esp32c6")]
|
||||||
type LpIo = crate::pac::LP_IO;
|
type LpIo = crate::pac::LP_IO;
|
||||||
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
|
||||||
type LpIo = crate::pac::RTC_IO;
|
type LpIo = crate::pac::RTC_IO;
|
||||||
|
|
||||||
pub struct Unknown {}
|
#[non_exhaustive]
|
||||||
|
pub struct Input<const PIN: u8> {}
|
||||||
|
|
||||||
pub struct Input<MODE> {
|
impl<const PIN: u8> Input<PIN> {
|
||||||
_mode: PhantomData<MODE>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Floating;
|
|
||||||
|
|
||||||
pub struct PullDown;
|
|
||||||
|
|
||||||
pub struct PullUp;
|
|
||||||
|
|
||||||
pub struct Output<MODE> {
|
|
||||||
_mode: PhantomData<MODE>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PushPull;
|
|
||||||
|
|
||||||
pub struct GpioPin<MODE, const PIN: u8> {
|
|
||||||
phantom: PhantomData<MODE>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<MODE, const PIN: u8> GpioPin<Input<MODE>, PIN> {
|
|
||||||
pub fn input_state(&self) -> bool {
|
pub fn input_state(&self) -> bool {
|
||||||
unsafe { &*LpIo::PTR }.in_().read().bits() >> PIN & 0x1 != 0
|
unsafe { &*LpIo::PTR }.in_().read().bits() >> PIN & 0x1 != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MODE, const PIN: u8> GpioPin<Output<MODE>, PIN> {
|
#[non_exhaustive]
|
||||||
|
pub struct Output<const PIN: u8> {}
|
||||||
|
|
||||||
|
impl<const PIN: u8> Output<PIN> {
|
||||||
pub fn output_state(&self) -> bool {
|
pub fn output_state(&self) -> bool {
|
||||||
unsafe { &*LpIo::PTR }.out().read().bits() >> PIN & 0x1 != 0
|
unsafe { &*LpIo::PTR }.out().read().bits() >> PIN & 0x1 != 0
|
||||||
}
|
}
|
||||||
@ -57,18 +39,26 @@ impl<MODE, const PIN: u8> GpioPin<Output<MODE>, PIN> {
|
|||||||
|
|
||||||
// Used by the `entry` procmacro:
|
// Used by the `entry` procmacro:
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub unsafe fn conjure<MODE, const PIN: u8>() -> Option<GpioPin<MODE, PIN>> {
|
pub unsafe fn conjure_output<const PIN: u8>() -> Option<Output<PIN>> {
|
||||||
if PIN > 7 {
|
if PIN > 7 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(GpioPin {
|
Some(Output {})
|
||||||
phantom: PhantomData,
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// Used by the `entry` procmacro:
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub unsafe fn conjure_input<const PIN: u8>() -> Option<Input<PIN>> {
|
||||||
|
if PIN > 7 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Input {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::InputPin for GpioPin<Input<MODE>, PIN> {
|
impl<const PIN: u8> embedded_hal_02::digital::v2::InputPin for Input<PIN> {
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
@ -81,7 +71,7 @@ impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::InputPin for GpioPin<Inp
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::OutputPin for GpioPin<Output<MODE>, PIN> {
|
impl<const PIN: u8> embedded_hal_02::digital::v2::OutputPin for Output<PIN> {
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
@ -96,9 +86,7 @@ impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::OutputPin for GpioPin<Ou
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin
|
impl<const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin for Output<PIN> {
|
||||||
for GpioPin<Output<MODE>, PIN>
|
|
||||||
{
|
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
Ok(self.output_state())
|
Ok(self.output_state())
|
||||||
}
|
}
|
||||||
@ -109,18 +97,20 @@ impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::toggleable::Default
|
impl<const PIN: u8> embedded_hal_02::digital::v2::toggleable::Default for Output<PIN> {}
|
||||||
for GpioPin<Output<MODE>, PIN>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-1")]
|
#[cfg(feature = "embedded-hal-1")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_1::digital::ErrorType for GpioPin<MODE, PIN> {
|
impl<const PIN: u8> embedded_hal_1::digital::ErrorType for Input<PIN> {
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-1")]
|
#[cfg(feature = "embedded-hal-1")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_1::digital::InputPin for GpioPin<Input<MODE>, PIN> {
|
impl<const PIN: u8> embedded_hal_1::digital::ErrorType for Output<PIN> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-hal-1")]
|
||||||
|
impl<const PIN: u8> embedded_hal_1::digital::InputPin for Input<PIN> {
|
||||||
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
Ok(self.input_state())
|
Ok(self.input_state())
|
||||||
}
|
}
|
||||||
@ -131,7 +121,7 @@ impl<MODE, const PIN: u8> embedded_hal_1::digital::InputPin for GpioPin<Input<MO
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-1")]
|
#[cfg(feature = "embedded-hal-1")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_1::digital::OutputPin for GpioPin<Output<MODE>, PIN> {
|
impl<const PIN: u8> embedded_hal_1::digital::OutputPin for Output<PIN> {
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
self.set_output(false);
|
self.set_output(false);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -144,9 +134,7 @@ impl<MODE, const PIN: u8> embedded_hal_1::digital::OutputPin for GpioPin<Output<
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-1")]
|
#[cfg(feature = "embedded-hal-1")]
|
||||||
impl<MODE, const PIN: u8> embedded_hal_1::digital::StatefulOutputPin
|
impl<const PIN: u8> embedded_hal_1::digital::StatefulOutputPin for Output<PIN> {
|
||||||
for GpioPin<Output<MODE>, PIN>
|
|
||||||
{
|
|
||||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
Ok(self.output_state())
|
Ok(self.output_state())
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,11 @@ fn main() -> ! {
|
|||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "esp32")] {
|
if #[cfg(feature = "esp32")] {
|
||||||
let analog_pin = io.pins.gpio32.into_analog();
|
let analog_pin = io.pins.gpio32;
|
||||||
} else if #[cfg(any(feature = "esp32s2", feature = "esp32s3"))] {
|
} else if #[cfg(any(feature = "esp32s2", feature = "esp32s3"))] {
|
||||||
let analog_pin = io.pins.gpio3.into_analog();
|
let analog_pin = io.pins.gpio3;
|
||||||
} else {
|
} else {
|
||||||
let analog_pin = io.pins.gpio2.into_analog();
|
let analog_pin = io.pins.gpio2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ fn main() -> ! {
|
|||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "esp32s3")] {
|
if #[cfg(feature = "esp32s3")] {
|
||||||
let analog_pin = io.pins.gpio3.into_analog();
|
let analog_pin = io.pins.gpio3;
|
||||||
} else {
|
} else {
|
||||||
let analog_pin = io.pins.gpio2.into_analog();
|
let analog_pin = io.pins.gpio2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ fn main() -> ! {
|
|||||||
// them. Note that only AdcCalLine returns readings in mV; the other two
|
// them. Note that only AdcCalLine returns readings in mV; the other two
|
||||||
// return raw readings in some unspecified scale.
|
// return raw readings in some unspecified scale.
|
||||||
//
|
//
|
||||||
type AdcCal = ();
|
//type AdcCal = ();
|
||||||
// type AdcCal = esp_hal::analog::adc::AdcCalBasic<ADC1>;
|
type AdcCal = esp_hal::analog::adc::AdcCalBasic<esp_hal::peripherals::ADC1>;
|
||||||
// type AdcCal = esp_hal::analog::adc::AdcCalLine<ADC1>;
|
// type AdcCal = esp_hal::analog::adc::AdcCalLine<ADC1>;
|
||||||
// type AdcCal = esp_hal::analog::adc::AdcCalCurve<ADC1>;
|
// type AdcCal = esp_hal::analog::adc::AdcCalCurve<ADC1>;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! This shows how to configure UART
|
//! This shows how to configure UART
|
||||||
//! You can short the TX and RX pin and see it reads what was written.
|
//! You can short the TX and RX pin and see it reads what was written.
|
||||||
//! Additionally you can connect a logic analzyer to TX and see how the changes
|
//! Additionally you can connect a logic analyzer to TX and see how the changes
|
||||||
//! of the configuration change the output signal.
|
//! of the configuration change the output signal.
|
||||||
//!
|
//!
|
||||||
//! The following wiring is assumed:
|
//! The following wiring is assumed:
|
||||||
@ -32,10 +32,7 @@ fn main() -> ! {
|
|||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let pins = TxRxPins::new_tx_rx(
|
let pins = TxRxPins::new_tx_rx(io.pins.gpio4, io.pins.gpio5);
|
||||||
io.pins.gpio4.into_push_pull_output(),
|
|
||||||
io.pins.gpio5.into_floating_input(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serial1 = Uart::new_with_config(
|
let mut serial1 = Uart::new_with_config(
|
||||||
peripherals.UART1,
|
peripherals.UART1,
|
||||||
|
@ -11,7 +11,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::Io,
|
gpio::{Io, Output},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
@ -25,9 +25,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// Set GPIO0 as an output, and set its state high initially.
|
// Set GPIO0 as an output, and set its state high initially.
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut led = io.pins.gpio8.into_push_pull_output();
|
let mut led = Output::new(io.pins.gpio0, true);
|
||||||
|
|
||||||
led.set_high();
|
|
||||||
|
|
||||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||||
// loop.
|
// loop.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Blinks 3 LEDs
|
//! Blinks 3 LEDs
|
||||||
//!
|
//!
|
||||||
//! This assumes that LEDs are connected to GPIO8, 9 and 10.
|
//! This assumes that LEDs are connected to GPIO2, 4 and 5.
|
||||||
//!
|
//!
|
||||||
//! GPIO1 is treated as an input, and will print a message when pressed. This
|
//! GPIO1 is treated as an input, and will print a message when pressed. This
|
||||||
//! Additionally demonstrates passing GPIO to a function in a generic way.
|
//! Additionally demonstrates passing GPIO to a function in a generic way.
|
||||||
@ -14,7 +14,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::{AnyPin, Input, Io, Output, PullDown, PushPull},
|
gpio::{AnyInput, AnyOutput, Io, Pull},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
@ -29,15 +29,20 @@ fn main() -> ! {
|
|||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
// Set LED GPIOs as an output:
|
// Set LED GPIOs as an output:
|
||||||
let led1 = io.pins.gpio8.into_push_pull_output();
|
let led1 = AnyOutput::new(io.pins.gpio2, false);
|
||||||
let led2 = io.pins.gpio9.into_push_pull_output();
|
let led2 = AnyOutput::new(io.pins.gpio4, false);
|
||||||
let led3 = io.pins.gpio10.into_push_pull_output();
|
let led3 = AnyOutput::new(io.pins.gpio5, false);
|
||||||
|
|
||||||
// Set GPIO0 as an input:
|
// Use boot button as an input:
|
||||||
let button = io.pins.gpio0.into_pull_down_input().into();
|
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||||
|
let button = io.pins.gpio0;
|
||||||
|
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||||
|
let button = io.pins.gpio9;
|
||||||
|
|
||||||
|
let button = AnyInput::new(button, Pull::Up);
|
||||||
|
|
||||||
// You can use `into` or `degrade`:
|
// You can use `into` or `degrade`:
|
||||||
let mut pins = [led1.into(), led2.into(), led3.degrade().into()];
|
let mut pins = [led1, led2, led3];
|
||||||
|
|
||||||
// Initialize the `Delay` peripheral, and use it to toggle the LED state
|
// Initialize the `Delay` peripheral, and use it to toggle the LED state
|
||||||
// in a loop:
|
// in a loop:
|
||||||
@ -49,7 +54,7 @@ fn main() -> ! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_pins(leds: &mut [AnyPin<Output<PushPull>>], button: &AnyPin<Input<PullDown>>) {
|
fn toggle_pins(leds: &mut [AnyOutput], button: &AnyInput) {
|
||||||
for pin in leds.iter_mut() {
|
for pin in leds.iter_mut() {
|
||||||
pin.toggle();
|
pin.toggle();
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,11 @@ fn main() -> ! {
|
|||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "esp32")] {
|
if #[cfg(feature = "esp32")] {
|
||||||
let dac1_pin = io.pins.gpio25.into_analog();
|
let dac1_pin = io.pins.gpio25;
|
||||||
let dac2_pin = io.pins.gpio26.into_analog();
|
let dac2_pin = io.pins.gpio26;
|
||||||
} else if #[cfg(feature = "esp32s2")] {
|
} else if #[cfg(feature = "esp32s2")] {
|
||||||
let dac1_pin = io.pins.gpio17.into_analog();
|
let dac1_pin = io.pins.gpio17;
|
||||||
let dac2_pin = io.pins.gpio18.into_analog();
|
let dac2_pin = io.pins.gpio18;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ use esp_hal::{
|
|||||||
cpu_control::{CpuControl, Stack},
|
cpu_control::{CpuControl, Stack},
|
||||||
embassy::{self, executor::Executor},
|
embassy::{self, executor::Executor},
|
||||||
get_core,
|
get_core,
|
||||||
gpio::{GpioPin, Io, Output, PushPull},
|
gpio::{AnyOutput, Io},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
|||||||
/// duration of time.
|
/// duration of time.
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn control_led(
|
async fn control_led(
|
||||||
mut led: GpioPin<Output<PushPull>, 0>,
|
mut led: AnyOutput<'static>,
|
||||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||||
) {
|
) {
|
||||||
println!("Starting control_led() on core {}", get_core() as usize);
|
println!("Starting control_led() on core {}", get_core() as usize);
|
||||||
@ -66,7 +66,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
||||||
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
||||||
|
|
||||||
let led = io.pins.gpio0.into_push_pull_output();
|
let led = AnyOutput::new(io.pins.gpio0, false);
|
||||||
|
|
||||||
let _guard = cpu_control
|
let _guard = cpu_control
|
||||||
.start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || {
|
.start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || {
|
||||||
|
@ -19,7 +19,7 @@ use esp_hal::{
|
|||||||
cpu_control::{CpuControl, Stack},
|
cpu_control::{CpuControl, Stack},
|
||||||
embassy::{self, executor::InterruptExecutor},
|
embassy::{self, executor::InterruptExecutor},
|
||||||
get_core,
|
get_core,
|
||||||
gpio::{GpioPin, Io, Output, PushPull},
|
gpio::{AnyOutput, Io},
|
||||||
interrupt::Priority,
|
interrupt::Priority,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
|||||||
/// duration of time.
|
/// duration of time.
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn control_led(
|
async fn control_led(
|
||||||
mut led: GpioPin<Output<PushPull>, 0>,
|
mut led: AnyOutput<'static>,
|
||||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||||
) {
|
) {
|
||||||
println!("Starting control_led() on core {}", get_core() as usize);
|
println!("Starting control_led() on core {}", get_core() as usize);
|
||||||
@ -85,7 +85,7 @@ fn main() -> ! {
|
|||||||
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
||||||
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
||||||
|
|
||||||
let led = io.pins.gpio0.into_push_pull_output();
|
let led = AnyOutput::new(io.pins.gpio0, false);
|
||||||
|
|
||||||
static EXECUTOR_CORE_1: StaticCell<InterruptExecutor<1>> = StaticCell::new();
|
static EXECUTOR_CORE_1: StaticCell<InterruptExecutor<1>> = StaticCell::new();
|
||||||
let executor_core1 =
|
let executor_core1 =
|
||||||
|
@ -13,7 +13,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
embassy::{self},
|
embassy::{self},
|
||||||
gpio::{Gpio5, Io, Output, PushPull},
|
gpio::{Gpio5, Io, Output},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rmt::{asynch::RxChannelAsync, PulseCode, Rmt, RxChannelConfig, RxChannelCreatorAsync},
|
rmt::{asynch::RxChannelAsync, PulseCode, Rmt, RxChannelConfig, RxChannelCreatorAsync},
|
||||||
@ -27,7 +27,7 @@ const WIDTH: usize = 80;
|
|||||||
compile_error!("Run this example in release mode");
|
compile_error!("Run this example in release mode");
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn signal_task(mut pin: Gpio5<Output<PushPull>>) {
|
async fn signal_task(mut pin: Output<'static, Gpio5>) {
|
||||||
loop {
|
loop {
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
pin.toggle();
|
pin.toggle();
|
||||||
@ -75,7 +75,7 @@ async fn main(spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spawner
|
spawner
|
||||||
.spawn(signal_task(io.pins.gpio5.into_push_pull_output()))
|
.spawn(signal_task(Output::new(io.pins.gpio5, false)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut data = [PulseCode {
|
let mut data = [PulseCode {
|
||||||
|
@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut channel = rmt
|
let mut channel = rmt
|
||||||
.channel0
|
.channel0
|
||||||
.configure(
|
.configure(
|
||||||
io.pins.gpio4.into_push_pull_output(),
|
io.pins.gpio4,
|
||||||
TxChannelConfig {
|
TxChannelConfig {
|
||||||
clk_divider: 255,
|
clk_divider: 255,
|
||||||
..TxChannelConfig::default()
|
..TxChannelConfig::default()
|
||||||
|
@ -91,16 +91,17 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
// Set the tx pin as open drain. Skip this if using transceivers.
|
let can_tx_pin = io.pins.gpio0;
|
||||||
let can_tx_pin = io.pins.gpio0.into_open_drain_output();
|
|
||||||
let can_rx_pin = io.pins.gpio2;
|
let can_rx_pin = io.pins.gpio2;
|
||||||
|
|
||||||
// The speed of the CAN bus.
|
// The speed of the CAN bus.
|
||||||
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
||||||
|
|
||||||
|
// !!! Use `new_async` when using a transceiver. `new_async_no_transceiver` sets TX to open-drain
|
||||||
|
|
||||||
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
||||||
// state that prevents transmission but allows configuration.
|
// state that prevents transmission but allows configuration.
|
||||||
let mut can_config = twai::TwaiConfiguration::new_async(
|
let mut can_config = twai::TwaiConfiguration::new_async_no_transceiver(
|
||||||
peripherals.TWAI0,
|
peripherals.TWAI0,
|
||||||
can_tx_pin,
|
can_tx_pin,
|
||||||
can_rx_pin,
|
can_rx_pin,
|
||||||
|
@ -13,8 +13,8 @@ use embassy_time::{Duration, Timer};
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
embassy::{self},
|
embassy,
|
||||||
gpio::Io,
|
gpio::{Input, Io, Pull},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
@ -33,9 +33,9 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||||
let mut input = io.pins.gpio0.into_pull_down_input();
|
let mut input = Input::new(io.pins.gpio0, Pull::Down);
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||||
let mut input = io.pins.gpio9.into_pull_down_input();
|
let mut input = Input::new(io.pins.gpio9, Pull::Down);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
esp_println::println!("Waiting...");
|
esp_println::println!("Waiting...");
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
etm::Etm,
|
etm::Etm,
|
||||||
gpio::{etm::GpioEtmChannels, Io},
|
gpio::{
|
||||||
|
etm::{GpioEtmChannels, GpioEtmOutputConfig},
|
||||||
|
Io,
|
||||||
|
Pull,
|
||||||
|
},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
timer::systimer::{etm::SysTimerEtmEvent, SystemTimer},
|
timer::systimer::{etm::SysTimerEtmEvent, SystemTimer},
|
||||||
@ -24,11 +28,18 @@ fn main() -> ! {
|
|||||||
alarm0.set_period(1u32.secs());
|
alarm0.set_period(1u32.secs());
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut led = io.pins.gpio1.into_push_pull_output();
|
let mut led = io.pins.gpio1;
|
||||||
|
|
||||||
// setup ETM
|
// setup ETM
|
||||||
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||||
let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
let led_task = gpio_ext.channel0_task.toggle(
|
||||||
|
&mut led,
|
||||||
|
GpioEtmOutputConfig {
|
||||||
|
open_drain: false,
|
||||||
|
pull: Pull::None,
|
||||||
|
initial_state: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let timer_event = SysTimerEtmEvent::new(&mut alarm0);
|
let timer_event = SysTimerEtmEvent::new(&mut alarm0);
|
||||||
|
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
etm::Etm,
|
etm::Etm,
|
||||||
gpio::{etm::GpioEtmChannels, Io},
|
gpio::{
|
||||||
|
etm::{GpioEtmChannels, GpioEtmInputConfig, GpioEtmOutputConfig},
|
||||||
|
Io,
|
||||||
|
Pull,
|
||||||
|
},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
@ -18,15 +22,24 @@ fn main() -> ! {
|
|||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut led = io.pins.gpio1.into_push_pull_output();
|
let mut led = io.pins.gpio1;
|
||||||
let button = io.pins.gpio9.into_pull_down_input();
|
let button = io.pins.gpio9;
|
||||||
|
|
||||||
led.set_high();
|
led.set_high();
|
||||||
|
|
||||||
// setup ETM
|
// setup ETM
|
||||||
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||||
let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
let led_task = gpio_ext.channel0_task.toggle(
|
||||||
let button_event = gpio_ext.channel0_event.falling_edge(button);
|
&mut led,
|
||||||
|
GpioEtmOutputConfig {
|
||||||
|
open_drain: false,
|
||||||
|
pull: Pull::None,
|
||||||
|
initial_state: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let button_event = gpio_ext
|
||||||
|
.channel0_event
|
||||||
|
.falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
|
||||||
|
|
||||||
let etm = Etm::new(peripherals.SOC_ETM);
|
let etm = Etm::new(peripherals.SOC_ETM);
|
||||||
let channel0 = etm.channel0;
|
let channel0 = etm.channel0;
|
||||||
|
@ -15,7 +15,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::{self, Event, Input, Io, PullDown},
|
gpio::{self, Event, Input, Io, Output, Pull},
|
||||||
macros::ram,
|
macros::ram,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -23,11 +23,9 @@ use esp_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||||
static BUTTON: Mutex<RefCell<Option<gpio::Gpio0<Input<PullDown>>>>> =
|
static BUTTON: Mutex<RefCell<Option<Input<gpio::Gpio0>>>> = Mutex::new(RefCell::new(None));
|
||||||
Mutex::new(RefCell::new(None));
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||||
static BUTTON: Mutex<RefCell<Option<gpio::Gpio9<Input<PullDown>>>>> =
|
static BUTTON: Mutex<RefCell<Option<Input<gpio::Gpio9>>>> = Mutex::new(RefCell::new(None));
|
||||||
Mutex::new(RefCell::new(None));
|
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
@ -38,12 +36,14 @@ fn main() -> ! {
|
|||||||
// Set GPIO2 as an output, and set its state high initially.
|
// Set GPIO2 as an output, and set its state high initially.
|
||||||
let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
io.set_interrupt_handler(handler);
|
io.set_interrupt_handler(handler);
|
||||||
let mut led = io.pins.gpio2.into_push_pull_output();
|
let mut led = Output::new(io.pins.gpio2, false);
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||||
let mut button = io.pins.gpio0.into_pull_down_input();
|
let button = io.pins.gpio0;
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||||
let mut button = io.pins.gpio9.into_pull_down_input();
|
let button = io.pins.gpio9;
|
||||||
|
|
||||||
|
let mut button = Input::new(button, Pull::Up);
|
||||||
|
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
button.listen(Event::FallingEdge);
|
button.listen(Event::FallingEdge);
|
||||||
|
@ -28,7 +28,7 @@ use esp_hal::{
|
|||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::Io,
|
gpio::{Io, Output},
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
lcd::i8080::{Config, TxEightBits, I8080},
|
lcd::i8080::{Config, TxEightBits, I8080},
|
||||||
LcdCam,
|
LcdCam,
|
||||||
@ -67,8 +67,8 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let delay = Delay::new(&clocks);
|
let delay = Delay::new(&clocks);
|
||||||
|
|
||||||
let mut backlight = lcd_backlight.into_push_pull_output();
|
let mut backlight = Output::new(lcd_backlight, false);
|
||||||
let mut reset = lcd_reset.into_push_pull_output();
|
let mut reset = Output::new(lcd_reset, false);
|
||||||
|
|
||||||
let tx_pins = TxEightBits::new(
|
let tx_pins = TxEightBits::new(
|
||||||
io.pins.gpio9,
|
io.pins.gpio9,
|
||||||
|
@ -31,7 +31,7 @@ fn main() -> ! {
|
|||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let led = io.pins.gpio0.into_push_pull_output();
|
let led = io.pins.gpio0;
|
||||||
|
|
||||||
let mut ledc = Ledc::new(peripherals.LEDC, &clocks);
|
let mut ledc = Ledc::new(peripherals.LEDC, &clocks);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
gpio::{lp_io::LowPowerOutput, Io},
|
||||||
lp_core::{LpCore, LpCoreWakeupSource},
|
lp_core::{LpCore, LpCoreWakeupSource},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -25,7 +25,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// configure GPIO 1 as LP output pin
|
// configure GPIO 1 as LP output pin
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let lp_pin = io.pins.gpio1.into_low_power().into_push_pull_output();
|
let lp_pin = LowPowerOutput::new(io.pins.gpio1);
|
||||||
|
|
||||||
let mut lp_core = LpCore::new(peripherals.LP_CORE);
|
let mut lp_core = LpCore::new(peripherals.LP_CORE);
|
||||||
lp_core.stop();
|
lp_core.stop();
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
gpio::{lp_io::LowPowerOutputOpenDrain, Io},
|
||||||
i2c::lp_i2c::LpI2c,
|
i2c::lp_i2c::LpI2c,
|
||||||
lp_core::{LpCore, LpCoreWakeupSource},
|
lp_core::{LpCore, LpCoreWakeupSource},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
@ -26,8 +26,8 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
let lp_sda = io.pins.gpio6.into_low_power().into_open_drain_output();
|
let lp_sda = LowPowerOutputOpenDrain::new(io.pins.gpio6);
|
||||||
let lp_scl = io.pins.gpio7.into_low_power().into_open_drain_output();
|
let lp_scl = LowPowerOutputOpenDrain::new(io.pins.gpio7);
|
||||||
|
|
||||||
let lp_i2c = LpI2c::new(peripherals.LP_I2C0, lp_sda, lp_scl, 100.kHz());
|
let lp_i2c = LpI2c::new(peripherals.LP_I2C0, lp_sda, lp_scl, 100.kHz());
|
||||||
|
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
gpio::{
|
||||||
|
lp_io::{LowPowerInput, LowPowerOutput},
|
||||||
|
Io,
|
||||||
|
},
|
||||||
lp_core::{LpCore, LpCoreWakeupSource},
|
lp_core::{LpCore, LpCoreWakeupSource},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -32,10 +35,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// Set up (HP) UART1:
|
// Set up (HP) UART1:
|
||||||
|
|
||||||
let pins = TxRxPins::new_tx_rx(
|
let pins = TxRxPins::new_tx_rx(io.pins.gpio6, io.pins.gpio7);
|
||||||
io.pins.gpio6.into_push_pull_output(),
|
|
||||||
io.pins.gpio7.into_floating_input(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut uart1 = Uart::new_with_config(
|
let mut uart1 = Uart::new_with_config(
|
||||||
peripherals.UART1,
|
peripherals.UART1,
|
||||||
@ -46,8 +46,8 @@ fn main() -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Set up (LP) UART:
|
// Set up (LP) UART:
|
||||||
let lp_tx = io.pins.gpio5.into_low_power().into_push_pull_output();
|
let lp_tx = LowPowerOutput::new(io.pins.gpio5);
|
||||||
let lp_rx = io.pins.gpio4.into_low_power().into_floating_input();
|
let lp_rx = LowPowerInput::new(io.pins.gpio4);
|
||||||
let lp_uart = LpUart::new(peripherals.LP_UART, lp_tx, lp_rx);
|
let lp_uart = LpUart::new(peripherals.LP_UART, lp_tx, lp_rx);
|
||||||
|
|
||||||
let mut lp_core = LpCore::new(peripherals.LP_CORE);
|
let mut lp_core = LpCore::new(peripherals.LP_CORE);
|
||||||
|
@ -16,9 +16,13 @@ use core::{cell::RefCell, cmp::min, sync::atomic::Ordering};
|
|||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
gpio::Io,
|
gpio::{Io, Pull},
|
||||||
interrupt::Priority,
|
interrupt::Priority,
|
||||||
pcnt::{channel, channel::PcntSource, unit, Pcnt},
|
pcnt::{
|
||||||
|
channel::{self, PcntInputConfig, PcntSource},
|
||||||
|
unit,
|
||||||
|
Pcnt,
|
||||||
|
},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
@ -48,12 +52,12 @@ fn main() -> ! {
|
|||||||
|
|
||||||
println!("setup channel 0");
|
println!("setup channel 0");
|
||||||
let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
||||||
let mut pin_a = io.pins.gpio4.into_pull_up_input();
|
let mut pin_a = io.pins.gpio4;
|
||||||
let mut pin_b = io.pins.gpio5.into_pull_up_input();
|
let mut pin_b = io.pins.gpio5;
|
||||||
|
|
||||||
ch0.configure(
|
ch0.configure(
|
||||||
PcntSource::from_pin(&mut pin_a),
|
PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||||
PcntSource::from_pin(&mut pin_b),
|
PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||||
channel::Config {
|
channel::Config {
|
||||||
lctrl_mode: channel::CtrlMode::Reverse,
|
lctrl_mode: channel::CtrlMode::Reverse,
|
||||||
hctrl_mode: channel::CtrlMode::Keep,
|
hctrl_mode: channel::CtrlMode::Keep,
|
||||||
@ -67,8 +71,8 @@ fn main() -> ! {
|
|||||||
println!("setup channel 1");
|
println!("setup channel 1");
|
||||||
let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
||||||
ch1.configure(
|
ch1.configure(
|
||||||
PcntSource::from_pin(&mut pin_b),
|
PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||||
PcntSource::from_pin(&mut pin_a),
|
PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||||
channel::Config {
|
channel::Config {
|
||||||
lctrl_mode: channel::CtrlMode::Reverse,
|
lctrl_mode: channel::CtrlMode::Reverse,
|
||||||
hctrl_mode: channel::CtrlMode::Keep,
|
hctrl_mode: channel::CtrlMode::Keep,
|
||||||
|
@ -27,7 +27,7 @@ fn main() -> ! {
|
|||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut out = io.pins.gpio5.into_push_pull_output();
|
let mut out = io.pins.gpio5;
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "esp32h2")] {
|
if #[cfg(feature = "esp32h2")] {
|
||||||
|
@ -13,7 +13,6 @@ use esp_hal::{
|
|||||||
delay::Delay,
|
delay::Delay,
|
||||||
entry,
|
entry,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
rtc_cntl::{get_reset_reason, get_wakeup_cause, sleep::TimerWakeupSource, Rtc, SocResetReason},
|
rtc_cntl::{get_reset_reason, get_wakeup_cause, sleep::TimerWakeupSource, Rtc, SocResetReason},
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
Cpu,
|
Cpu,
|
||||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
|||||||
entry,
|
entry,
|
||||||
gpio::Io,
|
gpio::Io,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
rtc_cntl::{
|
rtc_cntl::{
|
||||||
get_reset_reason,
|
get_reset_reason,
|
||||||
get_wakeup_cause,
|
get_wakeup_cause,
|
||||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
|||||||
entry,
|
entry,
|
||||||
gpio::{Io, RtcPin},
|
gpio::{Io, RtcPin},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
rtc_cntl::{
|
rtc_cntl::{
|
||||||
get_reset_reason,
|
get_reset_reason,
|
||||||
get_wakeup_cause,
|
get_wakeup_cause,
|
||||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
|||||||
entry,
|
entry,
|
||||||
gpio::{Io, RtcPinWithResistors},
|
gpio::{Io, RtcPinWithResistors},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
rtc_cntl::{
|
rtc_cntl::{
|
||||||
get_reset_reason,
|
get_reset_reason,
|
||||||
get_wakeup_cause,
|
get_wakeup_cause,
|
||||||
|
@ -16,7 +16,6 @@ use esp_hal::{
|
|||||||
gpio,
|
gpio,
|
||||||
gpio::Io,
|
gpio::Io,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
rtc_cntl::{
|
rtc_cntl::{
|
||||||
get_reset_reason,
|
get_reset_reason,
|
||||||
get_wakeup_cause,
|
get_wakeup_cause,
|
||||||
|
@ -37,7 +37,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::{self, Io},
|
gpio::{self, Io, Output},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{master::Spi, SpiMode},
|
spi::{master::Spi, SpiMode},
|
||||||
@ -63,20 +63,19 @@ fn main() -> ! {
|
|||||||
gpio::NO_PIN,
|
gpio::NO_PIN,
|
||||||
);
|
);
|
||||||
let spi_bus = RefCell::new(spi_bus);
|
let spi_bus = RefCell::new(spi_bus);
|
||||||
let mut spi_device_1 =
|
let mut spi_device_1 = RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio5, false));
|
||||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "esp32")] {
|
if #[cfg(feature = "esp32")] {
|
||||||
let mut spi_device_2 =
|
let mut spi_device_2 =
|
||||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio13.into_push_pull_output());
|
RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio13, false));
|
||||||
let mut spi_device_3 =
|
let mut spi_device_3 =
|
||||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio14.into_push_pull_output());
|
RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio14,false));
|
||||||
} else {
|
} else {
|
||||||
let mut spi_device_2 =
|
let mut spi_device_2 =
|
||||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio6.into_push_pull_output());
|
RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio6,false));
|
||||||
let mut spi_device_3 =
|
let mut spi_device_3 =
|
||||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio7.into_push_pull_output());
|
RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio7, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ use esp_backtrace as _;
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::Io,
|
gpio::{any_pin::AnyPin, Io},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{master::Spi, SpiMode},
|
spi::{master::Spi, SpiMode},
|
||||||
@ -42,6 +42,9 @@ fn main() -> ! {
|
|||||||
let mosi = io.pins.gpio4;
|
let mosi = io.pins.gpio4;
|
||||||
let cs = io.pins.gpio5;
|
let cs = io.pins.gpio5;
|
||||||
|
|
||||||
|
let miso = AnyPin::new(miso);
|
||||||
|
let mosi = AnyPin::new(mosi);
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks).with_pins(
|
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks).with_pins(
|
||||||
Some(sclk),
|
Some(sclk),
|
||||||
Some(mosi),
|
Some(mosi),
|
||||||
|
@ -34,7 +34,7 @@ use esp_hal::{
|
|||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::Io,
|
gpio::{Input, Io, Output, Pull},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
@ -53,13 +53,13 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let slave_sclk = io.pins.gpio0;
|
let slave_sclk = io.pins.gpio0;
|
||||||
let mut master_sclk = io.pins.gpio4.into_push_pull_output();
|
let mut master_sclk = Output::new(io.pins.gpio4, false);
|
||||||
let slave_miso = io.pins.gpio1;
|
let slave_miso = io.pins.gpio1;
|
||||||
let master_miso = io.pins.gpio5.into_floating_input();
|
let master_miso = Input::new(io.pins.gpio5, Pull::None);
|
||||||
let slave_mosi = io.pins.gpio2;
|
let slave_mosi = io.pins.gpio2;
|
||||||
let mut master_mosi = io.pins.gpio8.into_push_pull_output();
|
let mut master_mosi = Output::new(io.pins.gpio8, false);
|
||||||
let slave_cs = io.pins.gpio3;
|
let slave_cs = io.pins.gpio3;
|
||||||
let mut master_cs = io.pins.gpio9.into_push_pull_output();
|
let mut master_cs = Output::new(io.pins.gpio9, false);
|
||||||
master_cs.set_high();
|
master_cs.set_high();
|
||||||
master_sclk.set_low();
|
master_sclk.set_low();
|
||||||
master_mosi.set_low();
|
master_mosi.set_low();
|
||||||
|
@ -38,16 +38,17 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
// Set the tx pin as open drain. Skip this if using transceivers.
|
let can_tx_pin = io.pins.gpio0;
|
||||||
let can_tx_pin = io.pins.gpio0.into_open_drain_output();
|
|
||||||
let can_rx_pin = io.pins.gpio2;
|
let can_rx_pin = io.pins.gpio2;
|
||||||
|
|
||||||
// The speed of the CAN bus.
|
// The speed of the CAN bus.
|
||||||
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
||||||
|
|
||||||
|
// !!! Use `new` when using a transceiver. `new_no_transceiver` sets TX to open-drain
|
||||||
|
|
||||||
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
||||||
// state that prevents transmission but allows configuration.
|
// state that prevents transmission but allows configuration.
|
||||||
let mut can_config = twai::TwaiConfiguration::new(
|
let mut can_config = twai::TwaiConfiguration::new_no_transceiver(
|
||||||
peripherals.TWAI0,
|
peripherals.TWAI0,
|
||||||
can_tx_pin,
|
can_tx_pin,
|
||||||
can_rx_pin,
|
can_rx_pin,
|
||||||
|
@ -22,7 +22,7 @@ fn main() -> ! {
|
|||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let pin = io.pins.gpio1.into_low_power().into_push_pull_output();
|
let pin = LowPowerOutput::new(io.pins.gpio1);
|
||||||
|
|
||||||
let mut ulp_core = ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
let mut ulp_core = ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use esp_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
embassy,
|
embassy,
|
||||||
gpio::{GpioPin, Input, Io, Output, OutputPin, PullDown, PushPull, Unknown},
|
gpio::{Gpio2, Gpio4, GpioPin, Input, Io, Output, Pull},
|
||||||
macros::handler,
|
macros::handler,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
@ -26,16 +26,15 @@ use esp_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
|
static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
|
||||||
static INPUT_PIN: Mutex<RefCell<Option<esp_hal::gpio::Gpio2<Input<PullDown>>>>> =
|
static INPUT_PIN: Mutex<RefCell<Option<Input<'static, Gpio2>>>> = Mutex::new(RefCell::new(None));
|
||||||
Mutex::new(RefCell::new(None));
|
|
||||||
|
|
||||||
struct Context {
|
struct Context<'d> {
|
||||||
io2: GpioPin<Input<PullDown>, 2>,
|
io2: Input<'d, Gpio2>,
|
||||||
io4: GpioPin<Output<PushPull>, 4>,
|
io4: Output<'d, Gpio4>,
|
||||||
delay: Delay,
|
delay: Delay,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl<'d> Context<'d> {
|
||||||
pub fn init() -> Self {
|
pub fn init() -> Self {
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
@ -50,8 +49,8 @@ impl Context {
|
|||||||
embassy::init(&clocks, timg0);
|
embassy::init(&clocks, timg0);
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
io2: io.pins.gpio2.into_pull_down_input(),
|
io2: Input::new(io.pins.gpio2, Pull::Down),
|
||||||
io4: io.pins.gpio4.into_push_pull_output(),
|
io4: Output::new(io.pins.gpio4, false),
|
||||||
delay,
|
delay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,8 +59,6 @@ impl Context {
|
|||||||
#[handler]
|
#[handler]
|
||||||
pub fn interrupt_handler() {
|
pub fn interrupt_handler() {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
use esp_hal::gpio::Pin;
|
|
||||||
|
|
||||||
*COUNTER.borrow_ref_mut(cs) += 1;
|
*COUNTER.borrow_ref_mut(cs) += 1;
|
||||||
INPUT_PIN
|
INPUT_PIN
|
||||||
.borrow_ref_mut(cs)
|
.borrow_ref_mut(cs)
|
||||||
@ -75,13 +72,13 @@ pub fn interrupt_handler() {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use defmt::assert_eq;
|
use defmt::assert_eq;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_hal::gpio::{Event, Pin};
|
use esp_hal::gpio::{Event, OutputOpenDrain};
|
||||||
use portable_atomic::{AtomicUsize, Ordering};
|
use portable_atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init() -> Context {
|
fn init() -> Context<'static> {
|
||||||
let mut ctx = Context::init();
|
let mut ctx = Context::init();
|
||||||
// make sure tests don't interfere with each other
|
// make sure tests don't interfere with each other
|
||||||
ctx.io4.set_low();
|
ctx.io4.set_low();
|
||||||
@ -89,7 +86,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_async_edge(ctx: Context) {
|
async fn test_async_edge(ctx: Context<'static>) {
|
||||||
let counter = AtomicUsize::new(0);
|
let counter = AtomicUsize::new(0);
|
||||||
let Context {
|
let Context {
|
||||||
mut io2, mut io4, ..
|
mut io2, mut io4, ..
|
||||||
@ -115,8 +112,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_a_pin_can_wait(_ctx: Context) {
|
async fn test_a_pin_can_wait(_ctx: Context<'static>) {
|
||||||
let mut first = unsafe { GpioPin::<Unknown, 0>::steal() }.into_pull_down_input();
|
let mut first = Input::new( unsafe { GpioPin::<0>::steal() } , Pull::Down);
|
||||||
|
|
||||||
embassy_futures::select::select(
|
embassy_futures::select::select(
|
||||||
first.wait_for_rising_edge(),
|
first.wait_for_rising_edge(),
|
||||||
@ -128,14 +125,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_input(ctx: Context) {
|
fn test_gpio_input(ctx: Context<'static>) {
|
||||||
// `InputPin`:
|
// `InputPin`:
|
||||||
assert_eq!(ctx.io2.is_low(), true);
|
assert_eq!(ctx.io2.is_low(), true);
|
||||||
assert_eq!(ctx.io2.is_high(), false);
|
assert_eq!(ctx.io2.is_high(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_output(mut ctx: Context) {
|
fn test_gpio_output(mut ctx: Context<'static>) {
|
||||||
// `StatefulOutputPin`:
|
// `StatefulOutputPin`:
|
||||||
assert_eq!(ctx.io4.is_set_low(), true);
|
assert_eq!(ctx.io4.is_set_low(), true);
|
||||||
assert_eq!(ctx.io4.is_set_high(), false);
|
assert_eq!(ctx.io4.is_set_high(), false);
|
||||||
@ -154,7 +151,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||||
fn test_gpio_interrupt(mut ctx: Context) {
|
fn test_gpio_interrupt(mut ctx: Context<'static>) {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
*COUNTER.borrow_ref_mut(cs) = 0;
|
*COUNTER.borrow_ref_mut(cs) = 0;
|
||||||
ctx.io2.listen(Event::AnyEdge);
|
ctx.io2.listen(Event::AnyEdge);
|
||||||
@ -187,14 +184,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_od(ctx: Context) {
|
fn test_gpio_od(ctx: Context<'static>) {
|
||||||
let mut io2 = ctx.io2.into_open_drain_output();
|
let mut io2 = OutputOpenDrain::new(unsafe { GpioPin::<2>::steal() }, true, Pull::Up);
|
||||||
io2.internal_pull_up(true);
|
let mut io4 = OutputOpenDrain::new(unsafe { GpioPin::<4>::steal() }, true, Pull::Up);
|
||||||
let mut io4 = ctx.io4.into_open_drain_output();
|
|
||||||
io4.internal_pull_up(true);
|
|
||||||
|
|
||||||
io2.set_high();
|
|
||||||
io4.set_high();
|
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
assert_eq!(io2.is_high(), true);
|
assert_eq!(io2.is_high(), true);
|
||||||
@ -220,5 +213,20 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(io2.is_low(), true);
|
assert_eq!(io2.is_low(), true);
|
||||||
assert_eq!(io4.is_low(), true);
|
assert_eq!(io4.is_low(), true);
|
||||||
|
|
||||||
|
io2.set_high();
|
||||||
|
io4.set_high();
|
||||||
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
|
assert_eq!(io2.is_high(), true);
|
||||||
|
assert_eq!(io4.is_high(), true);
|
||||||
|
|
||||||
|
io2.set_low();
|
||||||
|
io4.set_low();
|
||||||
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
|
assert_eq!(io2.is_low(), true);
|
||||||
|
assert_eq!(io4.is_low(), true);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,7 @@ impl Context {
|
|||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let pins = TxRxPins::new_tx_rx(
|
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
|
||||||
io.pins.gpio2.into_push_pull_output(),
|
|
||||||
io.pins.gpio4.into_floating_input(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let uart = Uart::new_with_config(
|
let uart = Uart::new_with_config(
|
||||||
peripherals.UART0,
|
peripherals.UART0,
|
||||||
|
@ -33,10 +33,7 @@ impl Context {
|
|||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let pins = TxRxPins::new_tx_rx(
|
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
|
||||||
io.pins.gpio2.into_push_pull_output(),
|
|
||||||
io.pins.gpio4.into_floating_input(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let uart =
|
let uart =
|
||||||
Uart::new_async_with_config(peripherals.UART0, Config::default(), Some(pins), &clocks);
|
Uart::new_async_with_config(peripherals.UART0, Config::default(), Some(pins), &clocks);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user