ESPHome 2025.5.0
Loading...
Searching...
No Matches
my9231.cpp
Go to the documentation of this file.
1#include "my9231.h"
2#include "esphome/core/log.h"
4
5namespace esphome {
6namespace my9231 {
7
8static const char *const TAG = "my9231.output";
9
10// One-shot select (frame cycle repeat mode / frame cycle One-shot mode)
11static const uint8_t MY9231_CMD_ONE_SHOT_DISABLE = 0x0 << 6;
12static const uint8_t MY9231_CMD_ONE_SHOT_ENFORCE = 0x1 << 6;
13// Reaction time of Iout
14static const uint8_t MY9231_CMD_REACTION_FAST = 0x0 << 5;
15static const uint8_t MY9231_CMD_REACTION_SLOW = 0x1 << 5;
16// Grayscale resolution select
17static const uint8_t MY9231_CMD_BIT_WIDTH_16 = 0x0 << 3;
18static const uint8_t MY9231_CMD_BIT_WIDTH_14 = 0x1 << 3;
19static const uint8_t MY9231_CMD_BIT_WIDTH_12 = 0x2 << 3;
20static const uint8_t MY9231_CMD_BIT_WIDTH_8 = 0x3 << 3;
21// Internal oscillator freq. select (divider)
22static const uint8_t MY9231_CMD_FREQUENCY_DIVIDE_1 = 0x0 << 1;
23static const uint8_t MY9231_CMD_FREQUENCY_DIVIDE_4 = 0x1 << 1;
24static const uint8_t MY9231_CMD_FREQUENCY_DIVIDE_16 = 0x2 << 1;
25static const uint8_t MY9231_CMD_FREQUENCY_DIVIDE_64 = 0x3 << 1;
26// Output waveform
27static const uint8_t MY9231_CMD_SCATTER_APDM = 0x0 << 0;
28static const uint8_t MY9231_CMD_SCATTER_PWM = 0x1 << 0;
29
31 ESP_LOGCONFIG(TAG, "Setting up MY9231OutputComponent...");
32 this->pin_di_->setup();
33 this->pin_di_->digital_write(false);
34 this->pin_dcki_->setup();
35 this->pin_dcki_->digital_write(false);
36 this->pwm_amounts_.resize(this->num_channels_, 0);
37 uint8_t command = 0;
38 if (this->bit_depth_ <= 8) {
39 this->bit_depth_ = 8;
40 command |= MY9231_CMD_BIT_WIDTH_8;
41 } else if (this->bit_depth_ <= 12) {
42 this->bit_depth_ = 12;
43 command |= MY9231_CMD_BIT_WIDTH_12;
44 } else if (this->bit_depth_ <= 14) {
45 this->bit_depth_ = 14;
46 command |= MY9231_CMD_BIT_WIDTH_14;
47 } else {
48 this->bit_depth_ = 16;
49 command |= MY9231_CMD_BIT_WIDTH_16;
50 }
51 command |=
52 MY9231_CMD_SCATTER_APDM | MY9231_CMD_FREQUENCY_DIVIDE_1 | MY9231_CMD_REACTION_FAST | MY9231_CMD_ONE_SHOT_DISABLE;
53 ESP_LOGV(TAG, " Command: 0x%02X", command);
54
55 {
56 InterruptLock lock;
57 this->send_dcki_pulses_(32 * this->num_chips_);
58 this->init_chips_(command);
59 }
60 ESP_LOGV(TAG, " Chips initialized.");
61}
63 ESP_LOGCONFIG(TAG, "MY9231:");
64 LOG_PIN(" DI Pin: ", this->pin_di_);
65 LOG_PIN(" DCKI Pin: ", this->pin_dcki_);
66 ESP_LOGCONFIG(TAG, " Total number of channels: %u", this->num_channels_);
67 ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_);
68 ESP_LOGCONFIG(TAG, " Bit depth: %u", this->bit_depth_);
69}
71 if (!this->update_)
72 return;
73
74 {
75 InterruptLock lock;
76 for (auto pwm_amount : this->pwm_amounts_) {
77 this->write_word_(pwm_amount, this->bit_depth_);
78 }
79 // Send 8 DI pulses. After 8 falling edges, the duty data are store.
80 this->send_di_pulses_(8);
81 }
82 this->update_ = false;
83}
84void MY9231OutputComponent::set_channel_value_(uint8_t channel, uint16_t value) {
85 ESP_LOGV(TAG, "set channels %u to %u", channel, value);
86 uint8_t index = this->num_channels_ - channel - 1;
87 if (this->pwm_amounts_[index] != value) {
88 this->update_ = true;
89 }
90 this->pwm_amounts_[index] = value;
91}
93 // Send 12 DI pulse. After 6 falling edges, the duty data are stored
94 // and after 12 rising edges the command mode is activated.
95 this->send_di_pulses_(12);
97 for (uint8_t i = 0; i < this->num_chips_; i++) {
98 this->write_word_(command, 8);
99 }
100 // Send 16 DI pulse. After 14 falling edges, the command data are
101 // stored and after 16 falling edges the duty mode is activated.
102 this->send_di_pulses_(16);
104}
105void MY9231OutputComponent::write_word_(uint16_t value, uint8_t bits) {
106 for (uint8_t i = bits; i > 0; i--) {
107 this->pin_di_->digital_write(value & (1 << (i - 1)));
109 }
110}
113 for (uint8_t i = 0; i < count; i++) {
114 this->pin_di_->digital_write(true);
115 this->pin_di_->digital_write(false);
116 }
117}
120 for (uint8_t i = 0; i < count; i++) {
121 this->pin_dcki_->digital_write(true);
122 this->pin_dcki_->digital_write(false);
123 }
124}
125
126} // namespace my9231
127} // namespace esphome
virtual void setup()=0
virtual void digital_write(bool value)=0
virtual bool digital_read()=0
Helper class to disable interrupts.
Definition helpers.h:614
std::vector< uint16_t > pwm_amounts_
Definition my9231.h:59
void setup() override
Setup the MY9231.
Definition my9231.cpp:30
void set_channel_value_(uint8_t channel, uint16_t value)
Definition my9231.cpp:84
void loop() override
Send new values if they were updated.
Definition my9231.cpp:70
void send_di_pulses_(uint8_t count)
Definition my9231.cpp:111
void write_word_(uint16_t value, uint8_t bits)
Definition my9231.cpp:105
void send_dcki_pulses_(uint8_t count)
Definition my9231.cpp:118
void init_chips_(uint8_t command)
Definition my9231.cpp:92
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