source: trunk/platform/ixus65_sd630/kbd.c @ 955

Revision 955, 7.7 KB checked in by fe50, 3 years ago (diff)
  • Fixes by ultimA from http://chdk.setepontos.com/index.php/topic,650.msg55640.html#msg55640
  • Make the A2000, G11 and ixus100_sd780 ports compatible with GCC 4.5. Apparently GCC 4.4 was too forgiving and still built the code, but GCC 4.5.1 errored out on them. This patch fixes the ASM so that these cams can be built successfully. The changes were not actually tested, but the fixes are trivial. As a result, all stable ports can be built using GCC 4.5.1 now. Credit also goes to whim who noticed these cams failing to build and he also suggested the first set of fixes.
  • Shut up some (not all) warnings from ixus100_sd780, ixus40_sd300, ixus65_sd630, s5is, ixus60_sd600
  • Make edge overlay respect OPT_EDGEOVERLAY. Previously, generated binary size did not get significantly smaller even when OPT_EDGEOVERLAY was undefined, because undefining it only resulted in the overlay being excluded from the menu, but still being built. Excluding edge overlay now saves appr. 3Kbytes.
  • Edge overlay erroneously depended on OPT_DEBUGGING. Builds failed when OPT_DEBUGGING was not defined previously.
  • Property svn:eol-style set to native
