ESPHome 2025.10.3
Loading...
Searching...
No Matches
mpr121.cpp
Go to the documentation of this file.
1#include "mpr121.h"
2
3#include <cstdint>
4
5#include "esphome/core/hal.h"
6#include "esphome/core/log.h"
7
8namespace esphome {
9namespace mpr121 {
10
11static const char *const TAG = "mpr121";
12
14 this->disable_loop();
15 // soft reset device
16 this->write_byte(MPR121_SOFTRESET, 0x63);
17 this->set_timeout(100, [this]() {
18 if (!this->write_byte(MPR121_ECR, 0x0)) {
19 this->error_code_ = COMMUNICATION_FAILED;
20 this->mark_failed();
21 return;
22 }
23 // set touch sensitivity for all 12 channels
24 for (auto *channel : this->channels_) {
25 channel->setup();
26 }
27 this->write_byte(MPR121_MHDR, 0x01);
28 this->write_byte(MPR121_NHDR, 0x01);
29 this->write_byte(MPR121_NCLR, 0x0E);
30 this->write_byte(MPR121_FDLR, 0x00);
31
32 this->write_byte(MPR121_MHDF, 0x01);
33 this->write_byte(MPR121_NHDF, 0x05);
34 this->write_byte(MPR121_NCLF, 0x01);
35 this->write_byte(MPR121_FDLF, 0x00);
36
37 this->write_byte(MPR121_NHDT, 0x00);
38 this->write_byte(MPR121_NCLT, 0x00);
39 this->write_byte(MPR121_FDLT, 0x00);
40
42 // default, 16uA charge current
43 this->write_byte(MPR121_CONFIG1, 0x10);
44 // 0.5uS encoding, 1ms period
45 this->write_byte(MPR121_CONFIG2, 0x20);
46
47 // Write the Electrode Configuration Register
48 // * Highest 2 bits is "Calibration Lock", which we set to a value corresponding to 5 bits.
49 // * The 2 bits below is "Proximity Enable" and are left at 0.
50 // * The 4 least significant bits control how many electrodes are enabled. Electrodes are enabled
51 // as a range, starting at 0 up to the highest channel index used.
52 this->write_byte(MPR121_ECR, 0x80 | (this->max_touch_channel_ + 1));
53
54 this->flush_gpio_();
55 this->enable_loop();
56 });
57}
58
60 uint8_t mask = debounce << 4;
61 this->debounce_ &= 0x0f;
62 this->debounce_ |= mask;
63}
64
66 uint8_t mask = debounce & 0x0f;
67 this->debounce_ &= 0xf0;
68 this->debounce_ |= mask;
69};
70
72 ESP_LOGCONFIG(TAG, "MPR121:");
73 LOG_I2C_DEVICE(this);
74 switch (this->error_code_) {
76 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
77 break;
78 case NONE:
79 default:
80 break;
81 }
82}
84 uint16_t val = 0;
86
87 // Flip order
88 uint8_t lsb = val >> 8;
89 uint8_t msb = val;
90 val = (uint16_t(msb) << 8) | lsb;
91
92 for (auto *channel : this->channels_)
93 channel->process(val);
94
96}
97
98bool MPR121Component::digital_read(uint8_t ionum) { return (this->gpio_input_ & (1 << ionum)) != 0; }
99
100void MPR121Component::digital_write(uint8_t ionum, bool value) {
101 if (value) {
102 this->gpio_output_ |= (1 << ionum);
103 } else {
104 this->gpio_output_ &= ~(1 << ionum);
105 }
106 this->flush_gpio_();
107}
108
110 this->gpio_enable_ |= (1 << ionum);
111 if (flags & gpio::FLAG_INPUT) {
112 this->gpio_direction_ &= ~(1 << ionum);
113 } else if (flags & gpio::FLAG_OUTPUT) {
114 this->gpio_direction_ |= 1 << ionum;
115 }
116 this->flush_gpio_();
117}
118
120 if (this->is_failed()) {
121 return false;
122 }
123
124 // TODO: The CTL registers can configure internal pullup/pulldown resistors.
125 this->write_byte(MPR121_GPIOCTL0, 0x00);
126 this->write_byte(MPR121_GPIOCTL1, 0x00);
129
130 if (!this->write_byte(MPR121_GPIODATA, this->gpio_output_)) {
131 this->status_set_warning();
132 return false;
133 }
134
135 this->status_clear_warning();
136 return true;
137}
138
139void MPR121GPIOPin::setup() { this->pin_mode(this->flags_); }
140
142 assert(this->pin_ >= 4);
143 this->parent_->pin_mode(this->pin_ - 4, flags);
144}
145
147 assert(this->pin_ >= 4);
148 return this->parent_->digital_read(this->pin_ - 4) != this->inverted_;
149}
150
152 assert(this->pin_ >= 4);
153 this->parent_->digital_write(this->pin_ - 4, value != this->inverted_);
154}
155
156std::string MPR121GPIOPin::dump_summary() const {
157 char buffer[32];
158 snprintf(buffer, sizeof(buffer), "ELE%u on MPR121", this->pin_);
159 return buffer;
160}
161
162} // namespace mpr121
163} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
void enable_loop()
Enable this component's loop.
void disable_loop()
Disable this component's loop.
void status_clear_warning()
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:266
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:241
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition i2c.h:250
uint8_t gpio_enable_
The enable mask - zero means high Z, 1 means GPIO usage.
Definition mpr121.h:96
bool digital_read(uint8_t ionum)
Definition mpr121.cpp:98
void set_release_debounce(uint8_t debounce)
Definition mpr121.cpp:65
uint8_t gpio_direction_
Mask for the pin mode - 1 means output, 0 means input.
Definition mpr121.h:98
std::vector< MPR121Channel * > channels_
Definition mpr121.h:83
uint8_t gpio_output_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition mpr121.h:100
enum esphome::mpr121::MPR121Component::ErrorCode NONE
void digital_write(uint8_t ionum, bool value)
Definition mpr121.cpp:100
void pin_mode(uint8_t ionum, gpio::Flags flags)
Definition mpr121.cpp:109
uint8_t gpio_input_
The mask to read as input state - 1 means HIGH, 0 means LOW.
Definition mpr121.h:102
void set_touch_debounce(uint8_t debounce)
Definition mpr121.cpp:59
void digital_write(bool value) override
Definition mpr121.cpp:151
std::string dump_summary() const override
Definition mpr121.cpp:156
void pin_mode(gpio::Flags flags) override
Definition mpr121.cpp:141
MPR121Component * parent_
Definition mpr121.h:122
bool digital_read() override
Definition mpr121.cpp:146
uint16_t flags
mopeka_std_values val[4]
@ FLAG_OUTPUT
Definition gpio.h:19
@ FLAG_INPUT
Definition gpio.h:18
@ MPR121_TOUCHSTATUS_L
Definition mpr121.h:15
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7