source: trunk/platform/sx30/kbd.c @ 1292

Revision 1292, 11.0 KB checked in by philmoz, 22 months ago (diff)

Update for G12 & SX30:

  • Added key definitions for the G12 front dial (keyboard.h)
  • Enabled the front dial to adjust values in menus (gui_menu.c)
  • Fixed rear dial on SX30 working backwards in CHDK menus
  • Cleanup stubs_entry_2.S files (for new signature finding system)
  • Cleanup in camera kbd.c files
  • 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
13static long kbd_new_state[3];
14static long kbd_prev_state[3];
15static long kbd_mod_state[3];
16
17static long last_kbd_key = 0;
18static int usb_power=0;
19static int remote_key, remote_count;
20static int shoot_counter=0;
21extern void _GetKbdState(long*);
22
23#define DELAY_TIMEOUT 10000
24
25//void my_blinkk(void) {
26//      int i;
27////    while(1) {
28//              *((volatile int *) 0xC0220134) = 0x46; // Turn on LED
29//              for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
30//
31//              *((volatile int *) 0xC0220134) = 0x44; // Turn off LED
32//              for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
33//
34//              *((volatile int *) 0xC0220134) = 0x46; // Turn on LED
35//              for (i=0; i<0x200000; i++) { asm volatile ( "nop\n" ); }
36//
37//              *((volatile int *) 0xC0220134) = 0x44; // Turn off LED
38//              for (i=0; i<0x900000; i++) { asm volatile ( "nop\n" ); }
39////    }
40//}
41
42#define KEYS_MASK0 (0x00CFFDE0)
43#define KEYS_MASK1 (0x00000000)
44#define KEYS_MASK2 (0x00000300)
45
46#define SD_READONLY_FLAG (0x20000)
47#define USB_MASK (0x4000000)
48#define USB_REG 2
49
50static KeyMap keymap[] = {
51
52        { 0, KEY_ZOOM_IN        , 0x00000020 }, // 2 bits used, 4 values (0x00000060)
53        { 0, KEY_ZOOM_IN1       , 0x00000020 }, // 2 bits used, 4 values (0x00000060)
54        { 0, KEY_ZOOM_IN        , 0x00000040 }, // 2 bits used, 4 values (0x00000060)
55        { 0, KEY_ZOOM_IN2       , 0x00000040 }, // 2 bits used, 4 values (0x00000060)
56        { 0, KEY_ZOOM_IN        , 0x00000060 }, // 2 bits used, 4 values (0x00000060)
57        { 0, KEY_ZOOM_IN3       , 0x00000060 }, // 2 bits used, 4 values (0x00000060)
58        { 0, KEY_ZOOM_OUT       , 0x00000080 }, // 2 bits used, 4 values (0x00000180)
59        { 0, KEY_ZOOM_OUT1      , 0x00000080 }, // 2 bits used, 4 values (0x00000180)
60        { 0, KEY_ZOOM_OUT       , 0x00000100 }, // 2 bits used, 4 values (0x00000180)
61        { 0, KEY_ZOOM_OUT2      , 0x00000100 }, // 2 bits used, 4 values (0x00000180)
62        { 0, KEY_ZOOM_OUT       , 0x00000180 }, // 2 bits used, 4 values (0x00000180)
63        { 0, KEY_ZOOM_OUT3      , 0x00000180 }, // 2 bits used, 4 values (0x00000180)
64        { 0, KEY_UP                     , 0x00000400 },
65        { 0, KEY_DOWN           , 0x00000800 },
66        { 0, KEY_LEFT           , 0x00001000 },
67        { 0, KEY_RIGHT          , 0x00002000 },
68        { 0, KEY_SET            , 0x00004000 },
69        { 0, KEY_VIDEO      , 0x00008000 },
70        { 0, KEY_ZOOM_ASSIST, 0x00010000 },
71        { 0, KEY_DISPLAY        , 0x00020000 },
72        { 0, KEY_MENU           , 0x00040000 },
73        { 0, KEY_ERASE          , 0x00080000 },
74        { 0, KEY_FLASH      , 0x00400000 },
75        { 0, KEY_PRINT          , 0x00800000 },
76
77        { 2, KEY_SHOOT_HALF     , 0x00000100 },
78        { 2, KEY_SHOOT_FULL     , 0x00000300 },
79
80        { 0, 0, 0 }
81};
82
83
84long __attribute__((naked)) wrap_kbd_p1_f() ;
85
86void wait_until_remote_button_is_released(void)
87{
88
89long x[3];
90int count1;
91int count2;
92int tick,tick2,tick3;
93int nSW;
94int prev_usb_power,cur_usb_power;
95 // ------ add by Masuji SUTO (start) --------------
96    static int nMode;
97 // ------ add by Masuji SUTO (end)   --------------
98
99asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
100//debug_led(1);
101tick = get_tick_count();
102tick2 = tick;
103static long usb_physw[3];
104if (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
105  {
106// ------ add by Masuji SUTO (start) --------------
107        nMode=0;
108        usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
109        _kbd_read_keys_r2(usb_physw);
110        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
111// ------ add by Masuji SUTO (end)   --------------
112     if(conf.ricoh_ca1_mode && conf.remote_enable)
113     {
114        if(shooting_get_drive_mode()==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                    //continuous-shooting mode
115                if(conf.bracket_type>2){
116                        if(shoot_counter<2) shutter_int=3;
117                        shoot_counter--;
118                        }
119                else{
120                        prev_usb_power=0;
121                        nSW = 0;
122                        do
123                                {
124                                usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
125                                _kbd_read_keys_r2(usb_physw);
126                                cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
127                                if(cur_usb_power){
128                                        if(!prev_usb_power){
129                                                tick2 = get_tick_count();
130                                                prev_usb_power=cur_usb_power;
131                                                }
132                                        else{
133                                                if((int)get_tick_count()-tick2>1000) {/*debug_led(0);*/}
134                                                }
135                                        }
136                                else{
137                                        if(prev_usb_power){
138                                                tick3 = (int)get_tick_count()-tick2;
139                                                if(nSW==10) {
140                                                        if(tick3>50) shutter_int=1;
141                                                        nSW=20;
142                                                        }
143                                                if(nSW==0 && tick3>0) {
144                                                        if(tick3<50) {
145                                                        nSW=10;
146                                                        }
147                                                else{
148                                                        if(tick3>1000) shutter_int=1;
149                                                                nSW=20;
150                                                        }
151                                                }
152                                                prev_usb_power=cur_usb_power;
153                                                }
154                                        }
155                                if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
156                                }
157                         while(nSW<20);
158                         }
159                }               //continuous-shooting mode
160                else{           // normal mode
161                        shoot_counter=0;
162                        if(conf.bracket_type>2){
163                                shoot_counter=(conf.bracket_type-2)*2;
164                                }
165        do
166           {
167         //  _platformsub_kbd_fetch_data(x);
168           usb_physw[2] = 0;
169          _kbd_read_keys_r2(usb_physw);
170           }
171
172// ------ modif by Masuji SUTO (start) --------------
173    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));
174// ------ modif by Masuji SUTO (end)   --------------
175        }
176       } // ricoh ca-1 mode
177
178else
179
180       {
181         do
182          {
183         //  _platformsub_kbd_fetch_data(x);
184           usb_physw[2] = 0;
185          _kbd_read_keys_r2(usb_physw);
186           }
187        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
188
189        }
190
191  } // synch enable
192
193
194if (conf.synch_delay_enable && conf.synch_delay_value>0)       // if delay is switched on and greater than 0
195  {
196    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
197    {
198      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
199        {
200        }
201     }
202  }
203
204//debug_led(0);
205asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
206}
207
208static void __attribute__((noinline)) mykbd_task_proceed()
209{
210        while (physw_run){
211                _SleepTask(*((int*)0x1c44)); //10);
212
213                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
214                        _kbd_p2_f();
215                }
216        }
217}
218
219// no stack manipulation needed here, since we create the task directly
220void __attribute__((naked,noinline))
221mykbd_task()
222{
223    mykbd_task_proceed();
224
225    _ExitTask();
226}
227
228long __attribute__((naked,noinline)) wrap_kbd_p1_f()
229{
230        asm volatile(
231                "STMFD   SP!, {R1-R5,LR}\n"
232                "MOV     R4, #0\n"
233                //"BL      _kbd_read_keys \n"
234                "BL             my_kbd_read_keys\n"
235                "B       _kbd_p1_f_cont\n"
236        );
237        return 0; // shut up the compiler
238}
239
240// Set to 1 to disable jogdial events from being processed in firmware
241volatile int jogdial_stopped=0;
242
243// Pointer to stack location where jogdial task records previous and current
244// jogdial positions
245extern short* jog_position;
246extern short rear_dial_position;
247
248void jogdial_control(int n)
249{
250    if (jogdial_stopped && !n)
251    {
252        // If re-enabling jogdial set the task code current & previous positions to the actual
253        // dial positions so that the change won't get processed by the firmware
254        jog_position[0] = jog_position[2] = rear_dial_position;   // Rear dial
255    }
256    jogdial_stopped = n;
257}
258
259void my_kbd_read_keys()
260{
261        kbd_prev_state[0] = kbd_new_state[0];
262        kbd_prev_state[1] = kbd_new_state[1];
263        kbd_prev_state[2] = kbd_new_state[2];
264
265        _GetKbdState(kbd_new_state);
266        _kbd_read_keys_r2(kbd_new_state);
267
268        if (kbd_process() == 0){
269                // leave it alone...
270          physw_status[0] = kbd_new_state[0];
271          physw_status[1] = kbd_new_state[1];
272          physw_status[2] = kbd_new_state[2];
273          jogdial_control(0);
274
275        } else {
276                // override keys
277                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
278                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
279                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
280
281                if ((jogdial_stopped==0) && !state_kbd_script_run)
282                {
283                        jogdial_control(1);
284                        get_jogdial_direction();
285                }
286                else if (jogdial_stopped && state_kbd_script_run) jogdial_control(0);
287        }
288
289        //_kbd_read_keys_r2(physw_status);
290
291        remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
292                if (remote_key)
293                        remote_count += 1;
294                else if (remote_count) {
295                        usb_power = remote_count;
296                        remote_count = 0;
297                }
298        if (conf.remote_enable) {
299                physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
300        } else {
301                physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
302        }
303}
304
305
306/****************/
307
308void kbd_set_alt_mode_key_mask(long key)
309{
310}
311
312
313void kbd_key_press(long key)
314{
315        int i;
316
317        for (i=0;keymap[i].hackkey;i++){
318                if (keymap[i].hackkey == key)
319                {
320                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
321                        return;
322                }
323        }
324}
325
326void kbd_key_release(long key)
327{
328        int i;
329        for (i=0;keymap[i].hackkey;i++){
330                if (keymap[i].hackkey == key){
331                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
332                        return;
333                }
334        }
335}
336
337void kbd_key_release_all()
338{
339        kbd_mod_state[0] |= KEYS_MASK0;
340        kbd_mod_state[1] |= KEYS_MASK1;
341        kbd_mod_state[2] |= KEYS_MASK2;
342}
343
344long kbd_is_key_pressed(long key)
345{
346        int i;
347        for (i=0;keymap[i].hackkey;i++){
348                if (keymap[i].hackkey == key){
349                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
350                }
351        }
352        return 0;
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
367long kbd_get_pressed_key()
368{
369        int i;
370        for (i=0;keymap[i].hackkey;i++){
371                if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
372                        return keymap[i].hackkey;
373                }
374        }
375        return 0;
376}
377
378long kbd_get_clicked_key()
379{
380        int i;
381        for (i=0;keymap[i].hackkey;i++){
382                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
383                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
384                        return keymap[i].hackkey;
385                }
386        }
387        return 0;
388}
389
390void kbd_reset_autoclicked_key() {
391        last_kbd_key = 0;
392}
393
394long kbd_get_autoclicked_key() {
395        static long last_kbd_time = 0, press_count = 0;
396        register long key, t;
397
398        key=kbd_get_clicked_key();
399        if (key) {
400                last_kbd_key = key;
401                press_count = 0;
402                last_kbd_time = get_tick_count();
403                return key;
404        } else {
405                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
406                        t = get_tick_count();
407                        if (t-last_kbd_time>((press_count)?175:500)) {
408                                ++press_count;
409                                last_kbd_time = t;
410                                return last_kbd_key;
411                        } else {
412                                return 0;
413                        }
414                } else {
415                        last_kbd_key = 0;
416                        return 0;
417                }
418        }
419}
420
421int get_usb_power(int edge)
422{
423        int x;
424
425        if (edge) return remote_key;
426        x = usb_power;
427        usb_power = 0;
428        return x;
429}
430
431long kbd_use_zoom_as_mf() {
432 return 0;
433}
434
435static short new_jogdial=0, old_jogdial=0;
436
437long get_jogdial_direction(void)
438{
439    old_jogdial = new_jogdial;
440    new_jogdial = rear_dial_position;
441    if (old_jogdial < new_jogdial) return JOGDIAL_LEFT;
442    else if (old_jogdial > new_jogdial) return JOGDIAL_RIGHT;
443    else return 0;
444}
Note: See TracBrowser for help on using the repository browser.