feat: Add L76K GNSS
This commit is contained in:
parent
c589605407
commit
919065f377
3 changed files with 205 additions and 8 deletions
69
Cargo.lock
generated
69
Cargo.lock
generated
|
|
@ -17,6 +17,12 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d"
|
checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -92,6 +98,15 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-default"
|
name = "const-default"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
@ -425,6 +440,21 @@ dependencies = [
|
||||||
"heapless 0.9.2",
|
"heapless 0.9.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embassy_gps"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/jbeyerstedt/embassy_gps.git?branch=feat%2Frework-gpsfix#75f1a67a69372234330c0c9618a953c415380b99"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"embassy-futures",
|
||||||
|
"embassy-time",
|
||||||
|
"embedded-io-async 0.7.0",
|
||||||
|
"esp-hal",
|
||||||
|
"heapless 0.9.2",
|
||||||
|
"log",
|
||||||
|
"nmea",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-can"
|
name = "embedded-can"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
|
@ -903,9 +933,11 @@ dependencies = [
|
||||||
name = "esp32-c_its-companion"
|
name = "esp32-c_its-companion"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
|
"embassy_gps",
|
||||||
"embedded-io 0.7.1",
|
"embedded-io 0.7.1",
|
||||||
"embedded-io-async 0.7.0",
|
"embedded-io-async 0.7.0",
|
||||||
"esp-alloc",
|
"esp-alloc",
|
||||||
|
|
@ -1183,6 +1215,12 @@ version = "0.2.186"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked_list_allocator"
|
name = "linked_list_allocator"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
|
@ -1229,6 +1267,12 @@ version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nb"
|
name = "nb"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
@ -1244,6 +1288,30 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nmea"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2086c773d18da556c05ca235596d163c00379027189bafe2209ae40ebd19717c"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"cfg-if",
|
||||||
|
"chrono",
|
||||||
|
"heapless 0.8.0",
|
||||||
|
"nom",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-ansi-term"
|
name = "nu-ansi-term"
|
||||||
version = "0.50.3"
|
version = "0.50.3"
|
||||||
|
|
@ -1271,6 +1339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ esp-radio = { version = "0.18.0", features = [
|
||||||
"sniffer",
|
"sniffer",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
|
embassy_gps = { version = "0.1.0", default-features = false, features = ["esp", "log-04"], git = "https://github.com/jbeyerstedt/embassy_gps.git", branch = "feat/rework-gpsfix" }
|
||||||
|
chrono = { version = "0.4.44", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
|
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|
|
||||||
140
src/main.rs
140
src/main.rs
|
|
@ -5,10 +5,13 @@
|
||||||
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
|
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
|
||||||
holding buffers for the duration of a data transfer."
|
holding buffers for the duration of a data transfer."
|
||||||
)]
|
)]
|
||||||
#![deny(clippy::large_stack_frames)]
|
// #![deny(clippy::large_stack_frames)]
|
||||||
|
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
|
use critical_section::Mutex;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_gps::gps::l76k;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::timer::timg::TimerGroup;
|
use esp_hal::timer::timg::TimerGroup;
|
||||||
|
|
@ -21,10 +24,68 @@ mod radio;
|
||||||
|
|
||||||
const WIFI_CHANNEL: radio::Channel = 180;
|
const WIFI_CHANNEL: radio::Channel = 180;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct State {
|
||||||
|
initialized: bool,
|
||||||
|
time: chrono::NaiveDateTime,
|
||||||
|
|
||||||
|
lat_deg: f32,
|
||||||
|
lon_deg: f32,
|
||||||
|
heading_deg: Option<f32>,
|
||||||
|
speed_mps: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
fn update_with_gpsfix(&mut self, fix: &embassy_gps::types::GpsFix) {
|
||||||
|
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
|
||||||
|
let lat_deg = fix.latitude_deg as f32;
|
||||||
|
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
|
||||||
|
let lon_deg = fix.longitude_deg as f32;
|
||||||
|
|
||||||
|
self.lat_deg = lat_deg;
|
||||||
|
self.lon_deg = lon_deg;
|
||||||
|
|
||||||
|
if let Some(heading) = fix.true_course_deg {
|
||||||
|
self.heading_deg = Some(heading);
|
||||||
|
} else {
|
||||||
|
warn!("State: Course missing from GpsFix");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(speed) = fix.speed_over_ground {
|
||||||
|
self.speed_mps = Some(speed);
|
||||||
|
} else {
|
||||||
|
warn!("State: Speed missing from GpsFix");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(time) = fix.get_timestamp() {
|
||||||
|
self.time = time;
|
||||||
|
|
||||||
|
if !self.initialized {
|
||||||
|
info!("GNSS fix: {}", self.print_fix());
|
||||||
|
}
|
||||||
|
self.initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_fix(&self) -> alloc::string::String {
|
||||||
|
alloc::format!(
|
||||||
|
"{:?}, {:.4} N, {:.4} E, {:.0}°, {:.2} m/s",
|
||||||
|
self.time,
|
||||||
|
self.lat_deg,
|
||||||
|
self.lon_deg,
|
||||||
|
self.heading_deg.unwrap_or_default(),
|
||||||
|
self.speed_mps.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This creates a default app-descriptor required by the esp-idf bootloader.
|
// This creates a default app-descriptor required by the esp-idf bootloader.
|
||||||
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
||||||
esp_bootloader_esp_idf::esp_app_desc!();
|
esp_bootloader_esp_idf::esp_app_desc!();
|
||||||
|
|
||||||
|
static GNSS_UPDATE: Mutex<RefCell<Option<embassy_gps::types::GpsFix>>> =
|
||||||
|
Mutex::new(RefCell::new(None));
|
||||||
|
|
||||||
#[allow(
|
#[allow(
|
||||||
clippy::large_stack_frames,
|
clippy::large_stack_frames,
|
||||||
reason = "it's not unusual to allocate larger buffers etc. in main"
|
reason = "it's not unusual to allocate larger buffers etc. in main"
|
||||||
|
|
@ -70,13 +131,39 @@ async fn main(spawner: Spawner) -> ! {
|
||||||
|
|
||||||
info!("WiFi promiscuous mode on channel {WIFI_CHANNEL} running");
|
info!("WiFi promiscuous mode on channel {WIFI_CHANNEL} running");
|
||||||
|
|
||||||
// TODO: Spawn some tasks
|
// Seeed XIAO L67K:
|
||||||
let _ = spawner;
|
// RX: D7/ GPIO12
|
||||||
|
// TX: D6/ GPIO11
|
||||||
|
// WAKEUP: D0/ GPIO1 -> HIGH for active, LOW for Sleep
|
||||||
|
// RESET: D2/ GPIO25 -> HIGH for normal, LOW for Reset
|
||||||
|
spawner.spawn(
|
||||||
|
gnss_task(
|
||||||
|
peripherals.GPIO1,
|
||||||
|
peripherals.GPIO25,
|
||||||
|
peripherals.UART0,
|
||||||
|
peripherals.GPIO12,
|
||||||
|
peripherals.GPIO11,
|
||||||
|
)
|
||||||
|
.expect("Failed to spawn GNSS task"),
|
||||||
|
);
|
||||||
|
info!("GNSS task started, waiting for GNSS fix...");
|
||||||
|
|
||||||
|
let mut state = State::default();
|
||||||
loop {
|
loop {
|
||||||
// nothing to do here, all data is handled in RX callback for now
|
embassy_time::Timer::after(embassy_time::Duration::from_millis(100)).await;
|
||||||
// but use a timer so that this is yields to other tasks
|
|
||||||
Timer::after(Duration::from_secs(1)).await;
|
critical_section::with(|cs| {
|
||||||
|
let gnss_update_ref = GNSS_UPDATE.borrow(cs);
|
||||||
|
|
||||||
|
if let Some(fix) = gnss_update_ref.replace(None) {
|
||||||
|
state.update_with_gpsfix(&fix);
|
||||||
|
|
||||||
|
if let Some(time) = fix.get_timestamp() {
|
||||||
|
state.time = time;
|
||||||
|
info!("{}", state.print_fix()); // TODO: degrate to debug later?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,3 +186,42 @@ fn handle_frame(frame: wifi::sniffer::PromiscuousPkt<'_>) {
|
||||||
// TODO: handle 802.11 frame
|
// TODO: handle 802.11 frame
|
||||||
info!("Received frame with {} bytes", frame.len);
|
info!("Received frame with {} bytes", frame.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_stack_frames, reason = "GNSS driver needs some space")]
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn gnss_task(
|
||||||
|
gps_wakeup: esp_hal::peripherals::GPIO1<'static>,
|
||||||
|
gps_reset: esp_hal::peripherals::GPIO25<'static>,
|
||||||
|
uart: esp_hal::peripherals::UART0<'static>,
|
||||||
|
uart_rx: esp_hal::peripherals::GPIO12<'static>,
|
||||||
|
uart_tx: esp_hal::peripherals::GPIO11<'static>,
|
||||||
|
) {
|
||||||
|
use embassy_gps::gps::GpsFsm;
|
||||||
|
|
||||||
|
let mut gps = l76k::esp::L76kFsm::new_sep(
|
||||||
|
l76k::esp::GpsHw {
|
||||||
|
reinit: gps_reset,
|
||||||
|
standby: gps_wakeup,
|
||||||
|
},
|
||||||
|
|| {
|
||||||
|
esp_hal::uart::Uart::new(uart, esp_hal::uart::Config::default().with_baudrate(9600))
|
||||||
|
.expect("Failed to create UART for GNSS")
|
||||||
|
.with_rx(uart_rx)
|
||||||
|
.with_tx(uart_tx)
|
||||||
|
.into_async()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Ok(Some(embassy_gps::types::GpsEvent::Fix(fix))) = gps.step().await {
|
||||||
|
// send to main thread
|
||||||
|
critical_section::with(|cs| {
|
||||||
|
let gnss_update_ref = GNSS_UPDATE.borrow(cs);
|
||||||
|
gnss_update_ref.replace(Some(fix));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// FSM will recover automatically from errors and ignore other event types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue