Skip to content

Commit

Permalink
Merge branch 'master' into feat/usb
Browse files Browse the repository at this point in the history
  • Loading branch information
andelf authored Aug 23, 2024
2 parents 1e55abe + 96358fa commit 75bae77
Show file tree
Hide file tree
Showing 24 changed files with 1,238 additions and 190 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ license = "MIT/Apache-2.0"

[dependencies]
# hpm-metapac = { path = "../hpm-data/build/hpm-metapac" }
hpm-metapac = { version = "0.0.3", git = "https://github.com/hpmicro-rs/hpm-metapac.git", tag = "hpm-data-6740ca6fd1ed6d9bb57944b42aa299761b974713" }
hpm-metapac = { version = "0.0.4", git = "https://github.com/hpmicro-rs/hpm-metapac.git", tag = "hpm-data-7b07750284fa2b5b3f6b09c72e70ea6dd4d2231d" }

riscv = { version = "0.11", features = ["critical-section-single-hart"] }
embedded-hal = { version = "1.0.0" }
Expand Down Expand Up @@ -47,7 +47,7 @@ mcan = { version = "0.5.0", optional = true }
# hpm-metapac = { path = "../hpm-data/build/hpm-metapac", default-features = false, features = [
# "metadata",
# ] }
hpm-metapac = { version = "0.0.3", git = "https://github.com/hpmicro-rs/hpm-metapac.git", tag = "hpm-data-6740ca6fd1ed6d9bb57944b42aa299761b974713", default-features = false, features = [
hpm-metapac = { version = "0.0.4", git = "https://github.com/hpmicro-rs/hpm-metapac.git", tag = "hpm-data-7b07750284fa2b5b3f6b09c72e70ea6dd4d2231d", default-features = false, features = [
"metadata",
] }
proc-macro2 = "1.0.85"
Expand Down
19 changes: 18 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,23 @@ use quote::{format_ident, quote};
// HPM_SOC_IP_FEATURE
fn get_ip_features(chip_family: &str) -> &[&str] {
match chip_family {
"hpm67" | "hpm64" => &["ADC16_HAS_TEMPSNS"],
"hpm67" => &[
"ADC16_HAS_TEMPSNS",
// custom
"DUAL_CORE",
],
"hpm64" => &[
"ADC16_HAS_TEMPSNS", // custom
"DUAL_CORE",
],
"hpm63" => &["PWM_COUNTER_RESET"],
"hpm62" => &[
"UART_RX_IDLE_DETECT",
"PWM_COUNTER_RESET",
"PWM_HRPWM",
// custom
"DMA_IDMISC",
"DUAL_CORE",
],
"hpm53" => &[
"GPTMR_MONITOR",
Expand Down Expand Up @@ -101,6 +110,7 @@ fn get_ip_features(chip_family: &str) -> &[&str] {
"DMA_V2_SWAP_TABLE",
"I2C_TRANSFER_COUNT_MAX_4096",
"ADC_BUSMODE_ENABLE_CTRL_SUPPORT",
"DUAL_CORE",
],
_ => panic!("Unknown chip family: {}", chip_family),
}
Expand Down Expand Up @@ -260,6 +270,13 @@ fn main() {
(("mcan", "RXD"), quote!(crate::mcan::RxPin)),
(("mcan", "TXD"), quote!(crate::mcan::TxPin)),
(("mcan", "STBY"), quote!(crate::mcan::StbyPin)),
// qei
(("qei", "A"), quote!(crate::qei::APin)),
(("qei", "B"), quote!(crate::qei::BPin)),
(("qei", "Z"), quote!(crate::qei::ZPin)),
(("qei", "F"), quote!(crate::qei::FaultPin)),
(("qei", "H0"), quote!(crate::qei::Home0Pin)),
(("qei", "H1"), quote!(crate::qei::Home1Pin)),
// FEMC
(("femc", "A00"), quote!(crate::femc::A00Pin)),
(("femc", "A01"), quote!(crate::femc::A01Pin)),
Expand Down
1 change: 0 additions & 1 deletion examples/hpm5300evk/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ runner = [
"probe-rs", "run",
"--chip", "HPM5361",
"--chip-description-path", "../../HPMicro.yaml",
# "--chip-description-path", "../../../flash-algo/target/definition.yaml",
"--protocol","jtag",
"--log-format", "{t} {L} {F}:{l} {s}",
]
Expand Down
216 changes: 216 additions & 0 deletions examples/hpm5300evk/src/bin/adc_periodic_wdog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#![no_main]
#![no_std]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
#![feature(abi_riscv_interrupt)]

use core::future::poll_fn;
use core::task::Poll;

use defmt::println;
use embassy_executor::Spawner;
use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::Timer;
use hal::gpio::{AnyPin, Flex, Pin};
use hal::pac;
use hpm_hal::interrupt::InterruptExt;
use hpm_hal::peripherals;
use {defmt_rtt as _, hpm_hal as hal};

const BOARD_NAME: &str = "HPM5300EVK";
const BANNER: &str = include_str!("../../../assets/BANNER");

static ADC_WDOG_WAKER: AtomicWaker = AtomicWaker::new();

#[allow(non_snake_case)]
#[no_mangle]
unsafe extern "riscv-interrupt-m" fn ADC0() {
let r = pac::ADC0;

r.int_sts().modify(|w| w.set_wdog(7, true)); // clear interrupt status
r.int_en().modify(|w| w.set_wdog(7, false)); // disable interrupt

ADC_WDOG_WAKER.wake();

hal::interrupt::ADC0.complete();
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
pub enum Button {
Up,
Down,
Left,
Right,
Select,
}

impl Button {
pub fn from_adc_value(value: u16) -> Option<Self> {
match value {
0..1024 => Some(Self::Left),
1024..4096 => Some(Self::Up),
4096..8192 => Some(Self::Down),
8192..15000 => Some(Self::Right),
15000..32768 => Some(Self::Select),
_ => None,
}
}
}

pub struct AdcButton {
adc: hal::adc::Adc<'static, peripherals::ADC0>,
pin: peripherals::PB15,
}

impl AdcButton {
pub fn new(periph: peripherals::ADC0, pin: peripherals::PB15) -> Self {
let mut adc_config = hal::adc::Config::default();
adc_config.clock_divider = hal::adc::ClockDivider::DIV4;
let adc = hal::adc::Adc::new(periph, adc_config);

let mut periodic_config = hal::adc::PeriodicConfig::default();
periodic_config.prescale = 10;

let mut this = Self { adc, pin };
this.adc.configure_periodic(&mut this.pin, periodic_config);

// BUG: uninited periodic reading is always 0, and no way to know if it's ready
while this.read_raw() == 0 {}

unsafe {
hal::interrupt::ADC0.enable();
}

this
}

pub fn read_raw(&mut self) -> u16 {
self.adc.periodic_read(&mut self.pin)
}

pub fn read(&mut self) -> Option<Button> {
let val = self.adc.periodic_read(&mut self.pin);
Button::from_adc_value(val)
}

pub async fn wait_for_button_release(&mut self) {
if self.read().is_none() {
return;
}

let mut period_config = hal::adc::PeriodicConfig::default();
period_config.high_threshold = Some(50000); // released
period_config.prescale = 10;
self.adc.configure_periodic(&mut self.pin, period_config);

let r = pac::ADC0;

r.int_sts().modify(|w| w.set_wdog(7, true)); // clear interrupt status
r.int_en().modify(|w| w.set_wdog(7, true));

poll_fn(|cx| {
ADC_WDOG_WAKER.register(cx.waker());

// irq is cleared by the interrupt handler
if !r.int_en().read().wdog(7) {
return Poll::Ready(());
} else {
Poll::Pending
}
})
.await;
}

pub async fn wait_for_button_press(&mut self) -> Button {
if let Some(button) = self.read() {
return button;
}

let mut period_config = hal::adc::PeriodicConfig::default();
period_config.low_threshold = Some(32768); // anything pressed
period_config.prescale = 10;

self.adc.configure_periodic(&mut self.pin, period_config);

let r = pac::ADC0;

loop {
r.int_sts().modify(|w| w.set_wdog(7, true)); // clear interrupt status
r.int_en().modify(|w| w.set_wdog(7, true));

poll_fn(|cx| {
ADC_WDOG_WAKER.register(cx.waker());

// irq is cleared by the interrupt handler
if !r.int_en().read().wdog(7) {
return Poll::Ready(());
} else {
Poll::Pending
}
})
.await;

Timer::after_millis(10).await; // wait for stable value
if let Some(button) = self.read() {
return button;
}
}
}

pub async fn wait_for_button_click(&mut self) -> Button {
let btn = self.wait_for_button_press().await;
self.wait_for_button_release().await;

btn
}
}

#[embassy_executor::main(entry = "hpm_hal::entry")]
async fn main(spawner: Spawner) -> ! {
let p = hal::init(Default::default());

println!("\n{}", BANNER);
println!("==============================");
println!(" {} clock summary", BOARD_NAME);
println!("==============================");
println!("cpu0:\t{}Hz", hal::sysctl::clocks().cpu0.0);
println!("ahb:\t{}Hz", hal::sysctl::clocks().ahb.0);
println!("==============================");

spawner.spawn(blink(p.PA23.degrade())).unwrap();
spawner.spawn(blink(p.PA10.degrade())).unwrap();

println!("begin init adc");

let mut adc_btn = AdcButton::new(p.ADC0, p.PB15);

loop {
let btn = adc_btn.wait_for_button_press().await;

println!("Button pressed: {}", btn);

adc_btn.wait_for_button_release().await;

println!("Button released");
}
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
//let _ = println!("\n\n\n{}", info);

loop {}
}

#[embassy_executor::task(pool_size = 2)]
async fn blink(pin: AnyPin) {
let mut led = Flex::new(pin);
led.set_as_output(Default::default());
led.set_high();

loop {
led.toggle();

Timer::after_millis(500).await;
}
}
Loading

0 comments on commit 75bae77

Please sign in to comment.