Author Topic: TMK keyboard firmware  (Read 643767 times)

0 Members and 1 Guest are viewing this topic.

Offline a-c

  • Posts: 196
  • Location: USA
Re: TMK keyboard firmware
« Reply #1550 on: Fri, 05 August 2016, 13:30:40 »
I looked into it. When I push a button in pin19 the keyboard will type two letters on pin18 and pin19 at the same time. - Interesting - But when I push a button on pin18 it will only type the right letter. :)

Missing the break after row 1
Code: [Select]
        case 1:
            palSetPadMode(TEENSY_PIN18_IOPORT, TEENSY_PIN18, PAL_MODE_OUTPUT_PUSHPULL);
            palClearPad(TEENSY_PIN18_IOPORT, TEENSY_PIN18);
        case 2:
            palSetPadMode(TEENSY_PIN19_IOPORT, TEENSY_PIN19, PAL_MODE_OUTPUT_PUSHPULL);
            palClearPad(TEENSY_PIN19_IOPORT, TEENSY_PIN19);
            break;

Offline RichardRahl

  • Posts: 5
Re: TMK keyboard firmware
« Reply #1551 on: Fri, 05 August 2016, 13:44:55 »
Thank you! :)   :thumb:

Now I have to make the other layers.

Offline RichardRahl

  • Posts: 5
Re: TMK keyboard firmware
« Reply #1552 on: Mon, 08 August 2016, 05:40:12 »
Hello fellow geekhackers,

I still have a problem with my keyboard. The shift keys don't seem to work for me. I can't type capital letters with shift + letter, capslock works just fine. I tried to search for this problem with little or no success and I read the docs at tmk_core searching for capital letters but I didn't find anything helpful or if I found I didn't realize it would help me.. :(
Not to mention all the special characters I need shift for ( %, !, =, etc depending on your layout). - I hope it is a legit English sentence.
About these special characters, I haven't had time to worry about those. First, I wanted to solve the problem with the capital letters.

ctrl +c, ctrl +v, tab, capslock, numlock buttons are working for sure.

I attach some of 'my' codes, keep in mind that I tried a lot of different versions, modifications - this is just the latest one.

I would appreciate if you could point me to the right direction.
Best regrades,

RR

mod: Might seem to be wiring problem. I moved the pin9 cable with my fingers and now it works... :confused:  somewhere the connection not good, maybe a broken cable.
« Last Edit: Mon, 08 August 2016, 06:37:37 by RichardRahl »

Offline Mystic-X

  • Posts: 3
  • Location: east Germany
Re: TMK keyboard firmware
« Reply #1553 on: Tue, 09 August 2016, 11:29:58 »
Hey!

I need some advice from the experts.

bought one of those cheap "pro micro" boards with the atmega32u4 from ebay.

Now trying to get the TMK firmware (onekey sample) to run on this thing.
I'm using ubuntu 14.04LTS.

what I did:

modify the Makefile to
Code: [Select]
OPT_DEFS += -DBOOTLOADER_SIZE=512found this on another forum! but also tried with the default 4096 (changes nothing for me)

than I run: (from the folder where the onekey sample files are located)
make -f Makefile

Code: [Select]
-------- begin --------
avr-gcc (GCC) 4.8.2
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.

Linking: onekey_lufa.elf
avr-gcc -mmcu=atmega32u4 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=512 -DCONSOLE_ENABLE -DVERSION=unknown -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 -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=onekey_lufa.elf -I. -I../../tmk_core -I../../tmk_core/common -I../../tmk_core/protocol -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -std=gnu99 -include config.h -MMD -MP -MF .dep/onekey_lufa.elf.d  obj_onekey_lufa/keymap.o obj_onekey_lufa/matrix.o obj_onekey_lufa/led.o obj_onekey_lufa/common/host.o obj_onekey_lufa/common/keyboard.o obj_onekey_lufa/common/action.o obj_onekey_lufa/common/action_tapping.o obj_onekey_lufa/common/action_macro.o obj_onekey_lufa/common/action_layer.o obj_onekey_lufa/common/action_util.o obj_onekey_lufa/common/print.o obj_onekey_lufa/common/debug.o obj_onekey_lufa/common/util.o obj_onekey_lufa/common/hook.o obj_onekey_lufa/common/avr/suspend.o obj_onekey_lufa/common/avr/xprintf.o obj_onekey_lufa/common/avr/timer.o obj_onekey_lufa/common/avr/bootloader.o obj_onekey_lufa/common/keymap.o obj_onekey_lufa/protocol/lufa/lufa.o obj_onekey_lufa/protocol/lufa/descriptor.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Class/Common/HIDParser.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/ConfigDescriptors.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/DeviceStandardReq.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/Events.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/HostStandardReq.o obj_onekey_lufa/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/USBTask.o --output onekey_lufa.elf -Wl,-Map=onekey_lufa.map,--cref -Wl,--gc-sections     -lm

Creating load file for Flash: onekey_lufa.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature onekey_lufa.elf onekey_lufa.hex

Creating load file for EEPROM: onekey_lufa.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex onekey_lufa.elf onekey_lufa.eep || exit 0

Creating Extended Listing: onekey_lufa.lss
avr-objdump -h -S -z onekey_lufa.elf > onekey_lufa.lss

Creating Symbol Table: onekey_lufa.sym
avr-nm -n onekey_lufa.elf > onekey_lufa.sym

Size after:
   text    data     bss     dec     hex filename
  11816      14     123   11953    2eb1 onekey_lufa.elf

-------- end --------
looks like its working for me??!?!

than I plug in the pro micro board and short the reset pin to GND twice and than: ls /dev/tty*
-> schows me /dev/ttyACM3 as new devide

than I run:
avrdude -p atmega32u4 -P /dev/ttyACM3 -c avr109 -U flash:w:onekey_lufa.hex

Code: [Select]
Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "onekey_lufa.hex"
avrdude: input file onekey_lufa.hex auto detected as Intel Hex
avrdude: writing flash (11830 bytes):

Writing | ################################################## | 100% 1.02s

avrdude: 11830 bytes of flash written
avrdude: verifying flash memory against onekey_lufa.hex:
avrdude: load data flash data from input file onekey_lufa.hex:
avrdude: input file onekey_lufa.hex auto detected as Intel Hex
avrdude: input file onekey_lufa.hex contains 11830 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.19s

avrdude: verifying ...
avrdude: 11830 bytes of flash verified

avrdude: safemode: Fuses OK (H:CB, E:D8, L:FF)

avrdude done.  Thank you.

than I unplugged the pro micro from the USB and plugged it in again

than: dmesg |tail shows:
Code: [Select]
[158341.894298] hid-generic 0003:FEED:1111.000A: hiddev0,hidraw1: USB HID v1.11 Device [geekhack Onekey] on usb-0000:00:1d.0-2/input1
[158344.428219] usb 5-2: USB disconnect, device number 13
[158346.612080] usb 5-2: new full-speed USB device number 14 using uhci_hcd
[158346.793139] usb 5-2: New USB device found, idVendor=feed, idProduct=1111
[158346.793145] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[158346.793149] usb 5-2: Product: Onekey
[158346.793152] usb 5-2: Manufacturer: geekhack
[158346.798787] input: geekhack Onekey as /devices/pci0000:00/0000:00:1d.0/usb5/5-2/5-2:1.0/input/input16
[158346.798920] hid-generic 0003:FEED:1111.000B: input,hidraw0: USB HID v1.11 Keyboard [geekhack Onekey] on usb-0000:00:1d.0-2/input0
[158346.802278] hid-generic 0003:FEED:1111.000C: hiddev0,hidraw1: USB HID v1.11 Device [geekhack Onekey] on usb-0000:00:1d.0-2/input1

looks ok for me
BUT
If I connect PB0 and PB1 nothing happens!
Yes I have really connected the correct pins... I had a look ath the schematics of this thing and PB0=D14, PB1=D15

Any idea whats wrong with that?
I have tried 2 of this pro micro boards, they behave the same way.

I really hope someone has an advice for me.

Offline a-c

  • Posts: 196
  • Location: USA
Re: TMK keyboard firmware
« Reply #1554 on: Tue, 09 August 2016, 11:47:56 »

If I connect PB0 and PB1 nothing happens!
Yes I have really connected the correct pins... I had a look ath the schematics of this thing and PB0=D14, PB1=D15


B0 is connected to the LED.

Pick a different pin. http://i.imgur.com/wMNx2u6.png

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1555 on: Fri, 19 August 2016, 22:25:33 »
This is my first try at TMK so theres probably a lot going wrong. I'll just spill it all out.

Matrix Wiring: http://www.servimg.com/view/11209166/175

Teensy wiring: http://www.servimg.com/view/11209166/174

I used this guide made by Matteo: https://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html#p141386

I'm getting this message when compiling hexfile:
More
$ make -f Makefile
/usr/bin/sh: dfu-programmer: command not found
/usr/bin/sh: dfu-programmer: command not found

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 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_gh60_lufa
Compiling C: keymap_poker.c
avr-gcc -c -mmcu=at90usb1287 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -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 -DVERSION=unknown -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_gh60_lufa/keymap_poker.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_gh60_lufa_keymap_poker.o.d  keymap_poker.c -o obj_gh60_lufa/keymap_poker.o
In file included from keymap_poker.c:1:
keymap_common.h:43:8: error: parameter name missing
keymap_poker.c:5: warning: implicit declaration of function 'KEYMAP'
keymap_poker.c:5: warning: missing braces around initializer
keymap_poker.c:5: warning: (near initialization for 'keymaps[0]')
keymap_poker.c:5: error: initializer element is not constant
keymap_poker.c:5: error: (near initialization for 'keymaps[0][0][0]')
make: *** [obj_gh60_lufa/keymap_poker.o] Error 1


This is what I've done:
makefile
More
#----------------------------------------------------------------------------
-----------------------------------------------------

# 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

Config.h
More
#ifndef CONFIG_H
#define CONFIG_H


/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x6060
#define DEVICE_VER      0x0001
#define MANUFACTURER    geekhack
#define PRODUCT         GH34
#define DESCRIPTION     t.m.k. keyboard firmware for GH60

/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 7

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

#endif



Matrix.c
More
/*
 * 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 = 0;
        matrix_debouncing = 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 != cols) {
            matrix_debouncing = 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 = matrix_debouncing;
            }
        }
    }

    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);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3   4   5  6
 * pin: F0  F1  F4  F5  F6 F7 B6
  */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    PORTF |=  (1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    DDRB  &= ~(1<<6);
    PORTB |=  (1<<6);}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3)) |
           (PINF&(1<<6) ? 0 : (1<<4)) |
           (PINF&(1<<7) ? 0 : (1<<5)) |
           (PINB&(1<<6) ? 0 : (1<<6)) |
}

