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