aboutsummaryrefslogtreecommitdiff
path: root/protocol
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2014-11-24 13:50:33 +0900
committertmk <nobody@nowhere>2014-11-24 13:50:33 +0900
commit363950982a291c3bfa03ac6362061b1d37dc06b0 (patch)
treec46fc53fe00137ced3c8edd3d0766ee844f77516 /protocol
parenteb90ed6238426db9367e294abfaefb5de07564f5 (diff)
parent60096e11c77980ca6b54674c5b68248e8aa15d8d (diff)
downloadqmk_firmware-363950982a291c3bfa03ac6362061b1d37dc06b0.tar.gz
qmk_firmware-363950982a291c3bfa03ac6362061b1d37dc06b0.zip
Merge branch 'rn42' into merge_rn42
Conflicts: .gitignore common.mk common/debug_config.h common/print.h
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)
148*/ 148*/
149void EVENT_USB_Device_Connect(void) 149void EVENT_USB_Device_Connect(void)
150{ 150{
151 /* For battery powered device */
152 if (!USB_IsInitialized) {
153 USB_Init();
154 USB_Device_EnableSOFEvents();
155 }
151} 156}
152 157
153void EVENT_USB_Device_Disconnect(void) 158void EVENT_USB_Device_Disconnect(void)
154{ 159{
160 /* For battery powered device */
161/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
162 if (USB_IsInitialized) {
163 USB_Disable(); // Disable all interrupts
164 USB_Controller_Enable();
165 USB_INT_Enable(USB_INT_VBUSTI);
166 }
167*/
155} 168}
156 169
157void EVENT_USB_Device_Reset(void) 170void EVENT_USB_Device_Reset(void)
@@ -574,7 +587,7 @@ int main(void)
574 print("Keyboard start.\n"); 587 print("Keyboard start.\n");
575 while (1) { 588 while (1) {
576 while (USB_DeviceState == DEVICE_STATE_Suspended) { 589 while (USB_DeviceState == DEVICE_STATE_Suspended) {
577 suspend_power_down(); 590 suspend_power_down(WDTO_120MS);
578 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { 591 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
579 USB_Device_SendRemoteWakeup(); 592 USB_Device_SendRemoteWakeup();
580 } 593 }
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 @@
1#include <stdint.h>
2#include "USBHID.h"
3#include "USBHID_Types.h"
4#include "USBDescriptor.h"
5#include "HIDKeyboard.h"
6
7#define DEFAULT_CONFIGURATION (1)
8
9
10HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
11{
12 USBDevice::connect();
13}
14
15bool HIDKeyboard::sendReport(report_keyboard_t report) {
16 USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
17 return true;
18}
19
20uint8_t HIDKeyboard::leds() {
21 return led_state;
22}
23
24bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
25 if (configuration != DEFAULT_CONFIGURATION) {
26 return false;
27 }
28
29 // Configure endpoints > 0
30 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
31 //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
32
33 // We activate the endpoint to be able to recceive data
34 //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
35 return true;
36}
37
38
39uint8_t * HIDKeyboard::stringImanufacturerDesc() {
40 static uint8_t stringImanufacturerDescriptor[] = {
41 0x18, /*bLength*/
42 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
43 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
44 };
45 return stringImanufacturerDescriptor;
46}
47
48uint8_t * HIDKeyboard::stringIproductDesc() {
49 static uint8_t stringIproductDescriptor[] = {
50 0x0a, /*bLength*/
51 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
52 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
53 };
54 return stringIproductDescriptor;
55}
56
57uint8_t * HIDKeyboard::stringIserialDesc() {
58 static uint8_t stringIserialDescriptor[] = {
59 0x04, /*bLength*/
60 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
61 '0',0 /*bString iSerial*/
62 };
63 return stringIserialDescriptor;
64}
65
66uint8_t * HIDKeyboard::reportDesc() {
67 static uint8_t reportDescriptor[] = {
68 USAGE_PAGE(1), 0x01, // Generic Desktop
69 USAGE(1), 0x06, // Keyboard
70 COLLECTION(1), 0x01, // Application
71
72 USAGE_PAGE(1), 0x07, // Key Codes
73 USAGE_MINIMUM(1), 0xE0,
74 USAGE_MAXIMUM(1), 0xE7,
75 LOGICAL_MINIMUM(1), 0x00,
76 LOGICAL_MAXIMUM(1), 0x01,
77 REPORT_SIZE(1), 0x01,
78 REPORT_COUNT(1), 0x08,
79 INPUT(1), 0x02, // Data, Variable, Absolute
80
81 REPORT_COUNT(1), 0x01,
82 REPORT_SIZE(1), 0x08,
83 INPUT(1), 0x01, // Constant
84
85 REPORT_COUNT(1), 0x05,
86 REPORT_SIZE(1), 0x01,
87 USAGE_PAGE(1), 0x08, // LEDs
88 USAGE_MINIMUM(1), 0x01,
89 USAGE_MAXIMUM(1), 0x05,
90 OUTPUT(1), 0x02, // Data, Variable, Absolute
91
92 REPORT_COUNT(1), 0x01,
93 REPORT_SIZE(1), 0x03,
94 OUTPUT(1), 0x01, // Constant
95
96
97 REPORT_COUNT(1), 0x06,
98 REPORT_SIZE(1), 0x08,
99 LOGICAL_MINIMUM(1), 0x00,
100 LOGICAL_MAXIMUM(1), 0xFF,
101 USAGE_PAGE(1), 0x07, // Key Codes
102 USAGE_MINIMUM(1), 0x00,
103 USAGE_MAXIMUM(1), 0xFF,
104 INPUT(1), 0x00, // Data, Array
105 END_COLLECTION(0),
106 };
107 reportLength = sizeof(reportDescriptor);
108 return reportDescriptor;
109}
110
111uint16_t HIDKeyboard::reportDescLength() {
112 reportDesc();
113 return reportLength;
114}
115
116#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
117 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
118 + (1 * HID_DESCRIPTOR_LENGTH) \
119 + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
120uint8_t * HIDKeyboard::configurationDesc() {
121 static uint8_t configurationDescriptor[] = {
122 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
123 CONFIGURATION_DESCRIPTOR, // bDescriptorType
124 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
125 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
126 0x01, // bNumInterfaces
127 DEFAULT_CONFIGURATION, // bConfigurationValue
128 0x00, // iConfiguration
129 C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
130 C_POWER(100), // bMaxPowerHello World from Mbed
131
132 INTERFACE_DESCRIPTOR_LENGTH, // bLength
133 INTERFACE_DESCRIPTOR, // bDescriptorType
134 0x00, // bInterfaceNumber
135 0x00, // bAlternateSetting
136 0x01, // bNumEndpoints
137 HID_CLASS, // bInterfaceClass
138 1, // bInterfaceSubClass (boot)
139 1, // bInterfaceProtocol (keyboard)
140 0x00, // iInterface
141
142 HID_DESCRIPTOR_LENGTH, // bLength
143 HID_DESCRIPTOR, // bDescriptorType
144 LSB(HID_VERSION_1_11), // bcdHID (LSB)
145 MSB(HID_VERSION_1_11), // bcdHID (MSB)
146 0x00, // bCountryCode
147 0x01, // bNumDescriptors
148 REPORT_DESCRIPTOR, // bDescriptorType
149 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
150 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
151
152 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
153 ENDPOINT_DESCRIPTOR, // bDescriptorType
154 PHY_TO_DESC(EP1IN), // bEndpointAddress
155 E_INTERRUPT, // bmAttributes
156 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
157 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
158 1, // bInterval (milliseconds)
159 };
160 return configurationDescriptor;
161}
162
163#if 0
164uint8_t * HIDKeyboard::deviceDesc() {
165 static uint8_t deviceDescriptor[] = {
166 DEVICE_DESCRIPTOR_LENGTH, /* bLength */
167 DEVICE_DESCRIPTOR, /* bDescriptorType */
168 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
169 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
170 0x00, /* bDeviceClass */
171 0x00, /* bDeviceSubClass */
172 0x00, /* bDeviceprotocol */
173 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
174 (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
175 (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
176 (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
177 (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
178 (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
179 (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
180 0, /* iManufacturer */
181 0, /* iProduct */
182 0, /* iSerialNumber */
183 0x01 /* bNumConfigurations */
184 };
185 return deviceDescriptor;
186}
187#endif
188
189bool HIDKeyboard::USBCallback_request() {
190 bool success = false;
191 CONTROL_TRANSFER * transfer = getTransferPtr();
192 uint8_t *hidDescriptor;
193
194 // Process additional standard requests
195
196 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
197 {
198 switch (transfer->setup.bRequest)
199 {
200 case GET_DESCRIPTOR:
201 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
202 {
203 case REPORT_DESCRIPTOR:
204 if ((reportDesc() != NULL) \
205 && (reportDescLength() != 0))
206 {
207 transfer->remaining = reportDescLength();
208 transfer->ptr = reportDesc();
209 transfer->direction = DEVICE_TO_HOST;
210 success = true;
211 }
212 break;
213 case HID_DESCRIPTOR:
214 // Find the HID descriptor, after the configuration descriptor
215 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
216 if (hidDescriptor != NULL)
217 {
218 transfer->remaining = HID_DESCRIPTOR_LENGTH;
219 transfer->ptr = hidDescriptor;
220 transfer->direction = DEVICE_TO_HOST;
221 success = true;
222 }
223 break;
224
225 default:
226 break;
227 }
228 break;
229 default:
230 break;
231 }
232 }
233
234 // Process class-specific requests
235 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
236 {
237 switch (transfer->setup.bRequest) {
238 case SET_REPORT:
239 // LED indicator
240 // TODO: check Interface and Report length?
241 // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
242 // if (transfer->setup.wLength == 1)
243
244 transfer->remaining = 1;
245 //transfer->ptr = ?? what ptr should be set when OUT(not used?)
246 transfer->direction = HOST_TO_DEVICE;
247 transfer->notify = true; /* notify with USBCallback_requestCompleted */
248 success = true;
249 default:
250 break;
251 }
252 }
253
254 return success;
255}
256
257void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
258{
259 if (length > 0) {
260 CONTROL_TRANSFER *transfer = getTransferPtr();
261 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
262 switch (transfer->setup.bRequest) {
263 case SET_REPORT:
264 led_state = buf[0];
265 break;
266 default:
267 break;
268 }
269 }
270 }
271}
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 @@
1#ifndef HIDKEYBOARD_H
2
3#include "stdint.h"
4#include "stdbool.h"
5#include "USBHID.h"
6#include "report.h"
7
8
9class HIDKeyboard : public USBDevice {
10public:
11 HIDKeyboard(uint16_t vendor_id = 0xFEED, uint16_t product_id = 0xabed, uint16_t product_release = 0x0001);
12
13 bool sendReport(report_keyboard_t report);
14 uint8_t leds(void);
15protected:
16 uint16_t reportLength;
17 virtual bool USBCallback_setConfiguration(uint8_t configuration);
18 virtual uint8_t * stringImanufacturerDesc();
19 virtual uint8_t * stringIproductDesc();
20 virtual uint8_t * stringIserialDesc();
21 virtual uint16_t reportDescLength();
22 virtual uint8_t * reportDesc();
23 virtual uint8_t * configurationDesc();
24 //virtual uint8_t * deviceDesc();
25 virtual bool USBCallback_request();
26 virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
27private:
28 uint8_t led_state;
29};
30
31#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 @@
1#include "HIDKeyboard.h"
2#include "host.h"
3#include "host_driver.h"
4#include "mbed_driver.h"
5
6HIDKeyboard keyboard;
7
8
9/* Host driver */
10static uint8_t keyboard_leds(void);
11static void send_keyboard(report_keyboard_t *report);
12static void send_mouse(report_mouse_t *report);
13static void send_system(uint16_t data);
14static void send_consumer(uint16_t data);
15
16host_driver_t mbed_driver = {
17 keyboard_leds,
18 send_keyboard,
19 send_mouse,
20 send_system,
21 send_consumer
22};
23
24
25static uint8_t keyboard_leds(void)
26{
27 return keyboard.leds();
28}
29static void send_keyboard(report_keyboard_t *report)
30{
31 keyboard.sendReport(*report);
32}
33static void send_mouse(report_mouse_t *report)
34{
35}
36static void send_system(uint16_t data)
37{
38}
39static void send_consumer(uint16_t data)
40{
41}
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 @@
1#include "host_driver.h"
2
3extern 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.
39#define PS2_H 39#define PS2_H
40 40
41#include <stdbool.h> 41#include <stdbool.h>
42#include <util/delay.h> 42#include "wait.h"
43#include <avr/io.h> 43#include "ps2_io.h"
44#include "print.h"
44 45
45/* 46/*
46 * Primitive PS/2 Library for AVR 47 * Primitive PS/2 Library for AVR
@@ -92,79 +93,27 @@ uint8_t ps2_host_recv(void);
92void ps2_host_set_led(uint8_t usb_led); 93void ps2_host_set_led(uint8_t usb_led);
93 94
94 95
95/* Check port settings for clock and data line */
96#if !(defined(PS2_CLOCK_PORT) && \
97 defined(PS2_CLOCK_PIN) && \
98 defined(PS2_CLOCK_DDR) && \
99 defined(PS2_CLOCK_BIT))
100# error "PS/2 clock port setting is required in config.h"
101#endif
102
103#if !(defined(PS2_DATA_PORT) && \
104 defined(PS2_DATA_PIN) && \
105 defined(PS2_DATA_DDR) && \
106 defined(PS2_DATA_BIT))
107# error "PS/2 data port setting is required in config.h"
108#endif
109
110/*-------------------------------------------------------------------- 96/*--------------------------------------------------------------------
111 * static functions 97 * static functions
112 *------------------------------------------------------------------*/ 98 *------------------------------------------------------------------*/
113static inline void clock_lo(void)
114{
115 PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
116 PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
117}
118static inline void clock_hi(void)
119{
120 /* input with pull up */
121 PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
122 PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
123}
124static inline bool clock_in(void)
125{
126 PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
127 PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
128 _delay_us(1);
129 return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
130}
131static inline void data_lo(void)
132{
133 PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
134 PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
135}
136static inline void data_hi(void)
137{
138 /* input with pull up */
139 PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
140 PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
141}
142static inline bool data_in(void)
143{
144 PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
145 PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
146 _delay_us(1);
147 return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
148}
149
150static inline uint16_t wait_clock_lo(uint16_t us) 99static inline uint16_t wait_clock_lo(uint16_t us)
151{ 100{
152 while (clock_in() && us) { asm(""); _delay_us(1); us--; } 101 while (clock_in() && us) { asm(""); wait_us(1); us--; }
153 return us; 102 return us;
154} 103}
155static inline uint16_t wait_clock_hi(uint16_t us) 104static inline uint16_t wait_clock_hi(uint16_t us)
156{ 105{
157 while (!clock_in() && us) { asm(""); _delay_us(1); us--; } 106 while (!clock_in() && us) { asm(""); wait_us(1); us--; }
158 return us; 107 return us;
159} 108}
160static inline uint16_t wait_data_lo(uint16_t us) 109static inline uint16_t wait_data_lo(uint16_t us)
161{ 110{
162 while (data_in() && us) { asm(""); _delay_us(1); us--; } 111 while (data_in() && us) { asm(""); wait_us(1); us--; }
163 return us; 112 return us;
164} 113}
165static inline uint16_t wait_data_hi(uint16_t us) 114static inline uint16_t wait_data_hi(uint16_t us)
166{ 115{
167 while (!data_in() && us) { asm(""); _delay_us(1); us--; } 116 while (!data_in() && us) { asm(""); wait_us(1); us--; }
168 return us; 117 return us;
169} 118}
170 119
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.
40 */ 40 */
41 41
42#include <stdbool.h> 42#include <stdbool.h>
43#include <util/delay.h> 43#include "wait.h"
44#include "ps2.h" 44#include "ps2.h"
45#include "ps2_io.h"
45#include "debug.h" 46#include "debug.h"
46 47
47 48
@@ -58,8 +59,11 @@ uint8_t ps2_error = PS2_ERR_NONE;
58 59
59void ps2_host_init(void) 60void ps2_host_init(void)
60{ 61{
62 clock_init();
63 data_init();
64
61 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) 65 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
62 _delay_ms(2500); 66 wait_ms(2500);
63 67
64 inhibit(); 68 inhibit();
65} 69}
@@ -71,7 +75,7 @@ uint8_t ps2_host_send(uint8_t data)
71 75
72 /* terminate a transmission if we have */ 76 /* terminate a transmission if we have */
73 inhibit(); 77 inhibit();
74 _delay_us(100); // 100us [4]p.13, [5]p.50 78 wait_us(100); // 100us [4]p.13, [5]p.50
75 79
76 /* 'Request to Send' and Start bit */ 80 /* 'Request to Send' and Start bit */
77 data_lo(); 81 data_lo();
@@ -80,7 +84,7 @@ uint8_t ps2_host_send(uint8_t data)
80 84
81 /* Data bit */ 85 /* Data bit */
82 for (uint8_t i = 0; i < 8; i++) { 86 for (uint8_t i = 0; i < 8; i++) {
83 _delay_us(15); 87 wait_us(15);
84 if (data&(1<<i)) { 88 if (data&(1<<i)) {
85 parity = !parity; 89 parity = !parity;
86 data_hi(); 90 data_hi();
@@ -92,13 +96,13 @@ uint8_t ps2_host_send(uint8_t data)
92 } 96 }
93 97
94 /* Parity bit */ 98 /* Parity bit */
95 _delay_us(15); 99 wait_us(15);
96 if (parity) { data_hi(); } else { data_lo(); } 100 if (parity) { data_hi(); } else { data_lo(); }
97 WAIT(clock_hi, 50, 4); 101 WAIT(clock_hi, 50, 4);
98 WAIT(clock_lo, 50, 5); 102 WAIT(clock_lo, 50, 5);
99 103
100 /* Stop bit */ 104 /* Stop bit */
101 _delay_us(15); 105 wait_us(15);
102 data_hi(); 106 data_hi();
103 107
104 /* Ack */ 108 /* 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 @@
1#ifndef PS2_IO_H
2#define PS2_IO_H
3
4
5void clock_init(void);
6void clock_lo(void);
7void clock_hi(void);
8bool clock_in(void);
9
10void data_init(void);
11void data_lo(void);
12void data_hi(void);
13bool data_in(void);
14
15#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 @@
1#include <stdbool.h>
2#include <util/delay.h>
3
4/* Check port settings for clock and data line */
5#if !(defined(PS2_CLOCK_PORT) && \
6 defined(PS2_CLOCK_PIN) && \
7 defined(PS2_CLOCK_DDR) && \
8 defined(PS2_CLOCK_BIT))
9# error "PS/2 clock port setting is required in config.h"
10#endif
11
12#if !(defined(PS2_DATA_PORT) && \
13 defined(PS2_DATA_PIN) && \
14 defined(PS2_DATA_DDR) && \
15 defined(PS2_DATA_BIT))
16# error "PS/2 data port setting is required in config.h"
17#endif
18
19
20/*
21 * Clock
22 */
23void clock_init(void)
24{
25}
26
27void clock_lo(void)
28{
29 PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
30 PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
31}
32
33void clock_hi(void)
34{
35 /* input with pull up */
36 PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
37 PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
38}
39
40bool clock_in(void)
41{
42 PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
43 PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
44 _delay_us(1);
45 return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
46}
47
48/*
49 * Data
50 */
51void data_init(void)
52{
53}
54
55void data_lo(void)
56{
57 PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
58 PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
59}
60
61void data_hi(void)
62{
63 /* input with pull up */
64 PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
65 PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
66}
67
68bool data_in(void)
69{
70 PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
71 PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
72 _delay_us(1);
73 return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
74}
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 @@
1#include <stdbool.h>
2#include "ps2_io.h"
3#include "gpio_api.h"
4
5
6static gpio_t clock;
7static gpio_t data;
8
9/*
10 * Clock
11 */
12void clock_init(void)
13{
14 gpio_init(&clock, P0_9);
15 gpio_mode(&clock, OpenDrain|PullNone);
16}
17
18void clock_lo(void)
19{
20 gpio_dir(&clock, PIN_OUTPUT);
21 gpio_write(&clock, 0);
22}
23void clock_hi(void)
24{
25 gpio_dir(&clock, PIN_OUTPUT);
26 gpio_write(&clock, 1);
27}
28
29bool clock_in(void)
30{
31 gpio_dir(&clock, PIN_INPUT);
32 return gpio_read(&clock);
33}
34
35/*
36 * Data
37 */
38void data_init(void)
39{
40 gpio_init(&data, P0_8);
41 gpio_mode(&data, OpenDrain|PullNone);
42}
43
44void data_lo(void)
45{
46 gpio_dir(&data, PIN_OUTPUT);
47 gpio_write(&data, 0);
48}
49
50void data_hi(void)
51{
52 gpio_dir(&data, PIN_OUTPUT);
53 gpio_write(&data, 1);
54}
55
56bool data_in(void)
57{
58 gpio_dir(&data, PIN_INPUT);
59 return gpio_read(&data);
60}
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.
41#include "serial.h" 41#include "serial.h"
42 42
43 43
44#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
45 // Buffer state
46 // Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
47 // Last 1 space: RBUF_SPACE == 2
48 // Full: RBUF_SPACE == 1(last cell of rbuf be never used.)
49 #define RBUF_SPACE() (rbuf_head < rbuf_tail ? (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
50 // allow to send
51 #define rbuf_check_rts_lo() do { if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); } while (0)
52 // prohibit to send
53 #define rbuf_check_rts_hi() do { if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); } while (0)
54#else
55 #define rbuf_check_rts_lo()
56 #define rbuf_check_rts_hi()
57#endif
58
59
44void serial_init(void) 60void serial_init(void)
45{ 61{
46 SERIAL_UART_INIT(); 62 SERIAL_UART_INIT();
47} 63}
48 64
49// RX ring buffer 65// RX ring buffer
50#define RBUF_SIZE 8 66#define RBUF_SIZE 256
51static uint8_t rbuf[RBUF_SIZE]; 67static uint8_t rbuf[RBUF_SIZE];
52static uint8_t rbuf_head = 0; 68static uint8_t rbuf_head = 0;
53static uint8_t rbuf_tail = 0; 69static uint8_t rbuf_tail = 0;
@@ -61,6 +77,7 @@ uint8_t serial_recv(void)
61 77
62 data = rbuf[rbuf_tail]; 78 data = rbuf[rbuf_tail];
63 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; 79 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
80 rbuf_check_rts_lo();
64 return data; 81 return data;
65} 82}
66 83
@@ -73,6 +90,7 @@ int16_t serial_recv2(void)
73 90
74 data = rbuf[rbuf_tail]; 91 data = rbuf[rbuf_tail];
75 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; 92 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
93 rbuf_check_rts_lo();
76 return data; 94 return data;
77} 95}
78 96
@@ -90,4 +108,5 @@ ISR(SERIAL_UART_RXD_VECT)
90 rbuf[rbuf_head] = SERIAL_UART_DATA; 108 rbuf[rbuf_head] = SERIAL_UART_DATA;
91 rbuf_head = next; 109 rbuf_head = next;
92 } 110 }
111 rbuf_check_rts_hi();
93} 112}