Make touchpad access non-blocking
This commit is contained in:
parent
532219c3f8
commit
1b539e1206
@ -24,10 +24,12 @@ void kbc_init(void) {
|
||||
|
||||
#define KBC_TIMEOUT 1000
|
||||
|
||||
// Enable first port - TODO
|
||||
// Enable first port
|
||||
static bool kbc_first = false;
|
||||
// Enable second port - TODO
|
||||
// Enable second port
|
||||
static bool kbc_second = false;
|
||||
// Second port input timeout
|
||||
static uint8_t kbc_second_wait = 0;
|
||||
// Translate from scancode set 2 to scancode set 1
|
||||
// for basically no good reason
|
||||
static bool kbc_translate = true;
|
||||
@ -359,7 +361,15 @@ static void kbc_on_input_data(struct Kbc * kbc, uint8_t data) {
|
||||
case KBC_STATE_SECOND_PORT_INPUT:
|
||||
TRACE(" write second port input\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
ps2_write(&PS2_TOUCHPAD, &data, 1);
|
||||
// Begin write
|
||||
*(PS2_TOUCHPAD.control) = 0x0D;
|
||||
*(PS2_TOUCHPAD.data) = data;
|
||||
// Pull data line low
|
||||
*(PS2_TOUCHPAD.control) = 0x0C;
|
||||
// Pull clock line high
|
||||
*(PS2_TOUCHPAD.control) = 0x0E;
|
||||
// Set wait timeout of 100 cycles
|
||||
kbc_second_wait = 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -408,12 +418,37 @@ void kbc_event(struct Kbc * kbc) {
|
||||
|
||||
// Read from touchpad when possible
|
||||
if (kbc_second) {
|
||||
*(PS2_TOUCHPAD.control) = 0x07;
|
||||
if (state == KBC_STATE_NORMAL) {
|
||||
if (kbc_second_wait > 0) {
|
||||
// Wait for touchpad write transaction to finish
|
||||
kbc_second_wait -= 1;
|
||||
uint8_t sts = *(PS2_TOUCHPAD.status);
|
||||
*(PS2_TOUCHPAD.status) = sts;
|
||||
if (sts & BIT(3)) {
|
||||
state = KBC_STATE_TOUCHPAD;
|
||||
// If transaction is done, stop waiting
|
||||
if (sts & PSSTS_DONE) {
|
||||
kbc_second_wait = 0;
|
||||
}
|
||||
// If an error happened, clear status, print error, and stop waiting
|
||||
else if (sts & PSSTS_ALL_ERR) {
|
||||
ps2_reset(&PS2_TOUCHPAD);
|
||||
TRACE(" write second port input ERROR %02X\n", sts);
|
||||
kbc_second_wait = 0;
|
||||
}
|
||||
// If a timeout occurs, clear status, print error, and stop waiting
|
||||
else if (kbc_second_wait == 0) {
|
||||
ps2_reset(&PS2_TOUCHPAD);
|
||||
TRACE(" write second port input TIMEOUT\n");
|
||||
kbc_second_wait = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbc_second_wait == 0) {
|
||||
// Attempt to read from touchpad
|
||||
*(PS2_TOUCHPAD.control) = 0x07;
|
||||
if (state == KBC_STATE_NORMAL) {
|
||||
uint8_t sts = *(PS2_TOUCHPAD.status);
|
||||
*(PS2_TOUCHPAD.status) = sts;
|
||||
if (sts & PSSTS_DONE) {
|
||||
state = KBC_STATE_TOUCHPAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -5,6 +5,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PSSTS_TIMEOUT_ERR BIT(6)
|
||||
#define PSSTS_FRAME_ERR BIT(5)
|
||||
#define PSSTS_PARITY_ERR BIT(4)
|
||||
#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR)
|
||||
#define PSSTS_DONE BIT(3)
|
||||
|
||||
struct Ps2 {
|
||||
volatile uint8_t * control;
|
||||
volatile uint8_t * interrupt;
|
||||
@ -17,8 +23,6 @@ extern struct Ps2 __code PS2_2;
|
||||
extern struct Ps2 __code PS2_3;
|
||||
|
||||
void ps2_reset(struct Ps2 * ps2);
|
||||
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length);
|
||||
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length);
|
||||
|
||||
volatile uint8_t __xdata __at(0x1700) PSCTL1;
|
||||
volatile uint8_t __xdata __at(0x1701) PSCTL2;
|
||||
|
@ -1,8 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/macro.h>
|
||||
#include <ec/ps2.h>
|
||||
|
||||
#define PS2(NUM) { \
|
||||
@ -12,14 +9,6 @@
|
||||
.data = &PSDAT ## NUM, \
|
||||
}
|
||||
|
||||
#define PS2_TIMEOUT 10000
|
||||
|
||||
#define PSSTS_TIMEOUT_ERR BIT(6)
|
||||
#define PSSTS_FRAME_ERR BIT(5)
|
||||
#define PSSTS_PARITY_ERR BIT(4)
|
||||
#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR)
|
||||
#define PSSTS_DONE BIT(3)
|
||||
|
||||
struct Ps2 __code PS2_1 = PS2(1);
|
||||
struct Ps2 __code PS2_2 = PS2(2);
|
||||
struct Ps2 __code PS2_3 = PS2(3);
|
||||
@ -30,55 +19,3 @@ void ps2_reset(struct Ps2 * ps2) {
|
||||
// Clear status
|
||||
*(ps2->status) = *(ps2->status);
|
||||
}
|
||||
|
||||
static int ps2_transaction(struct Ps2 * ps2, uint8_t * data, int length, bool read) {
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
if (read) {
|
||||
// Begin read
|
||||
*(ps2->control) = 0x07;
|
||||
} else {
|
||||
// Begin write
|
||||
*(ps2->control) = 0x0D;
|
||||
*(ps2->data) = data[i];
|
||||
// Pull data line low
|
||||
*(ps2->control) = 0x0C;
|
||||
// Pull clock line high
|
||||
*(ps2->control) = 0x0E;
|
||||
}
|
||||
|
||||
uint32_t timeout;
|
||||
for (timeout = PS2_TIMEOUT; timeout > 0; timeout--) {
|
||||
uint8_t status = *(ps2->status);
|
||||
// If an error happened, clear status and return the error
|
||||
if (status & PSSTS_ALL_ERR) {
|
||||
ps2_reset(ps2);
|
||||
return -(int)status;
|
||||
}
|
||||
// If transaction is done, break
|
||||
if (status & PSSTS_DONE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If a timeout happened, return the error
|
||||
if (timeout == 0) {
|
||||
ps2_reset(ps2);
|
||||
return -0x1000;
|
||||
}
|
||||
if (read) {
|
||||
data[i] = *(ps2->data);
|
||||
}
|
||||
// Set interface to defaults
|
||||
ps2_reset(ps2);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length) {
|
||||
return ps2_transaction(ps2, data, length, true);
|
||||
}
|
||||
|
||||
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length) {
|
||||
return ps2_transaction(ps2, data, length, false);
|
||||
}
|
||||
|
@ -5,6 +5,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PSSTS_TIMEOUT_ERR BIT(6)
|
||||
#define PSSTS_FRAME_ERR BIT(5)
|
||||
#define PSSTS_PARITY_ERR BIT(4)
|
||||
#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR)
|
||||
#define PSSTS_DONE BIT(3)
|
||||
|
||||
struct Ps2 {
|
||||
volatile uint8_t * control;
|
||||
volatile uint8_t * interrupt;
|
||||
@ -17,8 +23,6 @@ extern struct Ps2 __code PS2_2;
|
||||
extern struct Ps2 __code PS2_3;
|
||||
|
||||
void ps2_reset(struct Ps2 * ps2);
|
||||
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length);
|
||||
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length);
|
||||
|
||||
volatile uint8_t __xdata __at(0x1700) PSCTL1;
|
||||
volatile uint8_t __xdata __at(0x1701) PSCTL2;
|
||||
|
@ -1,8 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/macro.h>
|
||||
#include <ec/ps2.h>
|
||||
|
||||
#define PS2(NUM) { \
|
||||
@ -12,14 +9,6 @@
|
||||
.data = &PSDAT ## NUM, \
|
||||
}
|
||||
|
||||
#define PS2_TIMEOUT 10000
|
||||
|
||||
#define PSSTS_TIMEOUT_ERR BIT(6)
|
||||
#define PSSTS_FRAME_ERR BIT(5)
|
||||
#define PSSTS_PARITY_ERR BIT(4)
|
||||
#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR)
|
||||
#define PSSTS_DONE BIT(3)
|
||||
|
||||
struct Ps2 __code PS2_1 = PS2(1);
|
||||
struct Ps2 __code PS2_2 = PS2(2);
|
||||
struct Ps2 __code PS2_3 = PS2(3);
|
||||
@ -30,55 +19,3 @@ void ps2_reset(struct Ps2 * ps2) {
|
||||
// Clear status
|
||||
*(ps2->status) = *(ps2->status);
|
||||
}
|
||||
|
||||
static int ps2_transaction(struct Ps2 * ps2, uint8_t * data, int length, bool read) {
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
if (read) {
|
||||
// Begin read
|
||||
*(ps2->control) = 0x07;
|
||||
} else {
|
||||
// Begin write
|
||||
*(ps2->control) = 0x0D;
|
||||
*(ps2->data) = data[i];
|
||||
// Pull data line low
|
||||
*(ps2->control) = 0x0C;
|
||||
// Pull clock line high
|
||||
*(ps2->control) = 0x0E;
|
||||
}
|
||||
|
||||
uint32_t timeout;
|
||||
for (timeout = PS2_TIMEOUT; timeout > 0; timeout--) {
|
||||
uint8_t status = *(ps2->status);
|
||||
// If an error happened, clear status and return the error
|
||||
if (status & PSSTS_ALL_ERR) {
|
||||
ps2_reset(ps2);
|
||||
return -(int)status;
|
||||
}
|
||||
// If transaction is done, break
|
||||
if (status & PSSTS_DONE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If a timeout happened, return the error
|
||||
if (timeout == 0) {
|
||||
ps2_reset(ps2);
|
||||
return -0x1000;
|
||||
}
|
||||
if (read) {
|
||||
data[i] = *(ps2->data);
|
||||
}
|
||||
// Set interface to defaults
|
||||
ps2_reset(ps2);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length) {
|
||||
return ps2_transaction(ps2, data, length, true);
|
||||
}
|
||||
|
||||
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length) {
|
||||
return ps2_transaction(ps2, data, length, false);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user