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

Revision 1344, 10.6 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 "keyboard.h"
5#include "conf.h"
6extern void _GetKbdState(long* buffer);
7extern void _GetKbdState2(long* buffer);
8
9typedef struct {
10        short grp;
11        short hackkey;
12        long canonkey;
13} KeyMap;
14
15
16static long kbd_new_state[3];
17static long kbd_prev_state[3];
18static long kbd_mod_state[3];
19static KeyMap keymap[];
20static long last_kbd_key = 0;
21static long alt_mode_key_mask = 0x00000200; 
22static long alt_mode_key_reg  = 1;     
23static int usb_power=0;
24static int remote_key, remote_count;
25static int shoot_counter=0;
26
27volatile int jogdial_stopped=0;
28
29#define DELAY_TIMEOUT 10000
30
31#define KEYS_MASK0 (0x00000300)
32#define KEYS_MASK1 (0x0000FF30)
33#define KEYS_MASK2 (0x00000000)
34
35static KeyMap keymap[] = {
36//      { grp,       hackkey, canonkey  }
37        { 1, KEY_UP                     , 0x00004000 },
38        { 1, KEY_DOWN           , 0x00000400 },
39        { 1, KEY_LEFT           , 0x00000100 },
40        { 1, KEY_RIGHT          , 0x00000200 },
41        { 1, KEY_SET            , 0x00008000 },
42        { 0, KEY_SHOOT_FULL     , 0x00000300 },
43    { 0, KEY_SHOOT_FULL_ONLY, 0x00000200 },
44        { 0, KEY_SHOOT_HALF     , 0x00000100 },
45        { 1, KEY_ZOOM_IN        , 0x00000010 },
46        { 1, KEY_ZOOM_OUT       , 0x00000020 },
47        { 1, KEY_MENU           , 0x00002000 },
48        { 1, KEY_DISPLAY        , 0x00001000 },
49        { 1, KEY_PRINT          , 0x00000800 }, // S Key
50//      { 0, KEY_PLAY           , 0x00000800 },
51//      { 1, KEY_RING_FUNC  , 0x00000040 },
52        { 0, 0, 0 }
53};
54
55#define SD_READONLY_FLAG (0x20000)
56#define USB_MASK (0x200000)
57
58
59void kbd_fetch_data(long*);
60
61long __attribute__((naked)) wrap_kbd_p1_f() ;
62
63void wait_until_remote_button_is_released(void)
64{
65int count1;
66int count2;
67int tick,tick2,tick3;
68int nSW;
69int prev_usb_power,cur_usb_power;
70
71// ------ add by Masuji SUTO (start) --------------
72    static int nMode;
73 // ------ add by Masuji SUTO (end)   --------------
74
75asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
76
77debug_led(1);
78tick = get_tick_count();
79tick2 = tick;
80static long usb_physw[3];
81if (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)))                                     
82// if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable)                                         // synch mode enable so wait for USB to disconnect
83  {
84// ------ add by Masuji SUTO (start) --------------
85        nMode=0;
86        usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
87        _kbd_read_keys_r2(usb_physw);
88        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
89// ------ add by Masuji SUTO (end)   --------------
90
91if(conf.ricoh_ca1_mode && conf.remote_enable)
92{
93        if(shooting_get_drive_mode() ==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                   //continuous-shooting mode
94                if(conf.bracket_type>2){
95                        if(shoot_counter<2) shutter_int=3;
96                        shoot_counter--;
97                        }
98                else{   
99                prev_usb_power=0;
100                nSW = 0;
101                do
102                        {     
103            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
104           _kbd_read_keys_r2(usb_physw);
105                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
106                        if(cur_usb_power){
107                                if(!prev_usb_power){
108                                        tick2 = get_tick_count();
109                                        prev_usb_power=cur_usb_power;
110                                        }
111                                else{
112                                        if((int)get_tick_count()-tick2>1000) {debug_led(0);}
113                                        }
114                                }
115                        else{
116                                if(prev_usb_power){
117                                        tick3 = (int)get_tick_count()-tick2;
118                                        if(nSW==10) {
119                                                if(tick3>50) shutter_int=1;
120                                                nSW=20;
121                                                }
122                                        if(nSW==0 && tick3>0) {
123                                                if(tick3<50) {
124                                                nSW=10;
125                                                }
126                                        else{
127                                                if(tick3>1000) shutter_int=1;
128                                                        nSW=20;
129                                                }
130                                        }
131                                        prev_usb_power=cur_usb_power;
132                                        }
133                                }
134                                               
135                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
136                        }
137                 while(nSW<20);
138                 }
139                }               //continuous-shooting mode
140        else{           // normal mode
141                        shoot_counter=0;
142                        if(conf.bracket_type>2){
143                                shoot_counter=(conf.bracket_type-2)*2;
144                                }
145   do
146         {     
147            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
148           _kbd_read_keys_r2(usb_physw);
149           }
150 //  while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
151// ------ modif by Masuji SUTO (start) --------------
152        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));
153// ------ modif by Masuji SUTO (end)   --------------
154        }
155 }
156
157else
158   {
159
160      do
161          {
162            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
163           _kbd_read_keys_r2(usb_physw);
164             
165           }
166        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
167    }
168
169  }
170
171if (conf.synch_delay_enable && conf.synch_delay_value>0)                                // if delay is switched on and greater than 0
172  {
173    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
174    {
175      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
176        {
177        }
178     }
179  }
180
181debug_led(0);
182asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
183}
184
185static void __attribute__((noinline)) mykbd_task_proceed()
186{
187        /* Initialize our own kbd_new_state[] array with the
188           current physical status.
189           */
190        kbd_new_state[0] = physw_status[0];
191        kbd_new_state[1] = physw_status[1];
192        kbd_new_state[2] = physw_status[2];
193
194        while (physw_run){
195                _SleepTask(10);
196                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
197                        _kbd_p2_f();
198                }
199    }
200}
201
202void __attribute__((naked,noinline))
203mykbd_task(long ua, long ub, long uc, long ud, long ue, long uf)
204{
205        mykbd_task_proceed();
206    /* function can be modified to restore SP here...
207     */
208    _ExitTask();
209}
210
211
212long __attribute__((naked,noinline)) wrap_kbd_p1_f()
213{
214    asm volatile(
215                "STMFD   SP!, {R1-R5,LR}\n"
216                "MOV     R4, #0\n"
217                "BL      my_kbd_read_keys\n"
218                "B       _kbd_p1_f_cont\n"     
219
220    );
221 return 0; // shut up the compiler
222}
223
224void my_kbd_read_keys()
225{
226
227    kbd_prev_state[0] = kbd_new_state[0];
228    kbd_prev_state[1] = kbd_new_state[1];
229    kbd_prev_state[2] = kbd_new_state[2];
230
231        _GetKbdState(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        //physw_status[0] |= alt_mode_key_mask;
239        jogdial_stopped=0;
240
241    } else {
242        // override keys
243                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) |
244                                  (kbd_mod_state[0] & KEYS_MASK0);
245                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) |
246                                  (kbd_mod_state[1] & KEYS_MASK1);
247                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) |
248                                  (kbd_mod_state[2] & KEYS_MASK2);
249                if ((jogdial_stopped==0) && !state_kbd_script_run)
250                        { jogdial_stopped=1; get_jogdial_direction(); }
251                else if (jogdial_stopped && state_kbd_script_run)
252                         jogdial_stopped=0;
253
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)     remote_count += 1;
261      else if (remote_count) {
262         usb_power = remote_count;
263         remote_count = 0;
264      }
265
266    if (conf.remote_enable) {
267      physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
268     }
269    else        physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
270}
271
272
273int get_usb_power(int edge)
274{
275        int x;
276
277        if (edge) return remote_key;
278        x = usb_power;
279        usb_power = 0;
280        return x;
281}
282
283/****************/
284void kbd_set_alt_mode_key_mask(long key)
285{
286    int i;
287    for (i=0; keymap[i].hackkey; ++i) {
288        if (keymap[i].hackkey == key) {
289            alt_mode_key_mask = keymap[i].canonkey;
290            alt_mode_key_reg  = keymap[i].grp;
291            return;
292        }
293    }
294}
295
296void kbd_key_press(long key)
297{
298    int i;
299    for (i=0;keymap[i].hackkey;i++){
300        if (keymap[i].hackkey == key){
301            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
302            return;
303        }
304    }
305}
306
307void kbd_key_release(long key)
308{
309    int i;
310    for (i=0;keymap[i].hackkey;i++){
311        if (keymap[i].hackkey == key){
312            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
313            return;
314        }
315    }
316}
317
318void kbd_key_release_all()
319{
320  kbd_mod_state[0] |= KEYS_MASK0;
321  kbd_mod_state[1] |= KEYS_MASK1;
322  kbd_mod_state[2] |= KEYS_MASK2;
323}
324
325long kbd_is_key_pressed(long key)
326{
327    int i;
328    for (i=0;keymap[i].hackkey;i++){
329        if (keymap[i].hackkey == key){
330            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
331        }
332    }
333    return 0;
334}
335
336long kbd_is_key_clicked(long key)
337{
338                int i;
339                for (i=0;keymap[i].hackkey;i++){
340                if (keymap[i].hackkey == key){
341                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
342                                ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
343                }
344                }
345                return 0;
346}
347
348long kbd_get_pressed_key()
349{
350    int i;
351    for (i=0;keymap[i].hackkey;i++){
352        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
353            return keymap[i].hackkey;
354        }
355    }
356    return 0;
357}
358
359long kbd_get_clicked_key()
360{
361    int i;
362    for (i=0;keymap[i].hackkey;i++){
363        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
364            ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
365            return keymap[i].hackkey;
366        }
367    }
368    return 0;
369}
370
371void kbd_reset_autoclicked_key() {
372    last_kbd_key = 0;
373}
374
375long kbd_get_autoclicked_key() {
376    static long last_kbd_time = 0, press_count = 0;
377    register long key, t;
378
379    key=kbd_get_clicked_key();
380    if (key) {
381        last_kbd_key = key;
382        press_count = 0;
383        last_kbd_time = get_tick_count();
384        return key;
385    } else {
386        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
387            t = get_tick_count();
388            if (t-last_kbd_time>((press_count)?175:500)) {
389                ++press_count;
390                last_kbd_time = t;
391                return last_kbd_key;
392            } else {
393                return 0;
394            }
395        } else {
396            last_kbd_key = 0;
397            return 0;
398        }
399    }
400       
401       
402}
403long kbd_use_zoom_as_mf() {
404        return 0;
405}
406
407
408static int new_jogdial=0, old_jogdial=0;
409
410/* Baseadr 0xC0240000 @FF85E948
411   Offset 104 @FF85E950 in Jogdial.c
412*/
413int Get_JogDial(void){
414 return (*(int*)0xC0240104)>>16;
415}
416
417long get_jogdial_direction(void) {
418 old_jogdial=new_jogdial;
419 new_jogdial=Get_JogDial();
420 if (old_jogdial<new_jogdial) return JOGDIAL_LEFT;
421 else if (old_jogdial>new_jogdial) return JOGDIAL_RIGHT;
422 else return 0;
423}
424
425
426/*
427void kbd_set_alt_mode_key_mask(long key)
428{
429    int i;
430    for (i=0; keymap[i].hackkey; ++i) {
431        if (keymap[i].hackkey == key) {
432            alt_mode_key_mask = keymap[i].canonkey;
433            return;
434        }
435    }
436}
437*/
438
Note: See TracBrowser for help on using the repository browser.