]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Keyboard: Palm serial keyboard USB converter (#4485)
authormilestogo <milestogo@users.noreply.github.com>
Fri, 7 Dec 2018 01:13:15 +0000 (17:13 -0800)
committerDrashna Jaelre <drashna@live.com>
Fri, 7 Dec 2018 01:13:15 +0000 (17:13 -0800)
* Initial palm_usb support

* removing left over sun .c file

* fixing licenses

* actually adding updated files

* fixing build error

* more include cleanup

keyboards/converter/palm_usb/config.h [new file with mode: 0644]
keyboards/converter/palm_usb/matrix.c [new file with mode: 0644]
keyboards/converter/palm_usb/readme.md [new file with mode: 0644]
keyboards/converter/palm_usb/rules.mk [new file with mode: 0644]
keyboards/converter/palm_usb/stowaway/keymaps/default/keymap.c [new file with mode: 0644]
keyboards/converter/palm_usb/stowaway/rules.mk [new file with mode: 0644]
keyboards/converter/palm_usb/stowaway/stowaway.h [new file with mode: 0644]

diff --git a/keyboards/converter/palm_usb/config.h b/keyboards/converter/palm_usb/config.h
new file mode 100644 (file)
index 0000000..4520725
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This code makes use of cy384's Arduino USB HID adapter for the Palm Portable
+ Keyboard, released under the BSD licence */
+
+
+
+
+#pragma once
+
+#define CUSTOM_MATRIX 2
+
+#define VENDOR_ID       0xFEED
+#define PRODUCT_ID      0x0001
+#define DEVICE_VER      0x0100
+#define MANUFACTURER    QMK
+#define PRODUCT         Stowaway converter
+#define DESCRIPTION     USB converter for Stowaway keyboard
+
+// IO pins to serial
+// https://deskthority.net/wiki/Arduino_Pro_Micro for pin lookup
+#define VCC_PIN D1 // pro micro 2 
+#define RX_PIN   D0 //pro micro 3 , was 8 on cy384
+#define RTS_PIN  C6 // 5  //[ was D4 // 4 on the cy384
+#define DCD_PIN  E6  //7 
+
+// if using the particular arduino pinout of CY384
+#ifdef CY384 
+    #define GND_PIN  D7 //6
+    #define PULLDOWN_PIN  B1 // 15
+#endif
+
+#ifndef HANDSPRING
+// Set to 1 for Handspring or to disable RTS/DCD based handshake. 
+    #define HANDSPRING 0
+#endif
+
+#define MAXDROP 10 // check if keyboard is connected every X polling cycles
+#define SLEEP_TIMEOUT 500000 // check keyboard/reset this many millis
+
+
+#define MATRIX_ROWS 12
+#define MATRIX_COLS 8
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+    keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) || \
+    keyboard_report->mods == (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) || \
+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+
+/* Serial(USART) configuration
+ *     asynchronous, negative logic, 9600baud, no flow control
+ *     1-start bit, 8-data bit, non parity, 1-stop bit
+ */
+#define SERIAL_SOFT_BAUD            9600
+#define SERIAL_SOFT_PARITY_NONE
+#define SERIAL_SOFT_BIT_ORDER_LSB
+#if (HANDSPRING == 0)
+    #define SERIAL_SOFT_LOGIC_NEGATIVE  //RS232 logic
+#endif 
+/* RXD Port */
+#define SERIAL_SOFT_RXD_ENABLE
+    
+// we are using Pro micro pin 3 / D0 as serial
+#define SERIAL_SOFT_RXD_DDR         DDRD
+#define SERIAL_SOFT_RXD_PORT        PORTD
+#define SERIAL_SOFT_RXD_PIN         PIND
+#define SERIAL_SOFT_RXD_BIT         0
+#define SERIAL_SOFT_RXD_VECT        INT0_vect
+
+/* RXD Interupt */
+#define SERIAL_SOFT_RXD_INIT()      do { \
+    /* pin configuration: input with pull-up */ \
+    SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
+    SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
+    /* enable interrupt: INT0(rising edge) */ \
+    EICRA |= ((1<<ISC01)|(1<<ISC00)); \
+    EIMSK |= (1<<INT0); \
+    sei(); \
+} while (0)
+#define SERIAL_SOFT_RXD_INT_ENTER()
+#define SERIAL_SOFT_RXD_INT_EXIT()  do { \
+    /* clear interrupt  flag */ \
+    EIFR = (1<<INTF0); \
+} while (0)
+#define SERIAL_SOFT_RXD_READ()      (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
+
+/* TXD Port */
+#define SERIAL_SOFT_TXD_ENABLE
+#define SERIAL_SOFT_TXD_DDR         DDRD
+#define SERIAL_SOFT_TXD_PORT        PORTD
+#define SERIAL_SOFT_TXD_PIN         PIND
+#define SERIAL_SOFT_TXD_BIT         3
+#define SERIAL_SOFT_TXD_HI()        do { SERIAL_SOFT_TXD_PORT |=  (1<<SERIAL_SOFT_TXD_BIT); } while (0)
+#define SERIAL_SOFT_TXD_LO()        do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
+#define SERIAL_SOFT_TXD_INIT()      do { \
+    /* pin configuration: output */ \
+    SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
+    /* idle */ \
+    SERIAL_SOFT_TXD_ON(); \
+} while (0)
+
+
diff --git a/keyboards/converter/palm_usb/matrix.c b/keyboards/converter/palm_usb/matrix.c
new file mode 100644 (file)
index 0000000..49212f2
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+Copyright 2018 milestogo 
+with elements Copyright 2014 cy384 under a modified BSD license
+building on qmk structure Copyright 2012 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include QMK_KEYBOARD_H
+#include "protocol/serial.h"
+#include "timer.h"
+#include "pincontrol.h"
+
+
+/*
+ * Matrix Array usage:
+ *
+ * ROW: 12(4bits)
+ * COL:  8(3bits)
+ *
+ *   +---------+
+ *  0|00 ... 07|
+ *  1|00 ... 07|
+ *  :|   ...   |
+ *  :|   ...   |
+ *  A|         |
+ *  B|         |
+ *   +---------+
+ */
+static uint8_t matrix[MATRIX_ROWS];
+
+
+// we're going to need a sleep timer
+static uint16_t last_activity ;
+// and a byte to track duplicate up events signalling all keys up. 
+static uint16_t last_upKey ;
+// serial device can disconnect. Check every MAXDROP characters. 
+static uint16_t disconnect_counter = 0;
+
+
+// bitmath masks. 
+#define KEY_MASK 0b10000000
+#define COL_MASK 0b00000111
+#define ROW_MASK 0b01111000
+
+
+#define ROW(code)    (( code & ROW_MASK ) >>3)
+#define COL(code)    ((code & COL_MASK) )
+#define KEYUP(code) ((code & KEY_MASK) >>7 )
+
+static bool is_modified = false;
+
+__attribute__ ((weak))
+void matrix_init_kb(void) {
+    matrix_init_user();
+}
+
+__attribute__ ((weak))
+void matrix_scan_kb(void) {
+    matrix_scan_user();
+}
+
+__attribute__ ((weak))
+void matrix_init_user(void) {
+}
+
+__attribute__ ((weak))
+void matrix_scan_user(void) {
+}
+
+inline
+uint8_t matrix_rows(void)
+{
+    return MATRIX_ROWS;
+}
+
+inline
+uint8_t matrix_cols(void)
+{
+    return MATRIX_COLS;
+}
+
+
+void pins_init(void) {
+ // set pins for pullups, Rts , power &etc. 
+
+    //print ("pins setup\n");
+    pinMode(VCC_PIN, PinDirectionOutput);
+    digitalWrite(VCC_PIN, PinLevelLow);
+
+#if ( HANDSPRING == 0)
+
+#ifdef CY835
+    pinMode(GND_PIN, PinDirectionOutput);
+    digitalWrite(GND_PIN, PinLevelLow);
+
+    pinMode(PULLDOWN_PIN, PinDirectionOutput);
+    digitalWrite(PULLDOWN_PIN, PinLevelLow);
+#endif
+
+    pinMode(DCD_PIN, PinDirectionInput);
+    pinMode(RTS_PIN, PinDirectionInput); 
+#endif
+
+/* check that the other side isn't powered up. 
+    test=digitalRead(DCD_PIN);
+    xprintf("b%02X:", test);
+    test=digitalRead(RTS_PIN);
+    xprintf("%02X\n", test);
+*/
+}
+
+uint8_t rts_reset(void) {
+    static uint8_t firstread ;
+/* bounce RTS so device knows it is rebooted */
+
+// On boot, we keep rts as input, then switch roles here
+// on leaving sleep, we toggle the same way
+
+    firstread=digitalRead(RTS_PIN);
+   // printf("r%02X:", firstread);
+
+    pinMode(RTS_PIN, PinDirectionOutput);
+
+    if (firstread == PinLevelHigh) {
+        digitalWrite(RTS_PIN, PinLevelLow);
+    } 
+     _delay_ms(10);
+    digitalWrite(RTS_PIN, PinLevelHigh);  
+    
+
+/* the future is Arm 
+    if (palReadPad(RTS_PIN_IOPRT) == PinLevelLow)
+  {
+    _delay_ms(10);
+    palSetPadMode(RTS_PINn_IOPORT, PinDirectionOutput_PUSHPULL);
+    palSetPad(RTS_PORT, RTS_PIN);
+  }
+  else
+  {
+    palSetPadMode(RTS_PIN_RTS_PORT, PinDirectionOutput_PUSHPULL);
+    palSetPad(RTS_PORT, RTS_PIN);
+    palClearPad(RTS_PORT, RTS_PIN);
+    _delay_ms(10);
+    palSetPad(RTS_PORT, RTS_PIN);
+  }
+*/
+
+
+ _delay_ms(5);  
+ //print("rts\n");
+ return 1;
+}
+
+uint8_t get_serial_byte(void) {
+    static uint8_t code;
+    while(1) {
+        code = serial_recv();
+        if (code) { 
+            debug_hex(code); debug(" ");
+            return code;
+        }
+    }
+}
+
+uint8_t palm_handshake(void) {
+    // assumes something has seen DCD go high, we've toggled RTS 
+    // and we now need to verify handshake. 
+    // listen for up to 4 packets before giving up. 
+    // usually I get the sequence FF FA FD
+    static uint8_t codeA=0;
+    for (uint8_t i=0; i < 5; i++) {
+        codeA=get_serial_byte();
+        if ( 0xFA == codeA) {
+            if( 0xFD == get_serial_byte()) {
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+uint8_t palm_reset(void) {
+    print("@");
+    rts_reset();  // shouldn't need to power cycle. 
+
+    if ( palm_handshake() ) {
+        last_activity = timer_read();
+        return 1;
+    } else { 
+        print("failed reset");
+        return 0;
+    }
+
+}
+
+uint8_t handspring_handshake(void) {
+    // should be sent 15 ms after power up. 
+    // listen for up to 4 packets before giving up. 
+    static uint8_t codeA=0;
+    for (uint8_t i=0; i < 5; i++) {
+        codeA=get_serial_byte();
+        if ( 0xF9 == codeA) {
+            if( 0xFB == get_serial_byte()) {
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+uint8_t handspring_reset(void) {
+    digitalWrite(VCC_PIN, PinLevelLow);
+    _delay_ms(5);
+    digitalWrite(VCC_PIN, PinLevelHigh);
+
+    if ( handspring_handshake() ) {
+        last_activity = timer_read();
+        disconnect_counter=0;
+        return 1;
+    } else { 
+        print("-HSreset");
+        return 0;   
+    }
+}
+
+void matrix_init(void)
+{
+    debug_enable = true;
+    //debug_matrix =true;
+    
+    serial_init(); // arguments all #defined 
+#if (HANDSPRING == 0)
+    pins_init(); // set all inputs and outputs. 
+#endif
+
+    print("power up\n");
+    digitalWrite(VCC_PIN, PinLevelHigh);
+
+    // wait for DCD strobe from keyboard - it will do this 
+    // up to 3 times, then the board needs the RTS toggled to try again
+  
+#if ( HANDSPRING == 1)
+    if ( handspring_handshake() ) {
+        last_activity = timer_read();
+    } else { 
+        print("failed handshake");
+        _delay_ms(1000);
+        //BUG /should/ power cycle or toggle RTS & reset, but this usually works. 
+    }
+
+#else  /// Palm / HP  device with DCD
+    while( digitalRead(DCD_PIN) != PinLevelHigh ) {;} 
+    print("dcd\n");
+
+    rts_reset(); // at this point the keyboard should think all is well. 
+
+    if ( palm_handshake() ) {
+        last_activity = timer_read();
+    } else { 
+        print("failed handshake");
+        _delay_ms(1000);
+        //BUG /should/ power cycle or toggle RTS & reset, but this usually works. 
+    }
+
+#endif
+
+    // initialize matrix state: all keys off
+    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+
+    matrix_init_quantum();
+    return;
+    
+    
+}
+
+
+uint8_t matrix_scan(void)
+{
+    uint8_t code;
+    code = serial_recv();
+    if (!code) {
+/*         
+        disconnect_counter ++;
+        if (disconnect_counter > MAXDROP) {
+            //  set all keys off
+             for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; 
+        }
+*/
+        // check if the keyboard is asleep. 
+        if (timer_elapsed(last_activity) > SLEEP_TIMEOUT) {
+#if(HANDSPRING ==0 )
+            palm_reset();
+#else
+            handspring_reset();
+#endif
+            return 0;
+        } 
+
+    }
+
+   last_activity = timer_read();
+   disconnect_counter=0; // if we are getting serial data, we're connected. 
+
+    debug_hex(code); debug(" ");
+
+
+    switch (code) {
+        case 0xFD:  // unexpected reset byte 2
+             print("rstD ");
+            return 0;
+        case 0xFA:  // unexpected reset
+            print("rstA ");
+            return 0;
+    }
+
+    if (KEYUP(code)) {
+        if (code == last_upKey) {
+            // all keys are not pressed. 
+            // Manual says to disable all modifiers left open now. 
+            // but that could defeat sticky keys. 
+            // BUG? dropping this byte. 
+            last_upKey=0;
+            return 0;
+        }
+        // release
+        if (matrix_is_on(ROW(code), COL(code))) {
+            matrix[ROW(code)] &= ~(1<<COL(code));
+            last_upKey=code;
+        }
+    } else {
+       // press
+        if (!matrix_is_on(ROW(code), COL(code))) {
+            matrix[ROW(code)] |= (1<<COL(code));
+
+        }
+    }
+
+    matrix_scan_quantum();
+    return code;
+}
+
+bool matrix_is_modified(void)
+{
+    return is_modified;
+}
+
+inline
+bool matrix_has_ghost(void)
+{
+    return false;
+}
+
+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++) {
+        phex(row); print(": ");
+        pbin_reverse(matrix_get_row(row));
+        print("\n");
+    }
+}
+
+uint8_t matrix_key_count(void)
+{
+    uint8_t count = 0;
+    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+        count += bitpop(matrix[i]);
+    }
+    return count;
+}
diff --git a/keyboards/converter/palm_usb/readme.md b/keyboards/converter/palm_usb/readme.md
new file mode 100644 (file)
index 0000000..17ba329
--- /dev/null
@@ -0,0 +1,96 @@
+# Stowaway Serial keyboard  to USB  protocol converter
+
+A converter for Palm Pilot era Stowaway serial keyboards. 
+
+Makes extensive use of the code from [cy384](https://github.com/cy384/ppk_usb). Ported to QMK by [milestogo](https://github.com/milestogo).
+
+Hardware Supported: See hardware section below  
+Hardware Availability: self-built
+
+Make example for this keyboard (after setting up your build environment):
+
+    make converter/palm_usb/stowaway:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+
+## Hardware
+
+Target MCU is ATMega32u4 but other USB capable AVRs should also work. 
+
+cy843 has a very specific way of wiring in order to fit all pins in sequence. It breaks
+qmk because  the Arduino softserial library uses different pins from QMK. 
+
+I've wired the pro micro  hardware as follows. 
+
+Label| TX0,RX1,GND,GND,2  ,3  ,4  ,5  ,6  ,7
+Palm |    ,   , * ,GND,VCC,RX ,NC ,RTS,nc ,DCD
+MCU  |                ,D1 ,D0 ,   ,C6 ,   ,E6
+
+\* The RX line from the keyboard should be conected to a ~10K ohm pull down resistor to ground.
+RX --|--3
+    10K
+     |
+    GND
+
+
+Power management is not implemented yet, this just reboots the keyboard frequently. 
+
+### Keyboards: 
+
+Think Outside Stowaway Keyboards
+There are at least 5 different versions of these keyboards out there. 
+
+Group 1: Palm 3, Palm 5 & HP Journada 540, and Compaq iPaq keyboards. These share
+the same RTS protocol, but with different pinouts for each device. 
+
+Group 2: Handspring keyboards. These don't do handshaking protocol, and use TTL signal. 
+Set HANDSPRING to 1 in config.h
+
+Group 3: IRDA models. Untested but theoretically serial.
+
+### Connectors
+
+See https://github.com/cy384/ppk_usb for wiring & sample 3d printable sockets.
+
+Only Palm3 wiring has been tested.  
+RXD pin is output from keyboard to MCU's RX. 
+
+Viewed from left to right with the keyboard in typing position. 
+
+Palm3: [NC, VCC, RXD, RTS, NC, NC, DCD, NC, NC, GND]
+Palm5: [NC, VCC, RXD, RTS, NC, NC, DCD, NC, NC, GND] (same order, different connector)
+Handspring: [VCC/TXD, NC, NC, NC, GND, NC, NC, RXD]
+Journada: [NC, NC, NC, GND, NC, RTS, NC, DTR/VCC, RXD, DCD, NC]   [GND-IN, VCC-IN]
+Ipaq:  [NC, NC, DTR/VCC, NC, NC, RTS, NC, RXD, DCD, GND, NC, NC]
+
+### Protocol
+
+    Signal: Asynchronous, Negative logic, 9600baud, No Flow control
+    Frame format: 1-Start bit, 8-Data bits, No-Parity, 1-Stop bit
+
+    AVR USART engine expects positive logic while stowaway keyboard signal is negative.
+    To use AVR UART engine you need external inverter in front of RX and TX pin.
+    Otherwise you can software serial routine to communicate the keyboard.
+
+This converter uses software method, you doesn't need any inverter part.
+
+
+Commands From System To Keyboard
+    none
+
+Commands From Keyboard To System
+
+    0xFA Reset/Ready Response(followed by 0xFD)
+     
+References
+
+* http://www.splorp.com/pdf/stowawayhwref.pdf
+
+### Todo
+- Test on anything but a palm 3 model keyboard. 
+- Change all of the soft serial to match the new Helix based code so that it is easier
+to switch pins. 
+- The driver should check for a keyboard that pressed the delete key then disconnected. 
+Check every MAXDROP scans that the keyboard is there, and if not, clear the matrix. 
+Not implemented yet, since matrix scan is so much faster than serial. 
diff --git a/keyboards/converter/palm_usb/rules.mk b/keyboards/converter/palm_usb/rules.mk
new file mode 100644 (file)
index 0000000..35ea399
--- /dev/null
@@ -0,0 +1,46 @@
+MCU = atmega32u4       # Teensy 2.0
+F_CPU = 16000000
+ARCH = AVR8
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+BOOTLOADER = caterina
+
+# Build Options
+#   change to "no" to disable the options, or define them in the Makefile in 
+#   the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = no        # Mouse keys(+4700)
+EXTRAKEY_ENABLE = no       # Audio control and System control(+450)
+CONSOLE_ENABLE = yes         # Console for debug(+400)
+COMMAND_ENABLE = yes         # Commands for debug and configuration
+NKRO_ENABLE = no           # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
+MIDI_ENABLE = no            # MIDI controls
+AUDIO_ENABLE = no           # Audio output on port C6
+UNICODE_ENABLE = no         # Unicode
+UNICODEMAP_ENABLE = no 
+BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE = no        # Enable WS2812 RGB underlight. 
+CUSTOM_MATRIX = yes
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend
+
+#HARDWARE_SERIAL = yes
+
+SRC += matrix.c
+
+ifdef HARDWARE_SERIAL
+       # untested with palm_usb
+        SRC += protocol/serial_uart.c
+        OPT_DEFS += -DHARDWARE_SERIAL
+else
+        SRC += protocol/serial_soft.c
+endif
+
+DEFAULT_FOLDER = converter/palm_usb/stowaway
+
diff --git a/keyboards/converter/palm_usb/stowaway/keymaps/default/keymap.c b/keyboards/converter/palm_usb/stowaway/keymaps/default/keymap.c
new file mode 100644 (file)
index 0000000..09b41f9
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+  Copyright 2018 milestogo
+
+  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 QMK_KEYBOARD_H
+
+enum layers {
+_QWERTY=0,
+_CDH,
+_FN
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+  /*
+      1,    2,    3,    4,    5,    6,    7,    8,    9,    0,   MINS, EQL, BACK,       APP0,
+    TAB,  Q,    W,    E,    R,    T,    Y,    U,    I,    O,   P,    LBRC,  RBRC, BSLS,  APP1,  
+    CAPS, A,    S,    D,    F,    G,    H,    J,    K,    L,   SCLN, QUOT,  ENT,         APP2,  
+    LSFT, Z,    X,    C,    V,    B,    N,    M,    COMM, DOT, SLSH, RSFT,  UP,          APP3, 
+    LCTL, FN,   LALT, CMD,  SPACE,SPACE,GRAVE,DONE, DEL, LEFT, DOWN, RIGHT     
+
+*/
+  [_QWERTY] = LAYOUT( /* Base */
+      KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,   KC_MINS, KC_EQL,  KC_BSPC,           KC_ESC,
+      KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,   KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,  TG(_CDH),  
+      KC_CAPS, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,   KC_SCLN, KC_QUOT, KC_ENT,            KC_PGUP,  
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,             KC_PGDN, 
+      KC_LCTL, MO(_FN),   KC_LALT, KC_LGUI, KC_SPACE,KC_SPACE,KC_GRAVE,KC_RGUI, KC_DEL,  KC_LEFT,KC_DOWN, KC_RIGHT  
+      ),
+
+  [_CDH] = LAYOUT( /* Base */
+      KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,   KC_MINS, KC_EQL,  KC_BSPC,           KC_ESC,
+      KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_B,    KC_J,    KC_L,    KC_U,    KC_Y,   KC_SCLN, KC_LBRC, KC_RBRC, KC_BSLS,  _______,  
+      KC_CAPS, KC_A,    KC_R,    KC_S,    KC_T,    KC_G,    KC_M,    KC_N,    KC_E,    KC_I,   KC_O,    KC_QUOT, KC_ENT,            KC_PGUP,  
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_D,    KC_V,    KC_K,    KC_H,    KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,             KC_PGDN, 
+      KC_LCTL, MO(_FN), KC_LALT, KC_LGUI, KC_SPACE,KC_SPACE,KC_GRAVE,KC_RGUI, KC_DEL,  KC_LEFT,KC_DOWN, KC_RIGHT  
+      ),
+
+  [_FN] = LAYOUT( // FN Key 
+      _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
+      _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+      _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
+      _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,    
+      _______, _______, _______, _______, KC_ENT,  _______, _______, _______, _______, _______, _______, _______     
+      ),
+
+};
diff --git a/keyboards/converter/palm_usb/stowaway/rules.mk b/keyboards/converter/palm_usb/stowaway/rules.mk
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/keyboards/converter/palm_usb/stowaway/stowaway.h b/keyboards/converter/palm_usb/stowaway/stowaway.h
new file mode 100644 (file)
index 0000000..71af9bf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+Copyright 2018 milestogo
+
+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/>.
+*/
+
+#pragma once
+
+#include "quantum.h"
+
+
+/* Stowaway Keyboard
+ based on matrix from http://www.splorp.com/pdf/stowawayhwref.pdf
+
+    1,    2,    3,    4,    5,    6,    7,    8,    9,    0,   MINS, EQL,   BACK         APP0,
+    TAB,  Q,    W,    E,    R,    T,    Y,    U,    I,    O,   P,    LBRC,  RBRC, BSLS,  APP1,  
+    CAPS, A,    S,    D,    F,    G,    H,    J,    K,    L,   SCLN, QUOT,  ENT,         APP2,  
+    LSFT, Z,    X,    C,    V,    B,    N,    M,    COMM, DOT, SLSH, RSFT,  UP,          APP3, 
+    LCTL, FN,   LALT, CMD,  SPACE,SPACE,GRAVE,DONE, DEL, LEFT, DOWN, RIGHT     
+
+*/
+#define LAYOUT(                                                         \
+    K000, K001, K002, K004, K005, K006, K007, K064, K065, K066, K060, K061, K062,       K063,\
+    K031, K011, K012, K013, K014, K015, K016, K074, K075, K076, K077, K070, K071, K072, K073,\
+    K030, K021, K022, K023, K024, K025, K026, K084, K085, K086, K087, K080, K081,       K082,\
+    K110, K003, K020, K054, K055, K056, K057, K094, K095, K096, K090, K111, K091,       K092,\
+    K032, K042, K043, K010, K027, K067, K017, K097, K100, K101, K102, K103 \
+) { \
+    { K000,  K001,   K002 , K003, K004,  K005, K006,  K007 }, \
+    { K010,  K011,   K012 , K013, K014,  K015, K016,  K017 }, \
+    { K020,  K021,   K022 , K023, K024,  K025, K026,  K027 }, \
+    { K030,  K031,   K032 , KC_NO,KC_NO, KC_NO,KC_NO, KC_NO }, \
+    { KC_NO, KC_NO,  K042 , K043, KC_NO, KC_NO,KC_NO, KC_NO }, \
+    { KC_NO, KC_NO,  KC_NO, KC_NO,K054,  K055, K056,  K057 }, \
+    { K060,  K061,   K062 , K063, K064,  K065, K066,  K067 }, \
+    { K070,  K071,   K072 , K073, K074,  K075, K076,  K077 }, \
+    { K080,  K081,   K082 , KC_NO,K084,  K085, K086,  K087 }, \
+    { K090,  K091,   K092 , KC_NO,K094,  K095, K096,  K097 }, \
+    { K100,  K101,   K102 , K103, KC_NO, KC_NO,KC_NO, KC_NO }, \
+    { K110,  K111,   KC_NO, KC_NO,KC_NO, KC_NO,KC_NO, KC_NO } \
+}
+