Tm1637 binarysensor (#2792)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Michiel van TurnhoutandJesse Hills authored and GitHub committed 2022-04-04 11:42:10 +12:00
1 parent 2e436eae6b
commit 70fafa473b
3 files changed
+132 -17

No files matched your search

+76 -16
View File
@@ -7,11 +7,17 @@ namespace esphome {
namespace tm1637 {
static const char *const TAG = "display.tm1637";
const uint8_t TM1637_I2C_COMM1 = 0x40;
const uint8_t TM1637_I2C_COMM2 = 0xC0;
const uint8_t TM1637_I2C_COMM3 = 0x80;
const uint8_t TM1637_CMD_DATA = 0x40; //!< Display data command
const uint8_t TM1637_CMD_CTRL = 0x80; //!< Display control command
const uint8_t TM1637_CMD_ADDR = 0xc0; //!< Display address command
const uint8_t TM1637_UNKNOWN_CHAR = 0b11111111;
// Data command bits
const uint8_t TM1637_DATA_WRITE = 0x00; //!< Write data
const uint8_t TM1637_DATA_READ_KEYS = 0x02; //!< Read keys
const uint8_t TM1637_DATA_AUTO_INC_ADDR = 0x00; //!< Auto increment address
const uint8_t TM1637_DATA_FIXED_ADDR = 0x04; //!< Fixed address
//
// A
// ---
@@ -138,6 +144,36 @@ void TM1637Display::dump_config() {
LOG_UPDATE_INTERVAL(this);
}
#ifdef USE_BINARY_SENSOR
void TM1637Display::loop() {
uint8_t val = this->get_keys();
for (auto *tm1637_key : this->tm1637_keys_)
tm1637_key->process(val);
}
uint8_t TM1637Display::get_keys() {
this->start_();
this->send_byte_(TM1637_CMD_DATA | TM1637_DATA_READ_KEYS);
this->start_();
uint8_t key_code = read_byte_();
this->stop_();
if (key_code != 0xFF) {
// Invert key_code:
// Bit | 7 6 5 4 3 2 1 0
// ------+-------------------------
// From | S0 S1 S2 K1 K2 1 1 1
// To | S0 S1 S2 K1 K2 0 0 0
key_code = ~key_code;
// Shift bits to:
// Bit | 7 6 5 4 3 2 1 0
// ------+------------------------
// To | 0 0 0 0 K2 S2 S1 S0
key_code = (uint8_t)((key_code & 0x80) >> 7 | (key_code & 0x40) >> 5 | (key_code & 0x20) >> 3 | (key_code & 0x08));
}
return key_code;
}
#endif
void TM1637Display::update() {
for (uint8_t &i : this->buffer_)
i = 0;
@@ -165,14 +201,14 @@ void TM1637Display::stop_() {
void TM1637Display::display() {
ESP_LOGVV(TAG, "Display %02X%02X%02X%02X", buffer_[0], buffer_[1], buffer_[2], buffer_[3]);
// Write COMM1
// Write DATA CMND
this->start_();
this->send_byte_(TM1637_I2C_COMM1);
this->send_byte_(TM1637_CMD_DATA);
this->stop_();
// Write COMM2 + first digit address
// Write ADDR CMD + first digit address
this->start_();
this->send_byte_(TM1637_I2C_COMM2);
this->send_byte_(TM1637_CMD_ADDR);
// Write the data bytes
if (this->inverted_) {
@@ -187,20 +223,17 @@ void TM1637Display::display() {
this->stop_();
// Write COMM3 + brightness
// Write display CTRL CMND + brightness
this->start_();
this->send_byte_(TM1637_I2C_COMM3 + ((this->intensity_ & 0x7) | 0x08));
this->send_byte_(TM1637_CMD_CTRL + ((this->intensity_ & 0x7) | 0x08));
this->stop_();
}
bool TM1637Display::send_byte_(uint8_t b) {
uint8_t data = b;
// 8 Data Bits
for (uint8_t i = 0; i < 8; i++) {
// CLK low
this->clk_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->bit_delay_();
// Set data bit
if (data & 0x01) {
this->dio_pin_->pin_mode(gpio::FLAG_INPUT);
@@ -209,19 +242,16 @@ bool TM1637Display::send_byte_(uint8_t b) {
}
this->bit_delay_();
// CLK high
this->clk_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
data = data >> 1;
}
// Wait for acknowledge
// CLK to zero
this->clk_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->dio_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
// CLK to high
this->clk_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
@@ -237,8 +267,38 @@ bool TM1637Display::send_byte_(uint8_t b) {
return ack;
}
uint8_t TM1637Display::read_byte_() {
uint8_t retval = 0;
// Prepare DIO to read data
this->dio_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
// Data is shifted out by the TM1637 on the CLK falling edge
for (uint8_t bit = 0; bit < 8; bit++) {
this->clk_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
// Read next bit
retval <<= 1;
if (this->dio_pin_->digital_read()) {
retval |= 0x01;
}
this->clk_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->bit_delay_();
}
// Return DIO to output mode
// Dummy ACK
this->dio_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->bit_delay_();
this->clk_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
this->clk_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->bit_delay_();
this->dio_pin_->pin_mode(gpio::FLAG_INPUT);
this->bit_delay_();
return retval;
}
uint8_t TM1637Display::print(uint8_t start_pos, const char *str) {
ESP_LOGV(TAG, "Print at %d: %s", start_pos, str);
// ESP_LOGV(TAG, "Print at %d: %s", start_pos, str);
uint8_t pos = start_pos;
for (; *str != '\0'; str++) {
uint8_t data = TM1637_UNKNOWN_CHAR;