Statistics
| Branch: | Tag: | Revision:

amiro-os / test / periphery-lld / AT42QT1050_v1 / aos_test_AT42QT1050.c @ 3cee92c7

History | View | Annotate | Download (18.758 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
#include <amiroos.h>
20
#include <aos_test_AT42QT1050.h>
21

    
22
#if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
23

    
24
/******************************************************************************/
25
/* LOCAL DEFINITIONS                                                          */
26
/******************************************************************************/
27

    
28
#define INTERRUPT_EVENT_ID            1
29

    
30
/******************************************************************************/
31
/* EXPORTED VARIABLES                                                         */
32
/******************************************************************************/
33

    
34
/******************************************************************************/
35
/* LOCAL TYPES                                                                */
36
/******************************************************************************/
37

    
38
/******************************************************************************/
39
/* LOCAL VARIABLES                                                            */
40
/******************************************************************************/
41

    
42
/******************************************************************************/
43
/* LOCAL FUNCTIONS                                                            */
44
/******************************************************************************/
45

    
46
void print_settings(int32_t* status, BaseSequentialStream* stream, const aos_test_t* test) {
47
    chprintf(stream, "settings...\n");
48

    
49
    uint8_t test8;
50
    at42qt1050_lld_register_t txbuf;
51
    *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_LOWPOWERMODE, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
52
    chprintf(stream, "\tmeasurement inverval %d ms\n", test8*8);
53

    
54
    *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_MAXONDURATION, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
55
    chprintf(stream, "\tMax on duration %d ms\n", test8*160);
56

    
57
    *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_FINFOUTMAXCALGUARD, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
58
    chprintf(stream, "\tFast In %d, Fast Out, %d MaxCal %d\n\tGuard channel ",
59
             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_FI,     //enter fast mode whenever an unfiltered signal value is detected
60
             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_FO,     //DI of 4 (global setting for all keys)
61
             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_MAXCAL);//recalibrate ALL KEYS after a Max On Duration timeout vs. individually
62

    
63
    //guard channel (which gets priority filtering)
64
    if((test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_GUARD) > AT42QT1050_LLD_NUM_KEYS-1)
65
        chprintf(stream, "off");
66
    else
67
        chprintf(stream, " %d", test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_GUARD);
68

    
69
    chprintf(stream, "\n\n\tkey\tgroup\tintegr.\tdelay\tthresh.\tpulse\tscale\n");
70
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
71
        chprintf(stream, "\t%d\t", key);
72
        txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, key);
73
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
74
        if(!((at42qt1050_lld_detectionintegratoraksreg_t)test8).aks)
75
            chprintf(stream, "none\t");
76
        else
77
            chprintf(stream, "%d\t", ((at42qt1050_lld_detectionintegratoraksreg_t)test8).aks);
78

    
79
        if(!((at42qt1050_lld_detectionintegratoraksreg_t)test8).detection_integrator)
80
            chprintf(stream, "off");
81
        else
82
            chprintf(stream, "%d", ((at42qt1050_lld_detectionintegratoraksreg_t)test8).detection_integrator);
83

    
84
        txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_CHARGESHAREDELAY_0, key);
85
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
86
        chprintf(stream, "\t+%d", test8);
87

    
88
        txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
89
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
90
        chprintf(stream, "\t%d", test8);
91

    
92
        txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_PULSE_SCALE_0, key);
93
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
94
        chprintf(stream, "\t%d\t%d\n", ((at42qt1050_lld_pulsescalereg_t)test8).pulse, ((at42qt1050_lld_pulsescalereg_t)test8).scale);
95
    }
96

    
97
}
98

    
99
void show_live(const uint8_t first_key, int32_t* status,
100
               BaseSequentialStream* stream, const aos_test_t* test) {
101

    
102
    apalDbgAssert(first_key<5);
103

    
104
    event_listener_t event_listener;
105
    aos_timestamp_t tcurrent, tend ,tdemo_end;
106

    
107
    //stop demo after 15 seconds
108
    aosSysGetUptime(&tcurrent);
109
    tdemo_end = tcurrent + 15*MICROSECONDS_PER_SECOND;
110

    
111
    uint8_t keyStatus, detectionStatus;
112
    uint16_t signal, reference;
113
    uint8_t threshold[AT42QT1050_LLD_NUM_KEYS];
114

    
115
    chprintf(stream, "key, count, ref, signal, [threshold], \033[31mtouch\n\033[0m");
116

    
117
    //get thresholds
118
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
119
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
120
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &threshold[key], ((aos_test_at42qt1050data_t*)test->data)->timeout);
121
    }
122
    chEvtRegister(((aos_test_at42qt1050data_t*)test->data)->evtsource, &event_listener, INTERRUPT_EVENT_ID);