Line 
1#include "lolevel.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "stdlib.h"
6
7#define KEY_MASK 0x17FF
8
9#define NEW_SS (0x2000)
10#define SD_READONLY_FLAG (0x20000)
11
12typedef struct {
13    long hackkey;
14    long canonkey;
15} KeyMap;
16
17long kbd_new_state[3];
18long kbd_prev_state[3];
19long kbd_mod_state = KEY_MASK;
20long debug_kbd_state_diff;
21
22static KeyMap keymap[];
23static long last_kbd_key = 0;
24static int usb_power=0;
25static int remote_key=0;
26static int remote_count=0;
27
28#ifndef MALLOCD_STACK
29static char kbd_stack[NEW_SS];
30#endif
31
32long __attribute__((naked)) wrap_kbd_p1_f() ;
33
34static void __attribute__((noinline)) hook_kbd_task_proceed()
35{
36    while (physw_run){
37        _SleepTask(5);
38
39        if (wrap_kbd_p1_f() == 1) // Readout key state via camera function
40        {
41            _kbd_p2_f();
42        }
43
44    }
45}
46
47void __attribute__((naked,noinline)) mykbd_task()
48{
49    /* WARNING
50     * Stack pointer manipulation performed here!
51     * This means (but not limited to):
52     *  function arguments destroyed;
53     *  function CAN NOT return properly;
54     *  MUST NOT call or use stack variables before stack
55     *  is setup properly;
56     *
57     */
58
59    register int i;
60    register long *newstack;
61
62#ifndef MALLOCD_STACK
63    newstack = (void*)kbd_stack;
64#else
65    newstack = malloc(NEW_SS);
66#endif
67
68    for (i=0;i<NEW_SS/4;i++)
69        newstack[i]=0xdededede;
70
71    asm volatile (
72        "MOV    SP, %0"
73        :: "r"(((char*)newstack)+NEW_SS)
74        : "memory"
75    );
76
77    hook_kbd_task_proceed();
78
79    /* function can be modified to restore SP here...
80     */
81
82    _ExitTask();
83}
84
85
86long __attribute__((naked,noinline)) wrap_kbd_p1_f()
87{
88
89    asm volatile(
90                "STMFD   SP!, {R4-R7,LR}\n"
91                "SUB     SP, SP, #0xC\n"
92                "BL      _kbd_read_keys\n"
93                "BL      hook_kbd_handle_keys\n"
94                "B       _kbd_p1_f_cont\n"        // Continue original function execution
95    );
96    return 0; // shut up the compiler
97}
98
99#if CAM_FEATURE_FEATHER
100//extern int touch_keys_angle;
101#endif
102
103#define IN(base, value) ((value < base + 20) && (value > base - 20))
104
105/**
106 * Handles and forwards key settings to key processing routines
107 */
108void hook_kbd_handle_keys()
109{
110    kbd_prev_state[0] = kbd_new_state[0];
111    kbd_prev_state[1] = kbd_new_state[1];
112    kbd_prev_state[2] = kbd_new_state[2];
113
114    kbd_new_state[0] = physw_status[0];
115    kbd_new_state[1] = physw_status[1];
116    kbd_new_state[2] = physw_status[2];
117
118    static int taskFeatherID = 0;
119
120    if (taskFeatherID == 0) {
121        taskFeatherID = taskNameToId("tFeather");
122        printf("taskFeatherID:%x\n", taskFeatherID);
123    }
124
125
126
127/*
128    int key_emu = 0;
129    int canonkey = 0;
130    int i;
131
132    if (IN(250, touch_keys_angle)) {
133        key_emu = KEY_RIGHT;
134    }
135    if (IN(450, touch_keys_angle)) {
136        key_emu = KEY_DOWN;
137    }
138    if (IN(675, touch_keys_angle)) {
139        key_emu = KEY_LEFT;
140    }
141    if (IN(870, touch_keys_angle)) {
142        key_emu = KEY_UP;
143    }
144   
145    if (key_emu != 0) {
146        for (i=0; keymap[i].hackkey; i++){
147            if (keymap[i].hackkey == key_emu) {
148                canonkey = keymap[i].canonkey;
149                break;;
150            }
151        }
152    }
153
154    if (canonkey != 0) {
155        kbd_new_state[2] = kbd_new_state[2] & ~canonkey;
156    }
157*/
158   
159    if (kbd_process() == 0){
160        // leave it ...
161#if CAM_FEATURE_FEATHER
162        taskResume(taskFeatherID);
163#endif
164    } else {
165        // Drop platform keys to none, and simulate ordered key presses
166        physw_status[2] = (physw_status[2] & (~KEY_MASK)) | (kbd_mod_state & KEY_MASK);
167#if CAM_FEATURE_FEATHER
168        taskSuspend(taskFeatherID);
169
170        // We still need this sema when simulating key presses
171        if (kbd_mod_state != KEY_MASK) {
172            taskResume(taskFeatherID);
173        }
174
175#endif
176    }
177
178    // Drop SD readonly status
179    physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
180
181}
182
183/****************/
184
185
186void kbd_key_press(long key)
187{
188    int i;
189    for (i=0;keymap[i].hackkey;i++){
190        if (keymap[i].hackkey == key){
191            kbd_mod_state &= ~keymap[i].canonkey;
192            return;
193        }
194    }
195}
196
197void kbd_key_release(long key)
198{
199    int i;
200    for (i=0;keymap[i].hackkey;i++){
201        if (keymap[i].hackkey == key){
202            kbd_mod_state |= keymap[i].canonkey;
203            return;
204        }
205    }
206}
207
208void kbd_key_release_all()
209{
210    kbd_mod_state |= KEY_MASK;
211}
212
213long kbd_is_key_pressed(long key)
214{
215    int i;
216    for (i=0;keymap[i].hackkey;i++){
217        if (keymap[i].hackkey == key){
218            return ((kbd_new_state[2] & keymap[i].canonkey) == 0) ? 1:0;
219        }
220    }
221    return 0;
222}
223
224long kbd_is_key_clicked(long key)
225{
226    int i;
227   
228    for (i=0;keymap[i].hackkey;i++){
229        if (keymap[i].hackkey == key){
230            return ((kbd_prev_state[2] & keymap[i].canonkey) != 0) &&
231                    ((kbd_new_state[2] & keymap[i].canonkey) == 0);
232        }
233    }
234    return 0;
235}
236
237long kbd_get_pressed_key()
238{
239    int i;
240    for (i=0;keymap[i].hackkey;i++){
241        if ((kbd_new_state[2] & keymap[i].canonkey) == 0){
242            return keymap[i].hackkey;
243        }
244    }
245    return 0;
246}
247
248long kbd_get_clicked_key()
249{
250    int i;
251    for (i=0;keymap[i].hackkey;i++){
252        if (((kbd_prev_state[2] & keymap[i].canonkey) != 0) &&
253            ((kbd_new_state[2] & keymap[i].canonkey) == 0)){
254            return keymap[i].hackkey;
255        }
256    }
257    return 0;
258}
259
260void kbd_reset_autoclicked_key() {
261    last_kbd_key = 0;
262}
263
264long kbd_get_autoclicked_key() {
265    static long last_kbd_time = 0, press_count = 0;
266    register long key, t;
267
268    key=kbd_get_clicked_key();
269    if (key) {
270        last_kbd_key = key;
271        press_count = 0;
272        last_kbd_time = get_tick_count();
273        return key;
274    } else {
275        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
276            t = get_tick_count();
277            if (t-last_kbd_time > ( press_count ? KBD_REPEAT_DELAY : KBD_INITIAL_DELAY) ) {
278                ++press_count;
279                last_kbd_time = t;
280                return last_kbd_key;
281            } else {
282                return 0;
283            }
284        } else {
285            last_kbd_key = 0;
286            return 0;
287        }
288    }
289}
290
291long kbd_use_zoom_as_mf() {
292    static long v;
293    static long zoom_key_pressed = 0;
294
295    if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
296        get_property_case(12, &v, 4);
297        if (v) {
298            kbd_key_release_all();
299            kbd_key_press(KEY_RIGHT);
300            zoom_key_pressed = KEY_ZOOM_IN;
301            return 1;
302        }
303    } else {
304        if (zoom_key_pressed==KEY_ZOOM_IN) {
305            kbd_key_release(KEY_RIGHT);
306            zoom_key_pressed = 0;
307            return 1;
308        }
309    }
310    if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (mode_get()&MODE_MASK) == MODE_REC) {
311        get_property_case(12, &v, 4);
312        if (v) {
313            kbd_key_release_all();
314            kbd_key_press(KEY_LEFT);
315            zoom_key_pressed = KEY_ZOOM_OUT;
316            return 1;
317        }
318    } else {
319        if (zoom_key_pressed==KEY_ZOOM_OUT) {
320            kbd_key_release(KEY_LEFT);
321            zoom_key_pressed = 0;
322            return 1;
323        }
324    }
325    return 0;
326}
327
328int get_usb_power(int edge)
329{
330        int x;
331
332        if (edge) return remote_key;
333        x = usb_power;
334        usb_power = 0;
335        return x;
336}
337
338static KeyMap keymap[] = {
339    /* tiny bug: key order matters. see kbd_get_pressed_key()
340     * for example
341     */
342        { KEY_UP        , 0x00000001 },
343        { KEY_DOWN      , 0x00000002 },
344        { KEY_LEFT      , 0x00000008 },
345        { KEY_RIGHT     , 0x00000004 },
346        { KEY_SET       , 0x00000100 },
347        { KEY_SHOOT_FULL, 0x00000030 }, // note 3 here!
348        { KEY_SHOOT_HALF, 0x00000010 },
349        { KEY_ZOOM_IN   , 0x00000040 },
350        { KEY_ZOOM_OUT  , 0x00000080 },
351        { KEY_MENU      , 0x00000200 },
352        { KEY_DISPLAY   , 0x00000400 },
353        { KEY_PRINT     , 0x00001000 },
354//      { KEY_ERASE     , 0x00000800 },
355        { KEY_DUMMY     , 0x00001000 },
356        { 0, 0 }
357};
Note: See TracBrowser for help on using the repository browser.