amiro-os / components / input / mpr121.cpp @ 4d54a507
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 = ®
|
||
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 */ |