123
    while(true) {
124
        aosSysGetUptime(&tcurrent);
125

    
126
        for (uint8_t key = first_key; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
127

    
128
            //highlight touched key
129
            *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_KEYSTATUS, &keyStatus, ((aos_test_at42qt1050data_t*)test->data)->timeout);
130
            if((key == 0 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY0)
131
                    || (key == 1 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY1)
132
                    || (key == 2 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY2)
133
                    || (key == 3 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY3)
134
                    || (key == 4 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY4))
135
                chprintf(stream, "\033[31m"); //red
136
            else
137
                chprintf(stream, "\033[0m"); //black
138

    
139
            *status |= at42qt1050_lld_read_keyssignal(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, key, &signal, ((aos_test_at42qt1050data_t*)test->data)->timeout);
140
            *status |= at42qt1050_lld_read_referencedata(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, key, &reference, ((aos_test_at42qt1050data_t*)test->data)->timeout);
141

    
142
            const uint16_t dist = (signal<reference?0:signal-reference);
143
            chprintf(stream, "\033[Kkey %d, %d\t0x%04X 0x%04X [", key, dist, reference, signal);
144
            uint16_t stars=0;
145
            for(; stars < dist; stars++) {
146
                chprintf(stream, "0");
147
                if(stars > 40) {           //max_stars = 40
148
                    chprintf(stream, "+"); //more than max_stars
149
                    break;
150
                }
151
            }
152
            for(; stars < threshold[key]; stars++)
153
                chprintf(stream, " ");
154
            if(stars == threshold[key])
155
                chprintf(stream, "]");
156
            chprintf(stream, "\n\033[0m");
157
        }
158

    
159
        //wait 1/3 second for a touch event
160
        tend = tcurrent + (MICROSECONDS_PER_SECOND/3);
161
        const eventmask_t emask = chEvtWaitOneTimeout(EVENT_MASK(INTERRUPT_EVENT_ID), chTimeUS2I(tend));
162
        const eventflags_t eflags = chEvtGetAndClearFlags(&event_listener);
163
        if (emask == EVENT_MASK(INTERRUPT_EVENT_ID) && eflags == ((aos_test_at42qt1050data_t*)test->data)->evtflags) {
164
            // interrupt detected
165
            chprintf(stream, "interrupt ");
166
        } // else: timeout
167

    
168
        *status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_DETECTIONSTATUS, &detectionStatus, ((aos_test_at42qt1050data_t*)test->data)->timeout);
169
        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_TOUCH)
170
            chprintf(stream, "touch ");
171
        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_OVERFLOW)
172
            chprintf(stream, "overflow ");
173
        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_CALIBRATE)
174
            chprintf(stream, "calibrate");
175
        chprintf(stream, "\033[K");
176

    
177
        if(tcurrent > tdemo_end)
178
            break;
179

    
180
        chprintf(stream, "\033[%dF", 5-first_key); //cursor up
181
    }
182
    chEvtUnregister(((aos_test_at42qt1050data_t*)test->data)->evtsource, &event_listener);
183
}
184

    
185
/******************************************************************************/
186
/* EXPORTED FUNCTIONS                                                         */
187
/******************************************************************************/
188

    
189
aos_testresult_t aosTestAt42qt1050Func(BaseSequentialStream* stream, const aos_test_t* test)
190
{
191
    aosDbgCheck(test->data != NULL && ((aos_test_at42qt1050data_t*)test->data)->at42qt1050d != NULL);
192

    
193
    // local variables
194
    aos_testresult_t result = {0, 0};
195
    int32_t status;
196
    uint8_t test_8;
197
    bool error;
198

    
199
    chprintf(stream, "read register...\n");
200
    error = false;
201
    status = at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_CHIPID, &test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
202
    chprintf(stream, "\t\tchip ID: 0x%02X\n", test_8);
203
    if (test_8 != AT42QT1050_LLD_CHIPID)
204
        error = true;
205
    status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_FIRMWAREVERSION, &test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
206
    chprintf(stream, "\t\tfirmware version: %u.%u (0x%02X)\n", ((at42qt1050_lld_firmwarereg_t)test_8).major, ((at42qt1050_lld_firmwarereg_t)test_8).minor, test_8);
207
    if (status == APAL_STATUS_SUCCESS && !error) {
208
        aosTestPassed(stream, &result);
209
    } else {
210
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
211
    }
212

    
213
    chprintf(stream, "write and readback threshold data...\n");
214
    status = APAL_STATUS_OK;
215
    const uint8_t threshold_test = 0x40;
216
    error = false;
217
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
218
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
219
        status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, threshold_test , ((aos_test_at42qt1050data_t*)test->data)->timeout);
220
        status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
221
        if(test_8 != threshold_test)
222
            error = true;
223
    }
224
    if (status == APAL_STATUS_SUCCESS  &&  !error) {
225
        aosTestPassedMsg(stream, &result, "Set thresholds successfull to 0x%04X\n", threshold_test);
226
    } else {
227
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
228
    }
229

    
230
    chprintf(stream, "guarding...\nincrease charge_delay0\ndisable multitouch\n");
231

    
232
    //channel 0 is to big to be charged in the default cycle
233
    status = at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_CHARGESHAREDELAY_0, 128 , ((aos_test_at42qt1050data_t*)test->data)->timeout);
234

    
235
    //set all channel to group 1 -> only 1 simultaneous touch in group = single touch
236
    at42qt1050_lld_detectionintegratoraksreg_t detectionintegrator;