/* Row pin configuration
 * row: 0   1   2   3   4  5
 * pin: B0  B1  B2  B3  B7 D0
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRB  &= ~0b10001111;
    PORTB &= ~0b10001111;
    DDRD  &= ~0b00000001;
    PORTD &= ~0b00000001;
}

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<<7;
            PORTB &= ~(1<<7);
            break;
        case 5:
            DDRD  |= (1<<0);
            PORTD &= ~(1<<0);
            break;
    }
}



keymap_common.h
More
#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];


/* GH34 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, \
    K10, K11, K12, K13, K14, K15, K16, \
    K20, K21, K22, K23, K24, K25, K26, \
       ,    ,    , K33, K34, K35,    , \
       , K41,    , K43, K44, K45, K46, \
    K50, K51, K52,    , K54, K55,    , \
)
#endif

Keymap_poker.c (I made this very simple to get a better understanding of it all.)
More
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP(1, 1,   1,   1,   1,   1,   1,  \
           1, 1,  1,  1,   1,  1,   1,  \
           1, 1,   1,   1,   1,   1,   1,   \
           1, 1,  1, \
           1, 1, 1, 1, 1, \
           1, 1, 1, 1, 1),
};

I understand it's quite a lot but any help is appreciated. Please be reminded this is my first try.
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline Moistgun

  • Slippery When Wet
  • * Esteemed Elder
  • Posts: 1832
Re: TMK keyboard firmware
« Reply #1556 on: Sat, 20 August 2016, 00:52:00 »
This is my first try at TMK so theres probably a lot going wrong. I'll just spill it all out.

Matrix Wiring: http://www.servimg.com/view/11209166/175

Teensy wiring: http://www.servimg.com/view/11209166/174

I used this guide made by Matteo: https://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html#p141386

I'm getting this message when compiling hexfile:
More
$ make -f Makefile
/usr/bin/sh: dfu-programmer: command not found
/usr/bin/sh: dfu-programmer: command not found

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 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_gh60_lufa
Compiling C: keymap_poker.c
avr-gcc -c -mmcu=at90usb1287 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -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 -DVERSION=unknown -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_gh60_lufa/keymap_poker.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_gh60_lufa_keymap_poker.o.d  keymap_poker.c -o obj_gh60_lufa/keymap_poker.o
In file included from keymap_poker.c:1:
keymap_common.h:43:8: error: parameter name missing
keymap_poker.c:5: warning: implicit declaration of function 'KEYMAP'
keymap_poker.c:5: warning: missing braces around initializer
keymap_poker.c:5: warning: (near initialization for 'keymaps[0]')
keymap_poker.c:5: error: initializer element is not constant
keymap_poker.c:5: error: (near initialization for 'keymaps[0][0][0]')
make: *** [obj_gh60_lufa/keymap_poker.o] Error 1


This is what I've done:
makefile
More
#----------------------------------------------------------------------------
-----------------------------------------------------

# 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

Config.h
More
#ifndef CONFIG_H
#define CONFIG_H


/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x6060
#define DEVICE_VER      0x0001
#define MANUFACTURER    geekhack
#define PRODUCT         GH34
#define DESCRIPTION     t.m.k. keyboard firmware for GH60

/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 7

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

#endif



Matrix.c
More
/*
 * 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 = 0;
        matrix_debouncing = 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 != cols) {
            matrix_debouncing = 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 = matrix_debouncing;
            }
        }
    }

    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);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3   4   5  6
 * pin: F0  F1  F4  F5  F6 F7 B6
  */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    PORTF |=  (1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    DDRB  &= ~(1<<6);
    PORTB |=  (1<<6);}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3)) |
           (PINF&(1<<6) ? 0 : (1<<4)) |
           (PINF&(1<<7) ? 0 : (1<<5)) |
           (PINB&(1<<6) ? 0 : (1<<6)) |
}

/* Row pin configuration
 * row: 0   1   2   3   4  5
 * pin: B0  B1  B2  B3  B7 D0
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRB  &= ~0b10001111;
    PORTB &= ~0b10001111;
    DDRD  &= ~0b00000001;
    PORTD &= ~0b00000001;
}

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<<7;
            PORTB &= ~(1<<7);
            break;
        case 5:
            DDRD  |= (1<<0);
            PORTD &= ~(1<<0);
            break;
    }
}



keymap_common.h
More
#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];


/* GH34 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, \
    K10, K11, K12, K13, K14, K15, K16, \
    K20, K21, K22, K23, K24, K25, K26, \
       ,    ,    , K33, K34, K35,    , \
       , K41,    , K43, K44, K45, K46, \
    K50, K51, K52,    , K54, K55,    , \
)
#endif

Keymap_poker.c (I made this very simple to get a better understanding of it all.)
More
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP(1, 1,   1,   1,   1,   1,   1,  \
           1, 1,  1,  1,   1,  1,   1,  \
           1, 1,   1,   1,   1,   1,   1,   \
           1, 1,  1, \
           1, 1, 1, 1, 1, \
           1, 1, 1, 1, 1),
};

I understand it's quite a lot but any help is appreciated. Please be reminded this is my first try.

I recommend just uploading all these in a folder to dropbox and sharing the link.
Someone is more likely willing to look through your code if they can use their editor.

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1557 on: Sat, 20 August 2016, 03:38:09 »
This is my first try at TMK so theres probably a lot going wrong. I'll just spill it all out.

Matrix Wiring: http://www.servimg.com/view/11209166/175

Teensy wiring: http://www.servimg.com/view/11209166/174

I used this guide made by Matteo: https://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html#p141386

I'm getting this message when compiling hexfile:
More
$ make -f Makefile
/usr/bin/sh: dfu-programmer: command not found
/usr/bin/sh: dfu-programmer: command not found

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 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_gh60_lufa
Compiling C: keymap_poker.c
avr-gcc -c -mmcu=at90usb1287 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -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 -DVERSION=unknown -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_gh60_lufa/keymap_poker.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_gh60_lufa_keymap_poker.o.d  keymap_poker.c -o obj_gh60_lufa/keymap_poker.o
In file included from keymap_poker.c:1:
keymap_common.h:43:8: error: parameter name missing
keymap_poker.c:5: warning: implicit declaration of function 'KEYMAP'
keymap_poker.c:5: warning: missing braces around initializer
keymap_poker.c:5: warning: (near initialization for 'keymaps[0]')
keymap_poker.c:5: error: initializer element is not constant
keymap_poker.c:5: error: (near initialization for 'keymaps[0][0][0]')
make: *** [obj_gh60_lufa/keymap_poker.o] Error 1


This is what I've done:
makefile
More
#----------------------------------------------------------------------------
-----------------------------------------------------

# 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

Config.h
More
#ifndef CONFIG_H
#define CONFIG_H


/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x6060
#define DEVICE_VER      0x0001
#define MANUFACTURER    geekhack
#define PRODUCT         GH34
#define DESCRIPTION     t.m.k. keyboard firmware for GH60

/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 7

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

#endif



Matrix.c
More
/*
 * 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 = 0;
        matrix_debouncing = 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 != cols) {
            matrix_debouncing = 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 = matrix_debouncing;
            }
        }
    }

    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);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3   4   5  6
 * pin: F0  F1  F4  F5  F6 F7 B6
  */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    PORTF |=  (1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    DDRB  &= ~(1<<6);
    PORTB |=  (1<<6);}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3)) |
           (PINF&(1<<6) ? 0 : (1<<4)) |
           (PINF&(1<<7) ? 0 : (1<<5)) |
           (PINB&(1<<6) ? 0 : (1<<6)) |
}

