mirror of
https://github.com/esphome/esphome.git
synced 2024-12-02 11:44:13 +01:00
de10b356cf
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
170 lines
5.2 KiB
C++
170 lines
5.2 KiB
C++
#include "max6956.h"
|
|
#include "esphome/core/log.h"
|
|
|
|
namespace esphome {
|
|
namespace max6956 {
|
|
|
|
static const char *const TAG = "max6956";
|
|
|
|
/// Masks for MAX6956 Configuration register
|
|
const uint32_t MASK_TRANSITION_DETECTION = 0x80;
|
|
const uint32_t MASK_INDIVIDUAL_CURRENT = 0x40;
|
|
const uint32_t MASK_NORMAL_OPERATION = 0x01;
|
|
|
|
const uint32_t MASK_1PORT_VALUE = 0x03;
|
|
const uint32_t MASK_PORT_CONFIG = 0x03;
|
|
const uint8_t MASK_CONFIG_CURRENT = 0x40;
|
|
const uint8_t MASK_CURRENT_PIN = 0x0F;
|
|
|
|
/**************************************
|
|
* MAX6956 *
|
|
**************************************/
|
|
void MAX6956::setup() {
|
|
ESP_LOGCONFIG(TAG, "Setting up MAX6956...");
|
|
uint8_t configuration;
|
|
if (!this->read_reg_(MAX6956_CONFIGURATION, &configuration)) {
|
|
this->mark_failed();
|
|
return;
|
|
}
|
|
|
|
write_brightness_global();
|
|
write_brightness_mode();
|
|
|
|
/** TO DO : read transition detection in yaml
|
|
TO DO : read indivdual current in yaml **/
|
|
this->read_reg_(MAX6956_CONFIGURATION, &configuration);
|
|
ESP_LOGD(TAG, "Initial reg[0x%.2X]=0x%.2X", MAX6956_CONFIGURATION, configuration);
|
|
configuration = configuration | MASK_NORMAL_OPERATION;
|
|
this->write_reg_(MAX6956_CONFIGURATION, configuration);
|
|
|
|
ESP_LOGCONFIG(TAG, "Enabling normal operation");
|
|
ESP_LOGD(TAG, "setup reg[0x%.2X]=0x%.2X", MAX6956_CONFIGURATION, configuration);
|
|
}
|
|
|
|
bool MAX6956::digital_read(uint8_t pin) {
|
|
uint8_t reg_addr = MAX6956_1PORT_VALUE_START + pin;
|
|
uint8_t value = 0;
|
|
this->read_reg_(reg_addr, &value);
|
|
return (value & MASK_1PORT_VALUE);
|
|
}
|
|
|
|
void MAX6956::digital_write(uint8_t pin, bool value) {
|
|
uint8_t reg_addr = MAX6956_1PORT_VALUE_START + pin;
|
|
this->write_reg_(reg_addr, value);
|
|
}
|
|
|
|
void MAX6956::pin_mode(uint8_t pin, gpio::Flags flags) {
|
|
uint8_t reg_addr = MAX6956_PORT_CONFIG_START + (pin - MAX6956_MIN) / 4;
|
|
uint8_t config = 0;
|
|
uint8_t shift = 2 * (pin % 4);
|
|
MAX6956GPIOMode mode = MAX6956_INPUT;
|
|
|
|
if (flags == gpio::FLAG_INPUT) {
|
|
mode = MAX6956GPIOMode::MAX6956_INPUT;
|
|
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
|
|
mode = MAX6956GPIOMode::MAX6956_INPUT_PULLUP;
|
|
} else if (flags == gpio::FLAG_OUTPUT) {
|
|
mode = MAX6956GPIOMode::MAX6956_OUTPUT;
|
|
}
|
|
|
|
this->read_reg_(reg_addr, &config);
|
|
config &= ~(MASK_PORT_CONFIG << shift);
|
|
config |= (mode << shift);
|
|
this->write_reg_(reg_addr, config);
|
|
}
|
|
|
|
void MAX6956::pin_mode(uint8_t pin, max6956::MAX6956GPIOFlag flags) {
|
|
uint8_t reg_addr = MAX6956_PORT_CONFIG_START + (pin - MAX6956_MIN) / 4;
|
|
uint8_t config = 0;
|
|
uint8_t shift = 2 * (pin % 4);
|
|
MAX6956GPIOMode mode = MAX6956GPIOMode::MAX6956_LED;
|
|
|
|
if (flags == max6956::FLAG_LED) {
|
|
mode = MAX6956GPIOMode::MAX6956_LED;
|
|
}
|
|
|
|
this->read_reg_(reg_addr, &config);
|
|
config &= ~(MASK_PORT_CONFIG << shift);
|
|
config |= (mode << shift);
|
|
this->write_reg_(reg_addr, config);
|
|
}
|
|
|
|
void MAX6956::set_brightness_global(uint8_t current) {
|
|
if (current > 15) {
|
|
ESP_LOGE(TAG, "Global brightness out off range (%u)", current);
|
|
return;
|
|
}
|
|
global_brightness_ = current;
|
|
}
|
|
|
|
void MAX6956::write_brightness_global() { this->write_reg_(MAX6956_GLOBAL_CURRENT, global_brightness_); }
|
|
|
|
void MAX6956::set_brightness_mode(max6956::MAX6956CURRENTMODE brightness_mode) { brightness_mode_ = brightness_mode; };
|
|
|
|
void MAX6956::write_brightness_mode() {
|
|
uint8_t reg_addr = MAX6956_CONFIGURATION;
|
|
uint8_t config = 0;
|
|
|
|
this->read_reg_(reg_addr, &config);
|
|
config &= ~MASK_CONFIG_CURRENT;
|
|
config |= brightness_mode_ << 6;
|
|
this->write_reg_(reg_addr, config);
|
|
}
|
|
|
|
void MAX6956::set_pin_brightness(uint8_t pin, float brightness) {
|
|
uint8_t reg_addr = MAX6956_CURRENT_START + (pin - MAX6956_MIN) / 2;
|
|
uint8_t config = 0;
|
|
uint8_t shift = 4 * (pin % 2);
|
|
uint8_t bright = roundf(brightness * 15);
|
|
|
|
if (prev_bright_[pin - MAX6956_MIN] == bright)
|
|
return;
|
|
|
|
prev_bright_[pin - MAX6956_MIN] = bright;
|
|
|
|
this->read_reg_(reg_addr, &config);
|
|
config &= ~(MASK_CURRENT_PIN << shift);
|
|
config |= (bright << shift);
|
|
this->write_reg_(reg_addr, config);
|
|
}
|
|
|
|
bool MAX6956::read_reg_(uint8_t reg, uint8_t *value) {
|
|
if (this->is_failed())
|
|
return false;
|
|
|
|
return this->read_byte(reg, value);
|
|
}
|
|
|
|
bool MAX6956::write_reg_(uint8_t reg, uint8_t value) {
|
|
if (this->is_failed())
|
|
return false;
|
|
|
|
return this->write_byte(reg, value);
|
|
}
|
|
|
|
void MAX6956::dump_config() {
|
|
ESP_LOGCONFIG(TAG, "MAX6956");
|
|
|
|
if (brightness_mode_ == MAX6956CURRENTMODE::GLOBAL) {
|
|
ESP_LOGCONFIG(TAG, "current mode: global");
|
|
ESP_LOGCONFIG(TAG, "global brightness: %u", global_brightness_);
|
|
} else {
|
|
ESP_LOGCONFIG(TAG, "current mode: segment");
|
|
}
|
|
}
|
|
|
|
/**************************************
|
|
* MAX6956GPIOPin *
|
|
**************************************/
|
|
void MAX6956GPIOPin::setup() { pin_mode(flags_); }
|
|
void MAX6956GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
|
bool MAX6956GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
|
void MAX6956GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
|
std::string MAX6956GPIOPin::dump_summary() const {
|
|
char buffer[32];
|
|
snprintf(buffer, sizeof(buffer), "%u via Max6956", pin_);
|
|
return buffer;
|
|
}
|
|
|
|
} // namespace max6956
|
|
} // namespace esphome
|