ESPHome  2024.11.0
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 
8 namespace esphome {
9 namespace mpr121 {
10 
11 static 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 
42  this->write_byte(MPR121_DEBOUNCE, 0);
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 
58 void MPR121Component::set_touch_debounce(uint8_t debounce) {
59  uint8_t mask = debounce << 4;
60  this->debounce_ &= 0x0f;
61  this->debounce_ |= mask;
62 }
63 
64 void MPR121Component::set_release_debounce(uint8_t debounce) {
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;
77  case WRONG_CHIP_STATE:
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 
97  this->read_byte(MPR121_GPIODATA, &this->gpio_input_);
98 }
99 
100 bool MPR121Component::digital_read(uint8_t ionum) { return (this->gpio_input_ & (1 << ionum)) != 0; }
101 
102 void 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 
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);
129  this->write_byte(MPR121_GPIOEN, this->gpio_enable_);
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 
141 void 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 
158 std::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
bool digital_read(uint8_t ionum)
Definition: mpr121.cpp:100
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition: i2c.h:246
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
uint8_t gpio_input_
The mask to read as input state - 1 means HIGH, 0 means LOW.
Definition: mpr121.h:103
bool digital_read() override
Definition: mpr121.cpp:148
bool is_failed() const
Definition: component.cpp:143
void set_release_debounce(uint8_t debounce)
Definition: mpr121.cpp:64
void pin_mode(uint8_t ionum, gpio::Flags flags)
Definition: mpr121.cpp:111
enum esphome::mpr121::MPR121Component::ErrorCode NONE
mopeka_std_values val[4]
std::vector< MPR121Channel * > channels_
Definition: mpr121.h:83
uint8_t gpio_enable_
The enable mask - zero means high Z, 1 means GPIO usage.
Definition: mpr121.h:97
void status_clear_warning()
Definition: component.cpp:166
uint8_t gpio_direction_
Mask for the pin mode - 1 means output, 0 means input.
Definition: mpr121.h:99
const uint32_t flags
Definition: stm32flash.h:85
void digital_write(uint8_t ionum, bool value)
Definition: mpr121.cpp:102
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
void digital_write(bool value) override
Definition: mpr121.cpp:153
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
std::string dump_summary() const override
Definition: mpr121.cpp:158
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void dump_config() override
Definition: mpr121.cpp:70
void pin_mode(gpio::Flags flags) override
Definition: mpr121.cpp:143
uint8_t gpio_output_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition: mpr121.h:101
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
void set_touch_debounce(uint8_t debounce)
Definition: mpr121.cpp:58