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

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