diff --git a/common.mk b/common.mk
index 5b70db94..2ca06daa 100644
--- a/common.mk
+++ b/common.mk
@@ -25,6 +25,7 @@ endif
ifdef MOUSEKEY_ENABLE
SRC += $(COMMON_DIR)/mousekey.c
OPT_DEFS += -DMOUSEKEY_ENABLE
+ OPT_DEFS += -DMOUSE_ENABLE
endif
ifdef EXTRAKEY_ENABLE
@@ -47,16 +48,6 @@ ifdef NKRO_ENABLE
OPT_DEFS += -DNKRO_ENABLE
endif
-ifdef PS2_MOUSE_ENABLE
- SRC += $(COMMON_DIR)/ps2.c \
- $(COMMON_DIR)/ps2_mouse.c
- OPT_DEFS += -DPS2_MOUSE_ENABLE
-endif
-
-ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
- OPT_DEFS += -DMOUSE_ENABLE
-endif
-
ifdef SLEEP_LED_ENABLE
SRC += $(COMMON_DIR)/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE
diff --git a/common/action.c b/common/action.c
index f7ae85b9..485abf81 100644
--- a/common/action.c
+++ b/common/action.c
@@ -485,12 +485,6 @@ void clear_keyboard_but_mods(void)
#endif
}
-bool sending_anykey(void)
-{
- return (has_anykey() || host_mouse_in_use() ||
- host_last_sysytem_report() || host_last_consumer_report());
-}
-
bool is_tap_key(key_t key)
{
action_t action = layer_switch_get_action(key);
diff --git a/common/action.h b/common/action.h
index d57f4a86..077711c2 100644
--- a/common/action.h
+++ b/common/action.h
@@ -64,7 +64,6 @@ void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
-bool sending_anykey(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(key_t key);
diff --git a/common/action_util.h b/common/action_util.h
index 939bc2b6..f9d3161a 100644
--- a/common/action_util.h
+++ b/common/action_util.h
@@ -18,6 +18,7 @@ along with this program. If not, see .
#define ACTION_UTIL_H
#include
+#include "report.h"
extern report_keyboard_t *keyboard_report;
diff --git a/common/host.c b/common/host.c
index 0703dba0..1eafef75 100644
--- a/common/host.c
+++ b/common/host.c
@@ -27,9 +27,6 @@ along with this program. If not, see .
bool keyboard_nkro = false;
#endif
-report_mouse_t mouse_report = {};
-
-
static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
@@ -89,11 +86,6 @@ void host_consumer_send(uint16_t report)
(*driver->send_consumer)(report);
}
-uint8_t host_mouse_in_use(void)
-{
- return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
-}
-
uint16_t host_last_sysytem_report(void)
{
return last_system_report;
diff --git a/common/host.h b/common/host.h
index c1a0fbac..8ff26298 100644
--- a/common/host.h
+++ b/common/host.h
@@ -32,9 +32,6 @@ extern "C" {
extern bool keyboard_nkro;
#endif
-/* report */
-extern report_mouse_t mouse_report;
-
/* host driver */
void host_set_driver(host_driver_t *driver);
@@ -47,9 +44,6 @@ void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
-/* mouse report utils */
-uint8_t host_mouse_in_use(void);
-
uint16_t host_last_sysytem_report(void);
uint16_t host_last_consumer_report(void);
diff --git a/common/keyboard.c b/common/keyboard.c
index 601e3abe..2b66f20a 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -30,8 +30,13 @@ along with this program. If not, see .
#include "sendchar.h"
#include "bootmagic.h"
#include "eeconfig.h"
-#include "mousekey.h"
#include "backlight.h"
+#ifdef MOUSEKEY_ENABLE
+# include "mousekey.h"
+#endif
+#ifdef PS2_MOUSE_ENABLE
+# include "ps2_mouse.h"
+#endif
#ifdef MATRIX_HAS_GHOST
@@ -111,10 +116,16 @@ void keyboard_task(void)
action_exec(TICK);
MATRIX_LOOP_END:
+
#ifdef MOUSEKEY_ENABLE
// mousekey repeat & acceleration
mousekey_task();
#endif
+
+#ifdef PS2_MOUSE_ENABLE
+ ps2_mouse_task();
+#endif
+
// update LED
if (led_status != host_keyboard_leds()) {
led_status = host_keyboard_leds();
diff --git a/common/mousekey.c b/common/mousekey.c
index 3068fc5e..017be941 100644
--- a/common/mousekey.c
+++ b/common/mousekey.c
@@ -26,6 +26,7 @@ along with this program. If not, see .
+static report_mouse_t mouse_report = {};
static uint8_t mousekey_repeat = 0;
static uint8_t mousekey_accel = 0;
diff --git a/protocol.mk b/protocol.mk
index 1442c520..0d5f06c7 100644
--- a/protocol.mk
+++ b/protocol.mk
@@ -1,2 +1,27 @@
+PROTOCOL_DIR = protocol
+
+
+ifdef PS2_MOUSE_ENABLE
+ SRC += $(PROTOCOL_DIR)/ps2_mouse.c
+ OPT_DEFS += -DPS2_MOUSE_ENABLE
+ OPT_DEFS += -DMOUSE_ENABLE
+endif
+
+ifdef PS2_USE_BUSYWAIT
+ SRC += protocol/ps2.c
+ OPT_DEFS += -DPS2_USE_BUSYWAIT
+endif
+
+ifdef PS2_USE_INT
+ SRC += protocol/ps2.c
+ OPT_DEFS += -DPS2_USE_INT
+endif
+
+ifdef PS2_USE_USART
+ SRC += protocol/ps2_usart.c
+ OPT_DEFS += -DPS2_USE_USART
+endif
+
+
# Search Path
VPATH += $(TOP_DIR)/protocol
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index a230d5ba..04e8e78f 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -539,11 +539,18 @@ int main(void)
{
SetupHardware();
sei();
+
+ /* wait for USB startup & debug output */
+ while (USB_DeviceState != DEVICE_STATE_Configured) {
#if defined(INTERRUPT_CONTROL_ENDPOINT)
- while (USB_DeviceState != DEVICE_STATE_Configured) ;
+ ;
+#else
+ USB_USBTask();
#endif
+ }
print("USB configured.\n");
+ /* init modules */
keyboard_init();
host_set_driver(&lufa_driver);
#ifdef SLEEP_LED_ENABLE
diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk
index 27f908b1..5a446138 100644
--- a/protocol/pjrc.mk
+++ b/protocol/pjrc.mk
@@ -7,7 +7,11 @@ SRC += $(PJRC_DIR)/main.c \
$(PJRC_DIR)/usb.c
# Option modules
-ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
+ifdef MOUSEKEY_ENABLE
+ SRC += $(PJRC_DIR)/usb_mouse.c
+endif
+
+ifdef PS2_MOUSE_ENABLE
SRC += $(PJRC_DIR)/usb_mouse.c
endif
diff --git a/protocol/ps2.c b/protocol/ps2.c
index ed456091..e5873a9b 100644
--- a/protocol/ps2.c
+++ b/protocol/ps2.c
@@ -1,5 +1,5 @@
/*
-Copyright 2010,2011 Jun WAKO
+Copyright 2010,2011,2012,2013 Jun WAKO
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -43,7 +43,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "debug.h"
+#ifndef PS2_USE_INT
static uint8_t recv_data(void);
+#endif
static inline void clock_lo(void);
static inline void clock_hi(void);
static inline bool clock_in(void);
@@ -109,12 +111,12 @@ uint8_t ps2_host_send(uint8_t data)
#endif
/* terminate a transmission if we have */
inhibit();
- _delay_us(100);
+ _delay_us(200); // at least 100us
/* start bit [1] */
data_lo();
clock_hi();
- WAIT(clock_lo, 15000, 1);
+ WAIT(clock_lo, 20000, 10); // may take 15ms at most until device starts clocking
/* data [2-9] */
for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
@@ -143,6 +145,9 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
+#ifdef PS2_USE_INT
+ PS2_INT_ON();
+#endif
res = ps2_host_recv_response();
ERROR:
#ifdef PS2_USE_INT
@@ -154,11 +159,15 @@ ERROR:
return res;
}
+#ifndef PS2_USE_INT
/* receive data when host want else inhibit communication */
uint8_t ps2_host_recv_response(void)
{
uint8_t data = 0;
+#ifdef PS2_USE_INT
+ PS2_INT_OFF();
+#endif
/* terminate a transmission if we have */
inhibit();
_delay_us(100);
@@ -167,12 +176,13 @@ uint8_t ps2_host_recv_response(void)
idle();
/* wait start bit */
- wait_clock_lo(2000);
+ wait_clock_lo(25000); // command response may take 20 ms at most
data = recv_data();
inhibit();
return data;
}
+#endif
#ifndef PS2_USE_INT
uint8_t ps2_host_recv(void)
@@ -187,9 +197,6 @@ static uint8_t pbuf_head = 0;
static uint8_t pbuf_tail = 0;
static inline void pbuf_enqueue(uint8_t data)
{
- if (!data)
- return;
-
uint8_t sreg = SREG;
cli();
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
@@ -215,6 +222,21 @@ static inline uint8_t pbuf_dequeue(void)
return val;
}
+static inline bool pbuf_has_data(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ bool has_data = (pbuf_head != pbuf_tail);
+ SREG = sreg;
+ return has_data;
+}
+static inline void pbuf_clear(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ pbuf_head = pbuf_tail = 0;
+ SREG = sreg;
+}
/* get data received by interrupt */
uint8_t ps2_host_recv(void)
@@ -229,13 +251,12 @@ uint8_t ps2_host_recv(void)
return pbuf_dequeue();
}
-#if 0
-#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
-#define DEBUGP(x) do { PORTC = x; } while (0)
-#else
-#define DEBUGP_INIT()
-#define DEBUGP(x)
-#endif
+uint8_t ps2_host_recv_response(void)
+{
+ while (!pbuf_has_data()) ;
+ return pbuf_dequeue();
+}
+
ISR(PS2_INT_VECT)
{
static enum {
@@ -256,7 +277,6 @@ ISR(PS2_INT_VECT)
}
state++;
- DEBUGP(state);
switch (state) {
case START:
if (data_in())
@@ -289,6 +309,7 @@ ISR(PS2_INT_VECT)
if (!data_in())
goto ERROR;
pbuf_enqueue(data);
+//phex(data);
goto DONE;
break;
default:
@@ -296,7 +317,6 @@ ISR(PS2_INT_VECT)
}
goto RETURN;
ERROR:
- DEBUGP(0x0F);
inhibit();
ps2_error = state;
DONE:
@@ -309,11 +329,6 @@ RETURN:
#endif
-static void ps2_reset(void)
-{
- ps2_host_send(0xFF);
-}
-
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
{
@@ -322,6 +337,7 @@ void ps2_host_set_led(uint8_t led)
}
+#ifndef PS2_USE_INT
/* called after start bit comes */
static uint8_t recv_data(void)
{
@@ -361,6 +377,7 @@ static uint8_t recv_data(void)
ERROR:
return 0;
}
+#endif
static inline void clock_lo()
{
diff --git a/protocol/ps2_mouse.c b/protocol/ps2_mouse.c
index f796b2b4..4702f12c 100644
--- a/protocol/ps2_mouse.c
+++ b/protocol/ps2_mouse.c
@@ -1,5 +1,5 @@
/*
-Copyright 2011 Jun Wako
+Copyright 2011,2013 Jun Wako
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,199 +20,196 @@ along with this program. If not, see .
#include
#include "ps2.h"
#include "ps2_mouse.h"
-#include "usb_mouse.h"
-
-#define PS2_MOUSE_DEBUG
-#ifdef PS2_MOUSE_DEBUG
-# include "print.h"
-# include "debug.h"
-#else
-# define print(s)
-# define phex(h)
-# define phex16(h)
-#endif
-
-// disable when errors occur 255 times.
-#define ERROR_RETURN() do { \
- if (ps2_error) { \
- if (ps2_mouse_error_count < 255) { \
- ps2_mouse_error_count++; \
- } else { \
- ps2_mouse_error_count = 0; \
- ps2_mouse_enable = false; \
- } \
- return ps2_error; \
- } \
-} while (0)
+#include "report.h"
+#include "host.h"
+#include "timer.h"
+#include "print.h"
+#include "debug.h"
-/*
-TODO
-----
-- Stream mode
-- Tracpoint command support: needed
-- Middle button + move = Wheel traslation
-*/
-bool ps2_mouse_enable = true;
-uint8_t ps2_mouse_x = 0;
-uint8_t ps2_mouse_y = 0;
-uint8_t ps2_mouse_btn = 0;
-uint8_t ps2_mouse_error_count = 0;
-
-static uint8_t ps2_mouse_btn_prev = 0;
+static report_mouse_t mouse_report = {};
+static void print_usb_data(void);
+
+
+/* supports only 3 button mouse at this time */
uint8_t ps2_mouse_init(void) {
uint8_t rcv;
- if (!ps2_mouse_enable) return 1;
-
ps2_host_init();
- // Reset
+ _delay_ms(1000); // wait for powering up
+
+ // send Reset
rcv = ps2_host_send(0xFF);
- print("ps2_mouse_init: send 0xFF: ");
- phex(ps2_error); print("\n");
- ERROR_RETURN();
-
- // ACK
- rcv = ps2_host_recv();
- print("ps2_mouse_init: read ACK: ");
+ print("ps2_mouse_init: send Reset: ");
phex(rcv); phex(ps2_error); print("\n");
- ERROR_RETURN();
- // BAT takes some time
- _delay_ms(100);
- rcv = ps2_host_recv();
+ // read completion code of BAT
+ rcv = ps2_host_recv_response();
print("ps2_mouse_init: read BAT: ");
phex(rcv); phex(ps2_error); print("\n");
- ERROR_RETURN();
- // Device ID
- rcv = ps2_host_recv();
+ // read Device ID
+ rcv = ps2_host_recv_response();
print("ps2_mouse_init: read DevID: ");
phex(rcv); phex(ps2_error); print("\n");
- ERROR_RETURN();
- // Enable data reporting
- ps2_host_send(0xF4);
- print("ps2_mouse_init: send 0xF4: ");
- phex(ps2_error); print("\n");
- ERROR_RETURN();
-
- // ACK
- rcv = ps2_host_recv();
- print("ps2_mouse_init: read ACK: ");
- phex(rcv); phex(ps2_error); print("\n");
- ERROR_RETURN();
-
- // Set Remote mode
- ps2_host_send(0xF0);
+ // send Set Remote mode
+ rcv = ps2_host_send(0xF0);
print("ps2_mouse_init: send 0xF0: ");
- phex(ps2_error); print("\n");
- ERROR_RETURN();
-
- // ACK
- rcv = ps2_host_recv();
- print("ps2_mouse_init: read ACK: ");
phex(rcv); phex(ps2_error); print("\n");
- ERROR_RETURN();
return 0;
}
-/*
-Data format:
- bit: 7 6 5 4 3 2 1 0
------------------------------------------------------------------------
-0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left
-1 x: X movement(0-255)
-2 y: Y movement(0-255)
-*/
-uint8_t ps2_mouse_read(void)
+#define X_IS_NEG (mouse_report.buttons & (1< USB(-127/127)
- if (ps2_mouse_btn & (1< 128 ? (int8_t)ps2_mouse_x : -127;
- else
- x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127;
+ // remove sign and overflow flags
+ mouse_report.buttons &= PS2_MOUSE_BTN_MASK;
- if (ps2_mouse_btn & (1< 128 ? (int8_t)ps2_mouse_y : -127;
- else
- y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127;
+ // invert coordinate of y to conform to USB HID mouse
+ mouse_report.y = -mouse_report.y;
- // Y is needed to reverse
- y = -y;
- if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) {
- // scroll
- if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x));
- if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y));
- if (h || v) {
- scrolled = true;
- usb_mouse_send(0,0, -v/16, h/16, 0);
- _delay_ms(100);
+#if PS2_MOUSE_SCROLL_BTN_MASK
+ static uint16_t scroll_button_time = 0;
+ if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == (PS2_MOUSE_SCROLL_BTN_MASK)) {
+ if (scroll_state == SCROLL_NONE) {
+ scroll_button_time = timer_read();
+ scroll_state = SCROLL_BTN;
}
- } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) {
- usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON);
- _delay_ms(100);
- usb_mouse_send(0,0,0,0, 0);
- } else {
- scrolled = false;
- usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
- }
- ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
- ps2_mouse_print();
+ // doesn't send Scroll Button
+ //mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
+
+ if (mouse_report.x || mouse_report.y) {
+ scroll_state = SCROLL_SENT;
+
+ mouse_report.v = -mouse_report.y/(PS2_MOUSE_SCROLL_DIVISOR_V);
+ mouse_report.h = mouse_report.x/(PS2_MOUSE_SCROLL_DIVISOR_H);
+ mouse_report.x = 0;
+ mouse_report.y = 0;
+ //host_mouse_send(&mouse_report);
+ }
+ }
+ else if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == 0) {
+#if PS2_MOUSE_SCROLL_BTN_SEND
+ if (scroll_state == SCROLL_BTN &&
+ TIMER_DIFF_16(timer_read(), scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
+ // send Scroll Button(down and up at once) when not scrolled
+ mouse_report.buttons |= (PS2_MOUSE_SCROLL_BTN_MASK);
+ host_mouse_send(&mouse_report);
+ _delay_ms(100);
+ mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
+ }
+#endif
+ scroll_state = SCROLL_NONE;
+ }
+ // doesn't send Scroll Button
+ mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
+#endif
+
+
+ host_mouse_send(&mouse_report);
+ print_usb_data();
}
- ps2_mouse_x = 0;
- ps2_mouse_y = 0;
- ps2_mouse_btn = 0;
+ // clear report
+ mouse_report.x = 0;
+ mouse_report.y = 0;
+ mouse_report.v = 0;
+ mouse_report.h = 0;
+ mouse_report.buttons = 0;
}
-void ps2_mouse_print(void)
+static void print_usb_data(void)
{
if (!debug_mouse) return;
- print("ps2_mouse[btn|x y]: ");
- phex(ps2_mouse_btn); print("|");
- phex(ps2_mouse_x); print(" ");
- phex(ps2_mouse_y); print("\n");
+ print("ps2_mouse usb: [");
+ phex(mouse_report.buttons); print("|");
+ print_hex8((uint8_t)mouse_report.x); print(" ");
+ print_hex8((uint8_t)mouse_report.y); print(" ");
+ print_hex8((uint8_t)mouse_report.v); print(" ");
+ print_hex8((uint8_t)mouse_report.h); print("]\n");
}
+
+
+/* PS/2 Mouse Synopsis
+ * http://www.computer-engineering.org/ps2mouse/
+ *
+ * Command:
+ * 0xFF: Reset
+ * 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled
+ * 0xF5: Disable Data Reporting
+ * 0xF4: Enable Data Reporting
+ * 0xF3: Set Sample Rate
+ * 0xF2: Get Device ID
+ * 0xF0: Set Remote Mode
+ * 0xEB: Read Data
+ * 0xEA: Set Stream Mode
+ * 0xE9: Status Request
+ * 0xE8: Set Resolution
+ * 0xE7: Set Scaling 2:1
+ * 0xE6: Set Scaling 1:1
+ *
+ * Mode:
+ * Stream Mode: devices sends the data when it changs its state
+ * Remote Mode: host polls the data periodically
+ *
+ * This code uses Remote Mode and polls the data with Read Data(0xEB).
+ *
+ * Data format:
+ * byte|7 6 5 4 3 2 1 0
+ * ----+--------------------------------------------------------------
+ * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
+ * 1| X movement
+ * 2| Y movement
+ */
diff --git a/protocol/ps2_mouse.h b/protocol/ps2_mouse.h
index 4529ce11..27d9790d 100644
--- a/protocol/ps2_mouse.h
+++ b/protocol/ps2_mouse.h
@@ -20,6 +20,16 @@ along with this program. If not, see .
#include
+#define PS2_MOUSE_READ_DATA 0xEB
+
+/*
+ * Data format:
+ * byte|7 6 5 4 3 2 1 0
+ * ----+--------------------------------------------------------------
+ * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
+ * 1| X movement(0-255)
+ * 2| Y movement(0-255)
+ */
#define PS2_MOUSE_BTN_MASK 0x07
#define PS2_MOUSE_BTN_LEFT 0
#define PS2_MOUSE_BTN_RIGHT 1
@@ -29,16 +39,28 @@ along with this program. If not, see .
#define PS2_MOUSE_X_OVFLW 6
#define PS2_MOUSE_Y_OVFLW 7
-bool ps2_mouse_enable;
-extern uint8_t ps2_mouse_x;
-extern uint8_t ps2_mouse_y;
-extern uint8_t ps2_mouse_btn;
-extern uint8_t ps2_mouse_error_count;
+
+/*
+ * Scroll by mouse move with pressing button
+ */
+/* mouse button to start scrolling; set 0 to disable scroll */
+#ifndef PS2_MOUSE_SCROLL_BTN_MASK
+#define PS2_MOUSE_SCROLL_BTN_MASK (1<
+Copyright 2010,2011,2012,2013 Jun WAKO
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -64,14 +64,6 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
#include "debug.h"
-#if 0
-#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
-#define DEBUGP(x) do { PORTC = x; } while (0)
-#else
-#define DEBUGP_INIT()
-#define DEBUGP(x)
-#endif
-
#define WAIT(stat, us, err) do { \
if (!wait_##stat(us)) { \
ps2_error = err; \
@@ -97,12 +89,12 @@ static inline void idle(void);
static inline void inhibit(void);
static inline uint8_t pbuf_dequeue(void);
static inline void pbuf_enqueue(uint8_t data);
+static inline bool pbuf_has_data(void);
+static inline void pbuf_clear(void);
void ps2_host_init(void)
{
- DEBUGP_INIT();
- DEBUGP(0x1);
idle();
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
@@ -114,7 +106,6 @@ uint8_t ps2_host_send(uint8_t data)
bool parity = true;
ps2_error = PS2_ERR_NONE;
- DEBUGP(0x6);
PS2_USART_OFF();
/* terminate a transmission if we have */
@@ -153,6 +144,8 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
+ PS2_USART_INIT();
+ PS2_USART_RX_INT_ON();
res = ps2_host_recv_response();
ERROR:
idle();
@@ -164,15 +157,10 @@ ERROR:
// Do polling data from keyboard to get response to last command.
uint8_t ps2_host_recv_response(void)
{
- uint8_t data = 0;
- PS2_USART_INIT();
- PS2_USART_RX_POLL_ON();
- while (!PS2_USART_RX_READY)
- ;
- data = PS2_USART_RX_DATA;
- PS2_USART_OFF();
- DEBUGP(0x9);
- return data;
+ while (!pbuf_has_data()) {
+ _delay_ms(1); // without this delay it seems to fall into deadlock
+ }
+ return pbuf_dequeue();
}
uint8_t ps2_host_recv(void)
@@ -182,15 +170,11 @@ uint8_t ps2_host_recv(void)
ISR(PS2_USART_RX_VECT)
{
- DEBUGP(0x7);
uint8_t error = PS2_USART_ERROR;
uint8_t data = PS2_USART_RX_DATA;
- if (error) {
- DEBUGP(error>>2);
- } else {
+ if (!error) {
pbuf_enqueue(data);
}
- DEBUGP(0x8);
}
/* send LED state to keyboard */
@@ -293,9 +277,6 @@ static uint8_t pbuf_head = 0;
static uint8_t pbuf_tail = 0;
static inline void pbuf_enqueue(uint8_t data)
{
- if (!data)
- return;
-
uint8_t sreg = SREG;
cli();
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
@@ -322,3 +303,18 @@ static inline uint8_t pbuf_dequeue(void)
return val;
}
+static inline bool pbuf_has_data(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ bool has_data = (pbuf_head != pbuf_tail);
+ SREG = sreg;
+ return has_data;
+}
+static inline void pbuf_clear(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ pbuf_head = pbuf_tail = 0;
+ SREG = sreg;
+}