ESPHome  2024.4.1
sm2135.cpp
Go to the documentation of this file.
1 #include "sm2135.h"
2 #include "esphome/core/log.h"
3 
4 // Tnx to the work of https://github.com/arendst (Tasmota) for making the initial version of the driver
5 
6 namespace esphome {
7 namespace sm2135 {
8 
9 static const char *const TAG = "sm2135";
10 
11 static const uint8_t SM2135_ADDR_MC = 0xC0; // Max current register
12 static const uint8_t SM2135_ADDR_CH = 0xC1; // RGB or CW channel select register
13 static const uint8_t SM2135_ADDR_R = 0xC2; // Red color
14 static const uint8_t SM2135_ADDR_G = 0xC3; // Green color
15 static const uint8_t SM2135_ADDR_B = 0xC4; // Blue color
16 static const uint8_t SM2135_ADDR_C = 0xC5; // Cold
17 static const uint8_t SM2135_ADDR_W = 0xC6; // Warm
18 
19 static const uint8_t SM2135_RGB = 0x00; // RGB channel
20 static const uint8_t SM2135_CW = 0x80; // CW channel (Chip default)
21 
22 void SM2135::setup() {
23  ESP_LOGCONFIG(TAG, "Setting up SM2135OutputComponent...");
24  this->data_pin_->setup();
25  this->data_pin_->digital_write(false);
27  this->clock_pin_->setup();
28  this->clock_pin_->digital_write(false);
30 
33 
34  this->pwm_amounts_.resize(5, 0);
35 }
36 
38  ESP_LOGCONFIG(TAG, "SM2135:");
39  LOG_PIN(" Data Pin: ", this->data_pin_);
40  LOG_PIN(" Clock Pin: ", this->clock_pin_);
41  ESP_LOGCONFIG(TAG, " CW Current: %dmA", 10 + (this->cw_current_ * 5));
42  ESP_LOGCONFIG(TAG, " RGB Current: %dmA", 10 + (this->rgb_current_ * 5));
43 }
44 
45 void SM2135::write_byte_(uint8_t data) {
46  for (uint8_t mask = 0x80; mask; mask >>= 1) {
47  if (mask & data) {
48  this->sm2135_set_high_(this->data_pin_);
49  } else {
50  this->sm2135_set_low_(this->data_pin_);
51  }
52 
53  this->sm2135_set_high_(this->clock_pin_);
56  }
57 
58  this->sm2135_set_high_(this->data_pin_);
59  this->sm2135_set_high_(this->clock_pin_);
61  this->sm2135_set_low_(this->clock_pin_);
63  this->sm2135_set_low_(this->data_pin_);
64 }
65 
67  this->sm2135_set_low_(this->data_pin_);
69  this->sm2135_set_low_(this->clock_pin_);
70 }
71 
73  this->sm2135_set_low_(this->data_pin_);
75  this->sm2135_set_high_(this->clock_pin_);
77  this->sm2135_set_high_(this->data_pin_);
79 }
80 
81 void SM2135::write_buffer_(uint8_t *buffer, uint8_t size) {
82  this->sm2135_start_();
83 
84  this->data_pin_->digital_write(false);
85  for (uint32_t i = 0; i < size; i++) {
86  this->write_byte_(buffer[i]);
87  }
88 
89  this->sm2135_stop_();
90 }
91 
92 void SM2135::loop() {
93  if (!this->update_)
94  return;
95 
96  this->sm2135_start_();
97  this->write_byte_(SM2135_ADDR_MC);
99 
100  if (this->separate_modes_) {
101  if (this->update_channel_ == 3 || this->update_channel_ == 4) {
102  // No color so must be Cold/Warm
103 
104  this->write_byte_(SM2135_CW);
105  this->sm2135_stop_();
106  delay(1);
107  this->sm2135_start_();
108  this->write_byte_(SM2135_ADDR_C);
109  this->write_byte_(this->pwm_amounts_[4]); // Warm
110  this->write_byte_(this->pwm_amounts_[3]); // Cold
111  } else {
112  // Color
113 
114  this->write_byte_(SM2135_RGB);
115  this->write_byte_(this->pwm_amounts_[1]); // Green
116  this->write_byte_(this->pwm_amounts_[0]); // Red
117  this->write_byte_(this->pwm_amounts_[2]); // Blue
118  }
119  } else {
120  this->write_byte_(SM2135_RGB);
121  this->write_byte_(this->pwm_amounts_[1]); // Green
122  this->write_byte_(this->pwm_amounts_[0]); // Red
123  this->write_byte_(this->pwm_amounts_[2]); // Blue
124  this->write_byte_(this->pwm_amounts_[4]); // Warm
125  this->write_byte_(this->pwm_amounts_[3]); // Cold
126  }
127 
128  this->sm2135_stop_();
129 
130  this->update_ = false;
131 }
132 
133 void SM2135::set_channel_value_(uint8_t channel, uint8_t value) {
134  if (this->pwm_amounts_[channel] != value) {
135  this->update_ = true;
136  this->update_channel_ = channel;
137  }
138  this->pwm_amounts_[channel] = value;
139 }
140 
142  pin->digital_write(false);
144 }
145 
147  pin->digital_write(true);
149 }
150 
151 } // namespace sm2135
152 } // namespace esphome
virtual void digital_write(bool value)=0
GPIOPin * data_pin_
Definition: sm2135.h:78
void sm2135_set_low_(GPIOPin *pin)
Definition: sm2135.cpp:141
void sm2135_set_high_(GPIOPin *pin)
Definition: sm2135.cpp:146
SM2135Current cw_current_
Definition: sm2135.h:82
void set_channel_value_(uint8_t channel, uint8_t value)
Definition: sm2135.cpp:133
virtual void pin_mode(gpio::Flags flags)=0
virtual void setup()=0
SM2135Current rgb_current_
Definition: sm2135.h:81
uint8_t current_mask_
Definition: sm2135.h:80
void dump_config() override
Definition: sm2135.cpp:37
void write_byte_(uint8_t data)
Definition: sm2135.cpp:45
uint8_t update_channel_
Definition: sm2135.h:84
std::vector< uint8_t > pwm_amounts_
Definition: sm2135.h:85
void write_buffer_(uint8_t *buffer, uint8_t size)
Definition: sm2135.cpp:81
void loop() override
Send new values if they were updated.
Definition: sm2135.cpp:92
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition: core.cpp:28
GPIOPin * clock_pin_
Definition: sm2135.h:79
void setup() override
Definition: sm2135.cpp:22
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26