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>
This commit is contained in:
parent
5bbc527460
commit
bcb6e23387
5 changed files with 172 additions and 20 deletions
|
@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#if defined(__AVR__)
|
||||
# include <avr/interrupt.h>
|
||||
#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ?
|
||||
// chibiOS headers
|
||||
# include "ch.h"
|
||||
# include "hal.h"
|
||||
#endif
|
||||
|
||||
#include "ps2.h"
|
||||
#include "ps2_io.h"
|
||||
#include "print.h"
|
||||
#include "wait.h"
|
||||
|
||||
#define WAIT(stat, us, err) \
|
||||
do { \
|
||||
|
@ -61,12 +69,30 @@ static inline void pbuf_enqueue(uint8_t data);
|
|||
static inline bool pbuf_has_data(void);
|
||||
static inline void pbuf_clear(void);
|
||||
|
||||
#if defined(PROTOCOL_CHIBIOS)
|
||||
void ps2_interrupt_service_routine(void);
|
||||
void palCallback(void *arg) { ps2_interrupt_service_routine(); }
|
||||
|
||||
# define PS2_INT_INIT() \
|
||||
{ palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); } \
|
||||
while (0)
|
||||
# define PS2_INT_ON() \
|
||||
{ \
|
||||
palEnableLineEvent(PS2_CLOCK, PAL_EVENT_MODE_FALLING_EDGE); \
|
||||
palSetLineCallback(PS2_CLOCK, palCallback, NULL); \
|
||||
} \
|
||||
while (0)
|
||||
# define PS2_INT_OFF() \
|
||||
{ palDisableLineEvent(PS2_CLOCK); } \
|
||||
while (0)
|
||||
#endif // PROTOCOL_CHIBIOS
|
||||
|
||||
void ps2_host_init(void) {
|
||||
idle();
|
||||
PS2_INT_INIT();
|
||||
PS2_INT_ON();
|
||||
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
|
||||
//_delay_ms(2500);
|
||||
// wait_ms(2500);
|
||||
}
|
||||
|
||||
uint8_t ps2_host_send(uint8_t data) {
|
||||
|
@ -77,7 +103,7 @@ uint8_t ps2_host_send(uint8_t data) {
|
|||
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
_delay_us(100); // 100us [4]p.13, [5]p.50
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
|
@ -86,7 +112,6 @@ uint8_t ps2_host_send(uint8_t data) {
|
|||
|
||||
/* Data bit[2-9] */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
_delay_us(15);
|
||||
if (data & (1 << i)) {
|
||||
parity = !parity;
|
||||
data_hi();
|
||||
|
@ -98,7 +123,7 @@ uint8_t ps2_host_send(uint8_t data) {
|
|||
}
|
||||
|
||||
/* Parity bit */
|
||||
_delay_us(15);
|
||||
wait_us(15);
|
||||
if (parity) {
|
||||
data_hi();
|
||||
} else {
|
||||
|
@ -108,7 +133,7 @@ uint8_t ps2_host_send(uint8_t data) {
|
|||
WAIT(clock_lo, 50, 5);
|
||||
|
||||
/* Stop bit */
|
||||
_delay_us(15);
|
||||
wait_us(15);
|
||||
data_hi();
|
||||
|
||||
/* Ack */
|
||||
|
@ -132,7 +157,7 @@ uint8_t ps2_host_recv_response(void) {
|
|||
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
|
||||
uint8_t retry = 25;
|
||||
while (retry-- && !pbuf_has_data()) {
|
||||
_delay_ms(1);
|
||||
wait_ms(1);
|
||||
}
|
||||
return pbuf_dequeue();
|
||||
}
|
||||
|
@ -148,7 +173,7 @@ uint8_t ps2_host_recv(void) {
|
|||
}
|
||||
}
|
||||
|
||||
ISR(PS2_INT_VECT) {
|
||||
void ps2_interrupt_service_routine(void) {
|
||||
static enum {
|
||||
INIT,
|
||||
START,
|
||||
|
@ -218,6 +243,10 @@ RETURN:
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(__AVR__)
|
||||
ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); }
|
||||
#endif
|
||||
|
||||
/* send LED state to keyboard */
|
||||
void ps2_host_set_led(uint8_t led) {
|
||||
ps2_host_send(0xED);
|
||||
|
@ -232,8 +261,13 @@ static uint8_t pbuf[PBUF_SIZE];
|
|||
static uint8_t pbuf_head = 0;
|
||||
static uint8_t pbuf_tail = 0;
|
||||
static inline void pbuf_enqueue(uint8_t data) {
|
||||
#if defined(__AVR__)
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysLockFromISR();
|
||||
#endif
|
||||
|
||||
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
|
||||
if (next != pbuf_tail) {
|
||||
pbuf[pbuf_head] = data;
|
||||
|
@ -241,31 +275,66 @@ static inline void pbuf_enqueue(uint8_t data) {
|
|||
} else {
|
||||
print("pbuf: full\n");
|
||||
}
|
||||
|
||||
#if defined(__AVR__)
|
||||
SREG = sreg;
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysUnlockFromISR();
|
||||
#endif
|
||||
}
|
||||
static inline uint8_t pbuf_dequeue(void) {
|
||||
uint8_t val = 0;
|
||||
|
||||
#if defined(__AVR__)
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysLock();
|
||||
#endif
|
||||
|
||||
if (pbuf_head != pbuf_tail) {
|
||||
val = pbuf[pbuf_tail];
|
||||
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
|
||||
}
|
||||
|
||||
#if defined(__AVR__)
|
||||
SREG = sreg;
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysUnlock();
|
||||
#endif
|
||||
|
||||
return val;
|
||||
}
|
||||
static inline bool pbuf_has_data(void) {
|
||||
#if defined(__AVR__)
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysLock();
|
||||
#endif
|
||||
|
||||
bool has_data = (pbuf_head != pbuf_tail);
|
||||
SREG = sreg;
|
||||
|
||||
#if defined(__AVR__)
|
||||
SREG = sreg;
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysUnlock();
|
||||
#endif
|
||||
return has_data;
|
||||
}
|
||||
static inline void pbuf_clear(void) {
|
||||
#if defined(__AVR__)
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysLock();
|
||||
#endif
|
||||
|
||||
pbuf_head = pbuf_tail = 0;
|
||||
SREG = sreg;
|
||||
|
||||
#if defined(__AVR__)
|
||||
SREG = sreg;
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
chSysUnlock();
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue