7
7
8
8
#include "kbd.h"
9
9
10
+ static long kbd_status = 0 ;
11
+ static long kbd_mod_prev_1 = 0xffffffff ;
12
+
13
+ ssymkeys symkeys [] = {
14
+ { 0x00020000 , 0 , 0x9a1 , 0x9a2 }, // KEY_SHOOT_HALF
15
+ { 0x00040000 , 0 , 0x9a3 , 0x9a4 }, // KEY_SHOOT_FULL_ONLY
16
+ { 0 , 0 , 0 , 0 } };
17
+
10
18
// use by kbd_common
11
19
long kbd_new_state [3 ] = { 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF };
12
20
long kbd_prev_state [3 ] = { 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF };
13
21
long kbd_mod_state [3 ] = { 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF };
14
22
15
- KeyMap keymap [] = {
16
- { 0 , KEY_PLAYBACK , 0x00000002 }, // Found @0xe05e4cdc, levent 0x101 (uses inverted logic in physw_status)
23
+ KeyMap keymap [] = { { 0 , KEY_PLAYBACK , 0x00000002 }, // Found @0xe05e4cdc, levent 0x101 (uses inverted logic in physw_status)
17
24
{ 0 , KEY_WIFI , 0x00000004 }, // Found @0xe05e4ce4, levent 0x103 (uses inverted logic in physw_status)
18
25
{ 1 , KEY_MENU , 0x00000080 }, // Found @0xe05e4d1c, levent 0x15
19
26
{ 1 , KEY_UP , 0x00000100 }, // Found @0xe05e4d24, levent 0x06
@@ -23,8 +30,7 @@ KeyMap keymap[] = {
23
30
{ 1 , KEY_SET , 0x00001000 }, // Found @0xe05e4d44, levent 0x0a
24
31
{ 1 , KEY_ERASE , 0x00008000 }, // Found @0xe05e4d5c, levent 0x0b
25
32
{ 2 , KEY_VIDEO , 0x00002000 }, // Found @0xe05e4db4, levent 0x02
26
- { 0 , 0 , 0 }
27
- };
33
+ { 0 , 0 , 0 } };
28
34
29
35
/**
30
36
* @header usb_remote.h
@@ -43,3 +49,96 @@ void kbd_fetch_data(long *dst) {
43
49
_GetKbdState (dst );
44
50
_kbd_read_keys_r2 (dst );
45
51
}
52
+
53
+ void my_kbd_read_keys () {
54
+ kbd_prev_state [0 ] = kbd_new_state [0 ];
55
+ kbd_prev_state [1 ] = kbd_new_state [1 ];
56
+ kbd_prev_state [2 ] = kbd_new_state [2 ];
57
+
58
+ // note assumed kbd_pwr_on has been called if needed
59
+ kbd_fetch_data (physw_status ); // has to be physw_status
60
+
61
+ kbd_new_state [0 ] = physw_status [0 ] ^ KEYS_INV0 ; // invert button(s) for CHDK use
62
+ kbd_new_state [1 ] = physw_status [1 ];
63
+ kbd_new_state [2 ] = physw_status [2 ];
64
+
65
+ static long kbd_status_prev = 0 ;
66
+ kbd_status = kbd_process ();
67
+
68
+ if (kbd_status == 0 ) {
69
+ // handle sw1 and sw2
70
+ if (kbd_status_prev != 0 ) {
71
+ int n = 0 ;
72
+ while (symkeys [n ].bit ) {
73
+ if (symkeys [n ].chdkstate ) {
74
+ PostLogicalEventToUI (symkeys [n ].unpresse , 0 );
75
+ symkeys [n ].chdkstate = 0 ;
76
+ }
77
+ n ++ ;
78
+ }
79
+ _post_msg_3_to_physw_releasesw ();
80
+ }
81
+
82
+ } else { // override keys
83
+ // invert button(s) before writing back to physw_status
84
+ physw_status [0 ] = ((kbd_new_state [0 ] & (~KEYS_MASK0 ))
85
+ | (kbd_mod_state [0 ] & KEYS_MASK0 )) ^ KEYS_INV0 ;
86
+
87
+ physw_status [1 ] = (kbd_new_state [1 ] & (~KEYS_MASK1 ))
88
+ | (kbd_mod_state [1 ] & KEYS_MASK1 );
89
+
90
+ physw_status [2 ] = (kbd_new_state [2 ] & (~KEYS_MASK2 ))
91
+ | (kbd_mod_state [2 ] & KEYS_MASK2 );
92
+
93
+ // handle sw1 and sw2 from kbd_mod_state, emit events
94
+ // TODO: event order won't necessarily match a real hw sequence (shoot_half might be released sooner than shoot_full and so on)
95
+ int n = 0 ;
96
+ while (symkeys [n ].bit ) {
97
+ long bit = symkeys [n ].bit ;
98
+ if ((kbd_mod_state [1 ] & bit ) < (kbd_mod_prev_1 & bit )) {
99
+ PostLogicalEventToUI (symkeys [n ].presse , 0 );
100
+ symkeys [n ].chdkstate = 1 ;
101
+ } else if ((kbd_mod_state [1 ] & bit ) > (kbd_mod_prev_1 & bit )) {
102
+ PostLogicalEventToUI (symkeys [n ].unpresse , 0 );
103
+ symkeys [n ].chdkstate = 0 ;
104
+ }
105
+ n ++ ;
106
+ }
107
+ kbd_mod_prev_1 = kbd_mod_state [1 ];
108
+ }
109
+ kbd_status_prev = kbd_status ;
110
+
111
+ // USB and SD read-only are standard
112
+ kbd_update_physw_bits ();
113
+ }
114
+
115
+ long __attribute__((naked ,noinline )) wrap_kbd_p1_f () {
116
+ asm volatile (
117
+ "push {r1-r7, lr}\n"
118
+ "movs r4, #0\n"
119
+ "bl my_kbd_read_keys\n"
120
+ "b _kbd_p1_f_cont\n"
121
+ );
122
+
123
+ return 0 ;
124
+ }
125
+
126
+ /**
127
+ * @header lolevel.h
128
+ */
129
+ void __attribute__((naked ,noinline )) mykbd_task () {
130
+ // initialize our own kbd_new_state[] array with the current physical status
131
+ kbd_new_state [0 ] = physw_status [0 ] ^ KEYS_INV0 ;
132
+ kbd_new_state [1 ] = physw_status [1 ];
133
+ kbd_new_state [2 ] = physw_status [2 ];
134
+
135
+ while (physw_run ) {
136
+ _SleepTask (physw_sleep_delay );
137
+
138
+ if (wrap_kbd_p1_f () == 1 ) {
139
+ _kbd_p2_f ();
140
+ }
141
+ }
142
+
143
+ _ExitTask ();
144
+ }
0 commit comments