mirror of
https://github.com/Djeeberjr/fw-anwesenheit.git
synced 2026-04-30 18:49:09 +00:00
redesigned dir structure for rust 2018 style guide. made (untested) rtc funtion
This commit is contained in:
139
src/init/hardware.rs
Normal file
139
src/init/hardware.rs
Normal file
@@ -0,0 +1,139 @@
|
||||
use core::slice::RChunks;
|
||||
|
||||
use ds3231::{DS3231, Alarm1Config};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{driver, Stack};
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use esp_hal::config;
|
||||
use esp_hal::gpio::{Input, Pull};
|
||||
use esp_hal::i2c::master::Config;
|
||||
use esp_hal::peripherals::{self, GPIO0, GPIO1, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO21, GPIO22, GPIO23, I2C0, UART1};
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::{
|
||||
Async,
|
||||
clock::CpuClock,
|
||||
timer::{systimer::SystemTimer, timg::TimerGroup},
|
||||
uart::Uart,
|
||||
i2c::master::I2c,
|
||||
gpio::{Output, OutputConfig}
|
||||
};
|
||||
use esp_println::logger::init_logger;
|
||||
use log::error;
|
||||
|
||||
use crate::init::wifi;
|
||||
use crate::init::network;
|
||||
|
||||
const RTC_ADDRESS: u8 = 0x57;
|
||||
|
||||
#[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>, I2c<'static, Async>, GPIO21<'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);
|
||||
|
||||
init_lvl_shifter(peripherals.GPIO0);
|
||||
|
||||
let uart_device = setup_uart(peripherals.UART1, peripherals.GPIO7, peripherals.GPIO6);
|
||||
|
||||
let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23);
|
||||
|
||||
//RTC Interrupt pin
|
||||
let sqw_pin = peripherals.GPIO21;
|
||||
|
||||
//TODO change to get I2C device back / maybe init for each protocol
|
||||
|
||||
(uart_device, stack, i2c_device, sqw_pin)
|
||||
}
|
||||
|
||||
// Initialize the level shifter for the NFC reader and LED (output-enable (OE) input is low, all outputs are placed in the high-impedance (Hi-Z) state)
|
||||
fn init_lvl_shifter(oe_pin: GPIO0<'static>){
|
||||
let mut oe_lvl_shifter = Output::new(oe_pin, esp_hal::gpio::Level::Low, OutputConfig::default());
|
||||
oe_lvl_shifter.set_high();
|
||||
}
|
||||
|
||||
fn setup_uart(
|
||||
uart1: UART1<'static>,
|
||||
uart_rx: GPIO7<'static>,
|
||||
uart_tx: GPIO6<'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(uart_rx).with_tx(uart_tx).into_async(),
|
||||
Err(e) => {
|
||||
error!("Failed to initialize UART: {e}");
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_i2c(
|
||||
i2c0: I2C0<'static>,
|
||||
sda: GPIO22<'static>,
|
||||
scl: GPIO23<'static>,
|
||||
) -> I2c<'static, Async> {
|
||||
|
||||
let config = Config::default().with_frequency(Rate::from_khz(400));
|
||||
let i2c = match I2c::new(i2c0, config) {
|
||||
Ok(i2c) => i2c.with_sda(sda).with_scl(scl).into_async(),
|
||||
Err(e) => {
|
||||
error!("Failed to initialize I2C: {:?}", e);
|
||||
panic!();
|
||||
}
|
||||
};
|
||||
i2c
|
||||
}
|
||||
|
||||
pub async fn rtc_init_iterrupt(sqw_pin: GPIO21<'static>) -> Input<'static> {
|
||||
let config = esp_hal::gpio::InputConfig::default().with_pull(Pull::Up);
|
||||
let mut sqw_interrupt = Input::new(sqw_pin, config);
|
||||
sqw_interrupt
|
||||
}
|
||||
|
||||
pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>> {
|
||||
let mut rtc: DS3231<I2c<'static, Async>> = DS3231::new(i2c, RTC_ADDRESS);
|
||||
let daily_alarm = Alarm1Config::AtTime {
|
||||
hours: 9,
|
||||
minutes: 30,
|
||||
seconds: 0,
|
||||
is_pm: None, // 24-hour mode
|
||||
};
|
||||
if let Err(e) = rtc.set_alarm1(&daily_alarm).await {
|
||||
error!("Failed to configure RTC: {:?}", e);
|
||||
panic!();
|
||||
}
|
||||
rtc
|
||||
}
|
||||
|
||||
|
||||
fn setup_spi_led() {
|
||||
|
||||
}
|
||||
|
||||
fn setup_rtc() {
|
||||
//TODO
|
||||
//setup rtc with i2c
|
||||
//setup interrupt for SQW
|
||||
//setup 24-h alarm
|
||||
}
|
||||
|
||||
72
src/init/network.rs
Normal file
72
src/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/init/wifi.rs
Normal file
56
src/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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user