diff options
| author | JohSchneider <JohSchneider@googlemail.com> | 2021-08-05 21:51:24 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-06 07:51:24 +1000 |
| commit | bcb6e23387290afb64712314bfb095f8d96c1a4e (patch) | |
| tree | c82814bce65ba34e28d7df885f23dd083d3c73d2 /tmk_core | |
| parent | 5bbc527460462fb9961fbd9f972cd5e1c49558da (diff) | |
| download | qmk_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.mk | 4 | ||||
| -rw-r--r-- | tmk_core/protocol/ps2_interrupt.c | 91 | ||||
| -rw-r--r-- | tmk_core/protocol/ps2_io_chibios.c | 55 | ||||
| -rw-r--r-- | tmk_core/protocol/ps2_mouse.c | 14 |
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 | ||
| 15 | ifeq ($(strip $(PS2_USE_INT)), yes) | 15 | ifeq ($(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 |
| 19 | endif | 19 | endif |
| 20 | 20 | ||
| 21 | ifeq ($(strip $(PS2_USE_USART)), yes) | 21 | ifeq ($(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 |
| 25 | endif | 25 | endif |
| 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); | |||
| 61 | static inline bool pbuf_has_data(void); | 69 | static inline bool pbuf_has_data(void); |
| 62 | static inline void pbuf_clear(void); | 70 | static inline void pbuf_clear(void); |
| 63 | 71 | ||
| 72 | #if defined(PROTOCOL_CHIBIOS) | ||
| 73 | void ps2_interrupt_service_routine(void); | ||
| 74 | void 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 | |||
| 64 | void ps2_host_init(void) { | 90 | void 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 | ||
| 72 | uint8_t ps2_host_send(uint8_t data) { | 98 | uint8_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 | ||
| 151 | ISR(PS2_INT_VECT) { | 176 | void 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__) | ||
| 247 | ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); } | ||
| 248 | #endif | ||
| 249 | |||
| 221 | /* send LED state to keyboard */ | 250 | /* send LED state to keyboard */ |
| 222 | void ps2_host_set_led(uint8_t led) { | 251 | void 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]; | |||
| 232 | static uint8_t pbuf_head = 0; | 261 | static uint8_t pbuf_head = 0; |
| 233 | static uint8_t pbuf_tail = 0; | 262 | static uint8_t pbuf_tail = 0; |
| 234 | static inline void pbuf_enqueue(uint8_t data) { | 263 | static 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 | } |
| 246 | static inline uint8_t pbuf_dequeue(void) { | 285 | static 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 | } |
| 259 | static inline bool pbuf_has_data(void) { | 308 | static 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 | } |
| 266 | static inline void pbuf_clear(void) { | 325 | static 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 | */ | ||
| 20 | void clock_init(void) {} | ||
| 21 | |||
| 22 | void clock_lo(void) { | ||
| 23 | palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); | ||
| 24 | palWriteLine(PS2_CLOCK, PAL_LOW); | ||
| 25 | } | ||
| 26 | |||
| 27 | void clock_hi(void) { | ||
| 28 | palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); | ||
| 29 | palWriteLine(PS2_CLOCK, PAL_HIGH); | ||
| 30 | } | ||
| 31 | |||
| 32 | bool clock_in(void) { | ||
| 33 | palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); | ||
| 34 | return palReadLine(PS2_CLOCK); | ||
| 35 | } | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Data | ||
| 39 | */ | ||
| 40 | void data_init(void) {} | ||
| 41 | |||
| 42 | void data_lo(void) { | ||
| 43 | palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); | ||
| 44 | palWriteLine(PS2_DATA, PAL_LOW); | ||
| 45 | } | ||
| 46 | |||
| 47 | void data_hi(void) { | ||
| 48 | palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); | ||
| 49 | palWriteLine(PS2_DATA, PAL_HIGH); | ||
| 50 | } | ||
| 51 | |||
| 52 | bool 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); | |||
| 42 | void ps2_mouse_init(void) { | 46 | void 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 |
