mirror of
https://github.com/esphome/esphome.git
synced 2025-01-23 04:45:58 +01:00
MAX6921: impl. display intensity (PWM input for BLANK pin)
This commit is contained in:
parent
c78d3e5e14
commit
0708b9734e
3 changed files with 204 additions and 52 deletions
|
@ -1,17 +1,15 @@
|
|||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import display, spi
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_ID, CONF_INTENSITY, CONF_LAMBDA
|
||||
|
||||
# from esphome.const import CONF_INTENSITY
|
||||
|
||||
DEPENDENCIES = ["spi"]
|
||||
DEPENDENCIES = ["spi", "esp32"]
|
||||
CODEOWNERS = ["@endym"]
|
||||
CONF_LOAD_PIN = "load_pin"
|
||||
CONF_BLANK_PIN = "blank_pin"
|
||||
CONF_NUM_DIGITS = "num_digits"
|
||||
# CONF_REVERSE_ENABLE = "reverse_enable"
|
||||
|
||||
max6921_ns = cg.esphome_ns.namespace("max6921")
|
||||
MAX6921Component = max6921_ns.class_(
|
||||
|
@ -24,13 +22,12 @@ CONFIG_SCHEMA = (
|
|||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX6921Component),
|
||||
cv.Required(CONF_LOAD_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Required(CONF_BLANK_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Required(CONF_BLANK_PIN): pins.internal_gpio_output_pin_schema,
|
||||
cv.Required(CONF_NUM_DIGITS): cv.int_range(min=1, max=20),
|
||||
# cv.Optional(CONF_INTENSITY, default=15): cv.int_range(min=0, max=15),
|
||||
# cv.Optional(CONF_REVERSE_ENABLE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_INTENSITY, default=16): cv.int_range(min=0, max=16),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("1ms"))
|
||||
.extend(cv.polling_component_schema("1s"))
|
||||
.extend(spi.spi_device_schema(cs_pin_required=False))
|
||||
)
|
||||
|
||||
|
@ -45,8 +42,7 @@ async def to_code(config):
|
|||
blank_pin = await cg.gpio_pin_expression(config[CONF_BLANK_PIN])
|
||||
cg.add(var.set_blank_pin(blank_pin))
|
||||
cg.add(var.set_num_digits(config[CONF_NUM_DIGITS]))
|
||||
# cg.add(var.set_intensity(config[CONF_INTENSITY]))
|
||||
# cg.add(var.set_reverse(config[CONF_REVERSE_ENABLE]))
|
||||
cg.add(var.set_intensity(config[CONF_INTENSITY]))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = await cg.process_lambda(
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace max6921 {
|
||||
|
@ -12,6 +13,9 @@ namespace max6921 {
|
|||
|
||||
static const char *const TAG = "max6921";
|
||||
|
||||
// display intensity (brightness)...
|
||||
static const uint MAX_DISPLAY_INTENSITY = 16;
|
||||
|
||||
// display segment to DOUTx mapping...
|
||||
static const uint8_t DISP_SEG_TO_OUT[] = {
|
||||
// a b c d e f g dp
|
||||
|
@ -134,16 +138,43 @@ const uint8_t ASCII_TO_SEG[95] PROGMEM = {
|
|||
SEG_UNSUPPORTED_CHAR, // '~', (0x7E)
|
||||
};
|
||||
|
||||
// MAX6921Component *global_max6921; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
|
||||
void MAX6921Component::init_display_(void) {
|
||||
uint32_t freq;
|
||||
const uint32_t PWM_FREQ_WANTED = 500;
|
||||
const uint8_t PWM_RESOLUTION = 8;
|
||||
|
||||
// setup PWM for blank pin (intensity)...
|
||||
this->display_.intensity.pwm_channel = 0;
|
||||
freq = ledcSetup(this->display_.intensity.pwm_channel, PWM_FREQ_WANTED, PWM_RESOLUTION);
|
||||
if (freq != 0) {
|
||||
ledcAttachPin(this->display_.intensity.pwm_pin->get_pin(), this->display_.intensity.pwm_channel);
|
||||
this->display_.intensity.max_duty = pow(2,PWM_RESOLUTION); // max. duty value for given resolution
|
||||
this->display_.intensity.duty_quotient = this->display_.intensity.max_duty / MAX_DISPLAY_INTENSITY; // pre-calc fixed duty quotient (256 / 16)
|
||||
ESP_LOGD(TAG, "Prepare intensity PWM: pin=%u, channel=%u, freq=%uHz, resolution=%ubit, duty quotient=%u",
|
||||
this->display_.intensity.pwm_pin->get_pin(),
|
||||
this->display_.intensity.pwm_channel, freq, PWM_RESOLUTION,
|
||||
this->display_.intensity.duty_quotient);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to configure PWM -> set to max. intensity");
|
||||
pinMode(this->display_.intensity.pwm_pin->get_pin(), OUTPUT);
|
||||
this->disable_blank(); // enable display (max. intensity)
|
||||
}
|
||||
|
||||
// display output buffer...
|
||||
this->display_.out_buf_size_ = this->display_.num_digits * 3;
|
||||
this->display_.out_buf_ = new uint8_t[this->display_.out_buf_size_]; // NOLINT
|
||||
memset(this->display_.out_buf_, 0, this->display_.out_buf_size_);
|
||||
|
||||
this->display_.current_text = new char[this->display_.num_digits + 1]; // NOLINT
|
||||
// display text buffer...
|
||||
this->display_.current_text_buf_size = this->display_.num_digits * 2 + 1; // twice number of digits, because of possible points + string terminator
|
||||
this->display_.current_text = new char[this->display_.current_text_buf_size]; // NOLINT
|
||||
this->display_.current_text[0] = 0;
|
||||
this->display_.text_changed = false;
|
||||
|
||||
// display position...
|
||||
this->display_.current_pos = 1;
|
||||
|
||||
// find smallest segment DOUT number...
|
||||
|
@ -152,8 +183,26 @@ void MAX6921Component::init_display_(void) {
|
|||
if (DISP_SEG_TO_OUT[i] < this->display_.seg_out_smallest)
|
||||
this->display_.seg_out_smallest = DISP_SEG_TO_OUT[i];
|
||||
}
|
||||
|
||||
// calculate refresh period for 60Hz
|
||||
this->display_.refresh_period_us = 1000000 / 60 / this->display_.num_digits;
|
||||
ESP_LOGD(TAG, "Set display refresh period: %" PRIu32 "us for %u digits @ 60Hz",
|
||||
this->display_.refresh_period_us, this->display_.num_digits);
|
||||
}
|
||||
|
||||
void MAX6921Component::update_display_(void) {
|
||||
if (this->display_.intensity.config_changed) {
|
||||
// calc duty for low-active BLANK pin...
|
||||
uint32_t inverted_duty = this->display_.intensity.max_duty - \
|
||||
this->display_.intensity.duty_quotient * \
|
||||
this->display_.intensity.config_value;
|
||||
ESP_LOGD(TAG, "Change display intensity to %u (off-time duty=%u/%u)",
|
||||
this->display_.intensity.config_value, inverted_duty,
|
||||
this->display_.intensity.max_duty);
|
||||
ledcWrite(this->display_.intensity.pwm_channel, inverted_duty);
|
||||
this->display_.intensity.config_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MAX6921Component::init_font_(void) {
|
||||
uint8_t seg_data;
|
||||
|
@ -182,27 +231,54 @@ void MAX6921Component::init_font_(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
float MAX6921Component::get_setup_priority() const { return setup_priority::BUS; }
|
||||
float MAX6921Component::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
|
||||
void MAX6921Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up MAX6921...");
|
||||
// global_max6921 = this;
|
||||
|
||||
this->spi_setup();
|
||||
this->load_pin_->setup();
|
||||
this->load_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
this->blank_pin_->setup();
|
||||
this->blank_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
this->disable_load(); // disable output latch
|
||||
this->enable_blank(); // disable display
|
||||
this->disable_load(); // disable output latch
|
||||
this->init_display_();
|
||||
this->init_font_();
|
||||
this->disable_blank(); // enable display (max. intensity)
|
||||
|
||||
|
||||
/* Setup display refresh.
|
||||
* Using a timer is not an option, because the WiFi component uses timer as
|
||||
* well, which leads to unstable refresh cycles (flickering). Therefore a
|
||||
* thread on 2nd MCU core is used.
|
||||
*/
|
||||
xTaskCreatePinnedToCore(&MAX6921Component::display_refresh_task,
|
||||
"display_refresh_task", // name
|
||||
2048, // stack size
|
||||
this, // pass component pointer as task parameter pv
|
||||
1, // priority (one above IDLE task)
|
||||
nullptr, // handle
|
||||
1 // core
|
||||
);
|
||||
}
|
||||
|
||||
void MAX6921Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "MAX6921:");
|
||||
LOG_PIN(" LOAD Pin: ", this->load_pin_);
|
||||
LOG_PIN(" BLANK Pin: ", this->blank_pin_);
|
||||
ESP_LOGCONFIG(TAG, " BLANK Pin: GPIO%u", this->display_.intensity.pwm_pin->get_pin());
|
||||
ESP_LOGCONFIG(TAG, " Number of digits: %u", this->display_.num_digits);
|
||||
ESP_LOGCONFIG(TAG, " Intensity: %u", this->display_.intensity.config_value);
|
||||
}
|
||||
|
||||
void MAX6921Component::set_intensity(uint8_t intensity) {
|
||||
if (intensity > MAX_DISPLAY_INTENSITY) {
|
||||
ESP_LOGW(TAG, "Invalid intensity: %u (0..%u)",
|
||||
this->display_.intensity.config_value, MAX_DISPLAY_INTENSITY);
|
||||
intensity = MAX_DISPLAY_INTENSITY;
|
||||
}
|
||||
if ((intensity == 0) || (intensity != this->display_.intensity.config_value)) {
|
||||
this->display_.intensity.config_value = intensity;
|
||||
ESP_LOGD(TAG, "Set intensity: %u", this->display_.intensity.config_value);
|
||||
this->display_.intensity.config_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -212,36 +288,34 @@ void MAX6921Component::dump_config() {
|
|||
* ------------------------------------------------
|
||||
* DOUT | x | x | x | x | 19 | 18 | ... | 1 | 0
|
||||
*/
|
||||
void MAX6921Component::write_data(uint8_t *ptr, size_t length) {
|
||||
void HOT MAX6921Component::write_data(uint8_t *ptr, size_t length) {
|
||||
uint8_t data[3];
|
||||
#ifdef MORE_DEBUG
|
||||
static bool once = false;
|
||||
#endif
|
||||
|
||||
assert(length == 3);
|
||||
this->disable_load(); // set LOAD to low
|
||||
memcpy(data, ptr, sizeof(data)); // make copy of data, because transfer buffer will be overwritten with SPI answer
|
||||
#ifdef MORE_DEBUG
|
||||
if (!once)
|
||||
ESP_LOGD(TAG, "SPI(%u): 0x%02x%02x%02x", length, data[0], data[1], data[2]);
|
||||
once = true;
|
||||
#endif
|
||||
this->transfer_array(data, sizeof(data));
|
||||
this->enable_load(); // set LOAD to high to update output latch
|
||||
// delayMicroseconds(10);
|
||||
once = true;
|
||||
}
|
||||
|
||||
void MAX6921Component::update() {
|
||||
/*
|
||||
if (this->intensity_changed_) {
|
||||
this->send_to_all_(MAX6921_REGISTER_INTENSITY, this->intensity_);
|
||||
this->intensity_changed_ = false;
|
||||
}
|
||||
for (uint8_t i = 0; i < this->num_chips_ * 8; i++)
|
||||
this->buffer_[i] = 0;
|
||||
*/
|
||||
this->update_display_();
|
||||
|
||||
if (this->writer_.has_value())
|
||||
(*this->writer_)(*this);
|
||||
this->display();
|
||||
}
|
||||
|
||||
void MAX6921Component::display() {
|
||||
|
||||
#if 0
|
||||
void HOT MAX6921Component::display() {
|
||||
static uint count = 0;
|
||||
|
||||
if (count < this->display_.num_digits) {
|
||||
|
@ -259,15 +333,62 @@ void MAX6921Component::display() {
|
|||
if (++this->display_.current_pos > this->display_.num_digits)
|
||||
this->display_.current_pos = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void HOT MAX6921Component::display_refresh_task(void *pv) {
|
||||
MAX6921Component *max6921_comp = (MAX6921Component*)pv;
|
||||
#ifdef MORE_DEBUG
|
||||
static uint count = max6921_comp->display_.num_digits;
|
||||
#endif
|
||||
|
||||
if (max6921_comp->display_.refresh_period_us == 0) {
|
||||
ESP_LOGE(TAG, "Invalid display refresh period -> using default 2ms");
|
||||
max6921_comp->display_.refresh_period_us = 2000;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
#ifdef MORE_DEBUG
|
||||
// debug output one-time after any text change for all digits...
|
||||
if (max6921_comp->display_.text_changed) {
|
||||
count = 0;
|
||||
max6921_comp->display_.text_changed = false;
|
||||
}
|
||||
if (count < max6921_comp->display_.num_digits) {
|
||||
count++;
|
||||
ESP_LOGD(TAG, "%s(): SPI transfer for position %u: 0x%02x%02x%02x", __func__,
|
||||
max6921_comp->display_.current_pos,
|
||||
max6921_comp->display_.out_buf_[(max6921_comp->display_.current_pos-1)*3],
|
||||
max6921_comp->display_.out_buf_[(max6921_comp->display_.current_pos-1)*3+1],
|
||||
max6921_comp->display_.out_buf_[(max6921_comp->display_.current_pos-1)*3+2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// write MAX9621 data of current position...
|
||||
max6921_comp->write_data(&max6921_comp->display_.out_buf_[(max6921_comp->display_.current_pos-1)*3], 3);
|
||||
|
||||
// next display position...
|
||||
if (++max6921_comp->display_.current_pos > max6921_comp->display_.num_digits)
|
||||
max6921_comp->display_.current_pos = 1;
|
||||
|
||||
delayMicroseconds(max6921_comp->display_.refresh_period_us);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Evaluates lambda function
|
||||
* start_pos: 0..n = left..right display position
|
||||
* str : display text
|
||||
*/
|
||||
uint8_t MAX6921Component::print(uint8_t start_pos, const char *str) {
|
||||
uint8_t pos = start_pos;
|
||||
|
||||
// ESP_LOGD(TAG, "%s(): str=%s, prev=%s", __func__, str, this->display_.current_text);
|
||||
if (strcmp(str, this->display_.current_text) == 0) // display text not changed?
|
||||
return strlen(str); // yes -> abort
|
||||
strncpy(this->display_.current_text, str, this->display_.num_digits);
|
||||
this->display_.current_text[this->display_.num_digits] = 0;
|
||||
ESP_LOGD_MORE(TAG, "%s(): text changed: str=%s, prev=%s", __func__, str, this->display_.current_text);
|
||||
strncpy(this->display_.current_text, str, this->display_.current_text_buf_size-1);
|
||||
this->display_.current_text[this->display_.current_text_buf_size-1] = 0;
|
||||
|
||||
for (; *str != '\0'; str++) {
|
||||
uint32_t out_data;
|
||||
|
@ -277,46 +398,56 @@ uint8_t MAX6921Component::print(uint8_t start_pos, const char *str) {
|
|||
}
|
||||
|
||||
// create segment data...
|
||||
ESP_LOGD(TAG, "%s(): pos: %u, char: '%c' (0x%02x)", __func__, pos+1, *str, *str);
|
||||
ESP_LOGD_MORE(TAG, "%s(): pos: %u, char: '%c' (0x%02x)", __func__, pos+1, *str, *str);
|
||||
if ((*str >= ' ') &&
|
||||
((*str - ' ') < ARRAY_ELEM_COUNT(ASCII_TO_SEG))) // supported char?
|
||||
out_data = this->ascii_out_data_[*str - ' ']; // yes ->
|
||||
else
|
||||
out_data = SEG_UNSUPPORTED_CHAR;
|
||||
ESP_LOGD(TAG, "%s(): segment data: 0x%06x", __func__, out_data);
|
||||
ESP_LOGD_MORE(TAG, "%s(): segment data: 0x%06x", __func__, out_data);
|
||||
if (out_data == SEG_UNSUPPORTED_CHAR) {
|
||||
ESP_LOGW(TAG, "Encountered character '%c' with no display representation!", *str);
|
||||
}
|
||||
if ((out_data == (uint32_t)SEG_DP) && (pos > start_pos)) // is point/comma?
|
||||
if (((*str == ',') || (*str == '.')) && (pos > start_pos)) // is point/comma?
|
||||
pos--; // yes -> modify display buffer of previous position
|
||||
else
|
||||
memset(&this->display_.out_buf_[pos*3], 0, 3); // no -> clear display buffer of current position (for later OR operation)
|
||||
|
||||
// shift data to the smallest segment OUT position...
|
||||
out_data <<= (this->display_.seg_out_smallest);
|
||||
ESP_LOGD(TAG, "%s(): segment data shifted to first segment bit (OUT%u): 0x%06x",
|
||||
__func__, this->display_.seg_out_smallest, out_data);
|
||||
ESP_LOGD_MORE(TAG, "%s(): segment data shifted to first segment bit (OUT%u): 0x%06x",
|
||||
__func__, this->display_.seg_out_smallest, out_data);
|
||||
|
||||
// add position data...
|
||||
out_data |= (1 << DISP_POS_TO_OUT[pos]);
|
||||
ESP_LOGD(TAG, "%s(): OUT data with position: 0x%06x", __func__, out_data);
|
||||
ESP_LOGD_MORE(TAG, "%s(): OUT data with position: 0x%06x", __func__, out_data);
|
||||
|
||||
// write to appropriate position of display buffer...
|
||||
this->display_.out_buf_[pos*3+0] |= (uint8_t)((out_data >> 16) & 0xFF);
|
||||
this->display_.out_buf_[pos*3+1] |= (uint8_t)((out_data >> 8) & 0xFF);
|
||||
this->display_.out_buf_[pos*3+2] |= (uint8_t)(out_data & 0xFF);
|
||||
ESP_LOGD(TAG, "%s(): display buffer of position %u: 0x%02x%02x%02x",
|
||||
__func__, pos+1, this->display_.out_buf_[pos*3+0],
|
||||
this->display_.out_buf_[pos*3+1], this->display_.out_buf_[pos*3+2]);
|
||||
ESP_LOGD_MORE(TAG, "%s(): display buffer of position %u: 0x%02x%02x%02x",
|
||||
__func__, pos+1, this->display_.out_buf_[pos*3+0],
|
||||
this->display_.out_buf_[pos*3+1], this->display_.out_buf_[pos*3+2]);
|
||||
|
||||
pos++;
|
||||
}
|
||||
this->display_.text_changed = true;
|
||||
|
||||
return pos - start_pos;
|
||||
}
|
||||
|
||||
uint8_t MAX6921Component::print(const char *str) { return this->print(0, str); }
|
||||
|
||||
uint8_t MAX6921Component::strftime(uint8_t pos, const char *format, ESPTime time) {
|
||||
char buffer[64];
|
||||
size_t ret = time.strftime(buffer, sizeof(buffer), format);
|
||||
if (ret > 0)
|
||||
return this->print(pos, buffer);
|
||||
return 0;
|
||||
}
|
||||
uint8_t MAX6921Component::strftime(const char *format, ESPTime time) { return this->strftime(0, format, time); }
|
||||
|
||||
void MAX6921Component::set_writer(max6921_writer_t &&writer) { this->writer_ = writer; }
|
||||
|
||||
} // namespace max6921
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/time.h"
|
||||
#include "esphome/components/spi/spi.h"
|
||||
#include <esp32-hal-gpio.h>
|
||||
|
||||
|
||||
//#define MORE_DEBUG
|
||||
#ifdef MORE_DEBUG
|
||||
#define ESP_LOGD_MORE(...) ESP_LOGD(__VA_ARGS__)
|
||||
#else
|
||||
#define ESP_LOGD_MORE(...) {}
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace max6921 {
|
||||
|
@ -12,13 +21,26 @@ class MAX6921Component;
|
|||
using max6921_writer_t = std::function<void(MAX6921Component &)>;
|
||||
|
||||
|
||||
typedef struct {
|
||||
InternalGPIOPin *pwm_pin;
|
||||
uint config_value; // intensity from 0..16
|
||||
bool config_changed;
|
||||
uint32_t max_duty;
|
||||
uint32_t duty_quotient;
|
||||
uint8_t pwm_channel;
|
||||
}display_intensity_t;
|
||||
|
||||
typedef struct {
|
||||
uint num_digits;
|
||||
display_intensity_t intensity;
|
||||
uint8_t *out_buf_;
|
||||
size_t out_buf_size_;
|
||||
uint seg_out_smallest;
|
||||
char *current_text;
|
||||
uint current_text_buf_size;
|
||||
uint current_pos;
|
||||
bool text_changed;
|
||||
uint32_t refresh_period_us;
|
||||
}display_t;
|
||||
|
||||
|
||||
|
@ -26,33 +48,36 @@ class MAX6921Component : public PollingComponent,
|
|||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
||||
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_4MHZ> {
|
||||
public:
|
||||
void display();
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override;
|
||||
uint8_t print(uint8_t pos, const char *str);
|
||||
uint8_t print(const char *str);
|
||||
void set_blank_pin(GPIOPin *blank) { this->blank_pin_ = blank; }
|
||||
void set_blank_pin(InternalGPIOPin *pin) { this->display_.intensity.pwm_pin = pin; }
|
||||
void set_intensity(uint8_t intensity);
|
||||
void set_load_pin(GPIOPin *load) { this->load_pin_ = load; }
|
||||
void set_num_digits(uint8_t num_digits) { this->display_.num_digits = num_digits; }
|
||||
void set_writer(max6921_writer_t &&writer);
|
||||
void setup() override;
|
||||
uint8_t strftime(uint8_t pos, const char *format, ESPTime time) __attribute__((format(strftime, 3, 0)));
|
||||
uint8_t strftime(const char *format, ESPTime time) __attribute__((format(strftime, 2, 0)));
|
||||
void write_data(uint8_t *ptr, size_t length);
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
GPIOPin *load_pin_{};
|
||||
GPIOPin *blank_pin_{};
|
||||
display_t display_;
|
||||
uint8_t *ascii_out_data_;
|
||||
void enable_load() { this->load_pin_->digital_write(true); }
|
||||
void disable_load() { this->load_pin_->digital_write(false); }
|
||||
void enable_blank() { this->blank_pin_->digital_write(true); } // display off
|
||||
void disable_blank() { this->blank_pin_->digital_write(false); } // display on
|
||||
void IRAM_ATTR HOT enable_load() { this->load_pin_->digital_write(true); }
|
||||
void IRAM_ATTR HOT disable_load() { this->load_pin_->digital_write(false); }
|
||||
void enable_blank() { digitalWrite(this->display_.intensity.pwm_pin->get_pin(), HIGH); } // display off
|
||||
void disable_blank() { digitalWrite(this->display_.intensity.pwm_pin->get_pin(), LOW); } // display on
|
||||
optional<max6921_writer_t> writer_{};
|
||||
static void display_refresh_task(void *pv);
|
||||
|
||||
private:
|
||||
void init_display_(void);
|
||||
void init_font_(void);
|
||||
void update_display_();
|
||||
};
|
||||
|
||||
} // namespace max6921
|
||||
|
|
Loading…
Reference in a new issue