source: trunk/platform/s100/kbd.c @ 1792

Revision 1792, 6.9 KB checked in by philmoz, 2 years ago (diff)

Add S100 firmware versions 1.00d, 1.00e and 1.01a from c10ud.
http://chdk.setepontos.com/index.php?topic=650.msg83736#msg83736

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