|
|
|
@ -1,11 +1,15 @@ |
|
|
|
|
#include "touchwheel.hpp" |
|
|
|
|
#include <stdint.h> |
|
|
|
|
|
|
|
|
|
#include <cstdint> |
|
|
|
|
|
|
|
|
|
#include "assert.h" |
|
|
|
|
#include "driver/gpio.h" |
|
|
|
|
#include "driver/i2c.h" |
|
|
|
|
#include "esp_err.h" |
|
|
|
|
#include "esp_log.h" |
|
|
|
|
#include "freertos/projdefs.h" |
|
|
|
|
#include "hal/gpio_types.h" |
|
|
|
|
#include "hal/i2c_types.h" |
|
|
|
|
|
|
|
|
|
#include "i2c.hpp" |
|
|
|
@ -15,34 +19,18 @@ 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; |
|
|
|
|
TouchWheel::TouchWheel() { |
|
|
|
|
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_INPUT); |
|
|
|
|
gpio_set_pull_mode(GPIO_NUM_25, GPIO_PULLUP_ONLY); |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
WriteRegister(Register::RESET, 1); |
|
|
|
|
// TODO(daniel): do we need this? how long does reset take?
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); |
|
|
|
|
WriteRegister(Register::SLIDER_OPTIONS, 0b11000000); |
|
|
|
|
WriteRegister(Register::CALIBRATE, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TouchWheel::TouchWheel(GpioExpander* gpio) { |
|
|
|
|
this->gpio_ = gpio; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
TouchWheel::~TouchWheel(){ |
|
|
|
|
}; |
|
|
|
|
TouchWheel::~TouchWheel() {} |
|
|
|
|
|
|
|
|
|
void TouchWheel::WriteRegister(uint8_t reg, uint8_t val) { |
|
|
|
|
// uint8_t maskedReg = reg | kWriteMask;
|
|
|
|
@ -55,38 +43,43 @@ void TouchWheel::WriteRegister(uint8_t reg, uint8_t val) { |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t TouchWheel::ReadRegister(uint8_t reg) { |
|
|
|
|
uint8_t res; |
|
|
|
|
I2CTransaction transaction; |
|
|
|
|
transaction.start() |
|
|
|
|
.write_addr(kTouchWheelAddress, I2C_MASTER_WRITE) |
|
|
|
|
.write_ack(maskedReg) |
|
|
|
|
.stop() |
|
|
|
|
.write_ack(reg) |
|
|
|
|
.start() |
|
|
|
|
.write_addr(kTouchWheelAddress, I2C_MASTER_READ) |
|
|
|
|
.read(data, I2C_MASTER_NACK) |
|
|
|
|
.read(&res, I2C_MASTER_NACK) |
|
|
|
|
.stop(); |
|
|
|
|
|
|
|
|
|
// TODO: Handle errors here.
|
|
|
|
|
ESP_ERROR_CHECK(transaction.Execute()); |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TouchWheel::Update() { |
|
|
|
|
// Read data from device into member struct
|
|
|
|
|
uint8_t position; |
|
|
|
|
this->ReadRegister(Register::SLIDER_POSITION, &position, 1); |
|
|
|
|
data_.wheel_position = position; |
|
|
|
|
// Read data from device into member struct
|
|
|
|
|
bool has_data = !gpio_get_level(GPIO_NUM_25); |
|
|
|
|
if (!has_data) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
uint8_t status = ReadRegister(Register::DETECTION_STATUS); |
|
|
|
|
if (status & 0b10000000) { |
|
|
|
|
// Still calibrating.
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (status & 0b10) { |
|
|
|
|
// Slider detect.
|
|
|
|
|
data_.wheel_position = ReadRegister(Register::SLIDER_POSITION); |
|
|
|
|
} |
|
|
|
|
if (status & 0b1) { |
|
|
|
|
// Key detect.
|
|
|
|
|
// TODO(daniel): implement me
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TouchWheelData TouchWheel::GetTouchWheelData() const { |
|
|
|
|
return data_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace drivers
|
|
|
|
|