not quite done, but getting there

This commit is contained in:
2025-07-08 22:19:18 +02:00
parent c5a734210a
commit d2cc61f28f
6 changed files with 311 additions and 71 deletions

View File

@@ -4,7 +4,7 @@
use core::{mem::MaybeUninit, panic::PanicInfo};
use cortex_ar::asm::nop;
use embassy_executor::Spawner;
use embassy_time::{Duration, Ticker};
use embassy_time::{Duration, Ticker, WithTimeout};
use embedded_hal::digital::StatefulOutputPin;
use embedded_io::Write;
use log::{error, info};
@@ -14,7 +14,7 @@ use zynq7000_hal::{
BootMode,
clocks::Clocks,
configure_level_shifter,
eth::{AlignedBuffer, EthernetConfig, EthernetLowLevel},
eth::{AlignedBuffer, ClkConfigCollection, EthernetConfig, EthernetLowLevel},
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
gpio::{GpioPins, Output, PinState},
gtc::Gtc,
@@ -59,12 +59,21 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
}
#[embassy_executor::task]
async fn net_task(
async fn embassy_net_task(
mut runner: embassy_net::Runner<'static, zynq7000_hal::eth::embassy_net::Driver>,
) -> ! {
runner.run().await
}
#[embassy_executor::task]
async fn led_task(mut mio_led: Output) -> ! {
let mut ticker = Ticker::every(Duration::from_millis(200));
loop {
mio_led.toggle().unwrap();
ticker.next().await; // Wait for the next cycle of the ticker
}
}
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(spawner: Spawner) -> ! {
@@ -136,17 +145,15 @@ async fn main(spawner: Spawner) -> ! {
// Unwrap okay, this is a valid peripheral.
let eth_ll = EthernetLowLevel::new(dp.eth_0).unwrap();
let (clk_config, clk_error) = zynq7000_hal::eth::ClkConfig::calculate_for_rgmii(
clocks.io_clocks().ref_clk(),
zynq7000_hal::eth::Speed::Mbps1000,
);
let (clk_collection, clk_errors) =
ClkConfigCollection::calculate_for_rgmii_and_io_clock(clocks.io_clocks());
info!(
"Calculated RGMII clock configuration: {:?}, error: {}",
clk_config, clk_error
"Calculated RGMII clock configuration: {:?}, errors (missmatch from ideal rate in hertz): {:?}",
clk_collection, clk_errors
);
// Unwrap okay, we use a standard clock config, and the clock config should never fail.
let eth_cfg = EthernetConfig::new(
clk_config,
clk_collection.cfg_100_mbps,
zynq7000_hal::eth::calculate_mdc_clk_div(clocks.arm_clocks()).unwrap(),
MAC_ADDRESS,
);
@@ -208,19 +215,13 @@ async fn main(spawner: Spawner) -> ! {
RESOURCES.init(embassy_net::StackResources::new()),
rng.next_u64(),
);
spawner.spawn(net_task(runner)).unwrap();
stack.wait_config_up().await;
let network_config = stack.config_v4();
info!(
"Network configuration is up: DHCP config: {:?}!",
network_config
);
let mut ticker = Ticker::every(Duration::from_millis(200));
spawner.spawn(embassy_net_task(runner)).unwrap();
let mut mio_led = Output::new_for_mio(gpio_pins.mio.mio7, PinState::Low);
let mut emio_leds: [Output; 8] = [
spawner.spawn(led_task(mio_led)).unwrap();
let mut _emio_leds: [Output; 8] = [
Output::new_for_emio(gpio_pins.emio.take(0).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(1).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(2).unwrap(), PinState::Low),
@@ -231,15 +232,34 @@ async fn main(spawner: Spawner) -> ! {
Output::new_for_emio(gpio_pins.emio.take(7).unwrap(), PinState::Low),
];
loop {
mio_led.toggle().unwrap();
// Create a wave pattern for emio_leds
for led in emio_leds.iter_mut() {
led.toggle().unwrap();
ticker.next().await; // Wait for the next ticker for each toggle
if !stack.is_link_up() {
loop {
let config_up_fut = stack.wait_config_up();
let status = phy.read_copper_status();
// TODO: How is this related to the ethernet stack link state? Should we only
// update the link state to up once auto-negotiation is complete and the clock
// was configured correctly?
if status.auto_negotiation_complete() {
let extended_status = phy.read_copper_specific_status_register_1();
eth.configure_clock_and_speed_duplex(
// If this has the reserved bits, what do we even do? For this example app,
// I am going to assume this never happens..
extended_status.speed().as_zynq7000_eth_speed().unwrap(),
extended_status.duplex().as_zynq7000_eth_duplex(),
&clk_collection,
);
eth.set_tx_rx_enable(true, true);
}
match config_up_fut.with_timeout(Duration::from_millis(100)).await {
Ok(_) => break,
Err(e) => todo!(),
}
}
}
ticker.next().await; // Wait for the next cycle of the ticker
let network_config = stack.config_v4();
info!("Network configuration is up: DHCP config: {network_config:?}!",);
//mio_led.toggle().unwrap();
//ticker.next().await; // Wait for the next cycle of the ticker
}
}