From 65a1f09a903cb2bcef9bcd576b5146407dd77ecd Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 18 Aug 2023 12:32:18 +1000 Subject: [PATCH] Support app console commands for the samd --- src/app_console/app_console.cpp | 58 +++++++++++++++++++++++++ src/app_console/include/app_console.hpp | 2 + src/drivers/include/samd.hpp | 8 ++-- src/drivers/samd.cpp | 55 +++++++++++------------ src/system_fsm/booting.cpp | 6 ++- 5 files changed, 93 insertions(+), 36 deletions(-) diff --git a/src/app_console/app_console.cpp b/src/app_console/app_console.cpp index 7804fd34..e9bd7cdc 100644 --- a/src/app_console/app_console.cpp +++ b/src/app_console/app_console.cpp @@ -38,6 +38,7 @@ namespace console { std::weak_ptr AppConsole::sDatabase; audio::TrackQueue* AppConsole::sTrackQueue; drivers::Bluetooth* AppConsole::sBluetooth; +drivers::Samd* AppConsole::sSamd; int CmdListDir(int argc, char** argv) { auto lock = AppConsole::sDatabase.lock(); @@ -481,6 +482,62 @@ void RegisterBtList() { esp_console_cmd_register(&cmd); } +int CmdSamd(int argc, char** argv) { + static const std::string usage = "usage: samd [flash|charge]"; + if (argc != 2) { + std::cout << usage << std::endl; + return 1; + } + + std::string cmd{argv[1]}; + if (cmd == "flash") { + std::cout << "resetting samd..." << std::endl; + vTaskDelay(pdMS_TO_TICKS(5)); + + AppConsole::sSamd->ResetToFlashSamd(); + } else if (cmd == "charge") { + auto res = AppConsole::sSamd->ReadChargeStatus(); + if (res) { + switch (res.value()) { + case drivers::Samd::ChargeStatus::kNoBattery: + std::cout << "kNoBattery" << std::endl; + break; + case drivers::Samd::ChargeStatus::kBatteryCritical: + std::cout << "kBatteryCritical" << std::endl; + break; + case drivers::Samd::ChargeStatus::kDischarging: + std::cout << "kDischarging" << std::endl; + break; + case drivers::Samd::ChargeStatus::kChargingRegular: + std::cout << "kChargingRegular" << std::endl; + break; + case drivers::Samd::ChargeStatus::kChargingFast: + std::cout << "kChargingFast" << std::endl; + break; + case drivers::Samd::ChargeStatus::kFullCharge: + std::cout << "kFullCharge" << std::endl; + break; + } + } else { + std::cout << "unknown" << std::endl; + } + } else { + std::cout << usage << std::endl; + return 1; + } + + return 0; +} + +void RegisterSamd() { + esp_console_cmd_t cmd{.command = "samd", + .help = "", + .hint = NULL, + .func = &CmdSamd, + .argtable = NULL}; + esp_console_cmd_register(&cmd); +} + auto AppConsole::RegisterExtraComponents() -> void { RegisterListDir(); RegisterPlayFile(); @@ -495,6 +552,7 @@ auto AppConsole::RegisterExtraComponents() -> void { RegisterDbDump(); RegisterTaskStates(); RegisterBtList(); + RegisterSamd(); } } // namespace console diff --git a/src/app_console/include/app_console.hpp b/src/app_console/include/app_console.hpp index 667e452f..6c23552e 100644 --- a/src/app_console/include/app_console.hpp +++ b/src/app_console/include/app_console.hpp @@ -11,6 +11,7 @@ #include "bluetooth.hpp" #include "console.hpp" #include "database.hpp" +#include "samd.hpp" #include "track_queue.hpp" namespace console { @@ -20,6 +21,7 @@ class AppConsole : public Console { static std::weak_ptr sDatabase; static audio::TrackQueue* sTrackQueue; static drivers::Bluetooth* sBluetooth; + static drivers::Samd* sSamd; protected: virtual auto RegisterExtraComponents() -> void; diff --git a/src/drivers/include/samd.hpp b/src/drivers/include/samd.hpp index 230cb069..1560b590 100644 --- a/src/drivers/include/samd.hpp +++ b/src/drivers/include/samd.hpp @@ -34,7 +34,7 @@ class Samd { auto ReadChargeStatus() -> std::optional; - enum class UsbMscStatus { + enum class UsbStatus { // There is no compatible usb host attached. kDetached, // There is a compatible usb host attached, but USB MSC is not currently @@ -44,11 +44,9 @@ class Samd { kAttachedMounted, }; - auto WriteAllowUsbMsc(bool is_allowed) -> void; - auto ReadUsbMscStatus() -> UsbMscStatus; + auto ReadUsbStatus() -> UsbStatus; - auto ReadFlashingEnabled() -> bool; - auto WriteFlashingEnabled(bool) -> void; + auto ResetToFlashSamd() -> void; }; } // namespace drivers diff --git a/src/drivers/samd.cpp b/src/drivers/samd.cpp index e87fc9d8..3c37b6c6 100644 --- a/src/drivers/samd.cpp +++ b/src/drivers/samd.cpp @@ -13,11 +13,12 @@ #include "hal/i2c_types.h" #include "i2c.hpp" -enum Registers { - kRegisterVersion = 0, - kRegisterCharge = 1, - kRegisterUsbMsc = 2, - kRegisterFlashing = 3, +enum Registers : uint8_t { + kSamdFirmwareVersion = 0, + kChargeStatus = 1, + kUsbStatus = 2, + kPowerControl = 3, + kUsbControl = 4, }; static const uint8_t kAddress = 0x45; @@ -33,13 +34,13 @@ Samd::Samd() { I2CTransaction transaction; transaction.start() .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(kRegisterVersion) + .write_ack(Registers::kSamdFirmwareVersion) + .start() .write_addr(kAddress, I2C_MASTER_READ) .read(&raw_res, I2C_MASTER_NACK) .stop(); - ESP_LOGI(kTag, "checking samd firmware rev"); - transaction.Execute(); - ESP_LOGI(kTag, "samd firmware: %u", raw_res); + ESP_ERROR_CHECK(transaction.Execute()); + ESP_LOGI(kTag, "samd firmware rev: %u", raw_res); } Samd::~Samd() {} @@ -48,12 +49,13 @@ auto Samd::ReadChargeStatus() -> std::optional { I2CTransaction transaction; transaction.start() .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(kRegisterCharge) + .write_ack(Registers::kChargeStatus) + .start() .write_addr(kAddress, I2C_MASTER_READ) .read(&raw_res, I2C_MASTER_NACK) .stop(); ESP_LOGI(kTag, "checking charge status"); - transaction.Execute(); + ESP_ERROR_CHECK(transaction.Execute()); ESP_LOGI(kTag, "raw charge status: %x", raw_res); uint8_t usb_state = raw_res & 0b11; @@ -77,37 +79,32 @@ auto Samd::ReadChargeStatus() -> std::optional { } } -auto Samd::WriteAllowUsbMsc(bool is_allowed) -> void { - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(kRegisterUsbMsc, is_allowed) - .stop(); - transaction.Execute(); -} - -auto Samd::ReadUsbMscStatus() -> UsbMscStatus { - return UsbMscStatus::kDetached; -} - -auto Samd::ReadFlashingEnabled() -> bool { +auto Samd::ReadUsbStatus() -> UsbStatus { uint8_t raw_res; I2CTransaction transaction; transaction.start() .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(kRegisterVersion) + .write_ack(Registers::kUsbStatus) + .start() .write_addr(kAddress, I2C_MASTER_READ) .read(&raw_res, I2C_MASTER_NACK) .stop(); + ESP_LOGI(kTag, "checking usb status"); ESP_ERROR_CHECK(transaction.Execute()); - return raw_res; + ESP_LOGI(kTag, "raw usb status: %x", raw_res); + + if (!(raw_res & 0b1)) { + return UsbStatus::kDetached; + } + return (raw_res & 0b10) ? UsbStatus::kAttachedMounted + : UsbStatus::kAttachedIdle; } -auto Samd::WriteFlashingEnabled(bool is_enabled) -> void { +auto Samd::ResetToFlashSamd() -> void { I2CTransaction transaction; transaction.start() .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(kRegisterFlashing, is_enabled) + .write_ack(Registers::kUsbControl, 0b100) .stop(); ESP_ERROR_CHECK(transaction.Execute()); } diff --git a/src/system_fsm/booting.cpp b/src/system_fsm/booting.cpp index 1fc01976..2a4d5f5c 100644 --- a/src/system_fsm/booting.cpp +++ b/src/system_fsm/booting.cpp @@ -16,6 +16,7 @@ #include "lvgl/lvgl.h" #include "nvs.hpp" #include "relative_wheel.hpp" +#include "samd.hpp" #include "spi.hpp" #include "system_events.hpp" #include "system_fsm.hpp" @@ -86,6 +87,7 @@ auto Booting::exit() -> void { sAppConsole = new console::AppConsole(); sAppConsole->sTrackQueue = sTrackQueue.get(); sAppConsole->sBluetooth = sBluetooth.get(); + sAppConsole->sSamd = sSamd.get(); sAppConsole->Launch(); } @@ -94,8 +96,8 @@ auto Booting::react(const BootComplete& ev) -> void { // 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. - if (sSamd && sSamd->ReadUsbMscStatus() == - drivers::Samd::UsbMscStatus::kAttachedMounted) { + if (sSamd && + sSamd->ReadUsbStatus() == drivers::Samd::UsbStatus::kAttachedMounted) { transit(); } transit();