source: trunk/platform/ixus200_sd980/kbd.c @ 1212

Revision 1212, 10.3 KB checked in by reyalp, 2 years ago (diff)

beta ixus200_sd980 101c support from waterwingz in http://chdk.setepontos.com/index.php?topic=650.msg69319#msg69319

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