@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#include <stdint.h> | |||
#include <stdbool.h> | |||
#include "usb_keycodes.h" | |||
/* keycode in specific layer */ |
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#include "host.h" | |||
#include "debug.h" | |||
#include "timer.h" | |||
#include "usb_keycodes.h" | |||
#include "layer.h" | |||
@@ -95,10 +95,8 @@ 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); | |||
#if defined PS2_USE_INT || defined PS2_USE_USART | |||
static inline uint8_t pbuf_dequeue(void); | |||
static inline void pbuf_enqueue(uint8_t data); | |||
#endif | |||
void ps2_host_init(void) |
@@ -0,0 +1,56 @@ | |||
# | |||
# Makefile for PJRC Teensy | |||
# | |||
# Target file name (without extension). | |||
TARGET = ps2_usb_pjrc_usart | |||
# Directory common source filess exist | |||
COMMON_DIR = .. | |||
# Directory keyboard dependent files exist | |||
TARGET_DIR = . | |||
# keyboard dependent files | |||
SRC = main.c \ | |||
keymap.c \ | |||
matrix.c \ | |||
led.c \ | |||
ps2_usart.c | |||
CONFIG_H = config_pjrc_usart.h | |||
# MCU name, you MUST set this to match the board you are using | |||
# type "make clean" after changing this, so all files will be rebuilt | |||
#MCU = at90usb162 # Teensy 1.0 | |||
MCU = atmega32u4 # Teensy 2.0 | |||
#MCU = at90usb646 # Teensy++ 1.0 | |||
#MCU = at90usb1286 # Teensy++ 2.0 | |||
# Processor frequency. | |||
# Normally the first thing your program should do is set the clock prescaler, | |||
# so your program will run at the correct speed. You should also set this | |||
# variable to same clock speed. The _delay_ms() macro uses this, and many | |||
# examples use this variable to calculate timings. Do not add a "UL" here. | |||
F_CPU = 16000000 | |||
# Build Options | |||
# *Comment out* to disable the options. | |||
# | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
NKRO_ENABLE = yes # USB Nkey Rollover | |||
#---------------- Programming Options -------------------------- | |||
PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | |||
include $(COMMON_DIR)/pjrc.mk | |||
include $(COMMON_DIR)/common.mk |
@@ -1,40 +1,56 @@ | |||
PS/2 to USB keyboard converter | |||
============================== | |||
This firmware converts PS/2 keyboard protocol to USB and for now supports only Scan Code Set 2. | |||
This will works on USB AVR(ATMega32U4, AT90USB) or V-USB. | |||
Features | |||
-------- | |||
Mouse keys | |||
You can emulates mouse move and button click using keyboard. | |||
System/Media control | |||
You can sends Power event, Volume down/up and Mute. | |||
USB NKRO(actually 120KRO+8Modifiers) | |||
You can tolggles NKRO feature. | |||
Keymap customization | |||
You can customize keymaps easily by editing source code. See keymap.c. | |||
PS/2 signal handling implementations | |||
------------------------------------ | |||
Following three methods are used to implement PS/2 signal handling. | |||
a. Simple and stupid wait & read loop(intensive use of cycles) | |||
This is implemented with (expected) portable C code for reference. See ps2.c. | |||
b. Interrupt driven | |||
See ps2_intr.c | |||
c. Using USART hardware module(no cycle needed) | |||
This uses AVR USART function to recevie PS/2 signal and be used in V-USB converter. | |||
See ps2_usart.c. | |||
Build Converter | |||
--------------- | |||
0. Connect PS/2 keyboard into Teensy with 4 lines(Vcc, GND, Data, Clock). | |||
By default Clock is on PF0 and Data on PF1. | |||
You can change this pin configuration by editing config_pjrc.h. | |||
In this photo Vcc is yellow, GND is green, Data is red and Clock is black. | |||
http://img17.imageshack.us/img17/7243/201101181933.jpg | |||
Connect PS/2 keyboard into Teensy with 4 lines(Vcc, GND, Data, Clock). | |||
For a. Simple and stupid and b. Interrupt implementaion: | |||
By default Clock is on PF0 and Data on PF1. | |||
You can change this pin configuration by editing config_pjrc.h. | |||
In this photo Vcc is yellow, GND is green, Data is red and Clock is black. | |||
http://img17.imageshack.us/img17/7243/201101181933.jpg | |||
For c. USART implementation: | |||
In case of Teensny(ATMega32u4) CLock is on PD2 and Data on PD5. | |||
Build Frimware | |||
-------------- | |||
1. Edit Makefile for build options and MCU setting. | |||
Use 'atmega32u4' for Teensy 2.0 or 'at90usb1286' for Teensy++ 2.0. | |||
Use 'atmega32u4' for Teensy 2.0 or 'at90usb1286' for Teensy++ 2.0. | |||
2. make | |||
Just type 'make' in a terminal. | |||
Just type 'make' in a terminal. | |||
Use '-f Makefile.pjrc_intr' option to use b. Interrupt. | |||
Use '-f Makefile.pjrc_usart' option to use c. USART. | |||
Use '-f Makefile.vusb' option to build V-USB converter. | |||
3. program with Teensy Loader. | |||
http://www.pjrc.com/teensy/loader.html | |||
http://www.pjrc.com/teensy/loader.html | |||
Demonstration of Features | |||
@@ -97,34 +113,4 @@ To define keymap layer switching may needs a bit of your effort at this time. | |||
), | |||
Multimedia keys | |||
--------------- | |||
Following lists PS/2 special keys supported by Windows. | |||
http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx | |||
Key PS/2(Set2) HID | |||
--------------------------------------------------- | |||
System Power E0 37 01 0081 | |||
System Sleep E0 3F 01 0082 | |||
System Wake E0 5E 01 0083 | |||
System Mute E0 23 0C 00E2 | |||
Volume Up E0 32 0C 00E9 | |||
Volume Down E0 21 0C 00EA | |||
Scan Next Track E0 4D 0C 00B5 | |||
Scan Previous Track E0 15 0C 00B6 | |||
Stop E0 3B 0C 00B7 | |||
Play/Pause E0 34 0C 00CD | |||
Media Select E0 50 0C 0183 | |||
Mail E0 48 0C 018A | |||
Calculator E0 2B 0C 0192 | |||
My Computer E0 40 0C 0194 | |||
WWW Search E0 10 0C 0221 | |||
WWW Home E0 3A 0C 0223 | |||
WWW Back E0 38 0C 0224 | |||
WWW Forward E0 30 0C 0225 | |||
WWW Stop E0 28 0C 0226 | |||
WWW Refresh E0 20 0C 0227 | |||
WWW Favorites E0 18 0C 022A | |||
EOF |
@@ -0,0 +1,91 @@ | |||
/* | |||
Copyright 2012 Jun Wako <[email protected]> | |||
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 | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef CONFIG_H | |||
#define CONFIG_H | |||
/* controller configuration */ | |||
#include "controller_teensy.h" | |||
#define VENDOR_ID 0xFEED | |||
#define PRODUCT_ID 0x6513 | |||
#define MANUFACTURER t.m.k. | |||
#define PRODUCT PS/2 keyboard converter(USART) | |||
#define DESCRIPTION convert PS/2 keyboard to USB | |||
/* matrix size */ | |||
#define MATRIX_ROWS 32 // keycode bit: 3-0 | |||
#define MATRIX_COLS 8 // keycode bit: 6-4 | |||
/* key combination for command */ | |||
#define IS_COMMAND() ( \ | |||
keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \ | |||
keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | |||
) | |||
/* mouse keys */ | |||
#ifdef MOUSEKEY_ENABLE | |||
# define MOUSEKEY_DELAY_TIME 255 | |||
#endif | |||
/* PS/2 lines */ | |||
#define PS2_CLOCK_PORT PORTF | |||
#define PS2_CLOCK_PIN PINF | |||
#define PS2_CLOCK_DDR DDRF | |||
#define PS2_CLOCK_BIT 5 | |||
#define PS2_DATA_PORT PORTF | |||
#define PS2_DATA_PIN PINF | |||
#define PS2_DATA_DDR DDRF | |||
#define PS2_DATA_BIT 2 | |||
// synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge | |||
// set DDR of CLOCK as input to be slave | |||
#define PS2_USART_INIT() do { \ | |||
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \ | |||
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \ | |||
UCSR1C = ((1 << UMSEL10) | \ | |||
(3 << UPM10) | \ | |||
(0 << USBS1) | \ | |||
(3 << UCSZ10) | \ | |||
(0 << UCPOL1)); \ | |||
UCSR1A = 0; \ | |||
UBRR1H = 0; \ | |||
UBRR1L = 0; \ | |||
} while (0) | |||
#define PS2_USART_RX_INT_ON() do { \ | |||
UCSR1B = ((1 << RXCIE1) | \ | |||
(1 << RXEN1)); \ | |||
} while (0) | |||
#define PS2_USART_RX_POLL_ON() do { \ | |||
UCSR1B = (1 << RXEN1); \ | |||
} while (0) | |||
#define PS2_USART_OFF() do { \ | |||
UCSR1C = 0; \ | |||
UCSR1B &= ~((1 << RXEN1) | \ | |||
(1 << TXEN1)); \ | |||
} while (0) | |||
#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1)) | |||
#define PS2_USART_RX_DATA UDR1 | |||
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1))) | |||
#define PS2_USART_RX_VECT USART1_RX_vect | |||
#endif |