libboard_zynq: add async delays, rm CountDown trait

This commit is contained in:
2025-06-25 13:45:02 +08:00
parent 6bb075c671
commit db78365bcc
6 changed files with 35 additions and 86 deletions

1
Cargo.lock generated
View File

@@ -86,6 +86,7 @@ version = "0.0.0"
dependencies = [
"bit_field",
"embedded-hal",
"libasync",
"libcortex_a9",
"libregister",
"log",

View File

@@ -18,6 +18,6 @@ log = "0.4"
embedded-hal = "0.2"
libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" }
libboard_zynq = { path = "../libboard_zynq" }
libboard_zynq = { path = "../libboard_zynq", features = ["async"] }
libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler", "dummy_fiq_handler"]}
libasync = { path = "../libasync" }

View File

@@ -9,8 +9,7 @@ use alloc::collections::BTreeMap;
use core::{arch::naked_asm,
sync::atomic::{AtomicBool, Ordering}};
use libasync::{delay,
smoltcp::{Sockets, TcpStream},
use libasync::{smoltcp::{Sockets, TcpStream},
task};
#[cfg(feature = "target_zc706")]
use libboard_zynq::print;
@@ -21,8 +20,7 @@ use libboard_zynq::{self as zynq,
smoltcp::{iface::{EthernetInterfaceBuilder, NeighborCache, Routes},
time::{Duration, Instant},
wire::{EthernetAddress, IpAddress, IpCidr}},
stdio,
timer::{self, Milliseconds, Timer}};
stdio, timer};
use libcortex_a9::{asm, interrupt_handler,
l2c::enable_l2_cache,
mutex::Mutex,
@@ -187,14 +185,13 @@ pub fn main_core0() {
#[cfg(feature = "target_kasli_soc")]
{
let mut err_cdwn = Timer::millis();
let mut err_state = true;
let mut led = zynq::error_led::ErrorLED::error_led();
task::spawn(async move {
loop {
led.toggle(err_state);
err_state = !err_state;
delay(&mut err_cdwn, Milliseconds(1000)).await;
timer::async_delay_ms(1000).await;
}
});
}
@@ -265,10 +262,9 @@ pub fn main_core0() {
}
});
let mut countdown = Timer::millis();
task::spawn(async move {
loop {
delay(&mut countdown, Milliseconds(1000)).await;
timer::async_delay_ms(1000).await;
let timestamp = timer::get_us();
let seconds = timestamp / 1_000_000;

View File

@@ -12,6 +12,7 @@ target_ebaz4205 = []
target_redpitaya = []
target_kasli_soc = []
ipv6 = [ "smoltcp/proto-ipv6" ]
async = [ "dep:libasync" ]
[dependencies]
volatile-register = "0.2"
@@ -22,6 +23,7 @@ void = { version = "1", default-features = false }
log = "0.4"
libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" }
libasync = { path = "../libasync", optional = true }
[dependencies.smoltcp]
version = "0.7"

View File

@@ -1,17 +1,16 @@
use embedded_hal::timer::CountDown;
use libcortex_a9::cache;
use libregister::*;
use log::{debug, trace};
use super::timer::{self, Milliseconds};
use crate::{slcr, timer::Timer};
use super::timer;
use crate::slcr;
mod regs;
pub struct DevC {
regs: &'static mut regs::RegisterBlock,
enabled: bool,
timeout_ms: Milliseconds,
timeout_ms: u64,
}
/// DMA transfer type for PCAP
@@ -63,12 +62,12 @@ impl core::fmt::Display for DevcError {
impl DevC {
/// Create a new DevC peripheral handle with default timeout = 500ms.
pub fn new() -> Self {
Self::new_timeout(Milliseconds(500))
Self::new_timeout(500)
}
/// Create a new DevC peripheral handle.
/// `timeout_ms`: timeout for operations like initialize and DMA transfer.
pub fn new_timeout(timeout_ms: Milliseconds) -> Self {
pub fn new_timeout(timeout_ms: u64) -> Self {
DevC {
regs: regs::RegisterBlock::devc(),
enabled: false,
@@ -109,9 +108,8 @@ impl DevC {
/// Wait on a certain condition with hardcoded timeout.
fn wait_condition<F: Fn(&mut Self) -> bool>(&mut self, fun: F, err: DevcError) -> Result<(), DevcError> {
let mut timeout = Timer::millis();
timeout.start(self.timeout_ms);
while let Err(nb::Error::WouldBlock) = timeout.wait() {
let max_time = timer::get_ms() + self.timeout_ms;
while timer::get_ms() < max_time {
if fun(self) {
return Ok(());
} else if self.has_error() {

View File

@@ -1,69 +1,7 @@
use embedded_hal::timer::CountDown;
use libregister::{RegisterR, RegisterW};
use void::Void;
use crate::{clocks::Clocks, mpcore};
#[derive(Clone)]
pub struct Timer<T> {
pub timeout: T,
}
impl Timer<Milliseconds> {
pub fn millis() -> Self {
Self {
timeout: Milliseconds(0),
}
}
}
impl Timer<Microseconds> {
pub fn micros() -> Self {
Self {
timeout: Microseconds(0),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Milliseconds(pub u64);
#[derive(Debug, Clone, Copy)]
pub struct Microseconds(pub u64);
/// embedded-hal async API
impl embedded_hal::timer::CountDown for Timer<Milliseconds> {
type Time = Milliseconds;
fn start<T: Into<Self::Time>>(&mut self, count: T) {
self.timeout = Milliseconds(get_ms() + count.into().0);
}
fn wait(&mut self) -> nb::Result<(), Void> {
if get_ms() <= self.timeout.0 {
Err(nb::Error::WouldBlock)
} else {
Ok(())
}
}
}
impl embedded_hal::timer::CountDown for Timer<Microseconds> {
type Time = Microseconds;
fn start<T: Into<Self::Time>>(&mut self, count: T) {
self.timeout = Microseconds(get_us() + count.into().0);
}
fn wait(&mut self) -> nb::Result<(), Void> {
if get_us() <= self.timeout.0 {
Err(nb::Error::WouldBlock)
} else {
Ok(())
}
}
}
pub fn start() {
let regs = mpcore::RegisterBlock::mpcore();
// Disable
@@ -123,13 +61,27 @@ pub fn get_us() -> u64 {
}
pub fn delay_ms(ms: u64) {
let mut timer = Timer::millis();
timer.start(Milliseconds(ms));
nb::block!(timer.wait()).unwrap();
let max_time = get_ms() + ms;
while get_ms() < max_time {}
}
pub fn delay_us(us: u64) {
let mut timer = Timer::micros();
timer.start(Microseconds(us));
nb::block!(timer.wait()).unwrap();
let max_time = get_us() + us;
while get_us() < max_time {}
}
#[cfg(feature = "async")]
pub async fn async_delay_ms(ms: u64) {
let max_time = get_ms() + ms;
while get_ms() < max_time {
libasync::task::r#yield().await;
}
}
#[cfg(feature = "async")]
pub async fn async_delay_us(us: u64) {
let max_time = get_us() + us;
while get_us() < max_time {
libasync::task::r#yield().await;
}
}