/* Row pin configuration
 * row: 0   1   2   3   4  5
 * pin: B0  B1  B2  B3  B7 D0
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRB  &= ~0b10001111;
    PORTB &= ~0b10001111;
    DDRD  &= ~0b00000001;
    PORTD &= ~0b00000001;
}

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<<7;
            PORTB &= ~(1<<7);
            break;
        case 5:
            DDRD  |= (1<<0);
            PORTD &= ~(1<<0);
            break;
    }
}



keymap_common.h
More
#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];


/* GH34 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, \
    K10, K11, K12, K13, K14, K15, K16, \
    K20, K21, K22, K23, K24, K25, K26, \
       ,    ,    , K33, K34, K35,    , \
       , K41,    , K43, K44, K45, K46, \
    K50, K51, K52,    , K54, K55,    , \
)
#endif

Keymap_poker.c (I made this very simple to get a better understanding of it all.)
More
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP(1, 1,   1,   1,   1,   1,   1,  \
           1, 1,  1,  1,   1,  1,   1,  \
           1, 1,   1,   1,   1,   1,   1,   \
           1, 1,  1, \
           1, 1, 1, 1, 1, \
           1, 1, 1, 1, 1),
};

I understand it's quite a lot but any help is appreciated. Please be reminded this is my first try.

I recommend just uploading all these in a folder to dropbox and sharing the link.
Someone is more likely willing to look through your code if they can use their editor.
Thank you for your help. I hope the link works. I had to install dropbox, never used it before.
https://www.dropbox.com/sh/gyt9cdhe03ukz5g/AADBFYGX0Cr1--R5BsmDOhi6a?dl=0
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline Tactile

  • Posts: 1371
  • Location: Portland, OR
Re: TMK keyboard firmware
« Reply #1558 on: Sat, 20 August 2016, 11:27:00 »
I think your keymap matrix (array, is that the right word?) in keymap_common.h is incomplete. Here's a piece of mine:

Code: [Select]
#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 }  \
}

Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1559 on: Sat, 20 August 2016, 11:37:47 »
This is my first try at TMK so theres probably a lot going wrong. I'll just spill it all out.

Matrix Wiring: http://www.servimg.com/view/11209166/175

Teensy wiring: http://www.servimg.com/view/11209166/174

I used this guide made by Matteo: https://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html#p141386

I'm getting this message when compiling hexfile:
More
$ make -f Makefile
/usr/bin/sh: dfu-programmer: command not found
/usr/bin/sh: dfu-programmer: command not found

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 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_gh60_lufa
Compiling C: keymap_poker.c
avr-gcc -c -mmcu=at90usb1287 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -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 -DVERSION=unknown -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_gh60_lufa/keymap_poker.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_gh60_lufa_keymap_poker.o.d  keymap_poker.c -o obj_gh60_lufa/keymap_poker.o
In file included from keymap_poker.c:1:
keymap_common.h:43:8: error: parameter name missing
keymap_poker.c:5: warning: implicit declaration of function 'KEYMAP'
keymap_poker.c:5: warning: missing braces around initializer
keymap_poker.c:5: warning: (near initialization for 'keymaps[0]')
keymap_poker.c:5: error: initializer element is not constant
keymap_poker.c:5: error: (near initialization for 'keymaps[0][0][0]')
make: *** [obj_gh60_lufa/keymap_poker.o] Error 1


This is what I've done:
makefile
More
#----------------------------------------------------------------------------
-----------------------------------------------------

# 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

Config.h
More
#ifndef CONFIG_H
#define CONFIG_H


/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x6060
#define DEVICE_VER      0x0001
#define MANUFACTURER    geekhack
#define PRODUCT         GH34
#define DESCRIPTION     t.m.k. keyboard firmware for GH60

/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 7

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

#endif



Matrix.c
More
/*
 * 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 = 0;
        matrix_debouncing = 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 != cols) {
            matrix_debouncing = 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 = matrix_debouncing;
            }
        }
    }

    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);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3   4   5  6
 * pin: F0  F1  F4  F5  F6 F7 B6
  */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    PORTF |=  (1<<0 | 1<<1| 1<<4| 1<<5| 1<<7);
    DDRB  &= ~(1<<6);
    PORTB |=  (1<<6);}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3)) |
           (PINF&(1<<6) ? 0 : (1<<4)) |
           (PINF&(1<<7) ? 0 : (1<<5)) |
           (PINB&(1<<6) ? 0 : (1<<6)) |
}

/* Row pin configuration
 * row: 0   1   2   3   4  5
 * pin: B0  B1  B2  B3  B7 D0
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRB  &= ~0b10001111;
    PORTB &= ~0b10001111;
    DDRD  &= ~0b00000001;
    PORTD &= ~0b00000001;
}

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<<7;
            PORTB &= ~(1<<7);
            break;
        case 5:
            DDRD  |= (1<<0);
            PORTD &= ~(1<<0);
            break;
    }
}



keymap_common.h
More
#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];


/* GH34 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, \
    K10, K11, K12, K13, K14, K15, K16, \
    K20, K21, K22, K23, K24, K25, K26, \
       ,    ,    , K33, K34, K35,    , \
       , K41,    , K43, K44, K45, K46, \
    K50, K51, K52,    , K54, K55,    , \
)
#endif

Keymap_poker.c (I made this very simple to get a better understanding of it all.)
More
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP(1, 1,   1,   1,   1,   1,   1,  \
           1, 1,  1,  1,   1,  1,   1,  \
           1, 1,   1,   1,   1,   1,   1,   \
           1, 1,  1, \
           1, 1, 1, 1, 1, \
           1, 1, 1, 1, 1),
};

I understand it's quite a lot but any help is appreciated. Please be reminded this is my first try.

Code: [Select]
keymap_common.h:43:8: error: parameter name missing
This error message tells you where the problem is - keymap_common.h, line 43, character 8 - it doesn't like you having a blank at the beginning of the line.  Comparing your file to some others there shouldn't be any blanks in that bit, and you're also missing a KC_##K00, KC_##K01, KC_##K02 bit which defines the matrix positions of the keys (probably exactly the same as the physical positions as you've handwired)

Hope that helps!
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1560 on: Sat, 20 August 2016, 21:58:05 »
wall of text

Code: [Select]
keymap_common.h:43:8: error: parameter name missing
This error message tells you where the problem is - keymap_common.h, line 43, character 8 - it doesn't like you having a blank at the beginning of the line.  Comparing your file to some others there shouldn't be any blanks in that bit, and you're also missing a KC_##K00, KC_##K01, KC_##K02 bit which defines the matrix positions of the keys (probably exactly the same as the physical positions as you've handwired)

Hope that helps!

Yes it helped tremendously and Tactile's example also. I've been able to correct a lot of errors.

Unfortunately I'm stuck now on another error: (I've only posted part of the output but I have the rest if this is not enough to go by. But that part didn't seem relevant for the error code to me.)

Code: [Select]
obj_gh60_lufa/common/keymap.o: In function `action_for_key':
C:\tmk_keyboard-master\keyboard\gh60/../../tmk_core/common/keymap.c:40: undefined reference to `keymap_fn_to_action'
make: *** [gh60_lufa.elf] Error 1

I can't find a file named keymap.c. I also had a look at keymap.o since it was mentioned as well but it was all garbled. So I'm kinda stuck atm. I don't have a clue what to look for now. Any thoughts?
« Last Edit: Sat, 20 August 2016, 21:59:50 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1561 on: Sun, 21 August 2016, 03:03:42 »
wall of text

Code: [Select]
keymap_common.h:43:8: error: parameter name missing
This error message tells you where the problem is - keymap_common.h, line 43, character 8 - it doesn't like you having a blank at the beginning of the line.  Comparing your file to some others there shouldn't be any blanks in that bit, and you're also missing a KC_##K00, KC_##K01, KC_##K02 bit which defines the matrix positions of the keys (probably exactly the same as the physical positions as you've handwired)

Hope that helps!

Yes it helped tremendously and Tactile's example also. I've been able to correct a lot of errors.

Unfortunately I'm stuck now on another error: (I've only posted part of the output but I have the rest if this is not enough to go by. But that part didn't seem relevant for the error code to me.)

Code: [Select]
obj_gh60_lufa/common/keymap.o: In function `action_for_key':
C:\tmk_keyboard-master\keyboard\gh60/../../tmk_core/common/keymap.c:40: undefined reference to `keymap_fn_to_action'
make: *** [gh60_lufa.elf] Error 1

I can't find a file named keymap.c. I also had a look at keymap.o since it was mentioned as well but it was all garbled. So I'm kinda stuck atm. I don't have a clue what to look for now. Any thoughts?

At the bottom of whichever file has actual letters etc assigned to keys you need a section to say what each Fn should do - have a look at any 60% for an example :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1562 on: Sun, 21 August 2016, 05:27:21 »
Ok, disregard all these ramblings below. I used the wrong makefile. I needed to use the Makefile.pjrc for the teensy. I was able to compile a proper hexfile and load it unto the Teensy. And that worked.
More
EDIT: I just read this:
Quote
LED Blinks Green or Blue
You have a counterfeit board. PJRC has never made any Teensy with a green or blue LED. If you purchased using Ebay and Paypal, we recommend you immediately begin a dispute on Paypal's website. Do not bother contacting the seller. They have already scammed many other people with defective boards, but they simply do not care. A dispute on Paypal is the only way you will recover your money. The sooner you file the dispute, the better your odds of receiving a refund. We recommend waiting to leave negative feedback until after Paypal returns your money.

https://www.pjrc.com/teensy/troubleshoot.html

Mine has a blue led. Is it fake?

Since I'm not able to program it?

----------------------------

Ok, I've successfully been able to generate a .hex file. A milestone!  :D

But.... when I try to load the hexfile on the Teensy via the Teensy loader I get this error message:  :(


Quote
Error: "gh60_lufa_hex is not compiled for this board.

Compiled for Teensy++ 2.0 (AT90USB1286)"
This board is: Teensy 2.0 (ATMEGA32U4)"

Ypu must configure and recompile for the correct board type.
To change the board configuration using a Makefile edit the MCU variable inside the Makefile.

To change the board configuration using the Arduino IDE, use the Tools -> Boards menu.

So that's what I did. I changed the MCU to ATMEGA32U4 and recompiled the hexfile. But I still get the same error code. Below the make file. What am I missing?

More
Code: [Select]
#----------------------------------------------------------------------------
# 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 = 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

EDIT2: If it's not a fake teensy: I have a Teensy 2.0 NOT the Teensy++ 2.0 so maybe I need to change more values in the Make file according to hardware differences between the two boards?

Still one problem which i guess is hardware/wired related. It 'automatically presses' 1 so I'm getting 111111111111 etc.
« Last Edit: Sun, 21 August 2016, 07:18:46 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1563 on: Sun, 21 August 2016, 09:15:00 »
Ok, here's the deal. I've been able to localize what matrix position is causing trouble by editing the keymap. It's col5, row1. Below is my keymap.

Code: [Select]
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP(6, 6,   6,   6,   9,   6,   6,  \
                    2, 2,   2,   2,   8,   2,   2,  \
                    3, 3,   3,   3,   7,   3,   3,  \
                    4, 4,   4,   4,   6,   4,   4,  \
                    5, 5,   5,   5,   5,   5,   5,  \
                    0, 1,   7,   8,   4,   1,   1),
    /* 1: ****off */
    KEYMAP(1, 1,   1,   1,   1,   1,   1,  \
                    1, 1,   1,   1,   1,   1,   1,  \
                    1, 1,   1,   1,   1,   1,   1,  \
                    1, 1,   1,   1,   1,   1,   1,  \
                    1, 1,   1,   1,   1,   1,   1,  \
                    1, 1,   1,   1,   1,   1,   1),
};

const uint16_t PROGMEM fn_actions[] = {
    /* Poker Layout */
    [0] = ACTION_LAYER_MOMENTARY(6),  // to Fn overlay
    [1] = ACTION_LAYER_TOGGLE(4),     // ****off
};

As you can see in the matrix col5, row1 outputs a 9.
As soon as I go in keyboard mode it goes 9999999999 etc. (until I disconnect the USB)

So I figured it was a hardware problem either in the matrix or with a switch so this is what I did:
1. check my soldered hardware matrix -> didn't see anything wrong
2. unsoldered the specific switch (col5, row1) and connected the usb again -> still the same problem
3. unsoldered the mirrored switch just in case I accidentally mirrored the hardware matrix and software -> still the same problem
4. unsoldered  both switches -> still the same problem
5. replaced both switches wit other ones -> still the same problem
This makes me think it's not a hardware problem in one of my matrices.

I did some more experimenting with editing the keymap_poker.c and it switches output to whatever change I make in that column. So it must be something in the programmed software.

hmm,  I compiled again and now I'm getting 987654987654 etc with the same Matrix as above. Maybe some sort of crazy function loop?

I'm at a loss (again). If someone could have a look please? would be much appreciated.
https://www.dropbox.com/sh/ssw3ltc185s1e21/AADADI6Nsg8P21V7yyIS5qDva?dl=0

EDIT: I still have doubts about the authenticity of my Teensy. I'm thinking of ordering another one.
« Last Edit: Sun, 21 August 2016, 15:34:50 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline a-c

  • Posts: 196
  • Location: USA
Re: TMK keyboard firmware
« Reply #1564 on: Sun, 21 August 2016, 19:10:21 »
Your 'teensy' is most likely a fake. Buy from one of these distributors if you want a genuine one. https://forum.pjrc.com/threads/23601-Official-Distributors

F6 is missing from your col init function.

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1565 on: Mon, 22 August 2016, 04:30:21 »
Your 'teensy' is most likely a fake. Buy from one of these distributors if you want a genuine one. https://forum.pjrc.com/threads/23601-Official-Distributors

F6 is missing from your col init function.

Thanks for your help. It's actually working now. Even fake Teensys work. Now that it works I start making a decent key lay-out.

But I did order a new one (from floris.cc) and I can get my money back on the old one. So it's all good. Now that I have 2 I need to find another project.  :)
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline rvense

  • Posts: 6
Re: TMK keyboard firmware
« Reply #1566 on: Tue, 30 August 2016, 19:30:47 »
I am trying to use TMK-on-ChibiOS as the basis for a... thing that's both a USB keyboard but also has internal functionality of sorts, so you could switch between the keystrokes going to a computer and going to some internal "applications", like a calculator, or a keylogger/note keeper, or for use as an old-fashioned dumb serial console byt adding the VGA text generator I've built in an FPGA which could attach to the FMC of an STM32...

I've etched a prototype board with a 5x6 key matrix and am using an STM32F7 board that's nicely supported by ChibiOS. I already have it running as a USB keyboard, was very impressed with how easy that was to get working. This means my "keyboard" is high-speed USB and has an Ethernet port, SD card, 8 megs of SDRAM and a 5" LCD. And of course a very nice, not particularly busy, RTOS to make use of it!

The next step for me is to modify the firmware to conditionally (based on some switch set by a button) send keystrokes either over USB or to a separate ChibiOS thread that handles... whatever else it is I want it to do.
 
I've been attempting to find the best place to do this without modifying the core of TMK too much, since I'd like to be able to get updates later on and maybe also share things back if I add/fix something that would be of more general use.

Really it looks like the best place would be making a new host driver, and have some global conditional set by a TMK action or a dedicated button decide whether to call send_keyboard from usb_main.c as normal, or send a message to my application thread with the keys.

It doesn't seem ideal, though, and whilst I generally find the code very nicely structured and easy to follow, I wonder if there's any reason why the calls to the host driver are hidden in the depths of action.c - wouldn't it be nicer if keyboard_task returned something (maybe just a pointer to the report_keyboard_t or NULL if nothing's changed) that was then passed to the driver in the main loop? I'll have to admit I haven't looked at a lot of the existing firmwares, so there might be obvious reasons why it's structured like it is, like how it works on different platforms or all the other advanced stuff this firmware does that I don't know about yet.

I know my use case is a little off from what the firmware normally does, but I wonder if there are some suggestions as to what'd be the best course of action. But having played with the firmware for a few days now I really feel like I've got a head start and a good base to build from, so thanks to all who've contributed for making this firmware.

Offline hag.com

  • Posts: 3
Re: TMK keyboard firmware
« Reply #1567 on: Wed, 31 August 2016, 00:07:01 »
Hello hasu and others!
I've (finnaly) managed to complete my custom keyboard to that point where it's alive and I can begin to design my keymap. However, I have som problems I hope you could help me with.

First, I don't use a normal keymap and would like to have special characters accessable on some keys directly without using shift or other layers. I have found the function(?) modified key which seems to be useful, but don't know how to implement it in the code to get it to work properly. I have tested inserting it in one of the keymaps in keymap_common.h, it compiles but only the last key is fired as the key is pressed.
For example, I want the key next to backspace to fire "!" on activation, but with this syntax it just works as a normal KC_1 key. (look for ACTION_MODS_KEY(MOD_LSFT, KC_1) )
More
Code: [Select]
#define KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C,      K0E,\
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E,\
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, K2E,\
    K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A,      K3C, K3D, K3E,\
    K40,   K42, K43,                K47,       K4A, K4B, K4C, K4D, K4E\
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, ACTION_MODS_KEY(MOD_LSFT, KC_1), KC_NO,    KC_##K0E }, \
    { 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_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_NO,    KC_##K2D, KC_##K2E }, \
    { 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_##K3C, KC_##K3D, KC_##K3E }, \
    { KC_##K40, KC_NO,    KC_##K42, KC_##K43, KC_NO,    KC_NO,    KC_NO,    KC_##K47, KC_NO,    KC_NO,    KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E}  \
}


Next, I would like to have other characters than the usual on that keys when shift is pressed, but have shift working as it should on the letter part of the keymap. It's possible that this is easy done with layers or something like that, that I haven't reseached very much yet. I guess I alway can make shift an FN layer button and use the action_mods_key-thing with shift key on the qwerty part although it seems like bad programming for me.  :p

Here's a picture of the keyboard so you can see what layout I seek for. I'm planning to have a keypad hidden under the qwerty-part on an fn-layer accesable via lower and only have symbols and commands on the fifth row.
More

Hope you can help me or link a page where I can read more about implementing the functions described in .../tmk_core/doc/keymap.md. :)

Offline Tactile

  • Posts: 1371
  • Location: Portland, OR
Re: TMK keyboard firmware
« Reply #1568 on: Wed, 31 August 2016, 00:23:08 »
For example, I want the key next to backspace to fire "!" on activation, but with this syntax it just works as a normal KC_1 key.

A lot of stuff you describe might be simpler in QMK. For example:

http://qmk.fm/#fun-with-modifier-keys

Offline hag.com

  • Posts: 3
Re: TMK keyboard firmware
« Reply #1569 on: Fri, 02 September 2016, 15:56:55 »
For example, I want the key next to backspace to fire "!" on activation, but with this syntax it just works as a normal KC_1 key.

A lot of stuff you describe might be simpler in QMK. For example:

http://qmk.fm/#fun-with-modifier-keys

Hm, yes, it looks quite easy to use. Thanks for the hint.
But now I have worked quite a while on getting TMK to work for my layout and would be glad if I could use it. It's even described in the documentations so it must be possible, I just can't find how to implement it.

Offline Tactile

  • Posts: 1371
  • Location: Portland, OR
Re: TMK keyboard firmware
« Reply #1570 on: Fri, 02 September 2016, 17:26:41 »
For example, I want the key next to backspace to fire "!" on activation, but with this syntax it just works as a normal KC_1 key.

A lot of stuff you describe might be simpler in QMK. For example:

http://qmk.fm/#fun-with-modifier-keys
Hm, yes, it looks quite easy to use. Thanks for the hint.
But now I have worked quite a while on getting TMK to work for my layout and would be glad if I could use it. It's even described in the documentations so it must be possible, I just can't find how to implement it.


This code isn't commented but here's how one guy did it...

https://github.com/matthewjf/tmk_firmware/blob/master/keyboard/gh60/keymap_poker_deprecated.c

« Last Edit: Fri, 02 September 2016, 21:30:35 by Tactile »

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1571 on: Tue, 06 September 2016, 09:44:56 »
I am trying to extend the number of keycodes that can be sent via the NKRO report for LUFA. It currently has a report size of 16 bytes, which can support 120 keys and 8 mods.

(Note that KEYBOARD_REPORT_BITS = 16-1.)

Code: [Select]
static inline void add_key_bit(uint8_t code)
{
    if ((code>>3) < KEYBOARD_REPORT_BITS) {
        keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
    } else {
        dprintf("add_key_bit: can't add: %02X\n", code);
    }
}

This prevents keys such as the language and international keys from being sent in NKRO mode. I did some experimentation and found I could change the size of the report from 16 to 32 bytes and get all the keys (but in reality, it only needs to be 21 bytes to hit all keycodes up to 0xA4 / KC_EXSEL).

Can someone tell me the ramifications of doing this?

Also... If I want to send more than the standard 104 keys plus F13-F24 to the host Windows PC, how should I handle it? add_key/del_key/send_keyboard_report? I want to do this to extend the number of keys that AutoHotkey can detect. It has support for virtual keys/scancodes.

Offline Tactile

  • Posts: 1371
  • Location: Portland, OR
Re: TMK keyboard firmware
« Reply #1572 on: Tue, 06 September 2016, 09:53:24 »
I am trying to extend the number of keycodes that can be sent via the NKRO report for LUFA. It currently has a report size of 16 bytes, which can support 120 keys and 8 mods.

...

Also... If I want to send more than the standard 104 keys plus F13-F24 to the host Windows PC, how should I handle it? add_key/del_key/send_keyboard_report? I want to do this to extend the number of keys that AutoHotkey can detect. It has support for virtual keys/scancodes.

I can't answer your questions, but have you read this?

https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/doc/USB_NKRO.txt

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1573 on: Tue, 06 September 2016, 09:58:57 »

I can't answer your questions, but have you read this?

https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/doc/USB_NKRO.txt

Thanks. That confirms that I was on the right path, but it isn't clear if the 32 byte report had a realistic downside.

EDIT: Also, a 32 byte report will only represent 248 keys and 8 mod keys. The distinction is critical because this means that keycodes F8 to FF will not be sent.
« Last Edit: Tue, 06 September 2016, 11:40:28 by IBNobody »

Offline hasu

  • Thread Starter
  • Posts: 3321
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #1574 on: Tue, 06 September 2016, 12:52:45 »
1

I can't answer your questions, but have you read this?

https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/doc/USB_NKRO.txt

Thanks. That confirms that I was on the right path, but it isn't clear if the 32 byte report had a realistic downside.

EDIT: Also, a 32 byte report will only represent 248 keys and 8 mod keys. The distinction is critical because this means that keycodes F8 to FF will not be sent.

Just efficiency of memory usage and report seding but these will be negligible probably. I prefer 32 byte size for simplicity than saving some bytes.

And with 32 byte report you will be able to use simple report descriptor to send 0x00-FF. But we have to test it.

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1575 on: Tue, 06 September 2016, 14:55:51 »
Just efficiency of memory usage and report seding but these will be negligible probably. I prefer 32 byte size for simplicity than saving some bytes.

And with 32 byte report you will be able to use simple report descriptor to send 0x00-FF. But we have to test it.

Do you mean sending 0x00-0xFF instead of sending 0x80-0x87 and 0x00-0xF7?

Offline Meepsi

  • Posts: 2
Re: TMK keyboard firmware
« Reply #1576 on: Tue, 06 September 2016, 17:55:14 »
Hey guys, long time lurker, first time writer.

So I've been working on a hand wired keyboard for a little while now and have finally finished the physical aspects of the work (mostly). I'm looking to get this Teensy 2.0 flashed with the settings I want but I am a complete moron when it comes to programming. I've spent the last couple nights looking into how to set up a keymap, and have even found a couple really good examples, but alas, it seems I am an idiot and cannot seem to get this right.

I am wondering if someone might be willing to hold my hand and help me get this keyboard up and running. Thanks in advance for any help to come!

Some background on the project:
I found an old Amiga 2000 Space Invader keyboard in a recycling bin at work. I of course could not allow such a travesty to befall such a specimen. It was missing a few keycaps and had a damaged cord, but was otherwise in a fairly decent condition. Failing to find any replacement keycaps for the missing keys, I did what and sensible person would do and got the Dremel (first I removed the case, PCB, and key switches; I'm not a monster). I cut away the function key row and the numpad. Now I have a tenkeyless board with an arrow cluster. Everything is wired up and ready to go (sans the caps LED; I'll come back to that once I get this baby working).

Pictures of the build so far:



So this is where I'm stuck...
This is how the board is wired:


And this is the key map I am attempting to get working:


What should code for this look like?
Thanks guys!

Offline hasu

  • Thread Starter
  • Posts: 3321
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #1577 on: Tue, 06 September 2016, 19:43:04 »
Just efficiency of memory usage and report seding but these will be negligible probably. I prefer 32 byte size for simplicity than saving some bytes.

And with 32 byte report you will be able to use simple report descriptor to send 0x00-FF. But we have to test it.

Do you mean sending 0x00-0xFF instead of sending 0x80-0x87 and 0x00-0xF7?

Yes, it looks like a commit below. But it requires some more changes on existent codes to .
https://github.com/tmk/tmk_keyboard/commit/622f3424045ac4f9d7e2e75a57de25814db00768

I think just changing of NKRO_EPSIZE to 32 is enough for a while, you can't send 0xF8-FF with this but who cares.

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1578 on: Tue, 06 September 2016, 20:50:06 »
Yes, it looks like a commit below. But it requires some more changes on existent codes to .
https://github.com/tmk/tmk_keyboard/commit/622f3424045ac4f9d7e2e75a57de25814db00768

I think just changing of NKRO_EPSIZE to 32 is enough for a while, you can't send 0xF8-FF with this but who cares.

That is what I thought. You are right. It would require extra work. keyboard_report->mods would need to change. That is more work to implement with no real benefit.

I will be happy with my INT1-6 and LANG1-5 keycodes and NKRO. Thank you!

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1579 on: Wed, 07 September 2016, 02:51:42 »
I'm stuck once again. I'm in QMK but I believe this part is the same as TMK? If not than this would be my actual problem.  ;)

