Add interrupts for samd changes
This commit is contained in:
@@ -496,7 +496,7 @@ int CmdSamd(int argc, char** argv) {
|
|||||||
|
|
||||||
AppConsole::sSamd->ResetToFlashSamd();
|
AppConsole::sSamd->ResetToFlashSamd();
|
||||||
} else if (cmd == "charge") {
|
} else if (cmd == "charge") {
|
||||||
auto res = AppConsole::sSamd->ReadChargeStatus();
|
auto res = AppConsole::sSamd->GetChargeStatus();
|
||||||
if (res) {
|
if (res) {
|
||||||
switch (res.value()) {
|
switch (res.value()) {
|
||||||
case drivers::Samd::ChargeStatus::kNoBattery:
|
case drivers::Samd::ChargeStatus::kNoBattery:
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ constexpr std::pair<uint8_t, uint8_t> unpack(uint16_t ba) {
|
|||||||
return std::pair((uint8_t)ba, (uint8_t)(ba >> 8));
|
return std::pair((uint8_t)ba, (uint8_t)(ba >> 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
void interrupt_isr(void* arg) {
|
SemaphoreHandle_t Gpios::sReadPending;
|
||||||
|
|
||||||
|
static void interrupt_isr(void* arg) {
|
||||||
SemaphoreHandle_t sem = reinterpret_cast<SemaphoreHandle_t>(arg);
|
SemaphoreHandle_t sem = reinterpret_cast<SemaphoreHandle_t>(arg);
|
||||||
xSemaphoreGive(sem);
|
xSemaphoreGive(sem);
|
||||||
}
|
}
|
||||||
@@ -73,10 +75,7 @@ auto Gpios::Create() -> Gpios* {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpios::Gpios()
|
Gpios::Gpios() : ports_(pack(kPortADefault, kPortBDefault)), inputs_(0) {
|
||||||
: ports_(pack(kPortADefault, kPortBDefault)),
|
|
||||||
inputs_(0),
|
|
||||||
read_pending_(xSemaphoreCreateBinary()) {
|
|
||||||
gpio_config_t config{
|
gpio_config_t config{
|
||||||
.pin_bit_mask = static_cast<uint64_t>(1) << GPIO_NUM_34,
|
.pin_bit_mask = static_cast<uint64_t>(1) << GPIO_NUM_34,
|
||||||
.mode = GPIO_MODE_INPUT,
|
.mode = GPIO_MODE_INPUT,
|
||||||
@@ -87,6 +86,7 @@ Gpios::Gpios()
|
|||||||
gpio_config(&config);
|
gpio_config(&config);
|
||||||
gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED |
|
gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED |
|
||||||
ESP_INTR_FLAG_IRAM);
|
ESP_INTR_FLAG_IRAM);
|
||||||
|
gpio_isr_handler_add(GPIO_NUM_34, &interrupt_isr, sReadPending);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpios::~Gpios() {
|
Gpios::~Gpios() {
|
||||||
@@ -141,8 +141,9 @@ auto Gpios::Read() -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Gpios::InstallReadPendingISR() -> void {
|
auto Gpios::CreateReadPending() -> SemaphoreHandle_t {
|
||||||
gpio_isr_handler_add(GPIO_NUM_34, &interrupt_isr, read_pending_);
|
sReadPending = xSemaphoreCreateBinary();
|
||||||
|
return sReadPending;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace drivers
|
} // namespace drivers
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ class Gpios : public IGpios {
|
|||||||
*/
|
*/
|
||||||
auto Read(void) -> bool;
|
auto Read(void) -> bool;
|
||||||
|
|
||||||
auto InstallReadPendingISR() -> void;
|
static auto CreateReadPending() -> SemaphoreHandle_t;
|
||||||
auto IsReadPending() -> SemaphoreHandle_t { return read_pending_; }
|
|
||||||
|
|
||||||
// Not copyable or movable. There should usually only ever be once instance
|
// Not copyable or movable. There should usually only ever be once instance
|
||||||
// of this class, and that instance will likely have a static lifetime.
|
// of this class, and that instance will likely have a static lifetime.
|
||||||
@@ -121,7 +120,7 @@ class Gpios : public IGpios {
|
|||||||
std::atomic<uint16_t> ports_;
|
std::atomic<uint16_t> ports_;
|
||||||
std::atomic<uint16_t> inputs_;
|
std::atomic<uint16_t> inputs_;
|
||||||
|
|
||||||
SemaphoreHandle_t read_pending_;
|
static SemaphoreHandle_t sReadPending;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace drivers
|
} // namespace drivers
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
namespace drivers {
|
namespace drivers {
|
||||||
|
|
||||||
class Samd {
|
class Samd {
|
||||||
@@ -32,7 +35,8 @@ class Samd {
|
|||||||
kFullCharge,
|
kFullCharge,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ReadChargeStatus() -> std::optional<ChargeStatus>;
|
auto GetChargeStatus() -> std::optional<ChargeStatus>;
|
||||||
|
auto UpdateChargeStatus() -> void;
|
||||||
|
|
||||||
enum class UsbStatus {
|
enum class UsbStatus {
|
||||||
// There is no compatible usb host attached.
|
// There is no compatible usb host attached.
|
||||||
@@ -44,9 +48,23 @@ class Samd {
|
|||||||
kAttachedMounted,
|
kAttachedMounted,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ReadUsbStatus() -> UsbStatus;
|
auto GetUsbStatus() -> UsbStatus;
|
||||||
|
auto UpdateUsbStatus() -> void;
|
||||||
|
|
||||||
auto ResetToFlashSamd() -> void;
|
auto ResetToFlashSamd() -> void;
|
||||||
|
|
||||||
|
static auto CreateReadPending() -> SemaphoreHandle_t;
|
||||||
|
|
||||||
|
// Not copyable or movable. There should usually only ever be once instance
|
||||||
|
// of this class, and that instance will likely have a static lifetime.
|
||||||
|
Samd(const Samd&) = delete;
|
||||||
|
Samd& operator=(const Samd&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<ChargeStatus> charge_status_;
|
||||||
|
UsbStatus usb_status_;
|
||||||
|
|
||||||
|
static SemaphoreHandle_t sReadPending;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace drivers
|
} // namespace drivers
|
||||||
|
|||||||
+50
-15
@@ -26,7 +26,24 @@ static const char kTag[] = "SAMD";
|
|||||||
|
|
||||||
namespace drivers {
|
namespace drivers {
|
||||||
|
|
||||||
|
SemaphoreHandle_t Samd::sReadPending;
|
||||||
|
|
||||||
|
static void interrupt_isr(void* arg) {
|
||||||
|
SemaphoreHandle_t sem = reinterpret_cast<SemaphoreHandle_t>(arg);
|
||||||
|
xSemaphoreGive(sem);
|
||||||
|
}
|
||||||
|
|
||||||
Samd::Samd() {
|
Samd::Samd() {
|
||||||
|
gpio_config_t config{
|
||||||
|
.pin_bit_mask = static_cast<uint64_t>(1) << GPIO_NUM_35,
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type = GPIO_INTR_NEGEDGE,
|
||||||
|
};
|
||||||
|
gpio_config(&config);
|
||||||
|
gpio_isr_handler_add(GPIO_NUM_35, &interrupt_isr, sReadPending);
|
||||||
|
|
||||||
// Being able to interface with the SAMD properly is critical. To ensure we
|
// Being able to interface with the SAMD properly is critical. To ensure we
|
||||||
// will be able to, we begin by checking the I2C protocol version is
|
// will be able to, we begin by checking the I2C protocol version is
|
||||||
// compatible, and throw if it's not.
|
// compatible, and throw if it's not.
|
||||||
@@ -41,10 +58,17 @@ Samd::Samd() {
|
|||||||
.stop();
|
.stop();
|
||||||
ESP_ERROR_CHECK(transaction.Execute());
|
ESP_ERROR_CHECK(transaction.Execute());
|
||||||
ESP_LOGI(kTag, "samd firmware rev: %u", raw_res);
|
ESP_LOGI(kTag, "samd firmware rev: %u", raw_res);
|
||||||
|
|
||||||
|
UpdateChargeStatus();
|
||||||
|
UpdateUsbStatus();
|
||||||
}
|
}
|
||||||
Samd::~Samd() {}
|
Samd::~Samd() {}
|
||||||
|
|
||||||
auto Samd::ReadChargeStatus() -> std::optional<ChargeStatus> {
|
auto Samd::GetChargeStatus() -> std::optional<ChargeStatus> {
|
||||||
|
return charge_status_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Samd::UpdateChargeStatus() -> void {
|
||||||
uint8_t raw_res;
|
uint8_t raw_res;
|
||||||
I2CTransaction transaction;
|
I2CTransaction transaction;
|
||||||
transaction.start()
|
transaction.start()
|
||||||
@@ -54,31 +78,39 @@ auto Samd::ReadChargeStatus() -> std::optional<ChargeStatus> {
|
|||||||
.write_addr(kAddress, I2C_MASTER_READ)
|
.write_addr(kAddress, I2C_MASTER_READ)
|
||||||
.read(&raw_res, I2C_MASTER_NACK)
|
.read(&raw_res, I2C_MASTER_NACK)
|
||||||
.stop();
|
.stop();
|
||||||
ESP_LOGI(kTag, "checking charge status");
|
|
||||||
ESP_ERROR_CHECK(transaction.Execute());
|
ESP_ERROR_CHECK(transaction.Execute());
|
||||||
ESP_LOGI(kTag, "raw charge status: 0x%x", raw_res);
|
|
||||||
|
|
||||||
uint8_t usb_state = raw_res & 0b11;
|
uint8_t usb_state = raw_res & 0b11;
|
||||||
uint8_t charge_state = (raw_res >> 2) & 0b111;
|
uint8_t charge_state = (raw_res >> 2) & 0b111;
|
||||||
switch (charge_state) {
|
switch (charge_state) {
|
||||||
case 0b000:
|
case 0b000:
|
||||||
case 0b011:
|
case 0b011:
|
||||||
return ChargeStatus::kNoBattery;
|
charge_status_ = ChargeStatus::kNoBattery;
|
||||||
|
break;
|
||||||
case 0b001:
|
case 0b001:
|
||||||
return usb_state == 1 ? ChargeStatus::kChargingRegular
|
charge_status_ = usb_state == 1 ? ChargeStatus::kChargingRegular
|
||||||
: ChargeStatus::kChargingFast;
|
: ChargeStatus::kChargingFast;
|
||||||
|
break;
|
||||||
case 0b010:
|
case 0b010:
|
||||||
return ChargeStatus::kFullCharge;
|
charge_status_ = ChargeStatus::kFullCharge;
|
||||||
|
break;
|
||||||
case 0b100:
|
case 0b100:
|
||||||
return ChargeStatus::kBatteryCritical;
|
charge_status_ = ChargeStatus::kBatteryCritical;
|
||||||
|
break;
|
||||||
case 0b101:
|
case 0b101:
|
||||||
return ChargeStatus::kDischarging;
|
charge_status_ = ChargeStatus::kDischarging;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return {};
|
charge_status_ = {};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Samd::ReadUsbStatus() -> UsbStatus {
|
auto Samd::GetUsbStatus() -> UsbStatus {
|
||||||
|
return usb_status_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Samd::UpdateUsbStatus() -> void {
|
||||||
uint8_t raw_res;
|
uint8_t raw_res;
|
||||||
I2CTransaction transaction;
|
I2CTransaction transaction;
|
||||||
transaction.start()
|
transaction.start()
|
||||||
@@ -88,15 +120,13 @@ auto Samd::ReadUsbStatus() -> UsbStatus {
|
|||||||
.write_addr(kAddress, I2C_MASTER_READ)
|
.write_addr(kAddress, I2C_MASTER_READ)
|
||||||
.read(&raw_res, I2C_MASTER_NACK)
|
.read(&raw_res, I2C_MASTER_NACK)
|
||||||
.stop();
|
.stop();
|
||||||
ESP_LOGI(kTag, "checking usb status");
|
|
||||||
ESP_ERROR_CHECK(transaction.Execute());
|
ESP_ERROR_CHECK(transaction.Execute());
|
||||||
ESP_LOGI(kTag, "raw usb status: 0x%x", raw_res);
|
|
||||||
|
|
||||||
if (!(raw_res & 0b1)) {
|
if (!(raw_res & 0b1)) {
|
||||||
return UsbStatus::kDetached;
|
usb_status_ = UsbStatus::kDetached;
|
||||||
}
|
}
|
||||||
return (raw_res & 0b10) ? UsbStatus::kAttachedMounted
|
usb_status_ =
|
||||||
: UsbStatus::kAttachedIdle;
|
(raw_res & 0b10) ? UsbStatus::kAttachedMounted : UsbStatus::kAttachedIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Samd::ResetToFlashSamd() -> void {
|
auto Samd::ResetToFlashSamd() -> void {
|
||||||
@@ -108,4 +138,9 @@ auto Samd::ResetToFlashSamd() -> void {
|
|||||||
ESP_ERROR_CHECK(transaction.Execute());
|
ESP_ERROR_CHECK(transaction.Execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Samd::CreateReadPending() -> SemaphoreHandle_t {
|
||||||
|
sReadPending = xSemaphoreCreateBinary();
|
||||||
|
return sReadPending;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace drivers
|
} // namespace drivers
|
||||||
|
|||||||
+8
-3
@@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
extern "C" void app_main(void) {
|
extern "C" void app_main(void) {
|
||||||
ESP_ERROR_CHECK(drivers::init_i2c());
|
ESP_ERROR_CHECK(drivers::init_i2c());
|
||||||
drivers::Gpios* gpios = system_fsm::SystemState::early_init_gpios();
|
SemaphoreHandle_t gpios_semphr = drivers::Gpios::CreateReadPending();
|
||||||
|
SemaphoreHandle_t samd_semphr = drivers::Samd::CreateReadPending();
|
||||||
|
|
||||||
// Semaphores must be empty before being added to a queue set. Hence all this
|
// Semaphores must be empty before being added to a queue set. Hence all this
|
||||||
// weird early init stuff; by being explicit about initialisation order, we're
|
// weird early init stuff; by being explicit about initialisation order, we're
|
||||||
@@ -27,7 +28,8 @@ extern "C" void app_main(void) {
|
|||||||
QueueSetHandle_t set = xQueueCreateSet(2);
|
QueueSetHandle_t set = xQueueCreateSet(2);
|
||||||
auto* event_queue = events::queues::SystemAndAudio();
|
auto* event_queue = events::queues::SystemAndAudio();
|
||||||
xQueueAddToSet(event_queue->has_events(), set);
|
xQueueAddToSet(event_queue->has_events(), set);
|
||||||
xQueueAddToSet(gpios->IsReadPending(), set);
|
xQueueAddToSet(gpios_semphr, set);
|
||||||
|
xQueueAddToSet(samd_semphr, set);
|
||||||
|
|
||||||
tinyfsm::FsmList<system_fsm::SystemState, ui::UiState,
|
tinyfsm::FsmList<system_fsm::SystemState, ui::UiState,
|
||||||
audio::AudioState>::start();
|
audio::AudioState>::start();
|
||||||
@@ -36,9 +38,12 @@ extern "C" void app_main(void) {
|
|||||||
QueueSetMemberHandle_t member = xQueueSelectFromSet(set, portMAX_DELAY);
|
QueueSetMemberHandle_t member = xQueueSelectFromSet(set, portMAX_DELAY);
|
||||||
if (member == event_queue->has_events()) {
|
if (member == event_queue->has_events()) {
|
||||||
event_queue->Service(0);
|
event_queue->Service(0);
|
||||||
} else if (member == gpios->IsReadPending()) {
|
} else if (member == gpios_semphr) {
|
||||||
xSemaphoreTake(member, 0);
|
xSemaphoreTake(member, 0);
|
||||||
events::System().Dispatch(system_fsm::internal::GpioInterrupt{});
|
events::System().Dispatch(system_fsm::internal::GpioInterrupt{});
|
||||||
|
} else if (member == samd_semphr) {
|
||||||
|
xSemaphoreTake(member, 0);
|
||||||
|
events::System().Dispatch(system_fsm::internal::SamdInterrupt{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ auto Booting::entry() -> void {
|
|||||||
// I2C and SPI are both always needed. We can't even power down or show an
|
// I2C and SPI are both always needed. We can't even power down or show an
|
||||||
// error without these.
|
// error without these.
|
||||||
ESP_ERROR_CHECK(drivers::init_spi());
|
ESP_ERROR_CHECK(drivers::init_spi());
|
||||||
sGpios->InstallReadPendingISR();
|
sGpios.reset(drivers::Gpios::Create());
|
||||||
|
|
||||||
// Start bringing up LVGL now, since we have all of its prerequisites.
|
// Start bringing up LVGL now, since we have all of its prerequisites.
|
||||||
sTrackQueue.reset(new audio::TrackQueue());
|
sTrackQueue.reset(new audio::TrackQueue());
|
||||||
@@ -97,7 +97,7 @@ auto Booting::react(const BootComplete& ev) -> void {
|
|||||||
// It's possible that the SAMD is currently exposing the SD card as a USB
|
// It's possible that the SAMD is currently exposing the SD card as a USB
|
||||||
// device. Make sure we don't immediately try to claim it.
|
// device. Make sure we don't immediately try to claim it.
|
||||||
if (sSamd &&
|
if (sSamd &&
|
||||||
sSamd->ReadUsbStatus() == drivers::Samd::UsbStatus::kAttachedMounted) {
|
sSamd->GetUsbStatus() == drivers::Samd::UsbStatus::kAttachedMounted) {
|
||||||
transit<Unmounted>();
|
transit<Unmounted>();
|
||||||
}
|
}
|
||||||
transit<Running>();
|
transit<Running>();
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ struct HasPhonesChanged : tinyfsm::Event {
|
|||||||
bool falling;
|
bool falling;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChargingStatusChanged : tinyfsm::Event {};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -68,11 +70,8 @@ namespace internal {
|
|||||||
*/
|
*/
|
||||||
struct ReadyToUnmount : tinyfsm::Event {};
|
struct ReadyToUnmount : tinyfsm::Event {};
|
||||||
|
|
||||||
/*
|
|
||||||
* Sent when the actual unmount operation should be performed. Always dispatched
|
|
||||||
* by SysState in response to StoragePrepareToUnmount.
|
|
||||||
*/
|
|
||||||
struct GpioInterrupt : tinyfsm::Event {};
|
struct GpioInterrupt : tinyfsm::Event {};
|
||||||
|
struct SamdInterrupt : tinyfsm::Event {};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
|
|||||||
public:
|
public:
|
||||||
virtual ~SystemState() {}
|
virtual ~SystemState() {}
|
||||||
|
|
||||||
static auto early_init_gpios() -> drivers::Gpios*;
|
|
||||||
|
|
||||||
virtual void entry() {}
|
virtual void entry() {}
|
||||||
virtual void exit() {}
|
virtual void exit() {}
|
||||||
|
|
||||||
@@ -45,6 +43,7 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
|
|||||||
|
|
||||||
void react(const FatalError&);
|
void react(const FatalError&);
|
||||||
void react(const internal::GpioInterrupt&);
|
void react(const internal::GpioInterrupt&);
|
||||||
|
void react(const internal::SamdInterrupt&);
|
||||||
|
|
||||||
virtual void react(const DisplayReady&) {}
|
virtual void react(const DisplayReady&) {}
|
||||||
virtual void react(const BootComplete&) {}
|
virtual void react(const BootComplete&) {}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#include "tag_parser.hpp"
|
#include "tag_parser.hpp"
|
||||||
#include "track_queue.hpp"
|
#include "track_queue.hpp"
|
||||||
|
|
||||||
|
static const char kTag[] = "system";
|
||||||
|
|
||||||
namespace system_fsm {
|
namespace system_fsm {
|
||||||
|
|
||||||
std::shared_ptr<drivers::Gpios> SystemState::sGpios;
|
std::shared_ptr<drivers::Gpios> SystemState::sGpios;
|
||||||
@@ -33,11 +35,6 @@ std::shared_ptr<audio::TrackQueue> SystemState::sTrackQueue;
|
|||||||
|
|
||||||
console::AppConsole* SystemState::sAppConsole;
|
console::AppConsole* SystemState::sAppConsole;
|
||||||
|
|
||||||
auto SystemState::early_init_gpios() -> drivers::Gpios* {
|
|
||||||
sGpios.reset(drivers::Gpios::Create());
|
|
||||||
return sGpios.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemState::react(const FatalError& err) {
|
void SystemState::react(const FatalError& err) {
|
||||||
if (!is_in_state<states::Error>()) {
|
if (!is_in_state<states::Error>()) {
|
||||||
transit<states::Error>();
|
transit<states::Error>();
|
||||||
@@ -78,6 +75,26 @@ void SystemState::react(const internal::GpioInterrupt&) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemState::react(const internal::SamdInterrupt&) {
|
||||||
|
auto prev_charge_status = sSamd->GetChargeStatus();
|
||||||
|
auto prev_usb_status = sSamd->GetUsbStatus();
|
||||||
|
|
||||||
|
sSamd->UpdateChargeStatus();
|
||||||
|
sSamd->UpdateUsbStatus();
|
||||||
|
|
||||||
|
auto charge_status = sSamd->GetChargeStatus();
|
||||||
|
auto usb_status = sSamd->GetUsbStatus();
|
||||||
|
|
||||||
|
if (charge_status != prev_charge_status) {
|
||||||
|
ChargingStatusChanged ev{};
|
||||||
|
events::System().Dispatch(ev);
|
||||||
|
events::Ui().Dispatch(ev);
|
||||||
|
}
|
||||||
|
if (usb_status != prev_usb_status) {
|
||||||
|
ESP_LOGI(kTag, "usb status changed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace system_fsm
|
} // namespace system_fsm
|
||||||
|
|
||||||
FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting)
|
FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting)
|
||||||
|
|||||||
Reference in New Issue
Block a user