summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/CMakeLists.txt2
-rw-r--r--src/drivers/i2c.cpp8
-rw-r--r--src/drivers/include/i2c.hpp2
-rw-r--r--src/drivers/include/touchwheel.hpp60
-rw-r--r--src/drivers/touchwheel.cpp92
-rw-r--r--src/main/main.cpp13
6 files changed, 173 insertions, 4 deletions
diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt
index c4e4c172..bf8f0c4e 100644
--- a/src/drivers/CMakeLists.txt
+++ b/src/drivers/CMakeLists.txt
@@ -1,5 +1,5 @@
idf_component_register(
- SRCS "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"
INCLUDE_DIRS "include"
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span")
diff --git a/src/drivers/i2c.cpp b/src/drivers/i2c.cpp
index 04a6d7d1..a66f54f0 100644
--- a/src/drivers/i2c.cpp
+++ b/src/drivers/i2c.cpp
@@ -36,6 +36,10 @@ esp_err_t init_i2c(void) {
if (esp_err_t err = i2c_driver_install(kI2CPort, config.mode, 0, 0, 0)) {
return err;
}
+ if (esp_err_t err = i2c_set_timeout(kI2CPort, 400000)) {
+ return err;
+ }
+
// TODO: INT line
@@ -57,8 +61,8 @@ I2CTransaction::~I2CTransaction() {
free(buffer_);
}
-esp_err_t I2CTransaction::Execute() {
- return i2c_master_cmd_begin(I2C_NUM_0, handle_, kI2CTimeout);
+esp_err_t I2CTransaction::Execute(uint8_t port) {
+ return i2c_master_cmd_begin(port, handle_, kI2CTimeout);
}
I2CTransaction& I2CTransaction::start() {
diff --git a/src/drivers/include/i2c.hpp b/src/drivers/include/i2c.hpp
index dbdd8a11..811c9333 100644
--- a/src/drivers/include/i2c.hpp
+++ b/src/drivers/include/i2c.hpp
@@ -35,7 +35,7 @@ class I2CTransaction {
* ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.
* ESP_ERR_TIMEOUT Operation timeout because the bus is busy.
*/
- esp_err_t Execute();
+ esp_err_t Execute(uint8_t port = I2C_NUM_0);
/*
* Enqueues a start condition. May also be used for repeated start
diff --git a/src/drivers/include/touchwheel.hpp b/src/drivers/include/touchwheel.hpp
new file mode 100644
index 00000000..14215acd
--- /dev/null
+++ b/src/drivers/include/touchwheel.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+
+#include <functional>
+#include <stdint.h>
+
+#include "esp_err.h"
+#include "result.hpp"
+
+#include "gpio_expander.hpp"
+
+namespace drivers {
+
+struct TouchWheelData {
+ bool is_touched = false;
+ uint8_t wheel_position = -1;
+};
+
+class TouchWheel {
+ public:
+ enum Error {
+ FAILED_TO_BOOT,
+ FAILED_TO_CONFIGURE,
+ };
+ static auto create(GpioExpander* expander)
+ -> cpp::result<std::unique_ptr<TouchWheel>, Error>;
+
+ TouchWheel(GpioExpander* gpio);
+ ~TouchWheel();
+
+ // Not copyable or movable.
+ TouchWheel(const TouchWheel&) = delete;
+ TouchWheel& operator=(const TouchWheel&) = delete;
+
+ auto Update() -> void;
+ auto GetTouchWheelData() const -> TouchWheelData;
+
+ private:
+ GpioExpander* gpio_;
+ TouchWheelData data_;
+
+ enum Register {
+ FIRMWARE_VERSION = 0x1,
+ DETECTION_STATUS = 0x2,
+ KEY_STATUS_A = 0x3,
+ KEY_STATUS_B = 0x4,
+ SLIDER_POSITION = 0x5,
+ CALIBRATE = 0x6,
+ RESET = 0x7,
+ LOW_POWER = 0x8,
+ SLIDER_OPTIONS = 0x14,
+ };
+
+
+ void WriteRegister(uint8_t reg, uint8_t val);
+ void ReadRegister(uint8_t reg, uint8_t* data, uint8_t count);
+
+};
+
+} // namespace drivers
diff --git a/src/drivers/touchwheel.cpp b/src/drivers/touchwheel.cpp
new file mode 100644
index 00000000..11a115fb
--- /dev/null
+++ b/src/drivers/touchwheel.cpp
@@ -0,0 +1,92 @@
+#include "touchwheel.hpp"
+
+#include <cstdint>
+
+#include "assert.h"
+#include "driver/i2c.h"
+#include "esp_err.h"
+#include "esp_log.h"
+#include "hal/i2c_types.h"
+
+#include "i2c.hpp"
+
+namespace drivers {
+
+static const char* kTag = "TOUCHWHEEL";
+static const uint8_t kTouchWheelAddress = 0x1C;
+
+static const uint8_t kWriteMask = 0x80;
+static const uint8_t kReadMask = 0xA0;
+
+double normalise(uint16_t min, uint16_t max, uint16_t value) {
+ if (value >= max) {
+ return 1.0;
+ }
+ if (value <= min) {
+ return 0.0;
+ }
+ uint16_t range = max - min;
+ return (double)(value - min) / range;
+}
+
+
+auto TouchWheel::create(GpioExpander* expander)
+ -> cpp::result<std::unique_ptr<TouchWheel>, Error> {
+ std::unique_ptr<TouchWheel> wheel = std::make_unique<TouchWheel>(expander);
+ wheel->WriteRegister(Register::SLIDER_OPTIONS, 0xC0);
+ return wheel;
+}
+
+TouchWheel::TouchWheel(GpioExpander* gpio) {
+ this->gpio_ = gpio;
+};
+
+TouchWheel::~TouchWheel(){
+};
+
+void TouchWheel::WriteRegister(uint8_t reg, uint8_t val) {
+ // uint8_t maskedReg = reg | kWriteMask;
+ uint8_t maskedReg = reg;
+ I2CTransaction transaction;
+ transaction.start()
+ .write_addr(kTouchWheelAddress, I2C_MASTER_WRITE)
+ .write_ack(maskedReg, val)
+ .stop();
+ ESP_ERROR_CHECK(transaction.Execute());
+}
+
+void TouchWheel::ReadRegister(uint8_t reg, uint8_t* data, uint8_t count) {
+ // uint8_t maskedReg = reg | kReadMask;
+ uint8_t maskedReg = reg;
+
+ if (count <= 0) {
+ return;
+ }
+
+ I2CTransaction transaction;
+ transaction.start()
+ .write_addr(kTouchWheelAddress, I2C_MASTER_WRITE)
+ .write_ack(maskedReg)
+ .stop()
+ .start()
+ .write_addr(kTouchWheelAddress, I2C_MASTER_READ)
+ .read(data, I2C_MASTER_NACK)
+ .stop();
+
+ // TODO: Handle errors here.
+ ESP_ERROR_CHECK(transaction.Execute());
+}
+
+void TouchWheel::Update() {
+ // Read data from device into member struct
+ uint8_t position;
+ this->ReadRegister(Register::SLIDER_POSITION, &position, 1);
+ data_.wheel_position = position;
+}
+
+TouchWheelData TouchWheel::GetTouchWheelData() const {
+ return data_;
+}
+
+
+} // namespace drivers
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 91e17451..bd0a06af 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -35,6 +35,7 @@
#include "i2c.hpp"
#include "spi.hpp"
#include "storage.hpp"
+#include "touchwheel.hpp"
static const char* TAG = "MAIN";
@@ -102,6 +103,7 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Enable power rails for development");
expander->with([&](auto& gpio) {
gpio.set_pin(drivers::GpioExpander::AUDIO_POWER_ENABLE, 1);
+ gpio.set_pin(drivers::GpioExpander::DISPLAY_LED, 0);
gpio.set_pin(drivers::GpioExpander::USB_INTERFACE_POWER_ENABLE, 0);
gpio.set_pin(drivers::GpioExpander::SD_CARD_POWER_ENABLE, 1);
gpio.set_pin(drivers::GpioExpander::SD_MUX_SWITCH,
@@ -121,6 +123,15 @@ extern "C" void app_main(void) {
storage = std::move(storage_res.value());
}
+ ESP_LOGI(TAG, "Init touch wheel");
+ auto touchwheel_res = drivers::TouchWheel::create(expander);
+ std::shared_ptr<drivers::TouchWheel> touchwheel;
+ if (touchwheel_res.has_error()) {
+ ESP_LOGE(TAG, "Failed!");
+ } else {
+ touchwheel = std::move(touchwheel_res.value());
+ }
+
LvglArgs* lvglArgs = (LvglArgs*)calloc(1, sizeof(LvglArgs));
lvglArgs->gpio_expander = expander;
xTaskCreateStaticPinnedToCore(&lvgl_main, "LVGL", kLvglStackSize,
@@ -146,6 +157,8 @@ extern "C" void app_main(void) {
console.Launch();
while (1) {
+ touchwheel->Update();
+ ESP_LOGI(TAG, "Touch wheel pos: %d", touchwheel->GetTouchWheelData().wheel_position);
vTaskDelay(pdMS_TO_TICKS(100));
}
}