How to build your very own keyboard firmware

User avatar
Halvar

20 Jan 2016, 09:49

Hi wes1099,

as for the diodes, a switch and a diode together (serialized) always connect a certain row with a certain column. It doesn't matter if the diode is between row and switch or between column and switch, you can do it both ways. The important thing is that the diodes point in the right direction which should be ring towards rows for the lightpad if I'm not mistaken.

The best way to test all of your questions is to load the teensy with the firmware before you solder it into the keyboard, connect it to the computer running aquatest or an editor, let it run the firmware, and connect one column pin with one row pin at a time with blank wire or a diode. Then look if the computer registers a key code and compare with what you expect. Do this with several pairs of rows and columns and you know how your circuits have to look. You can also test diode orientation this way. It's more fun than it sounds.

It's also a good idea to read the source code. The pin assignment is in matrix.c for example.

wes1099

20 Jan 2016, 15:01

Halvar wrote:Hi wes1099,

as for the diodes, a switch and a diode together (serialized) always connect a certain row with a certain column. It doesn't matter if the diode is between row and switch or between column and switch, you can do it both ways. The important thing is that the diodes point in the right direction which should be ring towards rows for the lightpad if I'm not mistaken.

The best way to test all of your questions is to load the teensy with the firmware before you solder it into the keyboard, connect it to the computer running aquatest or an editor, let it run the firmware, and connect one column pin with one row pin at a time with blank wire or a diode. Then look if the computer registers a key code and compare with what you expect. Do this with several pairs of rows and columns and you know how your circuits have to look. You can also test diode orientation this way. It's more fun than it sounds.

It's also a good idea to read the source code. The pin assignment is in matrix.c for example.
OK, thanks. I read the matrix.c file but none of the other ones. I will do more reading and figuring things out this afternoon.

metalhed73

22 Jan 2016, 21:06

Hello all, thank you for this post as it has gotten me close to running, but I have an error during compile that I need some help with. Below are the files I have modified for my build, I am running a 12c x 10r matrix to run a full tenkey with some added keys with a teensy 2.0

Make file

Code: Select all

# Target file name (without extension).
TARGET = gh60_lufa

# Directory common source filess exist
TMK_DIR = ../../tmk_core

# Directory keyboard dependent files exist
TARGET_DIR = .

# project specific files
SRC =	keymap_common.c \
	matrix.c \
	led.c

ifdef KEYMAP
    SRC := keymap_$(KEYMAP).c $(SRC)
else
    SRC := keymap_poker.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
#SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA


# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax

# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)

include $(TMK_DIR)/protocol/lufa.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk
Keymap_poker.c

Code: Select all

#include "keymap_common.h"

static uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
	/* 0: qwerty */
	KEYMAP(ESC,    ,     ,     ,     ,     ,      , HOME, PGUP,   P4, RCTL, , \
		   GRV,  F1,   F2,   F3,   F4,   F5,      ,  INS, PGDN,   P1,  APP, , \
		   TAB,   1,    2,    3,    4,   F6,      , BSPC,  END,   P0, RGUI, , \
		   FN0,   Q,    W,    E,    5,   F7,      ,  EQL,  DEL, RGHT, PMNS, , \
		   LSFT,  A,    S,    R,    6,   F8,  MUTE, LBRC, BSLS, DOWN, PAST,   P9, \
		   LCTL,  Z,    D,    T,    7,   F9,  VOLD,    P, RBRC,   UP, PSLS, PPLS, \
		   LGUI,  X,    F,    Y,    8,  F10,  VOLU,    L, QUOT, LEFT,   P7,   P6, \
		   LALT,  C,    G,    U,    9,  F11,  SLCK,    K, SCLN,  ENT,   P8,   P3, \
		   SPC,   V,    H,    I,    0,  F12,   BRK,    M,  DOT, RSFT,   P5, PENT, \
		   RALT,  B,    J,    O, MINS, PSCR,  NLCK,    N, COMM, SLSH,   P2, PDOT), 
};
keymap_common.h

Code: Select all

#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 "host.h"
#include "print.h"
#include "debug.h"
#include "keymap.h"


extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* GH60 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, \
    K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, \
    K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, \
	K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5A, K5B, \
	K60, K61, K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, \
	K70, K71, K72, K73, K74, K75, K76, K77, K78, K79, K7A, K7B, \
	K80, K81, K82, K83, K84, K85, K86, K87, K88, K89, K8A, K8B, \
	K90, K91, K92, K93, K94, K95, K96, K97, K98, K99, K9A, K9B \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_NO }, \
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_NO }, \
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_NO }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_NO }, \
    { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47, KC_##K48, KC_##K49, KC_##K4A, KC_##K4B }, \
	{ KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57, KC_##K58, KC_##K59, KC_##K5A, KC_##K5B }, \
	{ KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67, KC_##K68, KC_##K69, KC_##K6A, KC_##K6B }, \
	{ KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77, KC_##K78, KC_##K79, KC_##K7A, KC_##K7B }, \
	{ KC_##K80, KC_##K81, KC_##K82, KC_##K83, KC_##K84, KC_##K85, KC_##K86, KC_##K87, KC_##K88, KC_##K89, KC_##K8A, KC_##K8B }, \
	{ KC_##K90, KC_##K91, KC_##K92, KC_##K93, KC_##K94, KC_##K95, KC_##K96, KC_##K97, KC_##K98, KC_##K99, KC_##K9A, KC_##K9B } \
}


#endif
matrix.c

Code: Select all

static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)

    DDRC  &= ~(1<<7 | 1<<6);
    PORTC |=  (1<<7 | 1<<6);
    DDRD  &= ~(1<<5 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
    PORTD |=  (1<<5 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
    DDRC  &= ~(1<<7 | 1<<6);
    PORTC |=  (1<<7 | 1<<6);
    DDRB  &= ~(1<<7 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
    PORTB |=  (1<<7 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
}

static matrix_row_t read_cols(void)
{
    return (PINC&(1<<7) ? 0 : (1<<10)) |
           (PINC&(1<<6) ? 0 : (1<<9)) |
           (PIND&(1<<3) ? 0 : (1<<8)) |
           (PIND&(1<<2) ? 0 : (1<<7)) |
           (PIND&(1<<1) ? 0 : (1<<6)) |
           (PIND&(1<<0) ? 0 : (1<<5)) |
           (PINB&(1<<7) ? 0 : (1<<4)) |
           (PINB&(1<<3) ? 0 : (1<<3)) |
           (PINB&(1<<2) ? 0 : (1<<2)) |     // Rev.A and B
           (PINB&(1<<1) ? 0 : (1<<1)) |
           (PINB&(1<<0) ? 0 : (1<<0)) |
           (PIND&(1<<5) ? 0 : (1<<11));
           
}

/* Row pin configuration
 * row: 0   1   2   3   4   5   6   7   8   9
 * pin: F0  F1  F4  F5  F6  F7  B6  B5  B4  D7
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRF  &= ~0b11110011;
    PORTF &= ~0b11110011;
	DDRB  &= ~0b01110000;
	PORTB &= ~0b01110000;
	DDRD  &= ~0b10000000;
	PORTd &= ~0b10000000;
}

static void select_row(uint8_t row)
{
    // Output low(DDR:1, PORT:0) to select
    switch (row) {
        case 0:
            DDRF  |= (1<<0);
            PORTF &= ~(1<<0);
            break;
        case 1:
            DDRF  |= (1<<1);
            PORTF &= ~(1<<1);
            break;
        case 2:
            DDRF  |= (1<<4);
            PORTF &= ~(1<<4);
            break;
        case 3:
            DDRF  |= (1<<5);
            PORTF &= ~(1<<5);
            break;
        case 4:
            DDRF  |= (1<<6);
            PORTF &= ~(1<<6);
            break;
		case 5:
			DDRF  |= (1<<7)
			PORTF &= ~(1<<7)
			break;
		case 6:
			DDRB  |= (1<<6)
			PORTB &= ~(1<<6)
			break;
		case 7
			DDRB  |= (1<<5)
			PORTB &= ~(1<<5)
			break;
		case 8
			DDRB  |= (1<<4)
			PORTB &= ~(1<<4)
			break;
		case 9
			DDRD  |= (1<<7)
			PORTD &= ~(1<<7)
			break;
			
			
    }
}

I am pretty new at this and may have gotten in a little over my head but I think I am close here the error I am getting is attached

Any help would be greatly appreciated
Attachments
error.png
error.png (75.04 KiB) Viewed 2529 times

User avatar
Laser
emacs -nw

22 Jan 2016, 21:50

The error states clearly, you need to have 120 arguments in your KEYMAP, but have only 116.
Perhaps use KC_NO instead of empty arguments? I'm not clear what do you actually want to have there, but I don't think empty arguments (two commas one after another as empty argument) will work.
Last edited by Laser on 22 Jan 2016, 22:06, edited 3 times in total.

metalhed73

22 Jan 2016, 22:03

Forgive the fact that I am new to programming, I see the issue with the arguments my question is where is my coding error that needs to be corrected to get that taken care of?

thank you for your help with this

User avatar
Laser
emacs -nw

23 Jan 2016, 00:21

See my edited answer above.

metalhed73

23 Jan 2016, 04:16

thanks laser I will change those arguments and see how it goes,

User avatar
Ray

23 Jan 2016, 09:31

I think I found the mistake:
In your keymaps[][MATRIX_ROWS][MATRIX_COLS], remove the last comma in the first four rows.

And for the empty arguments, make them "NO" instead of empty space. (If there is no switch on that matix-crosspoint, the TMK way to do it would be to change the KEYMAP macro to do it; but you can change that also later, once it compiles with "NO" in the keymaps array.)

I am not sure about the following: maybe your MATRIX_ROWS and MATRIX_COLS are not set to your correct values.

metalhed73

26 Jan 2016, 02:04

thank you all for the help, got it figured out.....now much wiring ahead

battletux

02 Feb 2016, 09:22

Hi, this thread has been invaluble in getting my rev C GH60 up and running (odd that considering that you'd think gh would be the place for that...).

I do have a fews questions I hope that you guys could help out with. Firstly I'm using a standard poker layout and the default poker mapping from TMK_Keyboard which is awesome, however having come from a KBC pure I do miss the 'fn0 + LShift' macro for sending ctl + alt + del. Is there a way to mimic this in the standard poker layout, ideally with a simple edit to the poker keymap file and not having to resort to starting from scratch with a new layout (the online layout tools are confusing).

2ndly is there a way to get the LEDs to work (I know the board is not back light, I'm talking about the wasd, fn, esc, lights etc?) The only light that works is caps and I have soldered in all the resistor s and LEDs for the dozen or so keys that have lights by default and it would be nice to get them all to work.

Thanks.

User avatar
HzFaq

02 Feb 2016, 10:42

You could assign the macro to a FN key and stick that on the shift key on layer 1 (looking at the default poker keymap it does something similar with ctrl+shift+esc). Stick FN9 on the shift key on layer 1 and add this to the FN key action parameters at the bottom of the keymap file.

[9] = ACTION_MODS_KEY(MOD_RCTL|MOD_RALT, KC_DEL),

No idea about the LEDs, I don't think I even installed any on either of my GH60s.

User avatar
flabbergast

02 Feb 2016, 12:13

About the LEDs: TMK has built-in functionality for the standard three LEDs (caps, num, scroll locks); you'll need to edit the 'led.c' file and add stuff to the led_set function (you'll need to find out to which pins are the respective LEDs routed (one pin for esc, one pin for fn, one pin for wasd)); similarly as what's already there for caps lock.
(Also note that num and scroll locks don't work on OS X, because OS X doesn't ever send a signal to the keyboard to turn these on.)

Another option is to use some as 'backlight' - again this will require taking a look at other TMK examples that have backlight (e.g. kmac, lightpad, lightsaber, nerd) and adapting the code to gh60.

Finally, you can use the LEDs to indicate the current layer. This also requires editing some files. I wrote about this here (and a small follow-up here).

User avatar
tentator

04 Feb 2016, 22:49

I think also the number of available pins on the teensy for all those leds will be an issue.. how is the matrix looking like? 15x5? that would use up 20 pins of the teensy, so there would be only 5 left (the teensy 2.0 has max 25 pins usable, one of them, PD6, is also already wired to the internal led and if you want to use it for yourself you should unsolder it).
So 4 are left: maybe one for num, caps and scroll lock and one could drive other background illumination?

EDIT: clarified better...
Last edited by tentator on 08 Feb 2016, 10:31, edited 1 time in total.

CosmicFists

07 Feb 2016, 19:58

Hello everyone, i came into an issue when i tried to flash the code to the teensy (I have the teensy++) when i flashed the software, the keyboard inputs "279" then for some strange reason the computer acts as if the "CONTROL" key is being pressed. Even when the keyboard is unplugged. I really hope i didnt fry my teensy, or anything else. :( Can someone please review my code to see if i messed up anywhere :( I have been working at this for about 4 hours...

The Matrix

Code: Select all

/*
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/>.
*/

/*
 * scan matrix
 */
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"


#ifndef DEBOUNCE
#   define DEBOUNCE	5
#endif
static uint8_t debouncing = DEBOUNCE;

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

void matrix_init(void)
{
    // initialize row and col
    unselect_rows();
    init_cols();

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        matrix[i] = 0;
        matrix_debouncing[i] = 0;
    }
}

uint8_t matrix_scan(void)
{
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        select_row(i);
        _delay_us(30);  // without this wait read unstable value.
        matrix_row_t cols = read_cols();
        if (matrix_debouncing[i] != cols) {
            matrix_debouncing[i] = cols;
            if (debouncing) {
                debug("bounce!: "); debug_hex(debouncing); debug("\n");
            }
            debouncing = DEBOUNCE;
        }
        unselect_rows();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }
    }

    return 1;
}

bool matrix_is_modified(void)
{
    if (debouncing) return false;
    return true;
}

inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
    return (matrix[row] & ((matrix_row_t)1<<col));
}

inline
matrix_row_t matrix_get_row(uint8_t row)
{
    return matrix[row];
}

void matrix_print(void)
{
    print("\nr/c 0123456789ABCDEF\n");
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
        phex(row); print(": ");
        pbin_reverse16(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 += bitpop16(matrix[i]);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3   4   5   6   7   8   9   10  11  12  13
 * pin: F0  F1  E6  C7  C6  B6  D4  B1  B0  B5  B4  D7  D6  B3  (Rev.A)
 * pin:                                 B7                      (Rev.B)
 */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
	DDRF &= ~(1 << 7);
	PORTF |= (1 << 7);
	DDRE &= ~(1 << 0 | 1 << 1);
	PORTE |= (1 << 0 | 1 << 1);
	DDRD &= ~(1 << 7 | 1 << 5 | 1 << 4);
	PORTD |= (1 << 7 | 1 << 5 | 1 << 4);
	DDRC &= ~(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 1 | 1 << 0);
	PORTC |= (1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 1 | 1 << 0);
}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINE&(1<<6) ? 0 : (1<<2)) |
           (PINC&(1<<7) ? 0 : (1<<3)) |
           (PINC&(1<<6) ? 0 : (1<<4)) |
           (PINB&(1<<6) ? 0 : (1<<5)) |
           (PIND&(1<<4) ? 0 : (1<<6)) |
           (PINB&(1<<1) ? 0 : (1<<7)) |
           ((PINB&(1<<0) && PINB&(1<<7)) ? 0 : (1<<8)) |     // Rev.A and B
           (PINB&(1<<5) ? 0 : (1<<9)) |
           (PINB&(1<<4) ? 0 : (1<<10)) |
           (PIND&(1<<7) ? 0 : (1<<11)) |
           (PIND&(1<<6) ? 0 : (1<<12)) |
           (PINB&(1<<3) ? 0 : (1<<13));
}

/* Row pin configuration
 * row: 0   1   2   3   4
 * pin: D0  D1  D2  D3  D5
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRD  &= ~0b00101111;
    PORTD &= ~0b00101111;
}

static void select_row(uint8_t row)
{
	// Output low(DDR:1, PORT:0) to select
	switch (row) {
	case 0:
		DDRB |= (1 << 0);
		PORTB &= ~(1 << 0);
		break;
	case 1:
		DDRB |= (1 << 1);
		PORTB &= ~(1 << 1);
		break;
	case 2:
		DDRB |= (1 << 2);
		PORTB &= ~(1 << 2);
		break;
	case 3:
		DDRB |= (1 << 3);
		PORTB &= ~(1 << 3);
		break;
	case 4:
		DDRB |= (1 << 5);
		PORTB &= ~(1 << 5);
		break;
	}
}
Keymap_poker

Code: Select all

#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: qwerty */
    KEYMAP_ANSI(
        END, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, 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,     ENT,  \
        LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT, \
        LCTL,LGUI,LALT,          SPC,                     FN0, RGUI,APP, RCTL),
		
	/* 4: Poker Fn'd */
    KEYMAP_ANSI(
        ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, TRNS, \
        TRNS,FN6, UP,  TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,CALC,TRNS,HOME,INS, TRNS, \
        TRNS,LEFT,DOWN,RGHT,TRNS,TRNS,PSCR,SLCK,PAUS,TRNS,FN8, END,      TRNS, \
        TRNS,DEL, TRNS,WHOM,MUTE,VOLU,VOLD,TRNS,PGUP,PGDN,DEL,           TRNS, \
        TRNS,TRNS,TRNS,          FN5,                     FN4, TRNS,TRNS,TRNS),
};

const uint16_t PROGMEM fn_actions[] = {
  [0] = ACTION_LAYER_MOMENTARY(1),
};
Keymap.h

Code: Select all

/*
Copyright 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 "host.h"
#include "print.h"
#include "debug.h"
#include "keymap.h"


extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* GH60 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, \
    K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
    K40, K41, K42,           K45,                K49, K4A, K4B, K4C, K4D  \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D }, \
    { 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_##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_##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_##K40, KC_##K41, KC_##K42, KC_NO,    KC_NO,    KC_##K45, KC_NO,    KC_NO,    KC_NO,    KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D }  \
}

/* ANSI valiant. No extra keys for ISO */
#define KEYMAP_ANSI( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \
    K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B,           K3D, \
    K40, K41, K42,           K45,                     K4A, K4B, K4C, K4D  \
) KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO,  K2D, \
    K30, NO,  K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, NO,  K3D, \
    K40, K41, K42,           K45,                NO,  K4A, K4B, K4C, K4D  \
)


