ESPHome 2025.9.0-dev
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 // soft reset device
15 this->write_byte(MPR121_SOFTRESET, 0x63);
16 delay(100); // NOLINT
17 if (!this->write_byte(MPR121_ECR, 0x0)) {
18 this->error_code_ = COMMUNICATION_FAILED;
19 this->mark_failed();
20 return;
21 }
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}
56
58 uint8_t mask = debounce << 4;
59 this->debounce_ &= 0x0f;
60 this->debounce_ |= mask;
61}
62
64 uint8_t mask = debounce & 0x0f;
65 this->debounce_ &= 0xf0;
66 this->debounce_ |= mask;
67};
68
70 ESP_LOGCONFIG(TAG, "MPR121:");
71 LOG_I2C_DEVICE(this);
72 switch (this->error_code_) {
74 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
75 break;
77 ESP_LOGE(TAG, "MPR121 has wrong default value for CONFIG2?");
78 break;
79 case NONE:
80 default:
81 break;
82 }
83}
85 uint16_t val = 0;
87
88 // Flip order
89 uint8_t lsb = val >> 8;
90 uint8_t msb = val;
91 val = (uint16_t(msb) << 8) | lsb;
92
93 for (auto *channel : this->channels_)
94 channel->process(val);
95
97}
98
99bool MPR121Component::digital_read(uint8_t ionum) { return (this->gpio_input_ & (1 << ionum)) != 0; }
100
101void MPR121Component::digital_write(uint8_t ionum, bool value) {
102 if (value) {
103 this->gpio_output_ |= (1 << ionum);
104 } else {
105 this->gpio_output_ &= ~(1 << ionum);
106 }
107 this->flush_gpio_();
108}
109
110void MPR121Component::pin_mode(uint8_t ionum, gpio::Flags flags) {
111 this->gpio_enable_ |= (1 << ionum);
112 if (flags & gpio::FLAG_INPUT) {
113 this->gpio_direction_ &= ~(1 << ionum);
114 } else if (flags & gpio::FLAG_OUTPUT) {
115 this->gpio_direction_ |= 1 << ionum;
116 }
117 this->flush_gpio_();
118}
119
121 if (this->is_failed()) {
122 return false;
123 }
124
125 // TODO: The CTL registers can configure internal pullup/pulldown resistors.
126 this->write_byte(MPR121_GPIOCTL0, 0x00);
127 this->write_byte(MPR121_GPIOCTL1, 0x00);
130
131 if (!this->write_byte(MPR121_GPIODATA, this->gpio_output_)) {
132 this->status_set_warning();
133 return false;
134 }
135
136 this->status_clear_warning();
137 return true;
138}
139
140void MPR121GPIOPin::setup() { this->pin_mode(this->flags_); }
141
143 assert(this->pin_ >= 4);
144 this->parent_->pin_mode(this->pin_ - 4, flags);
145}
146
148 assert(this->pin_ >= 4);
149 return this->parent_->digital_read(this->pin_ - 4) != this->inverted_;
150}
151
153 assert(this->pin_ >= 4);
154 this->parent_->digital_write(this->pin_ - 4, value != this->inverted_);
155}
156
157std::string MPR121GPIOPin::dump_summary() const {
158 char buffer[32];
159 snprintf(buffer, sizeof(buffer), "ELE%u on MPR121", this->pin_);
160 return buffer;
161}
162
163} // namespace mpr121
164} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
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:99
void set_release_debounce(uint8_t debounce)
Definition mpr121.cpp:63
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:101
void pin_mode(uint8_t ionum, gpio::Flags flags)
Definition mpr121.cpp:110
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:57
void digital_write(bool value) override
Definition mpr121.cpp:152
std::string dump_summary() const override
Definition mpr121.cpp:157
void pin_mode(gpio::Flags flags) override
Definition mpr121.cpp:142
MPR121Component * parent_
Definition mpr121.h:123
bool digital_read() override
Definition mpr121.cpp:147
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:29