factory, ota: add ota led status

main app blinks orange while downloading update to sd card
factory app does a solid orange while writing the update from the sdcard to flash
This commit is contained in:
decentclock
2022-09-28 17:22:56 -04:00
parent 7d39855751
commit fcdd2ace7f
6 changed files with 70 additions and 17 deletions

41
factory/src/led.rs Normal file
View File

@@ -0,0 +1,41 @@
use embedded_hal::blocking::delay::DelayMs;
use esp_idf_hal::delay::Ets;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::rmt::config::TransmitConfig;
use esp_idf_hal::rmt::{FixedLengthSignal, PinState, Pulse, Transmit};
use std::time::Duration;
pub fn set_ota_led() {
let peripherals = Peripherals::take().unwrap();
let led = peripherals.pins.gpio8.into_output().unwrap();
let channel = peripherals.rmt.channel0;
let config = TransmitConfig::new().clock_divider(1);
let mut tx = Transmit::new(led, channel, &config).unwrap();
let rgb = 0xffa500; // Orange
let ticks_hz = tx.counter_clock().unwrap();
let t0h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(350)).unwrap();
let t0l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(800)).unwrap();
let t1h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(700)).unwrap();
let t1l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(600)).unwrap();
let mut signal = FixedLengthSignal::<24>::new();
for i in 0..24 {
let bit = 2_u32.pow(i) & rotate_rgb(rgb) != 0;
let (high_pulse, low_pulse) = if bit { (t1h, t1l) } else { (t0h, t0l) };
signal.set(i as usize, &(high_pulse, low_pulse)).unwrap();
}
tx.start_blocking(&signal).unwrap();
Ets.delay_ms(10u8);
}
fn ns(nanos: u64) -> Duration {
Duration::from_nanos(nanos)
}
fn rotate_rgb(rgb: u32) -> u32 {
let b_mask: u32 = 0xff;
let blue = (rgb & b_mask) << 16;
blue | (rgb >> 8)
}

View File