#define KEYMAP_HHKB( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K49,\
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \
    K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B,      K3D, K3C, \
    K40, K41, K42,           K45,                     K4A, K4B, K4C, K4D  \
) KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO,  K2D, \
    K30, NO,  K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
    K40, K41, K42,           K45,                K49, K4A, K4B, K4C, K4D  \
)

#endif
Makefile

Code: Select all

#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
#                Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
#               (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
#            have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
#             have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
#               (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
#                (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging, 
#              with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#                   bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------

# Target file name (without extension).
TARGET = gh60_lufa

# Directory common source filess exist
TMK_DIR = ../../tmk_core

# Directory keyboard dependent files exist
TARGET_DIR = .

# project specific files
SRC =	keymap_common.c \
	matrix.c \
	led.c

ifdef KEYMAP
    SRC := keymap_$(KEYMAP).c $(SRC)
else
    SRC := keymap_poker.c $(SRC)
endif

CONFIG_H = config.h


# MCU name
#MCU = at90usb1287
MCU = at90usb1287

# 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
#SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA


# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax

# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)

include $(TMK_DIR)/protocol/lufa.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk
http://imgur.com/a/AoFrT what the keyboard actually look like.

EDIT: added photos

User avatar
tentator

08 Feb 2016, 10:28

you do not seem to have changed anything from the original g60/poker, right? maybe you can point out what were your changes.. I didn't spot anything suspicious..
Maybe try to comment out in the makefile the following three options:
#BOOTMAGIC_ENABLE = yes
#MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
#EXTRAKEY_ENABLE = yes
Also not sure about the teensy++ if that will run out of the box, since I only tried it with teensy2.0 so far..
Otherwise no wanting messages during compilation?

mastermachetier

12 Feb 2016, 00:39

This is not a custom board , but I was hoping you guys could help me figure out why I cannot compile this keymap.
everything compiles fine with standard keymap or if i comment out the second layer.

I am using the default layout still i wrote a layout yesterday but I can't figure out why. I am not a c programmer btw.




keymap_raf.c

Code: Select all

#include "keymap_common.h"


const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* M0116 Apple Standard Keyboard ANSI
    *                     +-------+
    *                     | power |
    *                     +-------+
    * +---+---+---+---+---+---+---+---+---+---+---+---+---+-----+ +---+---+---+---+
    * |esc| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | bks | |clr| = | / | * |
    * +---------------------------------------------------------+ +---+---+---+---+
    * | tab | q | w | e | r | t | y | u | i | o | p | [ | ] |   | | 7 | 8 | 9 | + |
    * +-----------------------------------------------------+   | +---+---+---+---+
    * | ctrl | a | s | d | f | g | h | j | k | l | ; | ' |return| | 4 | 5 | 6 | - |
    * +---------------------------------------------------------+ +---+---+---+---+
    * | shift  | z | x | c | v | b | n | m | , | . | / |  shift | | 1 | 2 | 3 |   |
    * +---------------------------------------------------------+ +-------+---|ent|
    * |fn0|opt|comnd| ` |                   | \ |lef|rig|dwn|up | |   0   | . |   |
    * +---------------------------------------------------------+ +-------+---+---+
    */
  KEYMAP_M0116_ANSI( \
                                     POWER,                                                          \
       ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,   NLCK,EQL, PSLS,PAST, \
       TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,        P7,  P8,  P9,  PMNS, \
       LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,    P4,  P5,  P6,  PPLS, \
       LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT,   P1,  P2,  P3,        \
       FN0, LALT,LGUI,GRV,           SPC,      BSLS,LEFT,RGHT,DOWN,UP,          P0,       PDOT,PENT),

    /* M0116 Apple Standard Keyboard ANSI
    *                     +-------+
    *                     | power |
    *                     +-------+
    * +---+---+---+---+---+---+---+---+---+---+---+---+---+-----+ +----+----+--+-+---+
    * |esc| F1| F2| F3| F4| F5| F6| F7| F8| F9| F0| - | = | del | |    |    |    |   |
    * +---------------------------------------------------------+ +----+----+----+---+
    * | tab | q | w | e | r | t | y | u | i | o | p | [ | ] |   | |    |    |    | + |
    * +-----------------------------------------------------+   | +----+----+----+---+
    * | bks  | a | s | d | f | g | h | j | k | l | ; | ' |return| |    | UP |    | - |
    * +---------------------------------------------------------+ +----+----+----+---+
    * | shift  | z | x | c | v | b | n | m | , | . | / |  shift | |Left|DOWN|RGHT|   |
    * +---------------------------------------------------------+ +---------+----|ent|
    * |   |opt|comnd| clr|                  | \ |lef|rig|dwn|up | |  DEL    |bks |   |
    * +---------------------------------------------------------+ +---------+----+---+
    */
  KEYMAP_M0116_ANSI( \
                                     TRNS,                                                            \
       TRNS,F1,  F2,  F3,  F4,  F5,  f6,  F7,  F8,  F9,  F0,  TRNS,TRNS, DEL,    NO  ,NO  ,NO  ,NO  , \
       TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,         NO  ,NO  ,NO  ,TRNS, \
       BSPC,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,     TRNS,    NO  ,UP  ,NO  ,TRNS, \
       TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,          TRNS,    LEFT,DOWN,RGHT,      \
       NO,  TRNS,TRNS,LCTL,          TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,         DEL ,     BSPC,TRNS),

};

const uint16_t PROGMEM fn_actions[] = {
  [0] = ACTION_LAYER_MOMENTARY(1),             
};     

error

Code: Select all

make -f Makefile.teensy KEYMAP=raf                                                     
sh: dfu-programmer: command not found
sh: dfu-programmer: command not found

-------- begin --------
avr-gcc (GCC) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


mkdir -p obj_adb_usb_lufa
Compiling C: keymap_raf.c
avr-gcc -c -mmcu=at90usb1286  -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=2048 -DADB_MOUSE_MAXACC=8 -DF_USB=16000000UL -DARCH=ARCH_AVR8 -DUSB_DEVICE_ONLY -DUSE_FLASH_DESCRIPTORS -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -DFIXED_CONTROL_ENDPOINT_SIZE=8  -DFIXED_NUM_CONFIGURATIONS=1 -DPROTOCOL_LUFA -DBOOTMAGIC_ENABLE -DMOUSEKEY_ENABLE -DMOUSE_ENABLE -DEXTRAKEY_ENABLE -DCONSOLE_ENABLE -DCOMMAND_ENABLE -DNKRO_ENABLE -DVERSION=5c89d73-dirty -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fdata-sections -fno-inline-small-functions -fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Wstrict-prototypes -Wa,-adhlns=obj_adb_usb_lufa/keymap_raf.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/protocol -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_adb_usb_lufa_keymap_raf.o.d  keymap_raf.c -o obj_adb_usb_lufa/keymap_raf.o
In file included from keymap_raf.c:1:0:
keymap_common.h:149:65: error: 'KC_f6' undeclared here (not in a function)
   { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
                                                                 ^
keymap_raf.c:47:3: note: in expansion of macro 'KEYMAP_M0116_ANSI'
   KEYMAP_M0116_ANSI( \
   ^
keymap_common.h:150:55: error: 'KC_F0' undeclared here (not in a function)
   { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \
                                                       ^
keymap_raf.c:47:3: note: in expansion of macro 'KEYMAP_M0116_ANSI'
   KEYMAP_M0116_ANSI( \
   ^
make: *** [obj_adb_usb_lufa/keymap_raf.o] Error 1
keymap_common.h

Code: Select all

/*
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"


extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* M0115 Apple Extended Keyboard ANSI
 * ,---.   ,---------------. ,---------------. ,---------------. ,-----------.             ,---.
 * |Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|             |Pwr|
 * `---'   `---------------' `---------------' `---------------' `-----------'             `---'
 * ,-----------------------------------------------------------. ,-----------. ,---------------.
 * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa| |Ins|Hom|PgU| |NmL|  =|  /|  *|
 * |-----------------------------------------------------------| |-----------| |---------------|
 * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|    \| |Del|End|PgD| |  7|  8|  9|  -|
 * |-----------------------------------------------------------| `-----------' |---------------|
 * |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return  |               |  4|  5|  6|  +|
 * |-----------------------------------------------------------|     ,---.     |---------------|
 * |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |     |Up |     |  1|  2|  3|   |
 * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
 * |Ctrl |Opt |Cmd |         Space           |     |Opt |Ctrl  | |Lef|Dow|Rig| |      0|  .|   |
 * `-----------------------------------------------------------' `-----------' `---------------'
 */
