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

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