Merge branch 'ibm4704'
This commit is contained in:
		
						commit
						188ab49dd3
					
				
					 13 changed files with 1073 additions and 0 deletions
				
			
		| 
						 | 
					@ -41,6 +41,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di
 | 
				
			||||||
* [pc98_usb](converter/pc98_usb/)           - [PC98] to USB
 | 
					* [pc98_usb](converter/pc98_usb/)           - [PC98] to USB
 | 
				
			||||||
* [usb_usb](converter/usb_usb/)             - USB to USB(experimental)
 | 
					* [usb_usb](converter/usb_usb/)             - USB to USB(experimental)
 | 
				
			||||||
* [ascii_usb](converter/ascii_usb/)         - ASCII(Serial console terminal) to USB
 | 
					* [ascii_usb](converter/ascii_usb/)         - ASCII(Serial console terminal) to USB
 | 
				
			||||||
 | 
					* [ibm4704_usb](converter/ibm4704_usb)      - [IBM 4704 keyboard Converter][GH_ibm4704]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### keyboard
 | 
					### keyboard
 | 
				
			||||||
* [hhkb](keyboard/hhkb/)                    - [Happy Hacking Keyboard pro][GH_hhkb] **my main board**
 | 
					* [hhkb](keyboard/hhkb/)                    - [Happy Hacking Keyboard pro][GH_hhkb] **my main board**
 | 
				
			||||||
| 
						 | 
					@ -62,6 +63,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di
 | 
				
			||||||
[GH_terminal]:  http://geekhack.org/showwiki.php?title=Island:27272
 | 
					[GH_terminal]:  http://geekhack.org/showwiki.php?title=Island:27272
 | 
				
			||||||
[GH_x68k]:      http://geekhack.org/showwiki.php?title=Island:29060
 | 
					[GH_x68k]:      http://geekhack.org/showwiki.php?title=Island:29060
 | 
				
			||||||
[GH_hbkb]:      http://geekhack.org/showwiki.php?title=Island:29483
 | 
					[GH_hbkb]:      http://geekhack.org/showwiki.php?title=Island:29483
 | 
				
			||||||
 | 
					[GH_ibm4704]:   http://geekhack.org/index.php?topic=54706.0
 | 
				
			||||||
[HID_liber]:    http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions
 | 
					[HID_liber]:    http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions
 | 
				
			||||||
[Phantom]:      http://geekhack.org/index.php?topic=26742
 | 
					[Phantom]:      http://geekhack.org/index.php?topic=26742
 | 
				
			||||||
