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

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