#pragma once #ifdef USE_RP2040 #include "esphome/core/color.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" #include "esphome/components/light/addressable_light.h" #include "esphome/components/light/light_output.h" #include #include #include namespace esphome { namespace rp2040_pio_led_strip { enum RGBOrder : uint8_t { ORDER_RGB, ORDER_RBG, ORDER_GRB, ORDER_GBR, ORDER_BGR, ORDER_BRG, }; inline const char *rgb_order_to_string(RGBOrder order) { switch (order) { case ORDER_RGB: return "RGB"; case ORDER_RBG: return "RBG"; case ORDER_GRB: return "GRB"; case ORDER_GBR: return "GBR"; case ORDER_BGR: return "BGR"; case ORDER_BRG: return "BRG"; default: return "UNKNOWN"; } } using init_fn = void (*)(PIO pio, uint sm, uint offset, uint pin, float freq); class RP2040PIOLEDStripLightOutput : public light::AddressableLight { public: void setup() override; void write_state(light::LightState *state) override; float get_setup_priority() const override; int32_t size() const override { return this->num_leds_; } light::LightTraits get_traits() override { auto traits = light::LightTraits(); this->is_rgbw_ ? traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::RGB_WHITE}) : traits.set_supported_color_modes({light::ColorMode::RGB}); return traits; } void set_pin(uint8_t pin) { this->pin_ = pin; } void set_num_leds(uint32_t num_leds) { this->num_leds_ = num_leds; } void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; } void set_max_refresh_rate(float interval_us) { this->max_refresh_rate_ = interval_us; } void set_pio(int pio_num) { pio_num ? this->pio_ = pio1 : this->pio_ = pio0; } void set_program(const pio_program_t *program) { this->program_ = program; } void set_init_function(init_fn init) { this->init_ = init; } void set_rgb_order(RGBOrder rgb_order) { this->rgb_order_ = rgb_order; } void clear_effect_data() override { for (int i = 0; i < this->size(); i++) { this->effect_data_[i] = 0; } } void dump_config() override; protected: light::ESPColorView get_view_internal(int32_t index) const override; size_t get_buffer_size_() const { return this->num_leds_ * (3 + this->is_rgbw_); } uint8_t *buf_{nullptr}; uint8_t *effect_data_{nullptr}; uint8_t pin_; uint32_t num_leds_; bool is_rgbw_; pio_hw_t *pio_; uint sm_; RGBOrder rgb_order_{ORDER_RGB}; uint32_t last_refresh_{0}; float max_refresh_rate_; const pio_program_t *program_; init_fn init_; }; } // namespace rp2040_pio_led_strip } // namespace esphome #endif // USE_RP2040