Statistics
| Branch: | Tag: | Revision:

amiro-os / test / periphery-lld / AT42QT1050_v1 / aos_test_AT42QT1050.c @ 96621a83

History | View | Annotate | Download (18.787 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2020  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;
195
    int32_t status;
196
    uint8_t test_8;
197
    bool error;
198

    
199
    aosTestResultInit(&result);
200

    
201
    chprintf(stream, "read register...\n");
202
    error = false;
203
    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);
204
    chprintf(stream, "\t\tchip ID: 0x%02X\n", test_8);
205
    if (test_8 != AT42QT1050_LLD_CHIPID)
206
        error = true;
207
    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);
208
    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);
209
    if (status == APAL_STATUS_SUCCESS && !error) {
210
        aosTestPassed(stream, &result);
211
    } else {
212
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
213
    }
214

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

    
232
    chprintf(stream, "guarding...\nincrease charge_delay0\ndisable multitouch\n");
233

    
234
    //channel 0 is to big to be charged in the default cycle
235
    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);
236

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

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

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

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

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

    
285
    status = APAL_STATUS_OK;
286
    chprintf(stream, "write configuration...\npuls + scale + threshold 8\n");
287
    at42qt1050_lld_pulsescalereg_t pulse_scale;
288
    //values stored as exponent of 2
289
    pulse_scale.pulse = 0; // accumulate #pulses -> increase resolution & time to acquire
290
    pulse_scale.scale = 0; // scale = average factor n: NewAvg = (NewData/n) + [OldAvg*(n-1/n)] -> decrease noise
291
    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);
292
    pulse_scale.pulse = 1;
293
    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);
294

    
295
    pulse_scale.pulse = 4;
296
    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);
297
    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);
298

    
299
    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);
300

    
301
    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
302
        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
303
        status |= at42qt1050_lld_write_reg(((aos_test_at42qt1050data_t*)test->data)->at42qt1050d, txbuf, 8, ((aos_test_at42qt1050data_t*)test->data)->timeout);
304
    }
305
    chprintf(stream, "disable guard key\n");
306
    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
307
    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
308

    
309
    chprintf(stream, "calibrate...\n");
310
    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);
311

    
312

    
313

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

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

    
346
    chprintf(stream, "shutdown touch\n");
347
    test_8 = 0; //Power down
348
    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);
349
    if (status == APAL_STATUS_SUCCESS) {
350
        aosTestPassed(stream, &result);
351
    } else {
352
        aosTestFailedMsg(stream, &result, "0x%08X\n", status);
353
    }
354

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

    
357
    return result;
358
}
359

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