237
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
238
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, key);
239
        detectionintegrator.aks = 1;                  //on touch per group-id simultaneous
240
        detectionintegrator.detection_integrator = 4; //4 times > threshold => touchevent
241
        status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, detectionintegrator.raw, ((aos_test_at42qt1050data_t*)test->data)->timeout);
242
    }
243
    if (status == APAL_STATUS_SUCCESS) {
244
        aosTestPassed(stream, &result);
245
    } else {
246
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
247
    }
248

    
249
    chprintf(stream, "reset device...\n");
250
    status = at42qt1050_lld_reset(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, ((aos_test_at42qt1050data_t*)test->data)->timeout, true);
251
    if (status == APAL_STATUS_SUCCESS) {
252
        aosTestPassed(stream, &result);
253
    } else {
254
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
255
    }
256

    
257
    chprintf(stream, "read threshold data again...\n");
258
    status = APAL_STATUS_OK;
259
    const uint8_t threshold_default = 20;
260
    error = false;
261
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
262
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
263
        status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, &test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
264
        if(test_8 != threshold_default)
265
            error = true;
266
    }
267

    
268
    if (status == APAL_STATUS_SUCCESS && !error) {
269
        aosTestPassedMsg(stream, &result, "threshold 0x%04X = default\n", threshold_default);
270
    } else {
271
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
272
    }
273

    
274
    chprintf(stream, "demo of default configuration:\n");
275
    status = APAL_STATUS_OK;
276
    show_live(0, &status, stream, test);
277
    if (status == APAL_STATUS_SUCCESS) {
278
        aosTestPassed(stream, &result);
279
    } else {
280
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
281
    }
282

    
283
    status = APAL_STATUS_OK;
284
    chprintf(stream, "write configuration...\npuls + scale + threshold 8\n");
285
    at42qt1050_lld_pulsescalereg_t pulse_scale;
286
    //values stored as exponent of 2
287
    pulse_scale.pulse = 0; // accumulate #pulses -> increase resolution & time to acquire
288
    pulse_scale.scale = 0; // scale = average factor n: NewAvg = (NewData/n) + [OldAvg*(n-1/n)] -> decrease noise
289
    status  = at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_0, pulse_scale.raw , ((aos_test_at42qt1050data_t*)test->data)->timeout);
290
    pulse_scale.pulse = 1;
291
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_3, pulse_scale.raw , ((aos_test_at42qt1050data_t*)test->data)->timeout);
292

    
293
    pulse_scale.pulse = 4;
294
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, pulse_scale.raw , ((aos_test_at42qt1050data_t*)test->data)->timeout);
295
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_2, pulse_scale.raw , ((aos_test_at42qt1050data_t*)test->data)->timeout);
296

    
297
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_4, pulse_scale.raw , ((aos_test_at42qt1050data_t*)test->data)->timeout);
298

    
299
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
300
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
301
        status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, 8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
302
    }
303
    chprintf(stream, "disable guard key\n");
304
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, 0 , ((aos_test_at42qt1050data_t*)test->data)->timeout); //disable key
305
    status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_FINFOUTMAXCALGUARD, 8 , ((aos_test_at42qt1050data_t*)test->data)->timeout); //disable feature
306

    
307
    chprintf(stream, "calibrate...\n");
308
    status = at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_RESET_CALIBRATE, AT42QT1050_LLD_RESETCALIBRATE_CALIBRATE, ((aos_test_at42qt1050data_t*)test->data)->timeout);
309

    
310

    
311

    
312
    //wait for calibration to complete
313
    error = true;
314
    for(uint8_t i=0; i<0xFF; i++) {
315
        usleep(10);
316
        status |= at42qt1050_lld_read_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_DETECTIONSTATUS, &test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
317
        if(!(test_8 & AT42QT1050_LLD_DETECTIONSTATUS_CALIBRATE)) {
318
            error = false;
319
            break;
320
        }
321
    }
322
    if (status == APAL_STATUS_SUCCESS) {
323
        aosTestPassed(stream, &result);
324
    } else {
325
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
326
    }
327
    chprintf(stream, "demo of custom configuration:\n");
328
    status = APAL_STATUS_OK;
329
    show_live(1, &status, stream, test);
330
    if (status == APAL_STATUS_SUCCESS) {
331
        aosTestPassed(stream, &result);
332
    } else {
333
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
334
    }
335

    
336
    status = APAL_STATUS_OK;
337
    print_settings(&status, stream, test);
338
    if (status == APAL_STATUS_SUCCESS) {
339
        aosTestPassed(stream, &result);
340
    } else {
341
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
342
    }
343

    
344
    chprintf(stream, "shutdown touch\n");
345
    test_8 = 0; //Power down
346
    status = at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, AT42QT1050_LLD_REG_LOWPOWERMODE, test_8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
347
    if (status == APAL_STATUS_SUCCESS) {
348
        aosTestPassed(stream, &result);
349
    } else {
350
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
351
    }
352

    
353
    aosTestInfoMsg(stream,"driver object memory footprint: %u bytes\n", sizeof(AT42QT1050Driver));
354

    
355
    return result;
356
}
357

    
358
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */