v1.1.0
[hackover2013-badge-firmware.git] / drivers / displays / tft / touchscreen.c
1 /**************************************************************************/
2 /*!
3 @file touchscreen.c
4 @author K. Townsend (microBuilder.eu)
5
6 Parts copyright (c) 2001, Carlos E. Vidales. All rights reserved.
7
8 @section LICENSE
9
10 Software License Agreement (BSD License)
11
12 Copyright (c) 2010, microBuilder SARL
13 All rights reserved.
14
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions are met:
17 1. Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22 3. Neither the name of the copyright holders nor the
23 names of its contributors may be used to endorse or promote products
24 derived from this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
27 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37 /**************************************************************************/
38 #include "touchscreen.h"
39
40 #include "core/adc/adc.h"
41 #include "core/gpio/gpio.h"
42 #include "core/systick/systick.h"
43 #include "drivers/storage/eeprom/eeprom.h"
44 #include "drivers/displays/tft/lcd.h"
45 #include "drivers/displays/tft/drawing.h"
46 #include "drivers/displays/tft/controls/labelcentered.h"
47
48 #define TS_LINE1 "Touch the center of"
49 #define TS_LINE2 "the red circle using"
50 #define TS_LINE3 "a pen or stylus"
51
52 static bool _tsInitialised = FALSE;
53 static uint8_t _tsThreshhold = CFG_TFTLCD_TS_DEFAULTTHRESHOLD;
54 tsPoint_t _tsLCDPoints[3];
55 tsPoint_t _tsTSPoints[3];
56 tsMatrix_t _tsMatrix;
57
58 /**************************************************************************/
59 /* */
60 /* ----------------------- Private Methods ------------------------------ */
61 /* */
62 /**************************************************************************/
63
64 /**************************************************************************/
65 /*!
66 @brief Reads the current Z/pressure level using the ADC
67 */
68 /**************************************************************************/
69 void tsReadZ(uint32_t* z1, uint32_t* z2)
70 {
71 if (!_tsInitialised) tsInit();
72
73 // XP = ADC
74 // XM = GPIO Output Low
75 // YP = GPIO Output High
76 // YM = GPIO Input
77
78 TS_XM_FUNC_GPIO;
79 TS_YP_FUNC_GPIO;
80 TS_YM_FUNC_GPIO;
81
82 gpioSetDir (TS_XM_PORT, TS_XM_PIN, 1);
83 gpioSetDir (TS_YP_PORT, TS_YP_PIN, 1);
84 gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0);
85
86 gpioSetValue(TS_XM_PORT, TS_XM_PIN, 0); // GND
87 gpioSetValue(TS_YP_PORT, TS_YP_PIN, 1); // 3.3V
88
89 TS_XP_FUNC_ADC;
90 *z1 = adcRead(TS_XP_ADC_CHANNEL);
91
92 // XP = GPIO Input
93 // XM = GPIO Output Low
94 // YP = GPIO Output High
95 // YM = ADC
96
97 TS_XP_FUNC_GPIO;
98 gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0);
99
100 TS_YM_FUNC_ADC;
101 *z2 = adcRead(TS_YM_ADC_CHANNEL);
102 }
103
104 /**************************************************************************/
105 /*!
106 @brief Reads the current X position using the ADC
107 */
108 /**************************************************************************/
109 uint32_t tsReadX(void)
110 {
111 if (!_tsInitialised) tsInit();
112
113 // XP = GPIO Output High
114 // XM = GPIO Output Low
115 // YP = ADC
116 // YM = GPIO Input
117
118 TS_XP_FUNC_GPIO;
119 TS_XM_FUNC_GPIO;
120 TS_YM_FUNC_GPIO;
121
122 gpioSetDir (TS_XP_PORT, TS_XP_PIN, 1);
123 gpioSetDir (TS_XM_PORT, TS_XM_PIN, 1);
124 gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0);
125
126 gpioSetValue(TS_XP_PORT, TS_XP_PIN, 1); // 3.3V
127 gpioSetValue(TS_XM_PORT, TS_XM_PIN, 0); // GND
128
129 TS_YP_FUNC_ADC;
130
131 // Return the ADC results
132 return adcRead(TS_YP_ADC_CHANNEL);
133 }
134
135 /**************************************************************************/
136 /*!
137 @brief Reads the current Y position using the ADC
138 */
139 /**************************************************************************/
140 uint32_t tsReadY(void)
141 {
142 if (!_tsInitialised) tsInit();
143
144 // YP = GPIO Output High
145 // YM = GPIO Output Low
146 // XP = GPIO Input
147 // XM = ADC
148
149 TS_YP_FUNC_GPIO;
150 TS_YM_FUNC_GPIO;
151 TS_XP_FUNC_GPIO;
152
153 gpioSetDir (TS_YP_PORT, TS_YP_PIN, 1);
154 gpioSetDir (TS_YM_PORT, TS_YM_PIN, 1);
155 gpioSetDir (TS_XP_PORT, TS_XP_PIN, 0);
156
157 gpioSetValue(TS_YP_PORT, TS_YP_PIN, 1); // 3.3V
158 gpioSetValue(TS_YM_PORT, TS_YM_PIN, 0); // GND
159
160 TS_XM_FUNC_ADC;
161
162 // Return the ADC results
163 return adcRead(TS_XM_ADC_CHANNEL);
164 }
165
166 /**************************************************************************/
167 /*!
168 @brief Centers a line of text horizontally
169 */
170 /**************************************************************************/
171 void tsCalibCenterText(char* text, uint16_t y, uint16_t color)
172 {
173 labelcenteredRender(lcdGetWidth()/2, y, COLOR_WHITE, color, text, themeGetDefault());
174 }
175
176 /**************************************************************************/
177 /*!
178 @brief Renders the calibration screen with an appropriately
179 placed test point and waits for a touch event
180 */
181 /**************************************************************************/
182 tsTouchData_t tsRenderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius)
183 {
184 drawFill(COLOR_WHITE);
185 tsCalibCenterText(TS_LINE1, 50, COLOR_GRAY_50);
186 tsCalibCenterText(TS_LINE2, 65, COLOR_GRAY_50);
187 tsCalibCenterText(TS_LINE3, 80, COLOR_GRAY_50);
188 drawCircle(x, y, radius, COLOR_RED);
189 drawCircle(x, y, radius + 2, COLOR_GRAY_128);
190
191 // Wait for a valid touch events
192 tsTouchData_t data;
193 tsTouchError_t error;
194 bool valid = false;
195 while (!valid)
196 {
197 // Set calibration flag for ts read
198 error = tsRead(&data, true);
199 if (!error && data.valid)
200 {
201 valid = true;
202 }
203 }
204
205 return data;
206 }
207
208 /**************************************************************************/
209 /*!
210 @brief Calculates the difference between the touch screen and the
211 actual screen co-ordinates, taking into account misalignment
212 and any physical offset of the touch screen.
213
214 @note This is based on the public domain touch screen calibration code
215 written by Carlos E. Vidales (copyright (c) 2001).
216
217 For more information, see the following app notes:
218
219 - AN2173 - Touch Screen Control and Calibration
220 Svyatoslav Paliy, Cypress Microsystems
221 - Calibration in touch-screen systems
222 Wendy Fang and Tony Chang,
223 Analog Applications Journal, 3Q 2007 (Texas Instruments)
224 */
225 /**************************************************************************/
226 int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr)
227 {
228 int retValue = 0;
229
230 matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
231 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
232
233 if( matrixPtr->Divider == 0 )
234 {
235 retValue = -1 ;
236 }
237 else
238 {
239 matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
240 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
241
242 matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
243 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
244
245 matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
246 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
247 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
248
249 matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
250 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
251
252 matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
253 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
254
255 matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
256 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
257 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
258
259 // Persist data to EEPROM
260 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN, matrixPtr->An);
261 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN, matrixPtr->Bn);
262 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN, matrixPtr->Cn);
263 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN, matrixPtr->Dn);
264 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN, matrixPtr->En);
265 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn);
266 eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER, matrixPtr->Divider);
267 eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1);
268 }
269
270 return( retValue ) ;
271 }
272
273 /**************************************************************************/
274 /*!
275 @brief Converts the supplied touch screen location (screenPtr) to
276 a pixel location on the display (displayPtr) using the
277 supplied matrix. The screen orientation is also taken into
278 account when converting the touch screen co-ordinate to
279 a pixel location on the LCD.
280
281 @note This is based on the public domain touch screen calibration code
282 written by Carlos E. Vidales (copyright (c) 2001).
283 */
284 /**************************************************************************/
285 int getDisplayPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr )
286 {
287 int retValue = TS_ERROR_NONE ;
288
289 if( matrixPtr->Divider != 0 )
290 {
291 displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
292 (matrixPtr->Bn * screenPtr->y) +
293 matrixPtr->Cn
294 ) / matrixPtr->Divider ;
295
296 displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
297 (matrixPtr->En * screenPtr->y) +
298 matrixPtr->Fn
299 ) / matrixPtr->Divider ;
300 }
301 else
302 {
303 // return TS_ERROR_NOTCALIBRATED;
304 return -1;
305 }
306
307 // Adjust value if the screen is in landscape mode
308 lcdOrientation_t orientation;
309 orientation = lcdGetOrientation();
310 if (orientation == LCD_ORIENTATION_LANDSCAPE)
311 {
312 uint32_t oldx, oldy;
313 oldx = displayPtr->x;
314 oldy = displayPtr->y;
315 displayPtr->x = oldy;
316 displayPtr->y = lcdGetHeight() - oldx;
317 }
318
319 return( retValue ) ;
320 }
321
322 /**************************************************************************/
323 /* */
324 /* ----------------------- Public Methods ------------------------------- */
325 /* */
326 /**************************************************************************/
327
328 /**************************************************************************/
329 /*!
330 @brief Initialises the appropriate GPIO pins and ADC for the
331 touchscreen
332 */
333 /**************************************************************************/
334 void tsInit(void)
335 {
336 // Make sure that ADC is initialised
337 adcInit();
338
339 // Set initialisation flag
340 _tsInitialised = TRUE;
341 _tsThreshhold = tsGetThreshhold();
342
343 // Load values from EEPROM if touch screen has already been calibrated
344 if (eepromReadU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED) == 1)
345 {
346 // Load calibration data
347 _tsMatrix.An = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN);
348 _tsMatrix.Bn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN);
349 _tsMatrix.Cn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN);
350 _tsMatrix.Dn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN);
351 _tsMatrix.En = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN);
352 _tsMatrix.Fn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN);
353 _tsMatrix.Divider = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER);
354 }
355 else
356 {
357 // You may want to run the touch screen calibration sequence
358 // here since the ts has apparently never been calibrated!
359 // tsCalibrate();
360 }
361 }
362
363 /**************************************************************************/
364 /*!
365 @brief Reads the current X, Y and Z co-ordinates of the touch screen
366
367 @param[in] calibrating
368 Set to 1 if the read attempt is for calibration data.
369 No attempt will be made to correlate the touch screen
370 and LCD co-ordinates.
371 */
372 /**************************************************************************/
373 tsTouchError_t tsRead(tsTouchData_t* data, uint8_t calibrating)
374 {
375 uint32_t x1, x2, y1, y2, z1, z2;
376
377 // Assign pressure levels regardless of touch state
378 tsReadZ(&z1, &z2);
379 data->z1 = z1;
380 data->z2 = z2;
381 data->xraw = 0;
382 data->yraw = 0;
383 data->xlcd = 0;
384 data->ylcd = 0;
385
386 // Abort if the screen is not being touched (0 levels reported)
387 if (z1 < _tsThreshhold)
388 {
389 data->valid = false;
390 return TS_ERROR_NONE;
391 }
392
393 // Get two X/Y readings and compare results
394 x1 = tsReadX();
395 x2 = tsReadX();
396 y1 = tsReadY();
397 y2 = tsReadY();
398
399 // Throw an error if both readings aren't identical
400 if (x1 != x2 || y1 != y2)
401 {
402 data->valid = false;
403 data->xraw = x1;
404 data->yraw = y1;
405 return TS_ERROR_XYMISMATCH;
406 }
407
408 // X/Y seems to be valid and reading has been confirmed twice
409 data->xraw = x1;
410 data->yraw = y1;
411
412 // Convert x/y values to pixel location with matrix multiply
413 tsPoint_t location, touch;
414 touch.x = x1;
415 touch.y = y1;
416 // Only calculate the relative LCD value if this isn't for calibration
417 if (!calibrating)
418 {
419 getDisplayPoint( &location, &touch, &_tsMatrix) ;
420 data->xlcd = location.x;
421 data->ylcd = location.y;
422 }
423 else
424 {
425 // Assign some false values, but only xraw and yraw are
426 // used for calibration
427 data->xlcd = 0;
428 data->ylcd = 0;
429 }
430 data->valid = true;
431
432 return TS_ERROR_NONE;
433 }
434
435 /**************************************************************************/
436 /*!
437 @brief Starts the screen calibration process. Each corner will be
438 tested, meaning that each boundary (top, left, right and
439 bottom) will be tested twice and the readings averaged.
440 */
441 /**************************************************************************/
442 void tsCalibrate(void)
443 {
444 tsTouchData_t data;
445
446 /* --------------- Welcome Screen --------------- */
447 data = tsRenderCalibrationScreen(lcdGetWidth() / 2, lcdGetHeight() / 2, 5);
448 systickDelay(250);
449
450 /* ----------------- First Dot ------------------ */
451 // 10% over and 10% down
452 data = tsRenderCalibrationScreen(lcdGetWidth() / 10, lcdGetHeight() / 10, 5);
453 _tsLCDPoints[0].x = lcdGetWidth() / 10;
454 _tsLCDPoints[0].y = lcdGetHeight() / 10;
455 _tsTSPoints[0].x = data.xraw;
456 _tsTSPoints[0].y = data.yraw;
457 printf("Point 1 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n",
458 (int)_tsLCDPoints[0].x, (int)_tsLCDPoints[0].y, (int)_tsTSPoints[0].x, (int)_tsTSPoints[0].y);
459 systickDelay(250);
460
461 /* ---------------- Second Dot ------------------ */
462 // 50% over and 90% down
463 data = tsRenderCalibrationScreen(lcdGetWidth() / 2, lcdGetHeight() - lcdGetHeight() / 10, 5);
464 _tsLCDPoints[1].x = lcdGetWidth() / 2;
465 _tsLCDPoints[1].y = lcdGetHeight() - lcdGetHeight() / 10;
466 _tsTSPoints[1].x = data.xraw;
467 _tsTSPoints[1].y = data.yraw;
468 printf("Point 2 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n",
469 (int)_tsLCDPoints[1].x, (int)_tsLCDPoints[1].y, (int)_tsTSPoints[1].x, (int)_tsTSPoints[1].y);
470 systickDelay(250);
471
472 /* ---------------- Third Dot ------------------- */
473 // 90% over and 50% down
474 data = tsRenderCalibrationScreen(lcdGetWidth() - lcdGetWidth() / 10, lcdGetHeight() / 2, 5);
475 _tsLCDPoints[2].x = lcdGetWidth() - lcdGetWidth() / 10;
476 _tsLCDPoints[2].y = lcdGetHeight() / 2;
477 _tsTSPoints[2].x = data.xraw;
478 _tsTSPoints[2].y = data.yraw;
479 printf("Point 3 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n",
480 (int)_tsLCDPoints[2].x, (int)_tsLCDPoints[2].y, (int)_tsTSPoints[2].x, (int)_tsTSPoints[2].y);
481 systickDelay(250);
482
483 // Do matrix calculations for calibration and store to EEPROM
484 setCalibrationMatrix(&_tsLCDPoints[0], &_tsTSPoints[0], &_tsMatrix);
485 }
486
487 /**************************************************************************/
488 /*!
489 @brief Causes a blocking delay until a valid touch event occurs
490
491 @note Thanks to 'rossum' and limor for this nifty little tidbit on
492 debouncing the signals via pressure sensitivity (using Z)
493
494 @section Example
495
496 @code
497 #include "drivers/displays/tft/touchscreen.h"
498 ...
499 tsTouchData_t data;
500 tsTouchError_t error;
501
502 while (1)
503 {
504 // Cause a blocking delay until a touch event occurs or 5s passes
505 error = tsWaitForEvent(&data, 5000);
506
507 if (error)
508 {
509 switch(error)
510 {
511 case TS_ERROR_TIMEOUT:
512 printf("Timeout occurred %s", CFG_PRINTF_NEWLINE);
513 break;
514 default:
515 break;
516 }
517 }
518 else
519 {
520 // A valid touch event occurred ... display data
521 printf("Touch Event: X = %04u, Y = %04u %s",
522 data.xlcd,
523 data.ylcd,
524 CFG_PRINTF_NEWLINE);
525 }
526 }
527
528 @endcode
529 */
530 /**************************************************************************/
531 tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS)
532 {
533 if (!_tsInitialised) tsInit();
534
535 tsRead(data, false);
536
537 // Return the results right away if reading is valid
538 if (data->valid)
539 {
540 return TS_ERROR_NONE;
541 }
542
543 // Handle timeout if delay > 0 milliseconds
544 if (timeoutMS)
545 {
546 uint32_t startTick = systickGetTicks();
547 // Systick rollover may occur while waiting for timeout
548 if (startTick > 0xFFFFFFFF - timeoutMS)
549 {
550 while (data->valid == false)
551 {
552 // Throw alert if timeout delay has been passed
553 if ((systickGetTicks() < startTick) && (systickGetTicks() >= (timeoutMS - (0xFFFFFFFF - startTick))))
554 {
555 return TS_ERROR_TIMEOUT;
556 }
557 tsRead(data, false);
558 }
559 }
560 // No systick rollover will occur ... calculate timeout the simple way
561 else
562 {
563 // Wait in infinite loop
564 while (data->valid == false)
565 {
566 // Throw timeout if delay has been passed
567 if ((systickGetTicks() - startTick) > timeoutMS)
568 {
569 return TS_ERROR_TIMEOUT;
570 }
571 tsRead(data, false);
572 }
573 }
574 }
575 // No timeout requested ... wait forever
576 else
577 {
578 while (data->valid == false)
579 {
580 tsRead(data, false);
581 }
582 }
583
584 // Indicate correct reading
585 return TS_ERROR_NONE;
586 }
587
588 /**************************************************************************/
589 /*!
590 @brief Updates the touch screen threshhold level and saves it
591 to EEPROM
592 */
593 /**************************************************************************/
594 int tsSetThreshhold(uint8_t value)
595 {
596 if ((value < 0) || (value > 254))
597 {
598 return -1;
599 }
600
601 // Update threshhold value
602 _tsThreshhold = value;
603
604 // Persist to EEPROM
605 eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_THRESHHOLD, value);
606
607 return 0;
608 }
609
610 /**************************************************************************/
611 /*!
612 @brief Gets the current touch screen threshhold level from EEPROM
613 (if present) or returns the default value from projectconfig.h
614 */
615 /**************************************************************************/
616 uint8_t tsGetThreshhold(void)
617 {
618 // Check if custom threshold has been set in eeprom
619 uint8_t thold = eepromReadU8(CFG_EEPROM_TOUCHSCREEN_THRESHHOLD);
620 if (thold != 0xFF)
621 {
622 // Use value from EEPROM
623 _tsThreshhold = thold;
624 }
625 else
626 {
627 // Use the default value from projectconfig.h
628 _tsThreshhold = CFG_TFTLCD_TS_DEFAULTTHRESHOLD;
629 }
630
631 return _tsThreshhold;
632 }
This page took 0.100953 seconds and 5 git commands to generate.