ESPHome 2025.6.3
Loading...
Searching...
No Matches
bp1658cj.cpp
Go to the documentation of this file.
1#include "bp1658cj.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace bp1658cj {
6
7static const char *const TAG = "bp1658cj";
8
9static const uint8_t BP1658CJ_MODEL_ID = 0x80;
10static const uint8_t BP1658CJ_ADDR_STANDBY = 0x0;
11static const uint8_t BP1658CJ_ADDR_START_3CH = 0x10;
12static const uint8_t BP1658CJ_ADDR_START_2CH = 0x20;
13static const uint8_t BP1658CJ_ADDR_START_5CH = 0x30;
14
15static const uint8_t BP1658CJ_DELAY = 2;
16
18 ESP_LOGCONFIG(TAG, "Running setup");
19 this->data_pin_->setup();
20 this->data_pin_->digital_write(false);
21 this->clock_pin_->setup();
22 this->clock_pin_->digital_write(false);
23 this->pwm_amounts_.resize(5, 0);
24}
26 ESP_LOGCONFIG(TAG, "BP1658CJ:");
27 LOG_PIN(" Data Pin: ", this->data_pin_);
28 LOG_PIN(" Clock Pin: ", this->clock_pin_);
29 ESP_LOGCONFIG(TAG,
30 " Color Channels Max Power: %u\n"
31 " White Channels Max Power: %u",
33}
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
45 // First turn all channels off
46 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_5CH;
47 this->write_buffer_(data, 12);
48 // Then sleep
49 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_STANDBY;
50 this->write_buffer_(data, 12);
51 } else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
52 (this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
53 // Only data on white channels
54 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_2CH;
55 data[1] = 0 << 4 | this->max_power_white_channels_;
56 for (int i = 2, j = 0; i < 12; i += 2, j++) {
57 data[i] = this->pwm_amounts_[j] & 0x1F;
58 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
59 }
60 this->write_buffer_(data, 12);
61 } else if ((this->pwm_amounts_[0] > 0 || this->pwm_amounts_[1] > 0 || this->pwm_amounts_[2] > 0) &&
62 this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
63 // Only data on RGB channels
64 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_3CH;
65 data[1] = this->max_power_color_channels_ << 4 | 0;
66 for (int i = 2, j = 0; i < 12; i += 2, j++) {
67 data[i] = this->pwm_amounts_[j] & 0x1F;
68 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
69 }
70 this->write_buffer_(data, 12);
71 } else {
72 // All channels
73 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_5CH;
74 data[1] = this->max_power_color_channels_ << 4 | this->max_power_white_channels_;
75 for (int i = 2, j = 0; i < 12; i += 2, j++) {
76 data[i] = this->pwm_amounts_[j] & 0x1F;
77 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
78 }
79 this->write_buffer_(data, 12);
80 }
81
82 this->update_ = false;
83}
84
85void BP1658CJ::set_channel_value_(uint8_t channel, uint16_t value) {
86 if (this->pwm_amounts_[channel] != value) {
87 this->update_ = true;
88 this->update_channel_ = channel;
89 }
90 this->pwm_amounts_[channel] = value;
91}
92
93void BP1658CJ::write_bit_(bool value) {
94 this->data_pin_->digital_write(value);
95 delayMicroseconds(BP1658CJ_DELAY);
96 this->clock_pin_->digital_write(true);
97 delayMicroseconds(BP1658CJ_DELAY);
98 this->clock_pin_->digital_write(false);
99 delayMicroseconds(BP1658CJ_DELAY);
100}
101
102void BP1658CJ::write_byte_(uint8_t data) {
103 for (uint8_t mask = 0x80; mask; mask >>= 1) {
104 this->write_bit_(data & mask);
105 }
106
107 // ack bit
109 this->clock_pin_->digital_write(true);
110 delayMicroseconds(BP1658CJ_DELAY);
111 this->clock_pin_->digital_write(false);
112 delayMicroseconds(BP1658CJ_DELAY);
114}
115
116void BP1658CJ::write_buffer_(uint8_t *buffer, uint8_t size) {
117 this->data_pin_->digital_write(false);
118 delayMicroseconds(BP1658CJ_DELAY);
119 this->clock_pin_->digital_write(false);
120 delayMicroseconds(BP1658CJ_DELAY);
121
122 for (uint32_t i = 0; i < size; i++) {
123 this->write_byte_(buffer[i]);
124 }
125
126 this->clock_pin_->digital_write(true);
127 delayMicroseconds(BP1658CJ_DELAY);
128 this->data_pin_->digital_write(true);
129 delayMicroseconds(BP1658CJ_DELAY);
130}
131
132} // namespace bp1658cj
133} // namespace esphome
virtual void pin_mode(gpio::Flags flags)=0
virtual void setup()=0
virtual void digital_write(bool value)=0
void dump_config() override
Definition bp1658cj.cpp:25
std::vector< uint16_t > pwm_amounts_
Definition bp1658cj.h:59
void write_buffer_(uint8_t *buffer, uint8_t size)
Definition bp1658cj.cpp:116
void loop() override
Send new values if they were updated.
Definition bp1658cj.cpp:35
void write_bit_(bool value)
Definition bp1658cj.cpp:93
void set_channel_value_(uint8_t channel, uint16_t value)
Definition bp1658cj.cpp:85
void write_byte_(uint8_t data)
Definition bp1658cj.cpp:102
@ 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:31