aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorJohSchneider <JohSchneider@googlemail.com>2021-08-05 21:51:24 +0000
committerGitHub <noreply@github.com>2021-08-06 07:51:24 +1000
commitbcb6e23387290afb64712314bfb095f8d96c1a4e (patch)
treec82814bce65ba34e28d7df885f23dd083d3c73d2 /tmk_core
parent5bbc527460462fb9961fbd9f972cd5e1c49558da (diff)
downloadqmk_firmware-bcb6e23387290afb64712314bfb095f8d96c1a4e.tar.gz
qmk_firmware-bcb6e23387290afb64712314bfb095f8d96c1a4e.zip
Arm ps2 mouse interrupt (#6490)
* ps2_mouse on ARM: an interrupt-version of the ps2-mouse code ported to ARM/chibios * ps2_mouse on ARM: link EXT callback-channel selection to the user defined PS2_LINE_CLOCK * ps2_mouse on ARM: replace DELAY_X defines with hardware-agnostic wait_X * ps2_mouse on ARM: replace chibios-specific defines for the pins/lines with defines from quantum/config_common.h and drop the '_LINE' component from teh define name * ps2_mouse on ARM: expose the software-intterupt port as a user editable define * Update docs/feature_ps2_mouse.md Co-Authored-By: Hugo van Kemenade <hugovk@users.noreply.github.com> * Update feature_ps2_mouse.md * use a define to deduce the PS_DATA_PORT instead * reduce all-zero extcfg to oneliner * ps2_mouse: use generic wait instead of avr-delay * Update docs/feature_ps2_mouse.md * ps2_mouse: changes for new chibios version (17.6.0 -> 19.1.0) replacing the legacy externa-interrupt driver with pal-callbacks * ps2_mouse: use PLATFORM_KEY Co-Authored-By: Joel Challis <git@zvecr.com> * ps2_mouse: clang-format corrections * ps2_mouse: add systemlocks using the chibios equivalent to AVRs cli: chSys[Unl|L]ock Co-authored-by: Johannes <you@example.com> Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com> Co-authored-by: Joel Challis <git@zvecr.com>
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/protocol.mk4
-rw-r--r--tmk_core/protocol/ps2_interrupt.c91
-rw-r--r--tmk_core/protocol/ps2_io_chibios.c55
-rw-r--r--tmk_core/protocol/ps2_mouse.c14
4 files changed, 146 insertions, 18 deletions
diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk
index cc87e8347..b61f2f546 100644
--- a/tmk_core/protocol.mk
+++ b/tmk_core/protocol.mk
@@ -14,13 +14,13 @@ endif
14 14
15ifeq ($(strip $(PS2_USE_INT)), yes) 15ifeq ($(strip $(PS2_USE_INT)), yes)
16 SRC += protocol/ps2_interrupt.c 16 SRC += protocol/ps2_interrupt.c
17 SRC += protocol/ps2_io_avr.c 17 SRC += protocol/ps2_io_$(PLATFORM_KEY).c
18 OPT_DEFS += -DPS2_USE_INT 18 OPT_DEFS += -DPS2_USE_INT
19endif 19endif
20 20
21ifeq ($(strip $(PS2_USE_USART)), yes) 21ifeq ($(strip $(PS2_USE_USART)), yes)
22 SRC += protocol/ps2_usart.c 22 SRC += protocol/ps2_usart.c
23 SRC += protocol/ps2_io_avr.c 23 SRC += protocol/ps2_io_$(PLATFORM_KEY).c
24 OPT_DEFS += -DPS2_USE_USART 24 OPT_DEFS += -DPS2_USE_USART
25endif 25endif
26 26
diff --git a/tmk_core/protocol/ps2_interrupt.c b/tmk_core/protocol/ps2_interrupt.c
index 5afc8a82e..780040d15 100644
--- a/tmk_core/protocol/ps2_interrupt.c
+++ b/tmk_core/protocol/ps2_interrupt.c
@@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE.
40 */ 40 */
41 41
42#include <stdbool.h> 42#include <stdbool.h>
43#include <avr/interrupt.h> 43
44#include <util/delay.h> 44#if defined(__AVR__)
45# include <avr/interrupt.h>
46#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ?
47// chibiOS headers
48# include "ch.h"
49# include "hal.h"
50#endif
51
45#include "ps2.h" 52#include "ps2.h"
46#include "ps2_io.h" 53#include "ps2_io.h"
47#include "print.h" 54#include "print.h"
55#include "wait.h"
48 56
49#define WAIT(stat, us, err) \ 57#define WAIT(stat, us, err) \
50 do { \ 58 do { \
@@ -61,12 +69,30 @@ static inline void pbuf_enqueue(uint8_t data);
61static inline bool pbuf_has_data(void); 69static inline bool pbuf_has_data(void);
62static inline void pbuf_clear(void); 70static inline void pbuf_clear(void);
63 71
72#if defined(PROTOCOL_CHIBIOS)
73void ps2_interrupt_service_routine(void);
74void palCallback(void *arg) { ps2_interrupt_service_routine(); }
75
76# define PS2_INT_INIT() \
77 { palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); } \
78 while (0)
79# define PS2_INT_ON() \
80 { \
81 palEnableLineEvent(PS2_CLOCK, PAL_EVENT_MODE_FALLING_EDGE); \
82 palSetLineCallback(PS2_CLOCK, palCallback, NULL); \
83 } \
84 while (0)
85# define PS2_INT_OFF() \
86 { palDisableLineEvent(PS2_CLOCK); } \
87 while (0)
88#endif // PROTOCOL_CHIBIOS
89
64void ps2_host_init(void) { 90void ps2_host_init(void) {
65 idle(); 91 idle();
66 PS2_INT_INIT(); 92 PS2_INT_INIT();
67 PS2_INT_ON(); 93 PS2_INT_ON();
68 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) 94 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
69 //_delay_ms(2500); 95 // wait_ms(2500);
70} 96}
71 97
72uint8_t ps2_host_send(uint8_t data) { 98uint8_t ps2_host_send(uint8_t data) {
@@ -77,7 +103,7 @@ uint8_t ps2_host_send(uint8_t data) {
77 103
78 /* terminate a transmission if we have */ 104 /* terminate a transmission if we have */
79 inhibit(); 105 inhibit();
80 _delay_us(100); // 100us [4]p.13, [5]p.50 106 wait_us(100); // 100us [4]p.13, [5]p.50
81 107
82 /* 'Request to Send' and Start bit */ 108 /* 'Request to Send' and Start bit */
83 data_lo(); 109 data_lo();
@@ -86,7 +112,6 @@ uint8_t ps2_host_send(uint8_t data) {
86 112
87 /* Data bit[2-9] */ 113 /* Data bit[2-9] */
88 for (uint8_t i = 0; i < 8; i++) { 114 for (uint8_t i = 0; i < 8; i++) {
89 _delay_us(15);
90 if (data & (1 << i)) { 115 if (data & (1 << i)) {
91 parity = !parity; 116 parity = !parity;
92 data_hi(); 117 data_hi();
@@ -98,7 +123,7 @@ uint8_t ps2_host_send(uint8_t data) {
98 } 123 }
99 124
100 /* Parity bit */ 125 /* Parity bit */
101 _delay_us(15); 126 wait_us(15);
102 if (parity) { 127 if (parity) {
103 data_hi(); 128 data_hi();
104 } else { 129 } else {
@@ -108,7 +133,7 @@ uint8_t ps2_host_send(uint8_t data) {
108 WAIT(clock_lo, 50, 5); 133 WAIT(clock_lo, 50, 5);
109 134
110 /* Stop bit */ 135 /* Stop bit */
111 _delay_us(15); 136 wait_us(15);
112 data_hi(); 137 data_hi();
113 138
114 /* Ack */ 139 /* Ack */
@@ -132,7 +157,7 @@ uint8_t ps2_host_recv_response(void) {
132 // Command may take 25ms/20ms at most([5]p.46, [3]p.21) 157 // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
133 uint8_t retry = 25; 158 uint8_t retry = 25;
134 while (retry-- && !pbuf_has_data()) { 159 while (retry-- && !pbuf_has_data()) {
135 _delay_ms(1); 160 wait_ms(1);
136 } 161 }
137 return pbuf_dequeue(); 162 return pbuf_dequeue();
138} 163}
@@ -148,7 +173,7 @@ uint8_t ps2_host_recv(void) {
148 } 173 }
149} 174}
150 175
151ISR(PS2_INT_VECT) { 176void ps2_interrupt_service_routine(void) {
152 static enum { 177 static enum {
153 INIT, 178 INIT,
154 START, 179 START,
@@ -218,6 +243,10 @@ RETURN:
218 return; 243 return;
219} 244}
220 245
246#if defined(__AVR__)
247ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); }
248#endif
249
221/* send LED state to keyboard */ 250/* send LED state to keyboard */
222void ps2_host_set_led(uint8_t led) { 251void ps2_host_set_led(uint8_t led) {
223 ps2_host_send(0xED); 252 ps2_host_send(0xED);
@@ -232,8 +261,13 @@ static uint8_t pbuf[PBUF_SIZE];
232static uint8_t pbuf_head = 0; 261static uint8_t pbuf_head = 0;
233static uint8_t pbuf_tail = 0; 262static uint8_t pbuf_tail = 0;
234static inline void pbuf_enqueue(uint8_t data) { 263static inline void pbuf_enqueue(uint8_t data) {
264#if defined(__AVR__)
235 uint8_t sreg = SREG; 265 uint8_t sreg = SREG;
236 cli(); 266 cli();
267#elif defined(PROTOCOL_CHIBIOS)
268 chSysLockFromISR();
269#endif
270
237 uint8_t next = (pbuf_head + 1) % PBUF_SIZE; 271 uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
238 if (next != pbuf_tail) { 272 if (next != pbuf_tail) {
239 pbuf[pbuf_head] = data; 273 pbuf[pbuf_head] = data;
@@ -241,31 +275,66 @@ static inline void pbuf_enqueue(uint8_t data) {
241 } else { 275 } else {
242 print("pbuf: full\n"); 276 print("pbuf: full\n");
243 } 277 }
278
279#if defined(__AVR__)
244 SREG = sreg; 280 SREG = sreg;
281#elif defined(PROTOCOL_CHIBIOS)
282 chSysUnlockFromISR();
283#endif
245} 284}
246static inline uint8_t pbuf_dequeue(void) { 285static inline uint8_t pbuf_dequeue(void) {
247 uint8_t val = 0; 286 uint8_t val = 0;
248 287
288#if defined(__AVR__)
249 uint8_t sreg = SREG; 289 uint8_t sreg = SREG;
250 cli(); 290 cli();
291#elif defined(PROTOCOL_CHIBIOS)
292 chSysLock();
293#endif
294
251 if (pbuf_head != pbuf_tail) { 295 if (pbuf_head != pbuf_tail) {
252 val = pbuf[pbuf_tail]; 296 val = pbuf[pbuf_tail];
253 pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; 297 pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
254 } 298 }
299
300#if defined(__AVR__)
255 SREG = sreg; 301 SREG = sreg;
302#elif defined(PROTOCOL_CHIBIOS)
303 chSysUnlock();
304#endif
256 305
257 return val; 306 return val;
258} 307}
259static inline bool pbuf_has_data(void) { 308static inline bool pbuf_has_data(void) {
309#if defined(__AVR__)
260 uint8_t sreg = SREG; 310 uint8_t sreg = SREG;
261 cli(); 311 cli();
312#elif defined(PROTOCOL_CHIBIOS)
313 chSysLock();
314#endif
315
262 bool has_data = (pbuf_head != pbuf_tail); 316 bool has_data = (pbuf_head != pbuf_tail);
263 SREG = sreg; 317
318#if defined(__AVR__)
319 SREG = sreg;
320#elif defined(PROTOCOL_CHIBIOS)
321 chSysUnlock();
322#endif
264 return has_data; 323 return has_data;
265} 324}
266static inline void pbuf_clear(void) { 325static inline void pbuf_clear(void) {
326#if defined(__AVR__)
267 uint8_t sreg = SREG; 327 uint8_t sreg = SREG;
268 cli(); 328 cli();
329#elif defined(PROTOCOL_CHIBIOS)
330 chSysLock();
331#endif
332
269 pbuf_head = pbuf_tail = 0; 333 pbuf_head = pbuf_tail = 0;
270 SREG = sreg; 334
335#if defined(__AVR__)
336 SREG = sreg;
337#elif defined(PROTOCOL_CHIBIOS)
338 chSysUnlock();
339#endif
271} 340}
diff --git a/tmk_core/protocol/ps2_io_chibios.c b/tmk_core/protocol/ps2_io_chibios.c
new file mode 100644
index 000000000..b672bd1f4
--- /dev/null
+++ b/tmk_core/protocol/ps2_io_chibios.c
@@ -0,0 +1,55 @@
1#include <stdbool.h>
2#include "ps2_io.h"
3
4// chibiOS headers
5#include "ch.h"
6#include "hal.h"
7
8/* Check port settings for clock and data line */
9#if !(defined(PS2_CLOCK))
10# error "PS/2 clock setting is required in config.h"
11#endif
12
13#if !(defined(PS2_DATA))
14# error "PS/2 data setting is required in config.h"
15#endif
16
17/*
18 * Clock
19 */
20void clock_init(void) {}
21
22void clock_lo(void) {
23 palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN);
24 palWriteLine(PS2_CLOCK, PAL_LOW);
25}
26
27void clock_hi(void) {
28 palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN);
29 palWriteLine(PS2_CLOCK, PAL_HIGH);
30}
31
32bool clock_in(void) {
33 palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT);
34 return palReadLine(PS2_CLOCK);
35}
36
37/*
38 * Data
39 */
40void data_init(void) {}
41
42void data_lo(void) {
43 palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN);
44 palWriteLine(PS2_DATA, PAL_LOW);
45}
46
47void data_hi(void) {
48 palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN);
49 palWriteLine(PS2_DATA, PAL_HIGH);
50}
51
52bool data_in(void) {
53 palSetLineMode(PS2_DATA, PAL_MODE_INPUT);
54 return palReadLine(PS2_DATA);
55}
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index 5415453a0..525aeb45a 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -16,9 +16,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include <stdbool.h> 18#include <stdbool.h>
19#include <avr/io.h> 19
20#include <util/delay.h> 20#if defined(__AVR__)
21# include <avr/io.h>
22#endif
23
21#include "ps2_mouse.h" 24#include "ps2_mouse.h"
25#include "wait.h"
22#include "host.h" 26#include "host.h"
23#include "timer.h" 27#include "timer.h"
24#include "print.h" 28#include "print.h"
@@ -42,7 +46,7 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report);
42void ps2_mouse_init(void) { 46void ps2_mouse_init(void) {
43 ps2_host_init(); 47 ps2_host_init();
44 48
45 _delay_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up 49 wait_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up
46 50
47 PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset"); 51 PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset");
48 52
@@ -210,7 +214,7 @@ static inline void ps2_mouse_enable_scrolling(void) {
210 PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate"); 214 PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate");
211 PS2_MOUSE_SEND(80, "80"); 215 PS2_MOUSE_SEND(80, "80");
212 PS2_MOUSE_SEND(PS2_MOUSE_GET_DEVICE_ID, "Finished enabling scroll wheel"); 216 PS2_MOUSE_SEND(PS2_MOUSE_GET_DEVICE_ID, "Finished enabling scroll wheel");
213 _delay_ms(20); 217 wait_ms(20);
214} 218}
215 219
216#define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK) 220#define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK)
@@ -252,7 +256,7 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) {
252 if (scroll_state == SCROLL_BTN && timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) { 256 if (scroll_state == SCROLL_BTN && timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
253 PRESS_SCROLL_BUTTONS; 257 PRESS_SCROLL_BUTTONS;
254 host_mouse_send(mouse_report); 258 host_mouse_send(mouse_report);
255 _delay_ms(100); 259 wait_ms(100);
256 RELEASE_SCROLL_BUTTONS; 260 RELEASE_SCROLL_BUTTONS;
257 } 261 }
258#endif 262#endif