mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-04 07:34:10 +00:00 
			
		
		
		
	improved project structure and hardware init
This commit is contained in:
		
							parent
							
								
									2e6094ea11
								
							
						
					
					
						commit
						c91d2f070f
					
				
							
								
								
									
										61
									
								
								src/bin/init/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/bin/init/mod.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use esp_hal::peripherals::{GPIO1, GPIO2, UART1};
 | 
			
		||||
use esp_hal::{
 | 
			
		||||
    Async,
 | 
			
		||||
    clock::CpuClock,
 | 
			
		||||
    timer::{systimer::SystemTimer, timg::TimerGroup},
 | 
			
		||||
    uart::Uart,
 | 
			
		||||
};
 | 
			
		||||
use esp_println::logger::init_logger;
 | 
			
		||||
use log::error;
 | 
			
		||||
 | 
			
		||||
mod network;
 | 
			
		||||
mod wifi;
 | 
			
		||||
 | 
			
		||||
#[panic_handler]
 | 
			
		||||
fn panic(_: &core::panic::PanicInfo) -> ! {
 | 
			
		||||
    loop {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_bootloader_esp_idf::esp_app_desc!();
 | 
			
		||||
 | 
			
		||||
pub async fn hardware_init(spawner: &mut Spawner) -> (Uart<'static, Async>, Stack<'static>) {
 | 
			
		||||
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
 | 
			
		||||
    let peripherals = esp_hal::init(config);
 | 
			
		||||
 | 
			
		||||
    esp_alloc::heap_allocator!(size: 72 * 1024);
 | 
			
		||||
 | 
			
		||||
    let timer0 = SystemTimer::new(peripherals.SYSTIMER);
 | 
			
		||||
    esp_hal_embassy::init(timer0.alarm0);
 | 
			
		||||
 | 
			
		||||
    init_logger(log::LevelFilter::Debug);
 | 
			
		||||
 | 
			
		||||
    let timer1 = TimerGroup::new(peripherals.TIMG0);
 | 
			
		||||
    let mut rng = esp_hal::rng::Rng::new(peripherals.RNG);
 | 
			
		||||
    let network_seed = (rng.random() as u64) << 32 | rng.random() as u64;
 | 
			
		||||
 | 
			
		||||
    wifi::set_antenna_mode(peripherals.GPIO3, peripherals.GPIO14).await;
 | 
			
		||||
    let interfaces = wifi::setup_wifi(timer1.timer0, rng, peripherals.WIFI, spawner);
 | 
			
		||||
    let stack = network::setup_network(network_seed, interfaces.ap, spawner);
 | 
			
		||||
 | 
			
		||||
    let uart_devie = setup_uart(peripherals.UART1, peripherals.GPIO1, peripherals.GPIO2);
 | 
			
		||||
 | 
			
		||||
    (uart_devie, stack)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn setup_uart(
 | 
			
		||||
    uart1: UART1<'static>,
 | 
			
		||||
    gpio1: GPIO1<'static>,
 | 
			
		||||
    gpio2: GPIO2<'static>,
 | 
			
		||||
) -> Uart<'static, Async> {
 | 
			
		||||
    let uard_device = Uart::new(uart1, esp_hal::uart::Config::default().with_baudrate(9600));
 | 
			
		||||
 | 
			
		||||
    match uard_device {
 | 
			
		||||
        Ok(block) => block.with_rx(gpio1).with_tx(gpio2).into_async(),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("Failed to initialize UART: {e}");
 | 
			
		||||
            panic!();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/bin/init/network.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/bin/init/network.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
use core::{net::Ipv4Addr, str::FromStr};
 | 
			
		||||
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_wifi::wifi::WifiDevice;
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub fn setup_network<'a>(seed: u64, wifi: WifiDevice<'static>, spawner: &mut Spawner) -> Stack<'a> {
 | 
			
		||||
    let gw_ip_addr_str = "192.168.2.1";
 | 
			
		||||
    let gw_ip_addr = Ipv4Addr::from_str(gw_ip_addr_str).expect("failed to parse gateway ip");
 | 
			
		||||
    let config = embassy_net::Config::ipv4_static(StaticConfigV4 {
 | 
			
		||||
        address: Ipv4Cidr::new(gw_ip_addr, 24),
 | 
			
		||||
        gateway: Some(gw_ip_addr),
 | 
			
		||||
        dns_servers: Default::default(),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let (stack, runner) =
 | 
			
		||||
        embassy_net::new(wifi, config, make_static!(StackResources::<3>::new()), seed);
 | 
			
		||||
 | 
			
		||||
    spawner.must_spawn(net_task(runner));
 | 
			
		||||
    spawner.must_spawn(run_dhcp(stack, gw_ip_addr_str));
 | 
			
		||||
 | 
			
		||||
    stack
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
 | 
			
		||||
    use core::net::{Ipv4Addr, SocketAddrV4};
 | 
			
		||||
 | 
			
		||||
    use edge_dhcp::{
 | 
			
		||||
        io::{self, DEFAULT_SERVER_PORT},
 | 
			
		||||
        server::{Server, ServerOptions},
 | 
			
		||||
    };
 | 
			
		||||
    use edge_nal::UdpBind;
 | 
			
		||||
    use edge_nal_embassy::{Udp, UdpBuffers};
 | 
			
		||||
 | 
			
		||||
    let ip = Ipv4Addr::from_str(gw_ip_addr).expect("dhcp task failed to parse gw ip");
 | 
			
		||||
 | 
			
		||||
    let mut buf = [0u8; 1500];
 | 
			
		||||
 | 
			
		||||
    let mut gw_buf = [Ipv4Addr::UNSPECIFIED];
 | 
			
		||||
 | 
			
		||||
    let buffers = UdpBuffers::<3, 1024, 1024, 10>::new();
 | 
			
		||||
    let unbound_socket = Udp::new(stack, &buffers);
 | 
			
		||||
    let mut bound_socket = unbound_socket
 | 
			
		||||
        .bind(core::net::SocketAddr::V4(SocketAddrV4::new(
 | 
			
		||||
            Ipv4Addr::UNSPECIFIED,
 | 
			
		||||
            DEFAULT_SERVER_PORT,
 | 
			
		||||
        )))
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        _ = io::server::run(
 | 
			
		||||
            &mut Server::<_, 64>::new_with_et(ip),
 | 
			
		||||
            &ServerOptions::new(ip, Some(&mut gw_buf)),
 | 
			
		||||
            &mut bound_socket,
 | 
			
		||||
            &mut buf,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        .inspect_err(|e| log::warn!("DHCP server error: {e:?}"));
 | 
			
		||||
        Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
 | 
			
		||||
    runner.run().await;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								src/bin/init/wifi.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/bin/init/wifi.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_hal::gpio::{Output, OutputConfig};
 | 
			
		||||
use esp_hal::peripherals::{GPIO3, GPIO14, WIFI};
 | 
			
		||||
use esp_wifi::wifi::{AccessPointConfiguration, Configuration, WifiController, WifiEvent, WifiState};
 | 
			
		||||
use esp_wifi::{EspWifiRngSource, EspWifiTimerSource, wifi::Interfaces};
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
pub async fn set_antenna_mode(gpio3: GPIO3<'static>, gpio14: GPIO14<'static>) {
 | 
			
		||||
    let mut rf_switch = Output::new(gpio3, esp_hal::gpio::Level::Low, OutputConfig::default());
 | 
			
		||||
 | 
			
		||||
    rf_switch.set_low();
 | 
			
		||||
 | 
			
		||||
    Timer::after_millis(150).await;
 | 
			
		||||
 | 
			
		||||
    let mut antenna_mode = Output::new(gpio14, esp_hal::gpio::Level::Low, OutputConfig::default());
 | 
			
		||||
 | 
			
		||||
    antenna_mode.set_low();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn setup_wifi<'d: 'static>(
 | 
			
		||||
    timer: impl EspWifiTimerSource + 'd,
 | 
			
		||||
    rng: impl EspWifiRngSource + 'd,
 | 
			
		||||
    wifi: WIFI<'static>,
 | 
			
		||||
    spawner: &mut Spawner,
 | 
			
		||||
) -> Interfaces<'d> {
 | 
			
		||||
    let esp_wifi_ctrl = make_static!(esp_wifi::init(timer, rng).unwrap());
 | 
			
		||||
 | 
			
		||||
    let (controller, interfaces) = esp_wifi::wifi::new(esp_wifi_ctrl, wifi).unwrap();
 | 
			
		||||
 | 
			
		||||
    spawner.must_spawn(connection(controller));
 | 
			
		||||
 | 
			
		||||
    interfaces
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn connection(mut controller: WifiController<'static>) {
 | 
			
		||||
    loop {
 | 
			
		||||
        match esp_wifi::wifi::wifi_state() {
 | 
			
		||||
            WifiState::ApStarted => {
 | 
			
		||||
                // wait until we're no longer connected
 | 
			
		||||
                controller.wait_for_event(WifiEvent::ApStop).await;
 | 
			
		||||
                Timer::after(Duration::from_millis(5000)).await
 | 
			
		||||
            }
 | 
			
		||||
            _ => {}
 | 
			
		||||
        }
 | 
			
		||||
        if !matches!(controller.is_started(), Ok(true)) {
 | 
			
		||||
            let client_config = Configuration::AccessPoint(AccessPointConfiguration {
 | 
			
		||||
                ssid: "esp-wifi".try_into().unwrap(),
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            });
 | 
			
		||||
            controller.set_configuration(&client_config).unwrap();
 | 
			
		||||
            controller.start_async().await.unwrap();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										250
									
								
								src/bin/main.rs
									
									
									
									
									
								
							
							
						
						
									
										250
									
								
								src/bin/main.rs
									
									
									
									
									
								
							@ -3,115 +3,29 @@
 | 
			
		||||
#![feature(type_alias_impl_trait)]
 | 
			
		||||
#![feature(impl_trait_in_assoc_type)]
 | 
			
		||||
 | 
			
		||||
use core::net::Ipv4Addr;
 | 
			
		||||
use core::str::FromStr;
 | 
			
		||||
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_hal::clock::CpuClock;
 | 
			
		||||
use esp_hal::gpio::{Output, OutputConfig};
 | 
			
		||||
use esp_hal::peripherals::{GPIO1, GPIO2, UART1};
 | 
			
		||||
use esp_hal::timer::systimer::SystemTimer;
 | 
			
		||||
use esp_hal::timer::timg::TimerGroup;
 | 
			
		||||
use esp_hal::uart::{Config, Uart};
 | 
			
		||||
use esp_println::logger::init_logger;
 | 
			
		||||
use esp_wifi::wifi::{
 | 
			
		||||
    AccessPointConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState,
 | 
			
		||||
};
 | 
			
		||||
use esp_hal::Async;
 | 
			
		||||
use esp_hal::uart::Uart;
 | 
			
		||||
use log::{debug, info};
 | 
			
		||||
use picoserve::routing::get;
 | 
			
		||||
use picoserve::{AppBuilder, AppRouter};
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
#[panic_handler]
 | 
			
		||||
fn panic(_: &core::panic::PanicInfo) -> ! {
 | 
			
		||||
    loop {}
 | 
			
		||||
}
 | 
			
		||||
use crate::webserver::start_webserver;
 | 
			
		||||
 | 
			
		||||
extern crate alloc;
 | 
			
		||||
 | 
			
		||||
esp_bootloader_esp_idf::esp_app_desc!();
 | 
			
		||||
mod init;
 | 
			
		||||
mod webserver;
 | 
			
		||||
 | 
			
		||||
#[esp_hal_embassy::main]
 | 
			
		||||
async fn main(spawner: Spawner) {
 | 
			
		||||
    // ------------------- init ---------------------------
 | 
			
		||||
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
 | 
			
		||||
    let peripherals = esp_hal::init(config);
 | 
			
		||||
async fn main(mut spawner: Spawner) {
 | 
			
		||||
    let (uart_device, stack) = init::hardware_init(&mut spawner).await;
 | 
			
		||||
 | 
			
		||||
    info!("starting up...");
 | 
			
		||||
    wait_for_stack_up(stack).await;
 | 
			
		||||
 | 
			
		||||
    esp_alloc::heap_allocator!(size: 72 * 1024);
 | 
			
		||||
 | 
			
		||||
    let timer0 = SystemTimer::new(peripherals.SYSTIMER);
 | 
			
		||||
    esp_hal_embassy::init(timer0.alarm0);
 | 
			
		||||
 | 
			
		||||
    init_logger(log::LevelFilter::Debug);
 | 
			
		||||
 | 
			
		||||
    let timer1 = TimerGroup::new(peripherals.TIMG0);
 | 
			
		||||
    let mut rng = esp_hal::rng::Rng::new(peripherals.RNG);
 | 
			
		||||
 | 
			
		||||
    debug!("set wlan antenna..");
 | 
			
		||||
    let mut rf_switch = Output::new(
 | 
			
		||||
        peripherals.GPIO3,
 | 
			
		||||
        esp_hal::gpio::Level::Low,
 | 
			
		||||
        OutputConfig::default(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    rf_switch.set_low();
 | 
			
		||||
 | 
			
		||||
    Timer::after_secs(1).await;
 | 
			
		||||
 | 
			
		||||
    let mut antenna_mode = Output::new(
 | 
			
		||||
        peripherals.GPIO14,
 | 
			
		||||
        esp_hal::gpio::Level::Low,
 | 
			
		||||
        OutputConfig::default(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    antenna_mode.set_low();
 | 
			
		||||
 | 
			
		||||
    Timer::after_secs(1).await;
 | 
			
		||||
 | 
			
		||||
    // Setup wifi deivce
 | 
			
		||||
    debug!("setup wifi..");
 | 
			
		||||
    let esp_wifi_ctrl =
 | 
			
		||||
        make_static!(esp_wifi::init(timer1.timer0, rng).unwrap());
 | 
			
		||||
    let (controller, interfaces) = esp_wifi::wifi::new(esp_wifi_ctrl, peripherals.WIFI).unwrap();
 | 
			
		||||
    // let wifi_interface = interfaces.sta;
 | 
			
		||||
    let wifi_ap = interfaces.ap;
 | 
			
		||||
 | 
			
		||||
    let gw_ip_addr_str = "192.168.2.1";
 | 
			
		||||
    let gw_ip_addr = Ipv4Addr::from_str(gw_ip_addr_str).expect("failed to parse gateway ip");
 | 
			
		||||
 | 
			
		||||
    let config = embassy_net::Config::ipv4_static(StaticConfigV4 {
 | 
			
		||||
        address: Ipv4Cidr::new(gw_ip_addr, 24),
 | 
			
		||||
        gateway: Some(gw_ip_addr),
 | 
			
		||||
        dns_servers: Default::default(),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let seed = (rng.random() as u64) << 32 | rng.random() as u64;
 | 
			
		||||
 | 
			
		||||
    // Init network stack
 | 
			
		||||
    let (stack, runner) = embassy_net::new(
 | 
			
		||||
        wifi_ap,
 | 
			
		||||
        config,
 | 
			
		||||
        make_static!(StackResources::<3>::new()),
 | 
			
		||||
        seed,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    debug!("Setup complete. Running network tasks");
 | 
			
		||||
 | 
			
		||||
    spawner.spawn(connection(controller)).ok();
 | 
			
		||||
    spawner.spawn(net_task(runner)).ok();
 | 
			
		||||
    spawner.spawn(run_dhcp(stack, gw_ip_addr_str)).ok();
 | 
			
		||||
    spawner
 | 
			
		||||
        .spawn(rfid_reader_task(
 | 
			
		||||
            peripherals.UART1,
 | 
			
		||||
            peripherals.GPIO1,
 | 
			
		||||
            peripherals.GPIO2,
 | 
			
		||||
        ))
 | 
			
		||||
        .ok();
 | 
			
		||||
    start_webserver(&mut spawner, stack);
 | 
			
		||||
    spawner.must_spawn(rfid_reader_task(uart_device));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn wait_for_stack_up(stack: Stack<'static>) {
 | 
			
		||||
    loop {
 | 
			
		||||
        if stack.is_link_up() {
 | 
			
		||||
            break;
 | 
			
		||||
@ -122,154 +36,24 @@ async fn main(spawner: Spawner) {
 | 
			
		||||
        }
 | 
			
		||||
        Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debug!("Starting webserver");
 | 
			
		||||
 | 
			
		||||
    let app = make_static!(AppProps.build_app());
 | 
			
		||||
 | 
			
		||||
    let config = make_static!(picoserve::Config::new(picoserve::Timeouts {
 | 
			
		||||
        start_read_request: Some(Duration::from_secs(5)),
 | 
			
		||||
        persistent_start_read_request: Some(Duration::from_secs(1)),
 | 
			
		||||
        read_request: Some(Duration::from_secs(1)),
 | 
			
		||||
        write: Some(Duration::from_secs(1)),
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    let _ = spawner.spawn(webserver_task(0, stack, app, config));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct AppProps;
 | 
			
		||||
 | 
			
		||||
impl AppBuilder for AppProps {
 | 
			
		||||
    type PathRouter = impl picoserve::routing::PathRouter;
 | 
			
		||||
 | 
			
		||||
    fn build_app(self) -> picoserve::Router<Self::PathRouter> {
 | 
			
		||||
        picoserve::Router::new().route("/", get(|| async move { "Hello World" }))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn webserver_task(
 | 
			
		||||
    id: usize,
 | 
			
		||||
    stack: embassy_net::Stack<'static>,
 | 
			
		||||
    app: &'static AppRouter<AppProps>,
 | 
			
		||||
    config: &'static picoserve::Config<Duration>,
 | 
			
		||||
) -> ! {
 | 
			
		||||
    let mut tcp_rx_buffer = [0u8; 1024];
 | 
			
		||||
    let mut tcp_tx_buffer = [0u8; 1024];
 | 
			
		||||
    let mut http_buffer = [0u8; 2048];
 | 
			
		||||
 | 
			
		||||
    picoserve::listen_and_serve(
 | 
			
		||||
        id,
 | 
			
		||||
        app,
 | 
			
		||||
        config,
 | 
			
		||||
        stack,
 | 
			
		||||
        80,
 | 
			
		||||
        &mut tcp_rx_buffer,
 | 
			
		||||
        &mut tcp_tx_buffer,
 | 
			
		||||
        &mut http_buffer,
 | 
			
		||||
    )
 | 
			
		||||
    .await
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
 | 
			
		||||
    debug!("start dhcp");
 | 
			
		||||
    use core::net::{Ipv4Addr, SocketAddrV4};
 | 
			
		||||
 | 
			
		||||
    use edge_dhcp::{
 | 
			
		||||
        io::{self, DEFAULT_SERVER_PORT},
 | 
			
		||||
        server::{Server, ServerOptions},
 | 
			
		||||
    };
 | 
			
		||||
    use edge_nal::UdpBind;
 | 
			
		||||
    use edge_nal_embassy::{Udp, UdpBuffers};
 | 
			
		||||
 | 
			
		||||
    let ip = Ipv4Addr::from_str(gw_ip_addr).expect("dhcp task failed to parse gw ip");
 | 
			
		||||
 | 
			
		||||
    let mut buf = [0u8; 1500];
 | 
			
		||||
 | 
			
		||||
    let mut gw_buf = [Ipv4Addr::UNSPECIFIED];
 | 
			
		||||
 | 
			
		||||
    let buffers = UdpBuffers::<3, 1024, 1024, 10>::new();
 | 
			
		||||
    let unbound_socket = Udp::new(stack, &buffers);
 | 
			
		||||
    let mut bound_socket = unbound_socket
 | 
			
		||||
        .bind(core::net::SocketAddr::V4(SocketAddrV4::new(
 | 
			
		||||
            Ipv4Addr::UNSPECIFIED,
 | 
			
		||||
            DEFAULT_SERVER_PORT,
 | 
			
		||||
        )))
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        _ = io::server::run(
 | 
			
		||||
            &mut Server::<_, 64>::new_with_et(ip),
 | 
			
		||||
            &ServerOptions::new(ip, Some(&mut gw_buf)),
 | 
			
		||||
            &mut bound_socket,
 | 
			
		||||
            &mut buf,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        .inspect_err(|e| log::warn!("DHCP server error: {e:?}"));
 | 
			
		||||
        Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
 | 
			
		||||
    runner.run().await;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn connection(mut controller: WifiController<'static>) {
 | 
			
		||||
    debug!("start connection task");
 | 
			
		||||
    debug!("Device capabilities: {:?}", controller.capabilities());
 | 
			
		||||
    loop {
 | 
			
		||||
        match esp_wifi::wifi::wifi_state() {
 | 
			
		||||
            WifiState::ApStarted => {
 | 
			
		||||
                // wait until we're no longer connected
 | 
			
		||||
                controller.wait_for_event(WifiEvent::ApStop).await;
 | 
			
		||||
                Timer::after(Duration::from_millis(5000)).await
 | 
			
		||||
            }
 | 
			
		||||
            _ => {}
 | 
			
		||||
        }
 | 
			
		||||
        if !matches!(controller.is_started(), Ok(true)) {
 | 
			
		||||
            let client_config = Configuration::AccessPoint(AccessPointConfiguration {
 | 
			
		||||
                ssid: "esp-wifi".try_into().unwrap(),
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            });
 | 
			
		||||
            controller.set_configuration(&client_config).unwrap();
 | 
			
		||||
            debug!("Starting wifi");
 | 
			
		||||
            controller.start_async().await.unwrap();
 | 
			
		||||
            debug!("Wifi started!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn rfid_reader_task(uart1: UART1<'static>, gpio1: GPIO1<'static>, gpio2: GPIO2<'static>) {
 | 
			
		||||
    debug!("init rfid reader..");
 | 
			
		||||
 | 
			
		||||
    let uart1_block_result = Uart::new(uart1, Config::default().with_baudrate(9600));
 | 
			
		||||
    let mut nfc_reader = match uart1_block_result {
 | 
			
		||||
        Ok(block) => block.with_rx(gpio1).with_tx(gpio2).into_async(),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            log::error!("Failed to initialize UART: {:?}", e);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
async fn rfid_reader_task(mut uart_device: Uart<'static, Async>) {
 | 
			
		||||
    let mut uart_buffer = [0u8; 64];
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        debug!("Looking for NFC...");
 | 
			
		||||
        match nfc_reader.read_async(&mut uart_buffer).await {
 | 
			
		||||
        match uart_device.read_async(&mut uart_buffer).await {
 | 
			
		||||
            Ok(n) => {
 | 
			
		||||
                let mut hex_str = heapless::String::<128>::new();
 | 
			
		||||
                for byte in &uart_buffer[..n] {
 | 
			
		||||
                    core::fmt::Write::write_fmt(&mut hex_str, format_args!("{:02X} ", byte)).ok();
 | 
			
		||||
                }
 | 
			
		||||
                info!("Read {} bytes from UART: {}", n, hex_str);
 | 
			
		||||
                info!("Read {n} bytes from UART: {hex_str}");
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                log::error!("Error reading from UART: {:?}", e);
 | 
			
		||||
                log::error!("Error reading from UART: {e}");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Timer::after(Duration::from_millis(200)).await;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								src/bin/webserver/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/bin/webserver/mod.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use embassy_time::Duration;
 | 
			
		||||
use picoserve::{AppBuilder, AppRouter, routing::get};
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
pub fn start_webserver(spawner: &mut Spawner, stack: Stack<'static>) {
 | 
			
		||||
    let app = make_static!(AppProps.build_app());
 | 
			
		||||
 | 
			
		||||
    let config = make_static!(picoserve::Config::new(picoserve::Timeouts {
 | 
			
		||||
        start_read_request: Some(Duration::from_secs(5)),
 | 
			
		||||
        persistent_start_read_request: Some(Duration::from_secs(1)),
 | 
			
		||||
        read_request: Some(Duration::from_secs(1)),
 | 
			
		||||
        write: Some(Duration::from_secs(1)),
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    let _ = spawner.spawn(webserver_task(0, stack, app, config));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct AppProps;
 | 
			
		||||
 | 
			
		||||
impl AppBuilder for AppProps {
 | 
			
		||||
    type PathRouter = impl picoserve::routing::PathRouter;
 | 
			
		||||
 | 
			
		||||
    fn build_app(self) -> picoserve::Router<Self::PathRouter> {
 | 
			
		||||
        picoserve::Router::new().route("/", get(|| async move { "Hello World" }))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
async fn webserver_task(
 | 
			
		||||
    id: usize,
 | 
			
		||||
    stack: embassy_net::Stack<'static>,
 | 
			
		||||
    app: &'static AppRouter<AppProps>,
 | 
			
		||||
    config: &'static picoserve::Config<Duration>,
 | 
			
		||||
) -> ! {
 | 
			
		||||
    let mut tcp_rx_buffer = [0u8; 1024];
 | 
			
		||||
    let mut tcp_tx_buffer = [0u8; 1024];
 | 
			
		||||
    let mut http_buffer = [0u8; 2048];
 | 
			
		||||
 | 
			
		||||
    picoserve::listen_and_serve(
 | 
			
		||||
        id,
 | 
			
		||||
        app,
 | 
			
		||||
        config,
 | 
			
		||||
        stack,
 | 
			
		||||
        80,
 | 
			
		||||
        &mut tcp_rx_buffer,
 | 
			
		||||
        &mut tcp_tx_buffer,
 | 
			
		||||
        &mut http_buffer,
 | 
			
		||||
    )
 | 
			
		||||
    .await
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user