#define KEYMAP_EXT_ANSI( \
    K35,  K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71,              K7F, \
    K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K72,K73,K74,  K47,K51,K4B,K43, \
    K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K2A, K75,K77,K79,  K59,K5B,K5C,K4E, \
    K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27,    K24,               K56,K57,K58,K45, \
    K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C,        K7B,     K3E,      K53,K54,K55,     \
    K36,K3A,K37,        K31,                        K7C,K7D, K3B,K3D,K3C,  K52,    K41,K4C  \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
    { KC_##K08, KC_##K09, KC_NUBS,  KC_##K0B, 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_##K1E, 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_##K2E, KC_##K2F }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_PENT,  KC_##K35, KC_##K36, KC_##K37 }, \
    { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO    }, \
    { KC_F17,   KC_##K41, KC_NO,    KC_##K43, KC_F18,   KC_##K45, KC_NO,    KC_##K47 }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_##K4B, KC_##K4C, KC_NO,    KC_##K4E, KC_F18   }, \
    { KC_F19,   KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
    { KC_##K58, KC_##K59, KC_F20,   KC_##K5B, KC_##K5C, KC_INT3,  KC_INT1,  KC_PCMM  }, \
    { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_LANG2, KC_##K67 }, \
    { KC_LANG1, KC_##K69, KC_F16,   KC_##K6B, KC_NO,    KC_##K6D, KC_APP,   KC_##K6F }, \
    { KC_NO,    KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
    { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_NO,    KC_##K7F }  \
}

/* M0115 Apple Extended Keyboard ISO
 * ,---.   ,---------------. ,---------------. ,---------------. ,-----------.             ,---.
 * |Esc|   |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|             |Pwr|
 * `---'   `---------------' `---------------' `---------------' `-----------'             `---'
 * ,-----------------------------------------------------------. ,-----------. ,---------------.
 * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backspa| |Ins|Hom|PgU| |NmL|  =|  /|  *|
 * |-----------------------------------------------------------| |-----------| |---------------|
 * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|Retur| |Del|End|PgD| |  7|  8|  9|  -|
 * |------------------------------------------------------`    | `-----------' |---------------|
 * |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|    |               |  4|  5|  6|  +|
 * |-----------------------------------------------------------|     ,---.     |---------------|
 * |Shif|  \|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shift     |     |Up |     |  1|  2|  3|   |
 * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
 * |Ctrl |Opt |Cmd |         Space           |     |Opt |Ctrl  | |Lef|Dow|Rig| |      0|  .|   |
 * `-----------------------------------------------------------' `-----------' `---------------'
 */
#define KEYMAP_EXT_ISO( \
    K35,  K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71,              K7F, \
    K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K72,K73,K74,  K47,K51,K4B,K43, \
    K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K24, K75,K77,K79,  K59,K5B,K5C,K4E, \
    K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27,K2A,                   K56,K57,K58,K45, \
    K38,K0A,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C,    K7B,     K3E,      K53,K54,K55,     \
    K36,K3A,K37,        K31,                        K7C,K7D, K3B,K3D,K3C,  K52,    K41,K4C  \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
    { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##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_##K1E, 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_##K2E, KC_##K2F }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_PENT,  KC_##K35, KC_##K36, KC_##K37 }, \
    { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO    }, \
    { KC_F17,   KC_##K41, KC_NO,    KC_##K43, KC_F18,   KC_##K45, KC_NO,    KC_##K47 }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_##K4B, KC_##K4C, KC_NO,    KC_##K4E, KC_F18   }, \
    { KC_F19,   KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
    { KC_##K58, KC_##K59, KC_F20,   KC_##K5B, KC_##K5C, KC_INT3,  KC_INT1,  KC_PCMM  }, \
    { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_LANG2, KC_##K67 }, \
    { KC_LANG1, KC_##K69, KC_F16,   KC_##K6B, KC_NO,    KC_##K6D, KC_APP,   KC_##K6F }, \
    { KC_NO,    KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
    { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_NO,    KC_##K7F }  \
}




/* M0116 Apple Standard Keyboard ANSI
*                     +-------+
*                     | power |
*                     +-------+
* +---+---+---+---+---+---+---+---+---+---+---+---+---+-----+ +---+---+---+---+
* |esc| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | bks | |clr| = | / | * |
* +---------------------------------------------------------+ +---+---+---+---+
* | tab | q | w | e | r | t | y | u | i | o | p | [ | ] |   | | 7 | 8 | 9 | + |
* +-----------------------------------------------------+   | +---+---+---+---+
* | ctrl | a | s | d | f | g | h | j | k | l | ; | ' |return| | 4 | 5 | 6 | - |
* +---------------------------------------------------------+ +---+---+---+---+
* | shift  | z | x | c | v | b | n | m | , | . | / |  shift | | 1 | 2 | 3 |   |
* +---------------------------------------------------------+ +-------+---|ent|
* |cap|opt|comnd| ` |                   | \ |lef|rig|dwn|up | |   0   | . |   |
* +---------------------------------------------------------+ +-------+---+---+
*/
#define KEYMAP_M0116_ANSI( \
                           K7F,                                              \
   K35,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K47,K51,K4B,K43, \
   K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,     K59,K5B,K5C,K45, \
   K36,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27,    K24, K56,K57,K58,K4E, \
   K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C,        K7B, K53,K54,K55,     \
   K39,K3A,K37,K32,        K31,        K2A,K3B,K3C,K3D,K3E, K52,    K41,K4C  \
) { \
  { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
  { KC_##K08, KC_##K09, KC_NO,    KC_##K0B, 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_##K1E, 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_##K2E, KC_##K2F }, \
  { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_NO,    KC_##K35, KC_##K36, KC_##K37 }, \
  { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO    }, \
  { KC_NO,    KC_##K41, KC_NO,    KC_##K43, KC_NO,    KC_##K45, KC_NO,    KC_##K47 }, \
  { KC_NO,    KC_NO,    KC_NO,    KC_##K4B, KC_##K4C, KC_NO,    KC_##K4E, KC_NO    }, \
  { KC_NO,    KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
  { KC_##K58, KC_##K59, KC_NO,    KC_##K5B, KC_##K5C, 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_##K7B, KC_NO,    KC_NO,    KC_NO,    KC_##K7F }  \
}

#endif


/*
ADB ANSI/ISO Keymapping Note
============================
ANSI
,-----------    ----------.
| *a|  1|  2     =|Backspa|
|-----------    ----------|
|Tab  |  Q|     |  ]|   *c|
|-----------    ----------|
|CapsLo|  A|    '|Return  |
|-----------    ----------|
|Shift   |      Shift     |
`-----------    ----------'

ISO
,-----------    ----------.
| *a|  1|  2     =|Backspa|
|-----------    ----------|
|Tab  |  Q|     |  ]|Retur|
|-----------    -----`    |
|CapsLo|  A|    '| *c|    |
|-----------    ----------|
|Shif| *b|      Shift     |
`-----------    ----------'

ADB Keyboard scan code:
        ADB scan code   USB usage
        -------------   ---------
Key     ANSI    ISO     ANSI    ISO
---------------------------------------------
*a      0x32    0x0A    0x35    0x35
*b      ----    0x32    ----    0x64
*c      0x2A    0x2A    0x31    0x31(or 0x32)


TMK ADB-USB mapping:
ADB     USB(ANSI)   USB(ISO)
---------------------------------
0x32    0x35        0x64
0x0A    ----        0x35
0x2A    0x31        0x31(or 0x32)

Note that mappings of ADB code 0x32 are diffrent between ANSI and ISO keyboard.
https://github.com/tmk/tmk_keyboard/issues/35
 */
Makefile if you need it

Code: Select all

#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
#                Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
#               (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
#            have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
#             have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
#               (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
#                (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging, 
#              with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#                   bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------

# Target file name (without extension).
TARGET = adb_usb_lufa

# Directory common source filess exist
TMK_DIR = ../../tmk_core

# Directory keyboard dependent files exist
TARGET_DIR = .

# project specific files
SRC =	keymap_common.c \
	matrix.c \
	led.c \
	adb.c

ifdef KEYMAP
    SRC := keymap_$(KEYMAP).c $(SRC)
else
    SRC := keymap_ansi.c $(SRC)
endif

CONFIG_H = config.h


# MCU name
# atmega32u4 	Teensy2.0
# atemga32u4	TMK Converter rev.1
# atemga32u2	TMK Converter rev.2
MCU = at90usb1286 

# 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	for TMK Converter rev.1/rev.2
#   LUFA bootloader  4096
#   USBaspLoader     2048
OPT_DEFS += -DBOOTLOADER_SIZE=2048


# 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
#SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
NKRO_ENABLE = yes	# USB Nkey Rollover
#ADB_MOUSE_ENABLE = yes

# ADB Mice need acceleration for todays much bigger screens. 
OPT_DEFS += -DADB_MOUSE_MAXACC=8


# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax

# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)

include $(TMK_DIR)/protocol/lufa.mk
include $(TMK_DIR)/protocol.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk


matrix.c

Code: Select all

/*
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/>.
*/

/*
 * scan matrix
 */
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "util.h"
#include "debug.h"
#include "adb.h"
#include "matrix.h"
#include "report.h"
#include "host.h"


#if (MATRIX_COLS > 16)
#   error "MATRIX_COLS must not exceed 16"
#endif
#if (MATRIX_ROWS > 255)
#   error "MATRIX_ROWS must not exceed 255"
#endif


static bool is_modified = false;
static report_mouse_t mouse_report = {};

// matrix state buffer(1:on, 0:off)
#if (MATRIX_COLS <= 8)
static uint8_t matrix[MATRIX_ROWS];
#else
static uint16_t matrix[MATRIX_ROWS];
#endif

#ifdef MATRIX_HAS_GHOST
static bool matrix_has_ghost_in_row(uint8_t row);
#endif
static void register_key(uint8_t key);


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

void matrix_init(void)
{
    adb_host_init();
    // wait for keyboard to boot up and receive command
    _delay_ms(1000);
    // Enable keyboard left/right modifier distinction
    // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
    // upper byte: reserved bits 0000, device address 0010
    // lower byte: device handler 00000011
    adb_host_listen(0x2B,0x02,0x03);

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;

    debug_enable = true;
    //debug_matrix = true;
    //debug_keyboard = true;
    //debug_mouse = true;
    print("debug enabled.\n");

    // LED flash
    DDRD |= (1<<6); PORTD |= (1<<6);
    _delay_ms(500);
    DDRD |= (1<<6); PORTD &= ~(1<<6);

    return;
}

#ifdef ADB_MOUSE_ENABLE

#ifdef MAX
#undef MAX
#endif
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))

void adb_mouse_task(void)
{
    uint16_t codes;
    int16_t x, y;
    static int8_t mouseacc; 
    _delay_ms(12);  // delay for preventing overload of poor ADB keyboard controller
    codes = adb_host_mouse_recv();
    // If nothing received reset mouse acceleration, and quit. 
    if (!codes) {
        mouseacc = 1;
        return;
    };
    // Bit sixteen is button.
    if (~codes & (1 << 15))
        mouse_report.buttons |= MOUSE_BTN1;
    if (codes & (1 << 15))
        mouse_report.buttons &= ~MOUSE_BTN1;
    // lower seven bits are movement, as signed int_7. 
    // low byte is X-axis, high byte is Y. 
    y = (codes>>8 & 0x3F);
    x = (codes>>0 & 0x3F);
    // bit seven and fifteen is negative
    // usb does not use int_8, but int_7 (measuring distance) with sign-bit. 
    if (codes & (1 << 6))
          x = (x-0x40);
    if (codes & (1 << 14))
         y = (y-0x40);
    // Accelerate mouse. (They weren't meant to be used on screens larger than 320x200).
    x *= mouseacc;
    y *= mouseacc;
    // Cap our two bytes per axis to one byte. 
    // Easier with a MIN-function, but since -MAX(-a,-b) = MIN(a,b)...
	 // I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127)
    mouse_report.x = -MAX(-MAX(x, -127), -127);
    mouse_report.y = -MAX(-MAX(y, -127), -127);
    if (debug_mouse) {
            print("adb_host_mouse_recv: "); print_bin16(codes); print("\n");
            print("adb_mouse raw: [");
            phex(mouseacc); print(" ");
            phex(mouse_report.buttons); print("|");
            print_decs(mouse_report.x); print(" ");
            print_decs(mouse_report.y); print("]\n");
    }
    // Send result by usb. 
    host_mouse_send(&mouse_report);
    // increase acceleration of mouse
    mouseacc += ( mouseacc < ADB_MOUSE_MAXACC ? 1 : 0 );
    return;
}
#endif

uint8_t matrix_scan(void)
{
    /* extra_key is volatile and more convoluted than necessary because gcc refused
    to generate valid code otherwise. Making extra_key uint8_t and constructing codes
    here via codes = extra_key<<8 | 0xFF; would consistently fail to even LOAD
    extra_key from memory, and leave garbage in the high byte of codes. I tried
    dozens of code variations and it kept generating broken assembly output. So
    beware if attempting to make extra_key code more logical and efficient. */
    static volatile uint16_t extra_key = 0xFFFF;
    uint16_t codes;
    uint8_t key0, key1;

    is_modified = false;

    codes = extra_key;
    extra_key = 0xFFFF;

    if ( codes == 0xFFFF )
    {
        _delay_ms(12);  // delay for preventing overload of poor ADB keyboard controller
        codes = adb_host_kbd_recv();
    }
    key0 = codes>>8;
    key1 = codes&0xFF;

    if (debug_matrix && codes) {
        print("adb_host_kbd_recv: "); phex16(codes); print("\n");
    }

    if (codes == 0) {                           // no keys
        return 0;
    } else if (codes == 0x7F7F) {   // power key press
        register_key(0x7F);
    } else if (codes == 0xFFFF) {   // power key release
        register_key(0xFF);
    } else if (key0 == 0xFF) {      // error
        xprintf("adb_host_kbd_recv: ERROR(%d)\n", codes);
        return key1;
    } else {
        register_key(key0);
        if (key1 != 0xFF)       // key1 is 0xFF when no second key.
            extra_key = key1<<8 | 0xFF; // process in a separate call
    }

    return 1;
}

bool matrix_is_modified(void)
{
    return is_modified;
}

inline
bool matrix_has_ghost(void)
{
#ifdef MATRIX_HAS_GHOST
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        if (matrix_has_ghost_in_row(i))
            return true;
    }
#endif
    return false;
}

inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
    return (matrix[row] & (1<<col));
}

inline
#if (MATRIX_COLS <= 8)
uint8_t matrix_get_row(uint8_t row)
#else
uint16_t matrix_get_row(uint8_t row)
#endif
{
    return matrix[row];
}

void matrix_print(void)
{
    if (!debug_matrix) return;
#if (MATRIX_COLS <= 8)
    print("r/c 01234567\n");
#else
    print("r/c 0123456789ABCDEF\n");
#endif
    for (uint8_t row = 0; row < matrix_rows(); row++) {
        phex(row); print(": ");
#if (MATRIX_COLS <= 8)
        pbin_reverse(matrix_get_row(row));
#else
        pbin_reverse16(matrix_get_row(row));
#endif
#ifdef MATRIX_HAS_GHOST
        if (matrix_has_ghost_in_row(row)) {
            print(" <ghost");
        }
#endif
        print("\n");
    }
}

uint8_t matrix_key_count(void)
{
    uint8_t count = 0;
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
#if (MATRIX_COLS <= 8)
        count += bitpop(matrix[i]);
#else
        count += bitpop16(matrix[i]);
#endif
    }
    return count;
}

#ifdef MATRIX_HAS_GHOST
inline
static bool matrix_has_ghost_in_row(uint8_t row)
{
    // no ghost exists in case less than 2 keys on
    if (((matrix[row] - 1) & matrix[row]) == 0)
        return false;

    // ghost exists in case same state as other row
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        if (i != row && (matrix[i] & matrix[row]) == matrix[row])
            return true;
    }
    return false;
}
#endif

inline
static void register_key(uint8_t key)
{
    uint8_t col, row;
    col = key&0x07;
    row = (key>>3)&0x0F;
    if (key&0x80) {
        matrix[row] &= ~(1<<col);
    } else {
        matrix[row] |=  (1<<col);
    }
    is_modified = true;
}

User avatar
flabbergast

12 Feb 2016, 00:43

You have 'F0' instead of 'F10' on the second layer. There's no such key as 'F0' (this is actually kinda written in the error message you posted ;)

User avatar
Halvar

12 Feb 2016, 00:50

Replace f6 by F6 and F0 by F10 in the first line of your second layer in keymap_raf.c .

Also delete the trailing comma in this line:

Code: Select all

       NO,  TRNS,TRNS,LCTL,          TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,         DEL ,     BSPC,TRNS),
I don't know if that's all, but that seems to be what the error messages that you're getting are about.

User avatar
flabbergast

12 Feb 2016, 00:52

Ah yes, missed the other ones :) /me should get some sleep.

mastermachetier

12 Feb 2016, 01:04

Halvar wrote: Replace f6 by F6 and F0 by F10 in the first line of your second layer in keymap_raf.c .

Also delete the trailing comma in this line:

Code: Select all

       NO,  TRNS,TRNS,LCTL,          TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,         DEL ,     BSPC,TRNS),
I don't know if that's all, but that seems to be what the error messages that you're getting are about.

flabbergast wrote: Ah yes, missed the other ones :) /me should get some sleep.

Wow thanks guys !! I feel like an idiot now haha.

mastermachetier

12 Feb 2016, 15:36

mastermachetier wrote:
Halvar wrote: Replace f6 by F6 and F0 by F10 in the first line of your second layer in keymap_raf.c .

Also delete the trailing comma in this line:

Code: Select all

       NO,  TRNS,TRNS,LCTL,          TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,         DEL ,     BSPC,TRNS),
I don't know if that's all, but that seems to be what the error messages that you're getting are about.

flabbergast wrote: Ah yes, missed the other ones :) /me should get some sleep.

Wow thanks guys !! I feel like an idiot now haha.

spoke too soon It seems that only the second layer is working right now even if I am not holding down the FN key.

User avatar
tentator

12 Feb 2016, 18:13

I'm not sure about that coma "," was it really wrong?

User avatar
Halvar

12 Feb 2016, 19:04

You're right, the comma doesn't really matter. It doesn't really belong there and I think it even adds an empty layer, but it doesn't really change what the program does, except for using up some memory for that additional layer.

About the second layer: I'm not sure what's the problem. One thing I see is that you set the spot "above" the FN0 key on the second layer to "NO". I'm not 100% sure but I think it needs to be "TRNS" for the keyboard to switch back to layer 0 when you release the key. However, if that's the problem, I would expect the keyboard to be in layer 0 when you connect it, and go up to layer 1 and get stuck there if you press FN0 for the first time. So that'd be a bit different from what you have now.

Does everything work as expected if you comment out the whole layer 1 in your code?

mastermachetier

18 Feb 2016, 23:45

Finally got a change to sit down and look at this again and it turns out i needed to put the FN in the same place on the second layer.

User avatar
tentator

22 Feb 2016, 00:27

Hi guys,
not sure what I'm doing wrong here but for some strange reason I'm compiling tmk for teensy 2.0 with ps2 mouse support of a trackpoint as explained in this thread: workshop-f7/connecting-thinkpad-trackpo ... t9772.html
So far it does not work and It's unclear to me why.. basically I modified just the makefile and added those parts in the config.h.. maybe some other file should be changed?
By the way I used the GH60 as a basis keyboard.. maybe I should use another one better that already has the ps2-mouse part?
I tried a .hex firmware from jou today and that also is based on tmk, and this works flawlessly on that same trackpoint.. (so far I was headbanging my head on the hw pinout of the trackpoint being wrong for one week.. which of course was not the issue.. sw or better fw was the issue as usual.. :))
The relevant files are as follows...

makefile:
Spoiler:

Code: Select all

#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
#                Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
#               (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
#            have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
#             have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
#               (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
#                (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging, 
#              with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#                   bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------

# Target file name (without extension).
TARGET = tentboard

# Directory common source filess exist
TMK_DIR = ../../tmk_core

# Directory keyboard dependent files exist
TARGET_DIR = .

# project specific files
SRC =	keymap_common.c \
	matrix.c \
	led.c

ifdef KEYMAP
    SRC := keymap_$(KEYMAP).c $(SRC)
else
    SRC := keymap_tentboard.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
#SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA

PS2_MOUSE_ENABLE = yes  # PS/2 mouse(TrackPoint) support
#PS2_USE_BUSYWAIT = yes # uses primitive reference code
#PS2_USE_INT = yes      # uses external interrupt for falling edge of PS/2 clock pin
PS2_USE_USART = yes     # uses hardware USART engine for PS/2 signal receive(recomened)
PS2_MOUSE_DEBUG = no

# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax

# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)

include $(TMK_DIR)/protocol/lufa.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk
config.h:
Spoiler:

Code: Select all

/*
Copyright 2012 Jun Wako <wakojun@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef CONFIG_H
#define CONFIG_H


/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x6060
#define DEVICE_VER      0x0001
#define MANUFACTURER    10t8or
#define PRODUCT         TentBoard
#define DESCRIPTION     t.m.k. keyboard firmware for tentboard

/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 15

/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST

/* Set 0 if debouncing isn't needed */
#define DEBOUNCE    5

/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE

/* key combination for command */
#define IS_COMMAND() ( \
    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)



/*
 * Feature disable options
 *  These options are also useful to firmware size reduction.
 */

/* disable debug print */
//#define NO_DEBUG

/* disable print */
//#define NO_PRINT

/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION

    /* PS/2 mouse interrupt version */
    #ifdef PS2_USE_INT
    /* uses INT2 for clock line(ATMega32U4) */
    #define PS2_CLOCK_PORT  PORTD
    #define PS2_CLOCK_PIN   PIND
    #define PS2_CLOCK_DDR   DDRD
    #define PS2_CLOCK_BIT   2
    #define PS2_DATA_PORT   PORTD
    #define PS2_DATA_PIN    PIND
    #define PS2_DATA_DDR    DDRD
    #define PS2_DATA_BIT    5

    #define PS2_INT_INIT()  do {    \
        EICRA |= ((1<<ISC21) |      \
                  (0<<ISC20));      \
    } while (0)
    #define PS2_INT_ON()  do {      \
        EIMSK |= (1<<INT2);         \
    } while (0)
    #define PS2_INT_OFF() do {      \
        EIMSK &= ~(1<<INT2);        \
    } while (0)
    #define PS2_INT_VECT   INT2_vect
    #endif


    /* PS/2 mouse USART version */
    #ifdef PS2_USE_USART
    #if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
    /* XCK for clock line and RXD for data line */
    #define PS2_CLOCK_PORT  PORTD
    #define PS2_CLOCK_PIN   PIND
    #define PS2_CLOCK_DDR   DDRD
    #define PS2_CLOCK_BIT   5
    #define PS2_DATA_PORT   PORTD
    #define PS2_DATA_PIN    PIND
    #define PS2_DATA_DDR    DDRD
    #define PS2_DATA_BIT    2

    /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
    /* set DDR of CLOCK as input to be slave */
    #define PS2_USART_INIT() do {   \
        PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);   \
        PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);     \
        UCSR1C = ((1 << UMSEL10) |  \
                  (3 << UPM10)   |  \
                  (0 << USBS1)   |  \
                  (3 << UCSZ10)  |  \
                  (0 << UCPOL1));   \
        UCSR1A = 0;                 \
        UBRR1H = 0;                 \
        UBRR1L = 0;                 \
    } while (0)
    #define PS2_USART_RX_INT_ON() do {  \
        UCSR1B = ((1 << RXCIE1) |       \
                  (1 << RXEN1));        \
    } while (0)
    #define PS2_USART_RX_POLL_ON() do { \
        UCSR1B = (1 << RXEN1);          \
    } while (0)
    #define PS2_USART_OFF() do {    \
        UCSR1C = 0;                 \
        UCSR1B &= ~((1 << RXEN1) |  \
                    (1 << TXEN1));  \
    } while (0)
    #define PS2_USART_RX_READY      (UCSR1A & (1<<RXC1))
    #define PS2_USART_RX_DATA       UDR1
    #define PS2_USART_ERROR         (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
    #define PS2_USART_RX_VECT       USART1_RX_vect
    #endif

    #endif


