root/platform/m10/kbd.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_usb_bit
  2. wrap_kbd_p1_f
  3. mykbd_task_proceed
  4. mykbd_task
  5. get_jogdial_counter
  6. get_jogdial_direction
  7. handle_jogdial
  8. jogdial_control
  9. ifm_done
  10. sut_done
  11. xtra_kbd_cb
  12. my_kbd_read_keys
  13. kbd_fetch_data

   1 #include "lolevel.h"
   2 #include "platform.h"
   3 #include "core.h"
   4 #include "keyboard.h"
   5 #include "kbd_common.h"
   6 
   7 long kbd_new_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
   8 long kbd_prev_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
   9 long kbd_mod_state[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
  10 
  11 extern void _GetKbdState(long*);
  12 
  13 
  14 int get_usb_bit() {
  15     long usb_physw[3];
  16     usb_physw[USB_IDX] = 0;
  17     _kbd_read_keys_r2(usb_physw);
  18     return(( usb_physw[USB_IDX] & USB_MASK)==USB_MASK) ;
  19 }
  20 
  21 KeyMap keymap[] = {
  22 //    { 0, KEY_POWER           ,0x00000001 }, // Found @0xfc623cfc, levent 0x100 (uses inverted logic in physw_status)
  23     { 0, KEY_PLAYBACK        ,0x00000002 }, // Found @0xfc623d04, levent 0x101 (uses inverted logic in physw_status)
  24     { 0, KEY_WIFI            ,0x00000004 }, // Found @0xfc623d0c, levent 0x103 (uses inverted logic in physw_status)
  25     { 1, KEY_SHOOT_FULL      ,0x00040001 }, // Found @0xfc623d2c, levent 0x01
  26     { 1, KEY_SHOOT_HALF      ,0x00040000 }, // Found @0xfc623d7c, levent 0x00
  27     { 1, KEY_SHOOT_FULL_ONLY ,0x00000001 }, // Found @0xfc623d2c, levent 0x01
  28     { 1, KEY_VIDEO           ,0x00000008 }, // Found @0xfc623d34, levent 0x02
  29     { 1, KEY_UP              ,0x00000020 }, // Found @0xfc623d3c, levent 0x06
  30     { 1, KEY_DOWN            ,0x00000040 }, // Found @0xfc623d44, levent 0x07
  31     { 1, KEY_RIGHT           ,0x00000080 }, // Found @0xfc623d4c, levent 0x09
  32     { 1, KEY_LEFT            ,0x00000100 }, // Found @0xfc623d54, levent 0x08
  33     { 1, KEY_SET             ,0x00000200 }, // Found @0xfc623d5c, levent 0x0a
  34     { 1, KEY_MENU            ,0x00001000 }, // Found @0xfc623d74, levent 0x14
  35     { 0, 0, 0 }
  36 };
  37 
  38 long __attribute__((naked,noinline)) wrap_kbd_p1_f() {
  39 
  40     asm volatile(
  41         "push    {r1-r7, lr}\n"
  42         "movs    r4, #0\n"
  43         "bl      my_kbd_read_keys\n"
  44         //"b       _kbd_p1_f_cont\n"
  45         "b       kbd_p1_f_cont_my\n"
  46     );
  47 
  48     return 0;
  49 }
  50 
  51 static void __attribute__((noinline)) mykbd_task_proceed() {
  52 
  53     extern void kbd_p2_f_my();
  54 
  55     /* Initialize our own kbd_new_state[] array with the
  56     current physical status.*/
  57     kbd_new_state[0] = physw_status[0] ^ KEYS_INV0;
  58     kbd_new_state[1] = physw_status[1];
  59     kbd_new_state[2] = physw_status[2];
  60 
  61     while (physw_run) {
  62         _SleepTask(physw_sleep_delay);
  63 
  64         if (wrap_kbd_p1_f() == 1) {             // autorepeat ?
  65             kbd_p2_f_my();                      // replacement of _kbd_p2_f (in sub/<fwver>/boot.c)
  66         }
  67     }
  68 }
  69 
  70 // no stack manipulation needed here, since we create the task directly
  71 void __attribute__((naked,noinline)) mykbd_task() {
  72     mykbd_task_proceed();
  73 
  74     _ExitTask();
  75 }
  76 
  77 // jogdial hw counter (19 bits) 0xd9855004
  78 // 0x7fff8 .. 0x7fffc .. 0 (start pos) .. 4
  79 // intermediate positions are also available, but they are ignored by the fw for a good reason
  80 
  81 int jogdial_stopped=0;
  82 
  83 extern long jog_position[2];
  84 extern long jog_hw_pos;
  85 
  86 int get_jogdial_counter() {
  87     int p;
  88     p = jog_hw_pos & 0x7fffc;
  89     if (p > 0x3fffc) {
  90         p |= 0xfff80000;
  91     }
  92     return p;
  93 }
  94 
  95 long get_jogdial_direction(void) {
  96     static int new_jogdial=0, old_jogdial=0;
  97     
  98     old_jogdial=new_jogdial;
  99     new_jogdial=get_jogdial_counter();
 100     if (old_jogdial>new_jogdial) return JOGDIAL_RIGHT; 
 101     else if (old_jogdial<new_jogdial) return JOGDIAL_LEFT;
 102     else return 0;
 103 }
 104 
 105 int handle_jogdial() {
 106     // return 0 to prevent fw jogdial handler
 107     if (jogdial_stopped) {
 108         // update jog position in RAM
 109         jog_position[0] = jog_position[1] = get_jogdial_counter();
 110         return 0;
 111     }
 112     return 1;
 113 }
 114 
 115 void jogdial_control(int c) {
 116     jogdial_stopped = c;
 117 }
 118 
 119 static int startuptask_done = 0;
 120 static int initfilemodules_done = 0;
 121 
 122 void ifm_done()
 123 {
 124     initfilemodules_done = 1;
 125 }
 126 
 127 void sut_done()
 128 {
 129     startuptask_done = 1; 
 130 }
 131 
 132 static long kbdxtra = 0;
 133 
 134 // callback, to be called from later part of kbd_p1_f (see boot.c)
 135 long xtra_kbd_cb()
 136 {
 137     if (kbdxtra)
 138     {
 139         kbdxtra = 0;
 140         return physw_status[1] & 0x41fe9; // mask found @ 0xfc07f02a (110d fw), also in GetKbdState
 141     }
 142     return -1;
 143 }
 144 
 145 void my_kbd_read_keys()
 146 {
 147     kbd_prev_state[0] = kbd_new_state[0];
 148     kbd_prev_state[1] = kbd_new_state[1];
 149     kbd_prev_state[2] = kbd_new_state[2];
 150 
 151 #ifdef CAM_TOUCHSCREEN_UI
 152     kbd_prev_state[3] = kbd_new_state[3];
 153 #endif
 154 
 155     // note assumed kbd_pwr_on has been called if needed
 156     kbd_fetch_data(physw_status); // has to be physw_status
 157 
 158     kbd_new_state[0] = physw_status[0] ^ KEYS_INV0; // invert button(s) for CHDK use
 159     kbd_new_state[1] = physw_status[1];
 160     kbd_new_state[2] = physw_status[2];
 161 
 162     long status = kbd_process();
 163     if (status == 0){
 164         // leave it alone...
 165 #ifdef CAM_HAS_JOGDIAL
 166         jogdial_control(0);
 167 #endif
 168     } else {
 169         // override keys
 170 
 171         // invert button(s) before writing back to physw_status
 172         physw_status[0] = ((kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0)) ^ KEYS_INV0;
 173 
 174         physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
 175 
 176         physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
 177 
 178         kbdxtra = 1;
 179 
 180 #ifdef CAM_HAS_JOGDIAL
 181         if ((jogdial_stopped==0) && !camera_info.state.state_kbd_script_run) {
 182             jogdial_control(1);
 183             get_jogdial_direction();
 184         }
 185         else if (jogdial_stopped && camera_info.state.state_kbd_script_run) {
 186             jogdial_control(0);
 187         }
 188 #endif
 189     }
 190     // usb and SD read-only are standard
 191     kbd_update_physw_bits();
 192 
 193     // attempt to delay spytask so it doesn't crash the camera (crash reason is not known)
 194     extern int canon_gui_started_flag;
 195     extern void core_spytask_can_start();
 196     if (canon_gui_started_flag && initfilemodules_done && startuptask_done) {
 197         core_spytask_can_start();
 198         // re-use a variable to prevent multiple execution
 199         startuptask_done = 0;
 200     }
 201 }
 202 
 203 void kbd_fetch_data(long *dst)
 204 {
 205     _GetKbdState(dst);
 206     _kbd_read_keys_r2(dst);
 207 }

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