mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-06-04 03:48:29 +02:00
Implemented support for the TLC5971 as an output component (#6494)
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#include "tlc5971.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace tlc5971 {
|
||||
|
||||
static const char *const TAG = "tlc5971";
|
||||
|
||||
void TLC5971::setup() {
|
||||
this->data_pin_->setup();
|
||||
this->data_pin_->digital_write(true);
|
||||
this->clock_pin_->setup();
|
||||
this->clock_pin_->digital_write(true);
|
||||
|
||||
this->pwm_amounts_.resize(this->num_chips_ * N_CHANNELS_PER_CHIP, 0);
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Done setting up TLC5971 output component.");
|
||||
}
|
||||
void TLC5971::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "TLC5971:");
|
||||
LOG_PIN(" Data Pin: ", this->data_pin_);
|
||||
LOG_PIN(" Clock Pin: ", this->clock_pin_);
|
||||
ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_);
|
||||
}
|
||||
|
||||
void TLC5971::loop() {
|
||||
if (!this->update_)
|
||||
return;
|
||||
|
||||
uint32_t command;
|
||||
|
||||
// Magic word for write
|
||||
command = 0x25;
|
||||
|
||||
command <<= 5;
|
||||
// OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 0 -> 0x16
|
||||
command |= 0x16;
|
||||
|
||||
command <<= 7;
|
||||
command |= 0x7F; // default 100% brigthness
|
||||
|
||||
command <<= 7;
|
||||
command |= 0x7F; // default 100% brigthness
|
||||
|
||||
command <<= 7;
|
||||
command |= 0x7F; // default 100% brigthness
|
||||
|
||||
for (uint8_t n = 0; n < num_chips_; n++) {
|
||||
this->transfer_(command >> 24);
|
||||
this->transfer_(command >> 16);
|
||||
this->transfer_(command >> 8);
|
||||
this->transfer_(command);
|
||||
|
||||
// 12 channels per TLC59711
|
||||
for (int8_t c = 11; c >= 0; c--) {
|
||||
// 16 bits per channel, send MSB first
|
||||
this->transfer_(pwm_amounts_.at(n * 12 + c) >> 8);
|
||||
this->transfer_(pwm_amounts_.at(n * 12 + c));
|
||||
}
|
||||
}
|
||||
|
||||
this->update_ = false;
|
||||
}
|
||||
|
||||
void TLC5971::transfer_(uint8_t send) {
|
||||
uint8_t startbit = 0x80;
|
||||
|
||||
bool towrite, lastmosi = !(send & startbit);
|
||||
uint8_t bitdelay_us = (1000000 / 1000000) / 2;
|
||||
|
||||
for (uint8_t b = startbit; b != 0; b = b >> 1) {
|
||||
if (bitdelay_us) {
|
||||
delayMicroseconds(bitdelay_us);
|
||||
}
|
||||
|
||||
towrite = send & b;
|
||||
if ((lastmosi != towrite)) {
|
||||
this->data_pin_->digital_write(towrite);
|
||||
lastmosi = towrite;
|
||||
}
|
||||
|
||||
this->clock_pin_->digital_write(true);
|
||||
|
||||
if (bitdelay_us) {
|
||||
delayMicroseconds(bitdelay_us);
|
||||
}
|
||||
|
||||
this->clock_pin_->digital_write(false);
|
||||
}
|
||||
}
|
||||
void TLC5971::set_channel_value(uint16_t channel, uint16_t value) {
|
||||
if (channel >= this->num_chips_ * N_CHANNELS_PER_CHIP)
|
||||
return;
|
||||
if (this->pwm_amounts_[channel] != value) {
|
||||
this->update_ = true;
|
||||
}
|
||||
this->pwm_amounts_[channel] = value;
|
||||
}
|
||||
|
||||
} // namespace tlc5971
|
||||
} // namespace esphome
|
||||
Reference in New Issue
Block a user