source: branches/release-1_0/platform/a2100/kbd.c @ 1726

Revision 1726, 10.6 KB checked in by philmoz, 15 months ago (diff)

A800 1.00c & A2100 1.00a added (patches from waterwingz)
http://chdk.setepontos.com/index.php?topic=650.msg82671#msg82671
http://chdk.setepontos.com/index.php?topic=650.msg82692#msg82692

  • 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
13
14long kbd_new_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
15static long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
16static long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
17
18static KeyMap keymap[];
19static long last_kbd_key = 0;
20static int usb_power=0;
21static int remote_key, remote_count;
22static int shoot_counter=0;
23#define DELAY_TIMEOUT 10000
24
25#define SD_READONLY_FLAG    0x00020000 // Found @0xffe7172c, levent 0x90a
26#define SD_READONLY_IDX     2
27#define USB_MASK            0x00040000 // Found @0xffe71738, levent 0x902
28#define USB_IDX             2
29
30// changed for A2100IS
31#define LED_PWR 0xC0220014      // A2100IS Green - power led
32#define LED_DP 0xC0220018               // A2100IS Blue - Direct Print led
33#define LED_AF 0xC022000C               // A2100IS Red - AutoFocus led
34#define DELAY 5000000
35
36#define KEYS_MASK0 (0x00000000)
37#define KEYS_MASK1 (0x1F000000)
38#define KEYS_MASK2 (0xF3C)
39
40static KeyMap keymap[] = {
41   { 1, KEY_SET             ,0x01000000 }, // Found @0xffe71624, levent 0x08 0x1010238, 8, 1,
42   { 1, KEY_MENU            ,0x02000000 }, // Found @0xffe71630, levent 0x09
43   { 1, KEY_DISPLAY         ,0x04000000 }, // Found @0xffe7163c, levent 0x0a 0x101023A, 0xA, 1
44   { 1, KEY_PRINT           ,0x08000000 }, // Found manually
45   { 1, KEY_FACE            ,0x10000000 }, // Found manually
46   { 2, KEY_ZOOM_IN         ,0x00000010 }, // Found @0xffe716b4, levent 0x02
47   { 2, KEY_ZOOM_OUT        ,0x00000020 }, // Found @0xffe716c0, levent 0x03 0x1010245, 3, 1
48   { 2, KEY_UP              ,0x00000100 }, // Found @0xffe716e4, levent 0x04 0x1010248, 4, 1,
49   { 2, KEY_DOWN            ,0x00000200 }, // Found @0xffe716f0, levent 0x05 0x1010249, 5, 1
50   { 2, KEY_RIGHT           ,0x00000400 }, // Found @0xffe716fc, levent 0x07
51   { 2, KEY_LEFT            ,0x00000800 }, // Found @0xffe71708, levent 0x06
52   { 2, KEY_SHOOT_FULL      ,0x0000000c }, // Found @0xffe716a8, levent 0x01
53   { 2, KEY_SHOOT_FULL_ONLY ,0x00000008 }, // Found @0xffe716a8, levent 0x01
54   { 2, KEY_SHOOT_HALF      ,0x00000004 }, // Found @0xffe7169c, levent 0x00
55   { 0, 0, 0 }
56};
57
58void kbd_fetch_data(long*);
59
60long __attribute__((naked)) wrap_kbd_p1_f() ;
61
62void wait_until_remote_button_is_released(void)
63{
64int count1;
65int count2;
66int tick,tick2,tick3;
67int nSW;
68int prev_usb_power,cur_usb_power;
69
70 // ------ add by Masuji SUTO (start) --------------
71    static int nMode;
72 // ------ add by Masuji SUTO (end)   --------------
73
74asm volatile ("STMFD SP!, {R0-R11,LR}\n"); // store R0-R11 and LR in stack
75
76debug_led(1);
77tick = get_tick_count();
78tick2 = tick;
79static long usb_physw[3];
80if (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)))                                     
81// if (conf.synch_enable && conf.ricoh_ca1_mode && conf.remote_enable)                                         // synch mode enable so wait for USB to disconnect
82  {
83// ------ add by Masuji SUTO (start) --------------
84        nMode=0;
85        usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
86        _kbd_read_keys_r2(usb_physw);
87        if((usb_physw[2] & USB_MASK)==USB_MASK) nMode=1;
88// ------ add by Masuji SUTO (end)   --------------
89
90if(conf.ricoh_ca1_mode && conf.remote_enable)
91{
92        if(shooting_get_drive_mode() ==1 && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING){                   //continuous-shooting mode
93                if(conf.bracket_type>2){
94                        if(shoot_counter<2) shutter_int=3;
95                        shoot_counter--;
96                        }
97                else{   
98                prev_usb_power=0;
99                nSW = 0;
100                do
101                        {     
102            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
103           _kbd_read_keys_r2(usb_physw);
104                        cur_usb_power = (usb_physw[2] & USB_MASK)==USB_MASK;
105                        if(cur_usb_power){
106                                if(!prev_usb_power){
107                                        tick2 = get_tick_count();
108                                        prev_usb_power=cur_usb_power;
109                                        }
110                                else{
111                                        if((int)get_tick_count()-tick2>1000) {debug_led(0);}
112                                        }
113                                }
114                        else{
115                                if(prev_usb_power){
116                                        tick3 = (int)get_tick_count()-tick2;
117                                        if(nSW==10) {
118                                                if(tick3>50) shutter_int=1;
119                                                nSW=20;
120                                                }
121                                        if(nSW==0 && tick3>0) {
122                                                if(tick3<50) {
123                                                nSW=10;
124                                                }
125                                        else{
126                                                if(tick3>1000) shutter_int=1;
127                                                        nSW=20;
128                                                }
129                                        }
130                                        prev_usb_power=cur_usb_power;
131                                        }
132                                }
133                                               
134                        if((int)get_tick_count()-tick >= DELAY_TIMEOUT) {nSW=20;shutter_int=2;}
135                        }
136                 while(nSW<20);
137                 }
138                }               //continuous-shooting mode
139        else{           // normal mode
140                        shoot_counter=0;
141                        if(conf.bracket_type>2){
142                                shoot_counter=(conf.bracket_type-2)*2;
143                                }
144   do
145         {     
146            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
147           _kbd_read_keys_r2(usb_physw);
148           }
149 //  while(((usb_physw[2] & USB_MASK)==USB_MASK) && ((int)get_tick_count()-tick < DELAY_TIMEOUT));
150// ------ modif by Masuji SUTO (start) --------------
151        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));
152// ------ modif by Masuji SUTO (end)   --------------
153        }
154 }
155
156else
157   {
158
159      do
160          {
161            usb_physw[2] = 0;                                             // makes sure USB bit is cleared.
162           _kbd_read_keys_r2(usb_physw);
163             
164           }
165        while((usb_physw[2]&USB_MASK) &&  ((int)get_tick_count()-tick < DELAY_TIMEOUT));
166    }
167
168  }
169
170if (conf.synch_delay_enable && conf.synch_delay_value>0)                                // if delay is switched on and greater than 0
171  {
172    for (count1=0;count1<conf.synch_delay_value+(conf.synch_delay_coarse_value*1000);count1++) // wait delay_value * 0.1ms
173    {
174      for (count2=0;count2<1400;count2++)            // delay approx. 0.1ms
175        {
176        }
177     }
178  }
179
180debug_led(0);
181asm volatile ("LDMFD SP!, {R0-R11,LR}\n"); // restore R0-R11 and LR from stack
182}
183
184static void __attribute__((noinline)) mykbd_task_proceed()
185{
186        while (physw_run){
187                _SleepTask(10);
188
189                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
190                        _kbd_p2_f();
191                }
192        }
193}
194
195// no stack manipulation needed here, since we create the task directly
196void __attribute__((naked,noinline)) mykbd_task() {
197
198     mykbd_task_proceed();
199
200    _ExitTask();
201}
202
203long __attribute__((naked,noinline)) wrap_kbd_p1_f() {
204        asm volatile(
205                "STMFD   SP!, {R1-R5,LR}\n"
206                "MOV     R4, #0\n"
207        //      "BL      _kbd_read_keys \n"
208                "BL             my_kbd_read_keys\n" // replaced temporary
209                "B       _kbd_p1_f_cont\n"
210        );
211        return 0; // shut up the compiler
212}
213
214volatile int jogdial_stopped=0;
215
216void kbd_fetch_data(long *dst){
217    volatile long *mmio0 = (void*)0xc0220200;
218    volatile long *mmio1 = (void*)0xc0220204;
219    volatile long *mmio2 = (void*)0xc0220208;
220
221    dst[0] = *mmio0;
222    dst[1] = *mmio1;// | 0x7EF02000;
223    dst[2] = *mmio2;// | 0xf32;
224//  dst[2] = *mmio2;
225}
226
227void my_kbd_read_keys() {
228       
229        kbd_prev_state[0] = kbd_new_state[0];
230        kbd_prev_state[1] = kbd_new_state[1];
231        kbd_prev_state[2] = kbd_new_state[2];
232
233        _kbd_pwr_on();  // i.e. kbd_pwr_on      ROM:FFC11A28                 BL      _sub_FFC30B94__PhySwGpio.c__0 ; LOCATION: PhySwGpio.c:0
234       
235        // _GetKbdState(kbd_new_state); //empty without it
236        kbd_fetch_data(kbd_new_state);
237       
238        _kbd_read_keys_r2(kbd_new_state); // without this PS3 is almost empty: PS3: 0x400c
239       
240        if (kbd_process() == 0){
241        // leave it alone... pass key strokes to the camera
242
243                  physw_status[0] = kbd_new_state[0];
244          physw_status[1] = kbd_new_state[1];
245          physw_status[2] = kbd_new_state[2];
246
247        } else {
248                // override keys .. don't let them get to the camera or override them as on to trick the camera
249               
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
254        }
255       
256    remote_key = (physw_status[2] & USB_MASK)==USB_MASK;
257    if (remote_key)  remote_count += 1;
258    else if (remote_count) {
259        usb_power = remote_count;
260        remote_count = 0;
261    }
262
263        if (conf.remote_enable) {
264                physw_status[USB_IDX] = physw_status[USB_IDX] & ~(SD_READONLY_FLAG | USB_MASK);
265        } else {
266                physw_status[USB_IDX] = physw_status[USB_IDX] & ~SD_READONLY_FLAG;
267        }
268
269}
270
271/*
272void kbd_set_alt_mode_key_mask(long key)
273{
274        int i;
275        for (i=0; keymap[i].hackkey; ++i) {
276                if (keymap[i].hackkey == key) {
277                        alt_mode_key_mask = keymap[i].canonkey;
278                        return;
279                }
280        }
281}
282*/
283
284void kbd_key_press(long key)
285{
286        int i;
287
288        for (i=0;keymap[i].hackkey;i++){
289                if (keymap[i].hackkey == key)
290                {
291                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
292                        return;
293                }
294        }
295}
296
297void kbd_key_release(long key)
298{
299        int i;
300        for (i=0;keymap[i].hackkey;i++){
301                if (keymap[i].hackkey == key){
302                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
303                        return;
304                }
305        }
306}
307
308void kbd_key_release_all()
309{
310        kbd_mod_state[0] |= KEYS_MASK0;
311        kbd_mod_state[1] |= KEYS_MASK1;
312        kbd_mod_state[2] |= KEYS_MASK2;
313}
314
315long kbd_is_key_pressed(long key)
316{
317        int i;
318        for (i=0;keymap[i].hackkey;i++){
319                if (keymap[i].hackkey == key){
320                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
321                }
322        }
323        return 0;
324}
325
326long kbd_is_key_clicked(long key)
327{
328        int i;
329        for (i=0;keymap[i].hackkey;i++){
330                if (keymap[i].hackkey == key){
331                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
332                               ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
333                }
334        }
335        return 0;
336}
337
338long kbd_get_pressed_key()
339{
340        int i;
341        for (i=0;keymap[i].hackkey;i++){
342                if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
343                        return keymap[i].hackkey;
344                }
345        }
346        return 0;
347}
348
349long kbd_get_clicked_key()
350{
351        int i;
352        for (i=0;keymap[i].hackkey;i++){
353                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
354                    ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
355                        return keymap[i].hackkey;
356                }
357        }
358        return 0;
359}
360
361void kbd_reset_autoclicked_key() {
362        last_kbd_key = 0;
363}
364
365long kbd_get_autoclicked_key() {
366        static long last_kbd_time = 0, press_count = 0;
367        register long key, t;
368
369        key=kbd_get_clicked_key();
370        if (key) {
371                last_kbd_key = key;
372                press_count = 0;
373                last_kbd_time = get_tick_count();
374                return key;
375        } else {
376                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
377                        t = get_tick_count();
378                        if (t-last_kbd_time>((press_count)?175:500)) {
379                                ++press_count;
380                                last_kbd_time = t;
381                                return last_kbd_key;
382                        } else {
383                                return 0;
384                        }
385                } else {
386                        last_kbd_key = 0;
387                        return 0;
388                }
389        }
390}
391
392int get_usb_power(int edge)
393{
394        int x;
395
396        if (edge) return remote_key;
397        x = usb_power;
398        usb_power = 0;
399        return x;
400}
Note: See TracBrowser for help on using the repository browser.