ESPHome  2024.5.0
tlc5971.cpp
Go to the documentation of this file.
1 #include "tlc5971.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace tlc5971 {
6 
7 static const char *const TAG = "tlc5971";
8 
9 void TLC5971::setup() {
10  this->data_pin_->setup();
11  this->data_pin_->digital_write(true);
12  this->clock_pin_->setup();
13  this->clock_pin_->digital_write(true);
14 
15  this->pwm_amounts_.resize(this->num_chips_ * N_CHANNELS_PER_CHIP, 0);
16 
17  ESP_LOGCONFIG(TAG, "Done setting up TLC5971 output component.");
18 }
20  ESP_LOGCONFIG(TAG, "TLC5971:");
21  LOG_PIN(" Data Pin: ", this->data_pin_);
22  LOG_PIN(" Clock Pin: ", this->clock_pin_);
23  ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_);
24 }
25 
26 void TLC5971::loop() {
27  if (!this->update_)
28  return;
29 
30  uint32_t command;
31 
32  // Magic word for write
33  command = 0x25;
34 
35  command <<= 5;
36  // OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 0 -> 0x16
37  command |= 0x16;
38 
39  command <<= 7;
40  command |= 0x7F; // default 100% brigthness
41 
42  command <<= 7;
43  command |= 0x7F; // default 100% brigthness
44 
45  command <<= 7;
46  command |= 0x7F; // default 100% brigthness
47 
48  for (uint8_t n = 0; n < num_chips_; n++) {
49  this->transfer_(command >> 24);
50  this->transfer_(command >> 16);
51  this->transfer_(command >> 8);
52  this->transfer_(command);
53 
54  // 12 channels per TLC59711
55  for (int8_t c = 11; c >= 0; c--) {
56  // 16 bits per channel, send MSB first
57  this->transfer_(pwm_amounts_.at(n * 12 + c) >> 8);
58  this->transfer_(pwm_amounts_.at(n * 12 + c));
59  }
60  }
61 
62  this->update_ = false;
63 }
64 
65 void TLC5971::transfer_(uint8_t send) {
66  uint8_t startbit = 0x80;
67 
68  bool towrite, lastmosi = !(send & startbit);
69  uint8_t bitdelay_us = (1000000 / 1000000) / 2;
70 
71  for (uint8_t b = startbit; b != 0; b = b >> 1) {
72  if (bitdelay_us) {
73  delayMicroseconds(bitdelay_us);
74  }
75 
76  towrite = send & b;
77  if ((lastmosi != towrite)) {
78  this->data_pin_->digital_write(towrite);
79  lastmosi = towrite;
80  }
81 
82  this->clock_pin_->digital_write(true);
83 
84  if (bitdelay_us) {
85  delayMicroseconds(bitdelay_us);
86  }
87 
88  this->clock_pin_->digital_write(false);
89  }
90 }
91 void TLC5971::set_channel_value(uint16_t channel, uint16_t value) {
92  if (channel >= this->num_chips_ * N_CHANNELS_PER_CHIP)
93  return;
94  if (this->pwm_amounts_[channel] != value) {
95  this->update_ = true;
96  }
97  this->pwm_amounts_[channel] = value;
98 }
99 
100 } // namespace tlc5971
101 } // namespace esphome
virtual void digital_write(bool value)=0
const uint8_t N_CHANNELS_PER_CHIP
Definition: tlc5971.h:15
virtual void setup()=0
void transfer_(uint8_t send)
Definition: tlc5971.cpp:65
const char *const TAG
Definition: spi.cpp:8
std::vector< uint16_t > pwm_amounts_
Definition: tlc5971.h:39
void dump_config() override
Definition: tlc5971.cpp:19
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition: core.cpp:28
void setup() override
Definition: tlc5971.cpp:9
void set_channel_value(uint16_t channel, uint16_t value)
Definition: tlc5971.cpp:91
void loop() override
Send new values if they were updated.
Definition: tlc5971.cpp:26