Statistics
| Branch: | Tag: | Revision:

amiro-os / components / input / mpr121.cpp @ b8b3a9c9

History | View | Annotate | Download (4.186 KB)

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