From 04f351b80279c55dfc6c8028f95eab7e01d50c84 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 7 Feb 2011 14:59:07 +0900 Subject: [PATCH] PS/2 library receives data partially by interrupt --- ps2.c | 185 ++++++++++++++++++++++++++++++++++--------- ps2.h | 10 ++- ps2_vusb/config.h | 28 ++++++- ps2_vusb/host.h | 1 + ps2_vusb/host_vusb.c | 73 ++++++++++++++--- ps2_vusb/host_vusb.h | 1 - ps2_vusb/keyboard.c | 18 +++++ ps2_vusb/keyboard.h | 1 + ps2_vusb/main.c | 12 +++ ps2_vusb/matrix.c | 54 +------------ ps2_vusb/usbconfig.h | 2 +- 11 files changed, 277 insertions(+), 108 deletions(-) diff --git a/ps2.c b/ps2.c index dd5b24129f..f7aaf96e3f 100644 --- a/ps2.c +++ b/ps2.c @@ -1,5 +1,5 @@ /* -Copyright (c) 2010 Jun WAKO +Copyright (c) 2010,2011 Jun WAKO This software is licensed with a Modified BSD License. All of this is supposed to be Free Software, Open Source, DFSG-free, @@ -36,12 +36,13 @@ POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include #include #include "ps2.h" -#include "print.h" #include "debug.h" +static uint8_t recv_data(void); static inline void clock_lo(void); static inline void clock_hi(void); static inline bool clock_in(void); @@ -52,6 +53,8 @@ static inline uint16_t wait_clock_lo(uint16_t us); static inline uint16_t wait_clock_hi(uint16_t us); static inline uint16_t wait_data_lo(uint16_t us); static inline uint16_t wait_data_hi(uint16_t us); +static inline void idle(void); +static inline void inhibit(void); /* @@ -79,38 +82,38 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf } \ } while (0) -#define WAIT_NORETRY(stat, us, err) do { \ - if (!wait_##stat(us)) { \ - ps2_error = err; \ - return 0; \ - } \ -} while (0) - uint8_t ps2_error = PS2_ERR_NONE; void ps2_host_init(void) { - /* inhibit */ - clock_lo(); - data_hi(); +#ifdef PS2_INT_ENABLE + PS2_INT_ENABLE(); + idle(); +#else + inhibit(); +#endif } uint8_t ps2_host_send(uint8_t data) { - bool parity = true; + bool parity; +RETRY: + parity = true; ps2_error = 0; - /* request to send */ - clock_lo(); + /* terminate a transmission if we have */ + inhibit(); _delay_us(100); + /* start bit [1] */ data_lo(); clock_hi(); WAIT(clock_lo, 15000, 1); /* data [2-9] */ for (uint8_t i = 0; i < 8; i++) { + _delay_us(15); if (data&(1< +Copyright (c) 2010,2011 Jun WAKO This software is licensed with a Modified BSD License. All of this is supposed to be Free Software, Open Source, DFSG-free, @@ -66,11 +66,13 @@ POSSIBILITY OF SUCH DAMAGE. extern uint8_t ps2_error; -/* host side */ +/* host role */ void ps2_host_init(void); -uint8_t ps2_host_send(uint8_t); +uint8_t ps2_host_send(uint8_t data); +uint8_t ps2_host_recv_response(void); uint8_t ps2_host_recv(void); +void ps2_host_set_led(uint8_t usb_led); -/* TODO: device side */ +/* device role */ #endif diff --git a/ps2_vusb/config.h b/ps2_vusb/config.h index 1d2a283071..639a1ac719 100644 --- a/ps2_vusb/config.h +++ b/ps2_vusb/config.h @@ -23,14 +23,38 @@ # define MOUSEKEY_DELAY_TIME 255 #endif -/* PS/2 mouse */ +/* PS/2 lines */ #define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PIN PIND #define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 6 +#define PS2_CLOCK_BIT 3 #define PS2_DATA_PORT PORTD #define PS2_DATA_PIN PIND #define PS2_DATA_DDR DDRD #define PS2_DATA_BIT 7 +/* External interrupt for PS/2 clock line (optional) */ +#define PS2_INT_ENABLE() do { \ + EIMSK |= (1<bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ + /* print("CLASS: "); - phex(rq->bRequest); + phex(rq->bRequest); print(" "); + phex16(rq->wValue.word); print(" "); + phex16(rq->wIndex.word); print(" "); + phex16(rq->wLength.word); print(" "); + */ if(rq->bRequest == USBRQ_HID_GET_REPORT){ - print("GET_REPORT"); + print(" GET_REPORT"); /* we only have one report type, so don't look at wValue */ usbMsgPtr = (void *)keyboard_report; return sizeof(*keyboard_report); }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ - print("GET_IDLE: "); + print(" GET_IDLE: "); phex(idleRate); usbMsgPtr = &idleRate; return 1; }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ idleRate = rq->wValue.bytes[1]; - print("SET_IDLE: "); + print(" SET_IDLE: "); phex(idleRate); + }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ + //print(" SET_REPORT: "); + if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { + last_req.kind = SET_LED; + last_req.len = rq->wLength.word; + } + return USB_NO_MSG; // to get data in usbFunctionWrite } print("\n"); }else{ @@ -79,6 +112,26 @@ usbRequest_t *rq = (void *)data; return 0; /* default for not implemented requests: return no data back to host */ } +uchar usbFunctionWrite(uchar *data, uchar len) +{ + if (last_req.len == 0) { + return -1; + } + switch (last_req.kind) { + case SET_LED: + //print("SET_LED\n"); + host_keyboard_led = data[0]; + last_req.len = 0; + return 1; + break; + case NONE: + default: + return -1; + break; + } + return 1; +} + PROGMEM uchar keyboard_hid_report[] = { 0x05, 0x01, // Usage Page (Generic Desktop), diff --git a/ps2_vusb/host_vusb.h b/ps2_vusb/host_vusb.h index c9b1d77671..f09ad58228 100644 --- a/ps2_vusb/host_vusb.h +++ b/ps2_vusb/host_vusb.h @@ -4,4 +4,3 @@ void host_vusb_keyboard_send(void); #endif - diff --git a/ps2_vusb/keyboard.c b/ps2_vusb/keyboard.c index 95f65887f8..c480908f84 100644 --- a/ps2_vusb/keyboard.c +++ b/ps2_vusb/keyboard.c @@ -1,12 +1,30 @@ #include "usb_keycodes.h" #include "host.h" +#include "ps2.h" +#include "usb.h" #include "keyboard.h" +#include "print.h" static report_keyboard_t report0; static report_keyboard_t report1; static report_keyboard_t *report = &report0; static report_keyboard_t *report_prev = &report1; + +void keyboard_set_led(uint8_t usb_led) +{ + uint8_t ps2_led = 0; + if (usb_led & (1<