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

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