ESPHome  2024.3.2
led_strip.cpp
Go to the documentation of this file.
1 #include "led_strip.h"
2 
3 #ifdef USE_RP2040
4 
5 #include "esphome/core/helpers.h"
6 #include "esphome/core/log.h"
7 
8 #include <hardware/clocks.h>
9 #include <hardware/pio.h>
10 #include <pico/stdlib.h>
11 
12 namespace esphome {
13 namespace rp2040_pio_led_strip {
14 
15 static const char *TAG = "rp2040_pio_led_strip";
16 
18  ESP_LOGCONFIG(TAG, "Setting up RP2040 LED Strip...");
19 
20  size_t buffer_size = this->get_buffer_size_();
21 
23  this->buf_ = allocator.allocate(buffer_size);
24  if (this->buf_ == nullptr) {
25  ESP_LOGE(TAG, "Failed to allocate buffer of size %u", buffer_size);
26  this->mark_failed();
27  return;
28  }
29 
30  this->effect_data_ = allocator.allocate(this->num_leds_);
31  if (this->effect_data_ == nullptr) {
32  ESP_LOGE(TAG, "Failed to allocate effect data of size %u", this->num_leds_);
33  this->mark_failed();
34  return;
35  }
36 
37  // Select PIO instance to use (0 or 1)
38  this->pio_ = pio0;
39  if (this->pio_ == nullptr) {
40  ESP_LOGE(TAG, "Failed to claim PIO instance");
41  this->mark_failed();
42  return;
43  }
44 
45  // Load the assembled program into the PIO and get its location in the PIO's instruction memory
46  uint offset = pio_add_program(this->pio_, this->program_);
47 
48  // Configure the state machine's PIO, and start it
49  this->sm_ = pio_claim_unused_sm(this->pio_, true);
50  if (this->sm_ < 0) {
51  ESP_LOGE(TAG, "Failed to claim PIO state machine");
52  this->mark_failed();
53  return;
54  }
55  this->init_(this->pio_, this->sm_, offset, this->pin_, this->max_refresh_rate_);
56 }
57 
59  ESP_LOGVV(TAG, "Writing state...");
60 
61  if (this->is_failed()) {
62  ESP_LOGW(TAG, "Light is in failed state, not writing state.");
63  return;
64  }
65 
66  if (this->buf_ == nullptr) {
67  ESP_LOGW(TAG, "Buffer is null, not writing state.");
68  return;
69  }
70 
71  // assemble bits in buffer to 32 bit words with ex for GBR: 0bGGGGGGGGRRRRRRRRBBBBBBBB00000000
72  for (int i = 0; i < this->num_leds_; i++) {
73  uint8_t multiplier = this->is_rgbw_ ? 4 : 3;
74  uint8_t c1 = this->buf_[(i * multiplier) + 0];
75  uint8_t c2 = this->buf_[(i * multiplier) + 1];
76  uint8_t c3 = this->buf_[(i * multiplier) + 2];
77  uint8_t w = this->is_rgbw_ ? this->buf_[(i * 4) + 3] : 0;
78  uint32_t color = encode_uint32(c1, c2, c3, w);
79  pio_sm_put_blocking(this->pio_, this->sm_, color);
80  }
81 }
82 
84  int32_t r = 0, g = 0, b = 0, w = 0;
85  switch (this->rgb_order_) {
86  case ORDER_RGB:
87  r = 0;
88  g = 1;
89  b = 2;
90  break;
91  case ORDER_RBG:
92  r = 0;
93  g = 2;
94  b = 1;
95  break;
96  case ORDER_GRB:
97  r = 1;
98  g = 0;
99  b = 2;
100  break;
101  case ORDER_GBR:
102  r = 2;
103  g = 0;
104  b = 1;
105  break;
106  case ORDER_BGR:
107  r = 2;
108  g = 1;
109  b = 0;
110  break;
111  case ORDER_BRG:
112  r = 1;
113  g = 2;
114  b = 0;
115  break;
116  }
117  uint8_t multiplier = this->is_rgbw_ ? 4 : 3;
118  return {this->buf_ + (index * multiplier) + r,
119  this->buf_ + (index * multiplier) + g,
120  this->buf_ + (index * multiplier) + b,
121  this->is_rgbw_ ? this->buf_ + (index * multiplier) + 3 : nullptr,
122  &this->effect_data_[index],
123  &this->correction_};
124 }
125 
127  ESP_LOGCONFIG(TAG, "RP2040 PIO LED Strip Light Output:");
128  ESP_LOGCONFIG(TAG, " Pin: GPIO%d", this->pin_);
129  ESP_LOGCONFIG(TAG, " Number of LEDs: %d", this->num_leds_);
130  ESP_LOGCONFIG(TAG, " RGBW: %s", YESNO(this->is_rgbw_));
131  ESP_LOGCONFIG(TAG, " RGB Order: %s", rgb_order_to_string(this->rgb_order_));
132  ESP_LOGCONFIG(TAG, " Max Refresh Rate: %f Hz", this->max_refresh_rate_);
133 }
134 
136 
137 } // namespace rp2040_pio_led_strip
138 } // namespace esphome
139 
140 #endif
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition: light_state.h:34
void write_state(light::LightState *state) override
Definition: led_strip.cpp:58
An STL allocator that uses SPI RAM.
Definition: helpers.h:645
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
Definition: helpers.h:186
const char * rgb_order_to_string(RGBOrder order)
Definition: led_strip.h:28
light::ESPColorView get_view_internal(int32_t index) const override
Definition: led_strip.cpp:83
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition: component.cpp:18
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:113
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
bool state
Definition: fan.h:34