summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tcc780x
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tcc780x')
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-cowond2.c136
-rw-r--r--firmware/target/arm/tcc780x/cowond2/button-target.h8
-rw-r--r--firmware/target/arm/tcc780x/cowond2/power-cowond2.c10
3 files changed, 144 insertions, 10 deletions
diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
index ea37893f40..c0672f1c3a 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c
@@ -21,20 +21,92 @@
21#include "cpu.h" 21#include "cpu.h"
22#include "button.h" 22#include "button.h"
23#include "adc.h" 23#include "adc.h"
24#include "pcf50606.h"
25
26#define TOUCH_MARGIN 8
24 27
25static enum touchpad_mode current_mode = TOUCHPAD_POINT; 28static enum touchpad_mode current_mode = TOUCHPAD_POINT;
29
30static short last_x, last_y;
31static bool touch_available = false;
32
33static int touchpad_buttons[3][3] =
34{
35 {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT},
36 {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT},
37 {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT},
38};
39
26void touchpad_set_mode(enum touchpad_mode mode) 40void touchpad_set_mode(enum touchpad_mode mode)
27{ 41{
28 current_mode = mode; 42 current_mode = mode;
29} 43}
44
30enum touchpad_mode touchpad_get_mode(void) 45enum touchpad_mode touchpad_get_mode(void)
31{ 46{
32 return current_mode; 47 return current_mode;
33} 48}
34 49
50void button_set_touch_available(void)
51{
52 touch_available = true;
53}
54
55struct touch_calibration_point {
56 short px_x; /* known pixel value */
57 short px_y;
58 short val_x; /* touchpad value at the known pixel */
59 short val_y;
60};
61
62static struct touch_calibration_point topleft, bottomright;
63
64static int touch_to_pixels(short val_x, short val_y)
65{
66 short x,y;
67
68 x=val_x;
69 y=val_y;
70
71 x = (x-topleft.val_x)*(bottomright.px_x - topleft.px_x)
72 / (bottomright.val_x - topleft.val_x) + topleft.px_x;
73
74 y = (y-topleft.val_y)*(bottomright.px_y - topleft.px_y)
75 / (bottomright.val_y - topleft.val_y) + topleft.px_y;
76
77 if (x < 0)
78 x = 0;
79 else if (x>=LCD_WIDTH)
80 x=LCD_WIDTH-1;
81
82 if (y < 0)
83 y = 0;
84 else if (y>=LCD_HEIGHT)
85 y=LCD_HEIGHT-1;
86
87 return (x<<16)|y;
88}
89
35void button_init_device(void) 90void button_init_device(void)
36{ 91{
37 /* Nothing to do */ 92 /* Configure GPIOA 4 (POWER) and 8 (HOLD) for input */
93 GPIOA_DIR &= ~0x110;
94
95 /* Configure GPIOB 4 (button pressed) for input */
96 GPIOB_DIR &= ~0x10;
97
98 touch_available = false;
99
100 /* Arbitrary touchscreen calibration */
101 topleft.px_x = 0;
102 topleft.px_y = 0;
103 topleft.val_x = 50;
104 topleft.val_y = 50;
105
106 bottomright.px_x = LCD_WIDTH;
107 bottomright.px_y = LCD_HEIGHT;
108 bottomright.val_x = 980;
109 bottomright.val_y = 980;
38} 110}
39 111
40bool button_hold(void) 112bool button_hold(void)
@@ -42,10 +114,11 @@ bool button_hold(void)
42 return (GPIOA & 0x8) ? false : true; 114 return (GPIOA & 0x8) ? false : true;
43} 115}
44 116
45int button_read_device(void) 117int button_read_device(int *data)
46{ 118{
47 int btn = BUTTON_NONE; 119 int btn = BUTTON_NONE;
48 int adc; 120 int adc;
121 *data = 0;
49 122
50 if (GPIOB & 0x4) 123 if (GPIOB & 0x4)
51 { 124 {
@@ -69,8 +142,63 @@ int button_read_device(void)
69 } 142 }
70 } 143 }
71 144
72 /* TODO: Read 'fake' buttons based on touchscreen quadrants. 145 if (touch_available)
73 Question: How can I read from the PCF chip (I2C) in a tick task? */ 146 {
147 short x = 0, y = 0;
148 static long last_touch = 0;
149 bool send_touch = false;
150
151 int irq_level = disable_irq_save();
152 if (pcf50606_read(PCF5060X_ADCC1) & 0x80) /* Pen down */
153 {
154 unsigned char buf[3];
155 pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */
156 pcf50606_read_multiple(PCF5060X_ADCS1, buf, 3);
157 pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */
158
159 x = (buf[0] << 2) | (buf[1] & 3);
160 y = (buf[2] << 2) | ((buf[1] & 0xC) >> 2);
161
162 if (TIME_BEFORE(last_touch + HZ/5, current_tick))
163 {
164 if ((x > last_x + TOUCH_MARGIN) ||
165 (x < last_x - TOUCH_MARGIN) ||
166 (y > last_y + TOUCH_MARGIN) ||
167 (y < last_y - TOUCH_MARGIN))
168 {
169 send_touch = true;
170 }
171 }
172 else
173 {
174 send_touch = true;
175 }
176 }
177 restore_irq(irq_level);
178
179 if (send_touch)
180 {
181 last_x = x;
182 last_y = y;
183 *data = touch_to_pixels(x, y);
184 switch (current_mode)
185 {
186 case TOUCHPAD_POINT:
187 btn |= BUTTON_TOUCHPAD;
188 break;
189 case TOUCHPAD_BUTTON:
190 {
191 int px_x = (*data&0xffff0000)>>16;
192 int px_y = (*data&0x0000ffff);
193 btn |= touchpad_buttons[px_y/(LCD_HEIGHT/3)]
194 [px_x/(LCD_WIDTH/3)];
195 break;
196 }
197 }
198 }
199 last_touch = current_tick;
200 touch_available = false;
201 }
74 202
75 if (!(GPIOA & 0x4)) 203 if (!(GPIOA & 0x4))
76 btn |= BUTTON_POWER; 204 btn |= BUTTON_POWER;
diff --git a/firmware/target/arm/tcc780x/cowond2/button-target.h b/firmware/target/arm/tcc780x/cowond2/button-target.h
index 2890ef65a3..051ed39689 100644
--- a/firmware/target/arm/tcc780x/cowond2/button-target.h
+++ b/firmware/target/arm/tcc780x/cowond2/button-target.h
@@ -27,7 +27,8 @@
27 27
28bool button_hold(void); 28bool button_hold(void);
29void button_init_device(void); 29void button_init_device(void);
30int button_read_device(void); 30int button_read_device(int *data);
31void button_set_touch_available(void);
31 32
32/* Main unit's buttons */ 33/* Main unit's buttons */
33#define BUTTON_POWER 0x00000001 34#define BUTTON_POWER 0x00000001
@@ -42,7 +43,6 @@ int button_read_device(void);
42#define BUTTON_UP BUTTON_TOPMIDDLE 43#define BUTTON_UP BUTTON_TOPMIDDLE
43#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE 44#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE
44 45
45/* Faked buttons based on touchscreen quadrants (not yet read) */
46/* Touchpad Screen Area Buttons */ 46/* Touchpad Screen Area Buttons */
47#define BUTTON_TOPLEFT 0x00000010 47#define BUTTON_TOPLEFT 0x00000010
48#define BUTTON_TOPMIDDLE 0x00000020 48#define BUTTON_TOPMIDDLE 0x00000020
@@ -54,7 +54,9 @@ int button_read_device(void);
54#define BUTTON_BOTTOMMIDDLE 0x00000800 54#define BUTTON_BOTTOMMIDDLE 0x00000800
55#define BUTTON_BOTTOMRIGHT 0x00001000 55#define BUTTON_BOTTOMRIGHT 0x00001000
56 56
57#define BUTTON_MAIN 0x1FFF 57#define BUTTON_TOUCH 0x00002000
58
59#define BUTTON_MAIN 0x3FFF
58 60
59/* No remote */ 61/* No remote */
60#define BUTTON_REMOTE 0 62#define BUTTON_REMOTE 0
diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
index af5559dfb5..c7441256c5 100644
--- a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c
@@ -21,7 +21,7 @@
21#include "system.h" 21#include "system.h"
22#include "power.h" 22#include "power.h"
23#include "pcf50606.h" 23#include "pcf50606.h"
24#include "cpu.h" 24#include "button-target.h"
25 25
26#ifndef SIMULATOR 26#ifndef SIMULATOR
27 27
@@ -74,15 +74,19 @@ void EXT3(void)
74 74
75 if (data[0] & 0x04) 75 if (data[0] & 0x04)
76 { 76 {
77 /* ONKEY1S: don't reset the timeout, because we want a way to power off
78 the player in the event of a crashed plugin or UIE/panic, etc. */
79#if 0
77 /* ONKEY1S: reset timeout as we're using SW poweroff */ 80 /* ONKEY1S: reset timeout as we're using SW poweroff */
78 pcf50606_write(0x08, pcf50606_read(0x08) | 0x02); /* OOCC1: TOTRST=1 */ 81 pcf50606_write(0x08, pcf50606_read(0x08) | 0x02); /* OOCC1: TOTRST=1 */
82#endif
79 } 83 }
80 84
81 if (data[2] & 0x08) 85 if (data[2] & 0x08)
82 { 86 {
83 /* TODO: Touchscreen pen down event, do something about it */ 87 /* Touchscreen event, do something about it */
88 button_set_touch_available();
84 } 89 }
85
86 restore_fiq(fiq_status); 90 restore_fiq(fiq_status);
87} 91}
88#endif 92#endif