~ruther/qmk_firmware

9addeae8725719c138b097890edaed076686e061 — tmk 13 years ago 579991b
Added USART implementation for PS/2 signal handling.
6 files changed, 175 insertions(+), 44 deletions(-)

M keymap.h
M layer.c
M ps2_usart.c
A ps2_usb/Makefile.pjrc_usart
M ps2_usb/README
A ps2_usb/config_pjrc_usart.h
M keymap.h => keymap.h +0 -1
@@ 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 */

M layer.c => layer.c +1 -0
@@ 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"



M ps2_usart.c => ps2_usart.c +0 -2
@@ 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)

A ps2_usb/Makefile.pjrc_usart => ps2_usb/Makefile.pjrc_usart +56 -0
@@ 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

M ps2_usb/README => ps2_usb/README +27 -41
@@ 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

A ps2_usb/config_pjrc_usart.h => ps2_usb/config_pjrc_usart.h +91 -0
@@ 0,0 1,91 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>

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