Skip to content

Commit

Permalink
feat(base_peripheral): update how multi-byte registers are handled
Browse files Browse the repository at this point in the history
* Update how multi-byte registers are handled in base_peripheral and add additional logging for help debugging
* Update gt911 and st25dv to subclass with register size 16 bit
  • Loading branch information
finger563 committed Feb 13, 2024
1 parent 8d5c437 commit a3525f3
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 43 deletions.
69 changes: 52 additions & 17 deletions components/base_peripheral/include/base_peripheral.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,15 @@ class BasePeripheral : public BaseComponent {
size_t read_length, std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
if (base_config_.write_then_read) {
logger_.debug("write_then_read {} bytes", write_length);
if (!base_config_.write_then_read(base_config_.address, write_data, write_length, read_data,
read_length)) {
ec = std::make_error_code(std::errc::io_error);
} else {
ec.clear();
}
} else if (base_config_.write && base_config_.read) {
logger_.debug("write {} bytes then read {} bytes", write_length, read_length);
// write the data
if (!base_config_.write(base_config_.address, write_data, write_length)) {
ec = std::make_error_code(std::errc::io_error);
Expand All @@ -232,13 +234,12 @@ class BasePeripheral : public BaseComponent {
void write_u8_to_register(RegisterAddressType reg_addr, uint8_t data, std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
if (base_config_.write) {
logger_.debug("write 1 byte to register 0x{:x}", reg_addr);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[reg_addr_size + 1];
for (size_t i = 0; i < reg_addr_size; i++) {
buffer[i] = (reg_addr >> (i * 8)) & 0xff;
}
put_register_bytes(reg_addr, buffer);
buffer[reg_addr_size] = data;
if (!base_config_.write(base_config_.address, buffer, reg_addr_size + 1)) {
ec = std::make_error_code(std::errc::io_error);
Expand All @@ -257,13 +258,12 @@ class BasePeripheral : public BaseComponent {
void write_u16_to_register(RegisterAddressType reg_addr, uint16_t data, std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
if (base_config_.write) {
logger_.debug("write 2 bytes to register 0x{:x}", reg_addr);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[reg_addr_size + 2];
for (size_t i = 0; i < reg_addr_size; i++) {
buffer[i] = (reg_addr >> (i * 8)) & 0xff;
}
put_register_bytes(reg_addr, buffer);
buffer[reg_addr_size] = (data >> 8) & 0xff;
buffer[reg_addr_size + 1] = data & 0xff;
if (!base_config_.write(base_config_.address, buffer, reg_addr_size + 2)) {
Expand All @@ -285,13 +285,12 @@ class BasePeripheral : public BaseComponent {
std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
if (base_config_.write) {
logger_.debug("write {} bytes to register 0x{:x}", length, reg_addr);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[length + reg_addr_size];
for (size_t i = 0; i < reg_addr_size; i++) {
buffer[i] = (reg_addr >> (i * 8)) & 0xff;
}
put_register_bytes(reg_addr, buffer);
std::copy(data, data + length, buffer + reg_addr_size);
if (!base_config_.write(base_config_.address, buffer, length + reg_addr_size)) {
ec = std::make_error_code(std::errc::io_error);
Expand All @@ -307,17 +306,23 @@ class BasePeripheral : public BaseComponent {
/// \param register_address The address of the register to read from
/// \param ec The error code to set if there is an error
/// \return The data read from the peripheral
uint8_t read_u8_from_register(uint8_t register_address, std::error_code &ec) {
uint8_t read_u8_from_register(RegisterAddressType register_address, std::error_code &ec) {
uint8_t data = 0;
if (base_config_.read_register) {
logger_.debug("read_register 1 byte from register 0x{:x}", register_address);
if (!base_config_.read_register(base_config_.address, register_address, &data, 1)) {
ec = std::make_error_code(std::errc::io_error);
return 0;
} else {
ec.clear();
}
} else {
write_then_read(&register_address, 1, &data, 1, ec);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[reg_addr_size];
put_register_bytes(register_address, buffer);
write_then_read(buffer, reg_addr_size, &data, 1, ec);
if (ec) {
return 0;
}
Expand All @@ -329,17 +334,23 @@ class BasePeripheral : public BaseComponent {
/// \param register_address The address of the register to read from
/// \param ec The error code to set if there is an error
/// \return The data read from the peripheral
uint16_t read_u16_from_register(uint8_t register_address, std::error_code &ec) {
uint16_t read_u16_from_register(RegisterAddressType register_address, std::error_code &ec) {
uint8_t data[2];
if (base_config_.read_register) {
logger_.debug("read_register 2 bytes from register 0x{:x}", register_address);
if (!base_config_.read_register(base_config_.address, register_address, data, 2)) {
ec = std::make_error_code(std::errc::io_error);
return 0;
} else {
ec.clear();
}
} else {
write_then_read(&register_address, 1, (uint8_t *)&data, 2, ec);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[reg_addr_size];
put_register_bytes(register_address, buffer);
write_then_read(buffer, reg_addr_size, (uint8_t *)&data, 2, ec);
if (ec) {
return 0;
}
Expand All @@ -352,17 +363,23 @@ class BasePeripheral : public BaseComponent {
/// \param data The buffer to read into
/// \param length The length of the buffer
/// \param ec The error code to set if there is an error
void read_many_from_register(uint8_t register_address, uint8_t *data, size_t length,
void read_many_from_register(RegisterAddressType register_address, uint8_t *data, size_t length,
std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
if (base_config_.read_register) {
logger_.debug("read_register {} bytes from register 0x{:x}", length, register_address);
if (!base_config_.read_register(base_config_.address, register_address, data, length)) {
ec = std::make_error_code(std::errc::io_error);
} else {
ec.clear();
}
} else {
write_then_read(&register_address, 1, data, length, ec);
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
uint8_t buffer[reg_addr_size];
put_register_bytes(register_address, buffer);
write_then_read(buffer, reg_addr_size, data, length, ec);
}
}

Expand All @@ -372,7 +389,8 @@ class BasePeripheral : public BaseComponent {
/// \param ec The error code to set if there is an error
/// \note This function reads the register, sets the bits, and then writes the register
/// back to the peripheral
void set_bits_in_register(uint8_t register_address, uint8_t mask, std::error_code &ec) {
void set_bits_in_register(RegisterAddressType register_address, uint8_t mask,
std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
uint8_t data = read_u8_from_register(register_address, ec);
if (ec) {
Expand All @@ -388,7 +406,8 @@ class BasePeripheral : public BaseComponent {
/// \param ec The error code to set if there is an error
/// \note This function reads the register, clears the bits, and then writes the register
/// back to the peripheral
void clear_bits_in_register(uint8_t register_address, uint8_t mask, std::error_code &ec) {
void clear_bits_in_register(RegisterAddressType register_address, uint8_t mask,
std::error_code &ec) {
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
uint8_t data = read_u8_from_register(register_address, ec);
if (ec) {
Expand All @@ -398,6 +417,22 @@ class BasePeripheral : public BaseComponent {
write_u8_to_register(register_address, data, ec);
}

// Set the bytes of the register address in the buffer
void put_register_bytes(RegisterAddressType register_address, uint8_t *data) {
if constexpr (std::is_same_v<RegisterAddressType, uint8_t>) {
data[0] = register_address;
} else {
// use the size of the register address to determine how many bytes the
// register address is
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
// encode the address as big endian (MSB first)
for (size_t i = 0; i < reg_addr_size; i++) {
int shift = (reg_addr_size - i - 1) * 8;
data[i] = (register_address >> shift) & 0xff;
}
}
}

Config base_config_; ///< The configuration for the peripheral
std::recursive_mutex base_mutex_; ///< The mutex to protect access to the peripheral
};
Expand Down
26 changes: 5 additions & 21 deletions components/gt911/include/gt911.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace espp {
///
/// \section Example
/// \snippet gt911_example.cpp gt911 example
class Gt911 : public BasePeripheral<> {
class Gt911 : public BasePeripheral<std::uint16_t> {
public:
/// Default address for the GT911 chip
static constexpr uint8_t DEFAULT_ADDRESS_1 = 0x5D;
Expand Down Expand Up @@ -38,14 +38,15 @@ class Gt911 : public BasePeripheral<> {
bool update(std::error_code &ec) {
static constexpr size_t DATA_LEN = CONTACT_SIZE * MAX_CONTACTS;
static uint8_t data[DATA_LEN];
read_register(Registers::POINT_INFO, data, 1, ec);
read_many_from_register((uint16_t)Registers::POINT_INFO, data, 1, ec);
if (ec) {
return false;
}
num_touch_points_ = data[0] & 0x0f;
logger_.debug("Got {} touch points", num_touch_points_);
if (num_touch_points_ > 0) {
read_register(Registers::POINTS, data, CONTACT_SIZE * num_touch_points_, ec);
read_many_from_register((uint16_t)Registers::POINTS, data, CONTACT_SIZE * num_touch_points_,
ec);
if (ec) {
return false;
}
Expand All @@ -55,7 +56,7 @@ class Gt911 : public BasePeripheral<> {
y_ = point->y;
logger_.debug("Touch at ({}, {})", x_, y_);
}
write_register(Registers::POINT_INFO, 0x00, ec); // sync signal
write_u8_to_register((uint16_t)Registers::POINT_INFO, 0x00, ec); // sync signal
if (ec) {
return false;
}
Expand Down Expand Up @@ -227,23 +228,6 @@ class Gt911 : public BasePeripheral<> {
GTKeyConfig keys;
} __attribute__((packed));

// we use write_then_read since we have to write the u16 register address and
// then read the data
void read_register(Registers reg, uint8_t *data, size_t len, std::error_code &ec) {
uint16_t reg16 = static_cast<uint16_t>(reg);
uint8_t reg_buf[2] = {static_cast<uint8_t>(reg16 >> 8), static_cast<uint8_t>(reg16 & 0xff)};
write_then_read(reg_buf, 2, data, len, ec);
}

void write_register(Registers reg, const uint8_t value, std::error_code &ec) {
uint16_t reg16 = static_cast<uint16_t>(reg);
uint8_t write_buf[3];
write_buf[0] = static_cast<uint8_t>(reg16 >> 8);
write_buf[1] = static_cast<uint8_t>(reg16 & 0xff);
write_buf[2] = value;
write_many(write_buf, 3, ec);
}

std::atomic<bool> home_button_pressed_{false};
std::atomic<uint8_t> num_touch_points_;
std::atomic<uint16_t> x_;
Expand Down
8 changes: 3 additions & 5 deletions components/st25dv/include/st25dv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace espp {
* \section st25dv_ex1 St25dv Example
* \snippet st25dv_example.cpp st25dv example
*/
class St25dv : public BasePeripheral<> {
class St25dv : public BasePeripheral<uint16_t> {
public:
// NOTE: when the datasheet mentions E2 device select, they are talking
// about Bit 4 of the address which selects between the data (user memory,
Expand Down Expand Up @@ -575,8 +575,7 @@ class St25dv : public BasePeripheral<> {

void read_syst_register(Registers reg, uint8_t *data, uint8_t length, std::error_code &ec) {
uint8_t reg_addr[2];
reg_addr[0] = (uint16_t)reg >> 8;
reg_addr[1] = (uint16_t)reg & 0xFF;
put_register_bytes((uint16_t)reg, reg_addr);
bool success = base_config_.write(SYST_ADDRESS, reg_addr, 2);
if (!success) {
ec = std::make_error_code(std::errc::io_error);
Expand All @@ -592,8 +591,7 @@ class St25dv : public BasePeripheral<> {

void read_data_register(Registers reg, uint8_t *data, uint8_t length, std::error_code &ec) {
uint8_t reg_addr[2];
reg_addr[0] = (uint16_t)reg >> 8;
reg_addr[1] = (uint16_t)reg & 0xFF;
put_register_bytes((uint16_t)reg, reg_addr);
bool success = base_config_.write(DATA_ADDRESS, reg_addr, 2);
if (!success) {
ec = std::make_error_code(std::errc::io_error);
Expand Down

0 comments on commit a3525f3

Please sign in to comment.