source: trunk/platform/ixus970_sd890/kbd.c @ 790

Revision 790, 10.6 KB checked in by reyalp, 4 years ago (diff)

ixus970 updates from snc http://chdk.setepontos.com/index.php/topic,3246.120.html

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