Statistics
| Branch: | Tag: | Revision:

amiro-os / components / input / mpr121.cpp @ 58fe0e0b

History | View | Annotate | Download (4.149 KB)

1 58fe0e0b Thomas Schöpping
#include <amiro/bus/i2c/I2CDriver.hpp>
2
#include <amiro/input/mpr121.hpp>
3
4
namespace amiro {
5
6
MPR121::
7
MPR121(I2CDriver *driver, const uint8_t master_id) :
8
  BaseStaticThread<256>(),
9
  driver(driver),
10
  master_id(master_id),
11
  button_state(0x0000u) {
12
13
  chDbgCheck(master_id <= 0x03u, "MPR121 ctor master_id");
14
  this->tx_params.addr = MPR121::SLA | this->master_id;
15
16
}
17
18
MPR121::
19
~MPR121() {
20
21
}
22
23
msg_t
24
MPR121::
25
updateButtonData() {
26
27
  msg_t res;
28
  const uint8_t offset_touch = offsetof(MPR121::registers, touch_status);
29
  const uint8_t offset_electrode = offsetof(MPR121::registers, ele_filt_data);
30
  const uint8_t offset_baseline = offsetof(MPR121::registers, ele_baseline);
31
  uint8_t buffer[offsetof(MPR121::registers, mhd_rising) - offset_touch];
32
  uint8_t *tmp = buffer;
33
  uint8_t reg = offset_touch;
34
  uint8_t i;
35
  this->tx_params.txbuf = &reg;
36
  this->tx_params.txbytes = 1;
37
  this->tx_params.rxbuf = buffer;
38
  this->tx_params.rxbytes = sizeof(buffer);
39
40
  res = this->driver->masterTransmit(&this->tx_params);
41
42
  if (!res) {
43
    tmp = buffer + offset_touch;
44
    this->button_state = (*(tmp + 1) << 8) | *tmp;
45
    tmp = buffer + offset_electrode;
46
    for (i = 0x00; i < 13; i++) {
47
      this->electrode_data[i] = (*(tmp + 1) << 8) | *tmp;
48
      tmp += 2;
49
    }
50
    tmp = buffer + offset_baseline;
51
    for (i = 0x00; i < 13; i++)
52
      this->baseline_data[i] = *tmp++;
53
54
  }
55
56
  return res;
57
58
}
59
60
msg_t
61
MPR121::
62
softReset() {
63
64
  msg_t res;
65
  uint8_t buffer[2];
66
67
  buffer[0] = offsetof(MPR121::registers, soft_reset);
68
  buffer[1] = SOFT_RST_MAGIC;
69
70
  this->tx_params.txbuf = buffer;
71
  this->tx_params.txbytes = 2;
72
  this->tx_params.rxbytes = 0;
73
74
  res = this->driver->masterTransmit(&this->tx_params);
75
76
  if (res)
77
    return res;
78
79
  buffer[0] = offsetof(MPR121::registers, ele_config);
80
  buffer[1] = 0x00u; /* ele_config: make sure we are in stop mode */
81
82
  return this->driver->masterTransmit(&this->tx_params);
83
84
}
85
86
msg_t
87
MPR121::
88
writeConfig(const MPR121Config *cfg) {
89
90
  msg_t res;
91
  uint8_t buffer[6];
92
93
  buffer[0] = offsetof(MPR121::registers, auto_cfg_ctrl);
94
  buffer[1] = (cfg->auto_config & 0x00FFu);
95
  buffer[2] = (cfg->auto_config & 0xFF00u) >> 8;
96
  buffer[3] = cfg->up_side_limit;
97
  buffer[4] = cfg->low_side_limit;
98
  buffer[5] = cfg->target_level;
99
100
  this->tx_params.txbuf = buffer;
101
  this->tx_params.txbytes = 6;
102
  this->tx_params.rxbytes = 0;
103
104
  res = this->driver->masterTransmit(&this->tx_params);
105
106
  if (res)
107
    return res;
108
109
  buffer[0] = offsetof(MPR121::registers, cdc_config);
110
  buffer[1] = (cfg->global_config & 0x00FFu);
111
  buffer[2] = (cfg->global_config & 0xFF00u) >> 8;
112
  buffer[3] = cfg->ele_config;
113
114
  this->tx_params.txbytes = 4;
115
116
  return this->driver->masterTransmit(&this->tx_params);
117
118
}
119
120
uint16_t
121
MPR121::
122
getButtonStatus() {
123
124
  return this->button_state;
125
126
}
127
128
uint8_t
129
MPR121::
130
getButtonStatus(uint8_t ix) {
131
132
  return this->button_state & (1u << ix);
133
134
}
135
136
uint8_t
137
MPR121::
138
getBaselineData(uint8_t ix) {
139
140
  return this->baseline_data[ix];
141
142
}
143
144
uint16_t
145
MPR121::
146
getElectrodeData(uint8_t ix) {
147
148
  return this->electrode_data[ix];
149
150
}
151
152
/**
153
 * Main Sensor Thread.
154
 * Will not check whether sensor was actually configured prior to running.
155
 * @note   You should configure the sensor while stopped, then start.
156
 * @return RDY_OK on exit.
157
 */
158
msg_t
159
MPR121::
160
main(void) {
161
162
  I2CDriver *drv = this->driver;
163
164
  this->setName("MPR121");
165
166
  while (!this->shouldTerminate()) {
167
168
    drv->acquireBus();
169
    this->updateButtonData();
170
    drv->releaseBus();
171
172
    this->eventSource.broadcastFlags(0);
173
174
    this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(100));
175
  }
176
177
  return RDY_OK;
178
}
179
180
/**
181
 * Configure the MPR121 touch sensor.
182
 * Will perform a soft reset and then apply the configuration \p cfg.
183
 * @note      Call only when sensor is stopped.
184
 * @param cfg The new configuration.
185
 * @return    RDY_OK if everything went well. Appropriate error otherwise.
186
 */
187
msg_t
188
MPR121::
189
configure(const MPR121Config *cfg) {
190
191
  I2CDriver *drv = this->driver;
192
  msg_t res;
193
194
  drv->acquireBus();
195
196
  // do a soft reset, in case config changes config mode
197
  // (auto config vs. configure all sensors individually)
198
  res = this->softReset();
199
200
  if (res == RDY_OK) {
201
202
    res = this->writeConfig(cfg);
203
204
  }
205
206
  drv->releaseBus();
207
208
  return res;
209
}
210
211
212
} /* amiro */