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