[GH60]:         http://geekhack.org/index.php?topic=34959
 | 
					[GH60]:         http://geekhack.org/index.php?topic=34959
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										93
									
								
								converter/ibm4704_usb/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								converter/ibm4704_usb/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,93 @@
 | 
				
			||||||
 | 
					# Target file name (without extension).
 | 
				
			||||||
 | 
					TARGET = ibm4704_usb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Directory common source filess exist
 | 
				
			||||||
 | 
					TOP_DIR = ../..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Directory keyboard dependent files exist
 | 
				
			||||||
 | 
					TARGET_DIR = .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# project specific files
 | 
				
			||||||
 | 
					SRC =	keymap_common.c \
 | 
				
			||||||
 | 
						matrix.c \
 | 
				
			||||||
 | 
						led.c \
 | 
				
			||||||
 | 
						protocol/ibm4704.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifdef KEYMAP
 | 
				
			||||||
 | 
					    SRC := keymap_$(KEYMAP).c $(SRC)
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    SRC := keymap_plain.c $(SRC)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONFIG_H = config.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Search Path
 | 
				
			||||||
 | 
					VPATH += $(TARGET_DIR)
 | 
				
			||||||
 | 
					VPATH += $(TOP_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(TOP_DIR)/protocol.mk
 | 
				
			||||||
 | 
					include $(TOP_DIR)/protocol/lufa.mk
 | 
				
			||||||
 | 
					include $(TOP_DIR)/common.mk
 | 
				
			||||||
 | 
					include $(TOP_DIR)/rules.mk
 | 
				
			||||||
							
								
								
									
										46
									
								
								converter/ibm4704_usb/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								converter/ibm4704_usb/README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					IBM 4704 to USB keyboard converter
 | 
				
			||||||
 | 
					==================================
 | 
				
			||||||
 | 
					This firmware converts IBM 4704 keyboard protocol to USB HID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Keyboard initialization process takes a few seconds at start up. During that you will hear buzzer from the keyboard. **You need to plug USB cable after hooking up your keyboard to the converter.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4704 Connector
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					Keyboard Plug from front:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DSUB-9
 | 
				
			||||||
 | 
					    -------------
 | 
				
			||||||
 | 
					    \ N 2 3 4 5 /
 | 
				
			||||||
 | 
					     \ N N N N /
 | 
				
			||||||
 | 
					      ---------
 | 
				
			||||||
 | 
					    2   GND
 | 
				
			||||||
 | 
					    3   VCC 5V
 | 
				
			||||||
 | 
					    4   DATA
 | 
				
			||||||
 | 
					    5   CLOCK
 | 
				
			||||||
 | 
					    N   No connection/No pin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Connection
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					In case of using ATMega32U4(Teensy2.0):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Supply power with VCC and GND.
 | 
				
			||||||
 | 
					2. Connect CLOCK to PD1 and DATA to PD0. You can change pin with config.h.
 | 
				
			||||||
 | 
					3. Optionally you may need pull-up register. 1KOhm probably work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Build Firmware
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					Just run `make`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ make
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To select keymap:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ make KEYMAP=[plain|...]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Keymap
 | 
				
			||||||
 | 
					------
 | 
				
			||||||
 | 
					Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `keymap_<name>.c` and see keymap document(you can find in top README.md) and existent keymap files.
 | 
				
			||||||
							
								
								
									
										73
									
								
								converter/ibm4704_usb/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								converter/ibm4704_usb/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Jun Wako <wakojun@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					the Free Software Foundation, either version 2 of the License, or
 | 
				
			||||||
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_H
 | 
				
			||||||
 | 
					#define CONFIG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <avr/interrupt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VENDOR_ID       0xFEED
 | 
				
			||||||
 | 
					#define PRODUCT_ID      0x4707
 | 
				
			||||||
 | 
					#define DEVICE_VER      0x0001
 | 
				
			||||||
 | 
					#define MANUFACTURER    t.m.k.
 | 
				
			||||||
 | 
					#define PRODUCT         IBM 4704 keyboard converter
 | 
				
			||||||
 | 
					#define DESCRIPTION     convert IBM 4704 keyboard to USB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* matrix size */
 | 
				
			||||||
 | 
					#define MATRIX_ROWS 16  // keycode bit3-6 
 | 
				
			||||||
 | 
					#define MATRIX_COLS 8   // keycode bit0-2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* key combination for command */
 | 
				
			||||||
 | 
					#define IS_COMMAND() ( \
 | 
				
			||||||
 | 
					    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Busywait
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define IBM4704_CLOCK_PORT  PORTD
 | 
				
			||||||
 | 
					#define IBM4704_CLOCK_PIN   PIND
 | 
				
			||||||
 | 
					#define IBM4704_CLOCK_DDR   DDRD
 | 
				
			||||||
 | 
					#define IBM4704_CLOCK_BIT   1
 | 
				
			||||||
 | 
					#define IBM4704_DATA_PORT   PORTD
 | 
				
			||||||
 | 
					#define IBM4704_DATA_PIN    PIND
 | 
				
			||||||
 | 
					#define IBM4704_DATA_DDR    DDRD
 | 
				
			||||||
 | 
					#define IBM4704_DATA_BIT    0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Pin interrupt
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifdef IBM4704_USE_INT
 | 
				
			||||||
 | 
					#define IBM4704_INT_INIT()  do {    \
 | 
				
			||||||
 | 
					    EICRA |= ((1<<ISC11) |      \
 | 
				
			||||||
 | 
					              (0<<ISC10));      \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define IBM4704_INT_ON()  do {      \
 | 
				
			||||||
 | 
					    EIMSK |= (1<<INT1);         \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define IBM4704_INT_OFF() do {      \
 | 
				
			||||||
 | 
					    EIMSK &= ~(1<<INT1);        \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define IBM4704_INT_VECT    INT1_vect
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										160
									
								
								converter/ibm4704_usb/ibm4704.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								converter/ibm4704_usb/ibm4704.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,160 @@
 | 
				
			||||||
 | 
					4704 Keyboard
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					Keyboard Models:
 | 
				
			||||||
 | 
					    Model 100 6019273 50-key (grid layout)
 | 
				
			||||||
 | 
					    Model 200 6019284 62-key Alpha(60% layout)
 | 
				
			||||||
 | 
					    Model 300 6019303 77-key Expanded Alpha
 | 
				
			||||||
 | 
					    Model 400 6020218 107-key Full key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Resourse
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					The IBM 4704: lots of pictures and info
 | 
				
			||||||
 | 
					http://kishy.dyndns.org/?p=648#more-648 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Brochure:
 | 
				
			||||||
 | 
					http://ed-thelen.org/comp-hist/IBM-ProdAnn/4700.pdf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4704 Keyboard Protocol
 | 
				
			||||||
 | 
					======================
 | 
				
			||||||
 | 
					On powering up the keyboard sends keyboard id; A3h for 6019284(62-key), for example.
 | 
				
			||||||
 | 
					After that firmware enters FC command mode and waits for parameter data from host
 | 
				
			||||||
 | 
					so that it doesn't send any scancode until you send 'FF'(End of FC command).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Connector
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					    Keyboard Plug from front
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DSUB-9
 | 
				
			||||||
 | 
					    -------------
 | 
				
			||||||
 | 
					    \ N 2 3 4 5 /
 | 
				
			||||||
 | 
					     \ N N N N /
 | 
				
			||||||
 | 
					      ---------
 | 
				
			||||||
 | 
					    2   GND
 | 
				
			||||||
 | 
					    3   VCC 5V
 | 
				
			||||||
 | 
					    4   DATA
 | 
				
			||||||
 | 
					    5   CLOCK
 | 
				
			||||||
 | 
					    N   No connection/No pin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Keyboard to Host
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ____      __   __   __   __   __   __   __   __   __   ________
 | 
				
			||||||
 | 
					    Clock       \____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
 | 
				
			||||||
 | 
					                 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
 | 
				
			||||||
 | 
					    Data    ____/    X____X____X____X____X____X____X____X____X____X________
 | 
				
			||||||
 | 
					                Start   0    1    2    3    4    5    6    7    P  Stop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start bit:  can be long as 300-350us.
 | 
				
			||||||
 | 
					Inhibit:    Pull Data line down to inhibit keyboard to send.
 | 
				
			||||||
 | 
					Timing:     Host reads bit while Clock is hi.
 | 
				
			||||||
 | 
					Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Host to Keyboard
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ____        __   __   __   __   __   __   __   __   __   ________
 | 
				
			||||||
 | 
					    Clock       \______/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
 | 
				
			||||||
 | 
					                ^   ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
 | 
				
			||||||
 | 
					    Data    ____|__/    X____X____X____X____X____X____X____X____X____X   \___
 | 
				
			||||||
 | 
					                |  Start   0    1    2    3    4    5    6    7    P   Stop
 | 
				
			||||||
 | 
					                Request by host
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start bit:  can be long as 300-350us.
 | 
				
			||||||
 | 
					Request:    Host pulls Clock line down to request to send a command.
 | 
				
			||||||
 | 
					Timing:     After Request keyboard pull up Data and down Clock line to low for start bit.
 | 
				
			||||||
 | 
					            After request host release Clock line once Data line becomes hi.
 | 
				
			||||||
 | 
					            Host wirtes a bit while Clock is hi and Keyboard reads while low.
 | 
				
			||||||
 | 
					Stop bit:   Host releases or pulls up Data line to hi after 9th clock and waits for keybaord pull down the line to lo.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Scancodes
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					Keyboard doesn't send Break code for all keys except for Alt by default.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    6019284 62-key:
 | 
				
			||||||
 | 
					    ,-----------------------------------------------------------.
 | 
				
			||||||
 | 
					    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|???|BS |
 | 
				
			||||||
 | 
					    |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P| ¢|  \|  PD2|
 | 
				
			||||||
 | 
					    |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					    |Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '| {}| PD3|
 | 
				
			||||||
 | 
					    |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					    |Shif| <>|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|???|Shift |
 | 
				
			||||||
 | 
					    |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					    |Reset|blk|Alt  |         Space             |Alt  |blk|Enter|
 | 
				
			||||||
 | 
					    `-----------------------------------------------------------'
 | 
				
			||||||
 | 
					    +----------+---------------------+----------+----------+
 | 
				
			||||||
 | 
					    |`       00|PD1     04|Caps    20|LShift  30|Reset   31|
 | 
				
			||||||
 | 
					    |1       18|q       05|a       21|<>      3E|Rblank  41|
 | 
				
			||||||
 | 
					    |2       19|w       06|s       22|z       32|Alt     3F|
 | 
				
			||||||
 | 
					    |3       1A|e       13|d       23|x       33|Space   40|
 | 
				
			||||||
 | 
					    |4       10|r       14|f       24|c       34|Alt     3F|
 | 
				
			||||||
 | 
					    |5       11|t       15|g       25|v       35|Lblank  42|
 | 
				
			||||||
 | 
					    |6       12|y       16|h       26|b       36|Enter   2F|
 | 
				
			||||||
 | 
					    |7       08|u       17|j       27|n       37|          |
 | 
				
			||||||
 | 
					    |8       09|i       01|k       28|m       38|          |
 | 
				
			||||||
 | 
					    |9       0A|o       02|l       29|,       39|          |
 | 
				
			||||||
 | 
					    |0       0F|p       03|;       2A|.       3A|          |
 | 
				
			||||||
 | 
					    |-       1F|¢      1B|'       2B|/       3B|          |
 | 
				
			||||||
 | 
					    |=       0D|\       1C|{}      2C|???     3C|          |
 | 
				
			||||||
 | 
					    |???     0C|PD2     1D|PD3     2D|RShift  3D|          |
 | 
				
			||||||
 | 
					    |BS      0E|          |          |          |          |
 | 
				
			||||||
 | 
					    +----------+---------------------+----------+----------+
 | 
				
			||||||
 | 
					    Bit7 is 'press flag' which set 1 on press and 0 on release when break code is enabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE: When break code is enabled the key sends scancode with setting 7th bit on press
 | 
				
			||||||
 | 
					and without it on release. That is, '`' sends 80h on press and 00h on release.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					keyboard command
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					    FF  Soft Reset(0008h)
 | 
				
			||||||
 | 
					    FE  Resend(00e8h)
 | 
				
			||||||
 | 
					    FD  Buzzer stop?(00edh)
 | 
				
			||||||
 | 
					    FC  Set Key flag(00f6h)
 | 
				
			||||||
 | 
					    FB  Soft Reset(0008h)
 | 
				
			||||||
 | 
					    FA  Reset(0000h)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Keyboard response
 | 
				
			||||||
 | 
					-----------------
 | 
				
			||||||
 | 
					    FF  Not exist. [Outgoing buffer cannot have FFh(00h in fact)]
 | 
				
			||||||
 | 
					    FE  Overflow(key event/receive data)        at 00c5h, 0346h
 | 
				
			||||||
 | 
					    FE  Memory test error                       at 0224h
 | 
				
			||||||
 | 
					    FD  Command out of bound                    at 00d8h
 | 
				
			||||||
 | 
					        Key out of bound
 | 
				
			||||||
 | 
					    7E  Read/Parity error in receive from host  at 00bch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set Key flag command(FC)
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					After 'Power on Reset' firmware enters this command mode and waits for data from host,
 | 
				
			||||||
 | 
					so that you don't need to send 'FC' and it doesn't send any scancode until you send 'FF'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Data sent from host:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bit: 7   6 ... 0
 | 
				
			||||||
 | 
					         en  |     |
 | 
				
			||||||
 | 
					         |   `-----`--- scan code
 | 
				
			||||||
 | 
					         `------------- enable bit(0: enable repeat, 1: enable break)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    00-77   Enable repeat(78-7F: invalid scancode)
 | 
				
			||||||
 | 
					    80-F7   Enable break(F8-FF: invalid scancode)
 | 
				
			||||||
 | 
					    FE      Resend(011ah) no need to use
 | 
				
			||||||
 | 
					    FF      End(0114h) exits FC command mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Response from keyboard:
 | 
				
			||||||
 | 
					    FD      Out of bound - Invalid scancode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					    To enable break code of all keys.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FC 80 81 ... F7 FF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								converter/ibm4704_usb/keymap_common.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								converter/ibm4704_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)]) };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										73
									
								
								converter/ibm4704_usb/keymap_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								converter/ibm4704_usb/keymap_common.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					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[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Original keys */
 | 
				
			||||||
 | 
					#define KEYMAP( \
 | 
				
			||||||
 | 
					    K00,K18,K19,K1A,K10,K11,K12,K08,K09,K0A,K0F,K1F,K0D,K0C,K0E, \
 | 
				
			||||||
 | 
					    K04,K05,K06,K13,K14,K15,K16,K17,K01,K02,K03,K1B,K1C,K1D, \
 | 
				
			||||||
 | 
					    K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K2A,K2B,K2C,K2D, \
 | 
				
			||||||
 | 
					    K30,K3E,K32,K33,K34,K35,K36,K37,K38,K39,K3A,K3B,K3C,K3D, \
 | 
				
			||||||
 | 
					    K31,K41,K3F,        K40,                    K42,K2F \
 | 
				
			||||||
 | 
					) { \
 | 
				
			||||||
 | 
					    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_NO }, \
 | 
				
			||||||
 | 
					    { KC_##K08, KC_##K09, KC_##K0A, KC_NO,    KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
 | 
				
			||||||
 | 
					    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
 | 
				
			||||||
 | 
					    { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_NO,    KC_##K1F }, \
 | 
				
			||||||
 | 
					    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
 | 
				
			||||||
 | 
					    { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_NO,    KC_##K2F }, \
 | 
				
			||||||
 | 
					    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
 | 
				
			||||||
 | 
					    { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
 | 
				
			||||||
 | 
					    { KC_##K40, KC_##K41, KC_##K42, 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_NO }, \
 | 
				
			||||||
 | 
					    { 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_NO,    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_NO,    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_NO,    KC_NO }, \
 | 
				
			||||||
 | 
					    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    { K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
 | 
				
			||||||
 | 
					    { K50, K51, K52, K53, K54, K55, K56, K57 }, \
 | 
				
			||||||
 | 
					    { K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
 | 
				
			||||||
 | 
					    { K60, K61, K62, K63, K64, K65, K66, K67 }, \
 | 
				
			||||||
 | 
					    { K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
 | 
				
			||||||
 | 
					    { K70, K71, K72, K73, K74, K75, K76, K77 }, \
 | 
				
			||||||
 | 
					    { K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }, \
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
							
								
								
									
										85
									
								
								converter/ibm4704_usb/keymap_hasu.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								converter/ibm4704_usb/keymap_hasu.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					#include "keymap_common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
				
			||||||
 | 
					    /* 0: default
 | 
				
			||||||
 | 
					     * ,-----------------------------------------------------------.
 | 
				
			||||||
 | 
					     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|???|BS |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \|
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|xxx|Ret |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Shif|xxx|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|xxx|Shift |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Ctrl |Gui|Alt  |         Space             |Alt  |Gui|Ctrl |
 | 
				
			||||||
 | 
					     * `-----------------------------------------------------------'
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSLS,GRV, \
 | 
				
			||||||
 | 
					    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSPC, \
 | 
				
			||||||
 | 
					    LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   FN1, QUOT,NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2, NO,  FN0, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          FN3,                               RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL, \
 | 
				
			||||||
 | 
					    CAPS,NO,  NO,  NO,  NO,  NO,  NO,  NO,  PSCR,SLCK,PAUS, UP, NO,  BSPC, \
 | 
				
			||||||
 | 
					    LCTL,VOLD,VOLU,MUTE,NO,  NO,  PAST,PSLS,HOME,PGUP,LEFT,RGHT,NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  NO,  NO,  NO,  NO,  NO,  PPLS,PMNS,END, PGDN,DOWN,NO,  TRNS, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          SPC,                               RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL, \
 | 
				
			||||||
 | 
					    TAB, NO,  NO,  NO,  NO,  NO,  WH_L,WH_D,WH_U,WH_R,WSTP,WBAK,WFWD,BSPC, \
 | 
				
			||||||
 | 
					    LCTL,NO,  ACL0,ACL1,ACL2,NO,  MS_L,MS_D,MS_U,MS_R,TRNS,NO,  NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,BTN4,BTN5,NO,  NO,  RSFT,\
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          BTN1,                              RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL, \
 | 
				
			||||||
 | 
					    TAB, HOME,PGDN,UP,  PGUP,END, HOME,PGDN,PGUP,END, NO,  NO,  NO,  BSPC, \
 | 
				
			||||||
 | 
					    LCTL,NO,  LEFT,DOWN,RGHT,NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,  NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, TRNS,NO,  RSFT, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          SPC,                               RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL, \
 | 
				
			||||||
 | 
					    TAB, NO,  NO,  NO,  NO,  NO,  WH_L,WH_D,MS_U,WH_U,WH_R,BTN4,BTN5,FN4, \
 | 
				
			||||||
 | 
					    LCTL,VOLD,VOLU,MUTE,NO,  NO,  BTN2,MS_L,MS_D,MS_R,BTN1,NO,  NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,BTN4,BTN5,NO,  NO,  NO, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          TRNS,                              RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum macro_id {
 | 
				
			||||||
 | 
					    ALT_TAB,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t PROGMEM fn_actions[] = {
 | 
				
			||||||
 | 
					    [0] = ACTION_LAYER_MOMENTARY(1),
 | 
				
			||||||
 | 
					    [1] = ACTION_LAYER_TAP_KEY(2, KC_SCLN),
 | 
				
			||||||
 | 
					    [2] = ACTION_LAYER_TAP_KEY(3, KC_SLASH),
 | 
				
			||||||
 | 
					    [3] = ACTION_LAYER_TAP_KEY(4, KC_SPC),
 | 
				
			||||||
 | 
					    [4] = ACTION_MACRO(ALT_TAB),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Macro definition
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    keyevent_t event = record->event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (id) {
 | 
				
			||||||
 | 
					        case ALT_TAB:
 | 
				
			||||||
 | 
					            return (event.pressed ?
 | 
				
			||||||
 | 
					                    MACRO( D(LALT), D(TAB), END ) :
 | 
				
			||||||
 | 
					                    MACRO( U(TAB), END ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return MACRO_NONE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								converter/ibm4704_usb/keymap_plain.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								converter/ibm4704_usb/keymap_plain.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					#include "keymap_common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
				
			||||||
 | 
					    /* 0: default
 | 
				
			||||||
 | 
					     * ,-----------------------------------------------------------.
 | 
				
			||||||
 | 
					     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|???|BS |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \|
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|Ret |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Shif|  \|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|???|Shift |
 | 
				
			||||||
 | 
					     * |-----------------------------------------------------------|
 | 
				
			||||||
 | 
					     * |Ctrl |Gui|Alt  |         Space             |Alt* |Gui|Ctrl |
 | 
				
			||||||
 | 
					     * `-----------------------------------------------------------'
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSLS,BSPC, \
 | 
				
			||||||
 | 
					    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS, \
 | 
				
			||||||
 | 
					    LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,NUHS,ENT, \
 | 
				
			||||||
 | 
					    LSFT,NUBS,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,NO,  FN0, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          SPC,                               RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 1: HHKB */
 | 
				
			||||||
 | 
					    KEYMAP(
 | 
				
			||||||
 | 
					    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL, \
 | 
				
			||||||
 | 
					    CAPS,NO,  NO,  NO,  NO,  NO,  NO,  NO,  PSCR,SLCK,PAUS, UP, NO,  INS, \
 | 
				
			||||||
 | 
					    LCTL,VOLD,VOLU,MUTE,NO,  NO,  PAST,PSLS,HOME,PGUP,LEFT,RGHT,NO,  ENT, \
 | 
				
			||||||
 | 
					    LSFT,NO,  NO,  NO,  NO,  NO,  NO,  PPLS,PMNS,END, PGDN,DOWN,NO,  TRNS, \
 | 
				
			||||||
 | 
					    LCTL,LGUI,LALT,          SPC,                               RGUI,RCTL \
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t PROGMEM fn_actions[] = {
 | 
				
			||||||
 | 
					    [0] = ACTION_LAYER_MOMENTARY(1),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										24
									
								
								converter/ibm4704_usb/led.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								converter/ibm4704_usb/led.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					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/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stdint.h"
 | 
				
			||||||
 | 
					#include "led.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void led_set(uint8_t usb_led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										170
									
								
								converter/ibm4704_usb/matrix.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								converter/ibm4704_usb/matrix.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,170 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 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 <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <avr/io.h>
 | 
				
			||||||
 | 
					#include <util/delay.h>
 | 
				
			||||||
 | 
					#include "action.h"
 | 
				
			||||||
 | 
					#include "print.h"
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					#include "ibm4704.h"
 | 
				
			||||||
 | 
					#include "matrix.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void matrix_make(uint8_t code);
 | 
				
			||||||
 | 
					static void matrix_break(uint8_t code);
 | 
				
			||||||
 | 
					static void matrix_clear(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Matrix Array usage:
 | 
				
			||||||
 | 
					 * IBM 4704 scan codes are assigned into 128(16x8)-cell matrix.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    8bit wide
 | 
				
			||||||
 | 
					 *   +---------+
 | 
				
			||||||
 | 
					 *  0|         |
 | 
				
			||||||
 | 
					 *  :|   XX    | 00-7F
 | 
				
			||||||
 | 
					 *  f|         |
 | 
				
			||||||
 | 
					 *   +---------+
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Exceptions:
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static uint8_t matrix[MATRIX_ROWS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// scan code bits  7654 3210
 | 
				
			||||||
 | 
					// R:row/C:column  -RRR RCCC
 | 
				
			||||||
 | 
					#define ROW(code)      ((code>>3)&0x0f)
 | 
				
			||||||
 | 
					#define COL(code)      (code&0x07)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					uint8_t matrix_rows(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return MATRIX_ROWS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					uint8_t matrix_cols(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return MATRIX_COLS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void enable_break(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t ret;
 | 
				
			||||||
 | 
					    print("Enable break: ");
 | 
				
			||||||
 | 
					    // valid scancode: 00-77h
 | 
				
			||||||
 | 
					    for (uint8_t code = 0; code < 0x78; code++) {
 | 
				
			||||||
 | 
					        while (ibm4704_send(0x80|code) != 0) {
 | 
				
			||||||
 | 
					            print("z");
 | 
				
			||||||
 | 
					            _delay_us(500);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _delay_us(2000);
 | 
				
			||||||
 | 
					        ret = ibm4704_recv();
 | 
				
			||||||
 | 
					        if (ret != 0xff) {
 | 
				
			||||||
 | 
					            xprintf("c%02X:r%02X ", code, ret);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _delay_us(1000);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _delay_us(1000);
 | 
				
			||||||
 | 
					    while (ibm4704_send(0xFF) != 0) { _delay_us(500); } // End
 | 
				
			||||||
 | 
					    print("End\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void matrix_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t ret;
 | 
				
			||||||
 | 
					    debug_enable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ibm4704_init();
 | 
				
			||||||
 | 
					    matrix_clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // read keyboard id
 | 
				
			||||||
 | 
					    while ((ret = ibm4704_recv()) == 0xFF) {
 | 
				
			||||||
 | 
					        ibm4704_send(0xFE);
 | 
				
			||||||
 | 
					        _delay_us(100);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _delay_ms(2000);    // wait for starting up debug console 
 | 
				
			||||||
 | 
					    print("IBM 4704 converter\n");
 | 
				
			||||||
 | 
					    xprintf("Keyboard ID: %02X\n", ret);
 | 
				
			||||||
 | 
					    enable_break();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * IBM 4704 Scan Code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t matrix_scan(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t code = ibm4704_recv();
 | 
				
			||||||
 | 
					    if (code==0xFF) {
 | 
				
			||||||
 | 
					        // Not receivd
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    } else if ((code&0x78)==0x78) {
 | 
				
			||||||
 | 
					        // 0xFF-F8 and 0x7F-78 is not scancode
 | 
				
			||||||
 | 
					        xprintf("Error: %0X\n", code);
 | 
				
			||||||
 | 
					        matrix_clear();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    } else if (code&0x80) {
 | 
				
			||||||
 | 
					        matrix_make(code);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        matrix_break(code);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					bool matrix_is_on(uint8_t row, uint8_t col)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (matrix[row] & (1<<col));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					uint8_t matrix_get_row(uint8_t row)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return matrix[row];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void matrix_print(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    print("\nr/c 01234567\n");
 | 
				
			||||||
 | 
					    for (uint8_t row = 0; row < matrix_rows(); row++) {
 | 
				
			||||||
 | 
					        xprintf("%02X: %08b\n", row, bitrev(matrix_get_row(row)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					static void matrix_make(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    matrix[ROW(code)] |= 1<<COL(code);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					static void matrix_break(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    matrix[ROW(code)] &= ~(1<<COL(code));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					static void matrix_clear(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										169
									
								
								protocol/ibm4704.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								protocol/ibm4704.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,169 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <util/delay.h>
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "ibm4704.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WAIT(stat, us, err) do { \
 | 
				
			||||||
 | 
					    if (!wait_##stat(us)) { \
 | 
				
			||||||
 | 
					        ibm4704_error = err; \
 | 
				
			||||||
 | 
					        goto ERROR; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t ibm4704_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ibm4704_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    inhibit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Host to Keyboard
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ____        __   __   __   __   __   __   __   __   __   ________
 | 
				
			||||||
 | 
					Clock       \______/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
 | 
				
			||||||
 | 
					            ^   ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
 | 
				
			||||||
 | 
					Data    ____|__/    X____X____X____X____X____X____X____X____X____X   \___
 | 
				
			||||||
 | 
					            |  Start   0    1    2    3    4    5    6    7    P   Stop
 | 
				
			||||||
 | 
					            Request by host
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start bit:  can be long as 300-350us.
 | 
				
			||||||
 | 
					Request:    Host pulls Clock line down to request to send a command.
 | 
				
			||||||
 | 
					Timing:     After Request keyboard pull up Data and down Clock line to low for start bit.
 | 
				
			||||||
 | 
					            After request host release Clock line once Data line becomes hi.
 | 
				
			||||||
 | 
					            Host writes a bit while Clock is hi and Keyboard reads while low.
 | 
				
			||||||
 | 
					Stop bit:   Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					uint8_t ibm4704_send(uint8_t data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool parity = true; // odd parity
 | 
				
			||||||
 | 
					    ibm4704_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Request to send */
 | 
				
			||||||
 | 
					    idle();
 | 
				
			||||||
 | 
					    clock_lo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* wait for Start bit(Clock:lo/Data:hi) */
 | 
				
			||||||
 | 
					    WAIT(data_hi, 300, 0x30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Data bit */
 | 
				
			||||||
 | 
					    for (uint8_t i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					        WAIT(clock_hi, 100, 0x40+i);
 | 
				
			||||||
 | 
					        //_delay_us(5);
 | 
				
			||||||
 | 
					        if (data&(1<<i)) {
 | 
				
			||||||
 | 
					            parity = !parity;
 | 
				
			||||||
 | 
					            data_hi();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            data_lo();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        WAIT(clock_lo, 100, 0x48+i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Parity bit */
 | 
				
			||||||
 | 
					    WAIT(clock_hi, 100, 0x34);
 | 
				
			||||||
 | 
					    if (parity) { data_hi(); } else { data_lo(); }
 | 
				
			||||||
 | 
					    WAIT(clock_lo, 100, 0x35);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Stop bit */
 | 
				
			||||||
 | 
					    WAIT(clock_hi, 100, 0x34);
 | 
				
			||||||
 | 
					    data_hi();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* End */
 | 
				
			||||||
 | 
					    WAIT(data_lo, 100, 0x36);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inhibit();
 | 
				
			||||||
 | 
					    _delay_us(200); // wait to recover clock to hi
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					ERROR:
 | 
				
			||||||
 | 
					    inhibit();
 | 
				
			||||||
 | 
					    if (ibm4704_error >= 0x30) {
 | 
				
			||||||
 | 
					        xprintf("x%02X ", ibm4704_error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _delay_us(200); // wait to recover clock to hi
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* receive data when host want else inhibit communication */
 | 
				
			||||||
 | 
					uint8_t ibm4704_recv_response(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 250 * 100us(wait start bit in ibm4704_recv)
 | 
				
			||||||
 | 
					    uint8_t data = 0;
 | 
				
			||||||
 | 
					    uint8_t try = 250;
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        data = ibm4704_recv();
 | 
				
			||||||
 | 
					    } while (try-- && ibm4704_error);
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Keyboard to Host
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ____      __   __   __   __   __   __   __   __   __   ________
 | 
				
			||||||
 | 
					Clock       \____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
 | 
				
			||||||
 | 
					             ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
 | 
				
			||||||
 | 
					Data    ____/    X____X____X____X____X____X____X____X____X____X________
 | 
				
			||||||
 | 
					            Start   0    1    2    3    4    5    6    7    P  Stop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start bit:  can be long as 300-350us.
 | 
				
			||||||
 | 
					Inhibit:    Pull Data line down to inhibit keyboard to send.
 | 
				
			||||||
 | 
					Timing:     Host reads bit while Clock is hi.
 | 
				
			||||||
 | 
					Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					uint8_t ibm4704_recv(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t data = 0;
 | 
				
			||||||
 | 
					    bool parity = true;    // odd parity
 | 
				
			||||||
 | 
					    ibm4704_error = IBM4704_ERR_NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    idle();
 | 
				
			||||||
 | 
					    _delay_us(5);   // wait for line settles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* start bit */
 | 
				
			||||||
 | 
					    WAIT(clock_lo, 100, 0x11); // wait for keyboard to send
 | 
				
			||||||
 | 
					    WAIT(data_hi, 100, 0x12);  // can be delayed that long
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer
 | 
				
			||||||
 | 
					    /* data */
 | 
				
			||||||
 | 
					    for (uint8_t i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					        WAIT(clock_hi, 100, 0x20+i);
 | 
				
			||||||
 | 
					        //_delay_us(5);
 | 
				
			||||||
 | 
					        if (data_in()) {
 | 
				
			||||||
 | 
					            parity = !parity;
 | 
				
			||||||
 | 
					            data |= (1<<i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        WAIT(clock_lo, 150, 0x28+i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* parity */
 | 
				
			||||||
 | 
					    WAIT(clock_hi, 100, 0x17);
 | 
				
			||||||
 | 
					    if (data_in() != parity) {
 | 
				
			||||||
 | 
					        ibm4704_error = IBM4704_ERR_PARITY;
 | 
				
			||||||
 | 
					        goto ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    WAIT(clock_lo, 150, 0x18);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* stop bit */
 | 
				
			||||||
 | 
					    WAIT(clock_hi, 100, 0x19);
 | 
				
			||||||
 | 
					    WAIT(data_lo, 1, 0x19);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inhibit();
 | 
				
			||||||
 | 
					    _delay_us(200); // wait to recover clock to hi
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					ERROR:
 | 
				
			||||||
 | 
					    if (ibm4704_error > 0x12) {
 | 
				
			||||||
 | 
					        xprintf("x%02X ", ibm4704_error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    inhibit();
 | 
				
			||||||
 | 
					    _delay_us(200); // wait to recover clock to hi
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								protocol/ibm4704.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								protocol/ibm4704.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,110 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Jun WAKO <wakojun@gmail.com>
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#ifndef IBM4704_H
 | 
				
			||||||
 | 
					#define IBM4704_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IBM4704_ERR_NONE        0
 | 
				
			||||||
 | 
					#define IBM4704_ERR_PARITY      0x70
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ibm4704_init(void);
 | 
				
			||||||
 | 
					uint8_t ibm4704_send(uint8_t data);
 | 
				
			||||||
 | 
					uint8_t ibm4704_recv_response(void);
 | 
				
			||||||
 | 
					uint8_t ibm4704_recv(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Check pin configuration */
 | 
				
			||||||
 | 
					#if !(defined(IBM4704_CLOCK_PORT) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_CLOCK_PIN) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_CLOCK_DDR) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_CLOCK_BIT))
 | 
				
			||||||
 | 
					#   error "ibm4704 clock pin configuration is required in config.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !(defined(IBM4704_DATA_PORT) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_DATA_PIN) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_DATA_DDR) && \
 | 
				
			||||||
 | 
					      defined(IBM4704_DATA_BIT))
 | 
				
			||||||
 | 
					#   error "ibm4704 data pin configuration is required in config.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------
 | 
				
			||||||
 | 
					 * static functions
 | 
				
			||||||
 | 
					 *------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					static inline void clock_lo(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_PORT &= ~(1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_DDR  |=  (1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline void clock_hi(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* input with pull up */
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_DDR  &= ~(1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_PORT |=  (1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline bool clock_in(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_DDR  &= ~(1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					    IBM4704_CLOCK_PORT |=  (1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					    _delay_us(1);
 | 
				
			||||||
 | 
					    return IBM4704_CLOCK_PIN&(1<<IBM4704_CLOCK_BIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline void data_lo(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    IBM4704_DATA_PORT &= ~(1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					    IBM4704_DATA_DDR  |=  (1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline void data_hi(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* input with pull up */
 | 
				
			||||||
 | 
					    IBM4704_DATA_DDR  &= ~(1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					    IBM4704_DATA_PORT |=  (1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline bool data_in(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    IBM4704_DATA_DDR  &= ~(1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					    IBM4704_DATA_PORT |=  (1<<IBM4704_DATA_BIT);
 | 
				
			||||||
 | 
					    _delay_us(1);
 | 
				
			||||||
 | 
					    return IBM4704_DATA_PIN&(1<<IBM4704_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 
 | 
				
			||||||
 | 
					 * keyboard checks Data line on start bit(Data:hi) and it stops sending if Data line is low.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void inhibit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    clock_hi();
 | 
				
			||||||
 | 
					    data_lo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue