source: trunk/platform/ixus120_sd940/kbd.c @ 1334

Revision 1334, 9.6 KB checked in by reyalp, 21 months ago (diff)

ixus120_sd940 updates from waterwingz in http://chdk.setepontos.com/index.php?topic=650.msg73050#msg73050

  • Corrects bug in capt_seq.c for all firmware versions.
  • Enables USB remote operation in "Synchable Remote" mode.
  • 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
14//static long kbd_new_state[3];
15long kbd_new_state[3];
16static long kbd_prev_state[3];
17static long kbd_mod_state[3];
18
19static long last_kbd_key = 0;
20static long alt_mode_key_mask = 0x00000008;
21static int usb_power=0;
22static int remote_key, remote_count;
23static int shoot_counter=0;
24extern void _platformsub_kbd_fetch_data(long*);
25
26#define DELAY_TIMEOUT 10000
27
28#define KEYS_MASK0 (0x00000008|0X00000004)
29#define KEYS_MASK1 (0x00000000)
30#define KEYS_MASK2 (0x00000300|0x00000100|0x00000080|0x00000040|0x00000010|0x00000020|0x00000004|0x00000008|0x00000001)
31
32#define NEW_SS (0x2000)
33
34#define SD_READONLY_FLAG (0x00020000)
35#define SD_READONLY_REG 2
36
37#define USB_REG 2
38#define USB_MASK (0x00080000)
39
40#ifndef MALLOCD_STACK
41static char kbd_stack[NEW_SS];
42#endif
43
44static KeyMap keymap[] = {
45        /* tiny bug: key order matters. see kbd_get_pressed_key() */
46
47        { 2, KEY_SHOOT_FULL     , 0x00000300 },
48        { 2, KEY_SHOOT_HALF     , 0x00000100 },
49        { 2, KEY_UP                     , 0x00000080 },
50        { 2, KEY_DOWN           , 0x00000040 },
51        { 2, KEY_LEFT           , 0x00000010 },
52        { 2, KEY_RIGHT          , 0x00000020 },
53        { 2, KEY_ZOOM_IN        , 0x00000004 },
54        { 2, KEY_ZOOM_OUT       , 0x00000008 },
55        { 2, KEY_MENU           , 0x00000001 },
56        { 0, KEY_PRINT          , 0x00000008 }, //doesn't exist so fake as DISPLAY
57        { 0, KEY_DISPLAY        , 0x00000008 },
58        { 0, KEY_SET            , 0x00000004 },
59        /*
60        { 2, KEY_PWR_PLAYBACK   , 0x00000800 },
61        { 2, KEY_PWR_SHOOT              , 0x00000400 },
62        { 2, KEY_BATTERY_DOOR   , 0x00008000 },
63    { 0, KEY_SW_AUTO            , 0x00000001 },
64    { 0, KEY_SW_MANUAL      , 0x00000000 },
65    { 0, KEY_SW_VIDEO       , 0x00000002 },
66        */
67    { 0, 0, 0 }
68};
69
70
71long __attribute__((naked)) wrap_kbd_p1_f() ;
72
73void wait_until_remote_button_is_released(void)
74{
75int count1;
76int count2;
77int tick,tick2,tick3;
78int nSW;
79int prev_usb_power,cur_usb_power;
80 // ------ add by Masuji SUTO (start) --------------
81    static int nMode;
82 // ------ add by Masuji SUTO (end)   --------------
83
84asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
85debug_led(1);
86tick = get_tick_count();
87tick2 = tick;
88static long usb_physw[3];
89if (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
90  {
91// ------ add by Masuji SUTO (start) --------------
92        nMode=0;
93        usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
94        _kbd_read_keys_r2(usb_physw);
95        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
96// ------ add by Masuji SUTO (end)   --------------
97     if(conf.ricoh_ca1_mode && conf.remote_enable)
98     {
99        if(shooting_get_drive_mode()==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                    //continuous-shooting mode
100                if(conf.bracket_type>2){
101                        if(shoot_counter<2) shutter_int=3;
102                        shoot_counter--;
103                        }
104                else{
105                        prev_usb_power=0;
106                        nSW = 0;
107                        do
108                                {
109                                usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
110                                _kbd_read_keys_r2(usb_physw);
111                                cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
112                                if(cur_usb_power){
113                                        if(!prev_usb_power){
114                                                tick2 = get_tick_count();
115                                                prev_usb_power=cur_usb_power;
116                                                }
117                                        else{
118                                                if((int)get_tick_count()-tick2>1000) {debug_led(0);}
119                                                }
120                                        }
121                                else{
122                                        if(prev_usb_power){
123                                                tick3 = (int)get_tick_count()-tick2;
124                                                if(nSW==10) {
125                                                        if(tick3>50) shutter_int=1;
126                                                        nSW=20;
127                                                        }
128                                                if(nSW==0 && tick3>0) {
129                                                        if(tick3<50) {
130                                                        nSW=10;
131                                                        }
132                                                else{
133                                                        if(tick3>1000) shutter_int=1;
134                                                                nSW=20;
135                                                        }
136                                                }
137                                                prev_usb_power=cur_usb_power;
138                                                }
139                                        }
140                                if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
141                                }
142                         while(nSW<20);
143                         }
144                }               //continuous-shooting mode
145                else{           //nomal mode
146                        shoot_counter=0;
147                        if(conf.bracket_type>2){
148                                shoot_counter=(conf.bracket_type-2)*2;
149                                }
150        do
151           {
152         //  _platformsub_kbd_fetch_data(x);
153           usb_physw[2] = 0;
154          _kbd_read_keys_r2(usb_physw);
155           }
156
157// ------ modif by Masuji SUTO (start) --------------
158    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));
159// ------ modif by Masuji SUTO (end)   --------------
160        }
161       } // ricoh ca-1 mode
162
163else
164
165       {
166         do
167          {
168         //  _platformsub_kbd_fetch_data(x);
169           usb_physw[2] = 0;
170          _kbd_read_keys_r2(usb_physw);
171           }
172        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
173
174        }
175
176  } // synch enable
177
178
179if (conf.synch_delay_enable && conf.synch_delay_value>0)       // if delay is switched on and greater than 0
180  {
181    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
182    {
183      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
184        {
185        }
186     }
187  }
188
189debug_led(0);
190
191asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
192}
193
194
195static void __attribute__((noinline)) mykbd_task_proceed()
196{
197        while (physw_run){
198                _SleepTask(10);
199
200                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
201                        _kbd_p2_f();
202                }
203        }
204}
205
206void __attribute__((naked,noinline)) mykbd_task()
207{
208        mykbd_task_proceed();
209
210        _ExitTask();
211}
212
213
214long __attribute__((naked,noinline)) wrap_kbd_p1_f()
215{
216        asm volatile(
217                "STMFD   SP!, {R1-R5,LR}\n"
218                "MOV     R4, #0\n"
219                "BL      my_kbd_read_keys\n"
220
221                "B       _kbd_p1_f_cont\n"
222        );
223
224         return 0; // shut up the compiler
225}
226
227volatile int jogdial_stopped=0;
228
229void my_kbd_read_keys()
230{
231        static int altDownTimer=0;
232        const int DISP_DOWN_TIME = 20;
233
234        kbd_prev_state[0] = kbd_new_state[0];
235        kbd_prev_state[1] = kbd_new_state[1];
236        kbd_prev_state[2] = kbd_new_state[2];
237
238        _platformsub_kbd_fetch_data(kbd_new_state);
239
240        /* Get the rest of the buttons */
241       
242        _kbd_read_keys_r2(kbd_new_state);
243       
244        kbd_new_state[2] |=0x00008000;  /// disable the battery door switch
245
246        // support for short/long press of Display
247        if (kbd_is_key_pressed(KEY_DISPLAY)) {                  // Display held down
248                altDownTimer++;                                                         // timer for DISP
249        }
250        else {
251                altDownTimer = 0;
252        }
253
254        if (kbd_process() == 0) {
255                // leave it alone...
256                physw_status[0] = kbd_new_state[0];
257                physw_status[1] = kbd_new_state[1];
258                physw_status[2] = kbd_new_state[2];
259
260                physw_status[0] |= alt_mode_key_mask;  /// disable the ALT mode button
261
262        }
263        else {
264                // override keys
265
266                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) |(kbd_mod_state[0] & KEYS_MASK0);
267                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
268                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) |(kbd_mod_state[2] & KEYS_MASK2);
269
270                if (altDownTimer > DISP_DOWN_TIME) {
271                        physw_status[0] &= ~alt_mode_key_mask;  // press the Display button
272                }
273        }
274       
275       
276        remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
277        if (remote_key) {
278                remote_count += 1;
279        }
280        else if (remote_count) {
281                usb_power = remote_count;
282                remote_count = 0;
283        }
284       
285
286        if (conf.remote_enable) {
287                physw_status[2] = physw_status[SD_READONLY_REG] & ~(SD_READONLY_FLAG | USB_MASK);
288        } else {
289                physw_status[2] = physw_status[SD_READONLY_REG] & ~SD_READONLY_FLAG;
290        }
291}
292
293
294
295
296void kbd_set_alt_mode_key_mask(long key)
297{
298        int i;
299        for (i=0; keymap[i].hackkey; ++i) {
300                if (keymap[i].hackkey == key) {
301                        alt_mode_key_mask = keymap[i].canonkey;
302                        return;
303                }
304        }
305}
306
307
308void kbd_key_press(long key)
309{
310        int i;
311
312        for (i=0;keymap[i].hackkey;i++){
313                if (keymap[i].hackkey == key)
314                {
315                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
316                        return;
317                }
318        }
319}
320
321
322void kbd_key_release(long key)
323{
324        int i;
325        for (i=0;keymap[i].hackkey;i++){
326                if (keymap[i].hackkey == key){
327                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
328                        return;
329                }
330        }
331}
332
333
334void kbd_key_release_all()
335{
336        kbd_mod_state[0] |= KEYS_MASK0;
337        kbd_mod_state[1] |= KEYS_MASK1;
338        kbd_mod_state[2] |= KEYS_MASK2;
339}
340
341
342long kbd_is_key_pressed(long key)
343{
344        int i;
345
346        for (i=0;keymap[i].hackkey;i++){
347                if (keymap[i].hackkey == key){
348                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
349                }
350        }
351        return 0;
352}
353
354
355long kbd_is_key_clicked(long key)
356{
357        int i;
358        for (i=0;keymap[i].hackkey;i++){
359                if (keymap[i].hackkey == key){
360                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
361                               ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
362                }
363        }
364        return 0;
365}
366
367
368long kbd_get_pressed_key()
369{
370        int i;
371        for (i=0;keymap[i].hackkey;i++){
372                if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
373                        return keymap[i].hackkey;
374                }
375        }
376        return 0;
377}
378
379
380long kbd_get_clicked_key()
381{
382        int i;
383        for (i=0;keymap[i].hackkey;i++){
384                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
385                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
386                        return keymap[i].hackkey;
387                }
388        }
389        return 0;
390}
391
392
393void kbd_reset_autoclicked_key() {
394        last_kbd_key = 0;
395}
396
397
398long kbd_get_autoclicked_key() {
399        static long last_kbd_time = 0, press_count = 0;
400        register long key, t;
401
402        key=kbd_get_clicked_key();
403        if (key) {
404                last_kbd_key = key;
405                press_count = 0;
406                last_kbd_time = get_tick_count();
407                return key;
408        } else {
409                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
410                        t = get_tick_count();
411                        if (t-last_kbd_time>((press_count)?175:500)) {
412                                ++press_count;
413                                last_kbd_time = t;
414                                return last_kbd_key;
415                        } else {
416                                return 0;
417                        }
418                } else {
419                        last_kbd_key = 0;
420                        return 0;
421                }
422        }
423}
424
425
426int get_usb_power(int edge)
427{
428        int x;
429
430        if (edge) return remote_key;
431        x = usb_power;
432        usb_power = 0;
433        return x;
434}
435
436
437long kbd_use_zoom_as_mf() {
438        return 0;
439}
Note: See TracBrowser for help on using the repository browser.