mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 12:20:56 +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;
|
||||
#[cfg(feature = "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;
|
||||
|
||||
#[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"))]
|
||||
#[proc_macro]
|
||||
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 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()
|
||||
lp_core::load_lp_code(input)
|
||||
}
|
||||
|
||||
/// Marks the entry function of a LP core / ULP program.
|
||||
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
||||
#[proc_macro_error::proc_macro_error]
|
||||
#[proc_macro_attribute]
|
||||
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
use proc_macro2::{Ident, Span};
|
||||
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()
|
||||
lp_core::entry(args, input)
|
||||
}
|
||||
|
||||
/// 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 syn::{GenericArgument, 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("$");
|
||||
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
|
||||
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
use proc_macro2::{Ident, Span};
|
||||
use proc_macro_crate::{crate_name, FoundCrate};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{
|
||||
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 {
|
||||
String::from(match t {
|
||||
Type::Path(p) => String::from(&p.path.segments.last().unwrap().ident.to_string()),
|
||||
_ => String::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn extract_pin(ty: &Type) -> u8 {
|
||||
let mut res = 255u8;
|
||||
if let Type::Path(p) = ty {
|
||||
let segment = p.path.segments.last().unwrap();
|
||||
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
||||
for arg in &g.args {
|
||||
match arg {
|
||||
GenericArgument::Type(t) => {
|
||||
res = extract_pin(t);
|
||||
pub(crate) fn extract_pin(ty: &Type) -> u8 {
|
||||
let mut res = 255u8;
|
||||
if let Type::Path(p) = ty {
|
||||
let segment = p.path.segments.last().unwrap();
|
||||
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
||||
for arg in &g.args {
|
||||
match arg {
|
||||
GenericArgument::Type(t) => {
|
||||
res = extract_pin(t);
|
||||
}
|
||||
GenericArgument::Const(c) => {
|
||||
res = ("e! { #c }.to_string()).parse().unwrap();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
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
|
||||
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());
|
||||
|
||||
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) => {
|
||||
if let PathArguments::AngleBracketed(g) = &segment.arguments {
|
||||
res.push_str("<");
|
||||
let mut pushed = false;
|
||||
for arg in &g.args {
|
||||
if pushed {
|
||||
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)
|
||||
- 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)
|
||||
- Refactoring of GPIO module, have drivers for Input,Output,OutputOpenDrain, all drivers setup their GPIOs correctly (#1542)
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -20,6 +20,7 @@ bitfield = "0.15.0"
|
||||
cfg-if = "1.0.0"
|
||||
critical-section = "1.1.2"
|
||||
defmt = { version = "0.3.6", optional = true }
|
||||
delegate = "0.12.0"
|
||||
document-features = "0.2.8"
|
||||
embassy-executor = { version = "0.5.0", optional = true }
|
||||
embassy-futures = { version = "0.1.1", optional = true }
|
||||
|
@ -9,7 +9,7 @@
|
||||
//! ```no_run
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//! 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);
|
||||
//!
|
||||
@ -24,6 +24,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
pub use self::implementation::*;
|
||||
use crate::gpio::AnalogPin;
|
||||
|
||||
#[cfg_attr(esp32, path = "esp32.rs")]
|
||||
#[cfg_attr(riscv, path = "riscv.rs")]
|
||||
@ -93,8 +94,10 @@ impl<ADCI> AdcConfig<ADCI> {
|
||||
/// Enable the specified pin with the given attenuation
|
||||
pub fn enable_pin<PIN>(&mut self, pin: PIN, attenuation: Attenuation) -> AdcPin<PIN, ADCI>
|
||||
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);
|
||||
|
||||
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
|
||||
#[cfg(not(esp32))]
|
||||
pub fn enable_pin_with_cal<PIN, CS>(
|
||||
@ -114,9 +117,11 @@ impl<ADCI> AdcConfig<ADCI> {
|
||||
) -> AdcPin<PIN, ADCI, CS>
|
||||
where
|
||||
ADCI: CalibrationAccess,
|
||||
PIN: AdcChannel,
|
||||
PIN: AdcChannel + AnalogPin,
|
||||
CS: AdcCalScheme<ADCI>,
|
||||
{
|
||||
// TODO revert this on drop
|
||||
pin.set_analog(crate::private::Internal);
|
||||
self.attenuations[PIN::CHANNEL as usize] = Some(attenuation);
|
||||
|
||||
AdcPin {
|
||||
@ -206,12 +211,12 @@ macro_rules! impl_adc_interface {
|
||||
$( ($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;
|
||||
}
|
||||
|
||||
#[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;
|
||||
|
||||
fn channel() -> u8 { $channel }
|
||||
|
@ -13,8 +13,8 @@
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let gpio25 = io.pins.gpio25.into_analog();
|
||||
//! let gpio26 = io.pins.gpio26.into_analog();
|
||||
//! let gpio25 = io.pins.gpio25;
|
||||
//! let gpio26 = io.pins.gpio26;
|
||||
//!
|
||||
//! let mut dac1 = Dac1::new(peripherals.DAC1, gpio25);
|
||||
//! let mut dac2 = Dac2::new(peripherals.DAC2, gpio26);
|
||||
@ -37,18 +37,18 @@
|
||||
//! ```
|
||||
|
||||
use crate::{
|
||||
gpio,
|
||||
gpio::{self, AnalogPin},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals,
|
||||
};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
type Dac1Gpio = gpio::Gpio25<gpio::Analog>;
|
||||
type Dac2Gpio = gpio::Gpio26<gpio::Analog>;
|
||||
type Dac1Gpio = gpio::Gpio25;
|
||||
type Dac2Gpio = gpio::Gpio26;
|
||||
} else if #[cfg(esp32s2)] {
|
||||
type Dac1Gpio = gpio::Gpio17<gpio::Analog>;
|
||||
type Dac2Gpio = gpio::Gpio18<gpio::Analog>;
|
||||
type Dac1Gpio = gpio::Gpio17;
|
||||
type Dac2Gpio = gpio::Gpio18;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,8 +59,10 @@ pub struct Dac1<'d> {
|
||||
|
||||
impl<'d> Dac1<'d> {
|
||||
/// 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);
|
||||
// TODO revert this on drop
|
||||
pin.set_analog(crate::private::Internal);
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
unsafe { &*peripherals::SENS::PTR }
|
||||
@ -96,8 +98,10 @@ pub struct Dac2<'d> {
|
||||
|
||||
impl<'d> Dac2<'d> {
|
||||
/// 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);
|
||||
// TODO revert this on drop
|
||||
pin.set_analog(crate::private::Internal);
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
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
|
||||
//! ```no_run
|
||||
//! let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
||||
//! let button_event = gpio_ext.channel0_event.falling_edge(button);
|
||||
//! let led_task = gpio_ext.channel0_task.toggle(
|
||||
//! &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
|
||||
#[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
|
||||
pub struct GpioEtmEventChannel<const C: u8> {}
|
||||
|
||||
@ -87,12 +114,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
pub fn rising_edge<'d, PIN>(
|
||||
self,
|
||||
pin: impl Peripheral<P = PIN> + 'd,
|
||||
pin_config: GpioEtmInputConfig,
|
||||
) -> GpioEtmEventChannelRising<'d, PIN, C>
|
||||
where
|
||||
PIN: super::Pin,
|
||||
PIN: super::InputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -100,12 +135,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
pub fn falling_edge<'d, PIN>(
|
||||
self,
|
||||
pin: impl Peripheral<P = PIN> + 'd,
|
||||
pin_config: GpioEtmInputConfig,
|
||||
) -> GpioEtmEventChannelFalling<'d, PIN, C>
|
||||
where
|
||||
PIN: super::Pin,
|
||||
PIN: super::InputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -113,12 +156,20 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
pub fn any_edge<'d, PIN>(
|
||||
self,
|
||||
pin: impl Peripheral<P = PIN> + 'd,
|
||||
pin_config: GpioEtmInputConfig,
|
||||
) -> GpioEtmEventChannelAny<'d, PIN, C>
|
||||
where
|
||||
PIN: super::Pin,
|
||||
PIN: super::InputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
}
|
||||
@ -132,7 +183,7 @@ where
|
||||
_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
|
||||
{
|
||||
}
|
||||
@ -155,7 +206,7 @@ where
|
||||
_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
|
||||
{
|
||||
}
|
||||
@ -178,7 +229,7 @@ where
|
||||
_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
|
||||
{
|
||||
}
|
||||
@ -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
|
||||
pub struct GpioEtmTaskChannel<const C: u8> {}
|
||||
|
||||
@ -202,22 +275,50 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
||||
// number is the pin-count
|
||||
|
||||
/// 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
|
||||
PIN: super::Pin,
|
||||
PIN: super::OutputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
/// 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
|
||||
PIN: super::Pin,
|
||||
PIN: super::OutputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -225,12 +326,23 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
||||
pub fn toggle<'d, PIN>(
|
||||
self,
|
||||
pin: impl Peripheral<P = PIN> + 'd,
|
||||
pin_config: GpioEtmOutputConfig,
|
||||
) -> GpioEtmTaskToggle<'d, PIN, C>
|
||||
where
|
||||
PIN: super::Pin,
|
||||
PIN: super::OutputPin,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
}
|
||||
@ -244,10 +356,7 @@ where
|
||||
_pin: PeripheralRef<'d, PIN>,
|
||||
}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskSet<'d, PIN, C> where
|
||||
PIN: super::Pin
|
||||
{
|
||||
}
|
||||
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskSet<'d, PIN, C> where PIN: super::Pin {}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskSet<'d, PIN, C>
|
||||
where
|
||||
@ -264,10 +373,7 @@ pub struct GpioEtmTaskClear<'d, PIN, const C: u8> {
|
||||
_pin: PeripheralRef<'d, PIN>,
|
||||
}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskClear<'d, PIN, C> where
|
||||
PIN: super::Pin
|
||||
{
|
||||
}
|
||||
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskClear<'d, PIN, C> where PIN: super::Pin {}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskClear<'d, PIN, C>
|
||||
where
|
||||
@ -284,10 +390,7 @@ pub struct GpioEtmTaskToggle<'d, PIN, const C: u8> {
|
||||
_pin: PeripheralRef<'d, PIN>,
|
||||
}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::private::Sealed for GpioEtmTaskToggle<'d, PIN, C> where
|
||||
PIN: super::Pin
|
||||
{
|
||||
}
|
||||
impl<'d, PIN, const C: u8> private::Sealed for GpioEtmTaskToggle<'d, PIN, C> where PIN: super::Pin {}
|
||||
|
||||
impl<'d, PIN, const C: u8> crate::etm::EtmTask for GpioEtmTaskToggle<'d, PIN, C>
|
||||
where
|
||||
|
@ -17,23 +17,111 @@
|
||||
//! ```no_run
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! // 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;
|
||||
|
||||
#[cfg(esp32c6)]
|
||||
use super::OpenDrain;
|
||||
use super::{Floating, Input, Output, PullDown, PullUp, PushPull, Unknown};
|
||||
|
||||
/// A GPIO pin configured for low power operation
|
||||
pub struct LowPowerPin<MODE, const PIN: u8> {
|
||||
pub(crate) private: PhantomData<MODE>,
|
||||
/// A GPIO output pin configured for low power operation
|
||||
pub struct LowPowerOutput<'d, const PIN: u8> {
|
||||
phantom: PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
impl<MODE, const PIN: u8> LowPowerPin<MODE, PIN> {
|
||||
#[doc(hidden)]
|
||||
pub fn output_enable(&self, enable: bool) {
|
||||
impl<'d, const PIN: u8> LowPowerOutput<'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::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 };
|
||||
if enable {
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
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> {
|
||||
fn set_open_drain_output(&self, enable: bool) {
|
||||
use crate::peripherals::GPIO;
|
||||
|
||||
let gpio = unsafe { &*GPIO::PTR };
|
||||
|
||||
gpio.pin(PIN as usize)
|
||||
.modify(|_, w| w.pad_driver().bit(true));
|
||||
self.pulldown_enable(false);
|
||||
self.into_pull_up_input().into_push_pull_output();
|
||||
|
||||
LowPowerPin {
|
||||
private: PhantomData,
|
||||
}
|
||||
.modify(|_, w| w.pad_driver().bit(enable));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)]
|
||||
#[macro_export]
|
||||
macro_rules! lp_gpio {
|
||||
@ -171,16 +187,7 @@ macro_rules! lp_gpio {
|
||||
) => {
|
||||
paste::paste!{
|
||||
$(
|
||||
impl<MODE> $crate::gpio::lp_io::IntoLowPowerPin<$gpionum> for GpioPin<MODE, $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> {
|
||||
impl $crate::gpio::RtcPin for GpioPin<$gpionum> {
|
||||
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) {
|
||||
let lp_io = &*$crate::peripherals::LP_IO::ptr();
|
||||
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) {
|
||||
let lp_io = unsafe { &*$crate::peripherals::LP_IO::ptr() };
|
||||
lp_io.[< gpio $gpionum >]().modify(|_, w| w.fun_wpu().bit(enable));
|
||||
@ -249,3 +256,5 @@ macro_rules! 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
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! // 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;
|
||||
|
||||
#[cfg(esp32c6)]
|
||||
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
|
||||
pub struct LowPowerPin<MODE, const PIN: u8> {
|
||||
pub(crate) private: PhantomData<MODE>,
|
||||
/// A GPIO output pin configured for low power operation
|
||||
pub struct LowPowerOutput<'d, const PIN: u8> {
|
||||
phantom: PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
/// Configures a pin for use as a low power pin
|
||||
pub trait IntoLowPowerPin<const PIN: u8> {
|
||||
/// Convert into low power pin
|
||||
fn into_low_power(self) -> LowPowerPin<Unknown, { PIN }>;
|
||||
impl<'d, const PIN: u8> LowPowerOutput<'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::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> {
|
||||
#[doc(hidden)]
|
||||
pub fn output_enable(&self, enable: bool) {
|
||||
/// 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,
|
||||
{
|
||||
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() };
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
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();
|
||||
fn set_open_drain_output(&self, enable: bool) {
|
||||
use crate::peripherals::GPIO;
|
||||
|
||||
let gpio = unsafe { &*GPIO::PTR };
|
||||
|
||||
gpio.pin(PIN).modify(|_, w| w.pad_driver().bit(true));
|
||||
self.pulldown_enable(false);
|
||||
|
||||
LowPowerPin {
|
||||
private: PhantomData,
|
||||
}
|
||||
gpio.pin(PIN as usize)
|
||||
.modify(|_, w| w.pad_driver().bit(enable));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,20 +432,32 @@ where
|
||||
};
|
||||
|
||||
// avoid SCL/SDA going low during configuration
|
||||
scl.set_output_high(true);
|
||||
sda.set_output_high(true);
|
||||
scl.set_output_high(true, crate::private::Internal);
|
||||
sda.set_output_high(true, crate::private::Internal);
|
||||
|
||||
scl.set_to_open_drain_output()
|
||||
.enable_input(true)
|
||||
.internal_pull_up(true)
|
||||
.connect_peripheral_to_output(i2c.peripheral.scl_output_signal())
|
||||
.connect_input_to_peripheral(i2c.peripheral.scl_input_signal());
|
||||
scl.set_to_open_drain_output(crate::private::Internal);
|
||||
scl.enable_input(true, crate::private::Internal);
|
||||
scl.internal_pull_up(true, crate::private::Internal);
|
||||
scl.connect_peripheral_to_output(
|
||||
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()
|
||||
.enable_input(true)
|
||||
.internal_pull_up(true)
|
||||
.connect_peripheral_to_output(i2c.peripheral.sda_output_signal())
|
||||
.connect_input_to_peripheral(i2c.peripheral.sda_input_signal());
|
||||
sda.set_to_open_drain_output(crate::private::Internal);
|
||||
sda.enable_input(true, crate::private::Internal);
|
||||
sda.internal_pull_up(true, crate::private::Internal);
|
||||
sda.connect_peripheral_to_output(
|
||||
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);
|
||||
|
||||
@ -2017,7 +2029,7 @@ pub mod lp_i2c {
|
||||
use fugit::HertzU32;
|
||||
|
||||
use crate::{
|
||||
gpio::{lp_io::LowPowerPin, OpenDrain},
|
||||
gpio::lp_io::LowPowerOutputOpenDrain,
|
||||
peripherals::{LP_CLKRST, LP_I2C0},
|
||||
};
|
||||
|
||||
@ -2217,8 +2229,8 @@ pub mod lp_i2c {
|
||||
impl LpI2c {
|
||||
pub fn new(
|
||||
i2c: LP_I2C0,
|
||||
_sda: LowPowerPin<OpenDrain, 6>,
|
||||
_scl: LowPowerPin<OpenDrain, 7>,
|
||||
_sda: LowPowerOutputOpenDrain<6>,
|
||||
_scl: LowPowerOutputOpenDrain<7>,
|
||||
frequency: HertzU32,
|
||||
) -> Self {
|
||||
let me = Self { i2c };
|
||||
|
@ -578,8 +578,8 @@ where
|
||||
|
||||
pub fn with_mclk<P: OutputPin>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(I::mclk_signal());
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal);
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -907,6 +907,7 @@ mod private {
|
||||
interrupt::InterruptHandler,
|
||||
into_ref,
|
||||
peripherals::I2S0,
|
||||
private,
|
||||
system::Peripheral,
|
||||
Mode,
|
||||
};
|
||||
@ -937,8 +938,8 @@ mod private {
|
||||
P: OutputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::bclk_signal());
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal);
|
||||
self
|
||||
}
|
||||
|
||||
@ -947,8 +948,8 @@ mod private {
|
||||
P: OutputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::ws_signal());
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::ws_signal(), private::Internal);
|
||||
self
|
||||
}
|
||||
|
||||
@ -957,8 +958,8 @@ mod private {
|
||||
P: OutputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::dout_signal());
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::dout_signal(), private::Internal);
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -989,8 +990,8 @@ mod private {
|
||||
P: OutputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::bclk_rx_signal());
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::bclk_rx_signal(), crate::private::Internal);
|
||||
self
|
||||
}
|
||||
|
||||
@ -999,8 +1000,8 @@ mod private {
|
||||
P: OutputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::ws_rx_signal());
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::ws_rx_signal(), crate::private::Internal);
|
||||
self
|
||||
}
|
||||
|
||||
@ -1009,8 +1010,8 @@ mod private {
|
||||
P: InputPin,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_input()
|
||||
.connect_input_to_peripheral(T::din_signal());
|
||||
pin.set_to_input(crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::din_signal(), crate::private::Internal);
|
||||
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 {
|
||||
crate::into_ref!(mclk);
|
||||
mclk.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::CAM_CLK);
|
||||
mclk.set_to_push_pull_output(crate::private::Internal);
|
||||
mclk.connect_peripheral_to_output(OutputSignal::CAM_CLK, crate::private::Internal);
|
||||
self
|
||||
}
|
||||
|
||||
@ -236,14 +236,12 @@ impl<'d, RX: Rx> Camera<'d, RX> {
|
||||
crate::into_ref!(h_enable);
|
||||
crate::into_ref!(pclk);
|
||||
|
||||
vsync
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_V_SYNC);
|
||||
h_enable
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE);
|
||||
pclk.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_PCLK);
|
||||
vsync.set_to_input(crate::private::Internal);
|
||||
vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal);
|
||||
h_enable.set_to_input(crate::private::Internal);
|
||||
h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal);
|
||||
pclk.set_to_input(crate::private::Internal);
|
||||
pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -425,30 +423,22 @@ impl RxEightBits {
|
||||
crate::into_ref!(pin_6);
|
||||
crate::into_ref!(pin_7);
|
||||
|
||||
pin_0
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_0);
|
||||
pin_1
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_1);
|
||||
pin_2
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_2);
|
||||
pin_3
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_3);
|
||||
pin_4
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_4);
|
||||
pin_5
|
||||
.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);
|
||||
pin_0.set_to_input(crate::private::Internal);
|
||||
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||
pin_1.set_to_input(crate::private::Internal);
|
||||
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||
pin_2.set_to_input(crate::private::Internal);
|
||||
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||
pin_3.set_to_input(crate::private::Internal);
|
||||
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||
pin_4.set_to_input(crate::private::Internal);
|
||||
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||
pin_5.set_to_input(crate::private::Internal);
|
||||
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||
pin_6.set_to_input(crate::private::Internal);
|
||||
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||
pin_7.set_to_input(crate::private::Internal);
|
||||
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||
|
||||
Self { _pins: () }
|
||||
}
|
||||
@ -517,54 +507,38 @@ impl RxSixteenBits {
|
||||
crate::into_ref!(pin_14);
|
||||
crate::into_ref!(pin_15);
|
||||
|
||||
pin_0
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_0);
|
||||
pin_1
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_1);
|
||||
pin_2
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_2);
|
||||
pin_3
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_3);
|
||||
pin_4
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_4);
|
||||
pin_5
|
||||
.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);
|
||||
pin_8
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_8);
|
||||
pin_9
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(InputSignal::CAM_DATA_9);
|
||||
pin_10
|
||||
.set_to_input()
|
||||
.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);
|
||||
pin_0.set_to_input(crate::private::Internal);
|
||||
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||
pin_1.set_to_input(crate::private::Internal);
|
||||
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||
pin_2.set_to_input(crate::private::Internal);
|
||||
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||
pin_3.set_to_input(crate::private::Internal);
|
||||
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||
pin_4.set_to_input(crate::private::Internal);
|
||||
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||
pin_5.set_to_input(crate::private::Internal);
|
||||
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||
pin_6.set_to_input(crate::private::Internal);
|
||||
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||
pin_7.set_to_input(crate::private::Internal);
|
||||
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||
pin_8.set_to_input(crate::private::Internal);
|
||||
pin_8.connect_input_to_peripheral(InputSignal::CAM_DATA_8, crate::private::Internal);
|
||||
pin_9.set_to_input(crate::private::Internal);
|
||||
pin_9.connect_input_to_peripheral(InputSignal::CAM_DATA_9, crate::private::Internal);
|
||||
pin_10.set_to_input(crate::private::Internal);
|
||||
pin_10.connect_input_to_peripheral(InputSignal::CAM_DATA_10, crate::private::Internal);
|
||||
pin_11.set_to_input(crate::private::Internal);
|
||||
pin_11.connect_input_to_peripheral(InputSignal::CAM_DATA_11, crate::private::Internal);
|
||||
pin_12.set_to_input(crate::private::Internal);
|
||||
pin_12.connect_input_to_peripheral(InputSignal::CAM_DATA_12, crate::private::Internal);
|
||||
pin_13.set_to_input(crate::private::Internal);
|
||||
pin_13.connect_input_to_peripheral(InputSignal::CAM_DATA_13, crate::private::Internal);
|
||||
pin_14.set_to_input(crate::private::Internal);
|
||||
pin_14.connect_input_to_peripheral(InputSignal::CAM_DATA_14, crate::private::Internal);
|
||||
pin_15.set_to_input(crate::private::Internal);
|
||||
pin_15.connect_input_to_peripheral(InputSignal::CAM_DATA_15, crate::private::Internal);
|
||||
|
||||
Self { _pins: () }
|
||||
}
|
||||
|
@ -254,8 +254,8 @@ where
|
||||
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_CS);
|
||||
cs.set_to_push_pull_output(crate::private::Internal);
|
||||
cs.connect_peripheral_to_output(OutputSignal::LCD_CS, crate::private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -268,11 +268,11 @@ where
|
||||
crate::into_ref!(dc);
|
||||
crate::into_ref!(wrx);
|
||||
|
||||
dc.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DC);
|
||||
dc.set_to_push_pull_output(crate::private::Internal);
|
||||
dc.connect_peripheral_to_output(OutputSignal::LCD_DC, crate::private::Internal);
|
||||
|
||||
wrx.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_PCLK);
|
||||
wrx.set_to_push_pull_output(crate::private::Internal);
|
||||
wrx.connect_peripheral_to_output(OutputSignal::LCD_PCLK, crate::private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -610,30 +610,30 @@ where
|
||||
type Word = u8;
|
||||
|
||||
fn configure(&mut self) {
|
||||
self.pin_0.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_0
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0, crate::private::Internal);
|
||||
self.pin_1.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_1
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1, crate::private::Internal);
|
||||
self.pin_2.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_2
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2, crate::private::Internal);
|
||||
self.pin_3.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_3
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3, crate::private::Internal);
|
||||
self.pin_4.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_4
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4, crate::private::Internal);
|
||||
self.pin_5.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_5
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5, crate::private::Internal);
|
||||
self.pin_6.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_6
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6, crate::private::Internal);
|
||||
self.pin_7.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_7
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7, crate::private::Internal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,54 +755,60 @@ where
|
||||
{
|
||||
type Word = u16;
|
||||
fn configure(&mut self) {
|
||||
self.pin_0.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_0
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_0, crate::private::Internal);
|
||||
self.pin_1.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_1
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_1, crate::private::Internal);
|
||||
self.pin_2.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_2
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_2, crate::private::Internal);
|
||||
self.pin_3.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_3
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_3, crate::private::Internal);
|
||||
self.pin_4.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_4
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_4, crate::private::Internal);
|
||||
self.pin_5.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_5
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_5, crate::private::Internal);
|
||||
self.pin_6.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_6
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_6, crate::private::Internal);
|
||||
self.pin_7.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_7
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_7, crate::private::Internal);
|
||||
self.pin_8.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_8
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_8);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_8, crate::private::Internal);
|
||||
self.pin_9.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_9
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_9);
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_9, crate::private::Internal);
|
||||
self.pin_10
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_10);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_10
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_10, crate::private::Internal);
|
||||
self.pin_11
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_11);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_11
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_11, crate::private::Internal);
|
||||
self.pin_12
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_12);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_12
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_12, crate::private::Internal);
|
||||
self.pin_13
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_13);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_13
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_13, crate::private::Internal);
|
||||
self.pin_14
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_14);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_14
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_14, crate::private::Internal);
|
||||
self.pin_15
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_15);
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin_15
|
||||
.connect_peripheral_to_output(OutputSignal::LCD_DATA_15, crate::private::Internal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,8 +536,12 @@ where
|
||||
}
|
||||
|
||||
match cfg {
|
||||
config::PinConfig::PushPull => self.output_pin.set_to_push_pull_output(),
|
||||
config::PinConfig::OpenDrain => self.output_pin.set_to_open_drain_output(),
|
||||
config::PinConfig::PushPull => self
|
||||
.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;
|
||||
@ -585,7 +589,8 @@ where
|
||||
#[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))]
|
||||
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 {
|
||||
return Err(Error::Timer);
|
||||
}
|
||||
|
@ -220,6 +220,8 @@ impl crate::private::Sealed for Async {}
|
||||
|
||||
pub(crate) mod private {
|
||||
pub trait Sealed {}
|
||||
|
||||
pub struct Internal;
|
||||
}
|
||||
|
||||
/// Available CPU cores
|
||||
|
@ -34,7 +34,7 @@
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # use esp_hal::{mcpwm, prelude::*};
|
||||
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, PeripheralClockConfig, MCPWM};
|
||||
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, McPwm, PeripheralClockConfig};
|
||||
//!
|
||||
//! // initialize peripheral
|
||||
//! let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();
|
||||
|
@ -16,6 +16,7 @@ use crate::{
|
||||
gpio::OutputPin,
|
||||
mcpwm::{timer::Timer, PwmPeripheral},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
private,
|
||||
};
|
||||
|
||||
/// 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>();
|
||||
pin.pin
|
||||
.connect_peripheral_to_output(output_signal)
|
||||
.enable_output(true);
|
||||
.connect_peripheral_to_output(output_signal, private::Internal);
|
||||
pin.pin.enable_output(true, private::Internal);
|
||||
pin
|
||||
}
|
||||
|
||||
|
@ -331,9 +331,11 @@ where
|
||||
P: OutputPin,
|
||||
{
|
||||
fn configure(&mut self) {
|
||||
self.pin
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(crate::gpio::OutputSignal::PARL_TX_CLK);
|
||||
self.pin.set_to_push_pull_output(crate::private::Internal);
|
||||
self.pin.connect_peripheral_to_output(
|
||||
crate::gpio::OutputSignal::PARL_TX_CLK,
|
||||
crate::private::Internal,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,9 +365,11 @@ where
|
||||
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
|
||||
|
||||
self.pin
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(crate::gpio::InputSignal::PARL_TX_CLK);
|
||||
self.pin.set_to_input(crate::private::Internal);
|
||||
self.pin.connect_input_to_peripheral(
|
||||
crate::gpio::InputSignal::PARL_TX_CLK,
|
||||
crate::private::Internal,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -396,9 +400,11 @@ where
|
||||
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
|
||||
|
||||
self.pin
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(crate::gpio::InputSignal::PARL_RX_CLK);
|
||||
self.pin.set_to_input(crate::private::Internal);
|
||||
self.pin.connect_input_to_peripheral(
|
||||
crate::gpio::InputSignal::PARL_RX_CLK,
|
||||
crate::private::Internal,
|
||||
);
|
||||
|
||||
Instance::set_rx_clk_edge_sel(self.sample_edge);
|
||||
}
|
||||
@ -441,8 +447,11 @@ where
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
self.tx_pins.configure()?;
|
||||
self.valid_pin
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(Instance::tx_valid_pin_signal());
|
||||
.set_to_push_pull_output(crate::private::Internal);
|
||||
self.valid_pin.connect_peripheral_to_output(
|
||||
Instance::tx_valid_pin_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
Instance::set_tx_hw_valid_en(true);
|
||||
Ok(())
|
||||
}
|
||||
@ -516,9 +525,8 @@ macro_rules! tx_pins {
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error>{
|
||||
$(
|
||||
self.[< pin_ $pin:lower >]
|
||||
.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(crate::gpio::OutputSignal::$signal);
|
||||
self.[< pin_ $pin:lower >].set_to_push_pull_output(crate::private::Internal);
|
||||
self.[< pin_ $pin:lower >].connect_peripheral_to_output(crate::gpio::OutputSignal::$signal, crate::private::Internal);
|
||||
)+
|
||||
|
||||
private::Instance::set_tx_bit_width( private::WidSel::[< Bits $width >]);
|
||||
@ -659,9 +667,9 @@ where
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
self.rx_pins.configure()?;
|
||||
self.valid_pin.set_to_input(crate::private::Internal);
|
||||
self.valid_pin
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(Instance::rx_valid_pin_signal());
|
||||
.connect_input_to_peripheral(Instance::rx_valid_pin_signal(), crate::private::Internal);
|
||||
Instance::set_rx_sw_en(false);
|
||||
if let Some(sel) = self.enable_mode.pulse_submode_sel() {
|
||||
Instance::set_rx_pulse_submode_sel(sel);
|
||||
@ -763,9 +771,8 @@ macro_rules! rx_pins {
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
$(
|
||||
self.[< pin_ $pin:lower >]
|
||||
.set_to_input()
|
||||
.connect_input_to_peripheral(crate::gpio::InputSignal::$signal);
|
||||
self.[< pin_ $pin:lower >].set_to_input($crate::private::Internal);
|
||||
self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, $crate::private::Internal);
|
||||
)+
|
||||
|
||||
private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);
|
||||
|
@ -10,11 +10,25 @@
|
||||
|
||||
use super::unit;
|
||||
use crate::{
|
||||
gpio::{InputPin, InputSignal, ONE_INPUT, ZERO_INPUT},
|
||||
gpio::{InputPin, InputSignal, Pull, ONE_INPUT, ZERO_INPUT},
|
||||
peripheral::Peripheral,
|
||||
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
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub enum Number {
|
||||
@ -59,10 +73,20 @@ pub struct 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);
|
||||
|
||||
pin.init_input(
|
||||
pin_config.pull == Pull::Down,
|
||||
pin_config.pull == Pull::Up,
|
||||
crate::private::Internal,
|
||||
);
|
||||
|
||||
Self {
|
||||
source: pin.number(),
|
||||
source: pin.number(crate::private::Internal),
|
||||
}
|
||||
}
|
||||
pub fn always_high() -> Self {
|
||||
|
@ -47,12 +47,12 @@
|
||||
//! println!("setup channel 0");
|
||||
//! let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let mut pin_a = io.pins.gpio5.into_pull_up_input();
|
||||
//! let mut pin_b = io.pins.gpio6.into_pull_up_input();
|
||||
//! let mut pin_a = io.pins.gpio5;
|
||||
//! let mut pin_b = io.pins.gpio6;
|
||||
//!
|
||||
//! ch0.configure(
|
||||
//! PcntSource::from_pin(&mut pin_a),
|
||||
//! PcntSource::from_pin(&mut pin_b),
|
||||
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||
//! channel::Config {
|
||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||
@ -66,8 +66,8 @@
|
||||
//! println!("setup channel 1");
|
||||
//! let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
||||
//! ch1.configure(
|
||||
//! PcntSource::from_pin(&mut pin_b),
|
||||
//! PcntSource::from_pin(&mut pin_a),
|
||||
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||
//! channel::Config {
|
||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||
|
@ -317,8 +317,8 @@ where
|
||||
Self: Sized,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::output_signal());
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
@ -349,8 +349,8 @@ where
|
||||
Self: Sized,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(T::output_signal());
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
@ -394,8 +394,8 @@ where
|
||||
}
|
||||
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_input()
|
||||
.connect_input_to_peripheral(T::input_signal());
|
||||
pin.set_to_input(crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
@ -441,8 +441,8 @@ where
|
||||
}
|
||||
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_input()
|
||||
.connect_input_to_peripheral(T::input_signal());
|
||||
pin.set_to_input(crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
efuse::Efuse,
|
||||
gpio::{Pins, RtcFunction},
|
||||
peripherals::Peripherals,
|
||||
private,
|
||||
rtc_cntl::{
|
||||
rtc::{
|
||||
rtc_clk_cpu_freq_set_xtal,
|
||||
@ -64,7 +65,7 @@ impl Ext1WakeupSource<'_, '_> {
|
||||
use crate::gpio::RtcPin;
|
||||
|
||||
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.rtc_set_config(false, false, RtcFunction::Rtc);
|
||||
}
|
||||
@ -92,9 +93,9 @@ impl WakeSource for Ext1WakeupSource<'_, '_> {
|
||||
let mut pin_mask = 0u8;
|
||||
let mut level_mask = 0u8;
|
||||
for (pin, level) in pins.iter_mut() {
|
||||
pin_mask |= 1 << pin.number();
|
||||
pin_mask |= 1 << pin.number(private::Internal);
|
||||
level_mask |= match level {
|
||||
WakeupLevel::High => 1 << pin.number(),
|
||||
WakeupLevel::High => 1 << pin.number(private::Internal),
|
||||
WakeupLevel::Low => 0,
|
||||
};
|
||||
|
||||
|
@ -197,12 +197,14 @@ impl<'a, 'b> RtcioWakeupSource<'a, 'b> {
|
||||
|
||||
pin.rtc_set_config(true, true, RtcFunction::Rtc);
|
||||
|
||||
rtcio.pin(pin.number() as usize).modify(|_, w| unsafe {
|
||||
w.wakeup_enable().set_bit().int_type().bits(match level {
|
||||
WakeupLevel::Low => 4,
|
||||
WakeupLevel::High => 5,
|
||||
})
|
||||
});
|
||||
rtcio
|
||||
.pin(pin.number(crate::private::Internal) as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.wakeup_enable().set_bit().int_type().bits(match level {
|
||||
WakeupLevel::Low => 4,
|
||||
WakeupLevel::High => 5,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,6 @@ use crate::{
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
InterruptStatusRegisterAccessBank1,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
Cpu,
|
||||
|
@ -45,7 +45,6 @@ use crate::{
|
||||
GpioPin,
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
|
@ -46,7 +46,6 @@ use crate::{
|
||||
GpioPin,
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
|
@ -46,7 +46,6 @@ use crate::{
|
||||
GpioPin,
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
|
@ -46,7 +46,6 @@ use crate::{
|
||||
GpioPin,
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
|
@ -59,7 +59,6 @@ use crate::{
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
InterruptStatusRegisterAccessBank1,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
@ -556,5 +555,5 @@ impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 {
|
||||
}
|
||||
|
||||
// implement marker traits on USB pins
|
||||
impl<T> crate::otg_fs::UsbDp for Gpio19<T> {}
|
||||
impl<T> crate::otg_fs::UsbDm for Gpio20<T> {}
|
||||
impl crate::otg_fs::UsbDp for Gpio19 {}
|
||||
impl crate::otg_fs::UsbDm for Gpio20 {}
|
||||
|
@ -47,7 +47,6 @@ use crate::{
|
||||
InterruptStatusRegisterAccess,
|
||||
InterruptStatusRegisterAccessBank0,
|
||||
InterruptStatusRegisterAccessBank1,
|
||||
Unknown,
|
||||
},
|
||||
peripherals::GPIO,
|
||||
};
|
||||
@ -490,5 +489,5 @@ impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 {
|
||||
}
|
||||
|
||||
// implement marker traits on USB pins
|
||||
impl<T> crate::otg_fs::UsbDp for Gpio19<T> {}
|
||||
impl<T> crate::otg_fs::UsbDm for Gpio20<T> {}
|
||||
impl crate::otg_fs::UsbDp for Gpio19 {}
|
||||
impl crate::otg_fs::UsbDm for Gpio20 {}
|
||||
|
@ -75,6 +75,7 @@ use crate::{
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
private,
|
||||
system::PeripheralClockControl,
|
||||
};
|
||||
|
||||
@ -452,32 +453,32 @@ where
|
||||
|
||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_mosi<MOSI: OutputPin>(self, mosi: impl Peripheral<P = MOSI> + 'd) -> Self {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.mosi_signal());
|
||||
mosi.set_to_push_pull_output(private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_miso<MISO: InputPin>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
|
||||
crate::into_ref!(miso);
|
||||
miso.set_to_input()
|
||||
.connect_input_to_peripheral(self.spi.miso_signal());
|
||||
miso.set_to_input(private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -503,26 +504,26 @@ where
|
||||
) -> Self {
|
||||
if let Some(sck) = sck {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(mosi) = mosi {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.mosi_signal());
|
||||
mosi.set_to_push_pull_output(private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(miso) = miso {
|
||||
crate::into_ref!(miso);
|
||||
miso.set_to_input()
|
||||
.connect_input_to_peripheral(self.spi.miso_signal());
|
||||
miso.set_to_input(private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(cs) = cs {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
}
|
||||
|
||||
self
|
||||
@ -572,8 +573,8 @@ where
|
||||
|
||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -583,10 +584,10 @@ where
|
||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.enable_output(true);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal());
|
||||
mosi.enable_input(true);
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal());
|
||||
mosi.enable_output(true, private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
mosi.enable_input(true, private::Internal);
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -596,10 +597,10 @@ where
|
||||
miso: impl Peripheral<P = MISO> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(miso);
|
||||
miso.enable_output(true);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal());
|
||||
miso.enable_input(true);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal());
|
||||
miso.enable_output(true, private::Internal);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||
miso.enable_input(true, private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -609,10 +610,10 @@ where
|
||||
sio2: impl Peripheral<P = SIO2> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(sio2);
|
||||
sio2.enable_output(true);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal());
|
||||
sio2.enable_input(true);
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal());
|
||||
sio2.enable_output(true, private::Internal);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||
sio2.enable_input(true, private::Internal);
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -622,18 +623,18 @@ where
|
||||
sio3: impl Peripheral<P = SIO3> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(sio3);
|
||||
sio3.enable_output(true);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal());
|
||||
sio3.enable_input(true);
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal());
|
||||
sio3.enable_output(true, private::Internal);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||
sio3.enable_input(true, private::Internal);
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -660,46 +661,46 @@ where
|
||||
) -> Self {
|
||||
if let Some(sck) = sck {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.sclk_signal());
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(mosi) = mosi {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.enable_output(true);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal());
|
||||
mosi.enable_input(true);
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal());
|
||||
mosi.enable_output(true, private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
mosi.enable_input(true, private::Internal);
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(miso) = miso {
|
||||
crate::into_ref!(miso);
|
||||
miso.enable_output(true);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal());
|
||||
miso.enable_input(true);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal());
|
||||
miso.enable_output(true, private::Internal);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||
miso.enable_input(true, private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(sio2) = sio2 {
|
||||
crate::into_ref!(sio2);
|
||||
sio2.enable_output(true);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal());
|
||||
sio2.enable_input(true);
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal());
|
||||
sio2.enable_output(true, private::Internal);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||
sio2.enable_input(true, private::Internal);
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(sio3) = sio3 {
|
||||
crate::into_ref!(sio3);
|
||||
sio3.enable_output(true);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal());
|
||||
sio3.enable_input(true);
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal());
|
||||
sio3.enable_output(true, private::Internal);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||
sio3.enable_input(true, private::Internal);
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||
}
|
||||
|
||||
if let Some(cs) = cs {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(self.spi.cs_signal());
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
}
|
||||
|
||||
self
|
||||
@ -2135,7 +2136,7 @@ pub trait ExtendedInstance: Instance {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait Instance: crate::private::Sealed {
|
||||
pub trait Instance: private::Sealed {
|
||||
fn register_block(&self) -> &RegisterBlock;
|
||||
|
||||
fn sclk_signal(&self) -> OutputSignal;
|
||||
|
@ -54,6 +54,7 @@ use crate::{
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
private,
|
||||
system::PeripheralClockControl,
|
||||
};
|
||||
|
||||
@ -92,17 +93,17 @@ where
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
crate::into_ref!(spi, sck, mosi, miso, cs);
|
||||
sck.set_to_input()
|
||||
.connect_input_to_peripheral(spi.sclk_signal());
|
||||
sck.set_to_input(private::Internal);
|
||||
sck.connect_input_to_peripheral(spi.sclk_signal(), private::Internal);
|
||||
|
||||
mosi.set_to_input()
|
||||
.connect_input_to_peripheral(spi.mosi_signal());
|
||||
mosi.set_to_input(private::Internal);
|
||||
mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal);
|
||||
|
||||
miso.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(spi.miso_signal());
|
||||
miso.set_to_push_pull_output(private::Internal);
|
||||
miso.connect_peripheral_to_output(spi.miso_signal(), private::Internal);
|
||||
|
||||
cs.set_to_input()
|
||||
.connect_input_to_peripheral(spi.cs_signal());
|
||||
cs.set_to_input(private::Internal);
|
||||
cs.connect_input_to_peripheral(spi.cs_signal(), private::Internal);
|
||||
|
||||
Self::new_internal(spi, mode)
|
||||
}
|
||||
@ -736,7 +737,7 @@ where
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait Instance: crate::private::Sealed {
|
||||
pub trait Instance: private::Sealed {
|
||||
fn register_block(&self) -> &RegisterBlock;
|
||||
|
||||
fn sclk_signal(&self) -> InputSignal;
|
||||
|
@ -42,7 +42,7 @@ pub struct SystemTimer<'d, DM: crate::Mode> {
|
||||
pub alarm0: Alarm<Target, DM, 0>,
|
||||
pub alarm1: Alarm<Target, DM, 1>,
|
||||
pub alarm2: Alarm<Target, DM, 2>,
|
||||
_phantom: &'d PhantomData<()>,
|
||||
_phantom: PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
impl<'d> SystemTimer<'d, crate::Blocking> {
|
||||
@ -67,7 +67,7 @@ impl<'d> SystemTimer<'d, crate::Blocking> {
|
||||
alarm0: Alarm::new(),
|
||||
alarm1: Alarm::new(),
|
||||
alarm2: Alarm::new(),
|
||||
_phantom: &PhantomData,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ impl<'d> SystemTimer<'d, crate::Async> {
|
||||
alarm0: Alarm::new(),
|
||||
alarm1: Alarm::new(),
|
||||
alarm2: Alarm::new(),
|
||||
_phantom: &PhantomData,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -646,14 +646,18 @@ where
|
||||
clocks: &Clocks,
|
||||
baud_rate: BaudRate,
|
||||
interrupt: Option<InterruptHandler>,
|
||||
no_transceiver: bool,
|
||||
) -> Self {
|
||||
// Enable the peripheral clock for the TWAI peripheral.
|
||||
T::enable_peripheral();
|
||||
|
||||
// Set up the GPIO pins.
|
||||
crate::into_ref!(tx_pin, rx_pin);
|
||||
tx_pin.connect_peripheral_to_output(T::OUTPUT_SIGNAL);
|
||||
rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL);
|
||||
if no_transceiver {
|
||||
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 {
|
||||
peripheral: PhantomData,
|
||||
@ -775,6 +779,9 @@ impl<'d, T> TwaiConfiguration<'d, T, crate::Blocking>
|
||||
where
|
||||
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>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -783,7 +790,27 @@ where
|
||||
baud_rate: BaudRate,
|
||||
interrupt: Option<InterruptHandler>,
|
||||
) -> 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
|
||||
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>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -807,6 +837,31 @@ where
|
||||
clocks,
|
||||
baud_rate,
|
||||
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
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let pins = TxRxPins::new_tx_rx(
|
||||
//! io.pins.gpio1.into_push_pull_output(),
|
||||
//! io.pins.gpio2.into_floating_input(),
|
||||
//! );
|
||||
//! let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2);
|
||||
//!
|
||||
//! let mut uart1 =
|
||||
//! 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,
|
||||
) {
|
||||
if let Some(ref mut tx) = self.tx {
|
||||
tx.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(tx_signal);
|
||||
tx.set_to_push_pull_output(crate::private::Internal);
|
||||
tx.connect_peripheral_to_output(tx_signal, crate::private::Internal);
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
rts.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(rts_signal);
|
||||
rts.set_to_push_pull_output(crate::private::Internal);
|
||||
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,
|
||||
) {
|
||||
if let Some(ref mut tx) = self.tx {
|
||||
tx.set_to_push_pull_output()
|
||||
.connect_peripheral_to_output(tx_signal);
|
||||
tx.set_to_push_pull_output(crate::private::Internal);
|
||||
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 {
|
||||
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());
|
||||
|
||||
// Reset Tx/Rx FIFOs
|
||||
serial.txfifo_reset();
|
||||
serial.rxfifo_reset();
|
||||
serial.txfifo_reset();
|
||||
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
|
||||
}
|
||||
|
||||
@ -2110,9 +2117,9 @@ mod asynch {
|
||||
#[cfg(lp_uart)]
|
||||
pub mod lp_uart {
|
||||
use crate::{
|
||||
gpio::{lp_io::LowPowerPin, Floating, Input, Output, PushPull},
|
||||
gpio::lp_io::{LowPowerInput, LowPowerOutput},
|
||||
peripherals::{LP_CLKRST, LP_UART},
|
||||
uart::{config, config::Config},
|
||||
uart::config::{self, Config},
|
||||
};
|
||||
/// LP-UART driver
|
||||
///
|
||||
@ -2124,11 +2131,7 @@ pub mod lp_uart {
|
||||
impl LpUart {
|
||||
/// Initialize the UART driver using the default configuration
|
||||
// TODO: CTS and RTS pins
|
||||
pub fn new(
|
||||
uart: LP_UART,
|
||||
_tx: LowPowerPin<Output<PushPull>, 5>,
|
||||
_rx: LowPowerPin<Input<Floating>, 4>,
|
||||
) -> Self {
|
||||
pub fn new(uart: LP_UART, _tx: LowPowerOutput<5>, _rx: LowPowerInput<4>) -> Self {
|
||||
let lp_io = unsafe { &*crate::peripherals::LP_IO::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]
|
||||
# target = "riscv32imc-unknown-none-elf" # ESP32-S2 + ESP32-S3
|
||||
target = "riscv32imac-unknown-none-elf" # ESP32-C6
|
||||
|
||||
[target.'cfg(target_arch = "riscv32")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
]
|
||||
|
@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
|
||||
- Renamed to `esp-ulp-riscv-hal` (#916)
|
||||
- Remove 2nd level generics from GPIO pin (#1526)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -11,11 +11,7 @@
|
||||
#![no_main]
|
||||
|
||||
use embedded_hal_02::{blocking::delay::DelayMs, digital::v2::OutputPin};
|
||||
use esp_lp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{GpioPin, Output, PushPull},
|
||||
prelude::*,
|
||||
};
|
||||
use esp_lp_hal::{delay::Delay, gpio::Output, prelude::*};
|
||||
use panic_halt as _;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
@ -27,7 +23,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn main(mut gpio1: GpioPin<Output<PushPull>, 1>) -> ! {
|
||||
fn main(mut gpio1: Output<1>) -> ! {
|
||||
let mut i: u32 = 0;
|
||||
|
||||
let ptr = ADDRESS as *mut u32;
|
||||
|
@ -2,42 +2,24 @@
|
||||
//!
|
||||
//! It's assumed that GPIOs are already configured correctly by the HP core.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[cfg(feature = "esp32c6")]
|
||||
type LpIo = crate::pac::LP_IO;
|
||||
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
|
||||
type LpIo = crate::pac::RTC_IO;
|
||||
|
||||
pub struct Unknown {}
|
||||
#[non_exhaustive]
|
||||
pub struct Input<const PIN: u8> {}
|
||||
|
||||
pub struct Input<MODE> {
|
||||
_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> {
|
||||
impl<const PIN: u8> Input<PIN> {
|
||||
pub fn input_state(&self) -> bool {
|
||||
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 {
|
||||
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:
|
||||
#[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 {
|
||||
None
|
||||
} else {
|
||||
Some(GpioPin {
|
||||
phantom: PhantomData,
|
||||
})
|
||||
Some(Output {})
|
||||
}
|
||||
}
|
||||
|
||||
// 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")]
|
||||
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;
|
||||
|
||||
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")]
|
||||
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;
|
||||
|
||||
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")]
|
||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin
|
||||
for GpioPin<Output<MODE>, PIN>
|
||||
{
|
||||
impl<const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin for Output<PIN> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.output_state())
|
||||
}
|
||||
@ -109,18 +97,20 @@ impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::StatefulOutputPin
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, const PIN: u8> embedded_hal_02::digital::v2::toggleable::Default
|
||||
for GpioPin<Output<MODE>, PIN>
|
||||
{
|
||||
}
|
||||
impl<const PIN: u8> embedded_hal_02::digital::v2::toggleable::Default for Output<PIN> {}
|
||||
|
||||
#[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;
|
||||
}
|
||||
|
||||
#[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> {
|
||||
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")]
|
||||
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> {
|
||||
self.set_output(false);
|
||||
Ok(())
|
||||
@ -144,9 +134,7 @@ impl<MODE, const PIN: u8> embedded_hal_1::digital::OutputPin for GpioPin<Output<
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-1")]
|
||||
impl<MODE, const PIN: u8> embedded_hal_1::digital::StatefulOutputPin
|
||||
for GpioPin<Output<MODE>, PIN>
|
||||
{
|
||||
impl<const PIN: u8> embedded_hal_1::digital::StatefulOutputPin for Output<PIN> {
|
||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||
Ok(self.output_state())
|
||||
}
|
||||
|
@ -30,11 +30,11 @@ fn main() -> ! {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
cfg_if::cfg_if! {
|
||||
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"))] {
|
||||
let analog_pin = io.pins.gpio3.into_analog();
|
||||
let analog_pin = io.pins.gpio3;
|
||||
} 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);
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32s3")] {
|
||||
let analog_pin = io.pins.gpio3.into_analog();
|
||||
let analog_pin = io.pins.gpio3;
|
||||
} 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
|
||||
// return raw readings in some unspecified scale.
|
||||
//
|
||||
type AdcCal = ();
|
||||
// type AdcCal = esp_hal::analog::adc::AdcCalBasic<ADC1>;
|
||||
//type AdcCal = ();
|
||||
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::AdcCalCurve<ADC1>;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! This shows how to configure UART
|
||||
//! 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.
|
||||
//!
|
||||
//! The following wiring is assumed:
|
||||
@ -32,10 +32,7 @@ fn main() -> ! {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let pins = TxRxPins::new_tx_rx(
|
||||
io.pins.gpio4.into_push_pull_output(),
|
||||
io.pins.gpio5.into_floating_input(),
|
||||
);
|
||||
let pins = TxRxPins::new_tx_rx(io.pins.gpio4, io.pins.gpio5);
|
||||
|
||||
let mut serial1 = Uart::new_with_config(
|
||||
peripherals.UART1,
|
||||
|
@ -11,7 +11,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
gpio::Io,
|
||||
gpio::{Io, Output},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -25,9 +25,7 @@ fn main() -> ! {
|
||||
|
||||
// Set GPIO0 as an output, and set its state high initially.
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut led = io.pins.gpio8.into_push_pull_output();
|
||||
|
||||
led.set_high();
|
||||
let mut led = Output::new(io.pins.gpio0, true);
|
||||
|
||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||
// loop.
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! 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
|
||||
//! Additionally demonstrates passing GPIO to a function in a generic way.
|
||||
@ -14,7 +14,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, Input, Io, Output, PullDown, PushPull},
|
||||
gpio::{AnyInput, AnyOutput, Io, Pull},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -29,15 +29,20 @@ fn main() -> ! {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
// Set LED GPIOs as an output:
|
||||
let led1 = io.pins.gpio8.into_push_pull_output();
|
||||
let led2 = io.pins.gpio9.into_push_pull_output();
|
||||
let led3 = io.pins.gpio10.into_push_pull_output();
|
||||
let led1 = AnyOutput::new(io.pins.gpio2, false);
|
||||
let led2 = AnyOutput::new(io.pins.gpio4, false);
|
||||
let led3 = AnyOutput::new(io.pins.gpio5, false);
|
||||
|
||||
// Set GPIO0 as an input:
|
||||
let button = io.pins.gpio0.into_pull_down_input().into();
|
||||
// Use boot button as an input:
|
||||
#[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`:
|
||||
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
|
||||
// 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() {
|
||||
pin.toggle();
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ fn main() -> ! {
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32")] {
|
||||
let dac1_pin = io.pins.gpio25.into_analog();
|
||||
let dac2_pin = io.pins.gpio26.into_analog();
|
||||
let dac1_pin = io.pins.gpio25;
|
||||
let dac2_pin = io.pins.gpio26;
|
||||
} else if #[cfg(feature = "esp32s2")] {
|
||||
let dac1_pin = io.pins.gpio17.into_analog();
|
||||
let dac2_pin = io.pins.gpio18.into_analog();
|
||||
let dac1_pin = io.pins.gpio17;
|
||||
let dac2_pin = io.pins.gpio18;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
embassy::{self, executor::Executor},
|
||||
get_core,
|
||||
gpio::{GpioPin, Io, Output, PushPull},
|
||||
gpio::{AnyOutput, Io},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: GpioPin<Output<PushPull>, 0>,
|
||||
mut led: AnyOutput<'static>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
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();
|
||||
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
|
||||
.start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || {
|
||||
|
@ -19,7 +19,7 @@ use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
embassy::{self, executor::InterruptExecutor},
|
||||
get_core,
|
||||
gpio::{GpioPin, Io, Output, PushPull},
|
||||
gpio::{AnyOutput, Io},
|
||||
interrupt::Priority,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: GpioPin<Output<PushPull>, 0>,
|
||||
mut led: AnyOutput<'static>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
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();
|
||||
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();
|
||||
let executor_core1 =
|
||||
|
@ -13,7 +13,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::{Gpio5, Io, Output, PushPull},
|
||||
gpio::{Gpio5, Io, Output},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rmt::{asynch::RxChannelAsync, PulseCode, Rmt, RxChannelConfig, RxChannelCreatorAsync},
|
||||
@ -27,7 +27,7 @@ const WIDTH: usize = 80;
|
||||
compile_error!("Run this example in release mode");
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn signal_task(mut pin: Gpio5<Output<PushPull>>) {
|
||||
async fn signal_task(mut pin: Output<'static, Gpio5>) {
|
||||
loop {
|
||||
for _ in 0..10 {
|
||||
pin.toggle();
|
||||
@ -75,7 +75,7 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
spawner
|
||||
.spawn(signal_task(io.pins.gpio5.into_push_pull_output()))
|
||||
.spawn(signal_task(Output::new(io.pins.gpio5, false)))
|
||||
.unwrap();
|
||||
|
||||
let mut data = [PulseCode {
|
||||
|
@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) {
|
||||
let mut channel = rmt
|
||||
.channel0
|
||||
.configure(
|
||||
io.pins.gpio4.into_push_pull_output(),
|
||||
io.pins.gpio4,
|
||||
TxChannelConfig {
|
||||
clk_divider: 255,
|
||||
..TxChannelConfig::default()
|
||||
|
@ -91,16 +91,17 @@ async fn main(spawner: Spawner) {
|
||||
|
||||
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.into_open_drain_output();
|
||||
let can_tx_pin = io.pins.gpio0;
|
||||
let can_rx_pin = io.pins.gpio2;
|
||||
|
||||
// The speed of the CAN bus.
|
||||
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
|
||||
// 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,
|
||||
can_tx_pin,
|
||||
can_rx_pin,
|
||||
|
@ -13,8 +13,8 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
embassy,
|
||||
gpio::{Input, Io, Pull},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -33,9 +33,9 @@ async fn main(_spawner: Spawner) {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
#[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")))]
|
||||
let mut input = io.pins.gpio9.into_pull_down_input();
|
||||
let mut input = Input::new(io.pins.gpio9, Pull::Down);
|
||||
|
||||
loop {
|
||||
esp_println::println!("Waiting...");
|
||||
|
@ -8,7 +8,11 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
etm::Etm,
|
||||
gpio::{etm::GpioEtmChannels, Io},
|
||||
gpio::{
|
||||
etm::{GpioEtmChannels, GpioEtmOutputConfig},
|
||||
Io,
|
||||
Pull,
|
||||
},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
timer::systimer::{etm::SysTimerEtmEvent, SystemTimer},
|
||||
@ -24,11 +28,18 @@ fn main() -> ! {
|
||||
alarm0.set_period(1u32.secs());
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
|
@ -8,7 +8,11 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
etm::Etm,
|
||||
gpio::{etm::GpioEtmChannels, Io},
|
||||
gpio::{
|
||||
etm::{GpioEtmChannels, GpioEtmInputConfig, GpioEtmOutputConfig},
|
||||
Io,
|
||||
Pull,
|
||||
},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
};
|
||||
@ -18,15 +22,24 @@ fn main() -> ! {
|
||||
let peripherals = Peripherals::take();
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut led = io.pins.gpio1.into_push_pull_output();
|
||||
let button = io.pins.gpio9.into_pull_down_input();
|
||||
let mut led = io.pins.gpio1;
|
||||
let button = io.pins.gpio9;
|
||||
|
||||
led.set_high();
|
||||
|
||||
// setup ETM
|
||||
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||
let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
||||
let button_event = gpio_ext.channel0_event.falling_edge(button);
|
||||
let led_task = gpio_ext.channel0_task.toggle(
|
||||
&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 channel0 = etm.channel0;
|
||||
|
@ -15,7 +15,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
gpio::{self, Event, Input, Io, PullDown},
|
||||
gpio::{self, Event, Input, Io, Output, Pull},
|
||||
macros::ram,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -23,11 +23,9 @@ use esp_hal::{
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||
static BUTTON: Mutex<RefCell<Option<gpio::Gpio0<Input<PullDown>>>>> =
|
||||
Mutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Input<gpio::Gpio0>>>> = Mutex::new(RefCell::new(None));
|
||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||
static BUTTON: Mutex<RefCell<Option<gpio::Gpio9<Input<PullDown>>>>> =
|
||||
Mutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Input<gpio::Gpio9>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -38,12 +36,14 @@ fn main() -> ! {
|
||||
// Set GPIO2 as an output, and set its state high initially.
|
||||
let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
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"))]
|
||||
let mut button = io.pins.gpio0.into_pull_down_input();
|
||||
let button = io.pins.gpio0;
|
||||
#[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| {
|
||||
button.listen(Event::FallingEdge);
|
||||
|
@ -28,7 +28,7 @@ use esp_hal::{
|
||||
delay::Delay,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
gpio::Io,
|
||||
gpio::{Io, Output},
|
||||
lcd_cam::{
|
||||
lcd::i8080::{Config, TxEightBits, I8080},
|
||||
LcdCam,
|
||||
@ -67,8 +67,8 @@ fn main() -> ! {
|
||||
|
||||
let delay = Delay::new(&clocks);
|
||||
|
||||
let mut backlight = lcd_backlight.into_push_pull_output();
|
||||
let mut reset = lcd_reset.into_push_pull_output();
|
||||
let mut backlight = Output::new(lcd_backlight, false);
|
||||
let mut reset = Output::new(lcd_reset, false);
|
||||
|
||||
let tx_pins = TxEightBits::new(
|
||||
io.pins.gpio9,
|
||||
|
@ -31,7 +31,7 @@ fn main() -> ! {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
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);
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
||||
gpio::{lp_io::LowPowerOutput, Io},
|
||||
lp_core::{LpCore, LpCoreWakeupSource},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -25,7 +25,7 @@ fn main() -> ! {
|
||||
|
||||
// configure GPIO 1 as LP output pin
|
||||
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);
|
||||
lp_core.stop();
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
||||
gpio::{lp_io::LowPowerOutputOpenDrain, Io},
|
||||
i2c::lp_i2c::LpI2c,
|
||||
lp_core::{LpCore, LpCoreWakeupSource},
|
||||
peripherals::Peripherals,
|
||||
@ -26,8 +26,8 @@ fn main() -> ! {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let lp_sda = io.pins.gpio6.into_low_power().into_open_drain_output();
|
||||
let lp_scl = io.pins.gpio7.into_low_power().into_open_drain_output();
|
||||
let lp_sda = LowPowerOutputOpenDrain::new(io.pins.gpio6);
|
||||
let lp_scl = LowPowerOutputOpenDrain::new(io.pins.gpio7);
|
||||
|
||||
let lp_i2c = LpI2c::new(peripherals.LP_I2C0, lp_sda, lp_scl, 100.kHz());
|
||||
|
||||
|
@ -13,7 +13,10 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{lp_io::IntoLowPowerPin, Io},
|
||||
gpio::{
|
||||
lp_io::{LowPowerInput, LowPowerOutput},
|
||||
Io,
|
||||
},
|
||||
lp_core::{LpCore, LpCoreWakeupSource},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -32,10 +35,7 @@ fn main() -> ! {
|
||||
|
||||
// Set up (HP) UART1:
|
||||
|
||||
let pins = TxRxPins::new_tx_rx(
|
||||
io.pins.gpio6.into_push_pull_output(),
|
||||
io.pins.gpio7.into_floating_input(),
|
||||
);
|
||||
let pins = TxRxPins::new_tx_rx(io.pins.gpio6, io.pins.gpio7);
|
||||
|
||||
let mut uart1 = Uart::new_with_config(
|
||||
peripherals.UART1,
|
||||
@ -46,8 +46,8 @@ fn main() -> ! {
|
||||
);
|
||||
|
||||
// Set up (LP) UART:
|
||||
let lp_tx = io.pins.gpio5.into_low_power().into_push_pull_output();
|
||||
let lp_rx = io.pins.gpio4.into_low_power().into_floating_input();
|
||||
let lp_tx = LowPowerOutput::new(io.pins.gpio5);
|
||||
let lp_rx = LowPowerInput::new(io.pins.gpio4);
|
||||
let lp_uart = LpUart::new(peripherals.LP_UART, lp_tx, lp_rx);
|
||||
|
||||
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 esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
gpio::Io,
|
||||
gpio::{Io, Pull},
|
||||
interrupt::Priority,
|
||||
pcnt::{channel, channel::PcntSource, unit, Pcnt},
|
||||
pcnt::{
|
||||
channel::{self, PcntInputConfig, PcntSource},
|
||||
unit,
|
||||
Pcnt,
|
||||
},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
};
|
||||
@ -48,12 +52,12 @@ fn main() -> ! {
|
||||
|
||||
println!("setup channel 0");
|
||||
let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
||||
let mut pin_a = io.pins.gpio4.into_pull_up_input();
|
||||
let mut pin_b = io.pins.gpio5.into_pull_up_input();
|
||||
let mut pin_a = io.pins.gpio4;
|
||||
let mut pin_b = io.pins.gpio5;
|
||||
|
||||
ch0.configure(
|
||||
PcntSource::from_pin(&mut pin_a),
|
||||
PcntSource::from_pin(&mut pin_b),
|
||||
PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||
PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||
channel::Config {
|
||||
lctrl_mode: channel::CtrlMode::Reverse,
|
||||
hctrl_mode: channel::CtrlMode::Keep,
|
||||
@ -67,8 +71,8 @@ fn main() -> ! {
|
||||
println!("setup channel 1");
|
||||
let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
||||
ch1.configure(
|
||||
PcntSource::from_pin(&mut pin_b),
|
||||
PcntSource::from_pin(&mut pin_a),
|
||||
PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
|
||||
PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
|
||||
channel::Config {
|
||||
lctrl_mode: channel::CtrlMode::Reverse,
|
||||
hctrl_mode: channel::CtrlMode::Keep,
|
||||
|
@ -27,7 +27,7 @@ fn main() -> ! {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
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! {
|
||||
if #[cfg(feature = "esp32h2")] {
|
||||
|
@ -13,7 +13,6 @@ use esp_hal::{
|
||||
delay::Delay,
|
||||
entry,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rtc_cntl::{get_reset_reason, get_wakeup_cause, sleep::TimerWakeupSource, Rtc, SocResetReason},
|
||||
system::SystemControl,
|
||||
Cpu,
|
||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
||||
entry,
|
||||
gpio::Io,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rtc_cntl::{
|
||||
get_reset_reason,
|
||||
get_wakeup_cause,
|
||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
||||
entry,
|
||||
gpio::{Io, RtcPin},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rtc_cntl::{
|
||||
get_reset_reason,
|
||||
get_wakeup_cause,
|
||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
||||
entry,
|
||||
gpio::{Io, RtcPinWithResistors},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rtc_cntl::{
|
||||
get_reset_reason,
|
||||
get_wakeup_cause,
|
||||
|
@ -16,7 +16,6 @@ use esp_hal::{
|
||||
gpio,
|
||||
gpio::Io,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rtc_cntl::{
|
||||
get_reset_reason,
|
||||
get_wakeup_cause,
|
||||
|
@ -37,7 +37,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
gpio::{self, Io},
|
||||
gpio::{self, Io, Output},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
spi::{master::Spi, SpiMode},
|
||||
@ -63,20 +63,19 @@ fn main() -> ! {
|
||||
gpio::NO_PIN,
|
||||
);
|
||||
let spi_bus = RefCell::new(spi_bus);
|
||||
let mut spi_device_1 =
|
||||
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
|
||||
let mut spi_device_1 = RefCellDevice::new_no_delay(&spi_bus, Output::new(io.pins.gpio5, false));
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32")] {
|
||||
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 =
|
||||
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 {
|
||||
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 =
|
||||
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::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
gpio::Io,
|
||||
gpio::{any_pin::AnyPin, Io},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
spi::{master::Spi, SpiMode},
|
||||
@ -42,6 +42,9 @@ fn main() -> ! {
|
||||
let mosi = io.pins.gpio4;
|
||||
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(
|
||||
Some(sclk),
|
||||
Some(mosi),
|
||||
|
@ -34,7 +34,7 @@ use esp_hal::{
|
||||
delay::Delay,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
gpio::Io,
|
||||
gpio::{Input, Io, Output, Pull},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
spi::{
|
||||
@ -53,13 +53,13 @@ fn main() -> ! {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
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 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 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 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_sclk.set_low();
|
||||
master_mosi.set_low();
|
||||
|
@ -38,16 +38,17 @@ fn main() -> ! {
|
||||
|
||||
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.into_open_drain_output();
|
||||
let can_tx_pin = io.pins.gpio0;
|
||||
let can_rx_pin = io.pins.gpio2;
|
||||
|
||||
// The speed of the CAN bus.
|
||||
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
|
||||
// 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,
|
||||
can_tx_pin,
|
||||
can_rx_pin,
|
||||
|
@ -22,7 +22,7 @@ fn main() -> ! {
|
||||
let peripherals = Peripherals::take();
|
||||
|
||||
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);
|
||||
|
||||
|
@ -18,7 +18,7 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
embassy,
|
||||
gpio::{GpioPin, Input, Io, Output, OutputPin, PullDown, PushPull, Unknown},
|
||||
gpio::{Gpio2, Gpio4, GpioPin, Input, Io, Output, Pull},
|
||||
macros::handler,
|
||||
peripherals::Peripherals,
|
||||
system::SystemControl,
|
||||
@ -26,16 +26,15 @@ use esp_hal::{
|
||||
};
|
||||
|
||||
static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
|
||||
static INPUT_PIN: Mutex<RefCell<Option<esp_hal::gpio::Gpio2<Input<PullDown>>>>> =
|
||||
Mutex::new(RefCell::new(None));
|
||||
static INPUT_PIN: Mutex<RefCell<Option<Input<'static, Gpio2>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
struct Context {
|
||||
io2: GpioPin<Input<PullDown>, 2>,
|
||||
io4: GpioPin<Output<PushPull>, 4>,
|
||||
struct Context<'d> {
|
||||
io2: Input<'d, Gpio2>,
|
||||
io4: Output<'d, Gpio4>,
|
||||
delay: Delay,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
impl<'d> Context<'d> {
|
||||
pub fn init() -> Self {
|
||||
let peripherals = Peripherals::take();
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
@ -50,8 +49,8 @@ impl Context {
|
||||
embassy::init(&clocks, timg0);
|
||||
|
||||
Context {
|
||||
io2: io.pins.gpio2.into_pull_down_input(),
|
||||
io4: io.pins.gpio4.into_push_pull_output(),
|
||||
io2: Input::new(io.pins.gpio2, Pull::Down),
|
||||
io4: Output::new(io.pins.gpio4, false),
|
||||
delay,
|
||||
}
|
||||
}
|
||||
@ -60,8 +59,6 @@ impl Context {
|
||||
#[handler]
|
||||
pub fn interrupt_handler() {
|
||||
critical_section::with(|cs| {
|
||||
use esp_hal::gpio::Pin;
|
||||
|
||||
*COUNTER.borrow_ref_mut(cs) += 1;
|
||||
INPUT_PIN
|
||||
.borrow_ref_mut(cs)
|
||||
@ -75,13 +72,13 @@ pub fn interrupt_handler() {
|
||||
mod tests {
|
||||
use defmt::assert_eq;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::gpio::{Event, Pin};
|
||||
use esp_hal::gpio::{Event, OutputOpenDrain};
|
||||
use portable_atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[init]
|
||||
fn init() -> Context {
|
||||
fn init() -> Context<'static> {
|
||||
let mut ctx = Context::init();
|
||||
// make sure tests don't interfere with each other
|
||||
ctx.io4.set_low();
|
||||
@ -89,7 +86,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_async_edge(ctx: Context) {
|
||||
async fn test_async_edge(ctx: Context<'static>) {
|
||||
let counter = AtomicUsize::new(0);
|
||||
let Context {
|
||||
mut io2, mut io4, ..
|
||||
@ -115,8 +112,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_a_pin_can_wait(_ctx: Context) {
|
||||
let mut first = unsafe { GpioPin::<Unknown, 0>::steal() }.into_pull_down_input();
|
||||
async fn test_a_pin_can_wait(_ctx: Context<'static>) {
|
||||
let mut first = Input::new( unsafe { GpioPin::<0>::steal() } , Pull::Down);
|
||||
|
||||
embassy_futures::select::select(
|
||||
first.wait_for_rising_edge(),
|
||||
@ -128,14 +125,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_input(ctx: Context) {
|
||||
fn test_gpio_input(ctx: Context<'static>) {
|
||||
// `InputPin`:
|
||||
assert_eq!(ctx.io2.is_low(), true);
|
||||
assert_eq!(ctx.io2.is_high(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_output(mut ctx: Context) {
|
||||
fn test_gpio_output(mut ctx: Context<'static>) {
|
||||
// `StatefulOutputPin`:
|
||||
assert_eq!(ctx.io4.is_set_low(), true);
|
||||
assert_eq!(ctx.io4.is_set_high(), false);
|
||||
@ -154,7 +151,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[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| {
|
||||
*COUNTER.borrow_ref_mut(cs) = 0;
|
||||
ctx.io2.listen(Event::AnyEdge);
|
||||
@ -187,14 +184,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_od(ctx: Context) {
|
||||
let mut io2 = ctx.io2.into_open_drain_output();
|
||||
io2.internal_pull_up(true);
|
||||
let mut io4 = ctx.io4.into_open_drain_output();
|
||||
io4.internal_pull_up(true);
|
||||
fn test_gpio_od(ctx: Context<'static>) {
|
||||
let mut io2 = OutputOpenDrain::new(unsafe { GpioPin::<2>::steal() }, true, Pull::Up);
|
||||
let mut io4 = OutputOpenDrain::new(unsafe { GpioPin::<4>::steal() }, true, Pull::Up);
|
||||
|
||||
io2.set_high();
|
||||
io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
assert_eq!(io2.is_high(), true);
|
||||
@ -220,5 +213,20 @@ mod tests {
|
||||
|
||||
assert_eq!(io2.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 io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let pins = TxRxPins::new_tx_rx(
|
||||
io.pins.gpio2.into_push_pull_output(),
|
||||
io.pins.gpio4.into_floating_input(),
|
||||
);
|
||||
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
|
||||
|
||||
let uart = Uart::new_with_config(
|
||||
peripherals.UART0,
|
||||
|
@ -33,10 +33,7 @@ impl Context {
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let pins = TxRxPins::new_tx_rx(
|
||||
io.pins.gpio2.into_push_pull_output(),
|
||||
io.pins.gpio4.into_floating_input(),
|
||||
);
|
||||
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
|
||||
|
||||
let uart =
|
||||
Uart::new_async_with_config(peripherals.UART0, Config::default(), Some(pins), &clocks);
|
||||
|
Loading…
x
Reference in New Issue
Block a user