Anyhow, the code below enables me to (temporary) access layer 1 with FN0. But I can't for the life of me figure out how to access layer 2.  I experimented myself, looked at other peoples code and I've read all instructions and everything else I could find on the web but I guess I just don't understand. So if anyone could help me out it would be much appreciated.

Silly thing is when I pres the FN2 key

Code: [Select]
#include "GH30.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
      KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC, \
      KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_DEL, \
      KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_ENT, \
      KC_NO, KC_NO, KC_NO, KC_T, KC_E, KC_I, KC_TRNS, \
      KC_NO, KC_RIGHT, KC_NO, KC_D, KC_A, KC_R, KC_SPACE, \
      KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO \),
   
[1] = KEYMAP(  /* 1: fn */
      KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_BSPACE, \
      KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_TAB, \
      KC_TRNS, KC_HOME, KC_TRNS, KC_U, KC_G, KC_P, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_H, KC_L, KC_K, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_B, KC_V, KC_M, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),

[2] = KEYMAP( /* 2: fn */
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AT, KC_PERC, KC_HASH, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AMPR, KC_LCBR, KC_PIPE, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Y, KC_J, KC_LABK, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_C, KC_W, KC_F, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Q, KC_N, KC_X, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),
};

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

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
          if (record->event.pressed) {
            register_code(KC_RSFT);
          } else {
            unregister_code(KC_RSFT);
          }
        break;
      }
    return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1580 on: Wed, 07 September 2016, 03:06:33 »
I'm stuck once again. I'm in QMK but I believe this part is the same as TMK? If not than this would be my actual problem.  ;)

Anyhow, the code below enables me to (temporary) access layer 1 with FN0. But I can't for the life of me figure out how to access layer 2.  I experimented myself, looked at other peoples code and I've read all instructions and everything else I could find on the web but I guess I just don't understand. So if anyone could help me out it would be much appreciated.

Silly thing is when I pres the FN2 key

Code: [Select]
#include "GH30.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
      KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC, \
      KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_DEL, \
      KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_ENT, \
      KC_NO, KC_NO, KC_NO, KC_T, KC_E, KC_I, KC_TRNS, \
      KC_NO, KC_RIGHT, KC_NO, KC_D, KC_A, KC_R, KC_SPACE, \
      KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO \),
   
[1] = KEYMAP(  /* 1: fn */
      KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_BSPACE, \
      KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_TAB, \
      KC_TRNS, KC_HOME, KC_TRNS, KC_U, KC_G, KC_P, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_H, KC_L, KC_K, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_B, KC_V, KC_M, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),

[2] = KEYMAP( /* 2: fn */
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AT, KC_PERC, KC_HASH, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AMPR, KC_LCBR, KC_PIPE, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Y, KC_J, KC_LABK, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_C, KC_W, KC_F, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Q, KC_N, KC_X, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),
};

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

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
          if (record->event.pressed) {
            register_code(KC_RSFT);
          } else {
            unregister_code(KC_RSFT);
          }
        break;
      }
    return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}

Below the keymaps you have an fn_actions section, you need a line in there starting [1] and ending (2), assuming you want to use FN2 in the same way as FN :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1581 on: Wed, 07 September 2016, 03:35:58 »
I'm stuck once again. I'm in QMK but I believe this part is the same as TMK? If not than this would be my actual problem.  ;)

Anyhow, the code below enables me to (temporary) access layer 1 with FN0. But I can't for the life of me figure out how to access layer 2.  I experimented myself, looked at other peoples code and I've read all instructions and everything else I could find on the web but I guess I just don't understand. So if anyone could help me out it would be much appreciated.

Silly thing is when I pres the FN2 key

Code: [Select]
#include "GH30.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
      KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC, \
      KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_DEL, \
      KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_ENT, \
      KC_NO, KC_NO, KC_NO, KC_T, KC_E, KC_I, KC_TRNS, \
      KC_NO, KC_RIGHT, KC_NO, KC_D, KC_A, KC_R, KC_SPACE, \
      KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO \),
   
[1] = KEYMAP(  /* 1: fn */
      KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_BSPACE, \
      KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_TAB, \
      KC_TRNS, KC_HOME, KC_TRNS, KC_U, KC_G, KC_P, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_H, KC_L, KC_K, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_B, KC_V, KC_M, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),

[2] = KEYMAP( /* 2: fn */
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AT, KC_PERC, KC_HASH, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AMPR, KC_LCBR, KC_PIPE, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Y, KC_J, KC_LABK, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_C, KC_W, KC_F, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Q, KC_N, KC_X, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),
};

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

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
          if (record->event.pressed) {
            register_code(KC_RSFT);
          } else {
            unregister_code(KC_RSFT);
          }
        break;
      }
    return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}

Below the keymaps you have an fn_actions section, you need a line in there starting [1] and ending (2), assuming you want to use FN2 in the same way as FN :)

Thanks for your reply once again. That's actually what I've been doing (tried out different values as well) but then I get this error message when compiling:

Code: [Select]
Compiling: keyboards/gh30/keymaps/default/keymap.c                                                 keyboards/gh30/keymaps/default/keymap.c:37: error: subscripted value is neither array nor pointer
 [ERRORS]
 |
 |
 |
make[1]: *** [.build/obj_gh30_default/keyboards/gh30/keymaps/default/keymap.o] Error 1
Make finished with errors
make: *** [default] Error 1

If I load the hex with teensy anyway but when I press that FN key I get an 'windows background sound'.
And I just found out that when I'm in Firefox it does bookmarks shortcut (either Ctrl + B or Ctrl + I) when I press it.

EDIT:
I'm a step further. When I add , behind every line I don't get compile errors anymore but FN2 still does not work.
« Last Edit: Wed, 07 September 2016, 04:39:00 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1582 on: Wed, 07 September 2016, 06:27:57 »
I'm stuck once again. I'm in QMK but I believe this part is the same as TMK? If not than this would be my actual problem.  ;)

Anyhow, the code below enables me to (temporary) access layer 1 with FN0. But I can't for the life of me figure out how to access layer 2.  I experimented myself, looked at other peoples code and I've read all instructions and everything else I could find on the web but I guess I just don't understand. So if anyone could help me out it would be much appreciated.

