root/core/kbd_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kbd_update_key_state
  2. kbd_update_physw_bits
  3. get_usb_bit
  4. kbd_key_press
  5. kbd_key_release
  6. kbd_key_release_all
  7. kbd_is_key_pressed
  8. kbd_is_key_clicked
  9. kbd_get_pressed_key
  10. kbd_get_clicked_key
  11. kbd_use_zoom_as_mf
  12. kbd_use_zoom_as_mf

   1 /*
   2 common low level keyboard handling functions
   3 
   4 WARNING:
   5 If you change code here, be sure to grep platform_kbd.h files for
   6 KBD_CUSTOM_ and make sure that the cameras special platform specific
   7 requirements are updated if required.
   8 
   9 platform_kbd.h defines
  10 ** controls for kbd.c implementation
  11 * this camera has a totally custom keyboard code, don't build common code
  12 KBD_CUSTOM_ALL
  13 
  14 * non-standard key state update
  15 KBD_CUSTOM_UPDATE_KEY_STATE
  16 
  17 * non-standard manipulation of other physw bits (SD readonly, USB etc)
  18 KBD_CUSTOM_UPDATE_PHYSW_BITS
  19 
  20 
  21 * use logical event to simulate "video" button from script
  22 * for touchscreen cameras without a physical video button
  23 KBD_SIMULATE_VIDEO_KEY
  24 
  25 * For cams without an SD card lock (micro-SD)
  26 KBD_SKIP_READONLY_BIT
  27 
  28 * Cameras that have an MF key and enable ZOOM_FOR_MF detect mf presses and use MF key
  29 KBD_ZOOM_FOR_MF_USE_MF_KEY
  30 
  31 ** defines for hardware bits etc
  32 
  33 * key masks - for keys used by CHDK in alt mode
  34 * bitwise OR of all keymap canon key values
  35 KEYS_MASK0
  36 KEYS_MASK1
  37 KEYS_MASK2
  38 
  39 ** SD card read only bit
  40 SD_READONLY_FLAG
  41 ** physw_status index for readonly bit
  42 SD_READONLY_IDX
  43 
  44 ** USB +5v bit
  45 USB_MASK
  46 ** physw_status index for USB bit
  47 USB_IDX
  48 
  49 ** get_usb_bit should use the following MMIO directly.
  50 ** Otherwise, platform must implement get_usb_bit()
  51 USB_MMIO
  52 
  53 ** battery cover override - requires additional supporting code
  54 BATTCOVER_IDX
  55 BATTCOVER_FLAG 
  56 
  57 * override SD card door for cameras micro-sd cams that use it for autoboot
  58 SD_DOOR_OVERRIDE 1
  59 * bit for SD door
  60 SD_DOOR_FLAG
  61 * physw_status index for SD door
  62 SD_DOOR_IDX
  63 
  64 * HDMI Hot Plug Detect bit (0 = hotplug detected)
  65 HDMI_HPD_FLAG
  66 * HDMI Hot Plug Detect index
  67 HDMI_HPD_IDX
  68 
  69 * Analog AV present bit (0 = present)
  70 ANALOG_AV_FLAG
  71 * Analog AV present index
  72 ANALOG_AV_IDX
  73 
  74 */
  75 #include "platform.h"
  76 #include "core.h"
  77 #include "keyboard.h"
  78 #include "kbd_common.h"
  79 #include "conf.h"
  80 #include "usb_remote.h"
  81 
  82 // for KBD_SIMULATE_VIDEO_KEY
  83 #include "levent.h"
  84 
  85 // if KBD_CUSTOM_ALL, platform kbd.c provides everything, this file is noop
  86 // when adding funtionality, grep KBD_CUSTOM_ALL and update accordingly
  87 #ifndef KBD_CUSTOM_ALL
  88 extern long physw_status[3];
  89 extern int forced_usb_port;
  90 
  91 #ifndef KBD_CUSTOM_UPDATE_KEY_STATE
  92 
  93 #ifdef CAM_HAS_GPS
  94 int gps_key_trap=0 ;
  95 #endif
  96 
  97 /*
  98  saves & updates key state, runs main CHDK kbd task code in kbd_process,
  99  returns kbd_process value
 100 */
 101 long kbd_update_key_state(void)
 102 {
 103     kbd_prev_state[0] = kbd_new_state[0];
 104     kbd_prev_state[1] = kbd_new_state[1];
 105     kbd_prev_state[2] = kbd_new_state[2];
 106 
 107 #ifdef CAM_TOUCHSCREEN_UI
 108     kbd_prev_state[3] = kbd_new_state[3];
 109 #endif
 110 
 111     // note assumed kbd_pwr_on has been called if needed
 112     kbd_fetch_data(kbd_new_state);
 113 
 114 #ifdef CAM_HAS_GPS
 115     if (gps_key_trap > 0)        // check if gps code is waiting for a specific key press to cancel shutdown
 116     {
 117         if (kbd_get_pressed_key() == gps_key_trap)
 118         {
 119             kbd_key_release(gps_key_trap);
 120             kbd_key_press(0);
 121             gps_key_trap = -1;  // signal the gps task that the specified button was pressed
 122             msleep(1000);       // pause to allow button release so Canon f/w does not see the press
 123         }
 124     }
 125 #endif
 126 
 127     long status = kbd_process();
 128     if (status == 0){
 129         // leave it alone...
 130         physw_status[0] = kbd_new_state[0];
 131         physw_status[1] = kbd_new_state[1];
 132         physw_status[2] = kbd_new_state[2];
 133 
 134 #ifdef CAM_HAS_JOGDIAL
 135         jogdial_control(0);
 136 #endif
 137     } else {
 138         // override keys
 139         // TODO doesn't handle inverted logic yet
 140         physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
 141 
 142         physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
 143 
 144         physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
 145 
 146 #ifdef CAM_HAS_JOGDIAL
 147         if ((jogdial_stopped==0) && !camera_info.state.state_kbd_script_run) {
 148             jogdial_control(1);
 149             get_jogdial_direction();
 150         }
 151         else if (jogdial_stopped && camera_info.state.state_kbd_script_run) {
 152             jogdial_control(0);
 153         }
 154 #endif
 155     }
 156     return status;
 157 }
 158 #endif // KBD_CUSTOM_UPDATE_KEY_STATE
 159 
 160 #ifndef KBD_CUSTOM_UPDATE_PHYSW_BITS
 161 void kbd_update_physw_bits(void)
 162 {
 163     if (conf.remote_enable) {
 164 #ifdef CAM_REMOTE_MULTICHANNEL
 165         switch(conf.remote_input_channel)
 166         {
 167             case REMOTE_INPUT_USB:
 168                 physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 169                 break;
 170             #ifdef CAM_REMOTE_HDMI_HPD
 171             case REMOTE_INPUT_HDMI_HPD:
 172                 physw_status[HDMI_HPD_IDX] |= HDMI_HPD_FLAG;
 173                 break;
 174             #endif
 175             #ifdef CAM_REMOTE_ANALOG_AV
 176             case REMOTE_INPUT_ANALOG_AV:
 177                 physw_status[ANALOG_AV_IDX] |= ANALOG_AV_FLAG;
 178                 break;
 179             #endif
 180          }
 181 #else
 182         physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 183 #endif
 184     }
 185     // TODO could save the real USB bit to avoid low level calls in get_usb_bit when immediate update not needed
 186     if (forced_usb_port) {
 187         physw_status[USB_IDX] = physw_status[USB_IDX] | USB_MASK;
 188     }
 189 // microsd cams don't have a read only bit
 190 #ifndef KBD_SKIP_READONLY_BIT
 191     physw_status[SD_READONLY_IDX] = physw_status[SD_READONLY_IDX] & ~SD_READONLY_FLAG;
 192 #endif
 193 
 194 // n and possibly other micro SD cams uses door bit for autoboot, force back to closed (?)
 195 #ifdef SD_DOOR_OVERRIDE
 196     physw_status[SD_DOOR_IDX] |= SD_DOOR_FLAG;                // override SD card door switch
 197 #endif
 198 
 199 #ifdef OPT_RUN_WITH_BATT_COVER_OPEN
 200     physw_status[BATTCOVER_IDX] = physw_status[BATTCOVER_IDX] | BATTCOVER_FLAG;
 201 #endif
 202 
 203 #ifdef CAM_HOTSHOE_OVERRIDE
 204     if (conf.hotshoe_override == 1) {
 205         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] & ~HOTSHOE_FLAG;
 206     } else if (conf.hotshoe_override == 2) {
 207         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] | HOTSHOE_FLAG;
 208     }
 209 #endif
 210 }
 211 #endif // KBD_CUSTOM_UPDATE_PHYSW_BITS
 212 
 213 // if the port reads an MMIO directly to get USB +5v status, use generic get_usb_bit
 214 // others must define in platform kbd.c
 215 #ifdef USB_MMIO
 216 int get_usb_bit() 
 217 {
 218     volatile int *mmio = (void*)USB_MMIO;
 219     return(( *mmio & USB_MASK)==USB_MASK); 
 220 }
 221 #endif
 222 
 223 #ifdef KBD_SIMULATE_VIDEO_KEY
 224 static int is_video_key_pressed = 0;
 225 #endif
 226 
 227 void kbd_key_press(long key)
 228 {
 229 #ifdef KBD_SIMULATE_VIDEO_KEY
 230     if (key == KEY_VIDEO && !is_video_key_pressed)
 231     {
 232         // TODO define for ID would be more efficient
 233         PostLogicalEventToUI(levent_id_for_name("PressMovieButton"),0);
 234         is_video_key_pressed = 1;
 235         // TODO not clear if this should return, or set state too
 236         return;
 237     }    
 238 #endif
 239     int i;
 240     for (i=0;keymap[i].hackkey;i++){
 241         if (keymap[i].hackkey == key){
 242             kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
 243             return;
 244         }
 245     }
 246 }
 247 
 248 void kbd_key_release(long key)
 249 {
 250 #ifdef KBD_SIMULATE_VIDEO_KEY
 251     if (key == KEY_VIDEO && is_video_key_pressed)
 252     {
 253         PostLogicalEventToUI(levent_id_for_name("UnpressMovieButton"),0);
 254         is_video_key_pressed = 0;
 255         return;
 256     }
 257 #endif
 258     int i;
 259     for (i=0;keymap[i].hackkey;i++){
 260         if (keymap[i].hackkey == key){
 261             kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
 262             return;
 263         }
 264     }
 265 }
 266 
 267 void kbd_key_release_all()
 268 {
 269     kbd_mod_state[0] |= KEYS_MASK0;
 270     kbd_mod_state[1] |= KEYS_MASK1;
 271     kbd_mod_state[2] |= KEYS_MASK2;
 272 // touch screen virtual keys
 273 #ifdef CAM_TOUCHSCREEN_UI
 274     kbd_mod_state[3] |= 0xFFFFFFFF;
 275 #endif
 276 }
 277 
 278 long kbd_is_key_pressed(long key)
 279 {
 280     int i;
 281     for (i=0;keymap[i].hackkey;i++){
 282         if (keymap[i].hackkey == key){
 283             return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
 284         }
 285     }
 286     return 0;
 287 }
 288 
 289 long kbd_is_key_clicked(long key)
 290 {
 291     int i;
 292     for (i=0;keymap[i].hackkey;i++){
 293         if (keymap[i].hackkey == key){
 294             return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 295                     ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
 296         }
 297     }
 298     return 0;
 299 }
 300 
 301 long kbd_get_pressed_key()
 302 {
 303     int i;
 304     for (i=0;keymap[i].hackkey;i++){
 305         if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
 306             return keymap[i].hackkey;
 307         }
 308     }
 309     return 0;
 310 }
 311 
 312 long kbd_get_clicked_key()
 313 {
 314     int i;
 315     for (i=0;keymap[i].hackkey;i++){
 316         if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 317             ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
 318             return keymap[i].hackkey;
 319         }
 320     }
 321     return 0;
 322 }
 323 
 324 #ifdef CAM_USE_ZOOM_FOR_MF
 325 // cameras with an MF use it (s2, s3, s5 etc)
 326 #ifdef KBD_ZOOM_FOR_MF_USE_MF_KEY
 327 long kbd_use_zoom_as_mf() {
 328     static long zoom_key_pressed = 0;
 329 
 330     if (kbd_is_key_pressed(KEY_ZOOM_IN) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 331         if (shooting_get_focus_mode()) {
 332             kbd_key_release_all();
 333             kbd_key_press(KEY_MF);
 334             kbd_key_press(KEY_UP);
 335             zoom_key_pressed = KEY_ZOOM_IN;
 336             return 1;
 337         }
 338     } else {
 339         if (zoom_key_pressed==KEY_ZOOM_IN) {
 340             kbd_key_release(KEY_UP);
 341             zoom_key_pressed = 0;
 342             return 1;
 343         }
 344     }
 345     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 346         if (shooting_get_focus_mode()) {
 347             kbd_key_release_all();
 348             kbd_key_press(KEY_MF);
 349             kbd_key_press(KEY_DOWN);
 350             zoom_key_pressed = KEY_ZOOM_OUT;
 351             return 1;
 352         }
 353     } else {
 354         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 355             kbd_key_release(KEY_DOWN);
 356             zoom_key_pressed = 0;
 357             return 1;
 358         }
 359     }
 360     return 0;
 361 }
 362 #else
 363 long kbd_use_zoom_as_mf() {
 364     static long zoom_key_pressed = 0;
 365 
 366     if (kbd_is_key_pressed(KEY_ZOOM_IN) && camera_info.state.mode_rec) {
 367         if (shooting_get_focus_mode()) {
 368             kbd_key_release_all();
 369             kbd_key_press(KEY_RIGHT);
 370             zoom_key_pressed = KEY_ZOOM_IN;
 371             return 1;
 372         }
 373     } else {
 374         if (zoom_key_pressed==KEY_ZOOM_IN) {
 375             kbd_key_release(KEY_RIGHT);
 376             zoom_key_pressed = 0;
 377             return 1;
 378         }
 379     }
 380     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && camera_info.state.mode_rec) {
 381         if (shooting_get_focus_mode()) {
 382             kbd_key_release_all();
 383             kbd_key_press(KEY_LEFT);
 384             zoom_key_pressed = KEY_ZOOM_OUT;
 385             return 1;
 386         }
 387     } else {
 388         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 389             kbd_key_release(KEY_LEFT);
 390             zoom_key_pressed = 0;
 391             return 1;
 392         }
 393     }
 394     return 0;
 395 }
 396 #endif //KBD_ZOOM_FOR_MF_USE_MF_KEY
 397 #endif // CAM_USE_ZOOM_FOR_MF
 398 #endif // KBD_CUSTOM_ALL

/* [<][>][^][v][top][bottom][index][help] */