Touchwheel test

custom
ailurux 2 years ago
parent b9a75cd55a
commit 78ec09c494
  1. 1
      lib/esp-adf
  2. 2
      src/drivers/CMakeLists.txt
  3. 8
      src/drivers/i2c.cpp
  4. 2
      src/drivers/include/i2c.hpp
  5. 60
      src/drivers/include/touchwheel.hpp
  6. 92
      src/drivers/touchwheel.cpp
  7. 13
      src/main/main.cpp

@ -0,0 +1 @@
Subproject commit 9ffbb5a1b8be06484e23e67202607e6b0b0d3a8e

@ -1,5 +1,5 @@
idf_component_register( 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" "spi.cpp" "display.cpp" "display_init.cpp"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span") REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span")

@ -36,6 +36,10 @@ esp_err_t init_i2c(void) {
if (esp_err_t err = i2c_driver_install(kI2CPort, config.mode, 0, 0, 0)) { if (esp_err_t err = i2c_driver_install(kI2CPort, config.mode, 0, 0, 0)) {
return err; return err;
} }
if (esp_err_t err = i2c_set_timeout(kI2CPort, 400000)) {
return err;
}
// TODO: INT line // TODO: INT line
@ -57,8 +61,8 @@ I2CTransaction::~I2CTransaction() {
free(buffer_); free(buffer_);
} }
esp_err_t I2CTransaction::Execute() { esp_err_t I2CTransaction::Execute(uint8_t port) {
return i2c_master_cmd_begin(I2C_NUM_0, handle_, kI2CTimeout); return i2c_master_cmd_begin(port, handle_, kI2CTimeout);
} }
I2CTransaction& I2CTransaction::start() { I2CTransaction& I2CTransaction::start() {

@ -35,7 +35,7 @@ class I2CTransaction {
* ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode. * 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_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 * Enqueues a start condition. May also be used for repeated start

@ -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

@ -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

@ -35,6 +35,7 @@
#include "i2c.hpp" #include "i2c.hpp"
#include "spi.hpp" #include "spi.hpp"
#include "storage.hpp" #include "storage.hpp"
#include "touchwheel.hpp"
static const char* TAG = "MAIN"; static const char* TAG = "MAIN";
@ -102,6 +103,7 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Enable power rails for development"); ESP_LOGI(TAG, "Enable power rails for development");
expander->with([&](auto& gpio) { expander->with([&](auto& gpio) {
gpio.set_pin(drivers::GpioExpander::AUDIO_POWER_ENABLE, 1); 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::USB_INTERFACE_POWER_ENABLE, 0);
gpio.set_pin(drivers::GpioExpander::SD_CARD_POWER_ENABLE, 1); gpio.set_pin(drivers::GpioExpander::SD_CARD_POWER_ENABLE, 1);
gpio.set_pin(drivers::GpioExpander::SD_MUX_SWITCH, gpio.set_pin(drivers::GpioExpander::SD_MUX_SWITCH,
@ -121,6 +123,15 @@ extern "C" void app_main(void) {
storage = std::move(storage_res.value()); 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* lvglArgs = (LvglArgs*)calloc(1, sizeof(LvglArgs));
lvglArgs->gpio_expander = expander; lvglArgs->gpio_expander = expander;
xTaskCreateStaticPinnedToCore(&lvgl_main, "LVGL", kLvglStackSize, xTaskCreateStaticPinnedToCore(&lvgl_main, "LVGL", kLvglStackSize,
@ -146,6 +157,8 @@ extern "C" void app_main(void) {
console.Launch(); console.Launch();
while (1) { while (1) {
touchwheel->Update();
ESP_LOGI(TAG, "Touch wheel pos: %d", touchwheel->GetTouchWheelData().wheel_position);
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(100));
} }
} }

Loading…
Cancel
Save