Silly thing is when I pres the FN2 key

Code: [Select]
#include "GH30.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
      KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC, \
      KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_DEL, \
      KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_ENT, \
      KC_NO, KC_NO, KC_NO, KC_T, KC_E, KC_I, KC_TRNS, \
      KC_NO, KC_RIGHT, KC_NO, KC_D, KC_A, KC_R, KC_SPACE, \
      KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO \),
   
[1] = KEYMAP(  /* 1: fn */
      KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_BSPACE, \
      KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_TAB, \
      KC_TRNS, KC_HOME, KC_TRNS, KC_U, KC_G, KC_P, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_H, KC_L, KC_K, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_B, KC_V, KC_M, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),

[2] = KEYMAP( /* 2: fn */
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AT, KC_PERC, KC_HASH, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AMPR, KC_LCBR, KC_PIPE, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Y, KC_J, KC_LABK, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_C, KC_W, KC_F, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Q, KC_N, KC_X, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),
};

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

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
          if (record->event.pressed) {
            register_code(KC_RSFT);
          } else {
            unregister_code(KC_RSFT);
          }
        break;
      }
    return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}

Below the keymaps you have an fn_actions section, you need a line in there starting [1] and ending (2), assuming you want to use FN2 in the same way as FN :)


After a lot of trial and error I  ended up with:

Code: [Select]
[1] = ACTION_LAYER_MOMENTARY(1),
[0] = ACTION_LAYER_MOMENTARY(2),

But I only got it to work by swapping the FN0 key and the FN1 key in the base keymap.

So:              " KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN1, KC_FN0, KC_NO"
instead of:   "KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO"  as intended

So I actually have no insight why it works like this. :-[

And now it doesnt work at all any more. only D's. I quit for the day.
its a hardware problem apparently

« Last Edit: Wed, 07 September 2016, 06:58:21 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1583 on: Wed, 07 September 2016, 14:49:48 »
Hey guys, long time lurker, first time writer.

So I've been working on a hand wired keyboard for a little while now and have finally finished the physical aspects of the work (mostly). I'm looking to get this Teensy 2.0 flashed with the settings I want but I am a complete moron when it comes to programming. I've spent the last couple nights looking into how to set up a keymap, and have even found a couple really good examples, but alas, it seems I am an idiot and cannot seem to get this right.

I am wondering if someone might be willing to hold my hand and help me get this keyboard up and running. Thanks in advance for any help to come!

If you go ahead and fill out one of these spreadsheets, and let me know what pin assignments you used, I will use them to set up a QMK or TMK keyboard for you.


Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1584 on: Wed, 07 September 2016, 15:18:34 »
More
I'm stuck once again. I'm in QMK but I believe this part is the same as TMK? If not than this would be my actual problem.  ;)

Anyhow, the code below enables me to (temporary) access layer 1 with FN0. But I can't for the life of me figure out how to access layer 2.  I experimented myself, looked at other peoples code and I've read all instructions and everything else I could find on the web but I guess I just don't understand. So if anyone could help me out it would be much appreciated.

Silly thing is when I pres the FN2 key

Code: [Select]
#include "GH30.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
      KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC, \
      KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_DEL, \
      KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_ENT, \
      KC_NO, KC_NO, KC_NO, KC_T, KC_E, KC_I, KC_TRNS, \
      KC_NO, KC_RIGHT, KC_NO, KC_D, KC_A, KC_R, KC_SPACE, \
      KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO \),
   
[1] = KEYMAP(  /* 1: fn */
      KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_BSPACE, \
      KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_TAB, \
      KC_TRNS, KC_HOME, KC_TRNS, KC_U, KC_G, KC_P, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_H, KC_L, KC_K, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_B, KC_V, KC_M, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),

[2] = KEYMAP( /* 2: fn */
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AT, KC_PERC, KC_HASH, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_AMPR, KC_LCBR, KC_PIPE, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Y, KC_J, KC_LABK, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_C, KC_W, KC_F, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_Q, KC_N, KC_X, KC_TRNS, \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \),
};

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

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
          if (record->event.pressed) {
            register_code(KC_RSFT);
          } else {
            unregister_code(KC_RSFT);
          }
        break;
      }
    return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}

Below the keymaps you have an fn_actions section, you need a line in there starting [1] and ending (2), assuming you want to use FN2 in the same way as FN :)


After a lot of trial and error I  ended up with:

Code: [Select]
[1] = ACTION_LAYER_MOMENTARY(1),
[0] = ACTION_LAYER_MOMENTARY(2),

But I only got it to work by swapping the FN0 key and the FN1 key in the base keymap.

So:              " KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN1, KC_FN0, KC_NO"
instead of:   "KC_UP, KC_LEFT, KC_DOWN, KC_NO, KC_FN0, KC_FN1, KC_NO"  as intended

So I actually have no insight why it works like this. :-[

And now it doesnt work at all any more. only D's. I quit for the day.
its a hardware problem apparently


Ok, had a look on a big screen and not looking for the easy answer.

You have
Code: [Select]
[0] =
[1] =
etc before each KEYMAP( which I've never noticed in TMK and I just looked in QMK and can't see any there either.  As usual don't ask me what this means or does, I'm just playing spot the difference :))
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1585 on: Wed, 07 September 2016, 15:27:16 »
Ok, had a look on a big screen and not looking for the easy answer.

You have
Code: [Select]
[0] =
[1] =
etc before each KEYMAP( which I've never noticed in TMK and I just looked in QMK and can't see any there either.  As usual don't ask me what this means or does, I'm just playing spot the difference :))

Those define the layer and should be the same in TMK and QMK.

Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1586 on: Wed, 07 September 2016, 15:32:34 »
Ok, had a look on a big screen and not looking for the easy answer.

You have
Code: [Select]
[0] =
[1] =
etc before each KEYMAP( which I've never noticed in TMK and I just looked in QMK and can't see any there either.  As usual don't ask me what this means or does, I'm just playing spot the difference :))

Those define the layer and should be the same in TMK and QMK.

I see none here where there are two FNs and 3 layers?  Then again, all the keys don't start KC_ either so maybe it's not the same file...

I really should learn this stuff if you have time to explain what I'm missing that would be great :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1587 on: Wed, 07 September 2016, 16:14:41 »
I see none here where there are two FNs and 3 layers?  Then again, all the keys don't start KC_ either so maybe it's not the same file...

I really should learn this stuff if you have time to explain what I'm missing that would be great :)

They are optional and are just used for convenience or to errorproof your code.

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/retro_refit/keymaps/default/keymap.c

Online suicidal_orange

  • * Global Moderator
  • Posts: 4401
  • Location: England
Re: TMK keyboard firmware
« Reply #1588 on: Wed, 07 September 2016, 17:12:22 »
I see none here where there are two FNs and 3 layers?  Then again, all the keys don't start KC_ either so maybe it's not the same file...

I really should learn this stuff if you have time to explain what I'm missing that would be great :)

They are optional and are just used for convenience or to errorproof your code.

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/retro_refit/keymaps/default/keymap.c

Thanks, would never have guessed that!
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Meepsi

  • Posts: 2
Re: TMK keyboard firmware
« Reply #1589 on: Wed, 07 September 2016, 18:36:08 »
Hey guys, long time lurker, first time writer.

So I've been working on a hand wired keyboard for a little while now and have finally finished the physical aspects of the work (mostly). I'm looking to get this Teensy 2.0 flashed with the settings I want but I am a complete moron when it comes to programming. I've spent the last couple nights looking into how to set up a keymap, and have even found a couple really good examples, but alas, it seems I am an idiot and cannot seem to get this right.

I am wondering if someone might be willing to hold my hand and help me get this keyboard up and running. Thanks in advance for any help to come!

If you go ahead and fill out one of these spreadsheets, and let me know what pin assignments you used, I will use them to set up a QMK or TMK keyboard for you.

So apparently I have a Teensy-LC not a Teensy 2.0 I don't think this should be a problem though.
Pin reference:


ROW 0 - PIN 0
ROW 1 - PIN 1
ROW 2 - PIN 2
ROW 3 - PIN 3
ROW 4 - PIN 4

COL 0 - PIN 5
COL 1 - PIN 6
COL 2 - PIN 7
COL 3 - PIN 8
COL 4 - PIN 9
COL 5 - PIN 10
COL 6 - PIN 11
COL 7 - PIN 12
COL 8 - PIN 13
COL 9 - PIN 14
COL 10 - PIN 15
COL 11 - PIN 16
COL 12 - PIN 17
COL 13 - PIN 18
COL 14 - PIN 19
COL 15 - PIN 20
COL 16 - PIN 21
COL 17 - PIN 22

