ESPHome 2025.9.0-dev
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 this->data_pin_->setup();
19 this->data_pin_->digital_write(false);
20 this->clock_pin_->setup();
21 this->clock_pin_->digital_write(false);
22 this->pwm_amounts_.resize(5, 0);
23}
25 ESP_LOGCONFIG(TAG, "BP1658CJ:");
26 LOG_PIN(" Data Pin: ", this->data_pin_);
27 LOG_PIN(" Clock Pin: ", this->clock_pin_);
28 ESP_LOGCONFIG(TAG,
29 " Color Channels Max Power: %u\n"
30 " White Channels Max Power: %u",
32}
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
44 // First turn all channels off
45 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_5CH;
46 this->write_buffer_(data, 12);
47 // Then sleep
48 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_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] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
57 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
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] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
67 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
68 }
69 this->write_buffer_(data, 12);
70 } else {
71 // All channels
72 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
76 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
77 }
78 this->write_buffer_(data, 12);
79 }
80
81 this->update_ = false;
82}
83
84void BP1658CJ::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}
91
92void BP1658CJ::write_bit_(bool value) {
93 this->data_pin_->digital_write(value);
94 delayMicroseconds(BP1658CJ_DELAY);
95 this->clock_pin_->digital_write(true);
96 delayMicroseconds(BP1658CJ_DELAY);
97 this->clock_pin_->digital_write(false);
98 delayMicroseconds(BP1658CJ_DELAY);
99}
100
101void BP1658CJ::write_byte_(uint8_t data) {
102 for (uint8_t mask = 0x80; mask; mask >>= 1) {
103 this->write_bit_(data & mask);
104 }
105
106 // ack bit
108 this->clock_pin_->digital_write(true);
109 delayMicroseconds(BP1658CJ_DELAY);
110 this->clock_pin_->digital_write(false);
111 delayMicroseconds(BP1658CJ_DELAY);
113}
114
115void BP1658CJ::write_buffer_(uint8_t *buffer, uint8_t size) {
116 this->data_pin_->digital_write(false);
117 delayMicroseconds(BP1658CJ_DELAY);
118 this->clock_pin_->digital_write(false);
119 delayMicroseconds(BP1658CJ_DELAY);
120
121 for (uint32_t i = 0; i < size; i++) {
122 this->write_byte_(buffer[i]);
123 }
124
125 this->clock_pin_->digital_write(true);
126 delayMicroseconds(BP1658CJ_DELAY);
127 this->data_pin_->digital_write(true);
128 delayMicroseconds(BP1658CJ_DELAY);
129}
130
131} // namespace bp1658cj
132} // 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:24
std::vector< uint16_t > pwm_amounts_
Definition bp1658cj.h:59
void write_buffer_(uint8_t *buffer, uint8_t size)
Definition bp1658cj.cpp:115
void loop() override
Send new values if they were updated.
Definition bp1658cj.cpp:34
void write_bit_(bool value)
Definition bp1658cj.cpp:92
void set_channel_value_(uint8_t channel, uint16_t value)
Definition bp1658cj.cpp:84
void write_byte_(uint8_t data)
Definition bp1658cj.cpp:101
@ 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