forked from mirrors/qmk_userspace
		
	Merge branch 'ps2_keyboard_fix'
This commit is contained in:
		
				commit
				
					
						bc5b64d832
					
				
			
		
					 19 changed files with 941 additions and 910 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
# Target file name (without extension).
 | 
			
		||||
TARGET = ps2_usb
 | 
			
		||||
TARGET = ps2_usb_lufa
 | 
			
		||||
 | 
			
		||||
# Directory common source filess exist
 | 
			
		||||
TOP_DIR = ../..
 | 
			
		||||
| 
						 | 
				
			
			@ -7,69 +7,96 @@ TOP_DIR = ../..
 | 
			
		|||
# Directory keyboard dependent files exist
 | 
			
		||||
TARGET_DIR = .
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
PS2_USE_USART = yes	# uses hardware USART engine for PS/2 signal receive(recomened)
 | 
			
		||||
#PS2_USE_INT = yes	# uses external interrupt for falling edge of PS/2 clock pin
 | 
			
		||||
#PS2_USE_BUSYWAIT = yes	# uses primitive reference code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# keyboard dependent files
 | 
			
		||||
SRC =   keymap.c \
 | 
			
		||||
# project specific files
 | 
			
		||||
SRC =	keymap_common.c \
 | 
			
		||||
	matrix.c \
 | 
			
		||||
	led.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ifdef PS2_USE_USART
 | 
			
		||||
    SRC += protocol/ps2_usart.c
 | 
			
		||||
    OPT_DEFS += -DPS2_USE_USART
 | 
			
		||||
endif
 | 
			
		||||
ifdef PS2_USE_INT
 | 
			
		||||
    SRC += protocol/ps2.c
 | 
			
		||||
    OPT_DEFS += -DPS2_USE_INT
 | 
			
		||||
endif
 | 
			
		||||
ifdef PS2_USE_BUSYWAIT
 | 
			
		||||
    SRC += protocol/ps2.c
 | 
			
		||||
    OPT_DEFS += -DPS2_USE_BUSYWAIT
 | 
			
		||||
ifdef KEYMAP
 | 
			
		||||
    SRC := keymap_$(KEYMAP).c $(SRC)
 | 
			
		||||
else
 | 
			
		||||
    SRC := keymap_plain.c $(SRC)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#CONFIG_H = config_pjrc_usart.h
 | 
			
		||||
CONFIG_H = config.h
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#---------------- Programming Options --------------------------
 | 
			
		||||
PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
 | 
			
		||||
# MCU name
 | 
			
		||||
#MCU = at90usb1287
 | 
			
		||||
MCU = atmega32u4
 | 
			
		||||
 | 
			
		||||
# Processor frequency.
 | 
			
		||||
#     This will define a symbol, F_CPU, in all source code files equal to the
 | 
			
		||||
#     processor frequency in Hz. You can then use this symbol in your source code to
 | 
			
		||||
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
 | 
			
		||||
#     automatically to create a 32-bit value in your source code.
 | 
			
		||||
#
 | 
			
		||||
#     This will be an integer division of F_USB below, as it is sourced by
 | 
			
		||||
#     F_USB after it has run through any CPU prescalers. Note that this value
 | 
			
		||||
#     does not *change* the processor frequency - it should merely be updated to
 | 
			
		||||
#     reflect the processor speed set externally so that the code can use accurate
 | 
			
		||||
#     software delays.
 | 
			
		||||
F_CPU = 16000000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# LUFA specific
 | 
			
		||||
#
 | 
			
		||||
# Target architecture (see library "Board Types" documentation).
 | 
			
		||||
ARCH = AVR8
 | 
			
		||||
 | 
			
		||||
# Input clock frequency.
 | 
			
		||||
#     This will define a symbol, F_USB, in all source code files equal to the
 | 
			
		||||
#     input clock frequency (before any prescaling is performed) in Hz. This value may
 | 
			
		||||
#     differ from F_CPU if prescaling is used on the latter, and is required as the
 | 
			
		||||
#     raw input clock is fed directly to the PLL sections of the AVR for high speed
 | 
			
		||||
#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
 | 
			
		||||
#     at the end, this will be done automatically to create a 32-bit value in your
 | 
			
		||||
#     source code.
 | 
			
		||||
#
 | 
			
		||||
#     If no clock division is performed on the input clock inside the AVR (via the
 | 
			
		||||
#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
 | 
			
		||||
F_USB = $(F_CPU)
 | 
			
		||||
 | 
			
		||||
# Interrupt driven control endpoint task(+60)
 | 
			
		||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Boot Section Size in *bytes*
 | 
			
		||||
#   Teensy halfKay   512
 | 
			
		||||
#   Teensy++ halfKay 1024
 | 
			
		||||
#   Atmel DFU loader 4096
 | 
			
		||||
#   LUFA bootloader  4096
 | 
			
		||||
#   USBaspLoader     2048
 | 
			
		||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Build Options
 | 
			
		||||
#   comment out to disable the options.
 | 
			
		||||
#
 | 
			
		||||
#BOOTMAGIC_ENABLE = yes	# Virtual DIP switch configuration(+1000)
 | 
			
		||||
MOUSEKEY_ENABLE = yes	# Mouse keys(+4700)
 | 
			
		||||
EXTRAKEY_ENABLE = yes	# Audio control and System control(+450)
 | 
			
		||||
CONSOLE_ENABLE = yes	# Console for debug(+400)
 | 
			
		||||
COMMAND_ENABLE = yes    # Commands for debug and configuration
 | 
			
		||||
NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PS/2 Options
 | 
			
		||||
#
 | 
			
		||||
#PS2_USE_USART = yes	# uses hardware USART engine for PS/2 signal receive(recomened)
 | 
			
		||||
#PS2_USE_INT = yes	# uses external interrupt for falling edge of PS/2 clock pin
 | 
			
		||||
PS2_USE_BUSYWAIT = yes	# uses primitive reference code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Optimize size but this may cause error "relocation truncated to fit"
 | 
			
		||||
#EXTRALDFLAGS = -Wl,--relax
 | 
			
		||||
 | 
			
		||||
# Search Path
 | 
			
		||||
VPATH += $(TARGET_DIR)
 | 
			
		||||
VPATH += $(TOP_DIR)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(TOP_DIR)/protocol/pjrc.mk
 | 
			
		||||
include $(TOP_DIR)/protocol.mk
 | 
			
		||||
include $(TOP_DIR)/protocol/lufa.mk
 | 
			
		||||
include $(TOP_DIR)/common.mk
 | 
			
		||||
include $(TOP_DIR)/rules.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										75
									
								
								converter/ps2_usb/Makefile.pjrc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								converter/ps2_usb/Makefile.pjrc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
# Target file name (without extension).
 | 
			
		||||
TARGET = ps2_usb_pjrc
 | 
			
		||||
 | 
			
		||||
# Directory common source filess exist
 | 
			
		||||
TOP_DIR = ../..
 | 
			
		||||
 | 
			
		||||
# Directory keyboard dependent files exist
 | 
			
		||||
TARGET_DIR = .
 | 
			
		||||
 | 
			
		||||
# keyboard dependent files
 | 
			
		||||
SRC =   keymap_common.c \
 | 
			
		||||
	matrix.c \
 | 
			
		||||
	led.c
 | 
			
		||||
 | 
			
		||||
ifdef KEYMAP
 | 
			
		||||
    SRC := keymap_$(KEYMAP).c $(SRC)
 | 
			
		||||
else
 | 
			
		||||
    SRC := keymap_plain.c $(SRC)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
CONFIG_H = config.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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Boot Section Size in *bytes*
 | 
			
		||||
#   Teensy halfKay   512
 | 
			
		||||
#   Teensy++ halfKay 1024
 | 
			
		||||
#   Atmel DFU loader 4096
 | 
			
		||||
#   LUFA bootloader  4096
 | 
			
		||||
#   USBaspLoader     2048
 | 
			
		||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Build Options
 | 
			
		||||
#   *Comment out* to disable the options.
 | 
			
		||||
#
 | 
			
		||||
#BOOTMAGIC_ENABLE = yes	# Virtual DIP switch configuration(+1000)
 | 
			
		||||
MOUSEKEY_ENABLE = yes	# Mouse keys
 | 
			
		||||
EXTRAKEY_ENABLE = yes	# Audio control and System control
 | 
			
		||||
CONSOLE_ENABLE = yes	# Console for debug(+400)
 | 
			
		||||
COMMAND_ENABLE = yes    # Commands for debug and configuration
 | 
			
		||||
NKRO_ENABLE = yes	# USB Nkey Rollover
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PS/2 Options
 | 
			
		||||
#
 | 
			
		||||
#PS2_USE_USART = yes	# uses hardware USART engine for PS/2 signal receive(recomened)
 | 
			
		||||
#PS2_USE_INT = yes	# uses external interrupt for falling edge of PS/2 clock pin
 | 
			
		||||
PS2_USE_BUSYWAIT = yes	# uses primitive reference code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Search Path
 | 
			
		||||
VPATH += $(TARGET_DIR)
 | 
			
		||||
VPATH += $(TOP_DIR)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(TOP_DIR)/protocol.mk
 | 
			
		||||
include $(TOP_DIR)/protocol/pjrc.mk
 | 
			
		||||
include $(TOP_DIR)/common.mk
 | 
			
		||||
include $(TOP_DIR)/rules.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
#define VENDOR_ID       0xFEED
 | 
			
		||||
#define PRODUCT_ID      0x6512
 | 
			
		||||
#define DEVICE_VER      0x0001
 | 
			
		||||
#define MANUFACTURER    t.m.k.
 | 
			
		||||
#define PRODUCT         PS/2 keyboard converter
 | 
			
		||||
#define DESCRIPTION     convert PS/2 keyboard to USB
 | 
			
		||||
| 
						 | 
				
			
			@ -39,10 +40,52 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* legacy keymap support */
 | 
			
		||||
#define USE_LEGACY_KEYMAP
 | 
			
		||||
//#define NO_SUSPEND_POWER_DOWN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PS/2 Busywait
 | 
			
		||||
 */
 | 
			
		||||
#ifdef PS2_USE_BUSYWAIT
 | 
			
		||||
#define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
#define PS2_CLOCK_PIN   PIND
 | 
			
		||||
#define PS2_CLOCK_DDR   DDRD
 | 
			
		||||
#define PS2_CLOCK_BIT   5
 | 
			
		||||
#define PS2_DATA_PORT   PORTD
 | 
			
		||||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
#define PS2_DATA_BIT    2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PS/2 Pin interrupt
 | 
			
		||||
 */
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
/* uses INT1 for clock line(ATMega32U4) */
 | 
			
		||||
#define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
#define PS2_CLOCK_PIN   PIND
 | 
			
		||||
#define PS2_CLOCK_DDR   DDRD
 | 
			
		||||
#define PS2_CLOCK_BIT   1
 | 
			
		||||
#define PS2_DATA_PORT   PORTD
 | 
			
		||||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
#define PS2_DATA_BIT    2
 | 
			
		||||
#define PS2_INT_INIT()  do {    \
 | 
			
		||||
    EICRA |= ((1<<ISC11) |      \
 | 
			
		||||
              (0<<ISC10));      \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_ON()  do {      \
 | 
			
		||||
    EIMSK |= (1<<INT1);         \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_OFF() do {      \
 | 
			
		||||
    EIMSK &= ~(1<<INT1);        \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_VECT    INT1_vect
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PS/2 USART
 | 
			
		||||
 */
 | 
			
		||||
#ifdef PS2_USE_USART
 | 
			
		||||
#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
 | 
			
		||||
/* XCK for clock line and RXD for data line */
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +97,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
#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 {   \
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +127,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#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
 | 
			
		||||
 | 
			
		||||
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
 | 
			
		||||
/* XCK for clock line and RXD for data line */
 | 
			
		||||
#define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +137,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
#define PS2_DATA_BIT    0
 | 
			
		||||
 | 
			
		||||
/* 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 {   \
 | 
			
		||||
| 
						 | 
				
			
			@ -130,41 +170,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
/* uses INT1 for clock line(ATMega32U4) */
 | 
			
		||||
#define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
#define PS2_CLOCK_PIN   PIND
 | 
			
		||||
#define PS2_CLOCK_DDR   DDRD
 | 
			
		||||
#define PS2_CLOCK_BIT   1
 | 
			
		||||
#define PS2_DATA_PORT   PORTD
 | 
			
		||||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
#define PS2_DATA_BIT    2
 | 
			
		||||
 | 
			
		||||
#define PS2_INT_INIT()  do {    \
 | 
			
		||||
    EICRA |= ((1<<ISC11) |      \
 | 
			
		||||
              (0<<ISC10));      \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_ON()  do {      \
 | 
			
		||||
    EIMSK |= (1<<INT1);         \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_OFF() do {      \
 | 
			
		||||
    EIMSK &= ~(1<<INT1);        \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define PS2_INT_VECT    INT1_vect
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PS2_USE_BUSYWAIT
 | 
			
		||||
#define PS2_CLOCK_PORT  PORTF
 | 
			
		||||
#define PS2_CLOCK_PIN   PINF
 | 
			
		||||
#define PS2_CLOCK_DDR   DDRF
 | 
			
		||||
#define PS2_CLOCK_BIT   0
 | 
			
		||||
#define PS2_DATA_PORT   PORTF
 | 
			
		||||
#define PS2_DATA_PIN    PINF
 | 
			
		||||
#define PS2_DATA_DDR    DDRF
 | 
			
		||||
#define PS2_DATA_BIT    1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,379 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 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/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Keymap for PS/2 keyboard
 | 
			
		||||
 */
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
#include "keycode.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Following macros help you to define a keymap with the form of actual keyboard layout.
 | 
			
		||||
 | 
			
		||||
/* US layout plus all other various keys */
 | 
			
		||||
#define KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    K61,                     /* for European ISO */                                         \
 | 
			
		||||
    K51, K13, K6A, K64, K67, /* for Japanese JIS */                                         \
 | 
			
		||||
    K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */                \
 | 
			
		||||
    KB7, KBF, KDE,           /* System Power, Sleep, Wake */                                \
 | 
			
		||||
    KA3, KB2, KA1,           /* Mute, Volume Up, Volume Down */                             \
 | 
			
		||||
    KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */                \
 | 
			
		||||
    KC8, KAB, KC0,           /* Mail, Calculator, My Computer */                            \
 | 
			
		||||
    K90, KBA, KB8, KB0,      /* WWW Search, Home, Back, Forward */                          \
 | 
			
		||||
    KA8, KA0, K98            /* WWW Stop, Refresh, Favorites */                             \
 | 
			
		||||
) { \
 | 
			
		||||
    { KC_NO,    KC_##K01, KC_NO,    KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
 | 
			
		||||
    { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_NO    }, \
 | 
			
		||||
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_NO    }, \
 | 
			
		||||
    { KC_##K18, KC_NO,    KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_NO    }, \
 | 
			
		||||
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_NO    }, \
 | 
			
		||||
    { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_NO    }, \
 | 
			
		||||
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_NO    }, \
 | 
			
		||||
    { KC_##K38, KC_NO,    KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO    }, \
 | 
			
		||||
    { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_NO    }, \
 | 
			
		||||
    { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_NO    }, \
 | 
			
		||||
    { KC_##K50, KC_##K51, KC_##K52, KC_NO,    KC_##K54, KC_##K55, KC_NO,    KC_##K57 }, \
 | 
			
		||||
    { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_NO,    KC_##K5D, KC_NO,    KC_##K5F }, \
 | 
			
		||||
    { KC_NO,    KC_##K61, KC_NO,    KC_NO,    KC_##K64, KC_NO,    KC_##K66, KC_##K67 }, \
 | 
			
		||||
    { KC_NO,    KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
 | 
			
		||||
    { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_##K83, KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K90, KC_##K91, KC_NO,    KC_NO,    KC_##K94, KC_##K95, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K98, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_##K9F }, \
 | 
			
		||||
    { KC_##KA0, KC_##KA1, KC_NO,    KC_##KA3, KC_NO,    KC_NO,    KC_NO,    KC_##KA7 }, \
 | 
			
		||||
    { KC_##KA8, KC_NO,    KC_NO,    KC_##KAB, KC_NO,    KC_NO,    KC_NO,    KC_##KAF }, \
 | 
			
		||||
    { KC_##KB0, KC_NO,    KC_##KB2, KC_NO,    KC_##KB4, KC_NO,    KC_NO,    KC_##KB7 }, \
 | 
			
		||||
    { KC_##KB8, KC_NO,    KC_##KBA, KC_##KBB, KC_NO,    KC_NO,    KC_NO,    KC_##KBF }, \
 | 
			
		||||
    { KC_##KC0, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KC8, KC_NO,    KC_##KCA, KC_NO,    KC_NO,    KC_##KCD, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KD0, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_##KDA, KC_NO,    KC_NO,    KC_NO,    KC_##KDE, KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_##KE9, KC_NO,    KC_##KEB, KC_##KEC, KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KF0, KC_##KF1, KC_##KF2, KC_NO,    KC_##KF4, KC_##KF5, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_##KFA, KC_NO,    KC_##KFC, KC_##KFD, KC_##KFE, KC_NO    }, \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* US layout */
 | 
			
		||||
#define KEYMAP( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    NUBS,                                                                                   \
 | 
			
		||||
    RO, KANA, JYEN, HENK, MHEN,                                                             \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ISO layout */
 | 
			
		||||
#define KEYMAP_ISO( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,     KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,    K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    K61,                                                                                    \
 | 
			
		||||
    RO, KANA, JYEN, HENK, MHEN,                                                             \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* JIS layout */
 | 
			
		||||
#define KEYMAP_JIS( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,         KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,         KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,    K67,K29,K64,K13,            K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    NUBS,                                                                                   \
 | 
			
		||||
    K51, K13, K6A, K64, K67,                                                                \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
 | 
			
		||||
static const uint8_t PROGMEM fn_layer[] = {
 | 
			
		||||
    5,              // Fn0
 | 
			
		||||
    6,              // Fn1
 | 
			
		||||
    0,              // Fn2
 | 
			
		||||
    0,              // Fn3
 | 
			
		||||
    0,              // Fn4
 | 
			
		||||
    0,              // Fn5
 | 
			
		||||
    0,              // Fn6
 | 
			
		||||
    0               // Fn7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
 | 
			
		||||
// See layer.c for details.
 | 
			
		||||
static const uint8_t PROGMEM fn_keycode[] = {
 | 
			
		||||
    KC_SCLN,        // Fn0
 | 
			
		||||
    KC_SLSH,        // Fn1
 | 
			
		||||
    KC_NO,          // Fn2
 | 
			
		||||
    KC_NO,          // Fn3
 | 
			
		||||
    KC_NO,          // Fn4
 | 
			
		||||
    KC_NO,          // Fn5
 | 
			
		||||
    KC_NO,          // Fn6
 | 
			
		||||
    KC_NO           // Fn7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// The keymap is a 32*8 byte array which convert a PS/2 scan code into a USB keycode.
 | 
			
		||||
// See keycode.h for USB keycodes. You should omit a 'KC_' prefix of USB keycodes in keymap macro.
 | 
			
		||||
// Use KEYMAP_ISO() or KEYMAP_JIS() instead of KEYMAP() if your keyboard is ISO or JIS.
 | 
			
		||||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    /* 0: default
 | 
			
		||||
     * ,---.   ,---------------. ,---------------. ,---------------. ,-----------.     ,-----------.
 | 
			
		||||
     * |Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|     |Pwr|Slp|Wak|
 | 
			
		||||
     * `---'   `---------------' `---------------' `---------------' `-----------'     `-----------'
 | 
			
		||||
     * ,-----------------------------------------------------------. ,-----------. ,---------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa| |Ins|Hom|PgU| |NmL|  /|  *|  -|
 | 
			
		||||
     * |-----------------------------------------------------------| |-----------| |---------------|
 | 
			
		||||
     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \| |Del|End|PgD| |  7|  8|  9|   |
 | 
			
		||||
     * |-----------------------------------------------------------| `-----------' |-----------|  +|
 | 
			
		||||
     * |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return  |               |  4|  5|  6|   |
 | 
			
		||||
     * |-----------------------------------------------------------|     ,---.     |---------------|
 | 
			
		||||
     * |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |     |Up |     |  1|  2|  3|   |
 | 
			
		||||
     * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| |      0|  .|   |
 | 
			
		||||
     * `-----------------------------------------------------------' `-----------' `---------------'
 | 
			
		||||
     * ; = Fn0(to Layer 5)
 | 
			
		||||
     * / = Fn1(to Layer 6)
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   FN0, QUOT,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN1,           RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 1: plain Qwerty without layer switching
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `-----------------------------------------------------------'
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 2: Colemak http://colemak.com
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |  Q|  W|  F|  P|  G|  J|  L|  U|  Y|  ;|  [|  ]|    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |BackSp|  A|  R|  S|  T|  D|  H|  N|  E|  I|  O|  '|Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |  Z|  X|  C|  V|  B|  K|  M|  ,|  ,|  /|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `----------------------------------------------------------'
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, Q,   W,   F,   P,   G,   J,   L,   U,   Y,   SCLN,LBRC,RBRC,BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    BSPC,A,   R,   S,   T,   D,   H,   N,   E,   I,   O,   QUOT,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   K,   M,   COMM,DOT, SLSH,          RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 3: Dvorak http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  [|  ]|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |  '|  ,|  .|  P|  Y|  F|  G|  C|  R|  L|  /|  =|    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |BackSp|  A|  O|  E|  U|  I|  D|  H|  T|  N|  S|  -|Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |  ;|  Q|  J|  K|  X|  B|  M|  Wl  V|  Z|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `-----------------------------------------------------------'
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   LBRC,RBRC,BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, QUOT,COMM,DOT, P,   Y,   F,   G,   C,   R,   L,   SLSH,EQL, BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,A,   O,   E,   U,   I,   D,   H,   T,   N,   S,   MINS,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,SCLN,Q,   J,   K,   X,   B,   M,   W,   V,   Z,             RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 4: Workman http://viralintrospection.wordpress.com/2010/09/06/a-different-philosophy-in-designing-keyboard-layouts/
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |  Q|  D|  R|  W|  B|  J|  F|  U|  P|  ;|  [|  ]|    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |CapsLo|  A|  S|  H|  T|  G|  Y|  N|  E|  O|  I|  '|Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |  Z|  X|  M|  C|  V|  K|  L|  ,|  ,|  /|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `-----------------------------------------------------------'
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, Q,   D,   R,   W,   B,   J,   F,   U,   P,   SCLN,LBRC,RBRC,BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    BSPC,A,   S,   H,   T,   G,   Y,   N,   E,   O,   I,   QUOT,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   M,   C,   V,   K,   L,   COMM,DOT, SLSH,          RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 5: Mouse keys
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |MwL|MwU|McU|WwU|WwR|MwL|MwD|MwU|MwR|   |   |   |    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |CapsLo|   |McL|McD|McR|   |McL|McD|McU|McR|Fn0|   |Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |VoD|VoU|Mut|Mb2|Mb3|Mb2|Mb1|VoD|VoU|Mut|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Mb1           |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `-----------------------------------------------------------'
 | 
			
		||||
     * Mc = mouse cursor, Mw = mouse wheel, Mb = mouse button
 | 
			
		||||
     * Vo = Volume, Mut = Mute
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F8,  F10, F11, F12, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO,  NO,  NO,  BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,NO,  MS_L,MS_D,MS_R,NO,  MS_L,MS_D,MS_U,MS_R,FN0, NO,       ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE,          RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          BTN1,                    RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /* 6: Cursor keys
 | 
			
		||||
     * ,-----------------------------------------------------------.
 | 
			
		||||
     * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Tab  |Hom|PgU| Up|PgU|End|Hom|PgD|PgU|End|   |   |   |    \|
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |CapsLo|   |Lef|Dow|Rig|   |Lef|Dow| Up|Rig|   |   |Return  |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Shift   |   |   |   |   |   |Hom|PgD|PgU|End|Fn1|Shift     |
 | 
			
		||||
     * |-----------------------------------------------------------|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl|
 | 
			
		||||
     * `-----------------------------------------------------------'
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F8,  F10, F11, F12, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, NO,  NO,  NO,  BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,       ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,VOLD,VOLU,MUTE,NO,  NO,  HOME,PGDN,PGUP,END, FN1,           RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
 | 
			
		||||
{
 | 
			
		||||
    return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t keymap_fn_layer(uint8_t index)
 | 
			
		||||
{
 | 
			
		||||
    return pgm_read_byte(&fn_layer[index]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t keymap_fn_keycode(uint8_t index)
 | 
			
		||||
{
 | 
			
		||||
    return pgm_read_byte(&fn_keycode[index]);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								converter/ps2_usb/keymap_common.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								converter/ps2_usb/keymap_common.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011,2012,2013 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/>.
 | 
			
		||||
*/
 | 
			
		||||
#include "keymap_common.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* translates key to keycode */
 | 
			
		||||
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
 | 
			
		||||
{
 | 
			
		||||
    return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* translates Fn keycode to action */
 | 
			
		||||
action_t keymap_fn_to_action(uint8_t keycode)
 | 
			
		||||
{
 | 
			
		||||
    return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										174
									
								
								converter/ps2_usb/keymap_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								converter/ps2_usb/keymap_common.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,174 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011,2012,2013 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 KEYMAP_COMMON_H
 | 
			
		||||
#define KEYMAP_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
#include "keycode.h"
 | 
			
		||||
#include "action.h"
 | 
			
		||||
#include "action_macro.h"
 | 
			
		||||
#include "report.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 32*8(256) byte array which converts PS/2 code into USB code
 | 
			
		||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
 | 
			
		||||
extern const uint16_t fn_actions[];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* All keys */
 | 
			
		||||
#define KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    K61,                     /* for European ISO */                                         \
 | 
			
		||||
    K51, K13, K6A, K64, K67, /* for Japanese JIS */                                         \
 | 
			
		||||
    K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */                \
 | 
			
		||||
    KB7, KBF, KDE,           /* System Power, Sleep, Wake */                                \
 | 
			
		||||
    KA3, KB2, KA1,           /* Mute, Volume Up, Volume Down */                             \
 | 
			
		||||
    KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */                \
 | 
			
		||||
    KC8, KAB, KC0,           /* Mail, Calculator, My Computer */                            \
 | 
			
		||||
    K90, KBA, KB8, KB0,      /* WWW Search, Home, Back, Forward */                          \
 | 
			
		||||
    KA8, KA0, K98            /* WWW Stop, Refresh, Favorites */                             \
 | 
			
		||||
) { \
 | 
			
		||||
    { KC_NO,    KC_##K01, KC_NO,    KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
 | 
			
		||||
    { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_NO    }, \
 | 
			
		||||
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_NO    }, \
 | 
			
		||||
    { KC_##K18, KC_NO,    KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_NO    }, \
 | 
			
		||||
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_NO    }, \
 | 
			
		||||
    { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_NO    }, \
 | 
			
		||||
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_NO    }, \
 | 
			
		||||
    { KC_##K38, KC_NO,    KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO    }, \
 | 
			
		||||
    { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_NO    }, \
 | 
			
		||||
    { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_NO    }, \
 | 
			
		||||
    { KC_##K50, KC_##K51, KC_##K52, KC_NO,    KC_##K54, KC_##K55, KC_NO,    KC_##K57 }, \
 | 
			
		||||
    { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_NO,    KC_##K5D, KC_NO,    KC_##K5F }, \
 | 
			
		||||
    { KC_NO,    KC_##K61, KC_NO,    KC_NO,    KC_##K64, KC_NO,    KC_##K66, KC_##K67 }, \
 | 
			
		||||
    { KC_NO,    KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
 | 
			
		||||
    { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_##K83, KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K90, KC_##K91, KC_NO,    KC_NO,    KC_##K94, KC_##K95, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##K98, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_##K9F }, \
 | 
			
		||||
    { KC_##KA0, KC_##KA1, KC_NO,    KC_##KA3, KC_NO,    KC_NO,    KC_NO,    KC_##KA7 }, \
 | 
			
		||||
    { KC_##KA8, KC_NO,    KC_NO,    KC_##KAB, KC_NO,    KC_NO,    KC_NO,    KC_##KAF }, \
 | 
			
		||||
    { KC_##KB0, KC_NO,    KC_##KB2, KC_NO,    KC_##KB4, KC_NO,    KC_NO,    KC_##KB7 }, \
 | 
			
		||||
    { KC_##KB8, KC_NO,    KC_##KBA, KC_##KBB, KC_NO,    KC_NO,    KC_NO,    KC_##KBF }, \
 | 
			
		||||
    { KC_##KC0, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KC8, KC_NO,    KC_##KCA, KC_NO,    KC_NO,    KC_##KCD, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KD0, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_##KDA, KC_NO,    KC_NO,    KC_NO,    KC_##KDE, KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_##KE9, KC_NO,    KC_##KEB, KC_##KEC, KC_NO,    KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_##KF0, KC_##KF1, KC_##KF2, KC_NO,    KC_##KF4, KC_##KF5, KC_NO,    KC_NO    }, \
 | 
			
		||||
    { KC_NO,    KC_NO,    KC_##KFA, KC_NO,    KC_##KFC, KC_##KFD, KC_##KFE, KC_NO    }, \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* US layout */
 | 
			
		||||
#define KEYMAP( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    NUBS,                                                                                   \
 | 
			
		||||
    RO, KANA, JYEN, HENK, MHEN,                                                             \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ISO layout */
 | 
			
		||||
#define KEYMAP_ISO( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,     KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,    K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    K61,                                                                                    \
 | 
			
		||||
    RO, KANA, JYEN, HENK, MHEN,                                                             \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* JIS layout */
 | 
			
		||||
#define KEYMAP_JIS( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,         KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,         KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,    K67,K29,K64,K13,            K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA  \
 | 
			
		||||
) \
 | 
			
		||||
KEYMAP_ALL( \
 | 
			
		||||
    K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07,     KFC,K7E,KFE,                   \
 | 
			
		||||
    K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \
 | 
			
		||||
    K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \
 | 
			
		||||
    K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \
 | 
			
		||||
    K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,        K59,     KF5,      K69,K72,K7A,     \
 | 
			
		||||
    K14,K9F,K11,        K29,                K91,KA7,KAF,K94, KEB,KF2,KF4,  K70,    K71,KDA, \
 | 
			
		||||
                                                                                            \
 | 
			
		||||
    NUBS,                                                                                   \
 | 
			
		||||
    K51, K13, K6A, K64, K67,                                                                \
 | 
			
		||||
    F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,                             \
 | 
			
		||||
    SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE,                                                \
 | 
			
		||||
    AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN,                                               \
 | 
			
		||||
    MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT,         \
 | 
			
		||||
    MAIL, CALCULATOR, MY_COMPUTER,                                                          \
 | 
			
		||||
    WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD,                                            \
 | 
			
		||||
    WWW_STOP, WWW_REFRESH, WWW_FAVORITES                                                    \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										50
									
								
								converter/ps2_usb/keymap_plain.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								converter/ps2_usb/keymap_plain.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011,2012,2013 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/>.
 | 
			
		||||
*/
 | 
			
		||||
#include "keymap_common.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    /* 0: default
 | 
			
		||||
     * ,---.   ,---------------. ,---------------. ,---------------. ,-----------.     ,-----------.
 | 
			
		||||
     * |Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|     |Pwr|Slp|Wak|
 | 
			
		||||
     * `---'   `---------------' `---------------' `---------------' `-----------'     `-----------'
 | 
			
		||||
     * ,-----------------------------------------------------------. ,-----------. ,---------------.
 | 
			
		||||
     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa| |Ins|Hom|PgU| |NmL|  /|  *|  -|
 | 
			
		||||
     * |-----------------------------------------------------------| |-----------| |---------------|
 | 
			
		||||
     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \| |Del|End|PgD| |  7|  8|  9|   |
 | 
			
		||||
     * |-----------------------------------------------------------| `-----------' |-----------|  +|
 | 
			
		||||
     * |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return  |               |  4|  5|  6|   |
 | 
			
		||||
     * |-----------------------------------------------------------|     ,---.     |---------------|
 | 
			
		||||
     * |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |     |Up |     |  1|  2|  3|   |
 | 
			
		||||
     * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
 | 
			
		||||
     * |Ctrl |Gui |Alt |         Space         |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| |      0|  .|   |
 | 
			
		||||
     * `-----------------------------------------------------------' `-----------' `---------------'
 | 
			
		||||
     * ; = Fn0(to Layer 5)
 | 
			
		||||
     * / = Fn1(to Layer 6)
 | 
			
		||||
     */
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,BRK,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS,     DEL, END, PGDN,    P7,  P8,  P9,
 | 
			
		||||
    CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,                         P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT,          UP,           P1,  P2,  P3,
 | 
			
		||||
    LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint16_t PROGMEM fn_actions[] = {
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include "action.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
static void matrix_make(uint8_t code);
 | 
			
		||||
static void matrix_break(uint8_t code);
 | 
			
		||||
static void matrix_clear(void);
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
static bool matrix_has_ghost_in_row(uint8_t row);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +85,7 @@ uint8_t matrix_cols(void)
 | 
			
		|||
 | 
			
		||||
void matrix_init(void)
 | 
			
		||||
{
 | 
			
		||||
    debug_enable = true;
 | 
			
		||||
    ps2_host_init();
 | 
			
		||||
 | 
			
		||||
    // initialize matrix state: all keys off
 | 
			
		||||
| 
						 | 
				
			
			@ -185,8 +188,8 @@ uint8_t matrix_scan(void)
 | 
			
		|||
        matrix_break(PAUSE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t code;
 | 
			
		||||
    while ((code = ps2_host_recv())) {
 | 
			
		||||
    uint8_t code = ps2_host_recv();
 | 
			
		||||
    if (!ps2_error) {
 | 
			
		||||
        switch (state) {
 | 
			
		||||
            case INIT:
 | 
			
		||||
                switch (code) {
 | 
			
		||||
| 
						 | 
				
			
			@ -207,11 +210,19 @@ uint8_t matrix_scan(void)
 | 
			
		|||
                        matrix_make(PRINT_SCREEN);
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x00:  // Overrun [3]p.25
 | 
			
		||||
                        matrix_clear();
 | 
			
		||||
                        clear_keyboard();
 | 
			
		||||
                        print("Overrun\n");
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:    // normal key make
 | 
			
		||||
                        if (code < 0x80) {
 | 
			
		||||
                            matrix_make(code);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n");
 | 
			
		||||
                            matrix_clear();
 | 
			
		||||
                            clear_keyboard();
 | 
			
		||||
                            xprintf("unexpected scan code at INIT: %02X\n", code);
 | 
			
		||||
                        }
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +243,9 @@ uint8_t matrix_scan(void)
 | 
			
		|||
                        if (code < 0x80) {
 | 
			
		||||
                            matrix_make(code|0x80);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            debug("unexpected scan code at E0: "); debug_hex(code); debug("\n");
 | 
			
		||||
                            matrix_clear();
 | 
			
		||||
                            clear_keyboard();
 | 
			
		||||
                            xprintf("unexpected scan code at E0: %02X\n", code);
 | 
			
		||||
                        }
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -247,11 +260,18 @@ uint8_t matrix_scan(void)
 | 
			
		|||
                        matrix_break(PRINT_SCREEN);
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xF0:
 | 
			
		||||
                        matrix_clear();
 | 
			
		||||
                        clear_keyboard();
 | 
			
		||||
                        xprintf("unexpected scan code at F0: F0(clear and cont.)\n");
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:
 | 
			
		||||
                    if (code < 0x80) {
 | 
			
		||||
                        matrix_break(code);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
 | 
			
		||||
                        matrix_clear();
 | 
			
		||||
                        clear_keyboard();
 | 
			
		||||
                        xprintf("unexpected scan code at F0: %02X\n", code);
 | 
			
		||||
                    }
 | 
			
		||||
                    state = INIT;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -266,7 +286,9 @@ uint8_t matrix_scan(void)
 | 
			
		|||
                        if (code < 0x80) {
 | 
			
		||||
                            matrix_break(code|0x80);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n");
 | 
			
		||||
                            matrix_clear();
 | 
			
		||||
                            clear_keyboard();
 | 
			
		||||
                            xprintf("unexpected scan code at E0_F0: %02X\n", code);
 | 
			
		||||
                        }
 | 
			
		||||
                        state = INIT;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -357,8 +379,15 @@ uint8_t matrix_scan(void)
 | 
			
		|||
            default:
 | 
			
		||||
                state = INIT;
 | 
			
		||||
        }
 | 
			
		||||
        phex(code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: request RESEND when error occurs?
 | 
			
		||||
/*
 | 
			
		||||
    if (PS2_IS_FAILED(ps2_error)) {
 | 
			
		||||
        uint8_t ret = ps2_host_send(PS2_RESEND);
 | 
			
		||||
        xprintf("Resend: %02X\n", ret);
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -450,3 +479,9 @@ static void matrix_break(uint8_t code)
 | 
			
		|||
        is_modified = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
static void matrix_clear(void)
 | 
			
		||||
{
 | 
			
		||||
    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,8 +116,8 @@ CONSOLE_ENABLE = yes	# Console for debug(+400)
 | 
			
		|||
#SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
 | 
			
		||||
#NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA
 | 
			
		||||
 | 
			
		||||
PS2_MOUSE_ENABLE = yes  # PS/2 mouse(TrackPoint) support
 | 
			
		||||
PS2_USE_BUSYWAIT = yes # uses primitive reference code
 | 
			
		||||
#PS2_MOUSE_ENABLE = yes  # PS/2 mouse(TrackPoint) support
 | 
			
		||||
#PS2_USE_BUSYWAIT = yes # uses primitive reference code
 | 
			
		||||
#PS2_USE_INT = yes      # uses external interrupt for falling edge of PS/2 clock pin
 | 
			
		||||
#PS2_USE_USART = yes     # uses hardware USART engine for PS/2 signal receive(recomened)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
Onekey
 | 
			
		||||
======
 | 
			
		||||
Just one key keyboard for example. It sends 'a' key if pins PD0 and PD1 are short-circuited.
 | 
			
		||||
Just one key keyboard for example. It sends 'a' key if pins PB0 and PB1 are short-circuited.
 | 
			
		||||
 | 
			
		||||
https://github.com/tmk/tmk_keyboard/issues/56
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#   define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
#   define PS2_CLOCK_PIN   PIND
 | 
			
		||||
#   define PS2_CLOCK_DDR   DDRD
 | 
			
		||||
#   define PS2_CLOCK_BIT   5
 | 
			
		||||
#   define PS2_CLOCK_BIT   1
 | 
			
		||||
#   define PS2_DATA_PORT   PORTD
 | 
			
		||||
#   define PS2_DATA_PIN    PIND
 | 
			
		||||
#   define PS2_DATA_DDR    DDRD
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define PS2_CLOCK_PORT  PORTD
 | 
			
		||||
#define PS2_CLOCK_PIN   PIND
 | 
			
		||||
#define PS2_CLOCK_DDR   DDRD
 | 
			
		||||
#define PS2_CLOCK_BIT   5
 | 
			
		||||
#define PS2_CLOCK_BIT   1
 | 
			
		||||
#define PS2_DATA_PORT   PORTD
 | 
			
		||||
#define PS2_DATA_PIN    PIND
 | 
			
		||||
#define PS2_DATA_DDR    DDRD
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,29 +139,29 @@ uint8_t matrix_key_count(void)
 | 
			
		|||
 | 
			
		||||
/* Column pin configuration
 | 
			
		||||
 * col: 0
 | 
			
		||||
 * pin: D0
 | 
			
		||||
 * pin: B0
 | 
			
		||||
 */
 | 
			
		||||
static void  init_cols(void)
 | 
			
		||||
{
 | 
			
		||||
    // Input with pull-up(DDR:0, PORT:1)
 | 
			
		||||
    DDRD  &= ~(1<<0);
 | 
			
		||||
    PORTD |=  (1<<0);
 | 
			
		||||
    DDRB  &= ~(1<<0);
 | 
			
		||||
    PORTB |=  (1<<0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static matrix_row_t read_cols(void)
 | 
			
		||||
{
 | 
			
		||||
    return (PIND&(1<<0) ? 0 : (1<<0));
 | 
			
		||||
    return (PINB&(1<<0) ? 0 : (1<<0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Row pin configuration
 | 
			
		||||
 * row: 0
 | 
			
		||||
 * pin: D1
 | 
			
		||||
 * pin: B1
 | 
			
		||||
 */
 | 
			
		||||
static void unselect_rows(void)
 | 
			
		||||
{
 | 
			
		||||
    // Hi-Z(DDR:0, PORT:0) to unselect
 | 
			
		||||
    DDRD  &= ~0b00000010;
 | 
			
		||||
    PORTD &= ~0b00000010;
 | 
			
		||||
    DDRB  &= ~0b00000010;
 | 
			
		||||
    PORTB &= ~0b00000010;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void select_row(uint8_t row)
 | 
			
		||||
| 
						 | 
				
			
			@ -169,8 +169,8 @@ static void select_row(uint8_t row)
 | 
			
		|||
    // Output low(DDR:1, PORT:0) to select
 | 
			
		||||
    switch (row) {
 | 
			
		||||
        case 0:
 | 
			
		||||
            DDRD  |= (1<<1);
 | 
			
		||||
            PORTD &= ~(1<<1);
 | 
			
		||||
            DDRB  |= (1<<1);
 | 
			
		||||
            PORTB &= ~(1<<1);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,12 +8,12 @@ ifdef PS2_MOUSE_ENABLE
 | 
			
		|||
endif
 | 
			
		||||
 | 
			
		||||
ifdef PS2_USE_BUSYWAIT
 | 
			
		||||
    SRC += protocol/ps2.c
 | 
			
		||||
    SRC += protocol/ps2_busywait.c
 | 
			
		||||
    OPT_DEFS += -DPS2_USE_BUSYWAIT
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifdef PS2_USE_INT
 | 
			
		||||
    SRC += protocol/ps2.c
 | 
			
		||||
    SRC += protocol/ps2_interrupt.c
 | 
			
		||||
    OPT_DEFS += -DPS2_USE_INT
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,7 +148,6 @@ static void Console_Task(void)
 | 
			
		|||
*/
 | 
			
		||||
void EVENT_USB_Device_Connect(void)
 | 
			
		||||
{
 | 
			
		||||
    led_set(0x1f);  // all on
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Device_Disconnect(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -172,8 +171,9 @@ void EVENT_USB_Device_WakeUp()
 | 
			
		|||
 | 
			
		||||
#ifdef SLEEP_LED_ENABLE
 | 
			
		||||
    sleep_led_disable();
 | 
			
		||||
#endif
 | 
			
		||||
    // NOTE: converters may not accept this
 | 
			
		||||
    led_set(host_keyboard_leds());
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Device_StartOfFrame(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -662,8 +662,9 @@ ISR(USB_GEN_vect)
 | 
			
		|||
            suspend_wakeup_init();
 | 
			
		||||
#ifdef SLEEP_LED_ENABLE
 | 
			
		||||
            sleep_led_disable();
 | 
			
		||||
#endif
 | 
			
		||||
            // NOTE: converters may not accept this
 | 
			
		||||
            led_set(host_keyboard_leds());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            UDIEN |= (1<<SUSPE);
 | 
			
		||||
            UDIEN &= ~(1<<WAKEUPE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										144
									
								
								protocol/ps2.h
									
										
									
									
									
								
							
							
						
						
									
										144
									
								
								protocol/ps2.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2010,2011 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
 | 
			
		||||
This software is licensed with a Modified BSD License.
 | 
			
		||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
 | 
			
		||||
| 
						 | 
				
			
			@ -37,12 +37,62 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
 | 
			
		||||
#ifndef PS2_H
 | 
			
		||||
#define PS2_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Primitive PS/2 Library for AVR
 | 
			
		||||
 *
 | 
			
		||||
 * PS/2 Resources
 | 
			
		||||
 * --------------
 | 
			
		||||
 * [1] The PS/2 Mouse/Keyboard Protocol
 | 
			
		||||
 * http://www.computer-engineering.org/ps2protocol/
 | 
			
		||||
 * Concise and thorough primer of PS/2 protocol.
 | 
			
		||||
 *
 | 
			
		||||
 * [2] Keyboard and Auxiliary Device Controller
 | 
			
		||||
 * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		||||
 * Signal Timing and Format
 | 
			
		||||
 *
 | 
			
		||||
 * [3] Keyboards(101- and 102-key)
 | 
			
		||||
 * http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
 | 
			
		||||
 * Keyboard Layout, Scan Code Set, POR, and Commands.
 | 
			
		||||
 *
 | 
			
		||||
 * [4] PS/2 Reference Manuals
 | 
			
		||||
 * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		||||
 * Collection of IBM Personal System/2 documents.
 | 
			
		||||
 *
 | 
			
		||||
 * [5] TrackPoint Engineering Specifications for version 3E
 | 
			
		||||
 * https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
 | 
			
		||||
 */
 | 
			
		||||
#define PS2_ACK         0xFA
 | 
			
		||||
#define PS2_RESEND      0xFE
 | 
			
		||||
#define PS2_SET_LED     0xED
 | 
			
		||||
 | 
			
		||||
// TODO: error numbers
 | 
			
		||||
#define PS2_ERR_NONE        0
 | 
			
		||||
#define PS2_ERR_STARTBIT1   1
 | 
			
		||||
#define PS2_ERR_STARTBIT2   2
 | 
			
		||||
#define PS2_ERR_STARTBIT3   3
 | 
			
		||||
#define PS2_ERR_PARITY      0x10
 | 
			
		||||
#define PS2_ERR_NODATA      0x20
 | 
			
		||||
 | 
			
		||||
#define PS2_LED_SCROLL_LOCK 0
 | 
			
		||||
#define PS2_LED_NUM_LOCK    1
 | 
			
		||||
#define PS2_LED_CAPS_LOCK   2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* port settings for clock and data line */
 | 
			
		||||
extern uint8_t ps2_error;
 | 
			
		||||
 | 
			
		||||
void ps2_host_init(void);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Check port settings for clock and data line */
 | 
			
		||||
#if !(defined(PS2_CLOCK_PORT) && \
 | 
			
		||||
      defined(PS2_CLOCK_PIN) && \
 | 
			
		||||
      defined(PS2_CLOCK_DDR) && \
 | 
			
		||||
| 
						 | 
				
			
			@ -57,27 +107,79 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
#   error "PS/2 data port setting is required in config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PS2_ACK         0xFA
 | 
			
		||||
#define PS2_RESEND      0xFE
 | 
			
		||||
#define PS2_SET_LED     0xED
 | 
			
		||||
/*--------------------------------------------------------------------
 | 
			
		||||
 * 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PS2_ERR_NONE    0
 | 
			
		||||
#define PS2_ERR_PARITY  0x10
 | 
			
		||||
static inline uint16_t wait_clock_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (clock_in()  && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PS2_LED_SCROLL_LOCK 0
 | 
			
		||||
#define PS2_LED_NUM_LOCK    1
 | 
			
		||||
#define PS2_LED_CAPS_LOCK   2
 | 
			
		||||
/* idle state that device can send */
 | 
			
		||||
static inline void idle(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern uint8_t ps2_error;
 | 
			
		||||
 | 
			
		||||
/* host role */
 | 
			
		||||
void ps2_host_init(void);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/* device role */
 | 
			
		||||
/* inhibit device to send */
 | 
			
		||||
static inline void inhibit(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_lo();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										185
									
								
								protocol/ps2_busywait.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								protocol/ps2_busywait.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,185 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
 | 
			
		||||
This software is licensed with a Modified BSD License.
 | 
			
		||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
 | 
			
		||||
GPL-compatible, and OK to use in both free and proprietary applications.
 | 
			
		||||
Additions and corrections to this file are welcome.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
* Redistributions of source code must retain the above copyright
 | 
			
		||||
  notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
* Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
  notice, this list of conditions and the following disclaimer in
 | 
			
		||||
  the documentation and/or other materials provided with the
 | 
			
		||||
  distribution.
 | 
			
		||||
 | 
			
		||||
* Neither the name of the copyright holders nor the names of
 | 
			
		||||
  contributors may be used to endorse or promote products derived
 | 
			
		||||
  from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | 
			
		||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PS/2 protocol busywait version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include "ps2.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WAIT(stat, us, err) do { \
 | 
			
		||||
    if (!wait_##stat(us)) { \
 | 
			
		||||
        ps2_error = err; \
 | 
			
		||||
        goto ERROR; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ps2_host_init(void)
 | 
			
		||||
{
 | 
			
		||||
    // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
 | 
			
		||||
    _delay_ms(2500);
 | 
			
		||||
 | 
			
		||||
    inhibit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t ps2_host_send(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    bool parity = true;
 | 
			
		||||
    ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
    /* terminate a transmission if we have */
 | 
			
		||||
    inhibit();
 | 
			
		||||
    _delay_us(100); // 100us [4]p.13, [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* 'Request to Send' and Start bit */
 | 
			
		||||
    data_lo();
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    WAIT(clock_lo, 10000, 10);   // 10ms [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* Data bit */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        _delay_us(15);
 | 
			
		||||
        if (data&(1<<i)) {
 | 
			
		||||
            parity = !parity;
 | 
			
		||||
            data_hi();
 | 
			
		||||
        } else {
 | 
			
		||||
            data_lo();
 | 
			
		||||
        }
 | 
			
		||||
        WAIT(clock_hi, 50, 2);
 | 
			
		||||
        WAIT(clock_lo, 50, 3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Parity bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    if (parity) { data_hi(); } else { data_lo(); }
 | 
			
		||||
    WAIT(clock_hi, 50, 4);
 | 
			
		||||
    WAIT(clock_lo, 50, 5);
 | 
			
		||||
 | 
			
		||||
    /* Stop bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    data_hi();
 | 
			
		||||
 | 
			
		||||
    /* Ack */
 | 
			
		||||
    WAIT(data_lo, 50, 6);
 | 
			
		||||
    WAIT(clock_lo, 50, 7);
 | 
			
		||||
 | 
			
		||||
    /* wait for idle state */
 | 
			
		||||
    WAIT(clock_hi, 50, 8);
 | 
			
		||||
    WAIT(data_hi, 50, 9);
 | 
			
		||||
 | 
			
		||||
    inhibit();
 | 
			
		||||
    return ps2_host_recv_response();
 | 
			
		||||
ERROR:
 | 
			
		||||
    inhibit();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* receive data when host want else inhibit communication */
 | 
			
		||||
uint8_t ps2_host_recv_response(void)
 | 
			
		||||
{
 | 
			
		||||
    // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
 | 
			
		||||
    // 250 * 100us(wait for start bit in ps2_host_recv)
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    uint8_t try = 250;
 | 
			
		||||
    do {
 | 
			
		||||
        data = ps2_host_recv();
 | 
			
		||||
    } while (try-- && ps2_error);
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* called after start bit comes */
 | 
			
		||||
uint8_t ps2_host_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    bool parity = true;
 | 
			
		||||
    ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
    /* release lines(idle state) */
 | 
			
		||||
    idle();
 | 
			
		||||
 | 
			
		||||
    /* start bit [1] */
 | 
			
		||||
    WAIT(clock_lo, 100, 1); // TODO: this is enough?
 | 
			
		||||
    WAIT(data_lo, 1, 2);
 | 
			
		||||
    WAIT(clock_hi, 50, 3);
 | 
			
		||||
 | 
			
		||||
    /* data [2-9] */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        WAIT(clock_lo, 50, 4);
 | 
			
		||||
        if (data_in()) {
 | 
			
		||||
            parity = !parity;
 | 
			
		||||
            data |= (1<<i);
 | 
			
		||||
        }
 | 
			
		||||
        WAIT(clock_hi, 50, 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* parity [10] */
 | 
			
		||||
    WAIT(clock_lo, 50, 6);
 | 
			
		||||
    if (data_in() != parity) {
 | 
			
		||||
        ps2_error = PS2_ERR_PARITY;
 | 
			
		||||
        goto ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    WAIT(clock_hi, 50, 7);
 | 
			
		||||
 | 
			
		||||
    /* stop bit [11] */
 | 
			
		||||
    WAIT(clock_lo, 50, 8);
 | 
			
		||||
    WAIT(data_hi, 1, 9);
 | 
			
		||||
    WAIT(clock_hi, 50, 10);
 | 
			
		||||
 | 
			
		||||
    inhibit();
 | 
			
		||||
    return data;
 | 
			
		||||
ERROR:
 | 
			
		||||
    if (ps2_error > PS2_ERR_STARTBIT3) {
 | 
			
		||||
        xprintf("x%02X\n", ps2_error);
 | 
			
		||||
    }
 | 
			
		||||
    inhibit();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* send LED state to keyboard */
 | 
			
		||||
void ps2_host_set_led(uint8_t led)
 | 
			
		||||
{
 | 
			
		||||
    ps2_host_send(0xED);
 | 
			
		||||
    ps2_host_send(led);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -35,47 +35,15 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		|||
POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PS/2 protocol Pin interrupt version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
#include <avr/interrupt.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include "ps2.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef PS2_USE_INT
 | 
			
		||||
static uint8_t recv_data(void);
 | 
			
		||||
#endif
 | 
			
		||||
static inline void clock_lo(void);
 | 
			
		||||
static inline void clock_hi(void);
 | 
			
		||||
static inline bool clock_in(void);
 | 
			
		||||
static inline void data_lo(void);
 | 
			
		||||
static inline void data_hi(void);
 | 
			
		||||
static inline bool data_in(void);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Primitive PS/2 Library for AVR
 | 
			
		||||
==============================
 | 
			
		||||
Host side is only supported now.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I/O control
 | 
			
		||||
-----------
 | 
			
		||||
High state is asserted by input with pull up.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PS/2 References
 | 
			
		||||
---------------
 | 
			
		||||
http://www.computer-engineering.org/ps2protocol/
 | 
			
		||||
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		||||
*/
 | 
			
		||||
#include "print.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WAIT(stat, us, err) do { \
 | 
			
		||||
| 
						 | 
				
			
			@ -89,35 +57,38 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		|||
uint8_t ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline uint8_t pbuf_dequeue(void);
 | 
			
		||||
static inline void pbuf_enqueue(uint8_t data);
 | 
			
		||||
static inline bool pbuf_has_data(void);
 | 
			
		||||
static inline void pbuf_clear(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ps2_host_init(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
    idle();
 | 
			
		||||
    PS2_INT_INIT();
 | 
			
		||||
    PS2_INT_ON();
 | 
			
		||||
    idle();
 | 
			
		||||
#else
 | 
			
		||||
    inhibit();
 | 
			
		||||
#endif
 | 
			
		||||
    // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
 | 
			
		||||
    //_delay_ms(2500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: send using interrupt if available
 | 
			
		||||
uint8_t ps2_host_send(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t res = 0;
 | 
			
		||||
    bool parity = true;
 | 
			
		||||
    ps2_error = PS2_ERR_NONE;
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
 | 
			
		||||
    PS2_INT_OFF();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* terminate a transmission if we have */
 | 
			
		||||
    inhibit();
 | 
			
		||||
    _delay_us(200); // at least 100us
 | 
			
		||||
    _delay_us(100); // 100us [4]p.13, [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* start bit [1] */
 | 
			
		||||
    /* 'Request to Send' and Start bit */
 | 
			
		||||
    data_lo();
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    WAIT(clock_lo, 20000, 10);   // may take 15ms at most until device starts clocking
 | 
			
		||||
    /* data [2-9] */
 | 
			
		||||
    WAIT(clock_lo, 10000, 10);   // 10ms [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* Data bit[2-9] */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        _delay_us(15);
 | 
			
		||||
        if (data&(1<<i)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -129,15 +100,18 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
        WAIT(clock_hi, 50, 2);
 | 
			
		||||
        WAIT(clock_lo, 50, 3);
 | 
			
		||||
    }
 | 
			
		||||
    /* parity [10] */
 | 
			
		||||
 | 
			
		||||
    /* Parity bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    if (parity) { data_hi(); } else { data_lo(); }
 | 
			
		||||
    WAIT(clock_hi, 50, 4);
 | 
			
		||||
    WAIT(clock_lo, 50, 5);
 | 
			
		||||
    /* stop bit [11] */
 | 
			
		||||
 | 
			
		||||
    /* Stop bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    data_hi();
 | 
			
		||||
    /* ack [12] */
 | 
			
		||||
 | 
			
		||||
    /* Ack */
 | 
			
		||||
    WAIT(data_lo, 50, 6);
 | 
			
		||||
    WAIT(clock_lo, 50, 7);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,116 +119,35 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
    WAIT(clock_hi, 50, 8);
 | 
			
		||||
    WAIT(data_hi, 50, 9);
 | 
			
		||||
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
    PS2_INT_ON();
 | 
			
		||||
#endif
 | 
			
		||||
    res = ps2_host_recv_response();
 | 
			
		||||
ERROR:
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
    PS2_INT_ON();
 | 
			
		||||
    idle();
 | 
			
		||||
#else
 | 
			
		||||
    inhibit();
 | 
			
		||||
#endif
 | 
			
		||||
    return res;
 | 
			
		||||
    PS2_INT_ON();
 | 
			
		||||
    return ps2_host_recv_response();
 | 
			
		||||
ERROR:
 | 
			
		||||
    idle();
 | 
			
		||||
    PS2_INT_ON();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef PS2_USE_INT
 | 
			
		||||
/* receive data when host want else inhibit communication */
 | 
			
		||||
uint8_t ps2_host_recv_response(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef PS2_USE_INT
 | 
			
		||||
    PS2_INT_OFF();
 | 
			
		||||
#endif
 | 
			
		||||
    /* terminate a transmission if we have */
 | 
			
		||||
    inhibit();
 | 
			
		||||
    _delay_us(100);
 | 
			
		||||
 | 
			
		||||
    /* release lines(idle state) */
 | 
			
		||||
    idle();
 | 
			
		||||
 | 
			
		||||
    /* wait start bit */
 | 
			
		||||
    wait_clock_lo(25000);    // command response may take 20 ms at most
 | 
			
		||||
    data = recv_data();
 | 
			
		||||
 | 
			
		||||
    inhibit();
 | 
			
		||||
    return data;
 | 
			
		||||
    // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
 | 
			
		||||
    uint8_t retry = 25;
 | 
			
		||||
    while (retry-- && !pbuf_has_data()) {
 | 
			
		||||
        _delay_ms(1);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PS2_USE_INT
 | 
			
		||||
uint8_t ps2_host_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    return ps2_host_recv_response();
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
/* ring buffer to store ps/2 key data */
 | 
			
		||||
#define PBUF_SIZE 32
 | 
			
		||||
static uint8_t pbuf[PBUF_SIZE];
 | 
			
		||||
static uint8_t pbuf_head = 0;
 | 
			
		||||
static uint8_t pbuf_tail = 0;
 | 
			
		||||
static inline void pbuf_enqueue(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
 | 
			
		||||
    if (next != pbuf_tail) {
 | 
			
		||||
        pbuf[pbuf_head] = data;
 | 
			
		||||
        pbuf_head = next;
 | 
			
		||||
    } else {
 | 
			
		||||
        debug("pbuf: full\n");
 | 
			
		||||
    }
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
}
 | 
			
		||||
static inline uint8_t pbuf_dequeue(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val = 0;
 | 
			
		||||
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    if (pbuf_head != pbuf_tail) {
 | 
			
		||||
        val = pbuf[pbuf_tail];
 | 
			
		||||
        pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
 | 
			
		||||
    return val;
 | 
			
		||||
}
 | 
			
		||||
static inline bool pbuf_has_data(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    bool has_data = (pbuf_head != pbuf_tail);
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
    return has_data;
 | 
			
		||||
}
 | 
			
		||||
static inline void pbuf_clear(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    pbuf_head = pbuf_tail = 0;
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
    return pbuf_dequeue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* get data received by interrupt */
 | 
			
		||||
uint8_t ps2_host_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    if (ps2_error) {
 | 
			
		||||
        print("x");
 | 
			
		||||
        phex(ps2_error);
 | 
			
		||||
        ps2_host_send(0xFE);    // request to resend
 | 
			
		||||
    if (pbuf_has_data()) {
 | 
			
		||||
        ps2_error = PS2_ERR_NONE;
 | 
			
		||||
    }
 | 
			
		||||
    idle();
 | 
			
		||||
        return pbuf_dequeue();
 | 
			
		||||
    } else {
 | 
			
		||||
        ps2_error = PS2_ERR_NODATA;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
uint8_t ps2_host_recv_response(void)
 | 
			
		||||
{
 | 
			
		||||
    while (!pbuf_has_data()) ;
 | 
			
		||||
    return pbuf_dequeue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ISR(PS2_INT_VECT)
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +202,6 @@ ISR(PS2_INT_VECT)
 | 
			
		|||
            if (!data_in())
 | 
			
		||||
                goto ERROR;
 | 
			
		||||
            pbuf_enqueue(data);
 | 
			
		||||
//phex(data);
 | 
			
		||||
            goto DONE;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +209,6 @@ ISR(PS2_INT_VECT)
 | 
			
		|||
    }
 | 
			
		||||
    goto RETURN;
 | 
			
		||||
ERROR:
 | 
			
		||||
    inhibit();
 | 
			
		||||
    ps2_error = state;
 | 
			
		||||
DONE:
 | 
			
		||||
    state = INIT;
 | 
			
		||||
| 
						 | 
				
			
			@ -326,8 +217,6 @@ DONE:
 | 
			
		|||
RETURN:
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* send LED state to keyboard */
 | 
			
		||||
void ps2_host_set_led(uint8_t led)
 | 
			
		||||
| 
						 | 
				
			
			@ -337,116 +226,53 @@ void ps2_host_set_led(uint8_t led)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef PS2_USE_INT
 | 
			
		||||
/* called after start bit comes */
 | 
			
		||||
static uint8_t recv_data(void)
 | 
			
		||||
/*--------------------------------------------------------------------
 | 
			
		||||
 * Ring buffer to store scan codes from keyboard
 | 
			
		||||
 *------------------------------------------------------------------*/
 | 
			
		||||
#define PBUF_SIZE 32
 | 
			
		||||
static uint8_t pbuf[PBUF_SIZE];
 | 
			
		||||
static uint8_t pbuf_head = 0;
 | 
			
		||||
static uint8_t pbuf_tail = 0;
 | 
			
		||||
static inline void pbuf_enqueue(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    bool parity = true;
 | 
			
		||||
    ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
    /* start bit [1] */
 | 
			
		||||
    WAIT(clock_lo, 1, 1);
 | 
			
		||||
    WAIT(data_lo, 1, 2);
 | 
			
		||||
    WAIT(clock_hi, 50, 3);
 | 
			
		||||
 | 
			
		||||
    /* data [2-9] */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        WAIT(clock_lo, 50, 4);
 | 
			
		||||
        if (data_in()) {
 | 
			
		||||
            parity = !parity;
 | 
			
		||||
            data |= (1<<i);
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
 | 
			
		||||
    if (next != pbuf_tail) {
 | 
			
		||||
        pbuf[pbuf_head] = data;
 | 
			
		||||
        pbuf_head = next;
 | 
			
		||||
    } else {
 | 
			
		||||
        print("pbuf: full\n");
 | 
			
		||||
    }
 | 
			
		||||
        WAIT(clock_hi, 50, 5);
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
}
 | 
			
		||||
static inline uint8_t pbuf_dequeue(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val = 0;
 | 
			
		||||
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    if (pbuf_head != pbuf_tail) {
 | 
			
		||||
        val = pbuf[pbuf_tail];
 | 
			
		||||
        pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
 | 
			
		||||
    return val;
 | 
			
		||||
}
 | 
			
		||||
static inline bool pbuf_has_data(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    bool has_data = (pbuf_head != pbuf_tail);
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
    return has_data;
 | 
			
		||||
}
 | 
			
		||||
static inline void pbuf_clear(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sreg = SREG;
 | 
			
		||||
    cli();
 | 
			
		||||
    pbuf_head = pbuf_tail = 0;
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    /* parity [10] */
 | 
			
		||||
    WAIT(clock_lo, 50, 6);
 | 
			
		||||
    if (data_in() != parity) {
 | 
			
		||||
        ps2_error = PS2_ERR_PARITY;
 | 
			
		||||
        goto ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    WAIT(clock_hi, 50, 7);
 | 
			
		||||
 | 
			
		||||
    /* stop bit [11] */
 | 
			
		||||
    WAIT(clock_lo, 50, 8);
 | 
			
		||||
    WAIT(data_hi, 1, 9);
 | 
			
		||||
    WAIT(clock_hi, 50, 10);
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
ERROR:
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline void clock_lo()
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_DDR  |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void clock_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool clock_in()
 | 
			
		||||
{
 | 
			
		||||
    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()
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_DDR  |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool data_in()
 | 
			
		||||
{
 | 
			
		||||
    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--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* idle state that device can send */
 | 
			
		||||
static inline void idle(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* inhibit device to send */
 | 
			
		||||
static inline void inhibit(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_lo();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,32 +36,14 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Primitive PS/2 Library for AVR
 | 
			
		||||
==============================
 | 
			
		||||
Host side is only supported now.
 | 
			
		||||
Synchronous USART is used to receive data by hardware process
 | 
			
		||||
rather than interrupt. During V-USB interrupt runs, CLOCK interrupt
 | 
			
		||||
cannot interpose. In the result it is prone to lost CLOCK edge.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I/O control
 | 
			
		||||
-----------
 | 
			
		||||
High state is asserted by internal pull-up.
 | 
			
		||||
If you have a signaling problem, you may need to have
 | 
			
		||||
external pull-up resisters on CLOCK and DATA line.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PS/2 References
 | 
			
		||||
---------------
 | 
			
		||||
http://www.computer-engineering.org/ps2protocol/
 | 
			
		||||
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		||||
 * PS/2 protocol USART version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
#include <avr/interrupt.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include "ps2.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WAIT(stat, us, err) do { \
 | 
			
		||||
| 
						 | 
				
			
			@ -75,18 +57,6 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
 | 
			
		|||
uint8_t ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void clock_lo(void);
 | 
			
		||||
static inline void clock_hi(void);
 | 
			
		||||
static inline bool clock_in(void);
 | 
			
		||||
static inline void data_lo(void);
 | 
			
		||||
static inline void data_hi(void);
 | 
			
		||||
static inline bool data_in(void);
 | 
			
		||||
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);
 | 
			
		||||
static inline uint8_t pbuf_dequeue(void);
 | 
			
		||||
static inline void pbuf_enqueue(uint8_t data);
 | 
			
		||||
static inline bool pbuf_has_data(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -95,14 +65,15 @@ static inline void pbuf_clear(void);
 | 
			
		|||
 | 
			
		||||
void ps2_host_init(void)
 | 
			
		||||
{
 | 
			
		||||
    idle();
 | 
			
		||||
    idle(); // without this many USART errors occur when cable is disconnected
 | 
			
		||||
    PS2_USART_INIT();
 | 
			
		||||
    PS2_USART_RX_INT_ON();
 | 
			
		||||
    // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
 | 
			
		||||
    //_delay_ms(2500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t ps2_host_send(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t res = 0;
 | 
			
		||||
    bool parity = true;
 | 
			
		||||
    ps2_error = PS2_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -110,13 +81,14 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
 | 
			
		||||
    /* terminate a transmission if we have */
 | 
			
		||||
    inhibit();
 | 
			
		||||
    _delay_us(100);
 | 
			
		||||
    _delay_us(100); // [4]p.13
 | 
			
		||||
 | 
			
		||||
    /* start bit [1] */
 | 
			
		||||
    /* 'Request to Send' and Start bit */
 | 
			
		||||
    data_lo();
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    WAIT(clock_lo, 15000, 1);
 | 
			
		||||
    /* data [2-9] */
 | 
			
		||||
    WAIT(clock_lo, 10000, 10);   // 10ms [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* Data bit[2-9] */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        _delay_us(15);
 | 
			
		||||
        if (data&(1<<i)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -128,15 +100,18 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
        WAIT(clock_hi, 50, 2);
 | 
			
		||||
        WAIT(clock_lo, 50, 3);
 | 
			
		||||
    }
 | 
			
		||||
    /* parity [10] */
 | 
			
		||||
 | 
			
		||||
    /* Parity bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    if (parity) { data_hi(); } else { data_lo(); }
 | 
			
		||||
    WAIT(clock_hi, 50, 4);
 | 
			
		||||
    WAIT(clock_lo, 50, 5);
 | 
			
		||||
    /* stop bit [11] */
 | 
			
		||||
 | 
			
		||||
    /* Stop bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    data_hi();
 | 
			
		||||
    /* ack [12] */
 | 
			
		||||
 | 
			
		||||
    /* Ack */
 | 
			
		||||
    WAIT(data_lo, 50, 6);
 | 
			
		||||
    WAIT(clock_lo, 50, 7);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,127 +119,55 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
    WAIT(clock_hi, 50, 8);
 | 
			
		||||
    WAIT(data_hi, 50, 9);
 | 
			
		||||
 | 
			
		||||
    idle();
 | 
			
		||||
    PS2_USART_INIT();
 | 
			
		||||
    PS2_USART_RX_INT_ON();
 | 
			
		||||
    res = ps2_host_recv_response();
 | 
			
		||||
    return ps2_host_recv_response();
 | 
			
		||||
ERROR:
 | 
			
		||||
    idle();
 | 
			
		||||
    PS2_USART_INIT();
 | 
			
		||||
    PS2_USART_RX_INT_ON();
 | 
			
		||||
    return res;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Do polling data from keyboard to get response to last command.
 | 
			
		||||
uint8_t ps2_host_recv_response(void)
 | 
			
		||||
{
 | 
			
		||||
    while (!pbuf_has_data()) {
 | 
			
		||||
        _delay_ms(1);   // without this delay it seems to fall into deadlock
 | 
			
		||||
    // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
 | 
			
		||||
    uint8_t retry = 25;
 | 
			
		||||
    while (retry-- && !pbuf_has_data()) {
 | 
			
		||||
        _delay_ms(1);
 | 
			
		||||
    }
 | 
			
		||||
    return pbuf_dequeue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t ps2_host_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    if (pbuf_has_data()) {
 | 
			
		||||
        ps2_error = PS2_ERR_NONE;
 | 
			
		||||
        return pbuf_dequeue();
 | 
			
		||||
    } else {
 | 
			
		||||
        ps2_error = PS2_ERR_NODATA;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ISR(PS2_USART_RX_VECT)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t error = PS2_USART_ERROR;
 | 
			
		||||
    // TODO: request RESEND when error occurs?
 | 
			
		||||
    uint8_t error = PS2_USART_ERROR;    // USART error should be read before data
 | 
			
		||||
    uint8_t data = PS2_USART_RX_DATA;
 | 
			
		||||
    if (!error) {
 | 
			
		||||
        pbuf_enqueue(data);
 | 
			
		||||
    } else {
 | 
			
		||||
        xprintf("PS2 USART error: %02X data: %02X\n", error, data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* send LED state to keyboard */
 | 
			
		||||
void ps2_host_set_led(uint8_t led)
 | 
			
		||||
{
 | 
			
		||||
    // send 0xED then keyboard keeps waiting for next LED data
 | 
			
		||||
    // and keyboard does not send any scan codes during waiting.
 | 
			
		||||
    // If fail to send LED data keyboard looks like being freezed.
 | 
			
		||||
    uint8_t retry = 3;
 | 
			
		||||
    while (retry-- && ps2_host_send(PS2_SET_LED) != PS2_ACK)
 | 
			
		||||
        ;
 | 
			
		||||
    retry = 3;
 | 
			
		||||
    while (retry-- && ps2_host_send(led) != PS2_ACK)
 | 
			
		||||
        ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------------------------
 | 
			
		||||
 * static functions
 | 
			
		||||
 *------------------------------------------------------------------*/
 | 
			
		||||
static inline void clock_lo()
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_DDR  |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void clock_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool clock_in()
 | 
			
		||||
{
 | 
			
		||||
    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()
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_DDR  |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool data_in()
 | 
			
		||||
{
 | 
			
		||||
    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--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* idle state that device can send */
 | 
			
		||||
static inline void idle(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* inhibit device to send */
 | 
			
		||||
static inline void inhibit(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_lo();
 | 
			
		||||
    data_hi();
 | 
			
		||||
    ps2_host_send(0xED);
 | 
			
		||||
    ps2_host_send(led);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -284,11 +187,10 @@ static inline void pbuf_enqueue(uint8_t data)
 | 
			
		|||
        pbuf[pbuf_head] = data;
 | 
			
		||||
        pbuf_head = next;
 | 
			
		||||
    } else {
 | 
			
		||||
        debug("pbuf: full\n");
 | 
			
		||||
        print("pbuf: full\n");
 | 
			
		||||
    }
 | 
			
		||||
    SREG = sreg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint8_t pbuf_dequeue(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue