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