diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/ft6x06.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/firmware/drivers/ft6x06.c b/firmware/drivers/ft6x06.c index 538ca10480..c605ee0944 100644 --- a/firmware/drivers/ft6x06.c +++ b/firmware/drivers/ft6x06.c | |||
@@ -24,6 +24,16 @@ | |||
24 | #include "i2c-async.h" | 24 | #include "i2c-async.h" |
25 | #include <string.h> | 25 | #include <string.h> |
26 | 26 | ||
27 | #define BYTES_PER_POINT 6 | ||
28 | |||
29 | #ifdef FT6x06_SWAP_AXES | ||
30 | # define POS_X pos_y | ||
31 | # define POS_Y pos_x | ||
32 | #else | ||
33 | # define POS_X pos_x | ||
34 | # define POS_Y pos_y | ||
35 | #endif | ||
36 | |||
27 | struct ft6x06_driver { | 37 | struct ft6x06_driver { |
28 | /* i2c bus data */ | 38 | /* i2c bus data */ |
29 | int i2c_cookie; | 39 | int i2c_cookie; |
@@ -33,39 +43,42 @@ struct ft6x06_driver { | |||
33 | ft6x06_event_cb event_cb; | 43 | ft6x06_event_cb event_cb; |
34 | 44 | ||
35 | /* buffer for I2C transfers */ | 45 | /* buffer for I2C transfers */ |
36 | uint8_t raw_data[6]; | 46 | uint8_t raw_data[1 + 2 + BYTES_PER_POINT * FT6x06_NUM_POINTS]; |
37 | }; | 47 | }; |
38 | 48 | ||
39 | static struct ft6x06_driver ft_drv; | 49 | static struct ft6x06_driver ft_drv; |
40 | struct ft6x06_state ft6x06_state; | 50 | struct ft6x06_state ft6x06_state; |
41 | 51 | ||
52 | static inline void ft6x06_convert_point(const uint8_t* raw, | ||
53 | struct ft6x06_point* pt) | ||
54 | { | ||
55 | pt->event = (raw[0] >> 6) & 0x3; | ||
56 | pt->touch_id = (raw[2] >> 4) & 0xf; | ||
57 | pt->POS_X = ((raw[0] & 0xf) << 8) | raw[1]; | ||
58 | pt->POS_Y = ((raw[2] & 0xf) << 8) | raw[3]; | ||
59 | pt->weight = raw[4]; | ||
60 | pt->area = (raw[5] >> 4) & 0xf; | ||
61 | } | ||
62 | |||
42 | static void ft6x06_i2c_callback(int status, i2c_descriptor* desc) | 63 | static void ft6x06_i2c_callback(int status, i2c_descriptor* desc) |
43 | { | 64 | { |
44 | (void)desc; | 65 | (void)desc; |
45 | if(status != I2C_STATUS_OK) | 66 | if(status != I2C_STATUS_OK) |
46 | return; | 67 | return; |
47 | 68 | ||
48 | int evt = ft_drv.raw_data[1] >> 6; | 69 | ft6x06_state.gesture = ft_drv.raw_data[1]; |
49 | int tx = ft_drv.raw_data[2] | ((ft_drv.raw_data[1] & 0xf) << 8); | 70 | ft6x06_state.nr_points = ft_drv.raw_data[2] & 0xf; |
50 | int ty = ft_drv.raw_data[4] | ((ft_drv.raw_data[3] & 0xf) << 8); | 71 | for(int i = 0; i < FT6x06_NUM_POINTS; ++i) { |
51 | 72 | ft6x06_convert_point(&ft_drv.raw_data[3 + i * BYTES_PER_POINT], | |
52 | ft6x06_state.event = evt; | 73 | &ft6x06_state.points[i]); |
53 | #ifdef FT6x06_SWAP_AXES | 74 | } |
54 | ft6x06_state.pos_x = ty; | ||
55 | ft6x06_state.pos_y = tx; | ||
56 | #else | ||
57 | ft6x06_state.pos_x = tx; | ||
58 | ft6x06_state.pos_y = ty; | ||
59 | #endif | ||
60 | 75 | ||
61 | ft_drv.event_cb(evt, ft6x06_state.pos_x, ft6x06_state.pos_y); | 76 | ft_drv.event_cb(&ft6x06_state); |
62 | } | 77 | } |
63 | 78 | ||
64 | static void ft6x06_dummy_event_cb(int evt, int tx, int ty) | 79 | static void ft6x06_dummy_event_cb(struct ft6x06_state* state) |
65 | { | 80 | { |
66 | (void)evt; | 81 | (void)state; |
67 | (void)tx; | ||
68 | (void)ty; | ||
69 | } | 82 | } |
70 | 83 | ||
71 | void ft6x06_init(void) | 84 | void ft6x06_init(void) |
@@ -74,9 +87,10 @@ void ft6x06_init(void) | |||
74 | memset(&ft_drv, 0, sizeof(ft_drv)); | 87 | memset(&ft_drv, 0, sizeof(ft_drv)); |
75 | ft_drv.event_cb = ft6x06_dummy_event_cb; | 88 | ft_drv.event_cb = ft6x06_dummy_event_cb; |
76 | 89 | ||
77 | ft6x06_state.event = FT6x06_EVT_NONE; | 90 | memset(&ft6x06_state, 0, sizeof(struct ft6x06_state)); |
78 | ft6x06_state.pos_x = 0; | 91 | ft6x06_state.gesture = -1; |
79 | ft6x06_state.pos_y = 0; | 92 | for(int i = 0; i < FT6x06_NUM_POINTS; ++i) |
93 | ft6x06_state.points[i].event = FT6x06_EVT_NONE; | ||
80 | 94 | ||
81 | /* Reserve bus management cookie */ | 95 | /* Reserve bus management cookie */ |
82 | ft_drv.i2c_cookie = i2c_async_reserve_cookies(FT6x06_BUS, 1); | 96 | ft_drv.i2c_cookie = i2c_async_reserve_cookies(FT6x06_BUS, 1); |
@@ -85,16 +99,16 @@ void ft6x06_init(void) | |||
85 | ft_drv.i2c_desc.slave_addr = FT6x06_ADDR; | 99 | ft_drv.i2c_desc.slave_addr = FT6x06_ADDR; |
86 | ft_drv.i2c_desc.bus_cond = I2C_START | I2C_STOP; | 100 | ft_drv.i2c_desc.bus_cond = I2C_START | I2C_STOP; |
87 | ft_drv.i2c_desc.tran_mode = I2C_READ; | 101 | ft_drv.i2c_desc.tran_mode = I2C_READ; |
88 | ft_drv.i2c_desc.buffer[0] = &ft_drv.raw_data[5]; | 102 | ft_drv.i2c_desc.buffer[0] = &ft_drv.raw_data[0]; |
89 | ft_drv.i2c_desc.count[0] = 1; | 103 | ft_drv.i2c_desc.count[0] = 1; |
90 | ft_drv.i2c_desc.buffer[1] = &ft_drv.raw_data[0]; | 104 | ft_drv.i2c_desc.buffer[1] = &ft_drv.raw_data[1]; |
91 | ft_drv.i2c_desc.count[1] = 5; | 105 | ft_drv.i2c_desc.count[1] = sizeof(ft_drv.raw_data) - 1; |
92 | ft_drv.i2c_desc.callback = ft6x06_i2c_callback; | 106 | ft_drv.i2c_desc.callback = ft6x06_i2c_callback; |
93 | ft_drv.i2c_desc.arg = 0; | 107 | ft_drv.i2c_desc.arg = 0; |
94 | ft_drv.i2c_desc.next = NULL; | 108 | ft_drv.i2c_desc.next = NULL; |
95 | 109 | ||
96 | /* Set I2C register address */ | 110 | /* Set I2C register address */ |
97 | ft_drv.raw_data[5] = 0x02; | 111 | ft_drv.raw_data[0] = 0x01; |
98 | } | 112 | } |
99 | 113 | ||
100 | void ft6x06_set_event_cb(ft6x06_event_cb cb) | 114 | void ft6x06_set_event_cb(ft6x06_event_cb cb) |