cogito/esphome_dev/esphome/components/tlc5971/tlc5971.cpp

101 lines
2.4 KiB
C++

#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