ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
sm10bit_base.cpp
Go to the documentation of this file.
1#include "sm10bit_base.h"
2#include "esphome/core/log.h"
3
5
6static const char *const TAG = "sm10bit_base";
7
8static const uint8_t SM10BIT_ADDR_STANDBY = 0x0;
9static const uint8_t SM10BIT_ADDR_START_3CH = 0x8;
10static const uint8_t SM10BIT_ADDR_START_2CH = 0x10;
11static const uint8_t SM10BIT_ADDR_START_5CH = 0x18;
12
13static const uint8_t SM10BIT_DELAY = 2;
14
15// Power current values
16// HEX | Binary | RGB level | White level | Config value
17// 0x0 | 0000 | RGB 10mA | CW 5mA | 0
18// 0x1 | 0001 | RGB 20mA | CW 10mA | 1
19// 0x2 | 0010 | RGB 30mA | CW 15mA | 2 - Default spec color value
20// 0x3 | 0011 | RGB 40mA | CW 20mA | 3
21// 0x4 | 0100 | RGB 50mA | CW 25mA | 4 - Default spec white value
22// 0x5 | 0101 | RGB 60mA | CW 30mA | 5
23// 0x6 | 0110 | RGB 70mA | CW 35mA | 6
24// 0x7 | 0111 | RGB 80mA | CW 40mA | 7
25// 0x8 | 1000 | RGB 90mA | CW 45mA | 8
26// 0x9 | 1001 | RGB 100mA | CW 50mA | 9
27// 0xA | 1010 | RGB 110mA | CW 55mA | 10
28// 0xB | 1011 | RGB 120mA | CW 60mA | 11
29// 0xC | 1100 | RGB 130mA | CW 65mA | 12
30// 0xD | 1101 | RGB 140mA | CW 70mA | 13
31// 0xE | 1110 | RGB 150mA | CW 75mA | 14
32// 0xF | 1111 | RGB 160mA | CW 80mA | 15
33
35 if (!this->update_)
36 return;
37
38 uint8_t data[12];
39 if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
40 this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
41 for (int i = 1; i < 12; i++)
42 data[i] = 0;
43 // First turn all channels off
44 data[0] = this->model_id_ + SM10BIT_ADDR_START_5CH;
45 this->write_buffer_(data, 12);
46 // Then sleep
47 data[0] = this->model_id_ + SM10BIT_ADDR_STANDBY;
48 this->write_buffer_(data, 12);
49 } else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
50 (this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
51 // Only data on white channels
52 data[0] = this->model_id_ + SM10BIT_ADDR_START_2CH;
53 data[1] = 0 << 4 | this->max_power_white_channels_;
54 for (int i = 2, j = 0; i < 12; i += 2, j++) {
55 data[i] = this->pwm_amounts_[j] >> 0x8;
56 data[i + 1] = this->pwm_amounts_[j] & 0xFF;
57 }
58 this->write_buffer_(data, 12);
59 } else if ((this->pwm_amounts_[0] > 0 || this->pwm_amounts_[1] > 0 || this->pwm_amounts_[2] > 0) &&
60 this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
61 // Only data on RGB channels
62 data[0] = this->model_id_ + SM10BIT_ADDR_START_3CH;
63 data[1] = this->max_power_color_channels_ << 4 | 0;
64 for (int i = 2, j = 0; i < 12; i += 2, j++) {
65 data[i] = this->pwm_amounts_[j] >> 0x8;
66 data[i + 1] = this->pwm_amounts_[j] & 0xFF;
67 }
68 this->write_buffer_(data, 12);
69 } else {
70 // All channels
71 data[0] = this->model_id_ + SM10BIT_ADDR_START_5CH;
72 data[1] = this->max_power_color_channels_ << 4 | this->max_power_white_channels_;
73 for (int i = 2, j = 0; i < 12; i += 2, j++) {
74 data[i] = this->pwm_amounts_[j] >> 0x8;
75 data[i + 1] = this->pwm_amounts_[j] & 0xFF;
76 }
77 this->write_buffer_(data, 12);
78 }
79
80 this->update_ = false;
81}
82
83void Sm10BitBase::set_channel_value_(uint8_t channel, uint16_t value) {
84 if (this->pwm_amounts_[channel] != value) {
85 this->update_ = true;
86 this->update_channel_ = channel;
87 }
88 this->pwm_amounts_[channel] = value;
89}
90void Sm10BitBase::write_bit_(bool value) {
91 this->data_pin_->digital_write(value);
92 delayMicroseconds(SM10BIT_DELAY);
93 this->clock_pin_->digital_write(true);
94 delayMicroseconds(SM10BIT_DELAY);
95 this->clock_pin_->digital_write(false);
96 delayMicroseconds(SM10BIT_DELAY);
97}
98
99void Sm10BitBase::write_byte_(uint8_t data) {
100 for (uint8_t mask = 0x80; mask; mask >>= 1) {
101 this->write_bit_(data & mask);
102 }
103
104 // ack bit
106 this->clock_pin_->digital_write(true);
107 delayMicroseconds(SM10BIT_DELAY);
108 this->clock_pin_->digital_write(false);
109 delayMicroseconds(SM10BIT_DELAY);
111}
112
113void Sm10BitBase::write_buffer_(uint8_t *buffer, uint8_t size) {
114 this->data_pin_->digital_write(false);
115 delayMicroseconds(SM10BIT_DELAY);
116 this->clock_pin_->digital_write(false);
117 delayMicroseconds(SM10BIT_DELAY);
118
119 for (uint32_t i = 0; i < size; i++) {
120 this->write_byte_(buffer[i]);
121 }
122
123 this->clock_pin_->digital_write(true);
124 delayMicroseconds(SM10BIT_DELAY);
125 this->data_pin_->digital_write(true);
126 delayMicroseconds(SM10BIT_DELAY);
127}
128
129} // namespace esphome::sm10bit_base
virtual void pin_mode(gpio::Flags flags)=0
virtual void digital_write(bool value)=0
void write_buffer_(uint8_t *buffer, uint8_t size)
std::vector< uint16_t > pwm_amounts_
void set_channel_value_(uint8_t channel, uint16_t value)
@ FLAG_OUTPUT
Definition gpio.h:28
@ FLAG_INPUT
Definition gpio.h:27
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition hal.cpp:48
uint16_t size
Definition helpers.cpp:25
static void uint32_t