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

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