#endif
Kind regards,
tent:wq

User avatar
tentator

22 Feb 2016, 17:45

Bump :)

User avatar
Ray

22 Feb 2016, 18:01

Preprocessor-commands have to start at the beginning of a line, no indentation allowed iirc.

Also for getting the trackpoint to work, starting from the "onekey" basis might be easier, but ymmv.

To make sure I got it right: the thing compiles without errors or warnings, and everything but the trackpoint is fine? If that's the case, it is probably the indentation I mentioned first.

ReleaseCandidate

22 Feb 2016, 19:33

Ray wrote: Preprocessor-commands have to start at the beginning of a line, no indentation allowed iirc.
No. You can add as many whitespace as you like before a preprocessor (and spaces and tabs between the '#' and the preprocessor directive).
See '6.10 Preprocessing directives' in the C99 standard.
Ray wrote: To make sure I got it right: the thing compiles without errors or warnings, and everything but the trackpoint is fine? If that's the case, it is probably the indentation I mentioned first.
No, it's definitely not.

User avatar
tentator

22 Feb 2016, 20:13

Yes the keyboard works perfectly and it compiles without warnings.. only the trackpoint doesn't... it instead works with the .hex that jou gave me..
about indentation I never had issues before indenting in sources and includes.. only on makefiles it has to be watched out.. but that also should be OK... I double check. ..

Ps: performing a quick diff with the config.h of the onekey directory I can only spot a different int/port default (D1) that is used for interrupt which I anyway don't use..

User avatar
tentator

24 Feb 2016, 23:21

by the way I found the bug.. it was in my mind as usual and in the makefile where I completely forgot to add in the bottom something like:

Code: Select all

##### Enable PS/2 TrackPoint !!!
include $(TMK_DIR)/protocol.mk
##### Enable PS/2 TrackPoint END
otherwise of course the keyboard part works as expected but the ps2 part does not even get included..

yeah one week spent hunting ghosts.. ;)

Post Reply

Return to “Workshop”