source: trunk/platform/a650/kbd.c @ 515

Revision 515, 11.7 KB checked in by reyalp, 5 years ago (diff)

set svn:eol-style and fix files that had mixed line endings. See http://chdk.setepontos.com/index.php/topic,2145.15.html

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