root/trunk/platform/sx230hs/kbd.c @ 1344

Revision 1344, 14.3 KB (checked in by philmoz, 20 months ago)

Implement the full shutter press without releasing half-press logic:
 http://chdk.setepontos.com/index.php?topic=1444.0

  • 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 "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;
18static int usb_power=0;
19static int remote_key, remote_count;
20static int shoot_counter=0;
21static long alt_mode_key_mask = 0x00010800; // disp + set
22static int alt_mode_led=0;
23extern void _GetKbdState(long*);
24
25#define DELAY_TIMEOUT 10000
26
27// override key and feather bits to avoid feather osd messing up chdk display in ALT mode
28#define KEYS_MASK0 (0x000FFC0F)     // physw_status[0] was 7FC05
29#define KEYS_MASK1 (0x00200000)
30#define KEYS_MASK2 (0x00002182) 
31
32#define NEW_SS (0x2000)
33#define SD_READONLY_FLAG (0x20000)
34#define USB_MASK (0x4000000)
35#define USB_FLAG            0x04000000 // Found @0xff3bcf44, levent 0x902
36#define USB_REG 2
37#define SD_READONLY_IDX     2
38#define USB_IDX             2
39
40#ifndef MALLOCD_STACK
41static char kbd_stack[NEW_SS];
42#endif
43
44static KeyMap keymap[] = {
45
46        { 0, KEY_ZOOM_OUT       , 0x00000001 },
47        { 0, KEY_ZOOM_OUT1      , 0x00000001 },
48        { 0, KEY_ZOOM_OUT       , 0x00000002 },
49        { 0, KEY_ZOOM_OUT3              , 0x00000002 },
50        { 0, KEY_ZOOM_OUT       , 0x00000003 },
51        { 0, KEY_ZOOM_OUT2              , 0x00000003 },
52        { 0, KEY_ZOOM_IN                , 0x00000004 },
53        { 0, KEY_ZOOM_IN1       , 0x00000004 },
54        { 0, KEY_ZOOM_IN                , 0x00000008 },
55        { 0, KEY_ZOOM_IN3               , 0x00000008 },
56        { 0, KEY_ZOOM_IN                , 0x0000000C },
57        { 0, KEY_ZOOM_IN2               , 0x0000000C },
58        { 0, KEY_UP_SOFT        , 0x00000400 },   
59        { 0, KEY_DISPLAY        , 0x00000800 },
60        { 0, KEY_UP                     , 0x00001000 },         //1400
61        { 0, KEY_RIGHT_SOFT         , 0x00002000 },
62        { 0, KEY_RIGHT              , 0x00004000 },             //6000
63        { 0, KEY_DOWN_SOFT          , 0x00008000 },
64        { 0, KEY_SET                , 0x00010000 },
65        { 0, KEY_PRINT              , 0x00010800 },     //DISP+SET for ALT menu
66        { 0, KEY_DOWN               , 0x00020000 },     //28000
67        { 0, KEY_MENU               , 0x00040000 },     
68        { 0, KEY_VIDEO                  , 0x00080000 },         //200000        //TODO TESTING
69        { 1, KEY_PLAYBACK           , 0x00200000 },
70        { 2, KEY_LEFT_SOFT              , 0x00000080 },
71        { 2, KEY_LEFT                   , 0x00000100 },
72        { 2, KEY_SHOOT_FULL             , 0x00002002 },
73        { 2, KEY_SHOOT_FULL_ONLY, 0x00000002 },
74        { 2, KEY_SHOOT_HALF             , 0x00002000 },
75        { 0, 0, 0 }
76};
77
78void kbd_set_alt_mode_key_mask(long key)
79{
80        int i;
81        for (i=0; keymap[i].hackkey; ++i) {
82                if (keymap[i].hackkey == key) {
83                        alt_mode_key_mask = keymap[i].canonkey;
84                        return;
85                }
86        }
87}
88void my_blinkk(void) {
89        int i;
90        while(1) {
91                *((volatile int *) 0xC0220130) = 0x46; // Turn on LED
92                for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
93
94                *((volatile int *) 0xC0220130) = 0x44; // Turn off LED
95                for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
96
97                *((volatile int *) 0xC0220130) = 0x46; // Turn on LED
98                for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
99
100                *((volatile int *) 0xC0220130) = 0x44; // Turn off LED
101                for (i=0; i<0x900000; i++) { asm volatile ( "nop\n" ); }
102        }
103}
104
105volatile int jogdial_stopped=0;
106
107extern long __attribute__((naked)) wrap_kbd_p1_f();
108
109
110static void __attribute__((noinline)) mykbd_task_proceed() {
111       
112        while (physw_run) {
113        _SleepTask(*((int*)(0x1c44 +0x8))); //  @FF0248AC
114
115                if (wrap_kbd_p1_f() == 1) {   // autorepeat ?
116                _kbd_p2_f();
117        }
118    }
119}
120
121// no stack manipulation needed here, since we create the task directly
122void __attribute__((naked,noinline)) mykbd_task() {
123        mykbd_task_proceed();
124
125// function can be modified to restore SP here...
126        _ExitTask();
127}
128
129// copied from g12 and sx30, thx to philmoz
130// Pointer to stack location where jogdial task records previous and current
131// jogdial positions
132
133extern short* jog_position;
134
135void jogdial_control(int n)
136{
137    if (jogdial_stopped && !n)
138    {
139        // If re-enabling jogdial set the task code current & previous positions to the actual
140        // dial positions so that the change won't get processed by the firmware
141        jog_position[0] = jog_position[2] = (*(short*)0xC0240106);  // Rear dial
142    }
143    jogdial_stopped = n;
144}
145
146// like SX110
147void my_kbd_read_keys() {
148               
149
150    kbd_prev_state[0] = kbd_new_state[0];
151    kbd_prev_state[1] = kbd_new_state[1];
152    kbd_prev_state[2] = kbd_new_state[2];
153
154        _GetKbdState( kbd_new_state );
155        _kbd_read_keys_r2( kbd_new_state);
156       
157//    kbd_new_state[0] = physw_status[0];  //sx220 changed from physw_status[0]
158 //   kbd_new_state[2] = physw_status[2];
159 //   kbd_new_state[3] = physw_status[3]; //sx220 added
160       
161
162       
163    if (kbd_process() == 0) {
164        // we read keyboard state with _kbd_read_keys()
165                physw_status[0] = kbd_new_state[0];
166                physw_status[1] = kbd_new_state[1];
167                physw_status[2] = kbd_new_state[2];             
168                 jogdial_control(0);
169
170    } else {
171        // override keys
172        physw_status[0] = (kbd_new_state[0] | KEYS_MASK0) & (~KEYS_MASK0 | kbd_mod_state[0]);
173        physw_status[1] = (kbd_new_state[1] | KEYS_MASK1) & (~KEYS_MASK1 | kbd_mod_state[1]);
174        physw_status[2] = (kbd_new_state[2] | KEYS_MASK2) & (~KEYS_MASK2 | kbd_mod_state[2]);
175
176        if ((jogdial_stopped==0) && !state_kbd_script_run) {
177            jogdial_control(1);
178            get_jogdial_direction();
179        }
180        else if (jogdial_stopped && state_kbd_script_run)
181                 jogdial_control(0);
182    }
183       
184    remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
185    if (remote_key)
186        remote_count += 1;
187    else if (remote_count) {
188        usb_power = remote_count;
189        remote_count = 0;
190    }
191       
192    if (conf.remote_enable) {
193        physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);   // override USB and SD-Card Readonly Bits
194    }                                                                                                                                             //SX220 DONE.
195   
196    physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;   // override SD-Card Readonly Bit
197}
198
199int get_usb_power(int edge) {
200
201  int x;
202
203    if (edge) return remote_key;
204    x = usb_power;
205    usb_power = 0;
206    return x;
207}
208
209void kbd_key_press(long key) {
210   
211        int i;
212    for (i=0;keymap[i].hackkey;i++){
213        if (keymap[i].hackkey == key){
214            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
215            return;
216        }
217    }
218}
219
220void kbd_key_release(long key) {
221 
222   int i;
223    for (i=0;keymap[i].hackkey;i++) {
224        if (keymap[i].hackkey == key){
225            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
226            return;
227        }
228    }
229}
230
231void kbd_key_release_all() {
232   
233        kbd_mod_state[0] |= KEYS_MASK0;
234    kbd_mod_state[1] |= KEYS_MASK1;
235    kbd_mod_state[2] |= KEYS_MASK2;
236}
237
238long kbd_is_key_pressed(long key) {
239 
240        int i;
241    for (i=0;keymap[i].hackkey;i++) {
242        if (keymap[i].hackkey == key) {
243            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
244        }
245    }
246    return 0;
247}
248
249long kbd_is_key_clicked(long key) {
250   
251        int i;
252    for (i=0;keymap[i].hackkey;i++) {
253        if (keymap[i].hackkey == key){
254            return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
255                ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
256        }
257    }
258    return 0;
259}
260
261long kbd_get_pressed_key() {
262   
263        int i;
264    for (i=0;keymap[i].hackkey;i++) {
265        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) {
266            return keymap[i].hackkey;
267        }
268    }
269    return 0;
270}
271
272long kbd_get_clicked_key() {
273
274   int i;
275    for (i=0;keymap[i].hackkey;i++) {
276        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) && ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
277            return keymap[i].hackkey;
278        }
279    }
280    return 0;
281}
282
283void kbd_reset_autoclicked_key() {
284
285        last_kbd_key = 0;
286}
287
288long kbd_get_autoclicked_key() {
289   
290        static long last_kbd_time = 0, press_count = 0;
291    register long key, t;
292
293    key=kbd_get_clicked_key();
294    if (key) {
295        last_kbd_key = key;
296        press_count = 0;
297        last_kbd_time = get_tick_count();
298        return key;
299    } else {
300        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
301            t = get_tick_count();
302            if (t-last_kbd_time>((press_count)?175:500)) {
303                ++press_count;
304                last_kbd_time = t;
305                return last_kbd_key;
306            } else {
307                return 0;
308            }
309        } else {
310            last_kbd_key = 0;
311            return 0;
312        }
313    }
314}
315
316#ifdef CAM_USE_ZOOM_FOR_MF
317    long kbd_use_zoom_as_mf() {
318
319        static long v;
320        static long zoom_key_pressed = 0;
321
322        if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
323            get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
324            if (v) {
325                kbd_key_release_all();
326                kbd_key_press(KEY_RIGHT);
327                zoom_key_pressed = KEY_ZOOM_IN;
328                return 1;
329            }
330        } else {
331            if (zoom_key_pressed==KEY_ZOOM_IN) {
332                kbd_key_release(KEY_RIGHT);
333                zoom_key_pressed = 0;
334                return 1;
335            }
336        }
337        if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (mode_get()&MODE_MASK) == MODE_REC) {
338            get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
339            if (v) {
340                kbd_key_release_all();
341                kbd_key_press(KEY_LEFT);
342                zoom_key_pressed = KEY_ZOOM_OUT;
343                return 1;
344            }
345        } else {
346            if (zoom_key_pressed==KEY_ZOOM_OUT) {
347                kbd_key_release(KEY_LEFT);
348                zoom_key_pressed = 0;
349                return 1;
350            }
351        }
352        return 0;
353    }
354#endif
355
356///
357int Get_JogDial(void) {
358        return (*(int*)0xC0240104)>>16;     // 0xC0240000 + 0x104
359}
360
361static int new_jogdial=0, old_jogdial=0;
362
363long get_jogdial_direction(void) {
364        old_jogdial=new_jogdial;
365    new_jogdial=Get_JogDial();
366
367    if (old_jogdial<new_jogdial) {
368        return JOGDIAL_RIGHT;
369    } else if (old_jogdial>new_jogdial) {
370        return JOGDIAL_LEFT;
371    } else {
372        return 0;
373    }
374}
375
376// called from capt_seq.c at sub_FF9686A8_my()
377void wait_until_remote_button_is_released(void) {
378   
379        int count1;
380    int count2;
381    int tick,tick2,tick3;
382    int nSW;
383    int prev_usb_power,cur_usb_power;
384    static int nMode;
385
386    asm volatile ("STMFD SP!, {R0-R11,LR}\n");   // store R0-R11 and LR in stack
387
388    debug_led(1);
389    tick = get_tick_count();
390    tick2 = tick;
391    static long usb_physw[3];
392    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)))
393    //if (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
394    {
395        // ------ add by Masuji SUTO (start) --------------
396        nMode = 0;
397        usb_physw[2] = 0;   // makes sure USB bit is cleared.
398        _kbd_read_keys_r2(usb_physw);
399        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
400        // ------ add by Masuji SUTO (end)   --------------
401        if(conf.ricoh_ca1_mode && conf.remote_enable) {
402            if(shooting_get_drive_mode() == 1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING) {   //continuous-shooting mode
403                if(conf.bracket_type>2) {
404                    if(shoot_counter<2) shutter_int=3;
405                    shoot_counter--;
406                } else {
407                    prev_usb_power=0;
408                    nSW = 0;
409                    do {
410                        usb_physw[2] = 0;   // makes sure USB bit is cleared.
411                        _kbd_read_keys_r2(usb_physw);
412                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
413                        if(cur_usb_power) {
414                            if(!prev_usb_power) {
415                                tick2 = get_tick_count();
416                                prev_usb_power=cur_usb_power;
417                            } else {
418                                if((int)get_tick_count()-tick2>1000) {debug_led(0);}
419                            }
420                        } else {
421                            if(prev_usb_power) {
422                                tick3 = (int)get_tick_count()-tick2;
423                                if(nSW==10) {
424                                    if(tick3>50) shutter_int=1;
425                                        nSW=20;
426                                }
427                                if(nSW==0 && tick3>0) {
428                                    if(tick3<50) {
429                                    nSW=10;
430                                    } else {
431                                        if(tick3>1000) shutter_int=1;
432                                            nSW=20;
433                                    }
434                                }
435                                prev_usb_power=cur_usb_power;
436                            }
437                        }
438                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) { nSW=20;shutter_int=2; }
439                    }
440                    while(nSW<20);
441                }
442            }   // continuous-shooting mode
443            else {   //nomal mode
444                shoot_counter=0;
445                if(conf.bracket_type>2) {
446                    shoot_counter=(conf.bracket_type-2)*2;
447                }
448                do {
449                    usb_physw[2] = 0;    // makes sure USB bit is cleared.
450                    _kbd_read_keys_r2(usb_physw);
451                }
452                //while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
453                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));
454            }
455        } else {
456            do {
457                usb_physw[2] = 0;   // makes sure USB bit is cleared.
458               _kbd_read_keys_r2(usb_physw);
459            }
460           while ((usb_physw[2]&USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
461        }
462    }
463
464    if (conf.synch_delay_enable && conf.synch_delay_value>0) {   // if delay is switched on and greater than 0
465        for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) {   // wait delay_value * 0.1ms
466            for (count2=0;count2<1400;count2++) {   // delay approx. 0.1ms
467            }
468        }
469    }
470
471    debug_led(0);
472    asm volatile ("LDMFD SP!, {R0-R11,LR}\n");   // restore R0-R11 and LR from stack
473}
474
475
Note: See TracBrowser for help on using the browser.