diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-18 15:40:24 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-18 15:40:24 +1000 |
| commit | cad70605401e8fa30811e8c68a0cc5c014438942 (patch) | |
| tree | 42307c27b01ce80b1e9038dea6dca2d4aa94eae1 /src/drivers | |
| parent | 697ec3c5843c66253f73572c26b9b4885680d56c (diff) | |
| download | tangara-fw-cad70605401e8fa30811e8c68a0cc5c014438942.tar.gz | |
Add interrupts for samd changes
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/gpios.cpp | 15 | ||||
| -rw-r--r-- | src/drivers/include/gpios.hpp | 5 | ||||
| -rw-r--r-- | src/drivers/include/samd.hpp | 22 | ||||
| -rw-r--r-- | src/drivers/samd.cpp | 67 |
4 files changed, 81 insertions, 28 deletions
diff --git a/src/drivers/gpios.cpp b/src/drivers/gpios.cpp index f6293697..412c091f 100644 --- a/src/drivers/gpios.cpp +++ b/src/drivers/gpios.cpp @@ -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)); } -void interrupt_isr(void* arg) { +SemaphoreHandle_t Gpios::sReadPending; + +static void interrupt_isr(void* arg) { SemaphoreHandle_t sem = reinterpret_cast<SemaphoreHandle_t>(arg); xSemaphoreGive(sem); } @@ -73,10 +75,7 @@ auto Gpios::Create() -> Gpios* { return instance; } -Gpios::Gpios() - : ports_(pack(kPortADefault, kPortBDefault)), - inputs_(0), - read_pending_(xSemaphoreCreateBinary()) { +Gpios::Gpios() : ports_(pack(kPortADefault, kPortBDefault)), inputs_(0) { gpio_config_t config{ .pin_bit_mask = static_cast<uint64_t>(1) << GPIO_NUM_34, .mode = GPIO_MODE_INPUT, @@ -87,6 +86,7 @@ Gpios::Gpios() gpio_config(&config); gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM); + gpio_isr_handler_add(GPIO_NUM_34, &interrupt_isr, sReadPending); } Gpios::~Gpios() { @@ -141,8 +141,9 @@ auto Gpios::Read() -> bool { return true; } -auto Gpios::InstallReadPendingISR() -> void { - gpio_isr_handler_add(GPIO_NUM_34, &interrupt_isr, read_pending_); +auto Gpios::CreateReadPending() -> SemaphoreHandle_t { + sReadPending = xSemaphoreCreateBinary(); + return sReadPending; } } // namespace drivers diff --git a/src/drivers/include/gpios.hpp b/src/drivers/include/gpios.hpp index 5ac475bf..fe330e3b 100644 --- a/src/drivers/include/gpios.hpp +++ b/src/drivers/include/gpios.hpp @@ -107,8 +107,7 @@ class Gpios : public IGpios { */ auto Read(void) -> bool; - auto InstallReadPendingISR() -> void; - auto IsReadPending() -> SemaphoreHandle_t { return read_pending_; } + 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. @@ -121,7 +120,7 @@ class Gpios : public IGpios { std::atomic<uint16_t> ports_; std::atomic<uint16_t> inputs_; - SemaphoreHandle_t read_pending_; + static SemaphoreHandle_t sReadPending; }; } // namespace drivers diff --git a/src/drivers/include/samd.hpp b/src/drivers/include/samd.hpp index 1560b590..4a31a577 100644 --- a/src/drivers/include/samd.hpp +++ b/src/drivers/include/samd.hpp @@ -8,6 +8,9 @@ #include <optional> +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + namespace drivers { class Samd { @@ -32,7 +35,8 @@ class Samd { kFullCharge, }; - auto ReadChargeStatus() -> std::optional<ChargeStatus>; + auto GetChargeStatus() -> std::optional<ChargeStatus>; + auto UpdateChargeStatus() -> void; enum class UsbStatus { // There is no compatible usb host attached. @@ -44,9 +48,23 @@ class Samd { kAttachedMounted, }; - auto ReadUsbStatus() -> UsbStatus; + auto GetUsbStatus() -> UsbStatus; + auto UpdateUsbStatus() -> 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 diff --git a/src/drivers/samd.cpp b/src/drivers/samd.cpp index e7bfbb6b..455e9ce5 100644 --- a/src/drivers/samd.cpp +++ b/src/drivers/samd.cpp @@ -26,7 +26,24 @@ static const char kTag[] = "SAMD"; namespace drivers { +SemaphoreHandle_t Samd::sReadPending; + +static void interrupt_isr(void* arg) { + SemaphoreHandle_t sem = reinterpret_cast<SemaphoreHandle_t>(arg); + xSemaphoreGive(sem); +} + 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 // will be able to, we begin by checking the I2C protocol version is // compatible, and throw if it's not. @@ -41,10 +58,17 @@ Samd::Samd() { .stop(); ESP_ERROR_CHECK(transaction.Execute()); ESP_LOGI(kTag, "samd firmware rev: %u", raw_res); + + UpdateChargeStatus(); + UpdateUsbStatus(); } 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; I2CTransaction transaction; transaction.start() @@ -54,31 +78,39 @@ auto Samd::ReadChargeStatus() -> std::optional<ChargeStatus> { .write_addr(kAddress, I2C_MASTER_READ) .read(&raw_res, I2C_MASTER_NACK) .stop(); - ESP_LOGI(kTag, "checking charge status"); ESP_ERROR_CHECK(transaction.Execute()); - ESP_LOGI(kTag, "raw charge status: 0x%x", raw_res); uint8_t usb_state = raw_res & 0b11; uint8_t charge_state = (raw_res >> 2) & 0b111; switch (charge_state) { case 0b000: case 0b011: - return ChargeStatus::kNoBattery; + charge_status_ = ChargeStatus::kNoBattery; + break; case 0b001: - return usb_state == 1 ? ChargeStatus::kChargingRegular - : ChargeStatus::kChargingFast; + charge_status_ = usb_state == 1 ? ChargeStatus::kChargingRegular + : ChargeStatus::kChargingFast; + break; case 0b010: - return ChargeStatus::kFullCharge; + charge_status_ = ChargeStatus::kFullCharge; + break; case 0b100: - return ChargeStatus::kBatteryCritical; + charge_status_ = ChargeStatus::kBatteryCritical; + break; case 0b101: - return ChargeStatus::kDischarging; + charge_status_ = ChargeStatus::kDischarging; + break; default: - return {}; + charge_status_ = {}; + break; } } -auto Samd::ReadUsbStatus() -> UsbStatus { +auto Samd::GetUsbStatus() -> UsbStatus { + return usb_status_; +} + +auto Samd::UpdateUsbStatus() -> void { uint8_t raw_res; I2CTransaction transaction; transaction.start() @@ -88,15 +120,13 @@ auto Samd::ReadUsbStatus() -> UsbStatus { .write_addr(kAddress, I2C_MASTER_READ) .read(&raw_res, I2C_MASTER_NACK) .stop(); - ESP_LOGI(kTag, "checking usb status"); ESP_ERROR_CHECK(transaction.Execute()); - ESP_LOGI(kTag, "raw usb status: 0x%x", raw_res); if (!(raw_res & 0b1)) { - return UsbStatus::kDetached; + usb_status_ = UsbStatus::kDetached; } - return (raw_res & 0b10) ? UsbStatus::kAttachedMounted - : UsbStatus::kAttachedIdle; + usb_status_ = + (raw_res & 0b10) ? UsbStatus::kAttachedMounted : UsbStatus::kAttachedIdle; } auto Samd::ResetToFlashSamd() -> void { @@ -108,4 +138,9 @@ auto Samd::ResetToFlashSamd() -> void { ESP_ERROR_CHECK(transaction.Execute()); } +auto Samd::CreateReadPending() -> SemaphoreHandle_t { + sReadPending = xSemaphoreCreateBinary(); + return sReadPending; +} + } // namespace drivers |
