source: trunk/platform/ixus300_sd4000/kbd.c @ 1368

Revision 1368, 13.3 KB checked in by pixeldoc2000, 3 years ago (diff)

ixus300_sd4000 stubs_entry_2.S cleanup and stubs_entry.S updated

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 (0x0000090F)     // physw_status[0]
24// override key and feather bits to avoid feather osd messing up chdk display in ALT mode
25#define KEYS_MASK1 (0x00000FF0)     // physw_status[1], override 0xF0 (keys) + 0xF00 (feather)
26#define KEYS_MASK2 (0x00000000)     // physw_status[2]
27//static long alt_mode_key_mask = 0x00000000;   // we use two Keys, no need to override
28
29#define SD_READONLY_FLAG    (0x00020000)    // SD-Card Lock Status (locked / unlocked)
30#define SD_READONLY_IDX     2
31
32#define USB_MASK            (0x00080000)    // USB-Power (triggered around 3,5V)
33#define USB_IDX             2
34
35volatile int jogdial_stopped=0;
36
37long __attribute__((naked)) wrap_kbd_p1_f();
38
39static void __attribute__((noinline)) mykbd_task_proceed() {
40    while (physw_run) {
41        _SleepTask(10);
42
43        if (wrap_kbd_p1_f() == 1) {   // autorepeat ?
44            _kbd_p2_f();
45        }
46    }
47}
48
49// no stack manipulation needed here, since we create the task directly
50void __attribute__((naked,noinline)) mykbd_task() {
51    mykbd_task_proceed();
52    _ExitTask();
53}
54
55// ROM:FF83484C, like SX110
56long __attribute__((naked,noinline)) wrap_kbd_p1_f() {
57    asm volatile(
58        "STMFD   SP!, {R1-R5,LR}\n"
59        "MOV     R4, #0\n"
60        "BL      _kbd_read_keys\n"       // replaces kbd_fetch_data()
61        "BL      my_kbd_read_keys\n"     // +
62        "B       _kbd_p1_f_cont\n"       // continue at ROM:FF834858
63    );
64    return 0;   // shut up the compiler
65}
66
67// like SX110
68void my_kbd_read_keys() {
69    kbd_prev_state[0] = kbd_new_state[0];
70    kbd_prev_state[1] = kbd_new_state[1];
71    //kbd_prev_state[2] = kbd_new_state[2];   // nothing to override
72
73    // The following three lines replace the call to kbd_fetch_data()
74    kbd_new_state[0] = physw_status[0];
75    kbd_new_state[1] = physw_status[1];
76    //kbd_new_state[2] = physw_status[2];
77
78    if (kbd_process() == 0) {
79        // we read keyboard state with _kbd_read_keys()
80        jogdial_stopped=0;
81    } else {
82        // override keys
83        physw_status[0] = (kbd_new_state[0] | KEYS_MASK0) & (~KEYS_MASK0 | kbd_mod_state[0]);
84        physw_status[1] = (kbd_new_state[1] | KEYS_MASK1) & (~KEYS_MASK1 | kbd_mod_state[1]);
85        //physw_status[2] = (kbd_new_state[2] | KEYS_MASK2) & (~KEYS_MASK2 | kbd_mod_state[2]);
86
87        if ((jogdial_stopped==0) && !state_kbd_script_run) {
88            jogdial_stopped=1;
89            get_jogdial_direction();
90        } else if (jogdial_stopped && state_kbd_script_run)
91            jogdial_stopped=0;
92    }
93
94    remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
95    if (remote_key)
96        remote_count += 1;
97    else if (remote_count) {
98        usb_power = remote_count;
99        remote_count = 0;
100    }
101
102    if (conf.remote_enable) {
103        physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);   // override USB and SD-Card Readonly Bits
104    } else
105        physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;   // override SD-Card Readonly Bit
106}
107
108int get_usb_power(int edge) {
109    int x;
110
111    if (edge) return remote_key;
112    x = usb_power;
113    usb_power = 0;
114    return x;
115}
116
117void kbd_key_press(long key) {
118    int i;
119    for (i=0; keymap[i].hackkey; i++) {
120        if (keymap[i].hackkey == key) {
121            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
122            return;
123        }
124    }
125}
126
127void kbd_key_release(long key) {
128    int i;
129    for (i=0; keymap[i].hackkey; i++) {
130        if (keymap[i].hackkey == key) {
131            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
132            return;
133        }
134    }
135}
136
137void kbd_key_release_all() {
138    kbd_mod_state[0] |= KEYS_MASK0;
139    kbd_mod_state[1] |= KEYS_MASK1;
140    //kbd_mod_state[2] |= KEYS_MASK2;
141}
142
143long kbd_is_key_pressed(long key) {
144    int i;
145    for (i=0; keymap[i].hackkey; i++) {
146        if (keymap[i].hackkey == key) {
147            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
148        }
149    }
150    return 0;
151}
152
153long kbd_is_key_clicked(long key) {
154    int i;
155    for (i=0; keymap[i].hackkey; i++) {
156        if (keymap[i].hackkey == key) {
157            return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
158                   ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
159        }
160    }
161    return 0;
162}
163
164long kbd_get_pressed_key() {
165    int i;
166    for (i=0; keymap[i].hackkey; i++) {
167        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) {
168            return keymap[i].hackkey;
169        }
170    }
171    return 0;
172}
173
174long kbd_get_clicked_key() {
175    int i;
176    for (i=0; keymap[i].hackkey; i++) {
177        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) && ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
178            return keymap[i].hackkey;
179        }
180    }
181    return 0;
182}
183
184void kbd_reset_autoclicked_key() {
185    last_kbd_key = 0;
186}
187
188long kbd_get_autoclicked_key() {
189    static long last_kbd_time = 0, press_count = 0;
190    register long key, t;
191
192    key=kbd_get_clicked_key();
193    if (key) {
194        last_kbd_key = key;
195        press_count = 0;
196        last_kbd_time = get_tick_count();
197        return key;
198    } else {
199        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
200            t = get_tick_count();
201            if (t-last_kbd_time>((press_count)?175:500)) {
202                ++press_count;
203                last_kbd_time = t;
204                return last_kbd_key;
205            } else {
206                return 0;
207            }
208        } else {
209            last_kbd_key = 0;
210            return 0;
211        }
212    }
213}
214
215// ToDo
216#ifdef CAM_USE_ZOOM_FOR_MF
217long kbd_use_zoom_as_mf() {
218    static long v;
219    static long zoom_key_pressed = 0;
220
221    if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
222        get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
223        if (v) {
224            kbd_key_release_all();
225            kbd_key_press(KEY_RIGHT);
226            zoom_key_pressed = KEY_ZOOM_IN;
227            return 1;
228        }
229    } else {
230        if (zoom_key_pressed==KEY_ZOOM_IN) {
231            kbd_key_release(KEY_RIGHT);
232            zoom_key_pressed = 0;
233            return 1;
234        }
235    }
236    if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (mode_get()&MODE_MASK) == MODE_REC) {
237        get_property_case(PROPCASE_FOCUS_MODE, &v, 4);
238        if (v) {
239            kbd_key_release_all();
240            kbd_key_press(KEY_LEFT);
241            zoom_key_pressed = KEY_ZOOM_OUT;
242            return 1;
243        }
244    } else {
245        if (zoom_key_pressed==KEY_ZOOM_OUT) {
246            kbd_key_release(KEY_LEFT);
247            zoom_key_pressed = 0;
248            return 1;
249        }
250    }
251    return 0;
252}
253#endif
254
255// ROM:FF861F98
256int Get_JogDial(void) {
257    return (*(int*)0xC0240104)>>16;     // 0xC0240000 + 0x104
258}
259
260static int new_jogdial=0, old_jogdial=0;
261
262long get_jogdial_direction(void) {
263    old_jogdial=new_jogdial;
264    new_jogdial=Get_JogDial();
265
266    if (old_jogdial<new_jogdial) {
267        //return JOGDIAL_LEFT;
268        return JOGDIAL_RIGHT;
269    } else if (old_jogdial>new_jogdial) {
270        return JOGDIAL_LEFT;
271        //return JOGDIAL_RIGHT;
272    } else {
273        return 0;
274    }
275}
276
277// Base values in playback
278// physw_status[0] = 0x800C91F      // 1
279// physw_status[1] = 0xFFE          // 2 (Mode Switch: Auto)
280// physw_status[2] = 0x400000       // 3
281// Mode Switch:
282// physw_status[1] 0x1 Auto Mode
283// physw_status[1] 0x0 Photo Mode
284// physw_status[1] 0x2 Video Mode
285// physw_status[2] 0x20000 SD-Card READONLY
286static KeyMap keymap[] = {
287    { 0, KEY_UP         , 0x00000004 },    // finsig2
288    { 0, KEY_DOWN       , 0x00000001 },    // finsig2
289    { 0, KEY_LEFT       , 0x00000008 },    // finsig2
290    { 0, KEY_RIGHT      , 0x00000002 },    // finsig2
291    { 1, KEY_SET        , 0x00000040 },    // finsig2
292    { 0, KEY_SHOOT_FULL , 0x00000900 },    // 0x00000800(KEY_SHOOT_FULL) + 0x00000100 (KEY_SHOOT_HALF), ToDo: still not shure if correct (related to problems with shoot_full?), finsig2
293    { 0, KEY_SHOOT_FULL_ONLY , 0x00000800 },
294    { 0, KEY_SHOOT_HALF , 0x00000100 },    // finsig2
295    { 1, KEY_ZOOM_IN    , 0x00000010 },    // finsig2
296    { 1, KEY_ZOOM_OUT   , 0x00000020 },    // finsig2
297    { 1, KEY_MENU       , 0x00000080 },    // finsig2
298    { 0, KEY_PRINT      , 0x0000000C },   // ALT Key workaround: KEY_UP + KEY_LEFT (camera has no print key)
299    { 0, 0, 0 }
300};
301
302// generic function
303// called from capt_seq.c at sub_FF9686A8_my()
304void wait_until_remote_button_is_released(void) {
305    int count1;
306    int count2;
307    int tick,tick2,tick3;
308    int nSW;
309    int prev_usb_power,cur_usb_power;
310    static int nMode;
311
312    asm volatile ("STMFD SP!, {R0-R11,LR}\n");   // store R0-R11 and LR in stack
313
314    //debug_led(1);
315    tick = get_tick_count();
316    tick2 = tick;
317    static long usb_physw[3];
318    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)))
319        //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
320    {
321        // ------ add by Masuji SUTO (start) --------------
322        nMode = 0;
323        usb_physw[2] = 0;   // makes sure USB bit is cleared.
324        _kbd_read_keys_r2(usb_physw);
325        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
326        // ------ add by Masuji SUTO (end)   --------------
327        if(conf.ricoh_ca1_mode && conf.remote_enable) {
328            if(shooting_get_drive_mode() == 1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING) {   //continuous-shooting mode
329                if(conf.bracket_type>2) {
330                    if(shoot_counter<2) shutter_int=3;
331                    shoot_counter--;
332                } else {
333                    prev_usb_power=0;
334                    nSW = 0;
335                    do {
336                        usb_physw[2] = 0;   // makes sure USB bit is cleared.
337                        _kbd_read_keys_r2(usb_physw);
338                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
339                        if(cur_usb_power) {
340                            if(!prev_usb_power) {
341                                tick2 = get_tick_count();
342                                prev_usb_power=cur_usb_power;
343                            } else {
344                                if((int)get_tick_count()-tick2>1000) {
345                                    debug_led(0);
346                                }
347                            }
348                        } else {
349                            if(prev_usb_power) {
350                                tick3 = (int)get_tick_count()-tick2;
351                                if(nSW==10) {
352                                    if(tick3>50) shutter_int=1;
353                                    nSW=20;
354                                }
355                                if(nSW==0 && tick3>0) {
356                                    if(tick3<50) {
357                                        nSW=10;
358                                    } else {
359                                        if(tick3>1000) shutter_int=1;
360                                        nSW=20;
361                                    }
362                                }
363                                prev_usb_power=cur_usb_power;
364                            }
365                        }
366                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {
367                            nSW=20;
368                            shutter_int=2;
369                        }
370                    } while(nSW<20);
371                }
372            }   // continuous-shooting mode
373            else {   //nomal mode
374                shoot_counter=0;
375                if(conf.bracket_type>2) {
376                    shoot_counter=(conf.bracket_type-2)*2;
377                }
378                do {
379                    usb_physw[2] = 0;    // makes sure USB bit is cleared.
380                    _kbd_read_keys_r2(usb_physw);
381                }
382                //while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
383                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));
384            }
385        } else {
386            do {
387                usb_physw[2] = 0;   // makes sure USB bit is cleared.
388                _kbd_read_keys_r2(usb_physw);
389            } while ((usb_physw[2]&USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
390        }
391    }
392
393    if (conf.synch_delay_enable && conf.synch_delay_value>0) {   // if delay is switched on and greater than 0
394        for (count1=0; count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000); count1++) { // wait delay_value * 0.1ms
395            for (count2=0; count2<1400; count2++) { // delay approx. 0.1ms
396            }
397        }
398    }
399
400    //debug_led(0);
401    asm volatile ("LDMFD SP!, {R0-R11,LR}\n");   // restore R0-R11 and LR from stack
402}
Note: See TracBrowser for help on using the repository browser.