Compare commits
8 Commits
329eb6db04
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
7dee29b581
|
|||
|
03b6e01bd8
|
|||
|
8603d6fab4
|
|||
|
d3e915575f
|
|||
|
14f17d49df
|
|||
|
01738df95c
|
|||
|
2f89c58f95
|
|||
|
032d785d60
|
80
Cargo.lock
generated
80
Cargo.lock
generated
@@ -13,8 +13,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "air_filter"
|
||||
version = "0.4.0"
|
||||
version = "0.4.5"
|
||||
dependencies = [
|
||||
"air_filter_types",
|
||||
"bme280",
|
||||
"cfg-if",
|
||||
"const_format",
|
||||
@@ -49,6 +50,15 @@ dependencies = [
|
||||
"updater",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "air_filter_types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bme280",
|
||||
"defmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
@@ -123,9 +133,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.7.0"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@@ -351,9 +361,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.6.0"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||
checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f"
|
||||
|
||||
[[package]]
|
||||
name = "debug-helper"
|
||||
@@ -648,9 +658,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "embassy-sync"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3899a6e39fa3f54bf8aaf00979f9f9c0145a522f7244810533abbb748be6ce82"
|
||||
checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"critical-section",
|
||||
@@ -1008,9 +1018,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.0"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@@ -1018,13 +1028,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
|
||||
checksum = "3f187290c0ed3dfe3f7c85bedddd320949b68fc86ca0ceb71adfb05b3dc3af2a"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1085,7 +1095,7 @@ version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -1107,9 +1117,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.24"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
@@ -1284,8 +1294,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "picoserve"
|
||||
version = "0.13.3"
|
||||
source = "git+https://github.com/hodasemi/picoserve#c4fe40eccfcd1188f117d4b7c689f6dc48c94d44"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2c9a99cfe7a070728554f1d42f62067937ce30f9b057a6b507e0cc14fe96e9"
|
||||
dependencies = [
|
||||
"const-sha1",
|
||||
"data-encoding",
|
||||
@@ -1296,9 +1307,22 @@ dependencies = [
|
||||
"futures-util",
|
||||
"heapless",
|
||||
"lhash",
|
||||
"picoserve_derive",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde-json-core",
|
||||
"thiserror 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "picoserve_derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62ba0d83906d0357fedd23de7c5e3a5235342c248cc1d954d43d5e7b455c375c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1436,9 +1460,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1449,7 +1473,7 @@ version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"bitflags 2.8.0",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
@@ -1495,7 +1519,7 @@ version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1889,7 +1913,8 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "updater"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
source = "git+https://git.huizinga.dev/Dreaded_X/iot_tools?tag=v0.3.0#b8e543b97261ba358b14c8088e55e6425a13c8a8"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"defmt",
|
||||
@@ -1960,7 +1985,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1969,15 +1994,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
|
||||
19
Cargo.toml
19
Cargo.toml
@@ -1,12 +1,18 @@
|
||||
[package]
|
||||
name = "air_filter"
|
||||
version = "0.4.0"
|
||||
version = "0.4.5"
|
||||
edition = "2021"
|
||||
|
||||
[workspace.dependencies]
|
||||
defmt = "0.3"
|
||||
bme280 = { version = "0.5.0", features = ["async", "defmt"] }
|
||||
serde = { version = "1.0", default-features = false, features = ["derive"] }
|
||||
|
||||
[dependencies]
|
||||
air_filter_types = { path = "./air_filter_types/" }
|
||||
cortex-m = { version = "0.7", features = ["inline-asm"] }
|
||||
cortex-m-rt = "0.7"
|
||||
defmt = "0.3"
|
||||
defmt = { workspace = true }
|
||||
defmt-rtt = "0.4"
|
||||
embassy-embedded-hal = { version = "0.3.0", features = ["defmt"] }
|
||||
embassy-executor = { version = "0.7", features = [
|
||||
@@ -58,7 +64,7 @@ rust-mqtt = { version = "0.3", features = [
|
||||
], default-features = false }
|
||||
const_format = "0.2"
|
||||
git-version = "0.3"
|
||||
serde = { version = "1.0", default-features = false, features = ["derive"] }
|
||||
serde = { workspace = true }
|
||||
heapless = { version = "0.8", features = ["defmt-03", "serde"] }
|
||||
nourl = { version = "0.1", features = ["defmt"] }
|
||||
# Embassy hardcodes a max of 6 dns servers, if there are more it crashes. This is a workaround
|
||||
@@ -67,16 +73,15 @@ nourl = { version = "0.1", features = ["defmt"] }
|
||||
smoltcp = { version = "0.12", default-features = false, features = [
|
||||
"dns-max-server-count-4",
|
||||
] }
|
||||
updater = { version = "0.1.0", path = "../iot_tools/updater" }
|
||||
updater = { git = "https://git.huizinga.dev/Dreaded_X/iot_tools", tag = "v0.3.0" }
|
||||
portable-atomic = { version = "1.6", features = ["critical-section"] }
|
||||
bme280 = { version = "0.5.0", features = ["async", "defmt"] }
|
||||
picoserve = { version = "0.13.3", features = ["defmt", "embassy"] }
|
||||
bme280 = { workspace = true }
|
||||
picoserve = { version = "0.14", features = ["defmt", "embassy"] }
|
||||
embedded-storage = "0.3"
|
||||
|
||||
[patch.crates-io]
|
||||
# Make mqtt:// and mqtts:// actually work
|
||||
nourl = { git = "https://git.huizinga.dev/Dreaded_X/nourl" }
|
||||
picoserve = { git = "https://github.com/hodasemi/picoserve" }
|
||||
|
||||
[features]
|
||||
include_firmwares = []
|
||||
|
||||
9
air_filter_types/Cargo.toml
Normal file
9
air_filter_types/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "air_filter_types"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bme280 = { workspace = true }
|
||||
defmt = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
@@ -15,7 +15,7 @@ pub enum FanSpeed {
|
||||
High,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct FanState {
|
||||
pub speed: FanSpeed,
|
||||
@@ -26,20 +26,32 @@ impl FanState {
|
||||
pub fn new(speed: FanSpeed, manual: bool) -> Self {
|
||||
Self { speed, manual }
|
||||
}
|
||||
|
||||
pub fn speed(&self) -> FanSpeed {
|
||||
self.speed
|
||||
}
|
||||
|
||||
pub fn manual(&self) -> bool {
|
||||
self.manual
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SetFanSpeed {
|
||||
speed: FanSpeed,
|
||||
}
|
||||
|
||||
impl SetFanSpeed {
|
||||
pub fn new(speed: FanSpeed) -> Self {
|
||||
Self { speed }
|
||||
}
|
||||
|
||||
pub fn speed(&self) -> FanSpeed {
|
||||
self.speed
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SensorData {
|
||||
temperature: f32,
|
||||
humidity: f32,
|
||||
@@ -54,4 +66,16 @@ impl SensorData {
|
||||
pressure: measurements.pressure,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn temperature(&self) -> f32 {
|
||||
self.temperature
|
||||
}
|
||||
|
||||
pub fn humidity(&self) -> f32 {
|
||||
self.humidity
|
||||
}
|
||||
|
||||
pub fn pressure(&self) -> f32 {
|
||||
self.pressure
|
||||
}
|
||||
}
|
||||
223
src/main.rs
223
src/main.rs
@@ -1,9 +1,11 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use core::{cell::RefCell, str::FromStr};
|
||||
use core::{cell::RefCell, net::Ipv4Addr, str::FromStr};
|
||||
|
||||
use approuter::{AppRouter, AppState};
|
||||
use bme280::i2c::AsyncBME280;
|
||||
use cyw43::{JoinOptions, PowerManagementMode};
|
||||
use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER};
|
||||
@@ -11,13 +13,13 @@ use defmt::{debug, info, warn};
|
||||
use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
|
||||
use embassy_embedded_hal::flash::partition::BlockingPartition;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{Config, DhcpConfig, StackResources};
|
||||
use embassy_net::{tcp::TcpSocket, Config, DhcpConfig, Stack, StackResources};
|
||||
use embassy_rp::{
|
||||
bind_interrupts,
|
||||
clocks::RoscRng,
|
||||
flash::{Flash, WRITE_SIZE},
|
||||
gpio::{Flex, Input, Level, Output, Pin, Pull},
|
||||
i2c::{self, Async},
|
||||
i2c::{self},
|
||||
peripherals::{DMA_CH1, FLASH, I2C0, PIO0},
|
||||
pio::{self, Pio},
|
||||
Peripheral,
|
||||
@@ -31,26 +33,19 @@ use embassy_sync::{
|
||||
};
|
||||
use embassy_time::{Delay, Duration, Timer};
|
||||
use heapless::String;
|
||||
use picoserve::{
|
||||
extract, make_static,
|
||||
routing::{get, PathRouter},
|
||||
Router,
|
||||
};
|
||||
use picoserve::{make_static, Router};
|
||||
use rand::{rngs::StdRng, RngCore, SeedableRng};
|
||||
use static_cell::StaticCell;
|
||||
use updater::firmware_router;
|
||||
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
use air_filter::{FanSpeed, FanState, SensorData, SetFanSpeed};
|
||||
use air_filter_types::{FanSpeed, FanState};
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
PIO0_IRQ_0 => pio::InterruptHandler<PIO0>;
|
||||
I2C0_IRQ => i2c::InterruptHandler<I2C0>;
|
||||
});
|
||||
|
||||
const VERSION: &str = git_version::git_version!();
|
||||
const PUBLIC_SIGNING_KEY: &[u8; 32] = include_bytes!("../key.pub");
|
||||
const FLASH_SIZE: usize = 2 * 1024 * 1024;
|
||||
|
||||
struct Controller<'a> {
|
||||
@@ -156,39 +151,94 @@ impl<'a> Controller<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct SharedController(&'static Mutex<CriticalSectionRawMutex, Controller<'static>>);
|
||||
// We need this because otherwise the compiler yells at us
|
||||
mod approuter {
|
||||
use air_filter_types::{SensorData, SetFanSpeed};
|
||||
use bme280::i2c::AsyncBME280;
|
||||
use defmt::debug;
|
||||
use embassy_boot::BlockingFirmwareUpdater;
|
||||
use embassy_rp::{
|
||||
i2c::{Async, I2c},
|
||||
peripherals::I2C0,
|
||||
};
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
|
||||
use embassy_time::Delay;
|
||||
use picoserve::{
|
||||
extract, make_static,
|
||||
routing::{get, PathRouter},
|
||||
Router,
|
||||
};
|
||||
use updater::firmware_router;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct SharedBME280(
|
||||
&'static Mutex<CriticalSectionRawMutex, AsyncBME280<i2c::I2c<'static, I2C0, Async>>>,
|
||||
);
|
||||
use crate::{Controller, Partition};
|
||||
|
||||
struct AppState {
|
||||
shared_controller: SharedController,
|
||||
shared_bme280: SharedBME280,
|
||||
}
|
||||
const VERSION: &str = git_version::git_version!();
|
||||
const PUBLIC_SIGNING_KEY: &[u8; 32] = include_bytes!("../key.pub");
|
||||
|
||||
impl picoserve::extract::FromRef<AppState> for SharedController {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.shared_controller
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SharedController(pub &'static Mutex<CriticalSectionRawMutex, Controller<'static>>);
|
||||
|
||||
impl SharedController {
|
||||
fn new(controller: Controller<'static>) -> Self {
|
||||
Self(
|
||||
make_static!(Mutex<CriticalSectionRawMutex, Controller<'static>>, Mutex::new(controller)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl picoserve::extract::FromRef<AppState> for SharedBME280 {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.shared_bme280
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SharedBME280(
|
||||
pub &'static Mutex<CriticalSectionRawMutex, AsyncBME280<I2c<'static, I2C0, Async>>>,
|
||||
);
|
||||
|
||||
impl SharedBME280 {
|
||||
fn new(bme280: AsyncBME280<I2c<'static, I2C0, Async>>) -> Self {
|
||||
Self(
|
||||
make_static!(Mutex<CriticalSectionRawMutex, AsyncBME280<I2c<'static, I2C0, Async>>>, Mutex::new(bme280)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn state_router() -> Router<impl PathRouter<AppState>, AppState> {
|
||||
Router::new()
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub shared_controller: SharedController,
|
||||
pub shared_bme280: SharedBME280,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
pub fn new(
|
||||
controller: Controller<'static>,
|
||||
bme280: AsyncBME280<I2c<'static, I2C0, Async>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
shared_controller: SharedController::new(controller),
|
||||
shared_bme280: SharedBME280::new(bme280),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl picoserve::extract::FromRef<AppState> for SharedController {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.shared_controller
|
||||
}
|
||||
}
|
||||
|
||||
impl picoserve::extract::FromRef<AppState> for SharedBME280 {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.shared_bme280
|
||||
}
|
||||
}
|
||||
|
||||
fn state_router() -> Router<impl PathRouter<AppState>, AppState> {
|
||||
Router::new()
|
||||
.route(
|
||||
"/fan",
|
||||
get(
|
||||
|extract::State(SharedController(controller)): extract::State<
|
||||
SharedController,
|
||||
>| async {
|
||||
debug!("Getting fan state");
|
||||
|
||||
let state = controller.lock().await.get_state();
|
||||
picoserve::response::Json(state)
|
||||
},
|
||||
@@ -198,6 +248,8 @@ fn state_router() -> Router<impl PathRouter<AppState>, AppState> {
|
||||
SharedController,
|
||||
>,
|
||||
extract::Json(message): extract::Json<SetFanSpeed>| async move {
|
||||
debug!("Setting fan state");
|
||||
|
||||
let success = controller.lock().await.set_speed(message.speed());
|
||||
|
||||
if success {
|
||||
@@ -212,6 +264,8 @@ fn state_router() -> Router<impl PathRouter<AppState>, AppState> {
|
||||
"/sensor",
|
||||
get(
|
||||
|extract::State(SharedBME280(bme280)): extract::State<SharedBME280>| async {
|
||||
debug!("Getting sensor state");
|
||||
|
||||
let measurement = bme280
|
||||
.lock()
|
||||
.await
|
||||
@@ -224,6 +278,20 @@ fn state_router() -> Router<impl PathRouter<AppState>, AppState> {
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub type AppRouter = impl PathRouter<AppState>;
|
||||
pub fn make_app(
|
||||
updater: &'static Mutex<
|
||||
CriticalSectionRawMutex,
|
||||
BlockingFirmwareUpdater<'static, Partition, Partition>,
|
||||
>,
|
||||
) -> Router<AppRouter, AppState> {
|
||||
Router::new().nest("/state", state_router()).nest(
|
||||
"/firmware",
|
||||
firmware_router(VERSION, updater, PUBLIC_SIGNING_KEY),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the cyw43 firmware blobs
|
||||
@@ -268,16 +336,45 @@ async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'sta
|
||||
runner.run().await
|
||||
}
|
||||
|
||||
type Thingy = BlockingPartition<
|
||||
type Partition = BlockingPartition<
|
||||
'static,
|
||||
NoopRawMutex,
|
||||
Flash<'static, FLASH, embassy_rp::flash::Blocking, FLASH_SIZE>,
|
||||
>;
|
||||
|
||||
const WEB_TASK_POOL_SIZE: usize = 8;
|
||||
|
||||
#[embassy_executor::task(pool_size = WEB_TASK_POOL_SIZE)]
|
||||
async fn web_task(
|
||||
id: usize,
|
||||
stack: Stack<'static>,
|
||||
app: &'static Router<AppRouter, AppState>,
|
||||
config: &'static picoserve::Config<Duration>,
|
||||
state: AppState,
|
||||
) -> ! {
|
||||
let port = 80;
|
||||
let mut tcp_rx_buffer = [0; 1024];
|
||||
let mut tcp_tx_buffer = [0; 1024];
|
||||
let mut http_buffer = [0; 2048];
|
||||
|
||||
picoserve::listen_and_serve_with_state(
|
||||
id,
|
||||
app,
|
||||
config,
|
||||
stack,
|
||||
port,
|
||||
&mut tcp_rx_buffer,
|
||||
&mut tcp_tx_buffer,
|
||||
&mut http_buffer,
|
||||
&state,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn fan_task(shared_controller: SharedController) -> ! {
|
||||
async fn controller_task(state: AppState) {
|
||||
loop {
|
||||
shared_controller.0.lock().await.check_for_manual();
|
||||
state.shared_controller.0.lock().await.check_for_manual();
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
}
|
||||
@@ -293,7 +390,7 @@ async fn main(spawner: Spawner) {
|
||||
let config = FirmwareUpdaterConfig::from_linkerfile_blocking(flash, flash);
|
||||
let aligned = make_static!(AlignedBuffer<WRITE_SIZE>, AlignedBuffer([0; WRITE_SIZE]));
|
||||
let updater = BlockingFirmwareUpdater::new(config, &mut aligned.0);
|
||||
let updater = make_static!(Mutex<CriticalSectionRawMutex, BlockingFirmwareUpdater<'static, Thingy, Thingy>>, Mutex::new(updater));
|
||||
let updater = make_static!(Mutex<CriticalSectionRawMutex, BlockingFirmwareUpdater<'static, Partition, Partition>>, Mutex::new(updater));
|
||||
|
||||
let controller = Controller::new(p.PIN_28, p.PIN_27, p.PIN_26, p.PIN_22);
|
||||
|
||||
@@ -340,7 +437,7 @@ async fn main(spawner: Spawner) {
|
||||
// cryptographically secure PRNG
|
||||
let mut rng = StdRng::from_rng(&mut RoscRng).unwrap();
|
||||
|
||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||
static RESOURCES: StaticCell<StackResources<16>> = StaticCell::new();
|
||||
let (stack, runner) = embassy_net::new(
|
||||
net_device,
|
||||
config,
|
||||
@@ -392,39 +489,29 @@ async fn main(spawner: Spawner) {
|
||||
.keep_connection_alive()
|
||||
);
|
||||
|
||||
let app = Router::new().nest("/state", state_router()).nest(
|
||||
"/firmware",
|
||||
firmware_router(VERSION, updater, PUBLIC_SIGNING_KEY),
|
||||
);
|
||||
let app = make_static!(Router<AppRouter, AppState>, approuter::make_app(updater));
|
||||
|
||||
let shared_controller = SharedController(
|
||||
make_static!(Mutex<CriticalSectionRawMutex, Controller<'static>>, Mutex::new(controller)),
|
||||
);
|
||||
let shared_bme280 = SharedBME280(
|
||||
make_static!(Mutex<CriticalSectionRawMutex, AsyncBME280<i2c::I2c<'static, I2C0, Async>>>, Mutex::new(bme280)),
|
||||
);
|
||||
let state = AppState::new(controller, bme280);
|
||||
|
||||
let port = 80;
|
||||
let mut tcp_rx_buffer = [0; 1024];
|
||||
let mut tcp_tx_buffer = [0; 1024];
|
||||
let mut http_buffer = [0; 2048];
|
||||
for id in 0..WEB_TASK_POOL_SIZE {
|
||||
spawner.must_spawn(web_task(id, stack, app, config, state.clone()));
|
||||
}
|
||||
|
||||
spawner.must_spawn(fan_task(shared_controller));
|
||||
spawner.must_spawn(controller_task(state));
|
||||
|
||||
// We can only handle one request at a time
|
||||
picoserve::listen_and_serve_with_state(
|
||||
0,
|
||||
&app,
|
||||
config,
|
||||
stack,
|
||||
port,
|
||||
&mut tcp_rx_buffer,
|
||||
&mut tcp_tx_buffer,
|
||||
&mut http_buffer,
|
||||
&AppState {
|
||||
shared_controller,
|
||||
shared_bme280,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let mut rx_buffer = [0; 4096];
|
||||
let mut tx_buffer = [0; 4096];
|
||||
|
||||
loop {
|
||||
// TODO: In the future, use reqless to push the current state to automation_rs
|
||||
control.gpio_set(0, true).await;
|
||||
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||
socket.set_timeout(Some(Duration::from_secs(1)));
|
||||
socket
|
||||
.connect(("10.0.0.2".parse::<Ipv4Addr>().unwrap(), 80))
|
||||
.await
|
||||
.ok();
|
||||
control.gpio_set(0, false).await;
|
||||
Timer::after(Duration::from_secs(60)).await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user