diff options
Diffstat (limited to 'src/drivers/samd.cpp')
| -rw-r--r-- | src/drivers/samd.cpp | 111 |
1 files changed, 41 insertions, 70 deletions
diff --git a/src/drivers/samd.cpp b/src/drivers/samd.cpp index b4f6b88a..d8f56a46 100644 --- a/src/drivers/samd.cpp +++ b/src/drivers/samd.cpp @@ -5,18 +5,21 @@ */ #include "drivers/samd.hpp" +#include <stdint.h> #include <cstdint> #include <format> #include <optional> #include <string> +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "drivers/i2c.hpp" #include "esp_err.h" #include "esp_log.h" #include "hal/gpio_types.h" #include "hal/i2c_types.h" -#include "drivers/i2c.hpp" #include "drivers/nvs.hpp" static const uint8_t kAddress = 0x45; @@ -54,16 +57,20 @@ Samd::Samd(NvsStorage& nvs) : nvs_(nvs) { // 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. - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kSamdFirmwareMajorVersion)) - .start() - .write_addr(kAddress, I2C_MASTER_READ) - .read(&version_major_, I2C_MASTER_ACK) - .read(&version_minor_, I2C_MASTER_NACK) - .stop(); - ESP_ERROR_CHECK(transaction.Execute(1)); + i2c_device_config_t config = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = kAddress, + .scl_speed_hz = 100'000, + .scl_wait_us = 0, + .flags = {.disable_ack_check = false}, + }; + ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c_handle(), &config, &i2c_)); + + uint8_t cmd[] = {registerIdx(RegisterName::kSamdFirmwareMajorVersion)}; + uint8_t data[] = {0, 0}; + ESP_ERROR_CHECK(i2c_master_transmit_receive(i2c_, cmd, 1, data, 2, 100)); + version_major_ = data[0]; + version_minor_ = data[1]; if (version_major_ < 6) { version_minor_ = 0; @@ -85,24 +92,17 @@ auto Samd::GetChargeStatus() -> std::optional<ChargeStatus> { } auto Samd::UpdateChargeStatus() -> void { - uint8_t raw_res; - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kChargeStatus)) - .start() - .write_addr(kAddress, I2C_MASTER_READ) - .read(&raw_res, I2C_MASTER_NACK) - .stop(); - esp_err_t res = transaction.Execute(1); + uint8_t cmd[] = {registerIdx(RegisterName::kChargeStatus)}; + uint8_t data[] = {0}; + esp_err_t res = i2c_master_transmit_receive(i2c_, cmd, 1, data, 1, 100); if (res != ESP_OK) { return; } // Lower two bits are the usb power status, next three are the BMS status. // See 'gpio.c' in the SAMD21 firmware for how these bits get packed. - uint8_t charge_state = (raw_res & 0b11100) >> 2; - uint8_t usb_state = raw_res & 0b11; + uint8_t charge_state = (data[0] & 0b11100) >> 2; + uint8_t usb_state = data[0] & 0b11; switch (charge_state) { case 0b000: charge_status_ = ChargeStatus::kNoBattery; @@ -139,34 +139,23 @@ auto Samd::GetUsbStatus() -> UsbStatus { } auto Samd::UpdateUsbStatus() -> void { - uint8_t raw_res; - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kUsbStatus)) - .start() - .write_addr(kAddress, I2C_MASTER_READ) - .read(&raw_res, I2C_MASTER_NACK) - .stop(); - esp_err_t res = transaction.Execute(1); + uint8_t cmd[] = {registerIdx(RegisterName::kUsbStatus)}; + uint8_t data[] = {0}; + esp_err_t res = i2c_master_transmit_receive(i2c_, cmd, 1, data, 1, 100); if (res != ESP_OK) { return; } - if (!(raw_res & 0b1)) { + if (!(data[0] & 0b1)) { usb_status_ = UsbStatus::kDetached; } usb_status_ = - (raw_res & 0b10) ? UsbStatus::kAttachedBusy : UsbStatus::kAttachedIdle; + (data[0] & 0b10) ? UsbStatus::kAttachedBusy : UsbStatus::kAttachedIdle; } auto Samd::ResetToFlashSamd() -> void { - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kUsbControl), 0b100) - .stop(); - ESP_ERROR_CHECK(transaction.Execute(3)); + uint8_t cmd[] = {registerIdx(RegisterName::kUsbControl), 0b100}; + ESP_ERROR_CHECK(i2c_master_transmit(i2c_, cmd, 2, 100)); } auto Samd::SetFastChargeEnabled(bool en) -> void { @@ -178,47 +167,29 @@ auto Samd::SetFastChargeEnabled(bool en) -> void { return; } - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kPowerControl), (en << 1)) - .stop(); - ESP_ERROR_CHECK(transaction.Execute(3)); + uint8_t cmd[] = {registerIdx(RegisterName::kPowerControl), + static_cast<uint8_t>(en << 1)}; + ESP_ERROR_CHECK(i2c_master_transmit(i2c_, cmd, 2, 100)); } auto Samd::PowerDown() -> void { - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kPowerControl), 0b1) - .stop(); - ESP_ERROR_CHECK(transaction.Execute(3)); + uint8_t cmd[] = {registerIdx(RegisterName::kPowerControl), 0b1}; + ESP_ERROR_CHECK(i2c_master_transmit(i2c_, cmd, 2, 100)); } auto Samd::UsbMassStorage(bool en) -> void { - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kUsbControl), en) - .stop(); - ESP_ERROR_CHECK(transaction.Execute(3)); + uint8_t cmd[] = {registerIdx(RegisterName::kUsbControl), en}; + ESP_ERROR_CHECK(i2c_master_transmit(i2c_, cmd, 2, 100)); } auto Samd::UsbMassStorage() -> bool { - uint8_t raw_res; - I2CTransaction transaction; - transaction.start() - .write_addr(kAddress, I2C_MASTER_WRITE) - .write_ack(registerIdx(RegisterName::kUsbControl)) - .start() - .write_addr(kAddress, I2C_MASTER_READ) - .read(&raw_res, I2C_MASTER_NACK) - .stop(); - esp_err_t res = transaction.Execute(1); + uint8_t cmd[] = {registerIdx(RegisterName::kUsbControl)}; + uint8_t data[] = {0}; + esp_err_t res = i2c_master_transmit_receive(i2c_, cmd, 1, data, 1, 100); if (res != ESP_OK) { return false; } - return raw_res & 1; + return data[0] & 1; } auto Samd::registerIdx(RegisterName r) -> uint8_t { |
