parent
d71f726c42
commit
b320a6a863
@ -1,6 +1,6 @@ |
|||||||
idf_component_register( |
idf_component_register( |
||||||
SRCS "touchwheel.cpp" "dac.cpp" "gpio_expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" |
SRCS "touchwheel.cpp" "dac.cpp" "gpio_expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" |
||||||
"spi.cpp" "display.cpp" "display_init.cpp" "driver_cache.cpp" |
"spi.cpp" "display.cpp" "display_init.cpp" "driver_cache.cpp" "samd.cpp" |
||||||
INCLUDE_DIRS "include" |
INCLUDE_DIRS "include" |
||||||
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span") |
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span") |
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) |
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) |
||||||
|
@ -0,0 +1,46 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <optional> |
||||||
|
|
||||||
|
namespace drivers { |
||||||
|
|
||||||
|
class Samd { |
||||||
|
public: |
||||||
|
Samd(); |
||||||
|
~Samd(); |
||||||
|
|
||||||
|
enum class ChargeStatus { |
||||||
|
// There is no battery plugged into the device.
|
||||||
|
kNoBattery, |
||||||
|
// The battery is discharging, and the current voltage level is very low.
|
||||||
|
kBatteryCritical, |
||||||
|
// The battery is discharging.
|
||||||
|
kDischarging, |
||||||
|
// The battery is charging over a low-current USB connection
|
||||||
|
kChargingRegular, |
||||||
|
// The battery is charging over a high-current USB connection
|
||||||
|
kChargingFast, |
||||||
|
// The battery is full charged, and we are still plugged in.
|
||||||
|
kFullCharge, |
||||||
|
}; |
||||||
|
|
||||||
|
auto ReadChargeStatus() -> std::optional<ChargeStatus>; |
||||||
|
|
||||||
|
enum class UsbMscStatus { |
||||||
|
// There is no compatible usb host attached.
|
||||||
|
kDetached, |
||||||
|
// There is a compatible usb host attached, but USB MSC is not currently
|
||||||
|
// in use by the SAMD.
|
||||||
|
kAttachedIdle, |
||||||
|
// The SAMD is currently exposing the SD card via USB MSC.
|
||||||
|
kAttachedMounted, |
||||||
|
}; |
||||||
|
|
||||||
|
auto WriteAllowUsbMsc(bool is_allowed) -> void; |
||||||
|
auto ReadUsbMscStatus() -> UsbMscStatus; |
||||||
|
|
||||||
|
auto ReadFlashingEnabled() -> bool; |
||||||
|
auto WriteFlashingEnabled(bool) -> void; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace drivers
|
@ -0,0 +1,109 @@ |
|||||||
|
#include "samd.hpp" |
||||||
|
#include <stdint.h> |
||||||
|
#include <optional> |
||||||
|
|
||||||
|
#include "esp_err.h" |
||||||
|
#include "esp_log.h" |
||||||
|
#include "hal/i2c_types.h" |
||||||
|
#include "i2c.hpp" |
||||||
|
|
||||||
|
enum Registers { |
||||||
|
kRegisterVersion = 0, |
||||||
|
kRegisterCharge = 1, |
||||||
|
kRegisterUsbMsc = 2, |
||||||
|
kRegisterFlashing = 3, |
||||||
|
}; |
||||||
|
|
||||||
|
static const uint8_t kAddress = 0x45; |
||||||
|
static const char kTag[] = "SAMD"; |
||||||
|
|
||||||
|
namespace drivers { |
||||||
|
|
||||||
|
Samd::Samd() { |
||||||
|
// 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.
|
||||||
|
uint8_t raw_res = 0; |
||||||
|
I2CTransaction transaction; |
||||||
|
transaction.start() |
||||||
|
.write_addr(kAddress, I2C_MASTER_WRITE) |
||||||
|
.write_ack(kRegisterVersion) |
||||||
|
.write_addr(kAddress, I2C_MASTER_READ) |
||||||
|
.read(&raw_res, I2C_MASTER_NACK) |
||||||
|
.stop(); |
||||||
|
ESP_LOGI(kTag, "checking samd firmware rev"); |
||||||
|
ESP_ERROR_CHECK(transaction.Execute()); |
||||||
|
ESP_LOGI(kTag, "samd firmware: %u", raw_res); |
||||||
|
} |
||||||
|
Samd::~Samd() {} |
||||||
|
|
||||||
|
auto Samd::ReadChargeStatus() -> std::optional<ChargeStatus> { |
||||||
|
uint8_t raw_res; |
||||||
|
I2CTransaction transaction; |
||||||
|
transaction.start() |
||||||
|
.write_addr(kAddress, I2C_MASTER_WRITE) |
||||||
|
.write_ack(kRegisterCharge) |
||||||
|
.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: %x", raw_res); |
||||||
|
|
||||||
|
uint8_t usb_state = raw_res & 0b11; |
||||||
|
uint8_t charge_state = (raw_res >> 2) & 0b111; |
||||||
|
switch (charge_state) { |
||||||
|
case 0: |
||||||
|
return ChargeStatus::kNoBattery; |
||||||
|
case 1: |
||||||
|
return usb_state == 1 ? ChargeStatus::kChargingRegular |
||||||
|
: ChargeStatus::kChargingFast; |
||||||
|
case 2: |
||||||
|
return ChargeStatus::kFullCharge; |
||||||
|
case 4: |
||||||
|
return ChargeStatus::kBatteryCritical; |
||||||
|
case 5: |
||||||
|
return ChargeStatus::kDischarging; |
||||||
|
case 3: |
||||||
|
// Fall-through.
|
||||||
|
default: |
||||||
|
return {}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
auto Samd::WriteAllowUsbMsc(bool is_allowed) -> void { |
||||||
|
I2CTransaction transaction; |
||||||
|
transaction.start() |
||||||
|
.write_addr(kAddress, I2C_MASTER_WRITE) |
||||||
|
.write_ack(kRegisterUsbMsc, is_allowed) |
||||||
|
.stop(); |
||||||
|
ESP_ERROR_CHECK(transaction.Execute()); |
||||||
|
} |
||||||
|
|
||||||
|
auto Samd::ReadUsbMscStatus() -> UsbMscStatus { |
||||||
|
return UsbMscStatus::kDetached; |
||||||
|
} |
||||||
|
|
||||||
|
auto Samd::ReadFlashingEnabled() -> bool { |
||||||
|
uint8_t raw_res; |
||||||
|
I2CTransaction transaction; |
||||||
|
transaction.start() |
||||||
|
.write_addr(kAddress, I2C_MASTER_WRITE) |
||||||
|
.write_ack(kRegisterVersion) |
||||||
|
.write_addr(kAddress, I2C_MASTER_READ) |
||||||
|
.read(&raw_res, I2C_MASTER_NACK) |
||||||
|
.stop(); |
||||||
|
ESP_ERROR_CHECK(transaction.Execute()); |
||||||
|
return raw_res; |
||||||
|
} |
||||||
|
|
||||||
|
auto Samd::WriteFlashingEnabled(bool is_enabled) -> void { |
||||||
|
I2CTransaction transaction; |
||||||
|
transaction.start() |
||||||
|
.write_addr(kAddress, I2C_MASTER_WRITE) |
||||||
|
.write_ack(kRegisterFlashing, is_enabled) |
||||||
|
.stop(); |
||||||
|
ESP_ERROR_CHECK(transaction.Execute()); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace drivers
|
Loading…
Reference in new issue