Skip to content

Commit

Permalink
Feature/base peripheral (#150)
Browse files Browse the repository at this point in the history
* feat(base_peripheral): added base peripheral class

* doc: include base peripheral in doc

* feat: update peripherals
* Update peripheral classes to use new base_peripheral as the base class

* doc: rebuild

* fix: fix bldc_motor and bldc_haptics  example for breaking change to mt6701 config (read -> read_register)

* fix(bldc_driver): ensure configuration structs are zeroed out

* example(tla2528): update
* Updated tla2528 example to test all analog input channels

* fix(max1704x): fix u8 read to make it u16 so it reads the right values

* fix: typo

* doc: rebuild

* fix(gt911): fix reading / writing 16bit register addresses
  • Loading branch information
finger563 authored Feb 12, 2024
1 parent ae9724d commit bd2353f
Show file tree
Hide file tree
Showing 148 changed files with 4,414 additions and 1,738 deletions.
2 changes: 1 addition & 1 deletion components/ads1x15/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
idf_component_register(
INCLUDE_DIRS "include"
SRC_DIRS "src"
REQUIRES "logger" "pthread"
REQUIRES "base_peripheral" "pthread"
)
9 changes: 5 additions & 4 deletions components/ads1x15/example/main/ads1x15_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ extern "C" void app_main(void) {
// make the actual ads class
espp::Ads1x15 ads(espp::Ads1x15::Ads1015Config{
.device_address = espp::Ads1x15::DEFAULT_ADDRESS,
.write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3),
.read = std::bind(&espp::I2c::read, &i2c, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3)});
.write = [&i2c](uint8_t addr, const uint8_t *data,
size_t len) { return i2c.write(addr, data, len); },
.read = [&i2c](uint8_t addr, uint8_t *data,
size_t len) { return i2c.read(addr, data, len); },
});
// make the task which will get the raw data from the I2C ADC
auto ads_read_task_fn = [&ads](std::mutex &m, std::condition_variable &cv) {
static auto start = std::chrono::high_resolution_clock::now();
Expand Down
83 changes: 18 additions & 65 deletions components/ads1x15/include/ads1x15.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

#include <chrono>
#include <functional>
#include <mutex>
#include <thread>

#include "logger.hpp"
#include "base_peripheral.hpp"

namespace espp {
/**
Expand All @@ -14,28 +13,10 @@ namespace espp {
* \section ads1x15_ex1 ADS1X15 Example
* \snippet ads1x15_example.cpp ads1x15 example
*/
class Ads1x15 {
class Ads1x15 : public espp::BasePeripheral {
public:
static constexpr uint8_t DEFAULT_ADDRESS = (0x48); ///< I2C address of the ADS1x15 chips.

/**
* @brief Function to write bytes to the device.
* @param dev_addr Address of the device to write to.
* @param data Pointer to array of bytes to write.
* @param data_len Number of data bytes to write.
* @return True if the write was successful.
*/
typedef std::function<bool(uint8_t dev_addr, uint8_t *data, size_t data_len)> write_fn;

/**
* @brief Function to read bytes from the device.
* @param dev_addr Address of the device to write to.
* @param data Pointer to array of bytes to read into.
* @param data_len Number of data bytes to read.
* @return True if the read was successful.
*/
typedef std::function<bool(uint8_t dev_addr, uint8_t *data, size_t data_len)> read_fn;

/**
* @brief Gain values for the ADC conversion.
*/
Expand Down Expand Up @@ -80,8 +61,8 @@ class Ads1x15 {
*/
struct Ads1015Config {
uint8_t device_address = DEFAULT_ADDRESS; ///< I2C address of the device.
write_fn write; ///< Function to write to the ADC
read_fn read; ///< Function to read from the ADC
BasePeripheral::write_fn write; ///< Function to write to the ADC
BasePeripheral::read_fn read; ///< Function to read from the ADC
Gain gain{Gain::TWOTHIRDS}; ///< Gain for the ADC
Ads1015Rate sample_rate{Ads1015Rate::SPS1600}; ///< Sample rate for the ADC
espp::Logger::Verbosity log_level{espp::Logger::Verbosity::WARN}; ///< Verbosity for the logger.
Expand All @@ -92,8 +73,8 @@ class Ads1x15 {
*/
struct Ads1115Config {
uint8_t device_address = DEFAULT_ADDRESS; ///< I2C address of the device.
write_fn write; ///< Function to write to the ADC
read_fn read; ///< Function to read from the ADC
BasePeripheral::write_fn write; ///< Function to write to the ADC
BasePeripheral::read_fn read; ///< Function to read from the ADC
Gain gain{Gain::TWOTHIRDS}; ///< Gain for the ADC
Ads1115Rate sample_rate{Ads1115Rate::SPS128}; ///< Sample rate for the ADC
espp::Logger::Verbosity log_level{espp::Logger::Verbosity::WARN}; ///< Verbosity for the logger.
Expand All @@ -104,18 +85,24 @@ class Ads1x15 {
* @param config Configuration structure.
*/
explicit Ads1x15(const Ads1015Config &config)
: gain_(config.gain), ads1015rate_(config.sample_rate), bit_shift_(4),
address_(config.device_address), write_(config.write), read_(config.read),
logger_({.tag = "Ads1015", .level = config.log_level}) {}
: BasePeripheral(
{.address = config.device_address, .write = config.write, .read = config.read},
"Ads1015", config.log_level)
, gain_(config.gain)
, ads1015rate_(config.sample_rate)
, bit_shift_(4) {}

/**
* @brief Construct Ads1x15 specficially for ADS1115.
* @param config Configuration structure.
*/
explicit Ads1x15(const Ads1115Config &config)
: gain_(config.gain), ads1115rate_(config.sample_rate), bit_shift_(0),
address_(config.device_address), write_(config.write), read_(config.read),
logger_({.tag = "Ads1115", .level = config.log_level}) {}
: BasePeripheral(
{.address = config.device_address, .write = config.write, .read = config.read},
"Ads1115", config.log_level)
, gain_(config.gain)
, ads1115rate_(config.sample_rate)
, bit_shift_(0) {}

/**
* @brief Communicate with the ADC to sample the channel and return the
Expand Down Expand Up @@ -165,35 +152,6 @@ class Ads1x15 {
return raw * (fsRange / (32768 >> bit_shift_));
}

uint16_t read_two_(uint8_t reg_addr, std::error_code &ec) {
// lock the mutex so that we don't have multiple threads trying to read
// from the device at the same time
std::lock_guard<std::mutex> lock(mutex_);
// write the reg addr we want to read from
bool success = write_(address_, &reg_addr, 1);
if (!success) {
ec = std::make_error_code(std::errc::io_error);
return 0;
}
// then read the two bytes
uint8_t data[2];
success = read_(address_, data, 2);
if (!success) {
ec = std::make_error_code(std::errc::io_error);
return 0;
}
return (data[0] << 8) | data[1];
}

void write_two_(uint8_t reg_addr, uint16_t value, std::error_code &ec) {
uint8_t total_len = 3;
uint8_t data[total_len] = {reg_addr, (uint8_t)(value >> 8), (uint8_t)(value & 0xFF)};
bool success = write_(address_, data, total_len);
if (!success) {
ec = std::make_error_code(std::errc::io_error);
}
}

enum class Register : uint8_t {
POINTER_CONVERT = 0x00, ///< Conversion
POINTER_CONFIG = 0x01, ///< Configuration
Expand All @@ -208,10 +166,5 @@ class Ads1x15 {
uint16_t rate_;
};
int bit_shift_;
uint8_t address_;
write_fn write_;
read_fn read_;
std::mutex mutex_;
espp::Logger logger_;
};
} // namespace espp
14 changes: 5 additions & 9 deletions components/ads1x15/src/ads1x15.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ static constexpr uint16_t REG_CONFIG_CQUE_NONE =
(0x0003); ///< Disable the comparator and put ALERT/RDY in high state (default)

int16_t Ads1x15::sample_raw(int channel, std::error_code &ec) {
if (!write_ || !read_) {
logger_.error("Write / read functions not properly configured, cannot sample!");
return 0;
}
// Start with default values
uint16_t config = REG_CONFIG_MODE_SINGLE;
// This is equivalent to the below (since the rest are 0x0000):
Expand All @@ -72,17 +68,17 @@ int16_t Ads1x15::sample_raw(int channel, std::error_code &ec) {
config |= REG_CONFIG_OS_SINGLE;
// configure to read from mux 0
logger_.debug("configuring conversion for channel {}", channel);
write_two_((uint8_t)Register::POINTER_CONFIG, config, ec);
write_u16_to_register((uint8_t)Register::POINTER_CONFIG, config, ec);
if (ec) {
logger_.error("error configuring conversion for channel {}", channel);
return 0;
}
write_two_((uint8_t)Register::POINTER_HITHRESH, 0x8000, ec);
write_u16_to_register((uint8_t)Register::POINTER_HITHRESH, 0x8000, ec);
if (ec) {
logger_.error("error configuring hi threshold for channel {}", channel);
return 0;
}
write_two_((uint8_t)Register::POINTER_LOWTHRESH, 0x0000, ec);
write_u16_to_register((uint8_t)Register::POINTER_LOWTHRESH, 0x0000, ec);
if (ec) {
logger_.error("error configuring low threshold for channel {}", channel);
return 0;
Expand All @@ -97,7 +93,7 @@ int16_t Ads1x15::sample_raw(int channel, std::error_code &ec) {
return 0;
}
logger_.debug("reading conversion result for channel {}", channel);
uint16_t val = read_two_((uint8_t)Register::POINTER_CONVERT, ec) >> bit_shift_;
uint16_t val = read_u16_from_register((uint8_t)Register::POINTER_CONVERT, ec) >> bit_shift_;
if (ec) {
logger_.error("error reading conversion result for channel {}", channel);
return 0;
Expand All @@ -112,7 +108,7 @@ int16_t Ads1x15::sample_raw(int channel, std::error_code &ec) {
}

bool Ads1x15::conversion_complete(std::error_code &ec) {
auto val = read_two_((uint8_t)Register::POINTER_CONFIG, ec);
auto val = read_u16_from_register((uint8_t)Register::POINTER_CONFIG, ec);
if (ec) {
logger_.error("error reading config register");
return false;
Expand Down
2 changes: 1 addition & 1 deletion components/ads7138/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
REQUIRES "logger"
REQUIRES "base_peripheral"
)
Loading

0 comments on commit bd2353f

Please sign in to comment.