mirror of
https://github.com/esphome/esphome.git
synced 2025-09-17 10:42:21 +01:00
use conditional
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
namespace esphome::gpio_expander {
|
namespace esphome::gpio_expander {
|
||||||
@@ -20,14 +21,18 @@ namespace esphome::gpio_expander {
|
|||||||
/// Examples: MCP23017 (2x8-bit banks), TCA9555 (2x8-bit banks)
|
/// Examples: MCP23017 (2x8-bit banks), TCA9555 (2x8-bit banks)
|
||||||
/// * uint16_t: For chips that read all pins at once (up to 16 pins)
|
/// * uint16_t: For chips that read all pins at once (up to 16 pins)
|
||||||
/// Examples: PCF8574/8575 (8/16 pins), PCA9554/9555 (8/16 pins)
|
/// Examples: PCF8574/8575 (8/16 pins), PCA9554/9555 (8/16 pins)
|
||||||
/// N - Total number of pins (as uint8_t)
|
/// N - Total number of pins (maximum 65535)
|
||||||
template<typename T, uint8_t N> class CachedGpioExpander {
|
/// P - Type for pin number parameters (automatically selected based on N:
|
||||||
|
/// uint8_t for N<=256, uint16_t for N>256). Can be explicitly specified
|
||||||
|
/// if needed (e.g., for components like SN74HC165 with >256 pins)
|
||||||
|
template<typename T, uint16_t N, typename P = typename std::conditional<(N > 256), uint16_t, uint8_t>::type>
|
||||||
|
class CachedGpioExpander {
|
||||||
public:
|
public:
|
||||||
/// @brief Read the state of the given pin. This will invalidate the cache for the given pin number.
|
/// @brief Read the state of the given pin. This will invalidate the cache for the given pin number.
|
||||||
/// @param pin Pin number to read
|
/// @param pin Pin number to read
|
||||||
/// @return Pin state
|
/// @return Pin state
|
||||||
bool digital_read(uint8_t pin) {
|
bool digital_read(P pin) {
|
||||||
const uint8_t bank = pin / BANK_SIZE;
|
const P bank = pin / BANK_SIZE;
|
||||||
const T pin_mask = (1 << (pin % BANK_SIZE));
|
const T pin_mask = (1 << (pin % BANK_SIZE));
|
||||||
// Check if specific pin cache is valid
|
// Check if specific pin cache is valid
|
||||||
if (this->read_cache_valid_[bank] & pin_mask) {
|
if (this->read_cache_valid_[bank] & pin_mask) {
|
||||||
@@ -43,7 +48,7 @@ template<typename T, uint8_t N> class CachedGpioExpander {
|
|||||||
return this->digital_read_cache(pin);
|
return this->digital_read_cache(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void digital_write(uint8_t pin, bool value) { this->digital_write_hw(pin, value); }
|
void digital_write(P pin, bool value) { this->digital_write_hw(pin, value); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief Read GPIO bank from hardware into internal state
|
/// @brief Read GPIO bank from hardware into internal state
|
||||||
@@ -51,23 +56,23 @@ template<typename T, uint8_t N> class CachedGpioExpander {
|
|||||||
/// @return true if read succeeded, false on communication error
|
/// @return true if read succeeded, false on communication error
|
||||||
/// @note This does NOT return the pin state. It returns whether the read operation succeeded.
|
/// @note This does NOT return the pin state. It returns whether the read operation succeeded.
|
||||||
/// The actual pin state should be returned by digital_read_cache().
|
/// The actual pin state should be returned by digital_read_cache().
|
||||||
virtual bool digital_read_hw(uint8_t pin) = 0;
|
virtual bool digital_read_hw(P pin) = 0;
|
||||||
|
|
||||||
/// @brief Get cached pin value from internal state
|
/// @brief Get cached pin value from internal state
|
||||||
/// @param pin Pin number to read
|
/// @param pin Pin number to read
|
||||||
/// @return Pin state (true = HIGH, false = LOW)
|
/// @return Pin state (true = HIGH, false = LOW)
|
||||||
virtual bool digital_read_cache(uint8_t pin) = 0;
|
virtual bool digital_read_cache(P pin) = 0;
|
||||||
|
|
||||||
/// @brief Write GPIO state to hardware
|
/// @brief Write GPIO state to hardware
|
||||||
/// @param pin Pin number to write
|
/// @param pin Pin number to write
|
||||||
/// @param value Pin state to write (true = HIGH, false = LOW)
|
/// @param value Pin state to write (true = HIGH, false = LOW)
|
||||||
virtual void digital_write_hw(uint8_t pin, bool value) = 0;
|
virtual void digital_write_hw(P pin, bool value) = 0;
|
||||||
|
|
||||||
/// @brief Invalidate cache. This function should be called in component loop().
|
/// @brief Invalidate cache. This function should be called in component loop().
|
||||||
void reset_pin_cache_() { memset(this->read_cache_valid_, 0x00, CACHE_SIZE_BYTES); }
|
void reset_pin_cache_() { memset(this->read_cache_valid_, 0x00, CACHE_SIZE_BYTES); }
|
||||||
|
|
||||||
static constexpr uint8_t BITS_PER_BYTE = 8;
|
static constexpr uint16_t BITS_PER_BYTE = 8;
|
||||||
static constexpr uint8_t BANK_SIZE = sizeof(T) * BITS_PER_BYTE;
|
static constexpr uint16_t BANK_SIZE = sizeof(T) * BITS_PER_BYTE;
|
||||||
static constexpr size_t BANKS = N / BANK_SIZE;
|
static constexpr size_t BANKS = N / BANK_SIZE;
|
||||||
static constexpr size_t CACHE_SIZE_BYTES = BANKS * sizeof(T);
|
static constexpr size_t CACHE_SIZE_BYTES = BANKS * sizeof(T);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user