summaryrefslogtreecommitdiff
path: root/src/drivers/samd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/samd.cpp')
-rw-r--r--src/drivers/samd.cpp111
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 {