mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
Shared GPIO Implementation (#3)
* make esp32c3 examples run from flash / flashable * use gpio3 for blinky * direct boot in Cargo.toml * have a shared gpio impl * use PACs from their original locations again
This commit is contained in:
parent
4e9ad72839
commit
6d94b61268
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -1,4 +1,7 @@
|
||||
{
|
||||
"rust-analyzer.cargo.features": [
|
||||
"esp32c3"
|
||||
],
|
||||
"editor.formatOnSave": true,
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
}
|
||||
}
|
@ -4,5 +4,5 @@ members = [
|
||||
"esp32-hal",
|
||||
"esp32c3-hal",
|
||||
"esp32s2-hal",
|
||||
"esp32s3-hal",
|
||||
"esp32s3-hal"
|
||||
]
|
||||
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
paste = "1.0.6"
|
||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
nb = "1.0"
|
||||
riscv = { version = "0.7", optional = true }
|
||||
@ -12,7 +13,7 @@ xtensa-lx = { version = "0.4", optional = true }
|
||||
# IMPORTANT:
|
||||
# Each supported device MUST have its PAC included below along with a
|
||||
# corresponding feature.
|
||||
esp32_pac = { package = "esp32", git = "https://github.com/jessebraham/esp32.git", branch = "develop", optional = true }
|
||||
esp32_pac = { package = "esp32", git = "https://github.com/jessebraham/esp32.git", branch = "develop", optional = true }
|
||||
esp32c3_pac = { package = "esp32c3", git = "https://github.com/jessebraham/esp32c3.git", branch = "develop", optional = true }
|
||||
esp32s2_pac = { package = "esp32s2", git = "https://github.com/jessebraham/esp32s2.git", branch = "develop", optional = true }
|
||||
esp32s3_pac = { package = "esp32s3", git = "https://github.com/jessebraham/esp32s3.git", branch = "develop", optional = true }
|
||||
|
758
esp-hal-common/src/gpio/mod.rs
Normal file
758
esp-hal-common/src/gpio/mod.rs
Normal file
@ -0,0 +1,758 @@
|
||||
pub use crate::prelude::*;
|
||||
pub use paste::paste;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_output {
|
||||
(
|
||||
$gpio_function:ident,
|
||||
$pxi:ident:
|
||||
(
|
||||
$pin_num:expr, $iomux_reg:expr, $bit:expr, $out_en_set:ident, $out_en_clear:ident,
|
||||
$out_set:ident, $out_clear:ident, $out_reg:ident
|
||||
)
|
||||
$( ,( $( $af_signal:ident: $af:ident ),* ))?
|
||||
) => {
|
||||
impl<MODE> embedded_hal::digital::v2::OutputPin for $pxi<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) };
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> embedded_hal::digital::v2::StatefulOutputPin for $pxi<Output<MODE>> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
unsafe { Ok((*GPIO::ptr()).$out_reg.read().bits() & (1 << $bit) != 0) }
|
||||
}
|
||||
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_set_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> embedded_hal::digital::v2::ToggleableOutputPin for $pxi<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
if self.is_set_high()? {
|
||||
Ok(self.set_low()?)
|
||||
} else {
|
||||
Ok(self.set_high()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $pxi<MODE> {
|
||||
pub fn into_pull_up_input(self) -> $pxi<Input<PullUp>> {
|
||||
self.init_input(false, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_pull_down_input(self) -> $pxi<Input<PullDown>> {
|
||||
self.init_input(true, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
fn init_output(&self, alternate: AlternateFunction, open_drain: bool) {
|
||||
let gpio = unsafe { &*GPIO::ptr() };
|
||||
let iomux = unsafe { &*IO_MUX::ptr() };
|
||||
|
||||
gpio.$out_en_set.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
gpio.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(open_drain));
|
||||
gpio.func_out_sel_cfg[$pin_num]
|
||||
.modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) });
|
||||
|
||||
paste! {
|
||||
iomux.$iomux_reg.modify(|_, w| unsafe {
|
||||
w.mcu_sel()
|
||||
.bits(alternate as u8)
|
||||
.fun_ie()
|
||||
.clear_bit()
|
||||
.fun_wpd()
|
||||
.clear_bit()
|
||||
.fun_wpu()
|
||||
.clear_bit()
|
||||
.fun_drv()
|
||||
.bits(DriveStrength::I20mA as u8)
|
||||
.slp_sel()
|
||||
.clear_bit()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn into_push_pull_output(self) -> $pxi<Output<PushPull>> {
|
||||
self.init_output(AlternateFunction::$gpio_function, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_open_drain_output(self) -> $pxi<Output<OpenDrain>> {
|
||||
self.init_output(AlternateFunction::$gpio_function, true);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_alternate_1(self) -> $pxi<Alternate<AF1>> {
|
||||
self.init_output(AlternateFunction::Function1, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_alternate_2(self) -> $pxi<Alternate<AF2>> {
|
||||
self.init_output(AlternateFunction::Function2, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> OutputPin for $pxi<MODE> {
|
||||
fn set_to_open_drain_output(&mut self) -> &mut Self {
|
||||
self.init_output(AlternateFunction::$gpio_function, true);
|
||||
self
|
||||
}
|
||||
|
||||
fn set_to_push_pull_output(&mut self) -> &mut Self {
|
||||
self.init_output(AlternateFunction::$gpio_function, false);
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_output(&mut self, on: bool) -> &mut Self {
|
||||
if on {
|
||||
unsafe { &*GPIO::ptr() }
|
||||
.$out_en_set
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
} else {
|
||||
unsafe { &*GPIO::ptr() }
|
||||
.$out_en_clear
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_output_high(&mut self, high: bool) -> &mut Self {
|
||||
if high {
|
||||
unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) };
|
||||
} else {
|
||||
unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) };
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) });
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_open_drain(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*GPIO::ptr() }.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.mcu_wpu().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
paste!{
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.mcu_wpd().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.mcu_oe().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
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,
|
||||
) -> &mut Self {
|
||||
let af = if force_via_gpio_mux {
|
||||
AlternateFunction::$gpio_function
|
||||
} else {
|
||||
match signal {
|
||||
$( $(
|
||||
OutputSignal::$af_signal => AlternateFunction::$af,
|
||||
)* )?
|
||||
_ => AlternateFunction::$gpio_function
|
||||
}
|
||||
};
|
||||
|
||||
if af == AlternateFunction::$gpio_function && signal as usize > OUTPUT_SIGNAL_MAX as usize {
|
||||
panic!("Cannot connect this peripheral to GPIO");
|
||||
}
|
||||
|
||||
self.set_alternate_function(af);
|
||||
|
||||
let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize { signal as OutputSignalType } else { OUTPUT_SIGNAL_MAX };
|
||||
|
||||
unsafe { &*GPIO::ptr() }.func_out_sel_cfg[$pin_num].modify(|_, w| unsafe {
|
||||
w
|
||||
.out_sel().bits(clipped_signal)
|
||||
.inv_sel().bit(invert)
|
||||
.oen_sel().bit(enable_from_gpio)
|
||||
.oen_inv_sel().bit(invert_enable)
|
||||
});
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_up(&mut self, on: bool) -> &mut Self {
|
||||
paste!{
|
||||
unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpu().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_down(&mut self, on: bool) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpd().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_input {
|
||||
($gpio_function:ident,
|
||||
$pxi:ident:
|
||||
($pin_num:expr, $iomux_reg:expr, $bit:expr, $out_en_clear:ident, $reg:ident, $reader:ident,
|
||||
$status_w1tc:ident, $pcpu_int:ident, $pcpu_nmi:ident, $acpu_int:ident, $acpu_nmi:ident
|
||||
) $( ,( $( $af_signal:ident : $af:ident ),* ))?
|
||||
) => {
|
||||
impl<MODE> embedded_hal::digital::v2::InputPin for $pxi<Input<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(unsafe { &*GPIO::ptr() }.$reg.read().$reader().bits() & (1 << $bit) != 0)
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $pxi<MODE> {
|
||||
fn init_input(&self, pull_down: bool, pull_up: bool) {
|
||||
let gpio = unsafe { &*GPIO::ptr() };
|
||||
let iomux = unsafe { &*IO_MUX::ptr() };
|
||||
|
||||
|
||||
gpio.$out_en_clear
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
|
||||
gpio.func_out_sel_cfg[$pin_num]
|
||||
.modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) });
|
||||
|
||||
|
||||
paste! {
|
||||
iomux.$iomux_reg.modify(|_, w| unsafe {
|
||||
w.mcu_sel()
|
||||
.bits(2)
|
||||
.fun_ie()
|
||||
.set_bit()
|
||||
.fun_wpd()
|
||||
.bit(pull_down)
|
||||
.fun_wpu()
|
||||
.bit(pull_up)
|
||||
.slp_sel()
|
||||
.clear_bit()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_floating_input(self) -> $pxi<Input<Floating>> {
|
||||
self.init_input(false, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> InputPin for $pxi<MODE> {
|
||||
fn set_to_input(&mut self) -> &mut Self {
|
||||
self.init_input(false, false);
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_input(&mut self, on: bool) -> &mut Self {
|
||||
paste!{
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.fun_ie().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.mcu_ie().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn is_input_high(&mut self) -> bool {
|
||||
unsafe { &*GPIO::ptr() }.$reg.read().$reader().bits() & (1 << $bit) != 0
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
signal: InputSignal,
|
||||
invert: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
) -> &mut Self {
|
||||
|
||||
let af = if force_via_gpio_mux
|
||||
{
|
||||
AlternateFunction::$gpio_function
|
||||
}
|
||||
else {
|
||||
match signal {
|
||||
$( $(
|
||||
InputSignal::$af_signal => AlternateFunction::$af,
|
||||
)* )?
|
||||
_ => AlternateFunction::$gpio_function
|
||||
}
|
||||
};
|
||||
|
||||
if af == AlternateFunction::$gpio_function && signal as usize > INPUT_SIGNAL_MAX as usize {
|
||||
panic!("Cannot connect GPIO to this peripheral");
|
||||
}
|
||||
|
||||
self.set_alternate_function(af);
|
||||
|
||||
if (signal as usize) <= INPUT_SIGNAL_MAX as usize {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(invert)
|
||||
.in_sel()
|
||||
.bits($pin_num)
|
||||
});
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> Pin for $pxi<MODE> {
|
||||
fn sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| w.slp_sel().bit(on));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self {
|
||||
paste! {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.$iomux_reg
|
||||
.modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) });
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn listen_with_options(&mut self, event: Event,
|
||||
int_enable: bool, nmi_enable: bool,
|
||||
wake_up_from_light_sleep: bool
|
||||
) {
|
||||
if wake_up_from_light_sleep {
|
||||
match event {
|
||||
Event::AnyEdge | Event::RisingEdge | Event::FallingEdge => {
|
||||
panic!("Edge triggering is not supported for wake-up from light sleep");
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
(&*GPIO::ptr()).pin[$pin_num].modify(|_, w|
|
||||
w
|
||||
.pin_int_ena().bits(int_enable as u8 | ((nmi_enable as u8) << 1))
|
||||
.pin_int_type().bits(event as u8)
|
||||
.pin_wakeup_enable().bit(wake_up_from_light_sleep)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn unlisten(&mut self) {
|
||||
unsafe { (&*GPIO::ptr()).pin[$pin_num].modify(|_, w|
|
||||
w.pin_int_ena().bits(0).pin_int_type().bits(0).pin_int_ena().bits(0) );
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_interrupt(&mut self) {
|
||||
unsafe {&*GPIO::ptr()}.$status_w1tc.write(|w|
|
||||
unsafe {w.bits(1 << $bit)})
|
||||
}
|
||||
|
||||
fn is_pcore_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$pcpu_int.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn is_pcore_non_maskable_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$pcpu_nmi.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn is_acore_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$acpu_int.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn is_acore_non_maskable_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$acpu_nmi.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn enable_hold(&mut self, _on: bool) {
|
||||
|
||||
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_pin_wrap {
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, SingleCore
|
||||
$( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )?
|
||||
) => {
|
||||
impl_input!($gpio_function, $pxi: ($pin_num, $iomux_reg, $pin_num % 32, enable_w1tc, in_, data_next,
|
||||
status_w1tc, pcpu_int, pcpu_nmi_int, pcpu_int, pcpu_nmi_int)
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
};
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, SingleCore
|
||||
$( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )?
|
||||
) => {
|
||||
impl_input!($gpio_function, $pxi: ($pin_num, $iomux_reg, $pin_num % 32, enable1_w1tc, in1, data_next,
|
||||
status1_w1tc, pcpu_int1, pcpu_nmi_int1, pcpu_int1, pcpu_nmi_int1)
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
};
|
||||
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, DualCore
|
||||
$( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )?
|
||||
) => {
|
||||
impl_input!($gpio_function, $pxi: ($pin_num, $iomux_reg, $pin_num % 32, enable_w1tc, in_, data_next,
|
||||
status_w1tc, pcpu_int, pcpu_nmi_int, acpu_int, acpu_nmi_int)
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
};
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, DualCore
|
||||
$( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )?
|
||||
) => {
|
||||
impl_input!($gpio_function, $pxi: ($pin_num, $iomux_reg, $pin_num % 32, enable1_w1tc, in1, data_next,
|
||||
status1_w1tc, pcpu_int1, pcpu_nmi_int1, acpu_int1, acpu_nmi_int1)
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_output_wrap {
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank0
|
||||
$( ,( $( $af_output_signal:ident : $af_output:ident ),* ))?
|
||||
) => {
|
||||
impl_output!($gpio_function, $pxi:
|
||||
($pin_num, $iomux_reg, $pin_num % 32, enable_w1ts, enable_w1tc, out_w1ts, out_w1tc, out)
|
||||
|
||||
$( ,( $( $af_output_signal: $af_output ),* ) )? );
|
||||
};
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank1
|
||||
$( ,( $( $af_output_signal:ident : $af_output:ident ),* ))?
|
||||
) => {
|
||||
impl_output!($gpio_function, $pxi:
|
||||
($pin_num, $iomux_reg, $pin_num % 32, enable1_w1ts, enable1_w1tc, out1_w1ts, out1_w1tc, out1)
|
||||
|
||||
$( ,( $( $af_output_signal: $af_output ),* ) )? );
|
||||
};
|
||||
|
||||
($gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, $bank:ident
|
||||
$( ,( $( $af_output_signal:ident : $af_output:ident ),* ))?
|
||||
) => {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! gpio {
|
||||
( $gpio_function:ident,
|
||||
$cores:ident,
|
||||
$($pxi:ident: ($pname:ident, $pin_num:literal, $iomux_reg:expr, $type:ident, $rtc:tt, $bank:ident ),
|
||||
$(
|
||||
( $( $af_input_signal:ident: $af_input:ident ),* ),
|
||||
$(
|
||||
( $( $af_output_signal:ident: $af_output:ident ),* ),
|
||||
)?
|
||||
)?
|
||||
)+ ) => {
|
||||
use core::{convert::Infallible, marker::PhantomData};
|
||||
use embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _};
|
||||
use crate::pac::{GPIO, IO_MUX};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct IO {
|
||||
io_mux: IO_MUX,
|
||||
pub pins: Pins,
|
||||
}
|
||||
|
||||
impl IO {
|
||||
pub fn new(gpio: GPIO, io_mux: IO_MUX) -> Self {
|
||||
let pins = gpio.split();
|
||||
let io = IO { io_mux, pins };
|
||||
|
||||
io
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GpioExt {
|
||||
type Parts;
|
||||
|
||||
fn split(self) -> Self::Parts;
|
||||
}
|
||||
|
||||
pub trait Pin {
|
||||
fn sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self;
|
||||
|
||||
fn listen(&mut self, event: Event) {
|
||||
self.listen_with_options(event, true, false, false)
|
||||
}
|
||||
|
||||
fn listen_with_options(
|
||||
&mut self,
|
||||
event: Event,
|
||||
int_enable: bool,
|
||||
nmi_enable: bool,
|
||||
wake_up_from_light_sleep: bool,
|
||||
);
|
||||
|
||||
fn unlisten(&mut self);
|
||||
|
||||
fn clear_interrupt(&mut self);
|
||||
|
||||
fn is_pcore_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn is_pcore_non_maskable_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn is_acore_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn is_acore_non_maskable_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn enable_hold(&mut self, on: bool);
|
||||
}
|
||||
|
||||
pub trait InputPin: Pin {
|
||||
fn set_to_input(&mut self) -> &mut Self;
|
||||
|
||||
fn enable_input(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn is_input_high(&mut self) -> bool;
|
||||
|
||||
fn connect_input_to_peripheral(&mut self, signal: InputSignal) -> &mut Self {
|
||||
self.connect_input_to_peripheral_with_options(signal, false, false)
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
signal: InputSignal,
|
||||
invert: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
) -> &mut Self;
|
||||
}
|
||||
|
||||
pub trait OutputPin: Pin {
|
||||
fn set_to_open_drain_output(&mut self) -> &mut Self;
|
||||
|
||||
fn set_to_push_pull_output(&mut self) -> &mut Self;
|
||||
|
||||
fn enable_output(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_output_high(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self;
|
||||
|
||||
fn enable_open_drain(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn connect_peripheral_to_output(&mut self, signal: OutputSignal) -> &mut Self {
|
||||
self.connect_peripheral_to_output_with_options(signal, false, false, false, false)
|
||||
}
|
||||
|
||||
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,
|
||||
) -> &mut Self;
|
||||
|
||||
fn internal_pull_up(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_down(&mut self, on: bool) -> &mut Self;
|
||||
}
|
||||
|
||||
pub trait RTCPin {}
|
||||
|
||||
pub trait AnalogPin {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Event {
|
||||
RisingEdge = 1,
|
||||
FallingEdge = 2,
|
||||
AnyEdge = 3,
|
||||
LowLevel = 4,
|
||||
HighLevel = 5,
|
||||
}
|
||||
|
||||
pub struct Unknown {}
|
||||
|
||||
pub struct Input<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct RTCInput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct Floating;
|
||||
|
||||
pub struct PullDown;
|
||||
|
||||
pub struct PullUp;
|
||||
|
||||
pub struct Output<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct RTCOutput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct OpenDrain;
|
||||
|
||||
pub struct PushPull;
|
||||
|
||||
pub struct Analog;
|
||||
|
||||
pub struct Alternate<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct AF0;
|
||||
|
||||
pub struct AF1;
|
||||
|
||||
pub struct AF2;
|
||||
|
||||
pub enum DriveStrength {
|
||||
I5mA = 0,
|
||||
I10mA = 1,
|
||||
I20mA = 2,
|
||||
I40mA = 3,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum AlternateFunction {
|
||||
Function0 = 0,
|
||||
Function1 = 1,
|
||||
Function2 = 2,
|
||||
Function3 = 3,
|
||||
Function4 = 4,
|
||||
Function5 = 5,
|
||||
}
|
||||
|
||||
pub fn connect_low_to_peripheral(signal: InputSignal) {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(false)
|
||||
.in_sel()
|
||||
.bits(0x1f)
|
||||
});
|
||||
}
|
||||
|
||||
pub fn connect_high_to_peripheral(signal: InputSignal) {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(false)
|
||||
.in_sel()
|
||||
.bits(0x1e)
|
||||
});
|
||||
}
|
||||
|
||||
impl GpioExt for GPIO {
|
||||
type Parts = Pins;
|
||||
|
||||
fn split(self) -> Self::Parts {
|
||||
Pins {
|
||||
$(
|
||||
$pname: $pxi { _mode: PhantomData },
|
||||
)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct Pins {
|
||||
$(
|
||||
|
||||
pub $pname: $pxi<Unknown>,
|
||||
)+
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(
|
||||
|
||||
pub struct $pxi<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
impl_pin_wrap!($gpio_function, $pxi, $pin_num, $iomux_reg, $type, $bank, $cores
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
impl_output_wrap!($gpio_function, $pxi, $pin_num, $iomux_reg, $type, $bank
|
||||
$($( ,( $( $af_output_signal: $af_output ),* ) )? )? );
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
pub use gpio;
|
||||
pub use impl_input;
|
||||
pub use impl_output;
|
||||
pub use impl_output_wrap;
|
||||
pub use impl_pin_wrap;
|
@ -9,9 +9,11 @@ pub use esp32s2_pac as pac;
|
||||
#[cfg(feature = "esp32s3")]
|
||||
pub use esp32s3_pac as pac;
|
||||
|
||||
pub mod gpio;
|
||||
pub mod prelude;
|
||||
pub mod serial;
|
||||
pub mod timer;
|
||||
|
||||
pub use gpio::*;
|
||||
pub use serial::Serial;
|
||||
pub use timer::Timer;
|
||||
|
@ -112,13 +112,6 @@ impl<T: Instance> Write<u8> for Serial<T> {
|
||||
|
||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||
if self.uart.get_tx_fifo_count() < UART_FIFO_SIZE {
|
||||
#[cfg(feature = "esp32")]
|
||||
self.uart
|
||||
.register_block()
|
||||
.fifo()
|
||||
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
self.uart
|
||||
.register_block()
|
||||
.fifo
|
||||
@ -144,16 +137,6 @@ impl<T: Instance> Read<u8> for Serial<T> {
|
||||
|
||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||
if self.uart.get_rx_fifo_count() > 0 {
|
||||
#[cfg(feature = "esp32")]
|
||||
let value = self
|
||||
.uart
|
||||
.register_block()
|
||||
.fifo()
|
||||
.read()
|
||||
.rxfifo_rd_byte()
|
||||
.bits();
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
let value = self
|
||||
.uart
|
||||
.register_block()
|
||||
|
@ -99,13 +99,17 @@ pub trait Instance {
|
||||
|
||||
reg_block
|
||||
.wdtwprotect
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0u32) });
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) });
|
||||
|
||||
reg_block.wdtconfig0.write(|w| w.wdt_en().bit(enabled));
|
||||
if !enabled {
|
||||
reg_block.wdtconfig0.write(|w| unsafe { w.bits(0) });
|
||||
} else {
|
||||
reg_block.wdtconfig0.write(|w| w.wdt_en().bit(true));
|
||||
}
|
||||
|
||||
reg_block
|
||||
.wdtwprotect
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) });
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0u32) });
|
||||
}
|
||||
}
|
||||
|
||||
|
27
esp32-hal/examples/blinky.rs
Normal file
27
esp32-hal/examples/blinky.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32_hal::{gpio::IO, pac, prelude::*, Timer};
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = pac::Peripherals::take().unwrap();
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut timer0 = Timer::new(peripherals.TIMG0);
|
||||
|
||||
timer0.disable();
|
||||
|
||||
let mut led = io.pins.gpio15.into_push_pull_output();
|
||||
led.set_high().unwrap();
|
||||
|
||||
timer0.start(10_000_000u64);
|
||||
|
||||
loop {
|
||||
led.toggle().unwrap();
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
}
|
543
esp32-hal/src/gpio.rs
Normal file
543
esp32-hal/src/gpio.rs
Normal file
@ -0,0 +1,543 @@
|
||||
use esp_hal_common::gpio::gpio;
|
||||
|
||||
use crate::hal_gpio::*;
|
||||
|
||||
type OutputSignalType = u16;
|
||||
const OUTPUT_SIGNAL_MAX: u16 = 548;
|
||||
const INPUT_SIGNAL_MAX: u16 = 539;
|
||||
|
||||
/// Peripheral input signals for the GPIO mux
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub enum InputSignal {
|
||||
SPICLK = 0,
|
||||
SPIQ = 1,
|
||||
SPID = 2,
|
||||
SPIHD = 3,
|
||||
SPIWP = 4,
|
||||
SPICS0 = 5,
|
||||
SPICS1 = 6,
|
||||
SPICS2 = 7,
|
||||
HSPICLK = 8,
|
||||
HSPIQ = 9,
|
||||
HSPID = 10,
|
||||
HSPICS0 = 11,
|
||||
HSPIHD = 12,
|
||||
HSPIWP = 13,
|
||||
U0RXD = 14,
|
||||
U0CTS = 15,
|
||||
U0DSR = 16,
|
||||
U1RXD = 17,
|
||||
U1CTS = 18,
|
||||
I2CM_SDA = 20,
|
||||
EXT_I2C_SDA = 22,
|
||||
I2S0O_BCK = 23,
|
||||
I2S1O_BCK = 24,
|
||||
I2S0O_WS = 25,
|
||||
I2S1O_WS = 26,
|
||||
I2S0I_BCK = 27,
|
||||
I2S0I_WS = 28,
|
||||
I2CEXT0_SCL = 29,
|
||||
I2CEXT0_SDA = 30,
|
||||
PWM0_SYNC0 = 31,
|
||||
PWM0_SYNC1 = 32,
|
||||
PWM0_SYNC2 = 33,
|
||||
PWM0_F0 = 34,
|
||||
PWM0_F1 = 35,
|
||||
PWM0_F2 = 36,
|
||||
GPIO_BT_ACTIVE = 37,
|
||||
GPIO_BT_PRIORITY = 38,
|
||||
PCNT_SIG_CH0_0 = 39,
|
||||
PCNT_SIG_CH1_0 = 40,
|
||||
PCNT_CTRL_CH0_0 = 41,
|
||||
PCNT_CTRL_CH1_0 = 42,
|
||||
PCNT_SIG_CH0_1 = 43,
|
||||
PCNT_SIG_CH1_1 = 44,
|
||||
PCNT_CTRL_CH0_1 = 45,
|
||||
PCNT_CTRL_CH1_1 = 46,
|
||||
PCNT_SIG_CH0_2 = 47,
|
||||
PCNT_SIG_CH1_2 = 48,
|
||||
PCNT_CTRL_CH0_2 = 49,
|
||||
PCNT_CTRL_CH1_2 = 50,
|
||||
PCNT_SIG_CH0_3 = 51,
|
||||
PCNT_SIG_CH1_3 = 52,
|
||||
PCNT_CTRL_CH0_3 = 53,
|
||||
PCNT_CTRL_CH1_3 = 54,
|
||||
PCNT_SIG_CH0_4 = 55,
|
||||
PCNT_SIG_CH1_4 = 56,
|
||||
PCNT_CTRL_CH0_4 = 57,
|
||||
PCNT_CTRL_CH1_4 = 58,
|
||||
HSPICS1 = 61,
|
||||
HSPICS2 = 62,
|
||||
VSPICLK = 63,
|
||||
VSPIQ = 64,
|
||||
VSPID = 65,
|
||||
VSPIHD = 66,
|
||||
VSPIWP = 67,
|
||||
VSPICS0 = 68,
|
||||
VSPICS1 = 69,
|
||||
VSPICS2 = 70,
|
||||
PCNT_SIG_CH0_5 = 71,
|
||||
PCNT_SIG_CH1_5 = 72,
|
||||
PCNT_CTRL_CH0_5 = 73,
|
||||
PCNT_CTRL_CH1_5 = 74,
|
||||
PCNT_SIG_CH0_6 = 75,
|
||||
PCNT_SIG_CH1_6 = 76,
|
||||
PCNT_CTRL_CH0_6 = 77,
|
||||
PCNT_CTRL_CH1_6 = 78,
|
||||
PCNT_SIG_CH0_7 = 79,
|
||||
PCNT_SIG_CH1_7 = 80,
|
||||
PCNT_CTRL_CH0_7 = 81,
|
||||
PCNT_CTRL_CH1_7 = 82,
|
||||
RMT_SIG_0 = 83,
|
||||
RMT_SIG_1 = 84,
|
||||
RMT_SIG_2 = 85,
|
||||
RMT_SIG_3 = 86,
|
||||
RMT_SIG_4 = 87,
|
||||
RMT_SIG_5 = 88,
|
||||
RMT_SIG_6 = 89,
|
||||
RMT_SIG_7 = 90,
|
||||
EXT_ADC_START = 93,
|
||||
CAN_RX = 94,
|
||||
I2CEXT1_SCL = 95,
|
||||
I2CEXT1_SDA = 96,
|
||||
HOST_CARD_DETECT_N_1 = 97,
|
||||
HOST_CARD_DETECT_N_2 = 98,
|
||||
HOST_CARD_WRITE_PRT_1 = 99,
|
||||
HOST_CARD_WRITE_PRT_2 = 100,
|
||||
HOST_CARD_INT_N_1 = 101,
|
||||
HOST_CARD_INT_N_2 = 102,
|
||||
PWM1_SYNC0 = 103,
|
||||
PWM1_SYNC1 = 104,
|
||||
PWM1_SYNC2 = 105,
|
||||
PWM1_F0 = 106,
|
||||
PWM1_F1 = 107,
|
||||
PWM1_F2 = 108,
|
||||
PWM0_CAP0 = 109,
|
||||
PWM0_CAP1 = 110,
|
||||
PWM0_CAP2 = 111,
|
||||
PWM1_CAP0 = 112,
|
||||
PWM1_CAP1 = 113,
|
||||
PWM1_CAP2 = 114,
|
||||
PWM2_FLTA = 115,
|
||||
PWM2_FLTB = 116,
|
||||
PWM2_CAP1 = 117,
|
||||
PWM2_CAP2 = 118,
|
||||
PWM2_CAP3 = 119,
|
||||
PWM3_FLTA = 120,
|
||||
PWM3_FLTB = 121,
|
||||
PWM3_CAP1 = 122,
|
||||
PWM3_CAP2 = 123,
|
||||
PWM3_CAP3 = 124,
|
||||
CAN_CLKOUT = 125,
|
||||
SPID4 = 128,
|
||||
SPID5 = 129,
|
||||
SPID6 = 130,
|
||||
SPID7 = 131,
|
||||
HSPID4 = 132,
|
||||
HSPID5 = 133,
|
||||
HSPID6 = 134,
|
||||
HSPID7 = 135,
|
||||
VSPID4 = 136,
|
||||
VSPID5 = 137,
|
||||
VSPID6 = 138,
|
||||
VSPID7 = 139,
|
||||
I2S0I_DATA_0 = 140,
|
||||
I2S0I_DATA_1 = 141,
|
||||
I2S0I_DATA_2 = 142,
|
||||
I2S0I_DATA_3 = 143,
|
||||
I2S0I_DATA_4 = 144,
|
||||
I2S0I_DATA_5 = 145,
|
||||
I2S0I_DATA_6 = 146,
|
||||
I2S0I_DATA_7 = 147,
|
||||
I2S0I_DATA_8 = 148,
|
||||
I2S0I_DATA_9 = 149,
|
||||
I2S0I_DATA_10 = 150,
|
||||
I2S0I_DATA_11 = 151,
|
||||
I2S0I_DATA_12 = 152,
|
||||
I2S0I_DATA_13 = 153,
|
||||
I2S0I_DATA_14 = 154,
|
||||
I2S0I_DATA_15 = 155,
|
||||
I2S1I_BCK = 164,
|
||||
I2S1I_WS = 165,
|
||||
I2S1I_DATA_0 = 166,
|
||||
I2S1I_DATA_1 = 167,
|
||||
I2S1I_DATA_2 = 168,
|
||||
I2S1I_DATA_3 = 169,
|
||||
I2S1I_DATA_4 = 170,
|
||||
I2S1I_DATA_5 = 171,
|
||||
I2S1I_DATA_6 = 172,
|
||||
I2S1I_DATA_7 = 173,
|
||||
I2S1I_DATA_8 = 174,
|
||||
I2S1I_DATA_9 = 175,
|
||||
I2S1I_DATA_10 = 176,
|
||||
I2S1I_DATA_11 = 177,
|
||||
I2S1I_DATA_12 = 178,
|
||||
I2S1I_DATA_13 = 179,
|
||||
I2S1I_DATA_14 = 180,
|
||||
I2S1I_DATA_15 = 181,
|
||||
I2S0I_H_SYNC = 190,
|
||||
I2S0I_V_SYNC = 191,
|
||||
I2S0I_H_ENABLE = 192,
|
||||
I2S1I_H_SYNC = 193,
|
||||
I2S1I_V_SYNC = 194,
|
||||
I2S1I_H_ENABLE = 195,
|
||||
U2RXD = 198,
|
||||
U2CTS = 199,
|
||||
EMAC_MDC = 200,
|
||||
EMAC_MDI = 201,
|
||||
EMAC_CRS = 202,
|
||||
EMAC_COL = 203,
|
||||
PCMFSYNC = 204,
|
||||
PCMCLK = 205,
|
||||
PCMDIN = 206,
|
||||
SIG_IN_FUNC224 = 224,
|
||||
SIG_IN_FUNC225 = 225,
|
||||
SIG_IN_FUNC226 = 226,
|
||||
SIG_IN_FUNC227 = 227,
|
||||
SIG_IN_FUNC228 = 228,
|
||||
|
||||
SD_DATA0 = 512,
|
||||
SD_DATA1,
|
||||
SD_DATA2,
|
||||
SD_DATA3,
|
||||
HS1_DATA0,
|
||||
HS1_DATA1,
|
||||
HS1_DATA2,
|
||||
HS1_DATA3,
|
||||
HS1_DATA4,
|
||||
HS1_DATA5,
|
||||
HS1_DATA6,
|
||||
HS1_DATA7,
|
||||
HS2_DATA0,
|
||||
HS2_DATA1,
|
||||
HS2_DATA2,
|
||||
HS2_DATA3,
|
||||
|
||||
EMAC_TX_CLK,
|
||||
EMAC_RXD2,
|
||||
EMAC_TX_ER,
|
||||
EMAC_RX_CLK,
|
||||
EMAC_RX_ER,
|
||||
EMAC_RXD3,
|
||||
EMAC_RXD0,
|
||||
EMAC_RXD1,
|
||||
EMAC_RX_DV,
|
||||
|
||||
MTDI,
|
||||
MTCK,
|
||||
MTMS,
|
||||
}
|
||||
|
||||
/// Peripheral output signals for the GPIO mux
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub enum OutputSignal {
|
||||
SPICLK = 0,
|
||||
SPIQ = 1,
|
||||
SPID = 2,
|
||||
SPIHD = 3,
|
||||
SPIWP = 4,
|
||||
SPICS0 = 5,
|
||||
SPICS1 = 6,
|
||||
SPICS2 = 7,
|
||||
HSPICLK = 8,
|
||||
HSPIQ = 9,
|
||||
HSPID = 10,
|
||||
HSPICS0 = 11,
|
||||
HSPIHD = 12,
|
||||
HSPIWP = 13,
|
||||
U0TXD = 14,
|
||||
U0RTS = 15,
|
||||
U0DTR = 16,
|
||||
U1TXD = 17,
|
||||
U1RTS = 18,
|
||||
I2CM_SCL = 19,
|
||||
I2CM_SDA = 20,
|
||||
EXT2C_SCL = 21,
|
||||
EXT2C_SDA = 22,
|
||||
I2S0O_BCK = 23,
|
||||
I2S1O_BCK = 24,
|
||||
I2S0O_WS = 25,
|
||||
I2S1O_WS = 26,
|
||||
I2S0I_BCK = 27,
|
||||
I2S0I_WS = 28,
|
||||
I2CEXT0_SCL = 29,
|
||||
I2CEXT0_SDA = 30,
|
||||
SDIO_TOHOSTT = 31,
|
||||
PWM0_0A = 32,
|
||||
PWM0_0B = 33,
|
||||
PWM0_1A = 34,
|
||||
PWM0_1B = 35,
|
||||
PWM0_2A = 36,
|
||||
PWM0_2B = 37,
|
||||
GPIO_WLAN_ACTIVE = 40,
|
||||
BB_DIAG0 = 41,
|
||||
BB_DIAG1 = 42,
|
||||
BB_DIAG2 = 43,
|
||||
BB_DIAG3 = 44,
|
||||
BB_DIAG4 = 45,
|
||||
BB_DIAG5 = 46,
|
||||
BB_DIAG6 = 47,
|
||||
BB_DIAG7 = 48,
|
||||
BB_DIAG8 = 49,
|
||||
BB_DIAG9 = 50,
|
||||
BB_DIAG10 = 51,
|
||||
BB_DIAG11 = 52,
|
||||
BB_DIAG12 = 53,
|
||||
BB_DIAG13 = 54,
|
||||
BB_DIAG14 = 55,
|
||||
BB_DIAG15 = 56,
|
||||
BB_DIAG16 = 57,
|
||||
BB_DIAG17 = 58,
|
||||
BB_DIAG18 = 59,
|
||||
BB_DIAG19 = 60,
|
||||
HSPICS1 = 61,
|
||||
HSPICS2 = 62,
|
||||
VSPICLK = 63,
|
||||
VSPIQ = 64,
|
||||
VSPID = 65,
|
||||
VSPIHD = 66,
|
||||
VSPIWP = 67,
|
||||
VSPICS0 = 68,
|
||||
VSPICS1 = 69,
|
||||
VSPICS2 = 70,
|
||||
LEDC_HS_SIG_0 = 71,
|
||||
LEDC_HS_SIG_1 = 72,
|
||||
LEDC_HS_SIG_2 = 73,
|
||||
LEDC_HS_SIG_3 = 74,
|
||||
LEDC_HS_SIG_4 = 75,
|
||||
LEDC_HS_SIG_5 = 76,
|
||||
LEDC_HS_SIG_6 = 77,
|
||||
LEDC_HS_SIG_7 = 78,
|
||||
LEDC_LS_SIG_0 = 79,
|
||||
LEDC_LS_SIG_1 = 80,
|
||||
LEDC_LS_SIG_2 = 81,
|
||||
LEDC_LS_SIG_3 = 82,
|
||||
LEDC_LS_SIG_4 = 83,
|
||||
LEDC_LS_SIG_5 = 84,
|
||||
LEDC_LS_SIG_6 = 85,
|
||||
LEDC_LS_SIG_7 = 86,
|
||||
RMT_SIG_0 = 87,
|
||||
RMT_SIG_1 = 88,
|
||||
RMT_SIG_2 = 89,
|
||||
RMT_SIG_3 = 90,
|
||||
RMT_SIG_4 = 91,
|
||||
RMT_SIG_5 = 92,
|
||||
RMT_SIG_6 = 93,
|
||||
RMT_SIG_7 = 94,
|
||||
I2CEXT1_SCL = 95,
|
||||
I2CEXT1_SDA = 96,
|
||||
HOST_CCMD_OD_PULLUP_EN_N = 97,
|
||||
HOST_RST_N_1 = 98,
|
||||
HOST_RST_N_2 = 99,
|
||||
GPIO_SD0 = 100,
|
||||
GPIO_SD1 = 101,
|
||||
GPIO_SD2 = 102,
|
||||
GPIO_SD3 = 103,
|
||||
GPIO_SD4 = 104,
|
||||
GPIO_SD5 = 105,
|
||||
GPIO_SD6 = 106,
|
||||
GPIO_SD7 = 107,
|
||||
PWM1_0A = 108,
|
||||
PWM1_0B = 109,
|
||||
PWM1_1A = 110,
|
||||
PWM1_1B = 111,
|
||||
PWM1_2A = 112,
|
||||
PWM1_2B = 113,
|
||||
PWM2_1H = 114,
|
||||
PWM2_1L = 115,
|
||||
PWM2_2H = 116,
|
||||
PWM2_2L = 117,
|
||||
PWM2_3H = 118,
|
||||
PWM2_3L = 119,
|
||||
PWM2_4H = 120,
|
||||
PWM2_4L = 121,
|
||||
CAN_TX = 123,
|
||||
CAN_BUS_OFF_ON = 124,
|
||||
SPID4 = 128,
|
||||
SPID5 = 129,
|
||||
SPID6 = 130,
|
||||
SPID7 = 131,
|
||||
HSPID4 = 132,
|
||||
HSPID5 = 133,
|
||||
HSPID6 = 134,
|
||||
HSPID7 = 135,
|
||||
VSPID4 = 136,
|
||||
VSPID5 = 137,
|
||||
VSPID6 = 138,
|
||||
VSPID7 = 139,
|
||||
I2S0O_DATA_0 = 140,
|
||||
I2S0O_DATA_1 = 141,
|
||||
I2S0O_DATA_2 = 142,
|
||||
I2S0O_DATA_3 = 143,
|
||||
I2S0O_DATA_4 = 144,
|
||||
I2S0O_DATA_5 = 145,
|
||||
I2S0O_DATA_6 = 146,
|
||||
I2S0O_DATA_7 = 147,
|
||||
I2S0O_DATA_8 = 148,
|
||||
I2S0O_DATA_9 = 149,
|
||||
I2S0O_DATA_10 = 150,
|
||||
I2S0O_DATA_11 = 151,
|
||||
I2S0O_DATA_12 = 152,
|
||||
I2S0O_DATA_13 = 153,
|
||||
I2S0O_DATA_14 = 154,
|
||||
I2S0O_DATA_15 = 155,
|
||||
I2S0O_DATA_16 = 156,
|
||||
I2S0O_DATA_17 = 157,
|
||||
I2S0O_DATA_18 = 158,
|
||||
I2S0O_DATA_19 = 159,
|
||||
I2S0O_DATA_20 = 160,
|
||||
I2S0O_DATA_21 = 161,
|
||||
I2S0O_DATA_22 = 162,
|
||||
I2S0O_DATA_23 = 163,
|
||||
I2S1I_BCK = 164,
|
||||
I2S1I_WS = 165,
|
||||
I2S1O_DATA_0 = 166,
|
||||
I2S1O_DATA_1 = 167,
|
||||
I2S1O_DATA_2 = 168,
|
||||
I2S1O_DATA_3 = 169,
|
||||
I2S1O_DATA_4 = 170,
|
||||
I2S1O_DATA_5 = 171,
|
||||
I2S1O_DATA_6 = 172,
|
||||
I2S1O_DATA_7 = 173,
|
||||
I2S1O_DATA_8 = 174,
|
||||
I2S1O_DATA_9 = 175,
|
||||
I2S1O_DATA_10 = 176,
|
||||
I2S1O_DATA_11 = 177,
|
||||
I2S1O_DATA_12 = 178,
|
||||
I2S1O_DATA_13 = 179,
|
||||
I2S1O_DATA_14 = 180,
|
||||
I2S1O_DATA_15 = 181,
|
||||
I2S1O_DATA_16 = 182,
|
||||
I2S1O_DATA_17 = 183,
|
||||
I2S1O_DATA_18 = 184,
|
||||
I2S1O_DATA_19 = 185,
|
||||
I2S1O_DATA_20 = 186,
|
||||
I2S1O_DATA_21 = 187,
|
||||
I2S1O_DATA_22 = 188,
|
||||
I2S1O_DATA_23 = 189,
|
||||
PWM3_1H = 190,
|
||||
PWM3_1L = 191,
|
||||
PWM3_2H = 192,
|
||||
PWM3_2L = 193,
|
||||
PWM3_3H = 194,
|
||||
PWM3_3L = 195,
|
||||
PWM3_4H = 196,
|
||||
PWM3_4L = 197,
|
||||
U2TXD = 198,
|
||||
U2RTS = 199,
|
||||
EMAC_MDC = 200,
|
||||
EMAC_MDO = 201,
|
||||
EMAC_CRS = 202,
|
||||
EMAC_COL = 203,
|
||||
BT_AUDIO0RQ = 204,
|
||||
BT_AUDIO1RQ = 205,
|
||||
BT_AUDIO2RQ = 206,
|
||||
BLE_AUDIO0RQ = 207,
|
||||
BLE_AUDIO1RQ = 208,
|
||||
BLE_AUDIO2RQ = 209,
|
||||
PCMFSYNC = 210,
|
||||
PCMCLK = 211,
|
||||
PCMDOUT = 212,
|
||||
BLE_AUDIO_SYNC0_P = 213,
|
||||
BLE_AUDIO_SYNC1_P = 214,
|
||||
BLE_AUDIO_SYNC2_P = 215,
|
||||
ANT_SEL0 = 216,
|
||||
ANT_SEL1 = 217,
|
||||
ANT_SEL2 = 218,
|
||||
ANT_SEL3 = 219,
|
||||
ANT_SEL4 = 220,
|
||||
ANT_SEL5 = 221,
|
||||
ANT_SEL6 = 222,
|
||||
ANT_SEL7 = 223,
|
||||
SIGNAL_224 = 224,
|
||||
SIGNAL_225 = 225,
|
||||
SIGNAL_226 = 226,
|
||||
SIGNAL_227 = 227,
|
||||
SIGNAL_228 = 228,
|
||||
GPIO = 256,
|
||||
|
||||
CLK_OUT1 = 512,
|
||||
CLK_OUT2,
|
||||
CLK_OUT3,
|
||||
SD_CLK,
|
||||
SD_CMD,
|
||||
SD_DATA0,
|
||||
SD_DATA1,
|
||||
SD_DATA2,
|
||||
SD_DATA3,
|
||||
HS1_CLK,
|
||||
HS1_CMD,
|
||||
HS1_DATA0,
|
||||
HS1_DATA1,
|
||||
HS1_DATA2,
|
||||
HS1_DATA3,
|
||||
HS1_DATA4,
|
||||
HS1_DATA5,
|
||||
HS1_DATA6,
|
||||
HS1_DATA7,
|
||||
HS1_STROBE,
|
||||
HS2_CLK,
|
||||
HS2_CMD,
|
||||
HS2_DATA0,
|
||||
HS2_DATA1,
|
||||
HS2_DATA2,
|
||||
HS2_DATA3,
|
||||
|
||||
EMAC_TX_CLK,
|
||||
EMAC_TX_ER,
|
||||
EMAC_TXD3,
|
||||
EMAC_RX_ER,
|
||||
EMAC_TXD2,
|
||||
EMAC_CLK_OUT,
|
||||
EMAC_CLK_180,
|
||||
EMAC_TXD0,
|
||||
EMAC_TX_EN,
|
||||
EMAC_TXD1,
|
||||
|
||||
MTDO,
|
||||
}
|
||||
|
||||
gpio! {
|
||||
Function2,
|
||||
DualCore,
|
||||
Gpio0: (gpio0, 0, gpio0, IO, RTC, Bank0), (EMAC_TX_CLK: Function5), (CLK_OUT1: Function1),
|
||||
Gpio1: (gpio1, 1, gpio1, IO, 0, Bank0), (EMAC_RXD2: Function5), (U0TXD: Function1, CLK_OUT3: Function1),
|
||||
Gpio2: (gpio2, 2, gpio2, IO, RTC, Bank0), (HSPIWP: Function1, HS2_DATA0: Function3, SD_DATA0: Function4), (HS2_DATA0: Function3, SD_DATA0: Function4),
|
||||
Gpio3: (gpio3, 3, gpio3, IO, 0, Bank0), (U0RXD: Function0), (CLK_OUT2: Function1),
|
||||
Gpio4: (gpio4, 4, gpio4, IO, RTC, Bank0), (HSPIHD: Function1, HS2_DATA1: Function3, SD_DATA1: Function4, EMAC_TX_ER: Function5), (HS2_DATA1: Function3, SD_DATA1: Function4),
|
||||
Gpio5: (gpio5, 5, gpio5, IO, 0, Bank0), (VSPICS0: Function1, HS1_DATA6: Function3, EMAC_RX_CLK: Function5), (HS1_DATA6: Function3),
|
||||
Gpio6: (gpio6, 6, gpio6, IO, 0, Bank0), (U1CTS: Function4), (SD_CLK: Function0, SPICLK: Function1, HS1_CLK: Function3),
|
||||
Gpio7: (gpio7, 7, gpio7, IO, 0, Bank0), (SD_DATA0: Function0, SPIQ: Function1, HS1_DATA0: Function3), (SD_DATA0: Function0, SPIQ: Function1, HS1_DATA0: Function3, U2RTS: Function4),
|
||||
Gpio8: (gpio8, 8, gpio8, IO, 0, Bank0), (SD_DATA1: Function0, SPID: Function1, HS1_DATA1: Function3, U2CTS: Function4), (SD_DATA1: Function0, SPID: Function1, HS1_DATA1: Function3),
|
||||
Gpio9: (gpio9, 9, gpio9, IO, 0, Bank0), (SD_DATA2: Function0, SPIHD: Function1, HS1_DATA2: Function3, U1RXD: Function4), (SD_DATA2: Function0, SPIHD: Function1, HS1_DATA2: Function3),
|
||||
Gpio10: (gpio10, 10, gpio10, IO, 0, Bank0), (SD_DATA3: Function0, SPIWP: Function1, HS1_DATA3: Function3), (SD_DATA3: Function0, SPIWP: Function1, HS1_DATA3: Function3, U1TXD: Function4),
|
||||
Gpio11: (gpio11, 11, gpio11, IO, 0, Bank0), (SPICS0: Function1), (SD_CMD: Function0, SPICS0: Function1, HS1_CMD: Function3, U1RTS: Function4),
|
||||
Gpio12: (gpio12, 12, gpio12, IO, RTC, Bank0), (MTDI: Function0, HSPIQ: Function1, HS2_DATA2: Function3, SD_DATA2: Function4), (HSPIQ: Function1, HS2_DATA2: Function3, SD_DATA2: Function4, EMAC_TXD3: Function5),
|
||||
Gpio13: (gpio13, 13, gpio13, IO, RTC, Bank0), (MTCK: Function0, HSPID: Function1, HS2_DATA3: Function3, SD_DATA3: Function4), (HSPID: Function1, HS2_DATA3: Function3, SD_DATA3: Function4, EMAC_RX_ER: Function5),
|
||||
Gpio14: (gpio14, 14, gpio14, IO, RTC, Bank0), (MTMS: Function0, HSPICLK: Function1), (HSPICLK: Function1, HS2_CLK: Function3, SD_CLK: Function4, EMAC_TXD2: Function5),
|
||||
Gpio15: (gpio15, 15, gpio15, IO, RTC, Bank0), (HSPICS0: Function1, EMAC_RXD3: Function5), (MTDO: Function0, HSPICS0: Function1, HS2_CMD: Function3, SD_CMD: Function4),
|
||||
Gpio16: (gpio16, 16, gpio16, IO, 0, Bank0), (HS1_DATA4: Function3, U2RXD: Function4), (HS1_DATA4: Function3, EMAC_CLK_OUT: Function5),
|
||||
Gpio17: (gpio17, 17, gpio17, IO, 0, Bank0), (HS1_DATA5: Function3), (HS1_DATA5: Function3, U2TXD: Function4, EMAC_CLK_180: Function5),
|
||||
Gpio18: (gpio18, 18, gpio18, IO, 0, Bank0), (VSPICLK: Function1, HS1_DATA7: Function3), (VSPICLK: Function1, HS1_DATA7: Function3),
|
||||
Gpio19: (gpio19, 19, gpio19, IO, 0, Bank0), (VSPIQ: Function1, U0CTS: Function3), (VSPIQ: Function1, EMAC_TXD0: Function5),
|
||||
Gpio20: (gpio20, 20, gpio20, IO, 0, Bank0),
|
||||
Gpio21: (gpio21, 21, gpio21, IO, 0, Bank0), (VSPIHD: Function1), (VSPIHD: Function1, EMAC_TX_EN: Function5),
|
||||
|
||||
Gpio22: (gpio22, 22, gpio22, IO, 0, Bank0), (VSPIWP: Function1), (VSPIWP: Function1, U0RTS: Function3, EMAC_TXD1: Function5),
|
||||
Gpio23: (gpio23, 23, gpio23, IO, 0, Bank0), (VSPID: Function1), (VSPID: Function1, HS1_STROBE: Function3),
|
||||
Gpio24: (gpio24, 24, gpio24, IO, 0, Bank0),
|
||||
Gpio25: (gpio25, 25, gpio25, IO, 0, Bank0), (EMAC_RXD0: Function5), (),
|
||||
Gpio26: (gpio26, 26, gpio26, IO, 0, Bank0), (EMAC_RXD1: Function5), (),
|
||||
Gpio27: (gpio27, 27, gpio27, IO, 0, Bank0), (EMAC_RX_DV: Function5), (),
|
||||
|
||||
Gpio32: (gpio32, 32, gpio32, IO, 0, Bank1),
|
||||
Gpio33: (gpio33, 33, gpio33, IO, 0, Bank1),
|
||||
Gpio34: (gpio34, 34, gpio34, Input, 0, Bank1),
|
||||
Gpio35: (gpio35, 35, gpio35, Input, 0, Bank1),
|
||||
Gpio36: (gpio36, 36, gpio36, Input, 0, Bank1),
|
||||
Gpio37: (gpio37, 37, gpio37, Input, 0, Bank1),
|
||||
Gpio38: (gpio38, 38, gpio38, Input, 0, Bank1),
|
||||
Gpio39: (gpio39, 39, gpio39, Input, 0, Bank1),
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
#![no_std]
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{pac, prelude, Serial, Timer};
|
||||
pub use esp_hal_common::{gpio as hal_gpio, pac, prelude, Serial, Timer};
|
||||
|
||||
pub mod gpio;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {}
|
||||
|
@ -25,3 +25,6 @@ panic-halt = "0.2"
|
||||
[features]
|
||||
default = ["rt"]
|
||||
rt = ["riscv-rt"]
|
||||
|
||||
[package.metadata.espflash]
|
||||
format = "direct-boot"
|
||||
|
@ -14,6 +14,11 @@ fn main() {
|
||||
.write_all(include_bytes!("esp32c3-link.x"))
|
||||
.unwrap();
|
||||
|
||||
File::create(out.join("riscv-link.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("riscv-link.x"))
|
||||
.unwrap();
|
||||
|
||||
println!("cargo:rustc-link-search={}", out.display());
|
||||
|
||||
// Only re-run the build script when memory.x is changed,
|
||||
|
@ -1,2 +1,14 @@
|
||||
INCLUDE memory.x
|
||||
INCLUDE link.x
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.header : AT(0)
|
||||
{
|
||||
LONG(0xaedb041d)
|
||||
LONG(0xaedb041d)
|
||||
} > IROM
|
||||
}
|
||||
|
||||
_stext = ORIGIN(IROM) + 8;
|
||||
|
||||
INCLUDE riscv-link.x
|
||||
|
@ -1,15 +1,39 @@
|
||||
MEMORY
|
||||
{
|
||||
/*
|
||||
https://github.com/espressif/esptool/blob/master/esptool.py#L1919
|
||||
MEMORY_MAP = [[0x00000000, 0x00010000, "PADDING"],
|
||||
[0x3C000000, 0x3C800000, "DROM"],
|
||||
[0x3FC80000, 0x3FCE0000, "DRAM"],
|
||||
[0x3FC88000, 0x3FD00000, "BYTE_ACCESSIBLE"],
|
||||
[0x3FF00000, 0x3FF20000, "DROM_MASK"],
|
||||
[0x40000000, 0x40060000, "IROM_MASK"],
|
||||
[0x42000000, 0x42800000, "IROM"],
|
||||
[0x4037C000, 0x403E0000, "IRAM"],
|
||||
[0x50000000, 0x50002000, "RTC_IRAM"],
|
||||
[0x50000000, 0x50002000, "RTC_DRAM"],
|
||||
[0x600FE000, 0x60100000, "MEM_INTERNAL2"]]
|
||||
*/
|
||||
/* 400K of on soc RAM, 16K reserved for cache */
|
||||
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
|
||||
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
|
||||
/* 384K of on soc ROM */
|
||||
IROM : ORIGIN = 0x42000020, LENGTH = 0x60000
|
||||
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
|
||||
/* Instruction RAM */
|
||||
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
|
||||
/* Data RAM */
|
||||
DRAM : ORIGIN = 0x3FC80000, LENGTH = 0x50000
|
||||
|
||||
|
||||
/* External flash */
|
||||
/* Instruction ROM */
|
||||
IROM : ORIGIN = 0x42000000, LENGTH = 0x400000
|
||||
/* Data ROM */
|
||||
DROM : ORIGIN = 0x3C000000, LENGTH = 0x400000
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", IRAM);
|
||||
REGION_ALIAS("REGION_RODATA", IRAM);
|
||||
REGION_ALIAS("REGION_DATA", IRAM);
|
||||
REGION_ALIAS("REGION_BSS", IRAM);
|
||||
REGION_ALIAS("REGION_HEAP", IRAM);
|
||||
REGION_ALIAS("REGION_STACK", IRAM);
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", IROM);
|
||||
REGION_ALIAS("REGION_RODATA", DROM);
|
||||
|
||||
REGION_ALIAS("REGION_DATA", DRAM);
|
||||
REGION_ALIAS("REGION_BSS", DRAM);
|
||||
REGION_ALIAS("REGION_HEAP", DRAM);
|
||||
REGION_ALIAS("REGION_STACK", DRAM);
|
@ -1,7 +1,7 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32c3_hal::{pac, prelude::*, RtcCntl, Timer, IO};
|
||||
use esp32c3_hal::{gpio::IO, pac, prelude::*, RtcCntl, Timer};
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
@ -13,12 +13,14 @@ fn main() -> ! {
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
|
||||
let mut timer0 = Timer::new(peripherals.TIMG0);
|
||||
let mut timer1 = Timer::new(peripherals.TIMG1);
|
||||
|
||||
rtc_cntl.set_super_wdt_enable(false);
|
||||
rtc_cntl.set_wdt_enable(false);
|
||||
timer0.disable();
|
||||
timer1.disable();
|
||||
|
||||
let mut led = io.pins.gpio2.into_push_pull_output();
|
||||
let mut led = io.pins.gpio5.into_push_pull_output();
|
||||
led.set_high().unwrap();
|
||||
|
||||
timer0.start(10_000_000u64);
|
||||
|
173
esp32c3-hal/riscv-link.x
Normal file
173
esp32c3-hal/riscv-link.x
Normal file
@ -0,0 +1,173 @@
|
||||
PROVIDE(_stext = ORIGIN(REGION_TEXT));
|
||||
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
|
||||
PROVIDE(_max_hart_id = 0);
|
||||
PROVIDE(_hart_stack_size = 2K);
|
||||
PROVIDE(_heap_size = 0);
|
||||
|
||||
PROVIDE(UserSoft = DefaultHandler);
|
||||
PROVIDE(SupervisorSoft = DefaultHandler);
|
||||
PROVIDE(MachineSoft = DefaultHandler);
|
||||
PROVIDE(UserTimer = DefaultHandler);
|
||||
PROVIDE(SupervisorTimer = DefaultHandler);
|
||||
PROVIDE(MachineTimer = DefaultHandler);
|
||||
PROVIDE(UserExternal = DefaultHandler);
|
||||
PROVIDE(SupervisorExternal = DefaultHandler);
|
||||
PROVIDE(MachineExternal = DefaultHandler);
|
||||
|
||||
PROVIDE(DefaultHandler = DefaultInterruptHandler);
|
||||
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
|
||||
|
||||
/* # Pre-initialization function */
|
||||
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
|
||||
then the function this points to will be called before the RAM is initialized. */
|
||||
PROVIDE(__pre_init = default_pre_init);
|
||||
|
||||
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
|
||||
PROVIDE(_setup_interrupts = default_setup_interrupts);
|
||||
|
||||
/* # Multi-processing hook function
|
||||
fn _mp_hook() -> bool;
|
||||
|
||||
This function is called from all the harts and must return true only for one hart,
|
||||
which will perform memory initialization. For other harts it must return false
|
||||
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||
*/
|
||||
PROVIDE(_mp_hook = default_mp_hook);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text.dummy (NOLOAD) :
|
||||
{
|
||||
/* This section is intended to make _stext address work */
|
||||
. = ABSOLUTE(_stext);
|
||||
} > REGION_TEXT
|
||||
|
||||
.text _stext :
|
||||
{
|
||||
/* Put reset handler first in .text section so it ends up as the entry */
|
||||
/* point of the program. */
|
||||
KEEP(*(.init));
|
||||
KEEP(*(.init.rust));
|
||||
. = ALIGN(4);
|
||||
(*(.trap));
|
||||
(*(.trap.rust));
|
||||
|
||||
*(.text .text.*);
|
||||
_etext = .;
|
||||
} > REGION_TEXT
|
||||
|
||||
_text_size = _etext - _stext + 8;
|
||||
.rodata ORIGIN(DROM) + _text_size : AT(_text_size)
|
||||
{
|
||||
_srodata = .;
|
||||
*(.srodata .srodata.*);
|
||||
*(.rodata .rodata.*);
|
||||
|
||||
/* 4-byte align the end (VMA) of this section.
|
||||
This is required by LLD to ensure the LMA of the following .data
|
||||
section will have the correct alignment. */
|
||||
. = ALIGN(4);
|
||||
_erodata = .;
|
||||
} > REGION_RODATA
|
||||
|
||||
_rodata_size = _erodata - _srodata + 8;
|
||||
.data ORIGIN(DRAM) : AT(_text_size + _rodata_size)
|
||||
{
|
||||
_sidata = LOADADDR(.data);
|
||||
_sdata = .;
|
||||
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||
PROVIDE(__global_pointer$ = . + 0x800);
|
||||
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
||||
*(.data .data.*);
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > REGION_DATA
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_sbss = .;
|
||||
*(.sbss .sbss.* .bss .bss.*);
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
} > REGION_BSS
|
||||
|
||||
/* fictitious region that represents the memory available for the heap */
|
||||
.heap (NOLOAD) :
|
||||
{
|
||||
_sheap = .;
|
||||
. += _heap_size;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
} > REGION_HEAP
|
||||
|
||||
/* fictitious region that represents the memory available for the stack */
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
_estack = .;
|
||||
. = ABSOLUTE(_stack_start);
|
||||
_sstack = .;
|
||||
} > REGION_STACK
|
||||
|
||||
/* fake output .got section */
|
||||
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||
relocatable code in the input files and raise an error if relocatable code
|
||||
is found */
|
||||
.got (INFO) :
|
||||
{
|
||||
KEEP(*(.got .got.*));
|
||||
}
|
||||
|
||||
.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
|
||||
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
|
||||
}
|
||||
|
||||
/* Do not exceed this mark in the error messages above | */
|
||||
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
|
||||
|
||||
ASSERT(_stext % 4 == 0, "
|
||||
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
||||
|
||||
ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
|
||||
BUG(riscv-rt): .data is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sidata % 4 == 0, "
|
||||
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
|
||||
BUG(riscv-rt): .bss is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sheap % 4 == 0, "
|
||||
BUG(riscv-rt): start of .heap is not 4-byte aligned");
|
||||
|
||||
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
|
||||
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
|
||||
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
|
||||
|
||||
ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
|
||||
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
|
||||
Consider changing `_max_hart_id` or `_hart_stack_size`.");
|
||||
|
||||
ASSERT(SIZEOF(.got) == 0, "
|
||||
.got section detected in the input files. Dynamic relocations are not
|
||||
supported. If you are linking to C code compiled using the `gcc` crate
|
||||
then modify your build script to compile the C code _without_ the
|
||||
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
||||
details.");
|
||||
|
||||
/* Do not exceed this mark in the error messages above | */
|
165
esp32c3-hal/src/gpio.rs
Normal file
165
esp32c3-hal/src/gpio.rs
Normal file
@ -0,0 +1,165 @@
|
||||
use esp_hal_common::gpio::gpio;
|
||||
|
||||
use crate::hal_gpio::*;
|
||||
|
||||
type OutputSignalType = u8;
|
||||
const OUTPUT_SIGNAL_MAX: u8 = 128;
|
||||
const INPUT_SIGNAL_MAX: u8 = 100;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum InputSignal {
|
||||
SPIQ = 0,
|
||||
SPID = 1,
|
||||
SPIHD = 2,
|
||||
SPIWP = 3,
|
||||
U0RXD = 6,
|
||||
U0CTS = 7,
|
||||
U0DSR = 8,
|
||||
U1RXD = 9,
|
||||
U1CTS = 10,
|
||||
U1DSR = 11,
|
||||
I2S_MCLK = 12,
|
||||
I2SO_BCK = 13,
|
||||
I2SO_WS = 14,
|
||||
I2SI_SD = 15,
|
||||
I2SI_BCK = 16,
|
||||
I2SI_WS = 17,
|
||||
GPIO_BT_PRIORITY = 18,
|
||||
GPIO_BT_ACTIVE = 19,
|
||||
CPU_GPIO_0 = 28,
|
||||
CPU_GPIO_1 = 29,
|
||||
CPU_GPIO_2 = 30,
|
||||
CPU_GPIO_3 = 31,
|
||||
CPU_GPIO_4 = 32,
|
||||
CPU_GPIO_5 = 33,
|
||||
CPU_GPIO_6 = 34,
|
||||
CPU_GPIO_7 = 35,
|
||||
EXT_ADC_START = 45,
|
||||
RMT_SIG_0 = 51,
|
||||
RMT_SIG_1 = 52,
|
||||
I2CEXT0_SCL = 53,
|
||||
I2CEXT0_SDA = 54,
|
||||
FSPICLK = 63,
|
||||
FSPIQ = 64,
|
||||
FSPID = 65,
|
||||
FSPIHD = 66,
|
||||
FSPIWP = 67,
|
||||
FSPICS0 = 68,
|
||||
TWAI_RX = 74,
|
||||
SIG_FUNC_97 = 97,
|
||||
SIG_FUNC_98 = 98,
|
||||
SIG_FUNC_99 = 99,
|
||||
SIG_FUNC_100 = 100,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum OutputSignal {
|
||||
SPIQ = 0,
|
||||
SPID = 1,
|
||||
SPIHD = 2,
|
||||
SPIWP = 3,
|
||||
SPICLK_MUX = 4,
|
||||
SPICS0 = 5,
|
||||
U0TXD = 6,
|
||||
U0RTS = 7,
|
||||
U0DTR = 8,
|
||||
U1TXD = 9,
|
||||
U1RTS = 10,
|
||||
U1DTR = 11,
|
||||
I2S_MCLK = 12,
|
||||
I2SO_BCK = 13,
|
||||
I2SO_WS = 14,
|
||||
I2SI_SD = 15,
|
||||
I2SI_BCK = 16,
|
||||
I2SI_WS = 17,
|
||||
GPIO_WLAN_PRIO = 18,
|
||||
GPIO_WLAN_ACTIVE = 19,
|
||||
CPU_GPIO_0 = 28,
|
||||
CPU_GPIO_1 = 29,
|
||||
CPU_GPIO_2 = 30,
|
||||
CPU_GPIO_3 = 31,
|
||||
CPU_GPIO_4 = 32,
|
||||
CPU_GPIO_5 = 33,
|
||||
CPU_GPIO_6 = 34,
|
||||
CPU_GPIO_7 = 35,
|
||||
USB_JTAG_TCK = 36,
|
||||
USB_JTAG_TMS = 37,
|
||||
USB_JTAG_TDI = 38,
|
||||
USB_JTAG_TDO = 39,
|
||||
LEDC_LS_SIG0 = 45,
|
||||
LEDC_LS_SIG1 = 46,
|
||||
LEDC_LS_SIG2 = 47,
|
||||
LEDC_LS_SIG3 = 48,
|
||||
LEDC_LS_SIG4 = 49,
|
||||
LEDC_LS_SIG5 = 50,
|
||||
RMT_SIG_0 = 51,
|
||||
RMT_SIG_1 = 52,
|
||||
I2CEXT0_SCL = 53,
|
||||
I2CEXT0_SDA = 54,
|
||||
GPIO_SD0 = 55,
|
||||
GPIO_SD1 = 56,
|
||||
GPIO_SD2 = 57,
|
||||
GPIO_SD3 = 58,
|
||||
I2SO_SD1 = 59,
|
||||
FSPICLK_MUX = 63,
|
||||
FSPIQ = 64,
|
||||
FSPID = 65,
|
||||
FSPIHD = 66,
|
||||
FSPIWP = 67,
|
||||
FSPICS0 = 68,
|
||||
FSPICS1 = 69,
|
||||
FSPICS3 = 70,
|
||||
FSPICS2 = 71,
|
||||
FSPICS4 = 72,
|
||||
FSPICS5 = 73,
|
||||
TWAI_TX = 74,
|
||||
TWAI_BUS_OFF_ON = 75,
|
||||
TWAI_CLKOUT = 76,
|
||||
ANT_SEL0 = 89,
|
||||
ANT_SEL1 = 90,
|
||||
ANT_SEL2 = 91,
|
||||
ANT_SEL3 = 92,
|
||||
ANT_SEL4 = 93,
|
||||
ANT_SEL5 = 94,
|
||||
ANT_SEL6 = 95,
|
||||
ANT_SEL7 = 96,
|
||||
SIG_FUNC_97 = 97,
|
||||
SIG_FUNC_98 = 98,
|
||||
SIG_FUNC_99 = 99,
|
||||
SIG_FUNC_100 = 100,
|
||||
CLK_OUT1 = 123,
|
||||
CLK_OUT2 = 124,
|
||||
CLK_OUT3 = 125,
|
||||
SPICS1 = 126,
|
||||
USB_JTAG_TRST = 127,
|
||||
GPIO = 128,
|
||||
}
|
||||
|
||||
gpio! {
|
||||
Function1,
|
||||
SingleCore,
|
||||
Gpio0: (gpio0, 0, gpio[0], IO, RTC, Bank0),
|
||||
Gpio1: (gpio1, 1, gpio[1], IO, RTC, Bank0),
|
||||
Gpio2: (gpio2, 2, gpio[2], IO, RTC, Bank0), (FSPIQ: Function2), (FSPIQ: Function2),
|
||||
Gpio3: (gpio3, 3, gpio[3], IO, RTC, Bank0),
|
||||
Gpio4: (gpio4, 4, gpio[4], IO, RTC, Bank0), (FSPIHD: Function2), (USB_JTAG_TMS: Function0, FSPIHD: Function2),
|
||||
Gpio5: (gpio5, 5, gpio[5], IO, RTC, Bank0), (FSPIWP: Function2), (USB_JTAG_TDI: Function0, FSPIWP: Function2),
|
||||
Gpio6: (gpio6, 6, gpio[6], IO, 0, Bank0), (FSPICLK: Function2), (USB_JTAG_TCK: Function0, FSPICLK_MUX: Function2),
|
||||
Gpio7: (gpio7, 7, gpio[7], IO, 0, Bank0), (FSPID: Function2), (USB_JTAG_TDO: Function0, FSPID: Function2),
|
||||
Gpio8: (gpio8, 8, gpio[8], IO, 0, Bank0),
|
||||
Gpio9: (gpio9, 9, gpio[9], IO, 0, Bank0),
|
||||
Gpio10: (gpio10, 10, gpio[10], IO, 0, Bank0), (FSPICS0: Function2), (FSPICS0: Function2),
|
||||
Gpio11: (gpio11, 11, gpio[11], IO, 0, Bank0),
|
||||
Gpio12: (gpio12, 12, gpio[12], IO, 0, Bank0), (SPIHD: Function0), (SPIHD: Function0),
|
||||
Gpio13: (gpio13, 13, gpio[13], IO, 0, Bank0), (SPIWP: Function0), (SPIWP: Function0),
|
||||
Gpio14: (gpio14, 14, gpio[14], IO, 0, Bank0), (), (SPICS0: Function0),
|
||||
Gpio15: (gpio15, 15, gpio[15], IO, 0, Bank0), (), (SPICLK_MUX: Function0),
|
||||
Gpio16: (gpio16, 16, gpio[16], IO, 0, Bank0), (SPID: Function0), (SPID: Function0),
|
||||
Gpio17: (gpio17, 17, gpio[17], IO, 0, Bank0), (SPIQ: Function0), (SPIQ: Function0),
|
||||
Gpio18: (gpio18, 18, gpio[18], IO, 0, Bank0),
|
||||
Gpio19: (gpio19, 19, gpio[19], IO, 0, Bank0),
|
||||
Gpio20: (gpio20, 20, gpio[20], IO, 0, Bank0), (U0RXD: Function0), (),
|
||||
Gpio21: (gpio21, 21, gpio[21], IO, 0, Bank0), (), (U0TXD: Function0),
|
||||
}
|
@ -1,698 +0,0 @@
|
||||
use core::{convert::Infallible, marker::PhantomData};
|
||||
|
||||
use embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _};
|
||||
|
||||
use crate::pac::{GPIO, IO_MUX};
|
||||
|
||||
mod mux;
|
||||
pub use mux::*;
|
||||
|
||||
pub use crate::prelude::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct IO {
|
||||
io_mux: IO_MUX,
|
||||
pub pins: Pins,
|
||||
}
|
||||
|
||||
impl IO {
|
||||
pub fn new(gpio: GPIO, io_mux: IO_MUX) -> Self {
|
||||
let pins = gpio.split();
|
||||
let io = IO { io_mux, pins };
|
||||
|
||||
io
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GpioExt {
|
||||
type Parts;
|
||||
|
||||
fn split(self) -> Self::Parts;
|
||||
}
|
||||
|
||||
pub trait Pin {
|
||||
fn sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self;
|
||||
|
||||
fn listen(&mut self, event: Event) {
|
||||
self.listen_with_options(event, true, false, false)
|
||||
}
|
||||
|
||||
fn listen_with_options(
|
||||
&mut self,
|
||||
event: Event,
|
||||
int_enable: bool,
|
||||
nmi_enable: bool,
|
||||
wake_up_from_light_sleep: bool,
|
||||
);
|
||||
|
||||
fn unlisten(&mut self);
|
||||
|
||||
fn clear_interrupt(&mut self);
|
||||
|
||||
fn is_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn is_non_maskable_interrupt_set(&mut self) -> bool;
|
||||
|
||||
fn enable_hold(&mut self, on: bool);
|
||||
}
|
||||
|
||||
pub trait InputPin: Pin {
|
||||
fn set_to_input(&mut self) -> &mut Self;
|
||||
|
||||
fn enable_input(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn is_input_high(&mut self) -> bool;
|
||||
|
||||
fn connect_input_to_peripheral(&mut self, signal: InputSignal) -> &mut Self {
|
||||
self.connect_input_to_peripheral_with_options(signal, false, false)
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
signal: InputSignal,
|
||||
invert: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
) -> &mut Self;
|
||||
}
|
||||
|
||||
pub trait OutputPin: Pin {
|
||||
fn set_to_open_drain_output(&mut self) -> &mut Self;
|
||||
|
||||
fn set_to_push_pull_output(&mut self) -> &mut Self;
|
||||
|
||||
fn enable_output(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_output_high(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self;
|
||||
|
||||
fn enable_open_drain(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn connect_peripheral_to_output(&mut self, signal: OutputSignal) -> &mut Self {
|
||||
self.connect_peripheral_to_output_with_options(signal, false, false, false, false)
|
||||
}
|
||||
|
||||
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,
|
||||
) -> &mut Self;
|
||||
|
||||
fn internal_pull_up(&mut self, on: bool) -> &mut Self;
|
||||
|
||||
fn internal_pull_down(&mut self, on: bool) -> &mut Self;
|
||||
}
|
||||
|
||||
pub trait RTCPin {}
|
||||
|
||||
pub trait AnalogPin {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Event {
|
||||
RisingEdge = 1,
|
||||
FallingEdge = 2,
|
||||
AnyEdge = 3,
|
||||
LowLevel = 4,
|
||||
HighLevel = 5,
|
||||
}
|
||||
|
||||
pub struct Unknown {}
|
||||
|
||||
pub struct Input<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct RTCInput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct Floating;
|
||||
|
||||
pub struct PullDown;
|
||||
|
||||
pub struct PullUp;
|
||||
|
||||
pub struct Output<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct RTCOutput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct OpenDrain;
|
||||
|
||||
pub struct PushPull;
|
||||
|
||||
pub struct Analog;
|
||||
|
||||
pub struct Alternate<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
pub struct AF0;
|
||||
|
||||
pub struct AF1;
|
||||
|
||||
pub struct AF2;
|
||||
|
||||
pub enum DriveStrength {
|
||||
I5mA = 0,
|
||||
I10mA = 1,
|
||||
I20mA = 2,
|
||||
I40mA = 3,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum AlternateFunction {
|
||||
Function0 = 0,
|
||||
Function1 = 1,
|
||||
Function2 = 2,
|
||||
}
|
||||
|
||||
pub fn connect_low_to_peripheral(signal: InputSignal) {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sig_in_sel()
|
||||
.set_bit()
|
||||
.func_in_inv_sel()
|
||||
.bit(false)
|
||||
.func_in_sel()
|
||||
.bits(0x1f)
|
||||
});
|
||||
}
|
||||
|
||||
pub fn connect_high_to_peripheral(signal: InputSignal) {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sig_in_sel()
|
||||
.set_bit()
|
||||
.func_in_inv_sel()
|
||||
.bit(false)
|
||||
.func_in_sel()
|
||||
.bits(0x1e)
|
||||
});
|
||||
}
|
||||
|
||||
macro_rules! impl_output {
|
||||
(
|
||||
$pxi:ident:
|
||||
(
|
||||
$pin_num:expr, $bit:expr, $out_en_set:ident, $out_en_clear:ident,
|
||||
$out_set:ident, $out_clear:ident, $out_reg:ident
|
||||
)
|
||||
$( ,( $( $af_signal:ident: $af:ident ),* ))?
|
||||
) => {
|
||||
impl<MODE> embedded_hal::digital::v2::OutputPin for $pxi<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) };
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> embedded_hal::digital::v2::StatefulOutputPin for $pxi<Output<MODE>> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
unsafe { Ok((*GPIO::ptr()).$out_reg.read().bits() & (1 << $bit) != 0) }
|
||||
}
|
||||
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_set_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> embedded_hal::digital::v2::ToggleableOutputPin for $pxi<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
if self.is_set_high()? {
|
||||
Ok(self.set_low()?)
|
||||
} else {
|
||||
Ok(self.set_high()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $pxi<MODE> {
|
||||
pub fn into_pull_up_input(self) -> $pxi<Input<PullUp>> {
|
||||
self.init_input(false, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_pull_down_input(self) -> $pxi<Input<PullDown>> {
|
||||
self.init_input(true, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
fn init_output(&self, alternate: AlternateFunction, open_drain: bool) {
|
||||
let gpio = unsafe { &*GPIO::ptr() };
|
||||
let iomux = unsafe { &*IO_MUX::ptr() };
|
||||
|
||||
gpio.$out_en_set.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
gpio.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(open_drain));
|
||||
gpio.func_out_sel_cfg[$pin_num]
|
||||
.modify(|_, w| unsafe { w.func_out_sel().bits(OutputSignal::GPIO as u8) });
|
||||
|
||||
iomux.gpio[$pin_num].modify(|_, w| unsafe {
|
||||
w.mcu_sel()
|
||||
.bits(alternate as u8)
|
||||
.fun_ie()
|
||||
.clear_bit()
|
||||
.fun_wpd()
|
||||
.clear_bit()
|
||||
.fun_wpu()
|
||||
.clear_bit()
|
||||
.fun_drv()
|
||||
.bits(DriveStrength::I20mA as u8)
|
||||
.slp_sel()
|
||||
.clear_bit()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn into_push_pull_output(self) -> $pxi<Output<PushPull>> {
|
||||
self.init_output(AlternateFunction::Function1, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_open_drain_output(self) -> $pxi<Output<OpenDrain>> {
|
||||
self.init_output(AlternateFunction::Function1, true);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_alternate_1(self) -> $pxi<Alternate<AF1>> {
|
||||
self.init_output(AlternateFunction::Function1, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
pub fn into_alternate_2(self) -> $pxi<Alternate<AF2>> {
|
||||
self.init_output(AlternateFunction::Function2, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> OutputPin for $pxi<MODE> {
|
||||
fn set_to_open_drain_output(&mut self) -> &mut Self {
|
||||
self.init_output(AlternateFunction::Function1, true);
|
||||
self
|
||||
}
|
||||
|
||||
fn set_to_push_pull_output(&mut self) -> &mut Self {
|
||||
self.init_output(AlternateFunction::Function1, false);
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_output(&mut self, on: bool) -> &mut Self {
|
||||
if on {
|
||||
unsafe { &*GPIO::ptr() }
|
||||
.$out_en_set
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
} else {
|
||||
unsafe { &*GPIO::ptr() }
|
||||
.$out_en_clear
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_output_high(&mut self, high: bool) -> &mut Self {
|
||||
if high {
|
||||
unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) };
|
||||
} else {
|
||||
unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) };
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) });
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_open_drain(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*GPIO::ptr() }.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.mcu_wpu().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.mcu_wpd().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.mcu_oe().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
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,
|
||||
) -> &mut Self {
|
||||
let af = if force_via_gpio_mux {
|
||||
AlternateFunction::Function1
|
||||
} else {
|
||||
match signal {
|
||||
$( $(
|
||||
OutputSignal::$af_signal => AlternateFunction::$af,
|
||||
)* )?
|
||||
_ => AlternateFunction::Function1
|
||||
}
|
||||
};
|
||||
|
||||
if af == AlternateFunction::Function1 && signal as usize > 128 {
|
||||
panic!("Cannot connect this peripheral to GPIO");
|
||||
}
|
||||
|
||||
self.set_alternate_function(af);
|
||||
|
||||
let clipped_signal = if signal as usize <= 128 { signal as u8 } else { 128u8 };
|
||||
|
||||
unsafe { &*GPIO::ptr() }.func_out_sel_cfg[$pin_num].modify(|_, w| unsafe {
|
||||
w
|
||||
.func_out_sel().bits(clipped_signal)
|
||||
.func_out_inv_sel().bit(invert)
|
||||
.func_oen_sel().bit(enable_from_gpio)
|
||||
.func_oen_inv_sel().bit(invert_enable)
|
||||
});
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_up(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }.gpio[$pin_num].modify(|_, w| w.fun_wpu().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn internal_pull_down(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }.gpio[$pin_num].modify(|_, w| w.fun_wpd().bit(on));
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_input {
|
||||
($pxi:ident:
|
||||
($pin_num:expr, $bit:expr, $out_en_clear:ident, $reg:ident, $reader:ident,
|
||||
$status_w1tc:ident, $pcpu_int:ident, $pcpu_nmi:ident
|
||||
) $( ,( $( $af_signal:ident : $af:ident ),* ))?
|
||||
) => {
|
||||
impl<MODE> embedded_hal::digital::v2::InputPin for $pxi<Input<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(unsafe { &*GPIO::ptr() }.$reg.read().$reader().bits() & (1 << $bit) != 0)
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $pxi<MODE> {
|
||||
fn init_input(&self, pull_down: bool, pull_up: bool) {
|
||||
let gpio = unsafe { &*GPIO::ptr() };
|
||||
let iomux = unsafe { &*IO_MUX::ptr() };
|
||||
|
||||
|
||||
gpio.$out_en_clear
|
||||
.write(|w| unsafe { w.bits(1 << $bit) });
|
||||
|
||||
gpio.func_out_sel_cfg[$pin_num]
|
||||
.modify(|_, w| unsafe { w.func_out_sel().bits(OutputSignal::GPIO as u8) });
|
||||
|
||||
iomux.gpio[$pin_num].modify(|_, w| unsafe {
|
||||
w.mcu_sel()
|
||||
.bits(2)
|
||||
.fun_ie()
|
||||
.set_bit()
|
||||
.fun_wpd()
|
||||
.bit(pull_down)
|
||||
.fun_wpu()
|
||||
.bit(pull_up)
|
||||
.slp_sel()
|
||||
.clear_bit()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn into_floating_input(self) -> $pxi<Input<Floating>> {
|
||||
self.init_input(false, false);
|
||||
$pxi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> InputPin for $pxi<MODE> {
|
||||
fn set_to_input(&mut self) -> &mut Self {
|
||||
self.init_input(false, false);
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_input(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.fun_ie().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.mcu_ie().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn is_input_high(&mut self) -> bool {
|
||||
unsafe { &*GPIO::ptr() }.$reg.read().$reader().bits() & (1 << $bit) != 0
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
signal: InputSignal,
|
||||
invert: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
) -> &mut Self {
|
||||
|
||||
let af = if force_via_gpio_mux
|
||||
{
|
||||
AlternateFunction::Function1
|
||||
}
|
||||
else {
|
||||
match signal {
|
||||
$( $(
|
||||
InputSignal::$af_signal => AlternateFunction::$af,
|
||||
)* )?
|
||||
_ => AlternateFunction::Function1
|
||||
}
|
||||
};
|
||||
|
||||
if af == AlternateFunction::Function1 && signal as usize >= 128 {
|
||||
panic!("Cannot connect GPIO to this peripheral");
|
||||
}
|
||||
|
||||
self.set_alternate_function(af);
|
||||
|
||||
if (signal as usize) < 128 {
|
||||
unsafe { &*GPIO::ptr() }.func_in_sel_cfg[signal as usize].modify(|_, w| unsafe {
|
||||
w.sig_in_sel()
|
||||
.set_bit()
|
||||
.func_in_inv_sel()
|
||||
.bit(invert)
|
||||
.func_in_sel()
|
||||
.bits($pin_num)
|
||||
});
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> Pin for $pxi<MODE> {
|
||||
fn sleep_mode(&mut self, on: bool) -> &mut Self {
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| w.slp_sel().bit(on));
|
||||
self
|
||||
}
|
||||
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self {
|
||||
|
||||
unsafe { &*IO_MUX::ptr() }
|
||||
.gpio[$pin_num]
|
||||
.modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) });
|
||||
self
|
||||
}
|
||||
|
||||
fn listen_with_options(&mut self, event: Event,
|
||||
int_enable: bool, nmi_enable: bool,
|
||||
wake_up_from_light_sleep: bool
|
||||
) {
|
||||
if wake_up_from_light_sleep {
|
||||
match event {
|
||||
Event::AnyEdge | Event::RisingEdge | Event::FallingEdge => {
|
||||
panic!("Edge triggering is not supported for wake-up from light sleep");
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
(&*GPIO::ptr()).pin[$pin_num].modify(|_, w|
|
||||
w
|
||||
.pin_int_ena().bits(int_enable as u8 | ((nmi_enable as u8) << 1))
|
||||
.pin_int_type().bits(event as u8)
|
||||
.pin_wakeup_enable().bit(wake_up_from_light_sleep)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn unlisten(&mut self) {
|
||||
unsafe { (&*GPIO::ptr()).pin[$pin_num].modify(|_, w|
|
||||
w.pin_int_ena().bits(0).pin_int_type().bits(0).pin_int_ena().bits(0) );
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_interrupt(&mut self) {
|
||||
unsafe {&*GPIO::ptr()}.$status_w1tc.write(|w|
|
||||
unsafe {w.bits(1 << $bit)})
|
||||
}
|
||||
|
||||
fn is_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$pcpu_int.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn is_non_maskable_interrupt_set(&mut self) -> bool {
|
||||
(unsafe {&*GPIO::ptr()}.$pcpu_nmi.read().bits() & (1 << $bit)) !=0
|
||||
}
|
||||
|
||||
fn enable_hold(&mut self, _on: bool) {
|
||||
|
||||
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_pin_wrap {
|
||||
($pxi:ident, $pin_num:expr, IO
|
||||
$( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )?
|
||||
) => {
|
||||
impl_input!($pxi: ($pin_num, $pin_num % 32, enable_w1tc, in_, data_next,
|
||||
status_w1tc, pcpu_int, pcpu_nmi_int)
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_output_wrap {
|
||||
($pxi:ident, $pin_num:expr, IO
|
||||
$( ,( $( $af_output_signal:ident : $af_output:ident ),* ))?
|
||||
) => {
|
||||
impl_output!($pxi:
|
||||
($pin_num, $pin_num % 32, enable_w1ts, enable_w1tc, out_w1ts, out_w1tc, out)
|
||||
|
||||
$( ,( $( $af_output_signal: $af_output ),* ) )? );
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! gpio {
|
||||
( $($pxi:ident: ($pname:ident, $pin_num:literal,
|
||||
$type:ident, $rtc:tt ),
|
||||
$(
|
||||
( $( $af_input_signal:ident: $af_input:ident ),* ),
|
||||
$(
|
||||
( $( $af_output_signal:ident: $af_output:ident ),* ),
|
||||
)?
|
||||
)?
|
||||
)+ ) => {
|
||||
|
||||
impl GpioExt for GPIO {
|
||||
type Parts = Pins;
|
||||
|
||||
fn split(self) -> Self::Parts {
|
||||
Pins {
|
||||
$(
|
||||
$pname: $pxi { _mode: PhantomData },
|
||||
)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct Pins {
|
||||
$(
|
||||
|
||||
pub $pname: $pxi<Unknown>,
|
||||
)+
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(
|
||||
|
||||
pub struct $pxi<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
impl_pin_wrap!($pxi, $pin_num, $type
|
||||
$( ,( $( $af_input_signal: $af_input ),* ) )? );
|
||||
impl_output_wrap!($pxi, $pin_num, $type
|
||||
$($( ,( $( $af_output_signal: $af_output ),* ) )? )? );
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
gpio! {
|
||||
Gpio0: (gpio0, 0, IO, RTC),
|
||||
Gpio1: (gpio1, 1, IO, RTC),
|
||||
Gpio2: (gpio2, 2, IO, RTC), (FSPIQ: Function2), (FSPIQ: Function2),
|
||||
Gpio3: (gpio3, 3, IO, RTC),
|
||||
Gpio4: (gpio4, 4, IO, RTC), (FSPIHD: Function2), (USB_JTAG_TMS: Function0, FSPIHD: Function2),
|
||||
Gpio5: (gpio5, 5, IO, RTC), (FSPIWP: Function2), (USB_JTAG_TDI: Function0, FSPIWP: Function2),
|
||||
Gpio6: (gpio6, 6, IO, 0), (FSPICLK: Function2), (USB_JTAG_TCK: Function0, FSPICLK_MUX: Function2),
|
||||
Gpio7: (gpio7, 7, IO, 0), (FSPID: Function2), (USB_JTAG_TDO: Function0, FSPID: Function2),
|
||||
Gpio8: (gpio8, 8, IO, 0),
|
||||
Gpio9: (gpio9, 9, IO, 0),
|
||||
Gpio10: (gpio10, 10, IO, 0), (FSPICS0: Function2), (FSPICS0: Function2),
|
||||
Gpio11: (gpio11, 11, IO, 0),
|
||||
Gpio12: (gpio12, 12, IO, 0), (SPIHD: Function0), (SPIHD: Function0),
|
||||
Gpio13: (gpio13, 13, IO, 0), (SPIWP: Function0), (SPIWP: Function0),
|
||||
Gpio14: (gpio14, 14, IO, 0), (), (SPICS0: Function0),
|
||||
Gpio15: (gpio15, 15, IO, 0), (), (SPICLK_MUX: Function0),
|
||||
Gpio16: (gpio16, 16, IO, 0), (SPID: Function0), (SPID: Function0),
|
||||
Gpio17: (gpio17, 17, IO, 0), (SPIQ: Function0), (SPIQ: Function0),
|
||||
Gpio18: (gpio18, 18, IO, 0),
|
||||
Gpio19: (gpio19, 19, IO, 0),
|
||||
Gpio20: (gpio20, 20, IO, 0), (U0RXD: Function0), (),
|
||||
Gpio21: (gpio21, 21, IO, 0), (), (U0TXD: Function0),
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum InputSignal {
|
||||
SPIQ = 0,
|
||||
SPID = 1,
|
||||
SPIHD = 2,
|
||||
SPIWP = 3,
|
||||
U0RXD = 6,
|
||||
U0CTS = 7,
|
||||
U0DSR = 8,
|
||||
U1RXD = 9,
|
||||
U1CTS = 10,
|
||||
U1DSR = 11,
|
||||
I2S_MCLK = 12,
|
||||
I2SO_BCK = 13,
|
||||
I2SO_WS = 14,
|
||||
I2SI_SD = 15,
|
||||
I2SI_BCK = 16,
|
||||
I2SI_WS = 17,
|
||||
GPIO_BT_PRIORITY = 18,
|
||||
GPIO_BT_ACTIVE = 19,
|
||||
CPU_GPIO_0 = 28,
|
||||
CPU_GPIO_1 = 29,
|
||||
CPU_GPIO_2 = 30,
|
||||
CPU_GPIO_3 = 31,
|
||||
CPU_GPIO_4 = 32,
|
||||
CPU_GPIO_5 = 33,
|
||||
CPU_GPIO_6 = 34,
|
||||
CPU_GPIO_7 = 35,
|
||||
EXT_ADC_START = 45,
|
||||
RMT_SIG_0 = 51,
|
||||
RMT_SIG_1 = 52,
|
||||
I2CEXT0_SCL = 53,
|
||||
I2CEXT0_SDA = 54,
|
||||
FSPICLK = 63,
|
||||
FSPIQ = 64,
|
||||
FSPID = 65,
|
||||
FSPIHD = 66,
|
||||
FSPIWP = 67,
|
||||
FSPICS0 = 68,
|
||||
TWAI_RX = 74,
|
||||
SIG_FUNC_97 = 97,
|
||||
SIG_FUNC_98 = 98,
|
||||
SIG_FUNC_99 = 99,
|
||||
SIG_FUNC_100 = 100,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum OutputSignal {
|
||||
SPIQ = 0,
|
||||
SPID = 1,
|
||||
SPIHD = 2,
|
||||
SPIWP = 3,
|
||||
SPICLK_MUX = 4,
|
||||
SPICS0 = 5,
|
||||
U0TXD = 6,
|
||||
U0RTS = 7,
|
||||
U0DTR = 8,
|
||||
U1TXD = 9,
|
||||
U1RTS = 10,
|
||||
U1DTR = 11,
|
||||
I2S_MCLK = 12,
|
||||
I2SO_BCK = 13,
|
||||
I2SO_WS = 14,
|
||||
I2SI_SD = 15,
|
||||
I2SI_BCK = 16,
|
||||
I2SI_WS = 17,
|
||||
GPIO_WLAN_PRIO = 18,
|
||||
GPIO_WLAN_ACTIVE = 19,
|
||||
CPU_GPIO_0 = 28,
|
||||
CPU_GPIO_1 = 29,
|
||||
CPU_GPIO_2 = 30,
|
||||
CPU_GPIO_3 = 31,
|
||||
CPU_GPIO_4 = 32,
|
||||
CPU_GPIO_5 = 33,
|
||||
CPU_GPIO_6 = 34,
|
||||
CPU_GPIO_7 = 35,
|
||||
USB_JTAG_TCK = 36,
|
||||
USB_JTAG_TMS = 37,
|
||||
USB_JTAG_TDI = 38,
|
||||
USB_JTAG_TDO = 39,
|
||||
LEDC_LS_SIG0 = 45,
|
||||
LEDC_LS_SIG1 = 46,
|
||||
LEDC_LS_SIG2 = 47,
|
||||
LEDC_LS_SIG3 = 48,
|
||||
LEDC_LS_SIG4 = 49,
|
||||
LEDC_LS_SIG5 = 50,
|
||||
RMT_SIG_0 = 51,
|
||||
RMT_SIG_1 = 52,
|
||||
I2CEXT0_SCL = 53,
|
||||
I2CEXT0_SDA = 54,
|
||||
GPIO_SD0 = 55,
|
||||
GPIO_SD1 = 56,
|
||||
GPIO_SD2 = 57,
|
||||
GPIO_SD3 = 58,
|
||||
I2SO_SD1 = 59,
|
||||
FSPICLK_MUX = 63,
|
||||
FSPIQ = 64,
|
||||
FSPID = 65,
|
||||
FSPIHD = 66,
|
||||
FSPIWP = 67,
|
||||
FSPICS0 = 68,
|
||||
FSPICS1 = 69,
|
||||
FSPICS3 = 70,
|
||||
FSPICS2 = 71,
|
||||
FSPICS4 = 72,
|
||||
FSPICS5 = 73,
|
||||
TWAI_TX = 74,
|
||||
TWAI_BUS_OFF_ON = 75,
|
||||
TWAI_CLKOUT = 76,
|
||||
ANT_SEL0 = 89,
|
||||
ANT_SEL1 = 90,
|
||||
ANT_SEL2 = 91,
|
||||
ANT_SEL3 = 92,
|
||||
ANT_SEL4 = 93,
|
||||
ANT_SEL5 = 94,
|
||||
ANT_SEL6 = 95,
|
||||
ANT_SEL7 = 96,
|
||||
SIG_FUNC_97 = 97,
|
||||
SIG_FUNC_98 = 98,
|
||||
SIG_FUNC_99 = 99,
|
||||
SIG_FUNC_100 = 100,
|
||||
CLK_OUT1 = 123,
|
||||
CLK_OUT2 = 124,
|
||||
CLK_OUT3 = 125,
|
||||
SPICS1 = 126,
|
||||
USB_JTAG_TRST = 127,
|
||||
GPIO = 128,
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#![no_std]
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{pac, prelude, Serial, Timer};
|
||||
pub use esp_hal_common::{gpio as hal_gpio, pac, prelude, Serial, Timer};
|
||||
|
||||
pub mod gpio;
|
||||
pub mod rtc_cntl;
|
||||
|
||||
pub use gpio::IO;
|
||||
pub mod gpio;
|
||||
|
||||
pub use rtc_cntl::RtcCntl;
|
||||
|
@ -30,9 +30,13 @@ impl RtcCntl {
|
||||
pub fn set_wdt_enable(&self, enable: bool) {
|
||||
self.set_wdt_write_protection(false);
|
||||
|
||||
self.rtc_cntl
|
||||
.rtc_wdtconfig0
|
||||
.write(|w| w.wdt_en().bit(enable));
|
||||
if !enable {
|
||||
self.rtc_cntl.rtc_wdtconfig0.write(|w| unsafe { w.bits(0) });
|
||||
} else {
|
||||
self.rtc_cntl
|
||||
.rtc_wdtconfig0
|
||||
.write(|w| w.wdt_en().bit(enable));
|
||||
}
|
||||
|
||||
self.set_wdt_write_protection(true);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user