root/platform/g7x/kbd.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_usb_bit
  2. get_hdmi_hpd_bit
  3. get_analog_av_bit
  4. wrap_kbd_p1_f
  5. mykbd_task
  6. get_dial_hw_position
  7. get_jogdial_direction
  8. handle_jogdial
  9. jogdial_control
  10. my_kbd_read_keys
  11. kbd_fetch_data

   1 #include "lolevel.h"
   2 #include "platform.h"
   3 #include "keyboard.h"
   4 #include "kbd_common.h"
   5 
   6 long kbd_new_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
   7 long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
   8 long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
   9 
  10 extern void _GetKbdState(long*);
  11 
  12 
  13 int get_usb_bit() {
  14     long usb_physw[3];
  15     usb_physw[USB_IDX] = 0;
  16     _kbd_read_keys_r2(usb_physw);
  17     return(( usb_physw[USB_IDX] & USB_MASK)==USB_MASK) ;
  18 }
  19 
  20 int get_hdmi_hpd_bit() {
  21     long hpd_physw[3];
  22     hpd_physw[HDMI_HPD_IDX] = 0;
  23     _GetKbdState(hpd_physw);
  24     return( ((hpd_physw[HDMI_HPD_IDX] & HDMI_HPD_FLAG)==HDMI_HPD_FLAG)?0:1) ;
  25 }
  26 
  27 int get_analog_av_bit() {
  28     long av_physw[3];
  29     av_physw[ANALOG_AV_IDX] = 0;
  30     _GetKbdState(av_physw);
  31     return( ((av_physw[ANALOG_AV_IDX] & ANALOG_AV_FLAG)==ANALOG_AV_FLAG)?0:1) ;
  32 }
  33 
  34 KeyMap keymap[] = {
  35     { 0, KEY_SHOOT_FULL      ,0x00040001 }, // Found @0xfc613714, levent 0x01
  36     { 0, KEY_SHOOT_HALF      ,0x00040000 }, // Found @0xfc61378c, levent 0x00
  37     { 0, KEY_SHOOT_FULL_ONLY ,0x00000001 }, // Found @0xfc613714, levent 0x01
  38     { 0, KEY_ZOOM_OUT        ,0x00000002 }, // Found @0xfc61371c, levent 0x04
  39     { 0, KEY_ZOOM_IN         ,0x00000004 }, // Found @0xfc613724, levent 0x03
  40     { 0, KEY_VIDEO           ,0x00000008 }, // Found @0xfc61372c, levent 0x02
  41     { 0, KEY_MENU            ,0x00000010 }, // Found @0xfc613734, levent 0x14
  42     { 0, KEY_UP              ,0x00000020 }, // Found @0xfc61373c, levent 0x06
  43     { 0, KEY_DOWN            ,0x00000040 }, // Found @0xfc613744, levent 0x07
  44     { 0, KEY_RIGHT           ,0x00000080 }, // Found @0xfc61374c, levent 0x09
  45     { 0, KEY_LEFT            ,0x00000100 }, // Found @0xfc613754, levent 0x08
  46     { 0, KEY_SET             ,0x00000200 }, // Found @0xfc61375c, levent 0x0a
  47     { 0, KEY_ERASE           ,0x00000400 }, // ring func / erase, from watching  physw
  48     { 0, KEY_PLAYBACK        ,0x00000800 }, // Found @0xfc61376c, levent 0x101
  49     { 0, KEY_WIFI            ,0x00010000 }, // wifi button, from watching physw
  50 //    { 0, KEY_POWER           ,0x00020000 }, // Found @0xfc613784, levent 0x100
  51     { 0, 0, 0 }
  52 };
  53 // ev comp and mode dial is in word 1, lower bits, encoding unclear
  54 // flash open word 0, 0x00004000 = open
  55 // no battery door switch, cam runs with door open, no physw change
  56 
  57 long __attribute__((naked,noinline)) wrap_kbd_p1_f() {
  58 
  59     asm volatile(
  60         "push    {r1-r7, lr}\n"
  61         "movs    r4, #0\n"
  62         "bl      my_kbd_read_keys\n"
  63         "b       _kbd_p1_f_cont\n"
  64     );
  65 
  66     return 0;
  67 }
  68 
  69 // no stack manipulation needed here, since we create the task directly
  70 void __attribute__((noinline)) mykbd_task() {
  71     extern void kbd_p2_f_my();
  72 
  73     while (physw_run) {
  74         _SleepTask(physw_sleep_delay);
  75 
  76         if (wrap_kbd_p1_f() == 1) {
  77             kbd_p2_f_my();                      // replacement of _kbd_p2_f (in sub/<fwver>/boot.c)
  78         }
  79     }
  80 
  81     _ExitTask();
  82 }
  83 
  84 // g7x jogdial hw counters (19 bits) are at 0xd9854004 and 0xd9855004, use fw func to read + sign extend them
  85 // 0x7fff8 .. 0x7fffc .. 0 (start pos) .. 4
  86 // intermediate positions are also available, but they are ignored by the fw for a good reason
  87 extern int _get_dial_hw_position(int dial);
  88 #define DIAL_HW_REAR  4
  89 #define DIAL_HW_FRONT 5
  90 int get_dial_hw_position(int dial)
  91 {
  92     // mask low bits
  93     return _get_dial_hw_position(dial)&~3;
  94 }
  95 int jogdial_stopped=0;
  96 
  97 extern long dial_positions[4];
  98 
  99 long get_jogdial_direction(void) {
 100     static int new_jogdial=0, old_jogdial=0, new_frontdial=0, old_frontdial=0;
 101     
 102     old_jogdial=new_jogdial;
 103     new_jogdial=get_dial_hw_position(DIAL_HW_REAR);
 104 
 105     old_frontdial=new_frontdial;
 106     new_frontdial=get_dial_hw_position(DIAL_HW_FRONT);
 107 
 108     if (old_jogdial>new_jogdial) return JOGDIAL_LEFT; 
 109     else if (old_jogdial<new_jogdial) return JOGDIAL_RIGHT;
 110     if (old_frontdial<new_frontdial) return FRONTDIAL_LEFT;  // counter clockwise with camera aimed away from you
 111     else if (old_frontdial>new_frontdial) return FRONTDIAL_RIGHT;
 112     else return 0;
 113 }
 114 
 115 int handle_jogdial() {
 116     // return 0 to prevent fw dial handler
 117     if (jogdial_stopped) {
 118         // update positions in RAM
 119         dial_positions[0] = dial_positions[2] = get_dial_hw_position(DIAL_HW_REAR);
 120         dial_positions[1] = dial_positions[3] = get_dial_hw_position(DIAL_HW_FRONT);
 121         return 0;
 122     }
 123     return 1;
 124 }
 125 
 126 void jogdial_control(int c) {
 127     jogdial_stopped = c;
 128 }
 129 
 130 void my_kbd_read_keys() {
 131     kbd_update_key_state();
 132     kbd_update_physw_bits();
 133 }
 134 
 135 void kbd_fetch_data(long *dst)
 136 {
 137     _GetKbdState(dst);
 138     _kbd_read_keys_r2(dst);
 139 }

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