source: trunk/platform/a490/kbd.c @ 1205

Revision 1205, 10.3 KB checked in by reyalp, 2 years ago (diff)

a490 100f beta support, thanks to mrowl in http://chdk.setepontos.com/index.php?topic=650.msg68942#msg68942

  • 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    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];
17
18static long last_kbd_key = 0;
19static int usb_power=0;
20static int remote_key, remote_count;
21static int shoot_counter=0;
22extern void _platformsub_kbd_fetch_data(long*);
23
24#define DELAY_TIMEOUT 10000
25
26#define KEYS_MASK0 (0x00020000)
27#define KEYS_MASK1 (0x00000000)
28#define KEYS_MASK2 (0x017001f4)
29
30#define SD_READONLY_FLAG (0x40000)
31#define USB_MASK (0x80000)
32#define USB_REG 2
33
34
35static KeyMap keymap[] = {
36    /* tiny bug: key order matters. see kbd_get_pressed_key()
37    * for example
38    */
39
40    //{ 0, KEY_DISPLAY  , 0x00020000 }, // Playback
41    { 0, KEY_PRINT      , 0x00020000 }, // Playback
42
43    { 2, KEY_SHOOT_FULL , 0x00000030 }, // ? 0x00000010(KEY_SHOOT_HALF) + 0x00000030 (KEY_SHOOT_FULL)
44    { 2, KEY_SHOOT_HALF , 0x00000010 },
45   
46    { 2, KEY_UP         , 0x00100000 },
47    { 2, KEY_DOWN       , 0x00200000 },
48    { 2, KEY_LEFT       , 0x00400000 },
49    { 2, KEY_RIGHT      , 0x00000004 },
50    { 2, KEY_SET        , 0x00000100 },
51    { 2, KEY_ZOOM_IN    , 0x00000080 },
52    { 2, KEY_ZOOM_OUT   , 0x00000040 },
53    { 2, KEY_MENU       , 0x01000000 },
54    { 0, 0, 0 }
55};
56
57
58long __attribute__((naked)) wrap_kbd_p1_f() ;
59
60void wait_until_remote_button_is_released(void) {
61    int count1;
62    int count2;
63    int tick,tick2,tick3;
64    int nSW;
65    int prev_usb_power,cur_usb_power;
66    static int nMode;
67
68    asm volatile ("STMFD SP!, {R0-R11,LR}\n");   // store R0-R11 and LR in stack
69
70    //debug_led(1);
71    tick = get_tick_count();
72    tick2 = tick;
73    static long usb_physw[3];
74    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)))
75    //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
76    {
77        // ------ add by Masuji SUTO (start) --------------
78        nMode = 0;
79        usb_physw[2] = 0;   // makes sure USB bit is cleared.
80        _kbd_read_keys_r2(usb_physw);
81        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
82        // ------ add by Masuji SUTO (end)   --------------
83        if(conf.ricoh_ca1_mode && conf.remote_enable) {
84            if(shooting_get_drive_mode() == 1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING) {   //continuous-shooting mode
85                if(conf.bracket_type>2) {
86                    if(shoot_counter<2) shutter_int=3;
87                    shoot_counter--;
88                } else {
89                    prev_usb_power=0;
90                    nSW = 0;
91                    do {
92                        usb_physw[2] = 0;   // makes sure USB bit is cleared.
93                        _kbd_read_keys_r2(usb_physw);
94                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
95                        if(cur_usb_power) {
96                            if(!prev_usb_power) {
97                                tick2 = get_tick_count();
98                                prev_usb_power=cur_usb_power;
99                            } else {
100                                if((int)get_tick_count()-tick2>1000) {debug_led(0);}
101                            }
102                        } else {
103                            if(prev_usb_power) {
104                                tick3 = (int)get_tick_count()-tick2;
105                                if(nSW==10) {
106                                    if(tick3>50) shutter_int=1;
107                                        nSW=20;
108                                }
109                                if(nSW==0 && tick3>0) {
110                                    if(tick3<50) {
111                                    nSW=10;
112                                    } else {
113                                        if(tick3>1000) shutter_int=1;
114                                            nSW=20;
115                                    }
116                                }
117                                prev_usb_power=cur_usb_power;
118                            }
119                        }
120                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) { nSW=20;shutter_int=2; }
121                    }
122                    while(nSW<20);
123                }
124            }   // continuous-shooting mode
125            else {   //nomal mode
126                shoot_counter=0;
127                if(conf.bracket_type>2) {
128                    shoot_counter=(conf.bracket_type-2)*2;
129                }
130                do {
131                    usb_physw[2] = 0;    // makes sure USB bit is cleared.
132                    _kbd_read_keys_r2(usb_physw);
133                }
134                //while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
135                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));
136            }
137        } else {
138            do {
139                usb_physw[2] = 0;   // makes sure USB bit is cleared.
140               _kbd_read_keys_r2(usb_physw);
141            }
142           while ((usb_physw[2]&USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
143        }
144    }
145
146    if (conf.synch_delay_enable && conf.synch_delay_value>0) {   // if delay is switched on and greater than 0
147        for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) {   // wait delay_value * 0.1ms
148            for (count2=0;count2<1400;count2++) {   // delay approx. 0.1ms
149            }
150        }
151    }
152
153    //debug_led(0);
154    asm volatile ("LDMFD SP!, {R0-R11,LR}\n");   // restore R0-R11 and LR from stack
155}
156
157
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()
172{
173        mykbd_task_proceed();
174        _ExitTask();
175}
176
177
178long __attribute__((naked,noinline)) wrap_kbd_p1_f()
179{
180        asm volatile(
181                        "STMFD   SP!, {R1-R5,LR}\n"
182                        "MOV     R4, #0\n"
183                        //"BL      _kbd_read_keys\n"       // replaces kbd_fetch_data()
184                        "BL      my_kbd_read_keys\n"     // +
185                        "B       _kbd_p1_f_cont\n"       // continue
186        );
187       
188        return 0; // shut up the compiler
189}
190
191
192void my_kbd_read_keys()
193{
194        // If script are running, replace PRINT button with DISPLAY
195        if (state_kbd_script_run) {
196                int i;
197                for (i=0; keymap[i].hackkey; i++) {
198                        if (keymap[i].hackkey == KEY_PRINT) {
199                                keymap[i].hackkey = KEY_DISPLAY;
200                                break;
201                        }
202                }
203        } else {
204                int i;
205                for (i=0; keymap[i].hackkey; i++) {
206                        if (keymap[i].hackkey == KEY_DISPLAY) {
207                                keymap[i].hackkey = KEY_PRINT;
208                                break;
209                        }
210                }
211        }
212       
213        kbd_prev_state[0] = kbd_new_state[0];
214        //kbd_prev_state[1] = kbd_new_state[1];
215        kbd_prev_state[2] = kbd_new_state[2];
216       
217        asm volatile(
218        "BL      _kbd_read_keys\n"
219        );
220       
221        //_platformsub_kbd_fetch_data(kbd_new_state);
222        kbd_new_state[0] = physw_status[0];
223        kbd_new_state[1] = physw_status[1];
224        kbd_new_state[2] = physw_status[2];
225       
226        if (kbd_process() == 0){
227                // leave it alone...
228        } else {
229        // override keys
230        physw_status[0] = (kbd_new_state[0] | KEYS_MASK0) & (~KEYS_MASK0 | kbd_mod_state[0]);
231        //physw_status[1] = (kbd_new_state[1] | KEYS_MASK1) & (~KEYS_MASK1 | kbd_mod_state[1]);
232        physw_status[2] = (kbd_new_state[2] | KEYS_MASK2) & (~KEYS_MASK2 | kbd_mod_state[2]);
233        }
234       
235        //_kbd_read_keys_r2(physw_status);
236
237        remote_key = (physw_status[2] & USB_MASK) == USB_MASK;
238        if (remote_key)
239                remote_count += 1;
240        else if (remote_count) {
241                usb_power = remote_count;
242                remote_count = 0;
243        }
244       
245        if (conf.remote_enable) {
246                physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
247        } else {
248                physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
249        }
250}
251
252
253
254/****************/
255
256void kbd_key_press(long key)
257{
258        int i;
259        for (i=0;keymap[i].hackkey;i++){
260                if (keymap[i].hackkey == key){
261                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
262                        return;
263                }
264        }
265}
266
267void kbd_key_release(long key)
268{
269        int i;
270        for (i=0;keymap[i].hackkey;i++){
271                if (keymap[i].hackkey == key){
272                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
273                        return;
274                }
275        }
276}
277
278void kbd_key_release_all()
279{
280        kbd_mod_state[0] |= KEYS_MASK0;
281        kbd_mod_state[1] |= KEYS_MASK1;
282        kbd_mod_state[2] |= KEYS_MASK2 & ~0x01700000;
283}
284
285long kbd_is_key_pressed(long key)
286{
287        int i;
288        for (i=0;keymap[i].hackkey;i++){
289                if (keymap[i].hackkey == key){
290                        switch (keymap[i].hackkey) {
291                        case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_MENU:
292                                return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 0:1;
293                        default:
294                                return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
295                        }
296                }
297        }
298        return 0;
299}
300
301long kbd_is_key_clicked(long key)
302{
303        int i;
304        for (i=0;keymap[i].hackkey;i++){
305                if (keymap[i].hackkey == key){
306                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
307                                   ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
308                }
309        }
310        return 0;
311}
312
313long kbd_get_pressed_key()
314{
315        int i;
316        for (i=0;keymap[i].hackkey;i++){
317                if (kbd_is_key_pressed(keymap[i].hackkey)) {
318                        return keymap[i].hackkey;
319                }
320        }
321        return 0;
322}
323
324long kbd_get_clicked_key()
325{
326        int i;
327        for (i=0;keymap[i].hackkey;i++){
328                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
329                        ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
330                        return keymap[i].hackkey;
331                }
332        }
333        return 0;
334}
335
336
337void kbd_reset_autoclicked_key() {
338        last_kbd_key = 0;
339}
340
341long kbd_get_autoclicked_key() {
342        static long last_kbd_time = 0, press_count = 0;
343        register long key, t;
344       
345        key=kbd_get_clicked_key();
346        if (key) {
347                last_kbd_key = key;
348                press_count = 0;
349                last_kbd_time = get_tick_count();
350                return key;
351        } else {
352                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
353                        t = get_tick_count();
354                        if (t-last_kbd_time>((press_count)?175:500)) {
355                                ++press_count;
356                                last_kbd_time = t;
357                                return last_kbd_key;
358                        } else {
359                                return 0;
360                        }
361                } else {
362                        last_kbd_key = 0;
363                        return 0;
364                }
365        }
366}
367
368
369int get_usb_power(int edge)
370{
371        int x;
372
373        if (edge) return remote_key;
374        x = usb_power;
375        usb_power = 0;
376        return x;
377}
378
379long kbd_use_zoom_as_mf() {
380        return 0;
381}
Note: See TracBrowser for help on using the repository browser.