diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/tcc780x/cowond2/button-cowond2.c | 136 | ||||
-rw-r--r-- | firmware/target/arm/tcc780x/cowond2/button-target.h | 8 | ||||
-rw-r--r-- | firmware/target/arm/tcc780x/cowond2/power-cowond2.c | 10 |
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 | ||
25 | static enum touchpad_mode current_mode = TOUCHPAD_POINT; | 28 | static enum touchpad_mode current_mode = TOUCHPAD_POINT; |
29 | |||
30 | static short last_x, last_y; | ||
31 | static bool touch_available = false; | ||
32 | |||
33 | static 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 | |||
26 | void touchpad_set_mode(enum touchpad_mode mode) | 40 | void touchpad_set_mode(enum touchpad_mode mode) |
27 | { | 41 | { |
28 | current_mode = mode; | 42 | current_mode = mode; |
29 | } | 43 | } |
44 | |||
30 | enum touchpad_mode touchpad_get_mode(void) | 45 | enum touchpad_mode touchpad_get_mode(void) |
31 | { | 46 | { |
32 | return current_mode; | 47 | return current_mode; |
33 | } | 48 | } |
34 | 49 | ||
50 | void button_set_touch_available(void) | ||
51 | { | ||
52 | touch_available = true; | ||
53 | } | ||
54 | |||
55 | struct 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 | |||
62 | static struct touch_calibration_point topleft, bottomright; | ||
63 | |||
64 | static 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 | |||
35 | void button_init_device(void) | 90 | void 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 | ||
40 | bool button_hold(void) | 112 | bool 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 | ||
45 | int button_read_device(void) | 117 | int 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 | ||
28 | bool button_hold(void); | 28 | bool button_hold(void); |
29 | void button_init_device(void); | 29 | void button_init_device(void); |
30 | int button_read_device(void); | 30 | int button_read_device(int *data); |
31 | void 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 |