diff options
author | William Wilgus <wilgus.william@gmail.com> | 2020-09-12 05:03:12 -0400 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2020-09-13 16:23:24 +0000 |
commit | c62493e98adfd27c16eb2adb2ecd22716813b705 (patch) | |
tree | c5d2a0fbdcf145584518289885e7676f82b20a29 /firmware/target/mips/ingenic_jz47xx/xduoo_x3 | |
parent | 6b674a6a0a347bd4cb946b37b6e075dc2715f7ac (diff) | |
download | rockbox-c62493e98adfd27c16eb2adb2ecd22716813b705.tar.gz rockbox-c62493e98adfd27c16eb2adb2ecd22716813b705.zip |
Xduoo X3 Add tree scrolling FS#13240, Emulate Multibutton presses
Fixes deficiencies with the button system on the X3
The x3 has an interesting button layout.
Multiple key presses are NOT supported unless
[BUTTON_POWER] is one of the combined keys
As you can imagine this causes problems as the power button takes
precedence in the button system and initiates a shutdown if the
key is held too long
instead of BUTTON_POWER use BUTTON_PWRALT in combination with other keys
IF using as a prerequsite button then BUTTON_POWER should be used
Multiple buttons are emulated by button_read_device but there are a few
caveats to be aware of:
Button Order Matters!
different keys have different priorities, higher priority keys 'overide'
the lower priority keys
VOLUP[7] VOLDN[6] PREV[5] NEXT[4] PLAY[3] OPTION[2] HOME[1]
There will be no true release or repeat events, the user can let off the
button pressed initially and it will still continue to appear to be
pressed as long as the second key is held
Tree scrolling is PLAY+NEXT or PLAY+PREV
Change-Id: I88dfee1c70a6a99659e8227f5becacc50cc43910
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/xduoo_x3')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c | 67 |
2 files changed, 50 insertions, 19 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h index 2dd94b14bc..9e2800d57b 100644 --- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h +++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h | |||
@@ -32,7 +32,7 @@ | |||
32 | #define BUTTON_PLAY 0x00000020 | 32 | #define BUTTON_PLAY 0x00000020 |
33 | #define BUTTON_VOL_UP 0x00000040 | 33 | #define BUTTON_VOL_UP 0x00000040 |
34 | #define BUTTON_VOL_DOWN 0x00000080 | 34 | #define BUTTON_VOL_DOWN 0x00000080 |
35 | 35 | #define BUTTON_PWRALT 0x00000100 /* BUTTON_POWER combo with other buttons */ | |
36 | #define BUTTON_LEFT 0 | 36 | #define BUTTON_LEFT 0 |
37 | #define BUTTON_RIGHT 0 | 37 | #define BUTTON_RIGHT 0 |
38 | 38 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c index 0f845d96d3..0d251754dd 100644 --- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c +++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c | |||
@@ -56,6 +56,8 @@ | |||
56 | #define ADC_MASK 0x0FFF | 56 | #define ADC_MASK 0x0FFF |
57 | 57 | ||
58 | static volatile unsigned short bat_val, key_val; | 58 | static volatile unsigned short bat_val, key_val; |
59 | static volatile int btn_last = BUTTON_NONE; | ||
60 | static volatile long btn_last_tick; | ||
59 | 61 | ||
60 | bool headphones_inserted(void) | 62 | bool headphones_inserted(void) |
61 | { | 63 | { |
@@ -108,52 +110,82 @@ bool button_hold(void) | |||
108 | } | 110 | } |
109 | 111 | ||
110 | /* NOTE: Due to how this is wired, button combinations are not allowed | 112 | /* NOTE: Due to how this is wired, button combinations are not allowed |
111 | unless one of the two buttons is the POWER | 113 | * unless one of the two buttons is the POWER |
112 | */ | 114 | * |
115 | * Note --Update 2020 | ||
116 | * by toggling BOP common I was able to remove BACK, OPTION, PLAY from the | ||
117 | * loop selectively and test which keys were pressed but this took two adc rounds | ||
118 | * and proved to be minimally useful for the added overhead | ||
119 | * | ||
120 | * NOW multiple button presses are emulated but button priority needs to be taken | ||
121 | * into consideration; higher priority keys 'overide' the lower priority keys | ||
122 | * VOLUP[7] VOLDN[6] PREV[5] NEXT[4] PLAY[3] OPTION[2] HOME[1] | ||
123 | */ | ||
113 | int button_read_device(void) | 124 | int button_read_device(void) |
114 | { | 125 | { |
126 | unsigned short key; | ||
115 | int btn = BUTTON_NONE; | 127 | int btn = BUTTON_NONE; |
116 | unsigned short key = (key_val & ADC_MASK); | 128 | int btn_pwr = BUTTON_NONE; |
117 | 129 | ||
118 | if (button_hold()) | 130 | if (button_hold()) |
119 | return BUTTON_NONE; | 131 | return BUTTON_NONE; |
120 | 132 | ||
121 | if (KEY_IS_DOWN(PIN_BTN_POWER)) | 133 | if (KEY_IS_DOWN(PIN_BTN_POWER)) |
122 | btn |= BUTTON_POWER; | 134 | btn_pwr = BUTTON_POWER; |
123 | 135 | ||
124 | if (!KEY_IS_DOWN(PIN_KEY_INT)) | 136 | if (!KEY_IS_DOWN(PIN_KEY_INT)) |
125 | return btn; | 137 | { |
138 | __intc_mask_irq(IRQ_SADC); | ||
139 | REG_SADC_ADENA &= ~ADENA_AUXEN; | ||
140 | return btn_pwr; | ||
141 | } | ||
142 | |||
143 | key = (key_val & ADC_MASK); | ||
144 | |||
145 | /* Don't initiate a new request if we have one pending */ | ||
146 | if(!(REG_SADC_ADENA & (ADENA_AUXEN))) | ||
147 | { | ||
148 | REG_SADC_ADENA |= ADENA_AUXEN; | ||
149 | } | ||
126 | 150 | ||
127 | if (key < 261) | 151 | if (key < 261) |
128 | btn |= BUTTON_VOL_UP; | 152 | btn = BUTTON_VOL_UP; |
129 | else | 153 | else |
130 | if (key < 653) | 154 | if (key < 653) |
131 | btn |= BUTTON_VOL_DOWN; | 155 | btn = BUTTON_VOL_DOWN; |
132 | else | 156 | else |
133 | if (key < 1101) | 157 | if (key < 1101) |
134 | btn |= BUTTON_PREV; | 158 | btn = BUTTON_PREV; |
135 | else | 159 | else |
136 | if (key < 1498) | 160 | if (key < 1498) |
137 | btn |= BUTTON_NEXT; | 161 | btn = BUTTON_NEXT; |
138 | else | 162 | else |
139 | if (key < 1839) | 163 | if (key < 1839) |
140 | btn |= BUTTON_PLAY; | 164 | btn = BUTTON_PLAY; |
141 | else | 165 | else |
142 | if (key < 2213) | 166 | if (key < 2213) |
143 | btn |= BUTTON_OPTION; | 167 | btn = BUTTON_OPTION; |
144 | else | 168 | else |
145 | if (key < 2600) | 169 | if (key < 2600) |
146 | btn |= BUTTON_HOME; | 170 | btn = BUTTON_HOME; |
171 | |||
172 | if (btn_last == BUTTON_NONE && TIME_AFTER(current_tick, btn_last_tick + HZ/20)) | ||
173 | btn_last = btn; | ||
174 | |||
175 | if (btn_pwr != BUTTON_NONE) | ||
176 | btn |= BUTTON_PWRALT; | ||
147 | 177 | ||
148 | return btn; | 178 | return btn | btn_last; |
149 | } | 179 | } |
150 | 180 | ||
151 | /* called on button press interrupt */ | 181 | /* called on button press interrupt */ |
152 | void KEY_INT_IRQ(void) | 182 | void KEY_INT_IRQ(void) |
153 | { | 183 | { |
154 | /* Don't initiate a new request if we have one pending */ | 184 | btn_last = BUTTON_NONE; |
155 | if(!(REG_SADC_ADENA & (ADENA_AUXEN))) | 185 | key_val = ADC_MASK; |
156 | REG_SADC_ADENA |= ADENA_AUXEN; | 186 | __intc_unmask_irq(IRQ_SADC); |
187 | REG_SADC_ADENA |= ADENA_AUXEN; | ||
188 | btn_last_tick = current_tick; | ||
157 | } | 189 | } |
158 | 190 | ||
159 | /* Notes on batteries | 191 | /* Notes on batteries |
@@ -238,6 +270,7 @@ void adc_init(void) | |||
238 | REG_SADC_ADCFG = ADCFG_VBAT_SEL | ADCFG_CMD_AUX(1); /* VBAT_SEL is undocumented but required! */ | 270 | REG_SADC_ADCFG = ADCFG_VBAT_SEL | ADCFG_CMD_AUX(1); /* VBAT_SEL is undocumented but required! */ |
239 | REG_SADC_ADCLK = (199 << 16) | (1 << 8) | 61; | 271 | REG_SADC_ADCLK = (199 << 16) | (1 << 8) | 61; |
240 | system_enable_irq(IRQ_SADC); | 272 | system_enable_irq(IRQ_SADC); |
273 | REG_SADC_ADENA |= ADENA_AUXEN | ADENA_VBATEN; | ||
241 | } | 274 | } |
242 | 275 | ||
243 | void adc_close(void) | 276 | void adc_close(void) |
@@ -260,8 +293,6 @@ void SADC(void) | |||
260 | if(state & ADCTRL_ARDYM) | 293 | if(state & ADCTRL_ARDYM) |
261 | { | 294 | { |
262 | key_val = REG_SADC_ADADAT; | 295 | key_val = REG_SADC_ADADAT; |
263 | if (KEY_IS_DOWN(PIN_KEY_INT)) /* key(s) are down kick off another read */ | ||
264 | REG_SADC_ADENA = ADENA_AUXEN; | ||
265 | } | 296 | } |
266 | else if(UNLIKELY(state & ADCTRL_VRDYM)) | 297 | else if(UNLIKELY(state & ADCTRL_VRDYM)) |
267 | { | 298 | { |