As for the spreadsheet you linked me, my keymap didn't fit in there, so I filled what I could and hand entered the rest. I hope this is what you were looking for. If not let me know and I'll try again.
Code: [Select]
/* LAYER = PRIMARY
  .-----------------------------------------------------------------------------------------------------------------------------------------------------------------.
  | GRV    | 1      | 2      | 3      | 4      | 5      | 6      | 7      | 8      | 9      | 0      | MINS   | EQL    | BSLS   | BSPC   | DEL    |        | F5     |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  | TAB    |        | Q      | W      | E      | R      | T      | Y      | U      | I      | O      | P      | LBRC   | RBRC   |        |        |        |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  | LCTR   | CAPS   | A      | S      | D      | F      | G      | H      | J      | K      | L      | SCLN   | QUOT   |        | ENT    |        | UP     |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        | LSFT   |        | Z      | X      | C      | V      | B      | N      | M      | COMM   | DOT    | SLSH   |        | RSFT   | LEFT   | DOWN   | RGHT   |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        | LALT   | LGUI   |        |        |        |        | SPC    |        |        |        |        |        | FN0    | RALT   |        |        |        |
  '-----------------------------------------------------------------------------------------------------------------------------------------------------------------'
*/
[LAYER_PRIMARY] = {
  { GRV    , 1      , 2      , 3      , 4      , 5      , 6      , 7      , 8      , 9      , 0      , MINS   , EQL    , BSLS   , BSPC   , DEL    ,        , F5     },
  { TAB    ,        , Q      , W      , E      , R      , T      , Y      , U      , I      , O      , P      , LBRC   , RBRC   ,        ,        ,        ,        },
  { LCTR   , CAPS   , A      , S      , D      , F      , G      , H      , J      , K      , L      , SCLN   , QUOT   ,        , ENT    ,        ,        ,        },
  {        , LSFT   ,        , Z      , X      , C      , V      , B      , N      , M      , COMM   , DOT    , SLSH   ,        , RSFT   ,        ,        ,        },
  {        , LALT   , LGUI   ,        ,        ,        ,        , SPC    ,        ,        ,        ,        ,        , FN0    , RALT   ,        ,        ,        }
},
/* LAYER = FN0
  .-----------------------------------------------------------------------------------------------------------------------------------------------------------------.
  | ESC    | F1     | F2     | F3     | F4     | F5     | F6     | F7     | F8     | F9     | F10    | F11    | F12    |        |        |        |        |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        | PGUP   |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        | PGDN   |        |
  |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
  |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |        |
  '-----------------------------------------------------------------------------------------------------------------------------------------------------------------'
*/
[LAYER_FN0] = {
  { ESC    , F1     , F2     , F3     , F4     , F5     , F6     , F7     , F8     , F9     , F10    , F11    , F12    ,        ,        ,        ,        ,        },
  {        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        },
  {        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        , PGUP   ,        },
  {        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        , PGDN   ,        },
  {        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        ,        }
},

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1590 on: Wed, 07 September 2016, 20:05:54 »
So.... The good news is that half of your code is complete. The bad news is that... Having a Teensy LC makes things harder. It is because the LC has an ARM processor and the 2.0 has an AVR processor. I have not done any work using ARMs and cannot say which are supported via ChibiOS. No promises... I'll try. :)

EDIT: And... No... Sorry. There is ChibiOS support, but I didn't see a fully functional keyboard in the QMK repo for it with a full layout. I don't think I am your guy. If it were an AVR, it would be no sweat.
« Last Edit: Wed, 07 September 2016, 20:12:57 by IBNobody »

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1591 on: Thu, 08 September 2016, 03:23:11 »
Ok, had a look on a big screen and not looking for the easy answer.

You have
Code: [Select]
[0] =
[1] =
etc before each KEYMAP( which I've never noticed in TMK and I just looked in QMK and can't see any there either.  As usual don't ask me what this means or does, I'm just playing spot the difference :))

Those define the layer and should be the same in TMK and QMK.

I see none here where there are two FNs and 3 layers?  Then again, all the keys don't start KC_ either so maybe it's not the same file...

I really should learn this stuff if you have time to explain what I'm missing that would be great :)

I'm getting rid of the KC_'s since they're not necessary. Less chance of mistakes when editing. Hmm, apparently I can remove them from numbers but not from special symbols like underscore (KC_UNDS) or letters.

I see none here where there are two FNs and 3 layers?  Then again, all the keys don't start KC_ either so maybe it's not the same file...

I really should learn this stuff if you have time to explain what I'm missing that would be great :)

They are optional and are just used for convenience or to errorproof your code.

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/retro_refit/keymaps/default/keymap.c

I can't remember where I got the example from but in the example in the link you post they are part of the comment, not the code like in my keymap. I removed them and it still works. but theres also this line
Code: [Select]
#include "action_layer.h" which I didn't have. I added it and there's no error code when compiling.

Or have my 'problems' something to do with the fact that I use cygdrive and not mingw? For QMK MinGw and MHV-AVR_Tools were advised but I couldn't get them to install properly.
« Last Edit: Thu, 08 September 2016, 03:27:25 by Dwarlorf »
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1592 on: Thu, 08 September 2016, 07:38:17 »
I'm getting rid of the KC_'s since they're not necessary. Less chance of mistakes when editing. Hmm, apparently I can remove them from numbers but not from special symbols like underscore (KC_UNDS) or letters.

If you use a KEYMAP macro, you can get rid of KC_ because the KEYMAP macro adds them in. I prefer not to use KEYMAP macros that do this because with QMK, you have more options for keycodes that do not start with KC_.


I can't remember where I got the example from but in the example in the link you post they are part of the comment, not the code like in my keymap. I removed them and it still works. but theres also this line
Code: [Select]
#include "action_layer.h" which I didn't have. I added it and there's no error code when compiling.

Or have my 'problems' something to do with the fact that I use cygdrive and not mingw? For QMK MinGw and MHV-AVR_Tools were advised but I couldn't get them to install properly.

Haha, don't use my example to debug your momentary layer issue. I do not use momentary layers on that keyboard.

When I do use momentary layers, I do it via macros. They give me better control over what is happening and let me do things like flash my backlight, play a chiptune, or do some fairly complicated layer shifting. For example...

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/planck/keymaps/pvc/keymap.c

