ESPHome 2025.5.0
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, "Setting up BP1658CJ Output Component...");
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, " Color Channels Max Power: %u", this->max_power_color_channels_);
30 ESP_LOGCONFIG(TAG, " White Channels Max Power: %u", this->max_power_white_channels_);
31}
32
34 if (!this->update_)
35 return;
36
37 uint8_t data[12];
38 if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
39 this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
40 for (int i = 1; i < 12; i++)
41 data[i] = 0;
42
43 // First turn all channels off
44 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_5CH;
45 this->write_buffer_(data, 12);
46 // Then sleep
47 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_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] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
56 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
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] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
66 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
67 }
68 this->write_buffer_(data, 12);
69 } else {
70 // All channels
71 data[0] = BP1658CJ_MODEL_ID + BP1658CJ_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] & 0x1F;
75 data[i + 1] = (this->pwm_amounts_[j] >> 5) & 0x1F;
76 }
77 this->write_buffer_(data, 12);
78 }
79
80 this->update_ = false;
81}
82
83void BP1658CJ::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}
90
91void BP1658CJ::write_bit_(bool value) {
92 this->data_pin_->digital_write(value);
93 delayMicroseconds(BP1658CJ_DELAY);
94 this->clock_pin_->digital_write(true);
95 delayMicroseconds(BP1658CJ_DELAY);
96 this->clock_pin_->digital_write(false);
97 delayMicroseconds(BP1658CJ_DELAY);
98}
99
100void BP1658CJ::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(BP1658CJ_DELAY);
109 this->clock_pin_->digital_write(false);
110 delayMicroseconds(BP1658CJ_DELAY);
112}
113
114void BP1658CJ::write_buffer_(uint8_t *buffer, uint8_t size) {
115 this->data_pin_->digital_write(false);
116 delayMicroseconds(BP1658CJ_DELAY);
117 this->clock_pin_->digital_write(false);
118 delayMicroseconds(BP1658CJ_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(BP1658CJ_DELAY);
126 this->data_pin_->digital_write(true);
127 delayMicroseconds(BP1658CJ_DELAY);
128}
129
130} // namespace bp1658cj
131} // 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:114
void loop() override
Send new values if they were updated.
Definition bp1658cj.cpp:33
void write_bit_(bool value)
Definition bp1658cj.cpp:91
void set_channel_value_(uint8_t channel, uint16_t value)
Definition bp1658cj.cpp:83
void write_byte_(uint8_t data)
Definition bp1658cj.cpp:100
@ 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