source: trunk/platform/s95/kbd.c @ 1505

Revision 1505, 10.4 KB checked in by reyalp, 17 months ago (diff)

merge tsvstar module code from reyalp-flt branch, + fixups for r1499, see http://chdk.setepontos.com/index.php?topic=847.msg77690#msg77690 and following posts
NOTE modules in CHDK/MODULES are now required for CHDK to work properly. On multi-partition cards, this goes on the large card.
Adds tetris and snake, originally contributed by elektro255 in http://chdk.setepontos.com/index.php?topic=2925.0

  • Property svn:eol-style set to native
Line 
1#include "lolevel.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6extern void _GetKbdState(long* buffer);
7extern void _GetKbdState2(long* buffer);
8
9typedef struct {
10        short grp;
11        short hackkey;
12        long canonkey;
13} KeyMap;
14
15
16static long kbd_new_state[3];
17static long kbd_prev_state[3];
18static long kbd_mod_state[3];
19static KeyMap keymap[];
20static long last_kbd_key = 0;
21static long alt_mode_key_mask = 0x00000200;
22static long alt_mode_key_reg  = 1;
23static int usb_power=0;
24static int remote_key, remote_count;
25static int shoot_counter=0;
26volatile int jogdial_stopped=0;
27
28#define DELAY_TIMEOUT 10000
29
30#define KEYS_MASK0 (0x00000000)
31#define KEYS_MASK1 (0x0000FF30)
32#define KEYS_MASK2 (0x00000300)
33
34static KeyMap keymap[] = {
35//      { grp,       hackkey, canonkey  }
36        { 1, KEY_UP                     , 0x00004000 },
37        { 1, KEY_DOWN           , 0x00000400 },
38        { 1, KEY_LEFT           , 0x00000100 },
39        { 1, KEY_RIGHT          , 0x00000200 },
40        { 1, KEY_SET            , 0x00008000 },
41        { 2, KEY_SHOOT_FULL     , 0x00000300 },
42    { 2, KEY_SHOOT_FULL_ONLY, 0x00000200 },
43        { 2, KEY_SHOOT_HALF     , 0x00000100 },
44        { 1, KEY_ZOOM_IN        , 0x00000010 },
45        { 1, KEY_ZOOM_OUT       , 0x00000020 },
46        { 1, KEY_MENU           , 0x00002000 },
47        { 1, KEY_DISPLAY        , 0x00001000 },
48        { 1, KEY_PRINT          , 0x00000800 }, // S Key
49//      { 2, KEY_PLAY           , 0x00000800 },
50//      { 2, KEY_RING_FUNC  , 0x00004000 },
51//      { 2, KEY_POWER      , 0x00000400 },
52        { 0, 0, 0 }
53};
54
55
56#define SD_READONLY_FLAG (0x20000)      // in physw_status[2]
57#define USB_MASK (0x4000000)                    // in physw_status[2]
58
59
60void kbd_fetch_data(long*);
61
62long __attribute__((naked)) wrap_kbd_p1_f() ;
63
64void wait_until_remote_button_is_released(void)
65{
66int count1;
67int count2;
68int tick,tick2,tick3;
69int nSW;
70int prev_usb_power,cur_usb_power;
71
72// ------ add by Masuji SUTO (start) --------------
73    static int nMode;
74 // ------ add by Masuji SUTO (end)   --------------
75
76asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
77
78debug_led(1);
79tick = get_tick_count();
80tick2 = tick;
81static long usb_physw[3];
82if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable && (!shooting_get_drive_mode()|| (shooting_get_drive_mode()==1) || ((shooting_get_drive_mode()==2) && state_shooting_progress != SHOOTING_PROGRESS_PROCESSING)))
83// if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable)                                         // synch mode enable so wait for USB to disconnect
84  {
85// ------ add by Masuji SUTO (start) --------------
86        nMode=0;
87        usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
88        _kbd_read_keys_r2(usb_physw);
89        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
90// ------ add by Masuji SUTO (end)   --------------
91
92if(conf.ricoh_ca1_mode && conf.remote_enable)
93{
94        if(shooting_get_drive_mode() ==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                   //continuous-shooting mode
95                if(conf.bracket_type>2){
96                        if(shoot_counter<2) shutter_int=3;
97                        shoot_counter--;
98                        }
99                else{
100                prev_usb_power=0;
101                nSW = 0;
102                do
103                        {
104            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
105           _kbd_read_keys_r2(usb_physw);
106                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
107                        if(cur_usb_power){
108                                if(!prev_usb_power){
109                                        tick2 = get_tick_count();
110                                        prev_usb_power=cur_usb_power;
111                                        }
112                                else{
113                                        if((int)get_tick_count()-tick2>1000) {debug_led(0);}
114                                        }
115                                }
116                        else{
117                                if(prev_usb_power){
118                                        tick3 = (int)get_tick_count()-tick2;
119                                        if(nSW==10) {
120                                                if(tick3>50) shutter_int=1;
121                                                nSW=20;
122                                                }
123                                        if(nSW==0 && tick3>0) {
124                                                if(tick3<50) {
125                                                nSW=10;
126                                                }
127                                        else{
128                                                if(tick3>1000) shutter_int=1;
129                                                        nSW=20;
130                                                }
131                                        }
132                                        prev_usb_power=cur_usb_power;
133                                        }
134                                }
135
136                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
137                        }
138                 while(nSW<20);
139                 }
140                }               //continuous-shooting mode
141        else{           //nomal mode
142                        shoot_counter=0;
143                        if(conf.bracket_type>2){
144                                shoot_counter=(conf.bracket_type-2)*2;
145                                }
146   do
147         {
148            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
149           _kbd_read_keys_r2(usb_physw);
150           }
151 //  while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
152// ------ modif by Masuji SUTO (start) --------------
153        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));
154// ------ modif by Masuji SUTO (end)   --------------
155        }
156 }
157
158else
159   {
160
161      do
162          {
163            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
164           _kbd_read_keys_r2(usb_physw);
165
166           }
167        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
168    }
169
170  }
171
172if (conf.synch_delay_enable && conf.synch_delay_value>0)                                // if delay is switched on and greater than 0
173  {
174    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
175    {
176      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
177        {
178        }
179     }
180  }
181
182debug_led(0);
183asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
184}
185
186static void __attribute__((noinline)) mykbd_task_proceed()
187{
188        /* Initialize our own kbd_new_state[] array with the
189           current physical status.
190           */
191        kbd_new_state[0] = physw_status[0];
192        kbd_new_state[1] = physw_status[1];
193        kbd_new_state[2] = physw_status[2];
194
195        while (physw_run){
196                _SleepTask(10);
197                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
198                        _kbd_p2_f();
199                }
200    }
201}
202
203
204void __attribute__((naked,noinline))
205mykbd_task(long ua, long ub, long uc, long ud, long ue, long uf)
206{
207        mykbd_task_proceed();
208    /* function can be modified to restore SP here...
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                "B       _kbd_p1_f_cont\n"
221    );
222 return 0; // shut up the compiler
223}
224
225
226volatile int kbd_KEY_RING_FUNC;
227
228void my_kbd_read_keys()
229{
230        static long i=0;
231
232        kbd_prev_state[0] = kbd_new_state[0];
233        kbd_prev_state[1] = kbd_new_state[1];
234        kbd_prev_state[2] = kbd_new_state[2];
235
236        _GetKbdState(kbd_new_state);
237kbd_KEY_RING_FUNC = !(kbd_new_state[2]&0x4000);
238
239
240        if (kbd_process() == 0) {
241                // leave it alone...
242                physw_status[0] = kbd_new_state[0];
243                physw_status[1] = kbd_new_state[1];
244                physw_status[2] = kbd_new_state[2];
245                //physw_status[0] |= alt_mode_key_mask;
246                jogdial_stopped=0;
247        }
248        else {
249                // override keys
250                physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
251                physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
252                physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
253                if (!jogdial_stopped && !state_kbd_script_run) {
254                        jogdial_stopped=1;
255                        get_jogdial_direction();
256                }
257                else if (jogdial_stopped && state_kbd_script_run)
258                        jogdial_stopped=0;
259        }
260
261        _kbd_read_keys_r2(physw_status);
262
263        remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
264
265
266// hack to ignore battery door state
267//physw_status[2] |= 0x8000;
268
269        if (remote_key)
270                remote_count += 1;
271        else if (remote_count) {
272                usb_power = remote_count;
273                remote_count = 0;
274        }
275
276        if (conf.remote_enable)
277                physw_status[2] = physw_status[2] & ~(SD_READONLY_FLAG | USB_MASK);
278        else
279                physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
280}
281
282
283int get_usb_power(int edge)
284{
285        int x;
286
287        if (edge) return remote_key;
288        x = usb_power;
289        usb_power = 0;
290        return x;
291}
292
293
294void kbd_set_alt_mode_key_mask(long key)
295{
296    int i;
297    for (i=0; keymap[i].hackkey; ++i) {
298        if (keymap[i].hackkey == key) {
299            alt_mode_key_mask = keymap[i].canonkey;
300            alt_mode_key_reg  = keymap[i].grp;
301            return;
302        }
303    }
304}
305
306
307void kbd_key_press(long key)
308{
309    int i;
310    for (i=0;keymap[i].hackkey;i++){
311        if (keymap[i].hackkey == key){
312            kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
313            return;
314        }
315    }
316}
317
318
319void kbd_key_release(long key)
320{
321    int i;
322    for (i=0;keymap[i].hackkey;i++){
323        if (keymap[i].hackkey == key){
324            kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
325            return;
326        }
327    }
328}
329
330void kbd_key_release_all()
331{
332  kbd_mod_state[0] |= KEYS_MASK0;
333  kbd_mod_state[1] |= KEYS_MASK1;
334  kbd_mod_state[2] |= KEYS_MASK2;
335}
336
337long kbd_is_key_pressed(long key)
338{
339    int i;
340    for (i=0;keymap[i].hackkey;i++){
341        if (keymap[i].hackkey == key){
342            return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
343        }
344    }
345    return 0;
346}
347
348long kbd_is_key_clicked(long key)
349{
350                int i;
351                for (i=0;keymap[i].hackkey;i++){
352                if (keymap[i].hackkey == key){
353                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
354                                ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
355                }
356                }
357                return 0;
358}
359
360long kbd_get_pressed_key()
361{
362    int i;
363    for (i=0;keymap[i].hackkey;i++){
364        if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
365            return keymap[i].hackkey;
366        }
367    }
368    return 0;
369}
370
371long kbd_get_clicked_key()
372{
373    int i;
374    for (i=0;keymap[i].hackkey;i++){
375        if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
376            ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
377            return keymap[i].hackkey;
378        }
379    }
380    return 0;
381}
382
383void kbd_reset_autoclicked_key() {
384    last_kbd_key = 0;
385}
386
387long kbd_get_autoclicked_key() {
388    static long last_kbd_time = 0, press_count = 0;
389    register long key, t;
390
391    key=kbd_get_clicked_key();
392    if (key) {
393        last_kbd_key = key;
394        press_count = 0;
395        last_kbd_time = get_tick_count();
396        return key;
397    } else {
398        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
399            t = get_tick_count();
400            if (t-last_kbd_time>((press_count)?175:500)) {
401                ++press_count;
402                last_kbd_time = t;
403                return last_kbd_key;
404            } else {
405                return 0;
406            }
407        } else {
408            last_kbd_key = 0;
409            return 0;
410        }
411    }
412}
413
414
415long kbd_use_zoom_as_mf() {
416        return 0;
417}
418
419
420int Get_JogDial(void) {
421        return (*(int*) 0xC0240104) >> 16;                                              // 0xc4000000 - 0x03dc0000 + 0x104   s95 100e @FF865C7C
422}
423
424
425long get_jogdial_direction(void) {
426        static int new_jogdial = 0;
427        int old_jogdial = 0;
428
429        old_jogdial = new_jogdial;
430        new_jogdial = Get_JogDial();
431
432        if (old_jogdial < new_jogdial)
433                return JOGDIAL_RIGHT;
434        else if (old_jogdial > new_jogdial)
435                return JOGDIAL_LEFT;
436        else
437                return 0;
438}
Note: See TracBrowser for help on using the repository browser.