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