Code: [Select]
        case MACRO_UPPER:
            if (record->event.pressed)
            {
                layer_on(LAYER_UPPER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_UPPER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

        case MACRO_LOWER:
            if (record->event.pressed)
            {
                layer_on(LAYER_LOWER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_LOWER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

If I hold UPPER, I get the upper layer. If I hold LOWER, I get the LOWER layer. If I hold UPPER and then LOWER or LOWER and then UPPER, I get the ADJUST layer.

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1593 on: Thu, 08 September 2016, 19:02:43 »
I'm getting rid of the KC_'s since they're not necessary. Less chance of mistakes when editing. Hmm, apparently I can remove them from numbers but not from special symbols like underscore (KC_UNDS) or letters.

If you use a KEYMAP macro, you can get rid of KC_ because the KEYMAP macro adds them in. I prefer not to use KEYMAP macros that do this because with QMK, you have more options for keycodes that do not start with KC_.


I can't remember where I got the example from but in the example in the link you post they are part of the comment, not the code like in my keymap. I removed them and it still works. but theres also this line
Code: [Select]
#include "action_layer.h" which I didn't have. I added it and there's no error code when compiling.

Or have my 'problems' something to do with the fact that I use cygdrive and not mingw? For QMK MinGw and MHV-AVR_Tools were advised but I couldn't get them to install properly.

Haha, don't use my example to debug your momentary layer issue. I do not use momentary layers on that keyboard.

When I do use momentary layers, I do it via macros. They give me better control over what is happening and let me do things like flash my backlight, play a chiptune, or do some fairly complicated layer shifting. For example...

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/planck/keymaps/pvc/keymap.c

Code: [Select]
        case MACRO_UPPER:
            if (record->event.pressed)
            {
                layer_on(LAYER_UPPER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_UPPER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

        case MACRO_LOWER:
            if (record->event.pressed)
            {
                layer_on(LAYER_LOWER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_LOWER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

If I hold UPPER, I get the upper layer. If I hold LOWER, I get the LOWER layer. If I hold UPPER and then LOWER or LOWER and then UPPER, I get the ADJUST layer.

Hmm, that macro system is actually fairly clear and understandable. If I understand correctly I also need to use Macros for Tap Dance and Timer functionality so your example seems very useful for me. I'll delve into it some more.

Thanks for your help so far. I will probably return with more questions in the future .  :D
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline IBNobody

  • Posts: 113
Re: TMK keyboard firmware
« Reply #1594 on: Sun, 11 September 2016, 22:43:59 »
I am working on a way to send HID messages to AutoHotkey. (See this post...) It is the same principle as hid_listen.

In TMK, where is the best place for me to add print statements to output the pressed key / scancode to the HID message output?

What if I wanted to do the reverse and send data to the keyboard? Is that even implemented yet?

Offline eeymiel

  • Posts: 30
  • Location: NL
Re: TMK keyboard firmware
« Reply #1595 on: Mon, 12 September 2016, 00:48:54 »
What if I wanted to do the reverse and send data to the keyboard? Is that even implemented yet?
Would be cool if we could select the layer in software.For example I want to use a different layer in Windows vs Linux.
« Last Edit: Mon, 12 September 2016, 00:52:55 by eeymiel »

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1596 on: Tue, 13 September 2016, 05:00:43 »

When I do use momentary layers, I do it via macros. They give me better control over what is happening and let me do things like flash my backlight, play a chiptune, or do some fairly complicated layer shifting. For example...

https://github.com/jackhumbert/qmk_firmware/blob/master/keyboards/planck/keymaps/pvc/keymap.c

Code: [Select]
        case MACRO_UPPER:
            if (record->event.pressed)
            {
                layer_on(LAYER_UPPER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_UPPER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

        case MACRO_LOWER:
            if (record->event.pressed)
            {
                layer_on(LAYER_LOWER);
                breathing_speed_set(2);
                breathing_pulse();
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            else
            {
                layer_off(LAYER_LOWER);
                update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST);
            }
            break;

If I hold UPPER, I get the upper layer. If I hold LOWER, I get the LOWER layer. If I hold UPPER and then LOWER or LOWER and then UPPER, I get the ADJUST layer.

I've actually managed to make it work for my situation. I now have the basic three layers working.

More
Code: [Select]
#include "GH30.h"

enum keyboard_layers {
  LAYER_ONE = 0,
  LAYER_TWO,
  LAYER_THREE,
};

enum keyboard_macros {
  MACRO_ONE = 0,
  MACRO_TWO,
  MACRO_THREE,
};

#define M_ONE                   M(MACRO_ONE)
#define M_TWO                  M(MACRO_TWO)
#define M_THREE              M(MACRO_THREE)
#define M_FUNCT              M(MACRO_FUNCTION)

#define _______             KC_TRNS
#define XXXXXXX             KC_NO
#define ________________    _______, _______
#define XXXXXXXXXXXXXXXX    XXXXXXX, XXXXXXX

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* LAYER = LAYER_ONE
add visual lay out here
*/

[LAYER_ONE] = {
      { KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC },
      { KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_ENT },
      { KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_SPACE },
      { XXXXXXX, XXXXXXX , XXXXXXX , KC_T, KC_E, KC_I, KC_TRNS },
      { XXXXXXX, KC_RIGHT, XXXXXXX, KC_D, KC_A, KC_R, KC_DEL},
      { KC_UP, KC_LEFT, KC_DOWN, XXXXXXX, M_TWO, M_THREE, XXXXXXX  }
},   

/* LAYER = LAYER_TWO
add visual lay out here
*/

[LAYER_TWO] = {
     { KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_ESC },
     { KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_RCTL },
     { _______, KC_HOME, _______, KC_U, KC_G, KC_P, _______  },
     { _______, _______, _______, KC_H, KC_L, KC_K, _______  },
     { _______, _______, _______, KC_B, KC_V, KC_M, _______  },
     { _______, _______, _______, _______, _______, _______, _______  }
},

/* LAYER = LAYER_THREE
add visual lay out here
*/

[LAYER_THREE] = {
      { _______, _______, _______, KC_AT, KC_PERC, KC_HASH, _______ },
      { _______, _______, _______, KC_AMPR, KC_LCBR, KC_PIPE, _______ },
      { _______, _______, _______, KC_Y, KC_J, KC_LABK, _______ },
      { _______, _______, _______, KC_C, KC_W, KC_F, _______ },
      { _______, _______, _______, KC_Q, KC_Z, KC_X, _______ },
      { _______, _______, _______, _______, _______, _______, _______ }
},

};

/* toevoegen:
TOGGLE FUNCTIE VOOR ENTER EN SPACE
LONGPRESS NUMMER VOOR FTOETS
LONGPRESS VOOR OPPOSITES
*/

void persistant_default_layer_set(uint16_t default_layer)
{
    eeconfig_update_default_layer(default_layer);
    default_layer_set(default_layer);
}

const uint16_t PROGMEM fn_actions[] = {

};

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
 switch(id)
     {
     case MACRO_ONE:
            if (record->event.pressed)
            {
                persistant_default_layer_set(1UL<<LAYER_ONE);
            }
            break;

      case MACRO_TWO:
            if (record->event.pressed)
            {
                layer_on(LAYER_TWO);
            }
            else
            {
                layer_off(LAYER_TWO);
            }
            break;

       case MACRO_THREE:
            if (record->event.pressed)
            {
                layer_on(LAYER_THREE);
            }
            else
            {
               layer_off(LAYER_THREE);
            }
            break;
      }       
     
      return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}


And now I'm trying to put in the QMK timer function but I'm struggling. I want a long press of keys to result in their upper case variants.
These are the error messages:
Quote
Compiling: keyboards/gh30/keymaps/default/keymap.c 
keyboards/gh30/keymaps/default/keymap.c: In function 'action_get_macro':
keyboards/gh30/keymaps/default/keymap.c:91: error: expected expression before '=' token
keyboards/gh30/keymaps/default/keymap.c:95: error: too few arguments to function 'timer_elapsed'
keyboards/gh30/keymaps/default/keymap.c:96: error: expected expression before ',' token
keyboards/gh30/keymaps/default/keymap.c:147: error: expected declaration or statement at end of input
My problem is that I kinda understand what type of errors they are but don't know where to look/what to look for. This is what I have so far:
Code: [Select]
#include "GH30.h"

enum keyboard_layers {
  LAYER_ONE = 0,
  LAYER_TWO,
  LAYER_THREE,
};

enum keyboard_macros {
  MACRO_ONE = 0,
  MACRO_TWO,
  MACRO_THREE,
};

#define M_ONE                   M(MACRO_ONE)
#define M_TWO                  M(MACRO_TWO)
#define M_THREE              M(MACRO_THREE)
#define key_timer

#define _______             KC_TRNS
#define XXXXXXX             KC_NO
#define ________________    _______, _______
#define XXXXXXXXXXXXXXXX    XXXXXXX, XXXXXXX

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* LAYER = LAYER_ONE
add visual lay out here
*/

[LAYER_ONE] = {
      { KC_9, KC_6, KC_3, KC_0, KC_UNDS, KC_ASTR, KC_BSPC },
      { KC_8, KC_5, KC_2, KC_SCOLON, KC_LPRN, KC_DOT, KC_ENT },
      { KC_7, KC_4, KC_1, KC_O, KC_N, KC_S, KC_SPACE },
      { XXXXXXX, XXXXXXX , XXXXXXX , KC_T, KC_E, KC_I, KC_TRNS },
      { XXXXXXX, KC_RIGHT, XXXXXXX, KC_D, KC_A, KC_R, KC_DEL},
      { KC_UP, KC_LEFT, KC_DOWN, XXXXXXX, M_TWO, M_THREE, XXXXXXX  }
},   

/* LAYER = LAYER_TWO
add visual lay out here
*/

[LAYER_TWO] = {
     { KC_TRNS, KC_END, KC_PSCREEN, KC_PLUS, KC_EQUAL, KC_DLR, KC_ESC },
     { KC_PGUP, KC_TRNS, KC_PGDOWN, KC_EXLM, KC_LBRC, KC_BSLASH, KC_RCTL },
     { _______, KC_HOME, _______, KC_U, KC_G, KC_P, _______  },
     { _______, _______, _______, KC_H, KC_L, KC_K, _______  },
     { _______, _______, _______, KC_B, KC_V, KC_M, _______  },
     { _______, _______, _______, _______, _______, _______, _______  }
},

/* LAYER = LAYER_THREE
add visual lay out here
*/

[LAYER_THREE] = {
      { _______, _______, _______, KC_AT, KC_PERC, KC_HASH, _______ },
      { _______, _______, _______, KC_AMPR, KC_LCBR, KC_PIPE, _______ },
      { _______, _______, _______, KC_Y, KC_J, KC_LABK, _______ },
      { _______, _______, _______, KC_C, KC_W, KC_F, _______ },
      { _______, _______, _______, KC_Q, KC_Z, KC_X, _______ },
      { _______, _______, _______, _______, _______, _______, _______ }
},

};

/* toevoegen:
TOGGLE FUNCTIE VOOR ENTER EN SPACE
LONGPRESS NUMMER VOOR FTOETS
LONGPRESS VOOR OPPOSITES
*/

void persistant_default_layer_set(uint16_t default_layer)
{
    eeconfig_update_default_layer(default_layer);
    default_layer_set(default_layer);
};

const uint16_t PROGMEM fn_actions[] = {

};

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
 switch(id)
     {
      case MACRO_ONE:
            if (record->event.pressed)
            {
                persistant_default_layer_set(1UL<<LAYER_ONE);
                key_timer = timer_read();
            }
            else
{
                if (timer_elapsed(key_timer) > 150) {
                    return MACRO( D(LCTL), T(C),  ,END  );
                }
                else
{
                    return MACRO_ONE;
                }           
                break;


      case MACRO_TWO:
            if (record->event.pressed)
            {
                layer_on(LAYER_TWO);
            }
            else
            {
                layer_off(LAYER_TWO);
            }
            break;

       case MACRO_THREE:
            if (record->event.pressed)
            {
                layer_on(LAYER_THREE);
            }
            else
            {
               layer_off(LAYER_THREE);
            }
            break;
      }       
     
      return MACRO_NONE;
};


void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}


bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void led_set_user(uint8_t usb_led) {

}

If anyone could point me in the right direction it would be much appreciated.
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline algernon

  • Posts: 311
  • A tiny mouse, a hacker.
    • Diaries of a Madman
Re: TMK keyboard firmware
« Reply #1597 on: Tue, 13 September 2016, 05:32:21 »

Code: [Select]
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
 switch(id)
     {
      case MACRO_ONE:
            if (record->event.pressed)
            {
                persistant_default_layer_set(1UL<<LAYER_ONE);
                key_timer = timer_read();
            }
            else
{
                if (timer_elapsed(key_timer) > 150) {
                    return MACRO( D(LCTL), T(C),  ,END  );
                }
                else
{
                    return MACRO_ONE;
                }           
                break;

This is where your troubles start. Your curly braces are unbalanced, by the looks of it, and that upsets parsing. Make sure that any curly braces you open, are properly closed. This does not seem to be the only case of this issue.

Offline Dwarlorf

  • Posts: 100
  • Location: NL
Re: TMK keyboard firmware
« Reply #1598 on: Tue, 13 September 2016, 06:49:54 »

Code: [Select]
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
 switch(id)
     {
      case MACRO_ONE:
            if (record->event.pressed)
            {
                persistant_default_layer_set(1UL<<LAYER_ONE);
                key_timer = timer_read();
            }
            else
{
                if (timer_elapsed(key_timer) > 150) {
                    return MACRO( D(LCTL), T(C),  ,END  );
                }
                else
{
                    return MACRO_ONE;
                }           
                break;

This is where your troubles start. Your curly braces are unbalanced, by the looks of it, and that upsets parsing. Make sure that any curly braces you open, are properly closed. This does not seem to be the only case of this issue.

Thanks for your help. I was indeed missing some curly wurly braces which I was able to solve.

Now I still have these errors left:
Quote
keyboards/gh30/keymaps/default/keymap.c:91: error: expected expression before '=' token
keyboards/gh30/keymaps/default/keymap.c:95: error: too few arguments to function 'timer_elapsed'

Could that also be an issue with some curly braces or is there more to it? As example I used: http://qmk.fm/#example-single-key-copypaste-hold-to-copy-tap-to-paste

Code: [Select]
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
 switch(id)
     {
      case MACRO_ONE:
            if (record->event.pressed)
            {
                persistant_default_layer_set(1UL<<LAYER_ONE);
key_timer = timer_read();
            }
            else
{
                if (timer_elapsed(key_timer)> 150)
{
                    return MACRO( D(LCTL), T(C),  END );
                }
                else
{
                    return MACRO_ONE;
                }
}         
                break;
  
E5XKBP10140                 GH60 Iso/Ansi hybrid, cherry mx red

Offline algernon

  • Posts: 311
  • A tiny mouse, a hacker.
    • Diaries of a Madman
Re: TMK keyboard firmware
« Reply #1599 on: Tue, 13 September 2016, 09:25:58 »
Now I still have these errors left:
Quote
keyboards/gh30/keymaps/default/keymap.c:91: error: expected expression before '=' token
keyboards/gh30/keymaps/default/keymap.c:95: error: too few arguments to function 'timer_elapsed'

Could you upload your full keymap to gist.github.com, or somewhere similar where it is easier to see line numbers? (bonus points if I can clone it too, to see it locally).