source: trunk/platform/a800/kbd.c @ 1723

Revision 1723, 7.2 KB checked in by reyalp, 16 months ago (diff)

a800 100a port from mland, patch by waterwings in http://chdk.setepontos.com/index.php?topic=650.msg81174#msg81174

  • 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
14#define DELAY_TIMEOUT 10000
15
16#define KEYS_MASK0 (0x00020000)
17#define KEYS_MASK1 (0x00000000)
18#define KEYS_MASK2 (0x2E0003f0)
19#define KEYS_INV2  (0x2E000000) //higher  1=pressed (MENU,UP,DOWN,LEFT) =>INTRODUCED
20/*
21the 4 button states residing in the upper half of physw_status[2] seem to be inverted
22to handle these correctly, their value needs to be inverted:
23- when reading from physw_status[2] to the state variables
24- when writing to physw_status[2] from the state variables
25KEYS_INV2 should be used for that
26SD_READONLY_FLAG and USB_MASK are not affected by this
27 
28when idle, physw_status[2] looks like: ""
29                         KEYS_MASK2 is "00101110000000000000001111110000"
30*/
31
32static long kbd_new_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
33static long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
34static long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
35
36static long last_kbd_key = 0;
37static int usb_power=0;
38static int remote_key, remote_count;
39static int shoot_counter=0;
40extern void _platformsub_kbd_fetch_data(long*);
41
42//Original #define SD_READONLY_FLAG (0x40000)
43//Original #define USB_MASK (0x80000)
44//Original #define USB_REG 2
45#define SD_READONLY_FLAG    0x00020000 // Found @0xffe9db68, levent 0x90a
46#define SD_READONLY_IDX     2
47#define USB_MASK            0x01000000 // Found @0xffe9db88, levent 0x902
48#define USB_IDX             2
49
50extern void usb_remote_key( int ) ;
51int get_usb_bit()
52{
53        long usb_physw[3];
54        usb_physw[USB_IDX] = 0;
55        _kbd_read_keys_r2(usb_physw);
56        return(( usb_physw[USB_IDX] & USB_MASK)==USB_MASK) ;
57}
58
59// Keymap values for kbd.c. Additional keys may be present, only common values included here.
60static KeyMap keymap[] = {
61    { 0, KEY_PRINT           ,0x00020000 }, // Playback => ALT Mode
62    { 2, KEY_ZOOM_OUT        ,0x00000040 }, // Found @0xffe9db40, levent 0x03
63    { 2, KEY_ZOOM_IN         ,0x00000080 }, // Found @0xffe9db48, levent 0x02
64    { 2, KEY_SET             ,0x00000100 }, // Found @0xffe9db50, levent 0x08
65    { 2, KEY_RIGHT           ,0x00000200 }, // Found @0xffe9db58, levent 0x07
66    { 2, KEY_UP              ,0x02000000 }, // Found @0xffe9db90, levent 0x04
67    { 2, KEY_DOWN            ,0x04000000 }, // Found @0xffe9db98, levent 0x05
68    { 2, KEY_LEFT            ,0x08000000 }, // Found @0xffe9dba0, levent 0x06
69    { 2, KEY_MENU            ,0x20000000 }, // Found @0xffe9dbb0, levent 0x09
70    { 2, KEY_SHOOT_FULL      ,0x00000030 }, // Found @0xffe9db38, levent 0x01
71    { 2, KEY_SHOOT_FULL_ONLY ,0x00000020 }, // Found @0xffe9db38, levent 0x01
72    { 2, KEY_SHOOT_HALF      ,0x00000010 }, // Found @0xffe9db30, levent 0x00
73//    { 2, KEY_MODE            ,0x10000000 }, // OSD
74    { 0, 0, 0 }
75};
76
77
78long __attribute__((naked)) wrap_kbd_p1_f() ;
79
80
81static void __attribute__((noinline)) mykbd_task_proceed()
82{
83        /* Initialize our own kbd_new_state[] array with the
84           current physical status. (inspired by the S90 port)
85           */
86        kbd_new_state[0] = physw_status[0];
87        kbd_new_state[1] = physw_status[1];
88        kbd_new_state[2] = physw_status[2] ^ KEYS_INV2;
89        while (physw_run){
90                _SleepTask(10);
91                if (wrap_kbd_p1_f() == 1){ // autorepeat ?
92                        _kbd_p2_f();
93                }
94        }
95}
96
97void __attribute__((naked,noinline)) mykbd_task()
98{
99        mykbd_task_proceed();
100        _ExitTask();
101}
102
103
104long __attribute__((naked,noinline)) wrap_kbd_p1_f()
105{
106        asm volatile(
107                        "STMFD   SP!, {R1-R7,LR}\n"     // anterior "STMFD   SP!, {R1-R7,LR}\n"
108                        "MOV     R5, #0\n" // anterior "MOV     R4, #0\n"
109                        //"BL      _kbd_read_keys\n"       // replaces kbd_fetch_data()
110                        "BL      my_kbd_read_keys\n"     // +
111                        "B       _kbd_p1_f_cont\n"       // continue
112        );
113       
114        return 0; // shut up the compiler
115}
116
117
118void my_kbd_read_keys()
119{
120        // If script are running, replace PRINT button with DISPLAY
121        if (state_kbd_script_run) {
122                int i;
123                for (i=0; keymap[i].hackkey; i++) {
124                        if (keymap[i].hackkey == KEY_PRINT) {
125                                keymap[i].hackkey = KEY_DISPLAY;
126                                break;
127                        }
128                }
129        } else {
130                int i;
131                for (i=0; keymap[i].hackkey; i++) {
132                        if (keymap[i].hackkey == KEY_DISPLAY) {
133                                keymap[i].hackkey = KEY_PRINT;
134                                break;
135                        }
136                }
137        }
138       
139        kbd_prev_state[0] = kbd_new_state[0];
140        //kbd_prev_state[1] = kbd_new_state[1];
141        kbd_prev_state[2] = kbd_new_state[2];
142       
143        asm volatile(
144        "BL      _kbd_read_keys\n"
145        );
146       
147        //_platformsub_kbd_fetch_data(kbd_new_state);
148        kbd_new_state[0] = physw_status[0];
149        kbd_new_state[1] = physw_status[1];
150        kbd_new_state[2] = physw_status[2] ^ KEYS_INV2;
151
152        if (kbd_process() == 0){//core\kbd.c =>pode simular outras teclas (kbd_key_press/release)
153                // leave it alone...
154        } else {
155        // override keys
156        physw_status[0] = (kbd_new_state[0] | KEYS_MASK0) & (~KEYS_MASK0 | kbd_mod_state[0]);
157        //physw_status[1] = (kbd_new_state[1] | KEYS_MASK1) & (~KEYS_MASK1 | kbd_mod_state[1]);
158        physw_status[2] = ((kbd_new_state[2] | KEYS_MASK2) & (~KEYS_MASK2 | kbd_mod_state[2])) ^ KEYS_INV2;
159        }
160       
161        //_kbd_read_keys_r2(physw_status);
162
163        usb_remote_key(physw_status[USB_IDX]) ;
164       
165        if (conf.remote_enable) {
166                physw_status[USB_IDX] = physw_status[USB_IDX] & ~(SD_READONLY_FLAG | USB_MASK);
167        } else {
168                physw_status[USB_IDX] = physw_status[USB_IDX] & ~SD_READONLY_FLAG;
169        }
170}
171
172
173
174/****************/
175
176void kbd_key_press(long key)
177{
178        int i;
179        for (i=0;keymap[i].hackkey;i++){
180                if (keymap[i].hackkey == key){
181                        kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
182                        return;
183                }
184        }
185}
186
187void kbd_key_release(long key)
188{
189        int i;
190        for (i=0;keymap[i].hackkey;i++){
191                if (keymap[i].hackkey == key){
192                        kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
193                        return;
194                }
195        }
196}
197
198void kbd_key_release_all()
199{
200        kbd_mod_state[0] |= KEYS_MASK0;
201        kbd_mod_state[1] |= KEYS_MASK1;
202        kbd_mod_state[2] |= KEYS_MASK2;
203}
204
205long kbd_is_key_pressed(long key)
206{
207        int i;
208        for (i=0;keymap[i].hackkey;i++){
209                if (keymap[i].hackkey == key){
210                        return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
211                }
212        }
213        return 0;
214}
215
216long kbd_is_key_clicked(long key)
217{
218        int i;
219        for (i=0;keymap[i].hackkey;i++){
220                if (keymap[i].hackkey == key){
221                        return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
222                                   ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
223                }
224        }
225        return 0;
226}
227
228long kbd_get_pressed_key()
229{
230        int i;
231        for (i=0;keymap[i].hackkey;i++){
232                if (kbd_is_key_pressed(keymap[i].hackkey)) {
233                        return keymap[i].hackkey;
234                }
235        }
236        return 0;
237}
238
239long kbd_get_clicked_key()
240{
241        int i;
242        for (i=0;keymap[i].hackkey;i++){
243                if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
244                        ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)) {
245                        return keymap[i].hackkey;
246                }
247        }
248        return 0;
249}
250
251
252void kbd_reset_autoclicked_key() {
253        last_kbd_key = 0;
254}
255
256long kbd_get_autoclicked_key() {
257        static long last_kbd_time = 0, press_count = 0;
258        register long key, t;
259       
260        key=kbd_get_clicked_key();
261        if (key) {
262                last_kbd_key = key;
263                press_count = 0;
264                last_kbd_time = get_tick_count();
265                return key;
266        } else {
267                if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
268                        t = get_tick_count();
269                        if (t-last_kbd_time>((press_count)?175:500)) {
270                                ++press_count;
271                                last_kbd_time = t;
272                                return last_kbd_key;
273                        } else {
274                                return 0;
275                        }
276                } else {
277                        last_kbd_key = 0;
278                        return 0;
279                }
280        }
281}
282
283
284long kbd_use_zoom_as_mf() {
285        return 0;
286}
Note: See TracBrowser for help on using the repository browser.