source: trunk/platform/g10/kbd.c @ 1344

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

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 "conf.h"
5#include "keyboard.h"
6
7typedef struct {
8        short grp;
9        short hackkey;
10        long canonkey;
11} KeyMap;
12
13
14//static long kbd_new_state[3];
15long kbd_new_state[3];
16
17static long kbd_prev_state[3];
18static long kbd_mod_state[3];
19
20static long last_kbd_key = 0;
21static long alt_mode_key_mask = 0x00000400;     // G10
22
23static int usb_power=0;
24static int remote_key, remote_count;
25static int shoot_counter=0;
26extern void _GetKbdState(long*);
27
28#define DELAY_TIMEOUT 10000
29
30#define LED_ISO  (void*) 0xC02200D0 // G10 ISO select dial LED
31#define LED_DP   (void*) 0xC02200D4     // G10 direct print button LED
32#define LED_ECL  (void*) 0xC02200D8 // G10 exposure compensation dial LED
33#define LED_PWR  (void*) 0xC02200DC     // G10 power LED
34
35#define SD_READONLY_FLAG        0x00020000              // Found @0xffb0f940, levent 0x90a
36#define SD_READONLY_IDX     2         
37#define USB_FLAG            0x00040000  // Found @0xffb0f94c, levent 0x902
38#define USB_IDX             2   
39
40#define KEYS_MASK0 (0x00000003)
41#define KEYS_MASK1 (0x000FFE18)
42#define KEYS_MASK2 (0x00000000)
43
44static KeyMap keymap[] = {
45    { 0, KEY_SHOOT_FULL  ,0x00000003 }, // Found @0xffb0f7c0, levent 0x01
46    { 0, KEY_SHOOT_FULL_ONLY, 0x00000002 },      // http://chdk.setepontos.com/index.php?topic=1444.msg70223#msg70223
47    { 0, KEY_SHOOT_HALF  ,0x00000001 }, // Found @0xffb0f7b4, levent 0x00
48       
49    { 1, KEY_ZOOM_OUT    ,0x00000008 }, // Found @0xffb0f82c, levent 0x03
50    { 1, KEY_ZOOM_IN     ,0x00000010 }, // Found @0xffb0f838, levent 0x02
51        { 1, KEY_PRINT          , 0x00000200 }, //
52    { 1, KEY_LEFT        ,0x00000400 }, // Found @0xffb0f880, levent 0x06
53    { 1, KEY_SET         ,0x00000800 }, // Found @0xffb0f88c, levent 0x08
54    { 1, KEY_RIGHT       ,0x00001000 }, // Found @0xffb0f898, levent 0x07
55    { 1, KEY_DOWN        ,0x00002000 }, // Found @0xffb0f8a4, levent 0x05
56    { 1, KEY_UP          ,0x00004000 }, // Found @0xffb0f8b0, levent 0x04
57        { 1, KEY_METERING       , 0x00008000 }, //
58        { 1, KEY_ERASE          , 0x00010000 }, //
59    { 1, KEY_DISPLAY     ,0x00020000 }, // Found @0xffb0f8d4, levent 0x0a
60    { 1, KEY_MENU        ,0x00040000 }, // Found @0xffb0f8e0, levent 0x09
61        { 1, KEY_AE_LOCK        , 0x00080000 }, //
62
63/*     
64        { 0, KEY_PWR_PLAYBACK   , 0x80000000 }, // inverted
65        { 0, KEY_PWR_SHOOT              , 0x40000000 }, // inverted
66        { 0, KEY_BATTERY_DOOR   , 0x00008000 }, // inverted
67*/     
68    { 0, 0, 0 }
69};
70
71long __attribute__((naked)) wrap_kbd_p1_f() ;
72
73void wait_until_remote_button_is_released(void)
74{
75
76
77int count1;
78int count2;
79int tick,tick2,tick3;
80int nSW;
81int prev_usb_power,cur_usb_power;
82 // ------ add by Masuji SUTO (start) --------------
83    static int nMode;
84 // ------ add by Masuji SUTO (end)   --------------
85
86asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
87debug_led(1);
88tick = get_tick_count();
89tick2 = tick;
90static long usb_physw[3];
91if (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
92  {
93// ------ add by Masuji SUTO (start) --------------
94        nMode=0;
95        usb_physw[USB_IDX] = 0;                                             // makes sure USB bit is cleared.
96        _kbd_read_keys_r2(usb_physw);
97        if((usb_physw[USB_IDX] & USB_FLAG)==USB_FLAG) nMode=1;
98// ------ add by Masuji SUTO (end)   --------------
99     if(conf.ricoh_ca1_mode && conf.remote_enable)
100     {
101        if(shooting_get_drive_mode()==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                    //continuous-shooting mode
102                if(conf.bracket_type>2){
103                        if(shoot_counter<2) shutter_int=3;
104                        shoot_counter--;
105                        }
106                else{
107                        prev_usb_power=0;
108                        nSW = 0;
109                        do
110                                {
111                                usb_physw[USB_IDX] = 0;                                             // makes sure USB bit is cleared.
112                                _kbd_read_keys_r2(usb_physw);
113                                cur_usb_power = (usb_physw[USB_IDX] & USB_FLAG)==USB_FLAG;
114                                if(cur_usb_power){
115                                        if(!prev_usb_power){
116                                                tick2 = get_tick_count();
117                                                prev_usb_power=cur_usb_power;
118                                                }
119                                        else{
120                                                if((int)get_tick_count()-tick2>1000) {debug_led(0);}
121                                                }
122                                        }
123                                else{
124                                        if(prev_usb_power){
125                                                tick3 = (int)get_tick_count()-tick2;
126                                                if(nSW==10) {
127                                                        if(tick3>50) shutter_int=1;
128                                                        nSW=20;
129                                                        }
130                                                if(nSW==0 && tick3>0) {
131                                                        if(tick3<50) {
132                                                        nSW=10;
133                                                        }
134                                                else{
135                                                        if(tick3>1000) shutter_int=1;
136                                                                nSW=20;
137                                                        }
138                                                }
139                                                prev_usb_power=cur_usb_power;
140                                                }
141                                        }
142                                if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
143                                }
144                         while(nSW<20);
145                         }
146                }               //continuous-shooting mode
147                else{           // normal mode
148                        shoot_counter=0;
149                        if(conf.bracket_type>2){
150                                shoot_counter=(conf.bracket_type-2)*2;
151                                }
152        do
153           {
154         //  _platformsub_kbd_fetch_data(x);
155           usb_physw[USB_IDX] = 0;
156          _kbd_read_keys_r2(usb_physw);
157           }
158
159// ------ modif by Masuji SUTO (start) --------------
160    while(((((usb_physw[USB_IDX] & USB_FLAG)!=USB_FLAG) && (nMode==0)) || (((usb_physw[USB_IDX] & USB_FLAG)==USB_FLAG) && (nMode==1))) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
161// ------ modif by Masuji SUTO (end)   --------------
162        }
163       } // ricoh ca-1 mode
164
165else
166
167       {
168         do
169          {
170         //  _platformsub_kbd_fetch_data(x);
171           usb_physw[USB_IDX] = 0;
172          _kbd_read_keys_r2(usb_physw);
173           }
174        while((usb_physw[USB_IDX]&USB_FLAG) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
175
176        }
177
178  } // synch enable
179
180
181if (conf.synch_delay_enable && conf.synch_delay_value>0)       // if delay is switched on and greater than 0
182  {
183    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
184    {
185      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
186        {
187        }
188     }
189  }
190
191debug_led(0);
192asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
193}
194
195static void __attribute__((noinline)) mykbd_task_proceed()
196{
197        while (physw_run){
198                _SleepTask(10) ;  //    *((int*)(0x1c30+0x14)));
199
200
201                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
202                        _kbd_p2_f();
203                }
204        }
205}
206
207// no stack manipulation needed here, since we create the task directly
208void __attribute__((naked,noinline))
209mykbd_task()
210{
211    mykbd_task_proceed();
212
213    _ExitTask();
214}
215
216long __attribute__((naked,noinline)) wrap_kbd_p1_f()
217{
218        asm volatile(
219                "STMFD   SP!, {R1-R5,LR}\n"
220                "MOV     R4, #0\n"
221                //"BL      _kbd_read_keys \n"
222                "BL             my_kbd_read_keys\n"
223                "B       _kbd_p1_f_cont\n"
224        );
225        return 0; // shut up the compiler
226}
227
228volatile int jogdial_stopped=0;
229
230void my_kbd_read_keys()
231{
232
233       
234        kbd_prev_state[0] = kbd_new_state[0];
235        kbd_prev_state[1] = kbd_new_state[1];
236        kbd_prev_state[2] = kbd_new_state[2];
237       
238        // Get the state of the buttons on the top of the G10. Like On/off, shoot, zoom, etc.
239        // but none of the backside buttons, like cursor, menu, display,etc..
240           
241        _GetKbdState(kbd_new_state);
242       
243        /* Get the rest of the buttons */
244       
245        _kbd_read_keys_r2(kbd_new_state);
246
247        kbd_new_state[0] |=0x00008000;  /// disable the battery door switch
248       
249        if (kbd_process() == 0){
250
251                // leave it alone... pass key strokes to the camera
252         
253                  physw_status[0] = kbd_new_state[0];
254          physw_status[1] = kbd_new_state[1];
255          physw_status[2] = kbd_new_state[2];
256       
257                 jogdial_stopped=0;
258
259        } else {
260                // override keys .. don't let them get to the camera or override them as on to trick the camera
261               
262                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
263                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
264                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
265
266                if ((jogdial_stopped==0) && !state_kbd_script_run)
267                {
268                        jogdial_stopped=1;
269                        get_jogdial_direction();
270                }
271                else if (jogdial_stopped && state_kbd_script_run) jogdial_stopped=0;
272        }
273       
274        remote_key = (physw_status[USB_IDX] & USB_FLAG)==USB_FLAG;
275                if (remote_key)
276                        remote_count += 1;
277                else if (remote_count) {
278                        usb_power = remote_count;
279                        remote_count = 0;
280                }
281        if (conf.remote_enable) {
282                physw_status[USB_IDX] = physw_status[USB_IDX] & ~(SD_READONLY_FLAG | USB_FLAG);
283        } else {
284                physw_status[USB_IDX] = physw_status[USB_IDX] & ~SD_READONLY_FLAG;
285        }
286}
287
288
289void kbd_set_alt_mode_key_mask(long key)
290{
291        int i;
292        for (i=0; keymap[i].hackkey; ++i) {
293                if (keymap[i].hackkey == key) {
294                        alt_mode_key_mask = keymap[i].canonkey;
295                        return;
296                }
297        }
298}
299
300
301void kbd_key_press(long key)
302{
303        int i;
304
305        for (i=0;keymap[i].hackkey;i++){
306                if (keymap[i].hackkey == key)
307                {
308                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
309                        return;
310                }
311        }
312}
313
314void kbd_key_release(long key)
315{
316        int i;
317        for (i=0;keymap[i].hackkey;i++){
318                if (keymap[i].hackkey == key){
319                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
320                        return;
321                }
322        }
323}
324
325void kbd_key_release_all()
326{
327        kbd_mod_state[0] |= KEYS_MASK0;
328        kbd_mod_state[1] |= KEYS_MASK1;
329        kbd_mod_state[2] |= KEYS_MASK2;
330}
331
332long kbd_is_key_pressed(long key)
333{
334        int i;
335        for (i=0;keymap[i].hackkey;i++){
336                if (keymap[i].hackkey == key){
337                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
338                }
339        }
340        return 0;
341}
342
343long kbd_is_key_clicked(long key)
344{
345        int i;
346        for (i=0;keymap[i].hackkey;i++){
347                if (keymap[i].hackkey == key){
348                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
349                               ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
350                }
351        }
352        return 0;
353}
354
355long kbd_get_pressed_key()
356{
357        int i;
358        for (i=0;keymap[i].hackkey;i++){
359                if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
360                        return keymap[i].hackkey;
361                }
362        }
363        return 0;
364}
365
366long kbd_get_clicked_key()
367{
368        int i;
369        for (i=0;keymap[i].hackkey;i++){
370                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
371                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
372                        return keymap[i].hackkey;
373                }
374        }
375        return 0;
376}
377
378void kbd_reset_autoclicked_key() {
379        last_kbd_key = 0;
380}
381
382long kbd_get_autoclicked_key() {
383        static long last_kbd_time = 0, press_count = 0;
384        register long key, t;
385
386        key=kbd_get_clicked_key();
387        if (key) {
388                last_kbd_key = key;
389                press_count = 0;
390                last_kbd_time = get_tick_count();
391                return key;
392        } else {
393                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
394                        t = get_tick_count();
395                        if (t-last_kbd_time>((press_count)?175:500)) {
396                                ++press_count;
397                                last_kbd_time = t;
398                                return last_kbd_key;
399                        } else {
400                                return 0;
401                        }
402                } else {
403                        last_kbd_key = 0;
404                        return 0;
405                }
406        }
407}
408
409int get_usb_power(int edge)
410{
411        int x;
412
413        if (edge) return remote_key;
414        x = usb_power;
415        usb_power = 0;
416        return x;
417}
418
419
420static int new_jogdial=0, old_jogdial=0;
421
422int Get_JogDial(void){
423 return (*(int*)0xC0240104)>>16;                // G10 okay
424}
425
426long get_jogdial_direction(void) {
427 old_jogdial=new_jogdial;
428 new_jogdial=Get_JogDial();
429 if (old_jogdial>new_jogdial) return JOGDIAL_LEFT;
430 else if (old_jogdial<new_jogdial) return JOGDIAL_RIGHT;
431 else return 0;
432}
Note: See TracBrowser for help on using the repository browser.