source: trunk/platform/g1x/kbd.c @ 1810

Revision 1810, 7.3 KB checked in by philmoz, 13 months ago (diff)

Alpha version of CHDK for the G1X firmware 1.00f.

  • 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] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
14static long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
15static long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
16
17static long last_kbd_key = 0;
18
19extern void _GetKbdState(long*);
20
21#define KEYS_MASK0 (0x013FFC00)
22#define KEYS_MASK1 (0x00000000)
23#define KEYS_MASK2 (0x000C0000)
24
25#define SD_READONLY_FLAG    0x00000002 // Found @0xff464d1c, levent 0x20a
26#define SD_READONLY_IDX     1
27
28#define USB_MASK            0x10000000 // Found @0xff464d94, levent 0x202
29#define USB_IDX             2
30
31extern void usb_remote_key( int ) ;
32int get_usb_bit()
33{
34        long usb_physw[3];
35        usb_physw[USB_IDX] = 0;
36        _kbd_read_keys_r2(usb_physw);
37        return(( usb_physw[USB_IDX] & USB_MASK)==USB_MASK) ;
38}
39
40static KeyMap keymap[] = {
41
42    { 0, KEY_DISPLAY         ,0x00000400 }, // Pretend the Metering button is the Disp button
43//  { 0, KEY_METERING        ,0x00000400 },
44    { 0, KEY_SET             ,0x00000800 }, // Found @0xff464ca4, levent 0x08
45    { 0, KEY_RIGHT           ,0x00001000 }, // Found @0xff464cac, levent 0x07
46    { 0, KEY_DOWN            ,0x00002000 }, // Found @0xff464cb4, levent 0x05
47//  { 0, KEY_DISPLAY         ,0x00002000 },
48    { 0, KEY_MENU            ,0x00004000 }, // Found @0xff464cbc, levent 0x09
49    { 0, KEY_LEFT            ,0x00008000 }, // Found @0xff464cc4, levent 0x06
50        { 0, KEY_ERASE               ,0x00010000 },
51    { 0, KEY_AE_LOCK         ,0x00020000 },
52    { 0, KEY_UP              ,0x00040000 }, // Found @0xff464cdc, levent 0x04
53        { 0, KEY_VIDEO           ,0x00080000 },
54    { 0, KEY_ZOOM_IN         ,0x00100000 }, // Found @0xff464cec, levent 0x02
55    { 0, KEY_ZOOM_OUT        ,0x00200000 }, // Found @0xff464cf4, levent 0x03
56        { 0, KEY_PRINT               ,0x01000000 },
57
58    { 2, KEY_SHOOT_FULL      ,0x000c0000 }, // Found @0xff464d64, levent 0x01
59    { 2, KEY_SHOOT_FULL_ONLY ,0x00080000 }, // Found @0xff464d64, levent 0x01
60    { 2, KEY_SHOOT_HALF      ,0x00040000 }, // Found @0xff464d5c, levent 0x00
61
62        { 0, 0, 0 }
63};
64
65
66long __attribute__((naked)) wrap_kbd_p1_f() ;
67
68
69static void __attribute__((noinline)) mykbd_task_proceed()
70{
71        while (physw_run){
72                _SleepTask(*((int*)0x1c18)); //10);
73
74                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
75                        _kbd_p2_f();
76                }
77        }
78}
79
80// no stack manipulation needed here, since we create the task directly
81void __attribute__((naked,noinline))
82mykbd_task()
83{
84    mykbd_task_proceed();
85
86    _ExitTask();
87}
88
89long __attribute__((naked,noinline)) wrap_kbd_p1_f()
90{
91        asm volatile(
92                "STMFD   SP!, {R1-R7,LR}\n"
93                "MOV     R5, #0\n"
94                //"BL      _kbd_read_keys \n"
95                "BL             my_kbd_read_keys\n"
96                "B       _kbd_p1_f_cont\n"
97        );
98        return 0; // shut up the compiler
99}
100
101// Set to 1 to disable jogdial events from being processed in firmware
102volatile int jogdial_stopped=0;
103
104// Pointer to stack location where jogdial task records previous and current
105// jogdial positions
106extern short* jog_position;
107extern short rear_dial_position, front_dial_position;
108
109void jogdial_control(int n)
110{
111    if (jogdial_stopped && !n)
112    {
113        // If re-enabling jogdial set the task code current & previous positions to the actual
114        // dial positions so that the change won't get processed by the firmware
115        jog_position[0] = jog_position[2] = rear_dial_position;   // Rear dial
116        jog_position[1] = jog_position[3] = front_dial_position;  // Front dial
117    }
118    jogdial_stopped = n;
119}
120
121void my_kbd_read_keys()
122{
123        kbd_prev_state[0] = kbd_new_state[0];
124        kbd_prev_state[1] = kbd_new_state[1];
125        kbd_prev_state[2] = kbd_new_state[2];
126
127        _GetKbdState(kbd_new_state);
128        _kbd_read_keys_r2(kbd_new_state);
129
130        if (kbd_process() == 0){
131                // leave it alone...
132          physw_status[0] = kbd_new_state[0];
133          physw_status[1] = kbd_new_state[1];
134          physw_status[2] = kbd_new_state[2];
135          jogdial_control(0);
136
137        } else {
138                // override keys
139                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
140                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
141                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
142
143                if ((jogdial_stopped==0) && !state_kbd_script_run)
144                {
145                        jogdial_control(1);
146                        get_jogdial_direction();
147                }
148                else if (jogdial_stopped && state_kbd_script_run) jogdial_control(0);
149        }
150
151        //_kbd_read_keys_r2(physw_status);
152
153        usb_remote_key(physw_status[USB_IDX]) ;
154
155    physw_status[SD_READONLY_IDX] = physw_status[SD_READONLY_IDX] & ~SD_READONLY_FLAG;
156        if (conf.remote_enable) {
157                physw_status[USB_IDX] = physw_status[USB_IDX] & ~USB_MASK;
158        }
159
160}
161
162
163/****************/
164
165void kbd_set_alt_mode_key_mask(long key)
166{
167}
168
169void kbd_key_press(long key)
170{
171        int i;
172
173        for (i=0;keymap[i].hackkey;i++){
174                if (keymap[i].hackkey == key)
175                {
176                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
177                        return;
178                }
179        }
180}
181
182void kbd_key_release(long key)
183{
184        int i;
185        for (i=0;keymap[i].hackkey;i++){
186                if (keymap[i].hackkey == key){
187                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
188                        return;
189                }
190        }
191}
192
193void kbd_key_release_all()
194{
195        kbd_mod_state[0] |= KEYS_MASK0;
196        kbd_mod_state[1] |= KEYS_MASK1;
197        kbd_mod_state[2] |= KEYS_MASK2;
198}
199
200long kbd_is_key_pressed(long key)
201{
202        int i;
203        for (i=0;keymap[i].hackkey;i++){
204                if (keymap[i].hackkey == key){
205                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
206                }
207        }
208        return 0;
209}
210
211long kbd_is_key_clicked(long key)
212{
213        int i;
214        for (i=0;keymap[i].hackkey;i++){
215                if (keymap[i].hackkey == key){
216                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
217                               ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
218                }
219        }
220        return 0;
221}
222
223long kbd_get_pressed_key()
224{
225        int i;
226        for (i=0;keymap[i].hackkey;i++){
227                if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
228                        return keymap[i].hackkey;
229                }
230        }
231        return 0;
232}
233
234long kbd_get_clicked_key()
235{
236        int i;
237        for (i=0;keymap[i].hackkey;i++){
238                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
239                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
240                        return keymap[i].hackkey;
241                }
242        }
243        return 0;
244}
245
246void kbd_reset_autoclicked_key() {
247        last_kbd_key = 0;
248}
249
250long kbd_get_autoclicked_key() {
251        static long last_kbd_time = 0, press_count = 0;
252        register long key, t;
253
254        key=kbd_get_clicked_key();
255        if (key) {
256                last_kbd_key = key;
257                press_count = 0;
258                last_kbd_time = get_tick_count();
259                return key;
260        } else {
261                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
262                        t = get_tick_count();
263                        if (t-last_kbd_time>((press_count)?175:500)) {
264                                ++press_count;
265                                last_kbd_time = t;
266                                return last_kbd_key;
267                        } else {
268                                return 0;
269                        }
270                } else {
271                        last_kbd_key = 0;
272                        return 0;
273                }
274        }
275}
276
277long kbd_use_zoom_as_mf() {
278 return 0;
279}
280
281static short new_jogdial = 0, old_jogdial = 0, new_frontdial = 0, old_frontdial = 0;
282
283long get_jogdial_direction(void)
284{
285    old_jogdial = new_jogdial;
286    new_jogdial = rear_dial_position;
287
288    old_frontdial = new_frontdial;
289    new_frontdial = front_dial_position;
290
291    if      (old_jogdial < new_jogdial)     return JOGDIAL_LEFT;
292    else if (old_jogdial > new_jogdial)     return JOGDIAL_RIGHT;
293    else if (old_frontdial < new_frontdial) return FRONTDIAL_LEFT;
294    else if (old_frontdial > new_frontdial) return FRONTDIAL_RIGHT;
295    else                                    return 0;
296}
Note: See TracBrowser for help on using the repository browser.