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