@@ -1,5 +1,7 @@
mod led;
mod ota; mod ota;
mod sdcard; mod sdcard;
use crate::led::set_ota_led;
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use log::{error, info, warn}; use log::{error, info, warn};
use ota::{run_sdcard_ota_update, set_boot_main_app, UPDATE_BIN_PATH}; use ota::{run_sdcard_ota_update, set_boot_main_app, UPDATE_BIN_PATH};
@@ -14,6 +16,7 @@ fn main() {
esp_idf_sys::link_patches(); esp_idf_sys::link_patches();
thread::sleep(Duration::from_secs(10)); thread::sleep(Duration::from_secs(10));
set_ota_led();
info!("Hello, world! Mounting sd card..."); info!("Hello, world! Mounting sd card...");
sdcard::mount_sd_card(); sdcard::mount_sd_card();
info!("SD card mounted! Checking for update..."); info!("SD card mounted! Checking for update...");

View File

@@ -3,5 +3,5 @@
nvs, data, nvs, 0x9000, 0x4000, nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000, otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000, phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 377K, factory, app, factory, 0x10000, 448K,
ota_0, app, ota_0, 0x70000, 3648K, ota_0, app, ota_0, 0x80000, 3584K,
1 # ESP-IDF Partition Table
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 factory, app, factory, 0x10000, 377K, factory, app, factory, 0x10000, 448K,
7 ota_0, app, ota_0, 0x70000, 3648K, ota_0, app, ota_0, 0x80000, 3584K,

View File

@@ -34,6 +34,7 @@ pub enum Status {
ConnectingToMqtt, ConnectingToMqtt,
Connected, Connected,
Signing, Signing,
Ota,
} }
pub const ROOT_STORE: &str = "/sdcard/store"; pub const ROOT_STORE: &str = "/sdcard/store";
@@ -116,7 +117,9 @@ pub fn make_event_loop(
Event::Control(ref msg_bytes) => { Event::Control(ref msg_bytes) => {
log::info!("GOT A CONTROL MSG"); log::info!("GOT A CONTROL MSG");
let cres = ctrlr.handle(msg_bytes); let cres = ctrlr.handle(msg_bytes);
if let Some(res) = handle_control_response(&root_handler, cres, network) { if let Some(res) =
handle_control_response(&root_handler, cres, network, led_tx.clone())
{
let res_data = let res_data =
rmp_serde::to_vec(&res).expect("could not publish control response"); rmp_serde::to_vec(&res).expect("could not publish control response");
mqtt.publish(topics::CONTROL_RETURN, QOS, false, &res_data) mqtt.publish(topics::CONTROL_RETURN, QOS, false, &res_data)
@@ -133,6 +136,7 @@ fn handle_control_response(
root_handler: &RootHandler, root_handler: &RootHandler,
cres: anyhow::Result<(ControlMessage, ControlResponse)>, cres: anyhow::Result<(ControlMessage, ControlResponse)>,
network: Network, network: Network,
led_tx: mpsc::Sender<Status>,
) -> Option<ControlResponse> { ) -> Option<ControlResponse> {
match cres { match cres {
Ok((control_msg, mut control_res)) => { Ok((control_msg, mut control_res)) => {
@@ -171,7 +175,8 @@ fn handle_control_response(
ControlResponse::Error(format!("OTA update cannot launch {:?}", e)) ControlResponse::Error(format!("OTA update cannot launch {:?}", e))
} else { } else {
thread::spawn(move || { thread::spawn(move || {
if let Err(e) = update_sphinx_key(params) { led_tx.send(Status::Ota).unwrap();
if let Err(e) = update_sphinx_key(params, led_tx) {
log::error!("OTA update failed {:?}", e.to_string()); log::error!("OTA update failed {:?}", e.to_string());
} else { } else {
log::info!("OTA flow complete, restarting esp..."); log::info!("OTA flow complete, restarting esp...");

View File

@@ -1,8 +1,9 @@
use crate::core::events::Status;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use embedded_svc::http::client::Client; use embedded_svc::http::client::Client;
use embedded_svc::http::client::Request; use embedded_svc::http::client::Request;
use embedded_svc::http::client::Response; use embedded_svc::http::client::Response;
use embedded_svc::http::Status; use embedded_svc::http::Status as HttpStatus;
use embedded_svc::io::Read; use embedded_svc::io::Read;
use embedded_svc::ota::Ota; use embedded_svc::ota::Ota;
use esp_idf_svc::http::client::EspHttpClient; use esp_idf_svc::http::client::EspHttpClient;
@@ -14,6 +15,7 @@ use sphinx_key_signer::control::OtaParams;
use std::fs::{remove_file, File}; use std::fs::{remove_file, File};
use std::io::BufWriter; use std::io::BufWriter;
use std::io::Write; use std::io::Write;
use std::sync::mpsc;
const BUFFER_LEN: usize = 3072; const BUFFER_LEN: usize = 3072;
const UPDATE_BIN_PATH: &str = "/sdcard/update.bin"; const UPDATE_BIN_PATH: &str = "/sdcard/update.bin";
@@ -31,7 +33,7 @@ fn factory_reset() -> Result<()> {
} }
} }
fn get_update(params: OtaParams) -> Result<()> { fn get_update(params: OtaParams, led_tx: mpsc::Sender<Status>) -> Result<()> {
let configuration = EspHttpClientConfiguration { let configuration = EspHttpClientConfiguration {
buffer_size: Some(BUFFER_LEN), buffer_size: Some(BUFFER_LEN),
buffer_size_tx: Some(BUFFER_LEN / 3), buffer_size_tx: Some(BUFFER_LEN / 3),
@@ -62,6 +64,7 @@ fn get_update(params: OtaParams) -> Result<()> {
write_tot += w; write_tot += w;
i += 1; i += 1;
if i % 20 == 0 { if i % 20 == 0 {
led_tx.send(Status::Ota).unwrap();
info!("Cumulative bytes read: {}", read_tot); info!("Cumulative bytes read: {}", read_tot);
info!("Cumulative bytes written: {}", write_tot); info!("Cumulative bytes written: {}", write_tot);
} }
@@ -71,9 +74,9 @@ fn get_update(params: OtaParams) -> Result<()> {
Ok(()) Ok(())
} }
pub fn update_sphinx_key(params: OtaParams) -> Result<()> { pub fn update_sphinx_key(params: OtaParams, led_tx: mpsc::Sender<Status>) -> Result<()> {
info!("Getting the update..."); info!("Getting the update...");
get_update(params)?; get_update(params, led_tx)?;
info!("Update written to sd card, performing factory reset"); info!("Update written to sd card, performing factory reset");
factory_reset()?; factory_reset()?;
info!("Factory reset completed!"); info!("Factory reset completed!");

View File

@@ -19,15 +19,16 @@ pub struct Led {
fn states() -> BTreeMap<Status, (Color, Time)> { fn states() -> BTreeMap<Status, (Color, Time)> {
let mut s = BTreeMap::new(); let mut s = BTreeMap::new();
s.insert(Status::Starting, (0x000001, 100)); s.insert(Status::Starting, (0x000001, 100)); // Blue
s.insert(Status::MountingSDCard, (0x000102, 100)); s.insert(Status::MountingSDCard, (0x000102, 100)); // Cyan
s.insert(Status::SyncingTime, (0x000122, 100)); s.insert(Status::SyncingTime, (0x000122, 100)); // Cyan
s.insert(Status::WifiAccessPoint, (0x000100, 100)); s.insert(Status::WifiAccessPoint, (0x000100, 100)); // Green
s.insert(Status::Configuring, (0x010000, 20)); s.insert(Status::Configuring, (0x010000, 20)); // Red
s.insert(Status::ConnectingToWifi, (0x010100, 350)); s.insert(Status::ConnectingToWifi, (0x010100, 350)); // Yellow
s.insert(Status::ConnectingToMqtt, (0x010001, 100)); s.insert(Status::ConnectingToMqtt, (0x010001, 100)); // Purple
s.insert(Status::Connected, (0x000101, 400)); s.insert(Status::Connected, (0x000101, 400)); // Cyan
s.insert(Status::Signing, (0x111111, 100)); s.insert(Status::Signing, (0x111111, 100)); // White
s.insert(Status::Ota, (0xffa500, 100)); // Orange
s s
} }