source: trunk/platform/a470/kbd.c @ 739

Revision 739, 11.0 KB checked in by phyrephox, 4 years ago (diff)

+a470, port done by MrSpoon? - see http://chdk.setepontos.com/index.php/topic,3368.msg31068.html#msg31068 - beta

  • 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
13static long kbd_new_state[3];
14static long kbd_prev_state[3];
15static long kbd_mod_state[3];
16static KeyMap keymap[];
17static long last_kbd_key = 0;
18static int usb_power=0;
19static int remote_key, remote_count;
20static int shoot_counter=0;
21#define DELAY_TIMEOUT 10000
22
23#define KEYS_MASK0 (0x00000000)
24#define KEYS_MASK1 (0xC0800000)
25#define KEYS_MASK2 (0x1FFF)
26
27#define NEW_SS (0x2000)
28#define SD_READONLY_FLAG (0x20000)
29
30#define USB_MASK (0x40000)
31
32#ifndef MALLOCD_STACK
33static char kbd_stack[NEW_SS];
34#endif
35
36void kbd_fetch_data(long*);
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];
58if (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)))                                     
59// if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable)                                         // 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)   --------------
67
68if(conf.ricoh_ca1_mode && conf.remote_enable)
69{
70        if(shooting_get_drive_mode() ==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                   //continuous-shooting mode
71                if(conf.bracket_type>2){
72                        if(shoot_counter<2) shutter_int=3;
73                        shoot_counter--;
74                        }
75                else{   
76                prev_usb_power=0;
77                nSW = 0;
78                do
79                        {     
80            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
81           _kbd_read_keys_r2(usb_physw);
82                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
83                        if(cur_usb_power){
84                                if(!prev_usb_power){
85                                        tick2 = get_tick_count();
86                                        prev_usb_power=cur_usb_power;
87                                        }
88                                else{
89                                        if((int)get_tick_count()-tick2>1000) {debug_led(0);}
90                                        }
91                                }
92                        else{
93                                if(prev_usb_power){
94                                        tick3 = (int)get_tick_count()-tick2;
95                                        if(nSW==10) {
96                                                if(tick3>50) shutter_int=1;
97                                                nSW=20;
98                                                }
99                                        if(nSW==0 && tick3>0) {
100                                                if(tick3<50) {
101                                                nSW=10;
102                                                }
103                                        else{
104                                                if(tick3>1000) shutter_int=1;
105                                                        nSW=20;
106                                                }
107                                        }
108                                        prev_usb_power=cur_usb_power;
109                                        }
110                                }
111                                               
112                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
113                        }
114                 while(nSW<20);
115                 }
116                }               //continuous-shooting mode
117        else{           //nomal mode   
118                        shoot_counter=0;
119                        if(conf.bracket_type>2){
120                                shoot_counter=(conf.bracket_type-2)*2;
121                                }
122   do
123         {     
124            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
125           _kbd_read_keys_r2(usb_physw);
126           }
127 //  while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
128// ------ modif by Masuji SUTO (start) --------------
129        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));
130// ------ modif by Masuji SUTO (end)   --------------
131        }
132 }
133
134else
135   {
136
137      do
138          {
139            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
140           _kbd_read_keys_r2(usb_physw);
141             
142           }
143        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
144    }
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       
162        static 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
225void my_kbd_read_keys()
226{
227    kbd_prev_state[0] = kbd_new_state[0];
228    kbd_prev_state[1] = kbd_new_state[1];
229    kbd_prev_state[2] = kbd_new_state[2];
230
231    _kbd_pwr_on();
232
233    kbd_fetch_data(kbd_new_state);
234
235    if (kbd_process() == 0){
236        // leave it alone...
237        physw_status[0] = kbd_new_state[0];
238        physw_status[1] = kbd_new_state[1];
239        physw_status[2] = kbd_new_state[2];
240    } else {
241        // override keys
242        physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) |
243                          (kbd_mod_state[0] & KEYS_MASK0);
244
245        physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) |
246                          (kbd_mod_state[1] & KEYS_MASK1);
247
248        physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) |
249                          (kbd_mod_state[2] & KEYS_MASK2);
250    }
251
252    _kbd_read_keys_r2(physw_status);
253
254//    physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
255
256
257    remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
258      if (remote_key)  remote_count += 1;
259      else if (remote_count) {
260         usb_power = remote_count;
261         remote_count = 0;
262      }
263
264    if (conf.remote_enable) {
265      physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
266     }
267    else physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
268    _kbd_pwr_off();
269
270}
271
272
273int get_usb_power(int edge)
274{
275        int x;
276
277        if (edge) return remote_key;
278        x = usb_power;
279        usb_power = 0;
280        return x;
281}
282
283/****************/
284
285void kbd_key_press(long key)
286{
287    int i;
288    for (i=0;keymap[i].hackkey;i++){
289        if (keymap[i].hackkey == key){
290            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
291            return;
292        }
293    }
294}
295
296void kbd_key_release(long key)
297{
298    int i;
299    for (i=0;keymap[i].hackkey;i++){
300        if (keymap[i].hackkey == key){
301            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
302            return;
303        }
304    }
305}
306
307void kbd_key_release_all()
308{
309  kbd_mod_state[0] |= KEYS_MASK0;
310  kbd_mod_state[1] |= KEYS_MASK1;
311  kbd_mod_state[2] |= KEYS_MASK2;
312}
313
314long kbd_is_key_pressed(long key)
315{
316    int i;
317    for (i=0;keymap[i].hackkey;i++){
318        if (keymap[i].hackkey == key){
319            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
320        }
321    }
322    return 0;
323}
324
325long kbd_is_key_clicked(long key)
326{
327    int i;
328    for (i=0;keymap[i].hackkey;i++){
329        if (keymap[i].hackkey == key){
330            return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
331                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
332        }
333    }
334    return 0;
335}
336
337long kbd_get_pressed_key()
338{
339        int i;
340    for (i=0;keymap[i].hackkey;i++){
341        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
342            if (i!=7) return keymap[i].hackkey;
343        }
344    }
345    return 0;
346}
347
348long kbd_get_clicked_key()
349{
350    int i;
351    for (i=0;keymap[i].hackkey;i++){
352        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
353            ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
354            return keymap[i].hackkey;
355        }
356    }
357    return 0;
358}
359
360void kbd_reset_autoclicked_key() {
361    last_kbd_key = 0;
362}
363
364long kbd_get_autoclicked_key() {
365    static long last_kbd_time = 0, press_count = 0;
366    register long key, t;
367
368    key=kbd_get_clicked_key();
369    if (key) {
370        last_kbd_key = key;
371        press_count = 0;
372        last_kbd_time = get_tick_count();
373        return key;
374    } else {
375        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
376            t = get_tick_count();
377            if (t-last_kbd_time>((press_count)?175:500)) {
378                ++press_count;
379                last_kbd_time = t;
380                return last_kbd_key;
381            } else {
382                return 0;
383            }
384        } else {
385            last_kbd_key = 0;
386            return 0;
387        }
388    }
389       
390       
391}
392
393long kbd_use_zoom_as_mf() {
394    static long v;
395    static long zoom_key_pressed = 0;
396
397    if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
398        get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
399        if (v) {
400            kbd_key_release_all();
401            kbd_key_press(KEY_RIGHT);
402            zoom_key_pressed = KEY_ZOOM_IN;
403            return 1;
404        }
405    } else {
406        if (zoom_key_pressed==KEY_ZOOM_IN) {
407            kbd_key_release(KEY_RIGHT);
408            zoom_key_pressed = 0;
409            return 1;
410        }
411    }
412    if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (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_LEFT);
417            zoom_key_pressed = KEY_ZOOM_OUT;
418            return 1;
419        }
420    } else {
421        if (zoom_key_pressed==KEY_ZOOM_OUT) {
422            kbd_key_release(KEY_LEFT);
423            zoom_key_pressed = 0;
424            return 1;
425        }
426    }
427    return 0;
428}
429
430
431static KeyMap keymap[] = {
432    /* tiny bug: key order matters. see kbd_get_pressed_key()
433     * for example
434     */
435        { 2, KEY_UP                     , 0x00000001 }, //
436        { 2, KEY_DOWN           , 0x00000002 }, //
437        { 2, KEY_LEFT           , 0x00000008 }, //
438        { 2, KEY_RIGHT          , 0x00000004 }, //
439        { 2, KEY_SET            , 0x00000100 }, //
440        { 2, KEY_SHOOT_FULL     , 0x00000030 },
441        { 2, KEY_SHOOT_HALF     , 0x00000010 }, 
442        { 2, KEY_MENU           , 0x00000400 },
443        { 2, KEY_DISPLAY        , 0x00000111 },
444        { 2, KEY_PRINT          , 0x00001000 }, //
445        { 0, 0, 0 }
446};
447
448
449void kbd_fetch_data(long *dst)
450{
451    volatile long *mmio0 = (void*)0xc0220200;
452    volatile long *mmio1 = (void*)0xc0220204;
453    volatile long *mmio2 = (void*)0xc0220208;
454
455    dst[0] = *mmio0;
456    dst[1] = *mmio1;
457    dst[2] = *mmio2 & 0xffff;
458}
Note: See TracBrowser for help on using the repository browser.