source: branches/fe50t/platform/ixus90_sd790/kbd.c @ 232

Revision 232, 11.7 KB checked in by fe50, 3 years ago (diff)
Line 
1#include "lolevel.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6
7typedef struct {
8        short grp;
9        short hackkey;
10        long canonkey;
11} KeyMap;
12
13static long kbd_new_state[3];
14static long kbd_prev_state[3];
15static long kbd_mod_state[3];
16static KeyMap keymap[];
17static long last_kbd_key = 0;
18//static long alt_mode_key_mask = 0x00000800;
19static int usb_power=0;
20static int remote_key, remote_count;
21static int shoot_counter=0;
22#define DELAY_TIMEOUT 10000
23
24#define KEYS_MASK0 (0x00000000)
25#define KEYS_MASK1 (0x00000000)
26#define KEYS_MASK2 (0x0FFF)
27
28#define NEW_SS (0x2000)
29#define SD_READONLY_FLAG (0x20000)
30
31#define FEATURE_FEATHER 0
32#define USB_MASK (0x40000)
33#define USB_REG 2
34
35#ifndef MALLOCD_STACK
36static char kbd_stack[NEW_SS];
37#endif
38
39void kbd_fetch_data(long*);
40
41long __attribute__((naked)) wrap_kbd_p1_f() ;
42
43void wait_until_remote_button_is_released(void)
44{
45        int count1;
46        int count2;
47        int tick,tick2,tick3;
48        int nSW;
49        int prev_usb_power,cur_usb_power;
50
51        static int nMode;
52
53        asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
54
55        debug_led(1);
56        tick = get_tick_count();
57        tick2 = tick;
58        static long usb_physw[3];
59        if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable && (!shooting_get_drive_mode()|| (shooting_get_drive_mode()==1) || ((shooting_get_drive_mode()==2) && state_shooting_progress != SHOOTING_PROGRESS_PROCESSING))) {
60                nMode=0;
61                usb_physw[2] = 0; // makes sure USB bit is cleared.
62                _kbd_read_keys_r2(usb_physw);
63                if((usb_physw[2] & USB_MASK)==USB_MASK) {
64                        nMode=1;
65                }
66
67                if(conf.ricoh_ca1_mode && conf.remote_enable) {
68                        if(shooting_get_drive_mode() ==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING) { //continuous-shooting mode
69                                if(conf.bracket_type>2) {
70                                        if(shoot_counter<2) shutter_int=3;
71                                        shoot_counter--;
72                                } else {
73                                        prev_usb_power=0;
74                                        nSW = 0;
75                                        do {     
76                                                usb_physw[2] = 0; // makes sure USB bit is cleared.
77                                                _kbd_read_keys_r2(usb_physw);
78                                                cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
79                                                if(cur_usb_power) {
80                                                        if(!prev_usb_power) {
81                                                                tick2 = get_tick_count();
82                                                                prev_usb_power=cur_usb_power;
83                                                        } else {
84                                                                if((int)get_tick_count()-tick2>1000) {
85                                                                        debug_led(0);
86                                                                }
87                                                        }
88                                                }
89                                                else {
90                                                        if(prev_usb_power) {
91                                                                tick3 = (int)get_tick_count()-tick2;
92                                                                if(nSW==10) {
93                                                                        if(tick3>50) shutter_int=1;
94                                                                        nSW=20;
95                                                                }
96                                                                if(nSW==0 && tick3>0) {
97                                                                        if(tick3<50) {
98                                                                                nSW=10;
99                                                                        } else {
100                                                                                if(tick3>1000) {
101                                                                                        shutter_int=1;
102                                                                                }
103                                                                                nSW=20;
104                                                                        }
105                                                                }
106                                                                prev_usb_power=cur_usb_power;
107                                                        }
108                                                }
109                                                if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {
110                                                        nSW=20;shutter_int=2;
111                                                }
112                                        } while(nSW<20);
113                                }
114                        } else { //nomal mode
115                                shoot_counter=0;
116                                if(conf.bracket_type>2) {
117                                        shoot_counter=(conf.bracket_type-2)*2;
118                                }
119                                do {
120                                        usb_physw[2] = 0; // makes sure USB bit is cleared.
121                                        _kbd_read_keys_r2(usb_physw);
122                                } while(((((usb_physw[2] & USB_MASK)!=USB_MASK) && (nMode==0)) || (((usb_physw[2] & USB_MASK)==USB_MASK) && (nMode==1))) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
123                        }
124                } else {
125                        do {
126                                usb_physw[2] = 0; // makes sure USB bit is cleared.
127                                _kbd_read_keys_r2(usb_physw);
128                        } while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
129                }
130        }
131
132        if (conf.synch_delay_enable && conf.synch_delay_value>0) { // if delay is switched on and greater than 0
133                for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) { // wait delay_value * 0.1ms
134                        for (count2=0;count2<1400;count2++) { // delay approx. 0.1ms
135                        }
136                }
137        }
138
139        debug_led(0);
140        asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
141}
142
143static void __attribute__((noinline)) mykbd_task_proceed()
144{
145    while (physw_run){
146                _SleepTask(10);
147
148                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
149                _kbd_p2_f();
150                }
151    }
152}
153
154void __attribute__((naked,noinline))
155mykbd_task(long ua, long ub, long uc, long ud, long ue, long uf)
156{
157    /* WARNING
158     * Stack pointer manipulation performed here!
159     * This means (but not limited to):
160     *  function arguments destroyed;
161     *  function CAN NOT return properly;
162     *  MUST NOT call or use stack variables before stack
163     *  is setup properly;
164     *
165     */
166
167    register int i;
168    register long *newstack;
169
170#ifndef MALLOCD_STACK
171    newstack = (void*)kbd_stack;
172#else
173    newstack = malloc(NEW_SS);
174#endif
175
176    for (i=0;i<NEW_SS/4;i++)
177        newstack[i]=0xdededede;
178
179    asm volatile (
180        "MOV    SP, %0\n"
181        :: "r"(((char*)newstack)+NEW_SS)
182        : "memory"
183    );
184
185    mykbd_task_proceed();
186
187    /* function can be modified to restore SP here...
188     */
189
190    _ExitTask();
191}
192
193
194long __attribute__((naked,noinline)) wrap_kbd_p1_f()
195{
196
197    asm volatile(
198                "STMFD   SP!, {R1-R5,LR}\n"
199                "MOV     R4, #0\n"
200                "BL      my_kbd_read_keys\n"
201                                //"BL      _kbd_read_keys\n"
202                "B       _kbd_p1_f_cont\n"
203    );
204    return 0; // shut up the compiler
205}
206
207#if FEATURE_FEATHER
208extern int touch_keys_angle;
209extern int * touch_keys_sema;
210int touch_keys_sema_stored;
211#endif
212
213//extern void touch_wheel_print_on();
214//extern void touch_wheel_print_off();
215
216volatile int jogdial_stopped=0;
217
218void my_kbd_read_keys()
219{
220    kbd_prev_state[0] = kbd_new_state[0];
221    kbd_prev_state[1] = kbd_new_state[1];
222    kbd_prev_state[2] = kbd_new_state[2];
223
224    _kbd_pwr_on();
225
226    kbd_fetch_data(kbd_new_state);
227
228    if (kbd_process() == 0){
229                // leave it alone...
230                physw_status[0] = kbd_new_state[0];
231                physw_status[1] = kbd_new_state[1];
232                physw_status[2] = kbd_new_state[2];
233//              physw_status[2] = kbd_new_state[2] | alt_mode_key_mask;
234                jogdial_stopped=0;
235
236#if FEATURE_FEATHER
237        if (*touch_keys_sema == 0) {
238            *touch_keys_sema = touch_keys_sema_stored;
239        }
240#endif
241    } else {
242                // override keys
243                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) |
244                                  (kbd_mod_state[0] & KEYS_MASK0);
245
246                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) |
247                                  (kbd_mod_state[1] & KEYS_MASK1);
248
249                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) |
250                                  (kbd_mod_state[2] & KEYS_MASK2);
251
252                if ((jogdial_stopped==0) && !state_kbd_script_run) {
253                        jogdial_stopped=1; get_jogdial_direction();
254                } else if (jogdial_stopped && state_kbd_script_run) {
255                        jogdial_stopped=0;
256                }
257
258#if FEATURE_FEATHER
259        if (*touch_keys_sema != 0) {
260            touch_keys_sema_stored = *touch_keys_sema;
261            *touch_keys_sema = 0;
262        }
263        // We still need this sema when simulating key presses
264        if (/*kbd_mod_state[0] != KEYS_MASK0 || kbd_mod_state[1] != KEYS_MASK1 || */kbd_mod_state[2] != KEYS_MASK2) {
265            *touch_keys_sema = touch_keys_sema_stored;
266        }
267#endif
268    }
269
270    _kbd_read_keys_r2(physw_status);
271
272    if (conf.remote_enable) {
273      remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
274      if (remote_key)  remote_count += 1;
275      else if (remote_count) {
276         usb_power = remote_count;
277         remote_count = 0;
278      }
279      physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
280     }
281    else physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
282
283    _kbd_pwr_off();
284}
285
286
287int get_usb_power(int edge)
288{
289        int x;
290
291        if (edge) return remote_key;
292        x = usb_power;
293        usb_power = 0;
294        return x;
295        return 0;
296}
297
298/****************/
299
300
301void kbd_key_press(long key)
302{
303    int i;
304    for (i=0;keymap[i].hackkey;i++){
305        if (keymap[i].hackkey == key){
306            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
307            return;
308        }
309    }
310}
311
312void kbd_key_release(long key)
313{
314    int i;
315    for (i=0;keymap[i].hackkey;i++){
316        if (keymap[i].hackkey == key){
317            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
318            return;
319        }
320    }
321}
322
323void kbd_key_release_all()
324{
325  kbd_mod_state[0] |= KEYS_MASK0;
326  kbd_mod_state[1] |= KEYS_MASK1;
327  kbd_mod_state[2] |= KEYS_MASK2;
328}
329
330long kbd_is_key_pressed(long key)
331{
332    int i;
333    for (i=0;keymap[i].hackkey;i++){
334        if (keymap[i].hackkey == key){
335            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
336        }
337    }
338    return 0;
339}
340
341long kbd_is_key_clicked(long key)
342{
343    int i;
344    for (i=0;keymap[i].hackkey;i++){
345        if (keymap[i].hackkey == key){
346            return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
347                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
348        }
349    }
350    return 0;
351}
352
353long kbd_get_pressed_key()
354{
355    int i;
356    for (i=0;keymap[i].hackkey;i++){
357        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
358            return keymap[i].hackkey;
359        }
360    }
361    return 0;
362}
363
364long kbd_get_clicked_key()
365{
366    int i;
367    for (i=0;keymap[i].hackkey;i++){
368        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
369            ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
370            return keymap[i].hackkey;
371        }
372    }
373    return 0;
374}
375
376void kbd_reset_autoclicked_key() {
377    last_kbd_key = 0;
378}
379
380long kbd_get_autoclicked_key() {
381    static long last_kbd_time = 0, press_count = 0;
382    register long key, t;
383
384    key=kbd_get_clicked_key();
385    if (key) {
386        last_kbd_key = key;
387        press_count = 0;
388        last_kbd_time = get_tick_count();
389        return key;
390    } else {
391        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
392            t = get_tick_count();
393            if (t-last_kbd_time>((press_count)?175:500)) {
394                ++press_count;
395                last_kbd_time = t;
396                return last_kbd_key;
397            } else {
398                return 0;
399            }
400        } else {
401            last_kbd_key = 0;
402            return 0;
403        }
404    }
405       
406       
407}
408
409long kbd_use_zoom_as_mf() {
410    static long v;
411    static long zoom_key_pressed = 0;
412
413    if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
414        get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
415        if (v) {
416            kbd_key_release_all();
417            kbd_key_press(KEY_RIGHT);
418            zoom_key_pressed = KEY_ZOOM_IN;
419            return 1;
420        }
421    } else {
422        if (zoom_key_pressed==KEY_ZOOM_IN) {
423            kbd_key_release(KEY_RIGHT);
424            zoom_key_pressed = 0;
425            return 1;
426        }
427    }
428    if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (mode_get()&MODE_MASK) == MODE_REC) {
429        get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
430        if (v) {
431            kbd_key_release_all();
432            kbd_key_press(KEY_LEFT);
433            zoom_key_pressed = KEY_ZOOM_OUT;
434            return 1;
435        }
436    } else {
437        if (zoom_key_pressed==KEY_ZOOM_OUT) {
438            kbd_key_release(KEY_LEFT);
439            zoom_key_pressed = 0;
440            return 1;
441        }
442    }
443    return 0;
444}
445
446
447static KeyMap keymap[] = {
448    /* tiny bug: key order matters. see kbd_get_pressed_key()
449     * for example
450     */
451        { 2, KEY_UP             , 0x00000080 },
452        { 2, KEY_DOWN           , 0x00000040 },
453        { 2, KEY_LEFT           , 0x00000010 },
454        { 2, KEY_RIGHT          , 0x00000020 },
455        { 2, KEY_SET            , 0x00000100 },
456        { 2, KEY_SHOOT_FULL     , 0x00000003 },
457        { 2, KEY_SHOOT_HALF     , 0x00000001 },
458        { 2, KEY_ZOOM_IN        , 0x00000004 },
459        { 2, KEY_ZOOM_OUT       , 0x00000008 },
460        { 2, KEY_MENU           , 0x00000400 },
461        { 2, KEY_DISPLAY        , 0x00000200 },
462        { 2, KEY_PRINT          , 0x00000800 },
463        { 0, 0, 0 }
464};
465
466static int new_jogdial=0, old_jogdial=0;
467
468int Get_JogDial(void)
469{
470        // ??? \todo 0xC0240000+0x104 @ FF842A44  // address from sub above aJogdail (sub_FF84B8D8)
471        return (*(int*)0xC0240104)>>16;
472}
473
474long get_jogdial_direction(void)
475{
476        old_jogdial=new_jogdial;
477        new_jogdial=Get_JogDial();
478
479        if (old_jogdial<new_jogdial) {
480                return JOGDIAL_LEFT;
481        } else if (old_jogdial>new_jogdial) {
482                return JOGDIAL_RIGHT;
483        } else {
484                return 0;
485        }
486}
487
488void kbd_fetch_data(long *dst)
489{
490    volatile long *mmio0 = (void*)0xc0220200;
491    volatile long *mmio1 = (void*)0xc0220204;
492    volatile long *mmio2 = (void*)0xc0220208;
493
494    dst[0] = *mmio0;
495    dst[1] = *mmio1;
496    dst[2] = *mmio2 & 0xffff;
497}
Note: See TracBrowser for help on using the repository browser.