aboutsummaryrefslogtreecommitdiffstats
path: root/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'protocol')
-rw-r--r--protocol/lufa/lufa.c15
-rw-r--r--protocol/mbed/HIDKeyboard.cpp271
-rw-r--r--protocol/mbed/HIDKeyboard.h31
-rw-r--r--protocol/mbed/mbed_driver.cpp41
-rw-r--r--protocol/mbed/mbed_driver.h3
-rw-r--r--protocol/ps2.h65
-rw-r--r--protocol/ps2_busywait.c16
-rw-r--r--protocol/ps2_io.h15
-rw-r--r--protocol/ps2_io_avr.c74
-rw-r--r--protocol/ps2_io_mbed.c60
-rw-r--r--protocol/serial_uart.c21
11 files changed, 546 insertions, 66 deletions
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index 16a602df1..6802f3b63 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -148,10 +148,23 @@ static void Console_Task(void)
*/
void EVENT_USB_Device_Connect(void)
{
+ /* For battery powered device */
+ if (!USB_IsInitialized) {
+ USB_Init();
+ USB_Device_EnableSOFEvents();
+ }
}
void EVENT_USB_Device_Disconnect(void)
{
+ /* For battery powered device */
+/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
+ if (USB_IsInitialized) {
+ USB_Disable(); // Disable all interrupts
+ USB_Controller_Enable();
+ USB_INT_Enable(USB_INT_VBUSTI);
+ }
+*/
}
void EVENT_USB_Device_Reset(void)
@@ -574,7 +587,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) {
- suspend_power_down();
+ suspend_power_down(WDTO_120MS);
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
USB_Device_SendRemoteWakeup();
}
diff --git a/protocol/mbed/HIDKeyboard.cpp b/protocol/mbed/HIDKeyboard.cpp
new file mode 100644
index 000000000..947077cd2
--- /dev/null
+++ b/protocol/mbed/HIDKeyboard.cpp
@@ -0,0 +1,271 @@
+#include <stdint.h>
+#include "USBHID.h"
+#include "USBHID_Types.h"
+#include "USBDescriptor.h"
+#include "HIDKeyboard.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+
+HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
+{
+ USBDevice::connect();
+}
+
+bool HIDKeyboard::sendReport(report_keyboard_t report) {
+ USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
+ return true;
+}
+
+uint8_t HIDKeyboard::leds() {
+ return led_state;
+}
+
+bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
+ if (configuration != DEFAULT_CONFIGURATION) {
+ return false;
+ }
+
+ // Configure endpoints > 0
+ addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+ //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+ // We activate the endpoint to be able to recceive data
+ //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+ return true;
+}
+
+
+uint8_t * HIDKeyboard::stringImanufacturerDesc() {
+ static uint8_t stringImanufacturerDescriptor[] = {
+ 0x18, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
+ };
+ return stringImanufacturerDescriptor;
+}
+
+uint8_t * HIDKeyboard::stringIproductDesc() {
+ static uint8_t stringIproductDescriptor[] = {
+ 0x0a, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
+ };
+ return stringIproductDescriptor;
+}
+
+uint8_t * HIDKeyboard::stringIserialDesc() {
+ static uint8_t stringIserialDescriptor[] = {
+ 0x04, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ '0',0 /*bString iSerial*/
+ };
+ return stringIserialDescriptor;
+}
+
+uint8_t * HIDKeyboard::reportDesc() {
+ static uint8_t reportDescriptor[] = {
+ USAGE_PAGE(1), 0x01, // Generic Desktop
+ USAGE(1), 0x06, // Keyboard
+ COLLECTION(1), 0x01, // Application
+
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0xE0,
+ USAGE_MAXIMUM(1), 0xE7,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x01,
+ REPORT_SIZE(1), 0x01,
+ REPORT_COUNT(1), 0x08,
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x08,
+ INPUT(1), 0x01, // Constant
+
+ REPORT_COUNT(1), 0x05,
+ REPORT_SIZE(1), 0x01,
+ USAGE_PAGE(1), 0x08, // LEDs
+ USAGE_MINIMUM(1), 0x01,
+ USAGE_MAXIMUM(1), 0x05,
+ OUTPUT(1), 0x02, // Data, Variable, Absolute
+
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x03,
+ OUTPUT(1), 0x01, // Constant
+
+
+ REPORT_COUNT(1), 0x06,
+ REPORT_SIZE(1), 0x08,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0xFF,
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0x00,
+ USAGE_MAXIMUM(1), 0xFF,
+ INPUT(1), 0x00, // Data, Array
+ END_COLLECTION(0),
+ };
+ reportLength = sizeof(reportDescriptor);
+ return reportDescriptor;
+}
+
+uint16_t HIDKeyboard::reportDescLength() {
+ reportDesc();
+ return reportLength;
+}
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ + (1 * HID_DESCRIPTOR_LENGTH) \
+ + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
+uint8_t * HIDKeyboard::configurationDesc() {
+ static uint8_t configurationDescriptor[] = {
+ CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+ CONFIGURATION_DESCRIPTOR, // bDescriptorType
+ LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
+ MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
+ 0x01, // bNumInterfaces
+ DEFAULT_CONFIGURATION, // bConfigurationValue
+ 0x00, // iConfiguration
+ C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
+ C_POWER(100), // bMaxPowerHello World from Mbed
+
+ INTERFACE_DESCRIPTOR_LENGTH, // bLength
+ INTERFACE_DESCRIPTOR, // bDescriptorType
+ 0x00, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x01, // bNumEndpoints
+ HID_CLASS, // bInterfaceClass
+ 1, // bInterfaceSubClass (boot)
+ 1, // bInterfaceProtocol (keyboard)
+ 0x00, // iInterface
+
+ HID_DESCRIPTOR_LENGTH, // bLength
+ HID_DESCRIPTOR, // bDescriptorType
+ LSB(HID_VERSION_1_11), // bcdHID (LSB)
+ MSB(HID_VERSION_1_11), // bcdHID (MSB)
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ REPORT_DESCRIPTOR, // bDescriptorType
+ (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
+ (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EP1IN), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+ };
+ return configurationDescriptor;
+}
+
+#if 0
+uint8_t * HIDKeyboard::deviceDesc() {
+ static uint8_t deviceDescriptor[] = {
+ DEVICE_DESCRIPTOR_LENGTH, /* bLength */
+ DEVICE_DESCRIPTOR, /* bDescriptorType */
+ LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
+ MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
+ 0x00, /* bDeviceClass */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceprotocol */
+ MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
+ (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
+ (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
+ (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
+ (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
+ (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
+ (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
+ 0, /* iManufacturer */
+ 0, /* iProduct */
+ 0, /* iSerialNumber */
+ 0x01 /* bNumConfigurations */
+ };
+ return deviceDescriptor;
+}
+#endif
+
+bool HIDKeyboard::USBCallback_request() {
+ bool success = false;
+ CONTROL_TRANSFER * transfer = getTransferPtr();
+ uint8_t *hidDescriptor;
+
+ // Process additional standard requests
+
+ if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
+ {
+ switch (transfer->setup.bRequest)
+ {
+ case GET_DESCRIPTOR:
+ switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
+ {
+ case REPORT_DESCRIPTOR:
+ if ((reportDesc() != NULL) \
+ && (reportDescLength() != 0))
+ {
+ transfer->remaining = reportDescLength();
+ transfer->ptr = reportDesc();
+ transfer->direction = DEVICE_TO_HOST;
+ success = true;
+ }
+ break;
+ case HID_DESCRIPTOR:
+ // Find the HID descriptor, after the configuration descriptor
+ hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+ if (hidDescriptor != NULL)
+ {
+ transfer->remaining = HID_DESCRIPTOR_LENGTH;
+ transfer->ptr = hidDescriptor;
+ transfer->direction = DEVICE_TO_HOST;
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Process class-specific requests
+ if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
+ {
+ switch (transfer->setup.bRequest) {
+ case SET_REPORT:
+ // LED indicator
+ // TODO: check Interface and Report length?
+ // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
+ // if (transfer->setup.wLength == 1)
+
+ transfer->remaining = 1;
+ //transfer->ptr = ?? what ptr should be set when OUT(not used?)
+ transfer->direction = HOST_TO_DEVICE;
+ transfer->notify = true; /* notify with USBCallback_requestCompleted */
+ success = true;
+ default:
+ break;
+ }
+ }
+
+ return success;
+}
+
+void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
+{
+ if (length > 0) {
+ CONTROL_TRANSFER *transfer = getTransferPtr();
+ if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+ switch (transfer->setup.bRequest) {
+ case SET_REPORT:
+ led_state = buf[0];
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/protocol/mbed/HIDKeyboard.h b/protocol/mbed/HIDKeyboard.h
new file mode 100644
index 000000000..c537e5ece
--- /dev/null
+++ b/protocol/mbed/HIDKeyboard.h
@@ -0,0 +1,31 @@
+#ifndef HIDKEYBOARD_H
+
+#include "stdint.h"
+#include "stdbool.h"
+#include "USBHID.h"
+#include "report.h"
+
+
+class HIDKeyboard : public USBDevice {
+public:
+ HIDKeyboard(uint16_t vendor_id = 0xFEED, uint16_t product_id = 0xabed, uint16_t product_release = 0x0001);
+
+ bool sendReport(report_keyboard_t report);
+ uint8_t leds(void);
+protected:
+ uint16_t reportLength;
+ virtual bool USBCallback_setConfiguration(uint8_t configuration);
+ virtual uint8_t * stringImanufacturerDesc();
+ virtual uint8_t * stringIproductDesc();
+ virtual uint8_t * stringIserialDesc();
+ virtual uint16_t reportDescLength();
+ virtual uint8_t * reportDesc();
+ virtual uint8_t * configurationDesc();
+ //virtual uint8_t * deviceDesc();
+ virtual bool USBCallback_request();
+ virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
+private:
+ uint8_t led_state;
+};
+
+#endif
diff --git a/protocol/mbed/mbed_driver.cpp b/protocol/mbed/mbed_driver.cpp
new file mode 100644
index 000000000..6c7b16e23
--- /dev/null
+++ b/protocol/mbed/mbed_driver.cpp
@@ -0,0 +1,41 @@
+#include "HIDKeyboard.h"
+#include "host.h"
+#include "host_driver.h"
+#include "mbed_driver.h"
+
+HIDKeyboard keyboard;
+
+
+/* Host driver */
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+host_driver_t mbed_driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
+
+
+static uint8_t keyboard_leds(void)
+{
+ return keyboard.leds();
+}
+static void send_keyboard(report_keyboard_t *report)
+{
+ keyboard.sendReport(*report);
+}
+static void send_mouse(report_mouse_t *report)
+{
+}
+static void send_system(uint16_t data)
+{
+}
+static void send_consumer(uint16_t data)
+{
+}
diff --git a/protocol/mbed/mbed_driver.h b/protocol/mbed/mbed_driver.h
new file mode 100644
index 000000000..dd1153b43
--- /dev/null
+++ b/protocol/mbed/mbed_driver.h
@@ -0,0 +1,3 @@
+#include "host_driver.h"
+
+extern host_driver_t mbed_driver;
diff --git a/protocol/ps2.h b/protocol/ps2.h
index 483eea720..acde679cf 100644
--- a/protocol/ps2.h
+++ b/protocol/ps2.h
@@ -39,8 +39,9 @@ POSSIBILITY OF SUCH DAMAGE.
#define PS2_H
#include <stdbool.h>
-#include <util/delay.h>
-#include <avr/io.h>
+#include "wait.h"
+#include "ps2_io.h"
+#include "print.h"
/*
* Primitive PS/2 Library for AVR
@@ -92,79 +93,27 @@ uint8_t ps2_host_recv(void);
void ps2_host_set_led(uint8_t usb_led);
-/* Check port settings for clock and data line */
-#if !(defined(PS2_CLOCK_PORT) && \
- defined(PS2_CLOCK_PIN) && \
- defined(PS2_CLOCK_DDR) && \
- defined(PS2_CLOCK_BIT))
-# error "PS/2 clock port setting is required in config.h"
-#endif
-
-#if !(defined(PS2_DATA_PORT) && \
- defined(PS2_DATA_PIN) && \
- defined(PS2_DATA_DDR) && \
- defined(PS2_DATA_BIT))
-# error "PS/2 data port setting is required in config.h"
-#endif
-
/*--------------------------------------------------------------------
* static functions
*------------------------------------------------------------------*/
-static inline void clock_lo(void)
-{
- PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
-}
-static inline void clock_hi(void)
-{
- /* input with pull up */
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
-}
-static inline bool clock_in(void)
-{
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
- _delay_us(1);
- return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
-}
-static inline void data_lo(void)
-{
- PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
-}
-static inline void data_hi(void)
-{
- /* input with pull up */
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
-}
-static inline bool data_in(void)
-{
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
- _delay_us(1);
- return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
-}
-
static inline uint16_t wait_clock_lo(uint16_t us)
{
- while (clock_in() && us) { asm(""); _delay_us(1); us--; }
+ while (clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_clock_hi(uint16_t us)
{
- while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
+ while (!clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_data_lo(uint16_t us)
{
- while (data_in() && us) { asm(""); _delay_us(1); us--; }
+ while (data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_data_hi(uint16_t us)
{
- while (!data_in() && us) { asm(""); _delay_us(1); us--; }
+ while (!data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
diff --git a/protocol/ps2_busywait.c b/protocol/ps2_busywait.c
index 05dd7b27e..a64933219 100644
--- a/protocol/ps2_busywait.c
+++ b/protocol/ps2_busywait.c
@@ -40,8 +40,9 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdbool.h>
-#include <util/delay.h>
+#include "wait.h"
#include "ps2.h"
+#include "ps2_io.h"
#include "debug.h"
@@ -58,8 +59,11 @@ uint8_t ps2_error = PS2_ERR_NONE;
void ps2_host_init(void)
{
+ clock_init();
+ data_init();
+
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
- _delay_ms(2500);
+ wait_ms(2500);
inhibit();
}
@@ -71,7 +75,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();
@@ -80,7 +84,7 @@ uint8_t ps2_host_send(uint8_t data)
/* Data bit */
for (uint8_t i = 0; i < 8; i++) {
- _delay_us(15);
+ wait_us(15);
if (data&(1<<i)) {
parity = !parity;
data_hi();
@@ -92,13 +96,13 @@ uint8_t ps2_host_send(uint8_t data)
}
/* Parity bit */
- _delay_us(15);
+ wait_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
/* Stop bit */
- _delay_us(15);
+ wait_us(15);
data_hi();
/* Ack */
diff --git a/protocol/ps2_io.h b/protocol/ps2_io.h
new file mode 100644
index 000000000..a46a358e7
--- /dev/null
+++ b/protocol/ps2_io.h
@@ -0,0 +1,15 @@
+#ifndef PS2_IO_H
+#define PS2_IO_H
+
+
+void clock_init(void);
+void clock_lo(void);
+void clock_hi(void);
+bool clock_in(void);
+
+void data_init(void);
+void data_lo(void);
+void data_hi(void);
+bool data_in(void);
+
+#endif
diff --git a/protocol/ps2_io_avr.c b/protocol/ps2_io_avr.c
new file mode 100644
index 000000000..be13d6696
--- /dev/null
+++ b/protocol/ps2_io_avr.c
@@ -0,0 +1,74 @@
+#include <stdbool.h>
+#include <util/delay.h>
+
+/* Check port settings for clock and data line */
+#if !(defined(PS2_CLOCK_PORT) && \
+ defined(PS2_CLOCK_PIN) && \
+ defined(PS2_CLOCK_DDR) && \
+ defined(PS2_CLOCK_BIT))
+# error "PS/2 clock port setting is required in config.h"
+#endif
+
+#if !(defined(PS2_DATA_PORT) && \
+ defined(PS2_DATA_PIN) && \
+ defined(PS2_DATA_DDR) && \
+ defined(PS2_DATA_BIT))
+# error "PS/2 data port setting is required in config.h"
+#endif
+
+
+/*
+ * Clock
+ */
+void clock_init(void)
+{
+}
+
+void clock_lo(void)
+{
+ PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
+}
+
+void clock_hi(void)
+{
+ /* input with pull up */
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
+}
+
+bool clock_in(void)
+{
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
+ _delay_us(1);
+ return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
+}
+
+/*
+ * Data
+ */
+void data_init(void)
+{
+}
+
+void data_lo(void)
+{
+ PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
+}
+
+void data_hi(void)
+{
+ /* input with pull up */
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
+}
+
+bool data_in(void)
+{
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
+ _delay_us(1);
+ return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
+}
diff --git a/protocol/ps2_io_mbed.c b/protocol/ps2_io_mbed.c
new file mode 100644
index 000000000..83bdcef7f
--- /dev/null
+++ b/protocol/ps2_io_mbed.c
@@ -0,0 +1,60 @@
+#include <stdbool.h>
+#include "ps2_io.h"
+#include "gpio_api.h"
+
+
+static gpio_t clock;
+static gpio_t data;
+
+/*
+ * Clock
+ */
+void clock_init(void)
+{
+ gpio_init(&clock, P0_9);
+ gpio_mode(&clock, OpenDrain|PullNone);
+}
+
+void clock_lo(void)
+{
+ gpio_dir(&clock, PIN_OUTPUT);
+ gpio_write(&clock, 0);
+}
+void clock_hi(void)
+{
+ gpio_dir(&clock, PIN_OUTPUT);
+ gpio_write(&clock, 1);
+}
+
+bool clock_in(void)
+{
+ gpio_dir(&clock, PIN_INPUT);
+ return gpio_read(&clock);
+}
+
+/*
+ * Data
+ */
+void data_init(void)
+{
+ gpio_init(&data, P0_8);
+ gpio_mode(&data, OpenDrain|PullNone);
+}
+
+void data_lo(void)
+{
+ gpio_dir(&data, PIN_OUTPUT);
+ gpio_write(&data, 0);
+}
+
+void data_hi(void)
+{
+ gpio_dir(&data, PIN_OUTPUT);
+ gpio_write(&data, 1);
+}
+
+bool data_in(void)
+{
+ gpio_dir(&data, PIN_INPUT);
+ return gpio_read(&data);
+}
diff --git a/protocol/serial_uart.c b/protocol/serial_uart.c
index 6c0af8817..35df27fd6 100644
--- a/protocol/serial_uart.c
+++ b/protocol/serial_uart.c
@@ -41,13 +41,29 @@ POSSIBILITY OF SUCH DAMAGE.
#include "serial.h"
+#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
+ // Buffer state
+ // Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
+ // Last 1 space: RBUF_SPACE == 2
+ // Full: RBUF_SPACE == 1(last cell of rbuf be never used.)
+ #define RBUF_SPACE() (rbuf_head < rbuf_tail ? (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
+ // allow to send
+ #define rbuf_check_rts_lo() do { if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); } while (0)
+ // prohibit to send
+ #define rbuf_check_rts_hi() do { if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); } while (0)
+#else
+ #define rbuf_check_rts_lo()
+ #define rbuf_check_rts_hi()
+#endif
+
+
void serial_init(void)
{
SERIAL_UART_INIT();
}
// RX ring buffer
-#define RBUF_SIZE 8
+#define RBUF_SIZE 256
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;
@@ -61,6 +77,7 @@ uint8_t serial_recv(void)
data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
+ rbuf_check_rts_lo();
return data;
}
@@ -73,6 +90,7 @@ int16_t serial_recv2(void)
data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
+ rbuf_check_rts_lo();
return data;
}
@@ -90,4 +108,5 @@ ISR(SERIAL_UART_RXD_VECT)
rbuf[rbuf_head] = SERIAL_UART_DATA;
rbuf_head = next;
}
+ rbuf_check_rts_hi();
}