ESP
This commit is contained in:
parent
a4884bd189
commit
865599e059
64 changed files with 6448 additions and 1221 deletions
27
esp/.cargo/config.old.toml
Normal file
27
esp/.cargo/config.old.toml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[build]
|
||||
target = "xtensa-esp32-none-elf"
|
||||
|
||||
[target.'cfg(target_arch = "xtensa")']
|
||||
#runner = "espflash flash --monitor --flash-size 4mb --chip esp32 --partition-table partition.csv --flash-freq 40mhz --flash-mode qio"
|
||||
runner = "espflash flash --monitor --flash-size 4mb --chip esp32"
|
||||
rustflags = [
|
||||
# Optimization
|
||||
"-Z", "location-detail=none",
|
||||
"-C", "link-args=-Wl,--sort-section=alignment",
|
||||
"-C", "inline-threshold=7",
|
||||
|
||||
# GNU LD
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
|
||||
# LLD
|
||||
# "-C", "link-arg=-Tlinkall.x",
|
||||
# "-C", "linker=rust-lld",
|
||||
]
|
||||
|
||||
[env]
|
||||
ESP_LOGLEVEL = "info"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core", "panic_abort"]
|
||||
#build-std = ["core"]
|
||||
17
esp/.cargo/config.toml
Normal file
17
esp/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[target.xtensa-esp32-none-elf]
|
||||
runner = "espflash flash --monitor"
|
||||
|
||||
[env]
|
||||
ESP_LOG="info"
|
||||
|
||||
[build]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-Trom_functions.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
target = "xtensa-esp32-none-elf"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
3
esp/.gitignore
vendored
Normal file
3
esp/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
wifi-ssid.txt
|
||||
wifi-psw.txt
|
||||
target
|
||||
4
esp/.vscode/settings.json
vendored
Normal file
4
esp/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"rust-analyzer.cargo.allTargets": false,
|
||||
"rust-analyzer.cargo.target": "xtensa-esp32-none-elf",
|
||||
}
|
||||
1552
esp/Cargo.lock
generated
Normal file
1552
esp/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
53
esp/Cargo.toml
Normal file
53
esp/Cargo.toml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
[package]
|
||||
name = "rustphone"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
critical-section = "1.2.0"
|
||||
embassy-embedded-hal = "0.2.0"
|
||||
embassy-executor = { version = "0.6.3", features = ["task-arena-size-20480"] }
|
||||
embassy-net = { version = "0.4.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] }
|
||||
embassy-sync = "0.6.1"
|
||||
embassy-time = { version = "0.3.2", features = ["generic-queue-8"] }
|
||||
embedded-graphics = "0.8.1"
|
||||
embedded-hal = "1.0.0"
|
||||
embedded-hal-02 = { version = "0.2.7", package = "embedded-hal", features = ["unproven"] }
|
||||
embedded-io = "0.6.1"
|
||||
embedded-io-async = "0.6.1"
|
||||
embedded-layout = "0.4.1"
|
||||
embedded-text = "0.7.2"
|
||||
#embedded-tls = { version = "0.17.0", default-features = false }
|
||||
epd-waveshare = { path = "../../epd-waveshare", optional = true }
|
||||
esp-alloc = "0.5.0"
|
||||
esp-backtrace = { version = "0.14.2", features = ["esp32", "exception-handler", "panic-handler", "println"] }
|
||||
esp-hal = { version = "0.22.0", features = ["esp32"] }
|
||||
esp-hal-embassy = { version = "0.5.0", features = ["esp32"] }
|
||||
esp-println = { version = "0.12.0", features = ["esp32", "log"] }
|
||||
esp-wifi = { version = "0.11.0", default-features = false, features = ["esp32", "utils", "wifi", "esp-alloc", "log"] }
|
||||
log = "0.4.21"
|
||||
#oled_async = { path = "../../oled_async", features = ["spi"] }
|
||||
nb = "1.1.0"
|
||||
#panic-halt = "0.2.0"
|
||||
rand_core = "0.6.4"
|
||||
#sh1106 = { version = "0.5.0", optional = true }
|
||||
sh1106 = { git = "https://github.com/techmccat/sh1106", branch = "hal-1", optional = true }
|
||||
static_cell = { version = "2.1.0", features = ["nightly"] }
|
||||
|
||||
[features]
|
||||
default = ["display_sh1106"]
|
||||
|
||||
display_epd = ["dep:epd-waveshare"]
|
||||
display_sh1106 = ["dep:sh1106"]
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false
|
||||
incremental = false
|
||||
opt-level = 's'
|
||||
lto = 'fat'
|
||||
overflow-checks = false
|
||||
#panic = "abort"
|
||||
strip = true
|
||||
11
esp/README.md
Normal file
11
esp/README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
## Build
|
||||
|
||||
```bash
|
||||
cargo +esp run --release --target xtensa-esp32-none-elf
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
https://github.com/ivmarkov/rust-esp32-std-demo/blob/main/src/main.rs#L1505
|
||||
|
||||
OLED SPI/I2C V2 1.3in SH1106 5/3.3V
|
||||
5
esp/build.rs
Normal file
5
esp/build.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fn main() {
|
||||
//println!("cargo:rustc-link-arg-bins=-Tlinkall.x");
|
||||
//println!("cargo:rustc-link-arg-bins=-Tesp32_rom_functions.x");
|
||||
//println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||
}
|
||||
4
esp/partition.csv
Normal file
4
esp/partition.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x7000,
|
||||
factory, app, factory, 0x10000, 2M,
|
||||
spiffs, data, spiffs, , 2M,
|
||||
|
1982
esp/rom_functions.x
Normal file
1982
esp/rom_functions.x
Normal file
File diff suppressed because it is too large
Load diff
2
esp/rust-toolchain.toml
Normal file
2
esp/rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "esp"
|
||||
9
esp/rustfmt.toml
Normal file
9
esp/rustfmt.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
hard_tabs = true
|
||||
newline_style = "Unix"
|
||||
imports_granularity = "Crate"
|
||||
|
||||
unstable_features = true
|
||||
format_code_in_doc_comments = true
|
||||
format_macro_bodies = true
|
||||
format_macro_matchers = true
|
||||
format_strings = true
|
||||
9
esp/src/display.rs
Normal file
9
esp/src/display.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "display_sh1106")] {
|
||||
mod sh1106;
|
||||
pub use sh1106::*;
|
||||
} else if #[cfg(feature = "display_epd")] {
|
||||
mod epd;
|
||||
pub use epd::*;
|
||||
}
|
||||
}
|
||||
96
esp/src/display/epd.rs
Normal file
96
esp/src/display/epd.rs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
use core::cell::RefCell;
|
||||
|
||||
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice;
|
||||
use embassy_sync::blocking_mutex::{raw::NoopRawMutex, NoopMutex};
|
||||
use embedded_graphics::prelude::*;
|
||||
use epd_waveshare::{
|
||||
epd1in54::{Display1in54, Epd1in54},
|
||||
prelude::*,
|
||||
};
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{GpioPin, Input, InputPin, Level, Output, Pull},
|
||||
peripherals::SPI2,
|
||||
spi::{master::Spi, FullDuplexMode},
|
||||
};
|
||||
use esp_println::println;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
type EpdSpi<'a> =
|
||||
SpiDevice<'a, NoopRawMutex, Spi<'a, SPI2, FullDuplexMode>, Output<'a, GpioPin<15>>>;
|
||||
type Epd = Epd1in54<
|
||||
EpdSpi<'static>,
|
||||
Input<'static, GpioPin<18>>,
|
||||
Output<'static, GpioPin<19>>,
|
||||
Output<'static, GpioPin<21>>,
|
||||
Delay,
|
||||
>;
|
||||
|
||||
pub type Color = epd_waveshare::color::Color;
|
||||
pub const BLACK: Color = epd_waveshare::color::Color::Black;
|
||||
pub const WHITE: Color = epd_waveshare::color::Color::White;
|
||||
|
||||
//static DISPLAY: StaticCell<Display> = StaticCell::new();
|
||||
|
||||
pub fn init(
|
||||
spi: &mut EpdSpi<'static>,
|
||||
busy: GpioPin<18>,
|
||||
dc: GpioPin<19>,
|
||||
rst: GpioPin<21>,
|
||||
delay: &mut Delay,
|
||||
) -> Epd {
|
||||
Epd::new(
|
||||
spi,
|
||||
Input::new(busy, Pull::Down),
|
||||
Output::new(dc, Level::High),
|
||||
Output::new(rst, Level::High),
|
||||
delay,
|
||||
Some(5),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn run(mut spi: EpdSpi<'static>, mut epd: Epd, mut delay: Delay) {
|
||||
println!("EPD start");
|
||||
epd.clear_frame(&mut spi, &mut delay).unwrap();
|
||||
epd.display_frame(&mut spi, &mut delay).unwrap();
|
||||
let small_buffer = [Color::Black.get_byte_value(); 8]; //8x8
|
||||
epd.update_partial_frame(&mut spi, &mut delay, &small_buffer, 96, 96, 8, 8)
|
||||
.unwrap();
|
||||
|
||||
// Display updated frame
|
||||
epd.display_frame(&mut spi, &mut delay).unwrap();
|
||||
|
||||
delay.delay_millis(5000);
|
||||
|
||||
// Set the EPD to sleep
|
||||
epd.sleep(&mut spi, &mut delay).unwrap();
|
||||
println!("EPD done");
|
||||
}
|
||||
|
||||
/*pub struct Display {
|
||||
epd: Epd,
|
||||
display: Display1in54,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new(spi: &mut Spi<_, _>) -> Self {
|
||||
Self {
|
||||
epd: Epd1in54::new(&mut spi, cs, busy, dc, rst, &mut delay),
|
||||
display: Display1in54::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self) {
|
||||
//self.epd.update_and_display_frame( & mut spi, & self.display.buffer());
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &Display1in54 {
|
||||
&self.display
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> &mut Display1in54 {
|
||||
&mut self.display
|
||||
}
|
||||
}*/
|
||||
98
esp/src/display/sh1106.rs
Normal file
98
esp/src/display/sh1106.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
use crate::string::String;
|
||||
|
||||
use core::cell::RefCell;
|
||||
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice;
|
||||
use embassy_sync::{
|
||||
blocking_mutex::{
|
||||
raw::{CriticalSectionRawMutex, NoopRawMutex},
|
||||
NoopMutex,
|
||||
},
|
||||
channel::Channel,
|
||||
};
|
||||
use embedded_graphics::{
|
||||
mono_font::{ascii::FONT_5X8, MonoTextStyle},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
primitives::{PrimitiveStyle, Rectangle},
|
||||
text::renderer::CharacterStyle,
|
||||
};
|
||||
use embedded_text::{
|
||||
alignment::HorizontalAlignment,
|
||||
style::{HeightMode, TextBoxStyleBuilder},
|
||||
TextBox,
|
||||
};
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, GpioPin, Input, InputPin, Level, Output, Pull},
|
||||
peripherals::SPI2,
|
||||
spi::master::Spi,
|
||||
};
|
||||
use esp_println::println;
|
||||
use sh1106::{prelude::*, Builder};
|
||||
use static_cell::StaticCell;
|
||||
|
||||
type OledSpi<'a> =
|
||||
SpiDevice<'a, NoopRawMutex, Spi<'a, esp_hal::Blocking, SPI2>, Output<'a, GpioPin<15>>>;
|
||||
|
||||
pub static CHANNEL: Channel<CriticalSectionRawMutex, String<1024>, 2> = Channel::new();
|
||||
|
||||
/*pub fn init(
|
||||
spi: OledSpi<'static>,
|
||||
dc: GpioPin<19>,
|
||||
) -> GraphicsMode<SpiInterface<OledSpi<'static>, Output<'static, GpioPin<19>>>> {
|
||||
Builder::new()
|
||||
.connect_spi(spi, Output::new(dc, Level::High))
|
||||
.into()
|
||||
}*/
|
||||
|
||||
pub fn init(
|
||||
spi: OledSpi<'static>,
|
||||
dc: AnyPin,
|
||||
) -> GraphicsMode<SpiInterface<OledSpi<'static>, Output<'static, AnyPin>>> {
|
||||
Builder::new()
|
||||
.connect_spi(spi, Output::new(dc, Level::High))
|
||||
.into()
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn run(
|
||||
mut display: GraphicsMode<SpiInterface<OledSpi<'static>, Output<'static, GpioPin<19>>>>,
|
||||
delay: Delay,
|
||||
) {
|
||||
display.init().unwrap();
|
||||
display.flush().unwrap();
|
||||
|
||||
let mut character_style = MonoTextStyle::new(&FONT_5X8, BinaryColor::On);
|
||||
character_style.set_background_color(Some(BinaryColor::Off));
|
||||
let textbox_style = TextBoxStyleBuilder::new()
|
||||
.height_mode(HeightMode::FitToText)
|
||||
.alignment(HorizontalAlignment::Left)
|
||||
.paragraph_spacing(3)
|
||||
.build();
|
||||
|
||||
let bounds = Rectangle::new(Point::zero(), Size::new(128, 0));
|
||||
|
||||
loop {
|
||||
let buf = CHANNEL.receive().await;
|
||||
let text = buf.as_ref();
|
||||
|
||||
display.clear();
|
||||
|
||||
let text_box = TextBox::with_textbox_style(
|
||||
&text[0..text.len().min(100)],
|
||||
bounds,
|
||||
character_style,
|
||||
textbox_style,
|
||||
);
|
||||
text_box.draw(&mut display).ok();
|
||||
/*Rectangle::with_center(Point::new(20, 20), Size::new(8, 8))
|
||||
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
|
||||
.draw(&mut display)
|
||||
.ok();
|
||||
Rectangle::with_center(Point::new(25, 25), Size::new(8, 8))
|
||||
.into_styled(PrimitiveStyle::with_fill(BinaryColor::Off))
|
||||
.draw(&mut display)
|
||||
.ok();*/
|
||||
display.flush().ok();
|
||||
}
|
||||
}
|
||||
225
esp/src/main.rs
Normal file
225
esp/src/main.rs
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(array_windows)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
mod display;
|
||||
mod modem;
|
||||
//mod rng;
|
||||
mod string;
|
||||
#[macro_use]
|
||||
mod util;
|
||||
mod wifi;
|
||||
|
||||
use string::String;
|
||||
use util::*;
|
||||
|
||||
use core::cell::RefCell;
|
||||
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice;
|
||||
use embassy_sync::blocking_mutex::NoopMutex;
|
||||
//use embedded_tls::{Aes256GcmSha384, TlsConfig, TlsConnection, TlsContext};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{tcp::TcpSocket, Ipv4Address};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_io_async::Write;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{self, Level},
|
||||
prelude::*,
|
||||
spi::{self, master::Spi},
|
||||
timer::{timg::TimerGroup, AnyTimer, OneShotTimer},
|
||||
Blocking,
|
||||
};
|
||||
use esp_println::println;
|
||||
use log::info;
|
||||
|
||||
#[main]
|
||||
async fn main(spawner: Spawner) {
|
||||
let mut peripherals = esp_hal::init({
|
||||
let mut config = esp_hal::Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config
|
||||
});
|
||||
|
||||
esp_alloc::heap_allocator!(72 * 1024);
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
||||
let timer0 = esp_hal::timer::timg::TimerGroup::new(&mut peripherals.TIMG1);
|
||||
esp_hal_embassy::init(timer0.timer0);
|
||||
|
||||
info!("Embassy ok");
|
||||
|
||||
//let timer1 = esp_hal::timer::timg::TimerGroup::new(&mut peripherals.TIMG0);
|
||||
/*let _init = esp_wifi::init(
|
||||
timer1.timer0,
|
||||
esp_hal::rng::Rng::new(&mut peripherals.RNG),
|
||||
peripherals.RADIO_CLK,
|
||||
)
|
||||
.unwrap();*/
|
||||
|
||||
//let system = SystemControl::new(peripherals.SYSTEM);
|
||||
//let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//let io = Io::new(peripherals.IO_MUX);
|
||||
|
||||
//rng::init(peripherals.RNG, peripherals.ADC1);
|
||||
let mut trng = esp_hal::rng::Trng::new(peripherals.RNG, &mut peripherals.ADC1);
|
||||
let seed = {
|
||||
let mut buf = [0; 8];
|
||||
trng.read(&mut buf);
|
||||
u64::from_be_bytes(buf)
|
||||
};
|
||||
let rng = trng.downgrade();
|
||||
|
||||
let sclk = peripherals.GPIO14;
|
||||
let miso = peripherals.GPIO12;
|
||||
let mosi = peripherals.GPIO13;
|
||||
let cs = peripherals.GPIO15;
|
||||
|
||||
let spi = Spi::<Blocking, esp_hal::peripherals::SPI2>::new_typed_with_config(
|
||||
mk_static!(esp_hal::peripherals::SPI2, peripherals.SPI2),
|
||||
spi::master::Config {
|
||||
frequency: 400.kHz(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
.with_miso(miso);
|
||||
let spi = NoopMutex::new(RefCell::new(spi));
|
||||
let spi_dev = SpiDevice::new(
|
||||
mk_static!(
|
||||
NoopMutex<RefCell<Spi<'static, esp_hal::Blocking, esp_hal::peripherals::SPI2>>>,
|
||||
spi
|
||||
),
|
||||
gpio::Output::new_typed(cs, Level::High),
|
||||
);
|
||||
|
||||
info!("SPI ok");
|
||||
|
||||
let delay = Delay::new();
|
||||
#[cfg(feature = "display_epd")]
|
||||
let mut display = display::init(
|
||||
&mut spi_dev,
|
||||
io.pins.gpio18,
|
||||
io.pins.gpio19,
|
||||
io.pins.gpio21,
|
||||
&mut delay,
|
||||
);
|
||||
|
||||
#[cfg(feature = "display_sh1106")]
|
||||
//let mut display = display::init(spi_dev, io.pins.gpio19);
|
||||
let display = sh1106::Builder::new()
|
||||
.connect_spi(
|
||||
spi_dev,
|
||||
gpio::Output::new_typed(peripherals.GPIO19, Level::High),
|
||||
)
|
||||
.into();
|
||||
|
||||
info!("Display ok");
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let (wifi_interface, wifi_controller) =
|
||||
wifi::pre_init(timg0.timer0, rng, peripherals.RADIO_CLK, peripherals.WIFI);
|
||||
|
||||
info!("Wifi pre-init ok");
|
||||
|
||||
/*let timg1 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG1);
|
||||
esp_hal_embassy::init(
|
||||
mk_static!(
|
||||
[OneShotTimer<AnyTimer>; 1],
|
||||
[OneShotTimer::new(AnyTimer::from(timg1.timer0))]
|
||||
),
|
||||
);*/
|
||||
|
||||
#[cfg(feature = "display_sh1106")]
|
||||
let _gpio21 = gpio::Output::new(peripherals.GPIO21, Level::High);
|
||||
#[cfg(feature = "display_sh1106")]
|
||||
spawner.spawn(display::run(display, delay)).ok();
|
||||
#[cfg(feature = "display_epd")]
|
||||
spawner.spawn(display::run(spi_dev, display, delay)).ok();
|
||||
|
||||
let net_stack = wifi::post_init(&spawner, wifi_interface, wifi_controller, seed);
|
||||
info!("Wifi post-init ok");
|
||||
|
||||
let mut rx_buffer = [0; 4096];
|
||||
let mut tx_buffer = [0; 4096];
|
||||
|
||||
'get: loop {
|
||||
Timer::after(Duration::from_millis(1_000)).await;
|
||||
|
||||
let mut socket = TcpSocket::new(&net_stack, &mut rx_buffer, &mut tx_buffer);
|
||||
|
||||
socket.set_timeout(Some(embassy_time::Duration::from_millis(10_000)));
|
||||
|
||||
let remote_endpoint = (Ipv4Address::new(192, 168, 1, 14), 80);
|
||||
println!("conn...");
|
||||
let r = socket.connect(remote_endpoint).await;
|
||||
if let Err(e) = r {
|
||||
println!("conn err: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
println!("conn!");
|
||||
|
||||
/*let mut read_record_buffer = [0; 16384];
|
||||
let mut write_record_buffer = [0; 16384];
|
||||
let tls_config = TlsConfig::new().with_server_name("txmn.tk").with_psk(&[], &[]);
|
||||
let mut tls = TlsConnection::new(socket, &mut read_record_buffer, &mut write_record_buffer);
|
||||
if let Err(e) = tls.open(TlsContext::new(
|
||||
&tls_config,
|
||||
&mut prng,
|
||||
))
|
||||
.await {
|
||||
println!("TLS err: {:?}", e);
|
||||
continue;
|
||||
}*/
|
||||
|
||||
let mut buf = [0; 1024];
|
||||
loop {
|
||||
/*let r = socket
|
||||
.write_all(b"GET /fortune.php?raw HTTP/1.0\r\nHost: txmn.tk\r\n\r\n")
|
||||
.await;
|
||||
if let Err(e) = r {
|
||||
println!("w err: {:?}", e);
|
||||
break;
|
||||
}
|
||||
let n = match socket.read(&mut buf).await {
|
||||
Ok(0) => {
|
||||
println!("EOF");
|
||||
break;
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("r err: {:?}", e);
|
||||
break;
|
||||
}
|
||||
};*/
|
||||
socket
|
||||
.write_all(b"GET /fortune.php?raw HTTP/1.0\r\nHost: txmn.tk\r\n\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
socket.flush().await.unwrap();
|
||||
let n = match socket.read(&mut buf).await {
|
||||
Ok(0) => {
|
||||
println!("EOF");
|
||||
break;
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("r err: {:?}", e);
|
||||
break;
|
||||
}
|
||||
};
|
||||
println!("{}", core::str::from_utf8(&buf[..n]).unwrap());
|
||||
#[cfg(feature = "display_sh1106")]
|
||||
if let Some(content_start) = buf.array_windows().position(|o| o == b"\r\n\r\n") {
|
||||
if let Some(text) = String::from_ascii(&buf[content_start + 4..n]) {
|
||||
display::CHANNEL.send(text).await;
|
||||
}
|
||||
}
|
||||
//break 'get;
|
||||
}
|
||||
Timer::after(Duration::from_millis(5_000)).await;
|
||||
}
|
||||
}
|
||||
1
esp/src/modem.rs
Normal file
1
esp/src/modem.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
13
esp/src/rng.rs
Normal file
13
esp/src/rng.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use core::cell::OnceCell;
|
||||
use embassy_sync::{mutex::Mutex, blocking_mutex::NoopMutex};
|
||||
use esp_hal::{peripherals::Peripherals, rng::Trng};
|
||||
|
||||
static TRNG: OnceCell<Mutex<NoopMutex<Trng>, Trng>> = OnceCell::new();
|
||||
|
||||
pub fn init(rng: Peripherals::RNG, adc1: Peripherals::ADC1) {
|
||||
TRNG.set(Mutex::new(Trng::new(peripherals.RNG, &mut peripherals.ADC1))).unwrap();
|
||||
}
|
||||
|
||||
pub async fn randomize(buf: &mut [u8]) {
|
||||
TRNG.get().expect("no RNG").lock().await.read(buf)
|
||||
}
|
||||
45
esp/src/string.rs
Normal file
45
esp/src/string.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
use core::{mem::MaybeUninit, str::from_utf8_unchecked};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct String<const N: usize> {
|
||||
buf: [u8; N],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<const N: usize> String<N> {
|
||||
pub fn from_str(s: &str) -> Self {
|
||||
let mut buf = [0; N];
|
||||
buf[0..s.as_bytes().len()].copy_from_slice(s.as_bytes());
|
||||
Self { len: s.len(), buf }
|
||||
}
|
||||
|
||||
pub fn from_ascii(s: &[u8]) -> Option<Self> {
|
||||
if s.len() < N && s.is_ascii() {
|
||||
let mut buf = [0; N];
|
||||
buf[0..s.len()].copy_from_slice(s);
|
||||
Some(Self { len: s.len(), buf })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_buf_ascii(buf: [u8; N], len: usize) -> Option<Self> {
|
||||
if len < N && buf[0..len].is_ascii() {
|
||||
Some(Self { buf, len })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> AsRef<str> for String<N> {
|
||||
fn as_ref(&self) -> &str {
|
||||
unsafe { core::str::from_utf8_unchecked(&self.buf[0..self.len]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> AsMut<str> for String<N> {
|
||||
fn as_mut(&mut self) -> &mut str {
|
||||
unsafe { core::str::from_utf8_unchecked_mut(&mut self.buf[0..self.len]) }
|
||||
}
|
||||
}
|
||||
8
esp/src/util.rs
Normal file
8
esp/src/util.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
macro_rules! mk_static {
|
||||
($t:ty, $val:expr) => {{
|
||||
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||
#[deny(unused_attributes)]
|
||||
let x = STATIC_CELL.uninit().write(($val));
|
||||
x
|
||||
}};
|
||||
}
|
||||
112
esp/src/wifi.rs
Normal file
112
esp/src/wifi.rs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
//use crate::rng::randomize;
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::{peripheral::Peripheral, rng::Rng};
|
||||
use esp_println::println;
|
||||
use esp_wifi::{
|
||||
wifi::{WifiController, WifiDevice, WifiEvent, WifiStaDevice, WifiState},
|
||||
EspWifiController, EspWifiTimerSource,
|
||||
};
|
||||
use static_cell::StaticCell;
|
||||
|
||||
const SSID: &str = include_str!("../wifi-ssid.txt");
|
||||
const PASSWORD: &str = include_str!("../wifi-psw.txt");
|
||||
|
||||
static WIFI_CONTROLLER: StaticCell<WifiController> = StaticCell::new();
|
||||
|
||||
pub fn pre_init<'d, T: EspWifiTimerSource>(
|
||||
timer: impl Peripheral<P = T> + 'static,
|
||||
rng: Rng,
|
||||
radio_clk: esp_hal::peripherals::RADIO_CLK,
|
||||
wifi: esp_hal::peripherals::WIFI,
|
||||
) -> (
|
||||
WifiDevice<'static, WifiStaDevice>,
|
||||
&'static mut WifiController<'static>,
|
||||
) {
|
||||
let wifi_init = esp_wifi::init(timer, rng, radio_clk).unwrap();
|
||||
|
||||
let wifi_init = mk_static!(EspWifiController, wifi_init);
|
||||
|
||||
let (wifi_interface, wifi_controller) =
|
||||
esp_wifi::wifi::new_with_mode(wifi_init, wifi, WifiStaDevice).unwrap();
|
||||
(wifi_interface, WIFI_CONTROLLER.init(wifi_controller))
|
||||
}
|
||||
|
||||
pub fn post_init(
|
||||
spawner: &Spawner,
|
||||
interface: WifiDevice<'static, WifiStaDevice>,
|
||||
controller: &'static mut WifiController,
|
||||
seed: u64,
|
||||
) -> &'static embassy_net::Stack<WifiDevice<'static, WifiStaDevice>> {
|
||||
let net_stack = &*mk_static!(
|
||||
embassy_net::Stack<WifiDevice<'_, WifiStaDevice>>,
|
||||
embassy_net::Stack::new(
|
||||
interface,
|
||||
embassy_net::Config::dhcpv4(Default::default()),
|
||||
mk_static!(
|
||||
embassy_net::StackResources<3>,
|
||||
embassy_net::StackResources::<3>::new()
|
||||
),
|
||||
seed
|
||||
)
|
||||
);
|
||||
|
||||
spawner.spawn(connection(controller, &net_stack)).ok();
|
||||
spawner.spawn(net_task(&net_stack)).ok();
|
||||
net_stack
|
||||
}
|
||||
|
||||
/// Connection task
|
||||
///
|
||||
/// Reconnects automatically when needed.
|
||||
#[embassy_executor::task]
|
||||
pub async fn connection(
|
||||
controller: &'static mut WifiController<'static>,
|
||||
stack: &'static embassy_net::Stack<WifiDevice<'static, WifiStaDevice>>,
|
||||
) {
|
||||
loop {
|
||||
match esp_wifi::wifi::wifi_state() {
|
||||
WifiState::StaConnected => {
|
||||
controller.wait_for_event(WifiEvent::StaDisconnected).await;
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if !matches!(controller.is_started(), Ok(true)) {
|
||||
let client_config =
|
||||
esp_wifi::wifi::Configuration::Client(esp_wifi::wifi::ClientConfiguration {
|
||||
ssid: SSID.try_into().unwrap(),
|
||||
password: PASSWORD.try_into().unwrap(),
|
||||
auth_method: esp_wifi::wifi::AuthMethod::WPA2Personal,
|
||||
..Default::default()
|
||||
});
|
||||
controller.set_configuration(&client_config).unwrap();
|
||||
controller.start_async().await.unwrap();
|
||||
}
|
||||
|
||||
match controller.connect_async().await {
|
||||
Ok(_) => {
|
||||
while !stack.is_link_up() {
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
loop {
|
||||
if let Some(config) = stack.config_v4() {
|
||||
println!("IP {}", config.address);
|
||||
break;
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Wifi err: {e:?}");
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn net_task(stack: &'static embassy_net::Stack<WifiDevice<'static, WifiStaDevice>>) {
|
||||
stack.run().await
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue