aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ginput/touch/STMPE811/ginput_lld_mouse.c
blob: bdae310ee82c38a6db9bf4dc04e7cc4d3c1f65c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
    ChibiOS/GFX - Copyright (C) 2012, 2013
                 Joel Bodenmann aka Tectu <joel@unormal.org>

    This file is part of ChibiOS/GFX.

    ChibiOS/GFX is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ChibiOS/GFX is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

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

/**
 * @file    drivers/ginput/touch/STMPE811/ginput_lld_mouse.c
 * @brief   GINPUT Touch low level driver source for the STMPE811.
 *
 * @defgroup Mouse Mouse
 * @ingroup GINPUT
 * @{
 */

#include "ch.h"
#include "hal.h"
#include "gfx.h"

#include "stmpe811.h"

#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/

#include "ginput/lld/mouse.h"

	#include "ginput_lld_mouse_board_embest_dmstf4bb.h"

static coord_t lastx, lasty, lastz;

/* set the active window of the stmpe811. bl is bottom left, tr is top right */
static void setActiveWindow(uint16_t bl_x, uint16_t bl_y, uint16_t tr_x, uint16_t tr_y) {
	write_reg(STMPE811_REG_WDW_TR_X, 2, tr_x);
	write_reg(STMPE811_REG_WDW_TR_Y, 2, tr_y);
	write_reg(STMPE811_REG_WDW_BL_X, 2, bl_x);
	write_reg(STMPE811_REG_WDW_BL_Y, 2, bl_y);
}

/**
 * @brief   Initialise the mouse/touch.
 *
 * @notapi
 */
void ginput_lld_mouse_init(void) {
	init_board();

	write_reg(STMPE811_REG_SYS_CTRL1,		1, 0x02);	// Software chip reset
	write_reg(STMPE811_REG_SYS_CTRL2,		1, 0x0C);	// Temp. sensor clock off, GPIO clock off, touch clock on, ADC clock on
	write_reg(STMPE811_REG_INT_EN,			1, 0x03);	// Interrupt on INT pin when FIFO is equal or above threshold value OR touch is detected
	write_reg(STMPE811_REG_ADC_CTRL1,		1, 0x48);	// ADC conversion time = 80 clock ticks, 12-bit ADC, internaal voltage refernce

	chThdSleepMilliseconds(2);

	write_reg(STMPE811_REG_ADC_CTRL2,		1, 0x01);	// ADC speed 3.25MHz
	write_reg(STMPE811_REG_GPIO_AF,			1, 0x00);	// GPIO alternate function - OFF
	// @TODO: decide which value should STMPE811_REG_TSC_CFG have - either 0x9A or from comment;)
	write_reg(STMPE811_REG_TSC_CFG,			1, 0x9A);	// Averaging 4, Touch detect delay 1ms, Panel driver settling time 1ms
	write_reg(STMPE811_REG_FIFO_TH,			1, 0x01);	// FIFO threshold =1
	write_reg(STMPE811_REG_FIFO_STA,		1, 0x01);	// FIFO reset enable
	write_reg(STMPE811_REG_FIFO_STA,		1, 0x00);	// FIFO reset disable
	write_reg(STMPE811_REG_TSC_FRACT_XYZ,	1, 0x07);	// Z axis data format
	write_reg(STMPE811_REG_TSC_I_DRIVE,		1, 0x01);	// 50mA touchscreen line current
	write_reg(STMPE811_REG_TSC_CTRL,		1, 0x03);	// X&Y only, TSC enable
	write_reg(STMPE811_REG_INT_STA,			1, 0xFF);	// Clear all interrupts
	write_reg(STMPE811_REG_INT_CTRL,		1, 0x01);	// Level interrupt, enable intrrupts
}

/**
 * @brief   Read the mouse/touch position.
 *
 * @param[in] pt	A pointer to the structure to fill
 *
 * @note			For drivers that don't support returning a position
 *					when the touch is up (most touch devices), it should
 *					return the previous position with the new Z value.
 *					The z value is the pressure for those touch devices
 *					that support it (-100 to 100 where > 0 is touched)
 *					or, 0 or 100 for those drivers that don't.
 *
 * @notapi
 */
void ginput_lld_mouse_get_reading(MouseReading *pt) {
	uint16_t buf;

	// if not touched, return the previous results
	if(!getpin_pressed()) {
		pt->x = lastx;
		pt->y = lasty;
		pt->z = 0;
		pt->buttons = 0;
		return;
	}

	/* Get the X value */
	buf = read_reg(STMPE811_REG_TSC_DATA_X, 2);
	lastx = (coord_t)(buf);

	/* Get the Y value */
	buf = read_reg(STMPE811_REG_TSC_DATA_Y, 2);
	lasty = (coord_t)(buf);

	/* Get the Z value */
	buf = read_reg(STMPE811_REG_TSC_DATA_Z, 1);
	lastz = (buf & 0x00FF);

	// Return the results
	pt->x = lastx;
	pt->y = lasty;
	pt->z = 100;
	pt->buttons = GINPUT_TOUCH_PRESSED;
}

#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
/** @} */