Compare commits
No commits in common. "9e93f8b9f772846214238c758535113826f87fb4" and "0475ee343a1a124325d56f65d0d0d5946d23afb7" have entirely different histories.
9e93f8b9f7
...
0475ee343a
5 changed files with 93 additions and 297 deletions
|
|
@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) -> ! {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
println!("Scan");
|
println!("Scan");
|
||||||
let scan_config = ScanConfig::default().with_max(20);
|
let scan_config = ScanConfig::default().with_max(10);
|
||||||
let result = controller.scan_async(&scan_config).await.unwrap();
|
let result = controller.scan_async(&scan_config).await.unwrap();
|
||||||
for ap in result {
|
for ap in result {
|
||||||
println!("{:?}", ap);
|
println!("{:?}", ap);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channe
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_hal::gpio::Input;
|
use esp_hal::gpio::Input;
|
||||||
use esp_hal::i2c::master::{Config, I2c};
|
use esp_hal::i2c::master::{Config, I2c};
|
||||||
use esp_hal::peripherals::{GPIO21, GPIO22, I2C0};
|
use esp_hal::peripherals::{GPIO4, GPIO5, I2C0};
|
||||||
use esp_hal::time::Rate;
|
use esp_hal::time::Rate;
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
|
|
||||||
|
|
@ -15,16 +15,13 @@ pub static ANGLE: Mutex<CriticalSectionRawMutex, u16> = Mutex::new(0);
|
||||||
|
|
||||||
pub struct RotationConfig {
|
pub struct RotationConfig {
|
||||||
pub i2c0: I2C0<'static>,
|
pub i2c0: I2C0<'static>,
|
||||||
pub scl: GPIO22<'static>,
|
pub scl: GPIO5<'static>,
|
||||||
pub sda: GPIO21<'static>,
|
pub sda: GPIO4<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn rotation_read_task(config: RotationConfig) {
|
pub async fn rotation_read_task(config: RotationConfig) {
|
||||||
let i2c = I2c::new(
|
let i2c = I2c::new(config.i2c0, Config::default().with_frequency(Rate::from_khz(400)))
|
||||||
config.i2c0,
|
|
||||||
Config::default().with_frequency(Rate::from_khz(400)),
|
|
||||||
)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_sda(config.sda)
|
.with_sda(config.sda)
|
||||||
.with_scl(config.scl)
|
.with_scl(config.scl)
|
||||||
|
|
@ -46,7 +43,14 @@ pub async fn rotation_read_task(config: RotationConfig) {
|
||||||
let mut value = wheel.value;
|
let mut value = wheel.value;
|
||||||
let mut accumulated = wheel.accumulated;
|
let mut accumulated = wheel.accumulated;
|
||||||
let precision = crate::WHEEL_PRECISION;
|
let precision = crate::WHEEL_PRECISION;
|
||||||
apply_wheel_delta(&mut value, min, max, &mut accumulated, diff, precision);
|
apply_wheel_delta(
|
||||||
|
&mut value,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
&mut accumulated,
|
||||||
|
diff,
|
||||||
|
precision,
|
||||||
|
);
|
||||||
wheel.value = value;
|
wheel.value = value;
|
||||||
wheel.accumulated = accumulated;
|
wheel.accumulated = accumulated;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,17 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::select::{Either, select};
|
|
||||||
use embassy_net::tcp::{TcpReader, TcpWriter};
|
use embassy_net::tcp::{TcpReader, TcpWriter};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::mutex::Mutex;
|
use embassy_sync::mutex::Mutex;
|
||||||
use embassy_sync::signal::Signal;
|
use embassy_sync::signal::Signal;
|
||||||
use embassy_time::Timer;
|
|
||||||
use embedded_io::Write;
|
use embedded_io::Write;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
gpio::{Input, InputConfig as GpioInputConfig, Pin, Pull},
|
gpio::{Input, InputConfig as GpioInputConfig, Pin, Pull},
|
||||||
interrupt::software::SoftwareInterruptControl,
|
|
||||||
timer::timg::TimerGroup,
|
|
||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use owned_str::OwnedStr;
|
use owned_str::OwnedStr;
|
||||||
|
|
@ -31,29 +25,18 @@ mod screen;
|
||||||
|
|
||||||
pub use input::ANGLE;
|
pub use input::ANGLE;
|
||||||
|
|
||||||
use crate::screen::overwrite_lcd;
|
|
||||||
|
|
||||||
const WIFI_NETWORK: &str = "flamme";
|
const WIFI_NETWORK: &str = "flamme";
|
||||||
const WIFI_PASSWORD: &str = "12345678";
|
const WIFI_PASSWORD: &str = "12345678";
|
||||||
const TARGET_IP: &str = "84.238.32.253";
|
const TARGET_IP: &str = "84.238.32.253";
|
||||||
const TARGET_PORT: u16 = 7070;
|
const TARGET_PORT: u16 = 7070;
|
||||||
const WHEEL_PRECISION: i32 = 32;
|
const WHEEL_PRECISION: i32 = 32;
|
||||||
const WHEEL_INVERTED: bool = false;
|
const WHEEL_INVERTED: bool = false;
|
||||||
const DEVICE_ID: &str = "esp32-1";
|
|
||||||
|
|
||||||
enum QuestionType {
|
enum QuestionType {
|
||||||
Choice,
|
Choice,
|
||||||
Numeric { min: i32, max: i32 },
|
Numeric { min: i32, max: i32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
||||||
pub enum TcpDisconnect {
|
|
||||||
ReadError,
|
|
||||||
ReadEof,
|
|
||||||
WriteError,
|
|
||||||
Cancelled,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct QuestionData {
|
struct QuestionData {
|
||||||
text: OwnedStr<256>,
|
text: OwnedStr<256>,
|
||||||
q_type: QuestionType,
|
q_type: QuestionType,
|
||||||
|
|
@ -78,44 +61,18 @@ static WHEEL_VALUE: Mutex<CriticalSectionRawMutex, WheelData> = Mutex::new(Wheel
|
||||||
accumulated: 0,
|
accumulated: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
pub async fn reset_state() {
|
|
||||||
*QUESTION.lock().await = None;
|
|
||||||
*WHEEL_VALUE.lock().await = WheelData {
|
|
||||||
value: 0,
|
|
||||||
min: 0,
|
|
||||||
max: 0,
|
|
||||||
accumulated: 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
fn panic(_: &core::panic::PanicInfo) -> ! {
|
||||||
println!("PANIC! {:?}", info);
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn tcp_read_loop(
|
pub async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
||||||
mut read: TcpReader<'_>,
|
|
||||||
cancel: &Signal<CriticalSectionRawMutex, ()>,
|
|
||||||
) -> Result<(), TcpDisconnect> {
|
|
||||||
let mut buf = [0u8; 1024];
|
let mut buf = [0u8; 1024];
|
||||||
let mut generation = 1;
|
let mut generation = 1;
|
||||||
|
|
||||||
loop {
|
while let Ok(len) = read.read(&mut buf).await {
|
||||||
let read_fut = read.read(&mut buf);
|
|
||||||
let cancel_fut = cancel.wait();
|
|
||||||
let len = match select(read_fut, cancel_fut).await {
|
|
||||||
Either::First(Ok(len)) => len,
|
|
||||||
Either::First(Err(_)) => {
|
|
||||||
cancel.signal(());
|
|
||||||
return Err(TcpDisconnect::ReadError);
|
|
||||||
}
|
|
||||||
Either::Second(()) => return Err(TcpDisconnect::Cancelled),
|
|
||||||
};
|
|
||||||
|
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
cancel.signal(());
|
break;
|
||||||
return Err(TcpDisconnect::ReadEof);
|
|
||||||
}
|
}
|
||||||
let Ok(str) = core::str::from_utf8(&buf[..len]) else {
|
let Ok(str) = core::str::from_utf8(&buf[..len]) else {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -129,10 +86,6 @@ pub async fn tcp_read_loop(
|
||||||
accumulated: 0,
|
accumulated: 0,
|
||||||
};
|
};
|
||||||
for line in str.lines() {
|
for line in str.lines() {
|
||||||
if line == "##" {
|
|
||||||
overwrite_lcd("Waiting", DEVICE_ID).await;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if line == "$$" {
|
if line == "$$" {
|
||||||
counter = 1;
|
counter = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -156,10 +109,7 @@ pub async fn tcp_read_loop(
|
||||||
if key == "rangeMin" || key == "rangeMax" {
|
if key == "rangeMin" || key == "rangeMax" {
|
||||||
match q_type {
|
match q_type {
|
||||||
QuestionType::Choice => {}
|
QuestionType::Choice => {}
|
||||||
QuestionType::Numeric {
|
QuestionType::Numeric { ref mut min, ref mut max } => {
|
||||||
ref mut min,
|
|
||||||
ref mut max,
|
|
||||||
} => {
|
|
||||||
if key == "rangeMin" {
|
if key == "rangeMin" {
|
||||||
*min = value.parse().unwrap();
|
*min = value.parse().unwrap();
|
||||||
future_wheel.min = *min;
|
future_wheel.min = *min;
|
||||||
|
|
@ -202,30 +152,15 @@ pub async fn tcp_read_loop(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn tcp_write_loop(
|
pub async fn tcp_write_loop(mut write: TcpWriter<'_>) {
|
||||||
mut write: TcpWriter<'_>,
|
|
||||||
cancel: &Signal<CriticalSectionRawMutex, ()>,
|
|
||||||
) -> Result<(), TcpDisconnect> {
|
|
||||||
if write.write(DEVICE_ID.as_bytes()).await.is_err() {
|
|
||||||
cancel.signal(());
|
|
||||||
return Err(TcpDisconnect::WriteError);
|
|
||||||
}
|
|
||||||
let mut buffer = buffer::WriteBuffer::<256>::new();
|
let mut buffer = buffer::WriteBuffer::<256>::new();
|
||||||
loop {
|
loop {
|
||||||
let input_fut = input::INPUT.receive();
|
let data = input::INPUT.receive().await;
|
||||||
let cancel_fut = cancel.wait();
|
|
||||||
let data = match select(input_fut, cancel_fut).await {
|
|
||||||
Either::First(data) => data,
|
|
||||||
Either::Second(()) => return Err(TcpDisconnect::Cancelled),
|
|
||||||
};
|
|
||||||
println!("button={}", data);
|
println!("button={}", data);
|
||||||
let angle = *ANGLE.lock().await;
|
let angle = *ANGLE.lock().await;
|
||||||
core::writeln!(buffer, "button={} angle={}", data, angle).ok();
|
core::writeln!(buffer, "button={} angle={}", data, angle).ok();
|
||||||
println!("write: {}", &buffer);
|
println!("write: {}", &buffer);
|
||||||
if write.write(&buffer).await.is_err() {
|
write.write(&buffer).await.ok();
|
||||||
cancel.signal(());
|
|
||||||
return Err(TcpDisconnect::WriteError);
|
|
||||||
}
|
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -286,98 +221,42 @@ pub async fn main_loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_bootloader_esp_idf::esp_app_desc!();
|
|
||||||
|
|
||||||
#[esp_rtos::main]
|
#[esp_rtos::main]
|
||||||
async fn main(spawner: Spawner) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
let p =
|
let p = esp_hal::init(esp_hal::Config::default().with_cpu_clock(esp_hal::clock::CpuClock::max()));
|
||||||
esp_hal::init(esp_hal::Config::default().with_cpu_clock(esp_hal::clock::CpuClock::max()));
|
|
||||||
|
|
||||||
println!("Booting");
|
|
||||||
let timg0 = TimerGroup::new(p.TIMG0);
|
|
||||||
let sw_int = SoftwareInterruptControl::new(p.SW_INTERRUPT);
|
|
||||||
esp_rtos::start(timg0.timer0, sw_int.software_interrupt0);
|
|
||||||
|
|
||||||
esp_alloc::heap_allocator!(size: 64 * 1024);
|
esp_alloc::heap_allocator!(size: 64 * 1024);
|
||||||
|
|
||||||
let lcd = screen::LcdPins {
|
let lcd = screen::LcdPins {
|
||||||
rs: p.GPIO4,
|
rs: p.GPIO10,
|
||||||
e: p.GPIO16,
|
e: p.GPIO11,
|
||||||
d4: p.GPIO17,
|
d4: p.GPIO12,
|
||||||
d5: p.GPIO18,
|
d5: p.GPIO13,
|
||||||
d6: p.GPIO19,
|
d6: p.GPIO14,
|
||||||
d7: p.GPIO23,
|
d7: p.GPIO15,
|
||||||
};
|
};
|
||||||
|
|
||||||
spawner.spawn(screen::lcd_display_task(screen::LcdConfig { pins: lcd }).expect("spawn lcd"));
|
spawner.spawn(screen::lcd_display_task(screen::LcdConfig { pins: lcd }).expect("spawn lcd"));
|
||||||
spawner.spawn(
|
spawner.spawn(input::rotation_read_task(input::RotationConfig {
|
||||||
input::rotation_read_task(input::RotationConfig {
|
|
||||||
i2c0: p.I2C0,
|
i2c0: p.I2C0,
|
||||||
scl: p.GPIO22,
|
scl: p.GPIO5,
|
||||||
sda: p.GPIO21,
|
sda: p.GPIO4,
|
||||||
})
|
}).expect("spawn rotation"));
|
||||||
.expect("spawn rotation"),
|
|
||||||
);
|
|
||||||
|
|
||||||
spawner.spawn(
|
spawner.spawn(input::button_task(Input::new(p.GPIO18.degrade(), GpioInputConfig::default().with_pull(Pull::Up)), 1).expect("spawn btn1"));
|
||||||
input::button_task(
|
spawner.spawn(input::button_task(Input::new(p.GPIO19.degrade(), GpioInputConfig::default().with_pull(Pull::Up)), 2).expect("spawn btn2"));
|
||||||
Input::new(
|
spawner.spawn(input::button_task(Input::new(p.GPIO20.degrade(), GpioInputConfig::default().with_pull(Pull::Up)), 3).expect("spawn btn3"));
|
||||||
p.GPIO26.degrade(),
|
spawner.spawn(input::button_task(Input::new(p.GPIO21.degrade(), GpioInputConfig::default().with_pull(Pull::Up)), 4).expect("spawn btn4"));
|
||||||
GpioInputConfig::default().with_pull(Pull::Up),
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
.expect("spawn btn1"),
|
|
||||||
);
|
|
||||||
spawner.spawn(
|
|
||||||
input::button_task(
|
|
||||||
Input::new(
|
|
||||||
p.GPIO25.degrade(),
|
|
||||||
GpioInputConfig::default().with_pull(Pull::Up),
|
|
||||||
),
|
|
||||||
2,
|
|
||||||
)
|
|
||||||
.expect("spawn btn2"),
|
|
||||||
);
|
|
||||||
spawner.spawn(
|
|
||||||
input::button_task(
|
|
||||||
Input::new(
|
|
||||||
p.GPIO33.degrade(),
|
|
||||||
GpioInputConfig::default().with_pull(Pull::Up),
|
|
||||||
),
|
|
||||||
3,
|
|
||||||
)
|
|
||||||
.expect("spawn btn3"),
|
|
||||||
);
|
|
||||||
spawner.spawn(
|
|
||||||
input::button_task(
|
|
||||||
Input::new(
|
|
||||||
p.GPIO32.degrade(),
|
|
||||||
GpioInputConfig::default().with_pull(Pull::Up),
|
|
||||||
),
|
|
||||||
4,
|
|
||||||
)
|
|
||||||
.expect("spawn btn4"),
|
|
||||||
);
|
|
||||||
|
|
||||||
spawner.spawn(
|
spawner.spawn(net::network_setup_task(spawner, net::NetworkConfig {
|
||||||
net::network_setup_task(
|
|
||||||
spawner,
|
|
||||||
net::NetworkConfig {
|
|
||||||
wifi: p.WIFI,
|
wifi: p.WIFI,
|
||||||
wifi_network: WIFI_NETWORK,
|
wifi_network: WIFI_NETWORK,
|
||||||
wifi_password: WIFI_PASSWORD,
|
wifi_password: WIFI_PASSWORD,
|
||||||
target_ip: TARGET_IP,
|
target_ip: TARGET_IP,
|
||||||
target_port: TARGET_PORT,
|
target_port: TARGET_PORT,
|
||||||
},
|
}).expect("spawn net"));
|
||||||
)
|
|
||||||
.expect("spawn net"),
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("Init done");
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
Timer::after_millis(1000).await;
|
embassy_time::Timer::after_millis(1000).await;
|
||||||
// println!("Looping");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,16 @@
|
||||||
use core::net::SocketAddrV4;
|
use core::net::SocketAddrV4;
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
|
|
||||||
use alloc::format;
|
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_time::Duration;
|
||||||
use embassy_sync::signal::Signal;
|
|
||||||
use embassy_time::{Duration, Timer};
|
|
||||||
use esp_hal::peripherals::WIFI;
|
use esp_hal::peripherals::WIFI;
|
||||||
use esp_hal::rng::Rng;
|
use esp_hal::rng::Rng;
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
|
use esp_radio::wifi::{scan::ScanConfig, Config, ControllerConfig};
|
||||||
use esp_radio::wifi::sta::StationConfig;
|
use esp_radio::wifi::sta::StationConfig;
|
||||||
use esp_radio::wifi::{Config, ControllerConfig, scan::ScanConfig};
|
|
||||||
|
|
||||||
use crate::screen::overwrite_lcd;
|
use crate::{buffer::wait_for_config, tcp_read_loop, tcp_write_loop};
|
||||||
use crate::{TcpDisconnect, buffer::wait_for_config, tcp_read_loop, tcp_write_loop};
|
|
||||||
use crate::{WIFI_NETWORK, WIFI_PASSWORD};
|
|
||||||
|
|
||||||
pub struct NetworkConfig<'a> {
|
pub struct NetworkConfig<'a> {
|
||||||
pub wifi: WIFI<'a>,
|
pub wifi: WIFI<'a>,
|
||||||
|
|
@ -26,17 +21,12 @@ pub struct NetworkConfig<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(
|
async fn net_task(mut runner: embassy_net::Runner<'static, esp_radio::wifi::Interface<'static>>) -> ! {
|
||||||
mut runner: embassy_net::Runner<'static, esp_radio::wifi::Interface<'static>>,
|
|
||||||
) -> ! {
|
|
||||||
runner.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn network_setup_task(
|
pub async fn network_setup_task(spawner: embassy_executor::Spawner, config: NetworkConfig<'static>) {
|
||||||
spawner: embassy_executor::Spawner,
|
|
||||||
config: NetworkConfig<'static>,
|
|
||||||
) {
|
|
||||||
let wifi_config = Config::Station(
|
let wifi_config = Config::Station(
|
||||||
StationConfig::default()
|
StationConfig::default()
|
||||||
.with_ssid(config.wifi_network)
|
.with_ssid(config.wifi_network)
|
||||||
|
|
@ -51,10 +41,6 @@ pub async fn network_setup_task(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("Wifi configured and started!");
|
println!("Wifi configured and started!");
|
||||||
|
|
||||||
controller
|
|
||||||
.set_power_saving(esp_radio::wifi::PowerSaveMode::None)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let wifi_interface = interfaces.station;
|
let wifi_interface = interfaces.station;
|
||||||
let net_config = embassy_net::Config::dhcpv4(Default::default());
|
let net_config = embassy_net::Config::dhcpv4(Default::default());
|
||||||
let rng = Rng::new();
|
let rng = Rng::new();
|
||||||
|
|
@ -68,92 +54,28 @@ pub async fn network_setup_task(
|
||||||
);
|
);
|
||||||
spawner.spawn(net_task(runner).expect("spawn net task"));
|
spawner.spawn(net_task(runner).expect("spawn net task"));
|
||||||
|
|
||||||
loop {
|
|
||||||
loop {
|
|
||||||
overwrite_lcd("Connecting", "").await;
|
|
||||||
println!("Scan");
|
println!("Scan");
|
||||||
let scan_config = ScanConfig::default().with_max(10);
|
let scan_config = ScanConfig::default().with_max(10);
|
||||||
let result = controller.scan_async(&scan_config).await.unwrap();
|
let result = controller.scan_async(&scan_config).await.unwrap();
|
||||||
for ap in result {
|
for ap in result {
|
||||||
println!(
|
println!("{:?}", ap);
|
||||||
"- {} (CH {} Strength {})",
|
|
||||||
ap.ssid.as_str(),
|
|
||||||
ap.channel,
|
|
||||||
ap.signal_strength
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Scan ended");
|
|
||||||
|
|
||||||
if let Err(e) = controller.set_config(&Config::Station(
|
|
||||||
StationConfig::default()
|
|
||||||
// .with_auth_method(esp_radio::wifi::AuthenticationMethod::Wpa2Wpa3Personal)
|
|
||||||
.with_ssid(WIFI_NETWORK)
|
|
||||||
.with_password(WIFI_PASSWORD.into()),
|
|
||||||
)) {
|
|
||||||
println!("Connection error: {:?}", e);
|
|
||||||
overwrite_lcd("Connection error", &format!("{}", e)).await;
|
|
||||||
Timer::after_millis(1000).await;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(e) = controller.connect_async().await {
|
|
||||||
println!("Connect error: {:?}", e);
|
|
||||||
overwrite_lcd("Connection error", &format!("{}", e)).await;
|
|
||||||
Timer::after_millis(1000).await;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Configured");
|
|
||||||
|
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Waiting for DHCP");
|
|
||||||
|
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
let local_addr = cfg.address.address();
|
let local_addr = cfg.address.address();
|
||||||
println!("IP address: {:?}", local_addr);
|
println!("IP address: {:?}", local_addr);
|
||||||
|
|
||||||
loop {
|
|
||||||
let host_addr = embassy_net::Ipv4Address::from_str(config.target_ip).unwrap();
|
let host_addr = embassy_net::Ipv4Address::from_str(config.target_ip).unwrap();
|
||||||
let mut rx_buffer = [0; 4096];
|
let mut rx_buffer = [0; 4096];
|
||||||
let mut tx_buffer = [0; 4096];
|
let mut tx_buffer = [0; 4096];
|
||||||
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
socket.set_timeout(Some(Duration::from_secs(10)));
|
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||||
socket.set_keep_alive(Some(Duration::from_secs(1)));
|
socket.set_keep_alive(Some(Duration::from_secs(1)));
|
||||||
if let Err(e) = socket
|
if let Err(e) = socket.connect(SocketAddrV4::new(host_addr, config.target_port)).await {
|
||||||
.connect(SocketAddrV4::new(host_addr, config.target_port))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
println!("tcp connect error: {:?}", e);
|
println!("tcp connect error: {:?}", e);
|
||||||
overwrite_lcd("TCP error", &format!("{}", e)).await;
|
|
||||||
Timer::after_millis(1000).await;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
overwrite_lcd("Connected", "").await;
|
|
||||||
|
|
||||||
let cancel = Signal::<CriticalSectionRawMutex, ()>::new();
|
|
||||||
let (read, write) = socket.split();
|
let (read, write) = socket.split();
|
||||||
let (read_result, write_result) =
|
join(tcp_read_loop(read), tcp_write_loop(write)).await;
|
||||||
join(tcp_read_loop(read, &cancel), tcp_write_loop(write, &cancel)).await;
|
|
||||||
let disconnect = read_result.err().or(write_result.err());
|
|
||||||
|
|
||||||
if let Some(reason) = disconnect {
|
|
||||||
println!("tcp disconnected: {:?}", reason);
|
|
||||||
} else {
|
|
||||||
println!("tcp loops ended");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !stack.is_config_up() {
|
|
||||||
println!("wifi down, reconnecting wifi");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
overwrite_lcd("Connection close", "").await;
|
|
||||||
Timer::after_millis(500).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use ag_lcd::LcdDisplay;
|
use ag_lcd::LcdDisplay;
|
||||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, signal::Signal};
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, signal::Signal};
|
||||||
use embassy_time::{Delay, Timer};
|
use embassy_time::{Delay, Timer};
|
||||||
use esp_hal::gpio::{Level, Output, OutputConfig};
|
use esp_hal::gpio::{Level, Output, OutputConfig};
|
||||||
use esp_hal::peripherals::{GPIO4, GPIO16, GPIO17, GPIO18, GPIO19, GPIO23};
|
use esp_hal::peripherals::{GPIO10, GPIO11, GPIO12, GPIO13, GPIO14, GPIO15};
|
||||||
|
use ufmt::uWrite;
|
||||||
|
|
||||||
pub struct LcdPins {
|
pub struct LcdPins {
|
||||||
pub rs: GPIO4<'static>,
|
pub rs: GPIO10<'static>,
|
||||||
pub e: GPIO16<'static>,
|
pub e: GPIO11<'static>,
|
||||||
pub d4: GPIO17<'static>,
|
pub d4: GPIO12<'static>,
|
||||||
pub d5: GPIO18<'static>,
|
pub d5: GPIO13<'static>,
|
||||||
pub d6: GPIO19<'static>,
|
pub d6: GPIO14<'static>,
|
||||||
pub d7: GPIO23<'static>,
|
pub d7: GPIO15<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LcdConfig {
|
pub struct LcdConfig {
|
||||||
|
|
@ -23,16 +26,13 @@ pub async fn overwrite_lcd(line1: &str, line2: &str) {
|
||||||
buffer.line2_ptr = 0;
|
buffer.line2_ptr = 0;
|
||||||
buffer.line1.fill(0);
|
buffer.line1.fill(0);
|
||||||
buffer.line2.fill(0);
|
buffer.line2.fill(0);
|
||||||
let len1 = line1.len().min(buffer.line1.len());
|
buffer.line1[..line1.len()].copy_from_slice(line1.as_bytes());
|
||||||
let len2 = line2.len().min(buffer.line2.len());
|
buffer.line2[..line2.len()].copy_from_slice(line2.as_bytes());
|
||||||
buffer.line1[..len1].copy_from_slice(line1[..len1].as_bytes());
|
|
||||||
buffer.line2[..len2].copy_from_slice(line2[..len2].as_bytes());
|
|
||||||
LCD_UPDATE.signal(());
|
LCD_UPDATE.signal(());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stack_resources() -> &'static mut embassy_net::StackResources<5> {
|
pub fn stack_resources() -> &'static mut embassy_net::StackResources<5> {
|
||||||
static RESOURCES: static_cell::StaticCell<embassy_net::StackResources<5>> =
|
static RESOURCES: static_cell::StaticCell<embassy_net::StackResources<5>> = static_cell::StaticCell::new();
|
||||||
static_cell::StaticCell::new();
|
|
||||||
RESOURCES.init(embassy_net::StackResources::new())
|
RESOURCES.init(embassy_net::StackResources::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,10 +53,7 @@ impl ScreenBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static SCREEN_BUFFER: Mutex<CriticalSectionRawMutex, ScreenBuffer> = Mutex::new(ScreenBuffer {
|
pub static SCREEN_BUFFER: Mutex<CriticalSectionRawMutex, ScreenBuffer> = Mutex::new(ScreenBuffer {
|
||||||
line1: [0; 16],
|
line1: [0; 16], line1_ptr: 0, line2: [0; 16], line2_ptr: 0,
|
||||||
line1_ptr: 0,
|
|
||||||
line2: [0; 16],
|
|
||||||
line2_ptr: 0,
|
|
||||||
});
|
});
|
||||||
static LCD_UPDATE: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
static LCD_UPDATE: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||||
|
|
||||||
|
|
@ -79,20 +76,14 @@ pub async fn lcd_display_task(config: LcdConfig) {
|
||||||
.with_cursor(ag_lcd::Cursor::On)
|
.with_cursor(ag_lcd::Cursor::On)
|
||||||
.with_lines(ag_lcd::Lines::TwoLines)
|
.with_lines(ag_lcd::Lines::TwoLines)
|
||||||
.build();
|
.build();
|
||||||
lcd.set_blink(ag_lcd::Blink::Off);
|
|
||||||
lcd.set_cursor(ag_lcd::Cursor::Off);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
LCD_UPDATE.wait().await;
|
LCD_UPDATE.wait().await;
|
||||||
let buffer = SCREEN_BUFFER.lock().await;
|
let buffer = SCREEN_BUFFER.lock().await;
|
||||||
lcd.clear();
|
lcd.clear();
|
||||||
for byte in &buffer.line1 {
|
for byte in &buffer.line1 { lcd.write(*byte); }
|
||||||
lcd.write(*byte);
|
|
||||||
}
|
|
||||||
lcd.set_position(0, 1);
|
lcd.set_position(0, 1);
|
||||||
for byte in &buffer.line2 {
|
for byte in &buffer.line2 { lcd.write(*byte); }
|
||||||
lcd.write(*byte);
|
|
||||||
}
|
|
||||||
Timer::after_millis(20).await;
|
Timer::after_millis(20).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue