Merge branch 'ps2_keyboard_fix'

example_keyboards
tmk 11 years ago
commit bc5b64d832

@ -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 = .
# project specific 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
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# 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.
# 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
# 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
# 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)
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
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# keyboard dependent files
SRC = keymap.c \
matrix.c \
led.c
# 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
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
endif
# 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
#CONFIG_H = config_pjrc_usart.h
CONFIG_H = config.h
# 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
#---------------- Programming Options --------------------------
PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
# 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

@ -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]);
}

@ -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)]) };
}

@ -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

@ -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);

@ -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,32 +37,46 @@ 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
*/
/* port settings for clock and data line */
#if !(defined(PS2_CLOCK_PORT) && \
defined(PS2_CLOCK_PIN) && \
defined(PS2_CLOCK_DDR) && \
defined(PS2_CLOCK_BIT))
# error "PS/2 clock port setting is required in config.h"
#endif
#if !(defined(PS2_DATA_PORT) && \
defined(PS2_DATA_PIN) && \
defined(PS2_DATA_DDR) && \
defined(PS2_DATA_BIT))
# error "PS/2 data port setting is required in config.h"
#endif
#define PS2_ACK 0xFA
#define PS2_RESEND 0xFE
#define PS2_SET_LED 0xED
#define PS2_ERR_NONE 0
#define PS2_ERR_PARITY 0x10
// 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
@ -71,13 +85,101 @@ POSSIBILITY OF SUCH DAMAGE.
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 */
/* Check port settings for clock and data line */
#if !(defined(PS2_CLOCK_PORT) && \
defined(PS2_CLOCK_PIN) && \
defined(PS2_CLOCK_DDR) && \
defined(PS2_CLOCK_BIT))
# error "PS/2 clock port setting is required in config.h"
#endif
#if !(defined(PS2_DATA_PORT) && \
defined(PS2_DATA_PIN) && \
defined(PS2_DATA_DDR) && \
defined(PS2_DATA_BIT))
# error "PS/2 data port setting is required in config.h"
#endif
/*--------------------------------------------------------------------
* static functions
*------------------------------------------------------------------*/
static inline void clock_lo(void)
{
PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
}
static inline void clock_hi(void)
{
/* input with pull up */
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
}
static inline bool clock_in(void)
{
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
_delay_us(1);
return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
}
static inline void data_lo(void)
{
PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
}
static inline void data_hi(void)
{
/* input with pull up */
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
}
static inline bool data_in(void)
{
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
_delay_us(1);
return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
}
static inline uint16_t wait_clock_lo(uint16_t us)
{
while (clock_in() && us) { asm(""); _delay_us(1); us--; }
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();
}
#endif

@ -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
idle();
PS2_INT_ON();
#endif
res = ps2_host_recv_response();
return ps2_host_recv_response();
ERROR:
#ifdef PS2_USE_INT
PS2_INT_ON();
idle();
#else
inhibit();
#endif
return res;
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;
}
#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;
// 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);
}
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;
return pbuf_dequeue();
} else {
ps2_error = PS2_ERR_NODATA;
return 0;
}
idle();
return pbuf_dequeue();
}
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);
}
WAIT(clock_hi, 50, 5);
}
/* parity [10] */
WAIT(clock_lo, 50, 6);
if (data_in() != parity) {
ps2_error = PS2_ERR_PARITY;
goto ERROR;
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, 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);
SREG = sreg;
}
static inline bool data_in()
static inline uint8_t pbuf_dequeue(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);
}
uint8_t val = 0;
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;
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 uint16_t wait_data_hi(uint16_t us)
static inline bool pbuf_has_data(void)
{
while (!data_in() && us) { asm(""); _delay_us(1); us--; }
return us;
uint8_t sreg = SREG;
cli();
bool has_data = (pbuf_head != pbuf_tail);
SREG = sreg;
return has_data;
}
/* idle state that device can send */
static inline void idle(void)
static inline void pbuf_clear(void)
{
clock_hi();
data_hi();
uint8_t sreg = SREG;
cli();
pbuf_head = pbuf_tail = 0;
SREG = sreg;
}
/* 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.
* PS/2 protocol USART version
*/
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
*/
#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)
{
return pbuf_dequeue();
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…
Cancel
Save