diff --git a/CODEOWNERS b/CODEOWNERS index 204d2b58bd..6db701eaf2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -226,6 +226,7 @@ esphome/components/inkplate6/* @jesserockz esphome/components/integration/* @OttoWinter esphome/components/internal_temperature/* @Mat931 esphome/components/interval/* @esphome/core +esphome/components/io_bus/* @clydebarrow esphome/components/jsn_sr04t/* @Mafus1 esphome/components/json/* @OttoWinter esphome/components/kamstrup_kmp/* @cfeenstra1024 diff --git a/esphome/components/io_bus/__init__.py b/esphome/components/io_bus/__init__.py new file mode 100644 index 0000000000..4530649f74 --- /dev/null +++ b/esphome/components/io_bus/__init__.py @@ -0,0 +1,8 @@ +import esphome.codegen as cg + +io_bus_ns = cg.esphome_ns.namespace("io_bus") +IOBus = io_bus_ns.class_("IOBus") + +CODEOWNERS = ["@clydebarrow"] +# Allow configuration in yaml, for testing +CONFIG_SCHEMA = {} diff --git a/esphome/components/io_bus/io_bus.h b/esphome/components/io_bus/io_bus.h new file mode 100644 index 0000000000..e93b96535f --- /dev/null +++ b/esphome/components/io_bus/io_bus.h @@ -0,0 +1,73 @@ +#pragma once + +#include "esphome/core/log.h" +#include "esphome/core/gpio.h" + +namespace esphome { +namespace io_bus { + +/** + * A pin to replace those that don't exist. + */ +class NullPin : public GPIOPin { + public: + void setup() override {} + + void pin_mode(gpio::Flags _) override {} + + bool digital_read() override { return false; } + + void digital_write(bool _) override {} + + std::string dump_summary() const override { return {"Not used"}; } + + gpio::Flags get_flags() const override { return gpio::Flags{}; } +}; + +// https://bugs.llvm.org/show_bug.cgi?id=48040 +static GPIOPin *const NULL_PIN = new NullPin(); // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +/** + * A class that can write a byte-oriented bus interface with CS and DC controls, typically used for + * LCD display controller interfacing. + */ +class IOBus { + public: + virtual void bus_setup() = 0; + + virtual void bus_teardown() = 0; + + /** + * Write a data array. Will not control dc or cs pins. + * @param data + * @param length + */ + virtual void write_array(const uint8_t *data, size_t length) = 0; + + /** + * Write a command followed by data. CS and DC will be controlled automatically. + * On return, the DC pin will be in DATA mode. + * @param cmd An 8 bit command. Passing -1 will suppress the command phase + * @param data The data to write. May be null if length==0 + * @param length The number of data bytes to write (excludes the command byte) + */ + virtual void write_cmd_data(int cmd, const uint8_t *data, size_t length) = 0; + + /** + * Convenience function for parameterless commands. + * @param cmd The 8 bit command. + */ + void write_cmd(uint8_t cmd) { this->write_cmd_data(cmd, nullptr, 0); } + + virtual void dump_config(){}; + + virtual void begin_transaction() = 0; + virtual void end_transaction() = 0; + + void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; } + + protected: + GPIOPin *dc_pin_{io_bus::NULL_PIN}; +}; +} // namespace io_bus +} // namespace esphome diff --git a/tests/components/io_bus/common.yaml b/tests/components/io_bus/common.yaml new file mode 100644 index 0000000000..40fecb7d14 --- /dev/null +++ b/tests/components/io_bus/common.yaml @@ -0,0 +1,7 @@ +io_bus: + +esphome: + on_boot: + lambda: |- + #include "esphome/components/io_bus/io_bus.h" + diff --git a/tests/components/io_bus/test.esp32-ard.yaml b/tests/components/io_bus/test.esp32-ard.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.esp32-ard.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.esp32-c3-ard.yaml b/tests/components/io_bus/test.esp32-c3-ard.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.esp32-c3-ard.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.esp32-c3-idf.yaml b/tests/components/io_bus/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.esp32-c3-idf.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.esp32-idf.yaml b/tests/components/io_bus/test.esp32-idf.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.esp32-idf.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.esp8266-ard.yaml b/tests/components/io_bus/test.esp8266-ard.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.esp8266-ard.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.host.yaml b/tests/components/io_bus/test.host.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.host.yaml @@ -0,0 +1 @@ +!include common.yaml diff --git a/tests/components/io_bus/test.rp2040-ard.yaml b/tests/components/io_bus/test.rp2040-ard.yaml new file mode 100644 index 0000000000..380ca87628 --- /dev/null +++ b/tests/components/io_bus/test.rp2040-ard.yaml @@ -0,0 +1 @@ +!include common.yaml