How to build your very own keyboard firmware

User avatar
Halvar

16 Dec 2015, 13:58

rockosmodlife wrote: Now I get the following:

keymap_common.c: In function 'keymap_fn_to_action':
keymap_common.c:29: error: 'fn_actions' undeclared (first use in this function)
Seems to me that you have taken out all kinds of stuff from the source. Before you take out functions or macros or other stuff from the source, you basically need to find out where it is used and take out all references, too.

User avatar
Halvar

16 Dec 2015, 17:06

@nicstreet: I have used Teensy 2.0 and Teensy++ 2.0, and they both work. Teensy 3.x models have a totally different architecture based on ARM Chips instead of AVR chips, so the controller has to be ported to that architecture to work. There's a thread about that, it's a work in progress. The Mini Pro should work I think (haven't tried it), you'll have to configure the software and compile it for the ATmega328.

I have bluetoothed my IBM SSK with a Teensy++ 2.0 and an Adafruit Bluefruit EZKey, but that one is preconfigured for keyboard applications. Some code for that one is inside Hasu's TMK software (not by me, search for bluefruit in the code) so you can maybe take that as a start.

nicstreet

16 Dec 2015, 17:26

Thanks Halvar, very useful... I'll likely get a bit of time to invest over Xmas (trusting I can drag myself away from the kids toys :P) I'll likely start with the Mini Pro and see how I progress, could be slow as I'm by no means an experienced dev.

burn1nsun

18 Dec 2015, 03:20

Hello, super thankful for the guide!

Like many, I also ran into some issues, but for some reason this one makes no sense to me: I'm trying to create a neutrino build, and I got everything (In my mind) set up correctly, I've even read the amount of lines and code and keys over at least 30 times now. I got rid of many problems by troubleshooting, but I can't just find an answer to this one.

Here is my keymap_poker.c:

http://pastebin.com/FYDq8YRM

Here is my keymap_common.h:

http://pastebin.com/EWinVHLz

I get this error and I don't know any way to fix this:

https://i.gyazo.com/d132d90b124d4ee3f2b ... f28603.png

I've been trying to create my own firmware since 1 am or even earlier, and its 4:20 am right now, I feel like I'm going crazy, but I can't stop while achieving nothing, so I figured that I'll just give in and ask for help :(

EDIT: Alright I woke up today and fixed that issue in 5 minutes, came out that I forgot to save my config.c file, so I had 14 columns instead of 15, and the poker keymap file had 15 columns in the fourth row instead of 14 and was missing a comma :)

User avatar
awkwrdm3

26 Dec 2015, 11:07

I'm building a 60% board.... so i'm going off the guilds that are really well put together!!! THANKS.

I have a few questions.

1) I'm using a Teensy 3.2, will this guild still work for the 3.2?

2) The "Setting up the rows and columns" part of the guide talks about pins with names like "f7" ... the 3.2 does not have that naming system. and I have looked all over and found nothing that talks about this.(making me go back to question 1)

for now thats all my question i'm sure there will be more;)

hypkx
Chasing the Dream

26 Dec 2015, 13:31

The firmware works only on a teensy 2.0.

User avatar
matt3o
-[°_°]-

26 Dec 2015, 16:37

Hasu recently added teensy 3 (indeed the whitefox that has the same controller runs on the TMK) but I'm afraid some more work is needed.

I'll talk to Hasu to see if I can make a tutorial.

User avatar
flabbergast

26 Dec 2015, 20:00

I'm working with hasu on ARM Teensies (i.e. LC, 3.x) support in TMK, build on top of chibios. It is still relatively early days (so more testing and reports are needed and welcome), but generally things seem to work.

Some instructions are here. It points to my TMK fork, chibios branch (I'm trying to keep it up-to-date with TMK mainline); or you can use the official hasu's TMK from github, flabbergast-tmk_chibios branch; hasu's reviewing the changes, so it's generally a bit behind my fork.

User avatar
awkwrdm3

27 Dec 2015, 01:13

this is my first project using micro controllers like this... so i'm a bit noob... I did just order a 2.0 just in case lol. I'll give it a crack with the instructions you put together... thanks for the help

User avatar
flabbergast

27 Dec 2015, 18:24

Yea, 2.0 is probably much better choice for the first project - the point is that it's already tested a lot, many more people can help, and so diagnosing whether a problem is in the hardware vs in the software is way easier.

PallyPenguin

04 Jan 2016, 16:38

Is there any reason to use the Teensy 3.2 over the 2.0? From what I hear there doesn't seem to be much reason to choose the 3.2 over the 2.0... (I will be beginning my first keyboard build as well and really don't want to mess this up :oops: ) Thanks!

User avatar
flabbergast

04 Jan 2016, 16:47

No there is not (unless you really need the extra pins that are on 3.2). The thing is that last year it was expensive to get 2.0 in Europe (low stock and high prices), compared to 3.x. (They're still priced almost the same here in the UK, with LC being quite a bit cheaper.)

User avatar
Halvar

04 Jan 2016, 17:04

Hardware-wise, the Teensy 3.2 does give you much more bang for the buck. More RAM, faster processor etc. On the other hand, there are well-tested firmware solutions with plenty of features for the Teensy 2.0 and Teensy++ 2.0, while the existing keyboard firmware for Teensy 3.2 is more bleeding edge and less feature-packed if they exist at all.

For your first keyboard build, with few experience in microcontroller programming, I would definitely go for the 2.0 generation. It has more than enough processing power for a keyboard controller. If you feel you want to do advanced stuff like really complicated memory-intensive keyboard macros, programming of RGB illumination effects, build a color display into your keyboard or things like that, and are willing to learn to program these features for yourself, then go ahead and use the version 3.x.

nicstreet

05 Jan 2016, 01:54

Agree with the guys stating use a 2.0 for a first project. I'll likely complete my build tomorrow but have spent hours getting my Arduino Pro Micro working, even then I have had to make sacrifices due to pin shortage and had a number of minor issues with what appears to be AVR running under W10.

I looked at using my Teensy 3.0 but ran into some issues early on, I'll save that one for later this month.

Likely should have waited for my 2.0++ to arrive :P

I'll post some brief destructions soon for anyone wanting to use an Arduino Pro Micro (or derivative) from a Windows box.

User avatar
awkwrdm3

05 Jan 2016, 07:52

So i got me 2.0... and i'll save the 3.2 for later... I edited all the code i needed to but i got this error when i went to make my file.... any ideas of what the problem is?

Code: Select all

##-iMac:~ ##$ /Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile ; exit;
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 42: TARGET: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 45: TMK_DIR: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 48: TARGET_DIR: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 51: SRC: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 55: ifdef: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 56: KEYMAP: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 56: SRC: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 56: SRC: command not found
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 57: syntax error near unexpected token `else'
/Users/##/Desktop/tmk_keyboard-master/keyboard/gh60/Makefile: line 57: `else'
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

User avatar
Halvar

05 Jan 2016, 08:59

Looks like your make command doesn't understand some of the Makefile. Could you share some details about the OS and software setup you're running this on?

User avatar
awkwrdm3

05 Jan 2016, 09:06

OSX...

I just realized i need to compile it in xcode... but i have never used xcode....


never mind i got i forgot to cd to the file then run make -f Makefile... :lol:

User avatar
Halvar

05 Jan 2016, 09:42

Ah ok, now I see it, you tried to run the makefile ...
awkwrdm3 wrote: I just realized i need to compile it in xcode...
Definitely not. :D

studyourheart

11 Jan 2016, 06:49

I too am having many problems compiling firmware.

my config.h
Spoiler:

Code: Select all

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

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

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

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

#ifndef CONFIG_H
#define CONFIG_H


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

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

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

my keymap_common.h
Spoiler:

Code: Select all

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

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

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

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

#include <stdint.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
#include "keycode.h"
#include "action.h"
#include "action_macro.h"
#include "report.h"
#include "host.h"
#include "print.h"
#include "debug.h"
#include "keymap.h"


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


/* GH60 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
 #define KEYMAP( \
    K5A, K5b,  K5C, K5D, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5o, K5p, K5q, \
    K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4N, K4o, K4p, K4q, \
    K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3o, K3p, K3q, \
    K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2N, \
    K1A, K2b, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1N, K1p, \
    K0A, K0C, K0D, K0G, K0K, K0L, K0M, K0N, K0o, K0p, K0q \
) { \
    { KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_NO, KC_##K5F, KC_##K5G, KC_##K5H, KC_##K5I, KC_##K5J, KC_##K5K, KC_##K5ML, KC_##K5M, KC_##K5N, KC_##K5O, KC_##K5P, KC_##K5Q}, \
    { KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F, KC_##K4G, KC_##K4H, KC_##K4I, KC_##K4J, KC_##K4K, KC_##K4L, KC_NO, KC_##K4N, KC_##K4O, KC_##K4P, KC_##K4Q}, \
    { KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F, KC_##K3G, KC_##K3H, KC_##K3I, KC_##K3J, KC_##K3K, KC_##K3L, KC_##K3M, KC_##K3N, KC_##K3O, KC_##K3P, KC_##K3Q}, \
    { KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F, KC_##K2G, KC_##K2H, KC_##K2I, KC_##K2J, KC_##K2K, KC_##K2L, KC_NO, KC_##K2N, KC_##K2O, KC_##K2P, KC_##K2Q}, \
    { KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F, KC_##K1G, KC_##K1H, KC_##K1I, KC_##K1J, KC_##K1K, KC_##K1L, KC_NO, KC_##K1N, KC_##K1O, KC_##K1P, KC_##K1Q}, \
    { KC_##K0A, KC_NO, KC_##K0C, KC_##K0D, KC_NO, KC_NO, KC_##K0G, KC_NO, KC_NO, KC_NO, KC_##K0K, KC_##K0L, KC_##K0M, KC_##K0N, KC_##K0O, KC_##K0P, KC_##K0Q} \
}

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


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

#endif
my matrix.c
Spoiler:

Code: Select all

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

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

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

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

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


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

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

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


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

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

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

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

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

    return 1;
}

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

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

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

void matrix_print(void)
{
    print("\nr/c 0123456789ABCDEF\n");
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
        phex(row); print(": ");
        pbin_reverse16(matrix_get_row(row));
        print("\n");
    }
}

uint8_t matrix_key_count(void)
{
    uint8_t count = 0;
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        count += bitpop16(matrix[i]);
    }
    return count;
}


 
 /* Column pin configuration
 * col: 0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
 * pin: D5  C7  C6  D4  D0  E6  F0  F1  F4  F5  F6  F7  D7  D6  D1  D2  D3
 */
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);
    DDRE  &= ~(1<<6);
    PORTE |=  (1<<6);
    DDRD  &= ~(1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
    PORTD |=  (1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
    DDRC  &= ~(1<<7 | 1<<6);
    PORTC |=  (1<<7 | 1<<6);
	DDRB  &= ~(1<<6);
	PORTB |=  (1<<6);
}

static matrix_row_t read_cols(void)
{
    return (PIND&(1<<5) ? 0 : (1<<0)) |
           (PINC&(1<<7) ? 0 : (1<<1)) |
           (PINC&(1<<6) ? 0 : (1<<2)) |
           (PIND&(1<<4) ? 0 : (1<<3)) |
           (PIND&(1<<0) ? 0 : (1<<4)) |
           (PINE&(1<<6) ? 0 : (1<<5)) |
           (PINF&(1<<0) ? 0 : (1<<6)) |
           (PINF&(1<<1) ? 0 : (1<<7)) |
		   (PINF&(1<<4) ? 0 : (1<<8)) |
		   (PINF&(1<<5) ? 0 : (1<<9)) |
           (PINF&(1<<6) ? 0 : (1<<10)) |
           (PINF&(1<<7) ? 0 : (1<<11)) |
           (PIND&(1<<7) ? 0 : (1<<12)) |
           (PINB&(1<<6) ? 0 : (1<<13)) |
           (PIND&(1<<1) ? 0 : (1<<14)) |
           (PIND&(1<<2) ? 0 : (1<<15)) |
		   (PIND&(1<<3) ? 0 : (1<<16)) ;
}

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

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

Code: Select all

#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: qwerty */
    KEYMAP(\
	    ESC,F1, F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,       PSCR,SLCK,BRK,  \
        GRV,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,      INS, HOME,PGUP, \
        TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS,      DEL, END, PGDN, \
        FN0, A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,                       \
        LSFT, 1,    Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,     RSFT,           UP,        \
        LCTL,LGUI,LALT,               SPC,                RALT,RGUI,APP, RCTL,      LEFT,DOWN,RGHT),

};

const uint16_t PROGMEM fn_actions[] = {
/* 1: fn0 */
    KEYMAP(\
        TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,      TRNS,TRNS,SLEP, \
        TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,      TRNS,TRNS,TRNS, \
        TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,      TRNS,TRNS,TRNS, \
        TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,     TRNS,                      \
        TRNS,     TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,     TRNS,           TRNS,      \
        TRNS,TRNS,TRNS,               TRNS,               TRNS,TRNS,TRNS,TRNS,      TRNS,TRNS,TRNS)


};

any help would be appreciated. thanks!

obones

11 Jan 2016, 09:22

Well, without the exact error messages it's hard to help.
And, if you look at messages, always look at the first and solve it, the following ones usually are a consequence of the first.

Finally, you are using 17 columns, which is above 16 and may lead to problems, as explained here:

https://github.com/tmk/tmk_keyboard/wik ... -beyond-16
http://deskthority.net/workshop-f7/rebu ... ml#p146279

studyourheart

12 Jan 2016, 03:32

Ahh, thanks for that. I actually found even more syntax errors while updating my matrix file. I think I was just staring at the code for too long last night. I'll go over it again in a day or two when I have time and see what else I can find. If I still have problems I'll make sure to post a log from the terminal. Thanks for the help!

Aenuriel

12 Jan 2016, 16:02

Hi guys,
I need your support and and tips in order to configure a Tensy 2.0 firmware.

- 1. As a French using a BÉPO layer, is better to proceed like this?
o I code for a QWERTY layout, adding:
/* translates key to keycode */
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key
{
return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
}
o Then I change layout in “Keyboards and Language” in Windows

- 2.a) Can I configure an key like this? (with 2 actions)
const uint16_t PROGMEM fn_actions[] =
{
[1] = ACTION_LAYER_MOMENTARY(1), /* active layer “1” */
[1] = ACTION_KEY(KC_RALT), /* “Alt Gr” key */
}

- 2.b) Or like this? (with “if” function)
const uint16_t PROGMEM fn_actions[] =
{
[2] = if (and{RALT=1;LSFT=0;RSFT=0})
then (–) /* “–” key */
else if (and{RALT=0;or(LSFT=1;RSFT=1)})
then ($) /* “$” key */
else if (and{RALT=1;or(LSFT=1;RSFT=1)})
then (NO) /* pointless key */
else (ACTION_KEY(ESC)) /* “Escape” key */
}

- Note: If you know other ways to get 2.a) and 2.b) results don’t hesitate :)

Thank you fou your attention,
Aenuriel

User avatar
Ray

12 Jan 2016, 18:03

I am not 100% sure, if I understood your questions correctly, but I try to answer anyways:
1) If you have a physical layout that is close to standard ISO or ANSI, it is easier to map a more or less standard layout in firmware and switch to BEPO in the OS. This way, you get the BEPO "shift-layer" for the number row and similar stuff for free.

2a) you want a key, that acts as ALT_GR but also switches to a different layer when pressed?
short answer is, you can't do it like you tried. You can do it with ACTION_FUNCTION.

2b) TMK isn't made for stuff like this, I think. You can get info about which mods are pressed though - iirc. So I guess you can do it with ACTION_FUNCTION(_TAP). You can do a lot of stuff with it. But you need to do some programming and also invest time into TMK to understand how you can do stuff.
Also fn_actions[] is restricted to 32 "keys". You might find this as a problem.

From your pseudocode, I guess you are not firm with C. You would need to invest a good amount of (probably frustrating) time to get anything to work with the 2) way. Instead make a regular layout in firmware and switch to a layout you like in the OS.

Aenuriel

13 Jan 2016, 10:25

Thank you for your answer.

So, if I understand:

1. I was right.

2.a) I don't use this way.

2.b) I have to do it better. I changed the code for this:
const uint16_t PROGMEM fn_actions[] =
{
[2] = if (RALT=1;LSFT=0;RSFT=0) /* Alt Gr */
{ACTION_MODS_KEY(MOD_RALT , KC_GRV)} /* “–” key */
else if (RALT=0;LSFT=1;RSFT=0) /* L Shift */
{ACTION_KEY(KC_GRV)} /* “$” key */
else if (RALT=0;LSFT=0;RSFT=1) /* R Shift */
{ACTION_KEY(KC_GRV)} /* “$” key */
else if (RALT=0;LSFT=1;RSFT=1) /* L Shift + L Shift */
{ACTION_KEY(KC_GRV)} /* “$” key */
else if (RALT=1;LSFT=1;RSFT=0) /* Alt Gr + L Shift */
{ACTION_KEY(KC_NO)} /* pointless key */
else if (RALT=1;LSFT=0;RSFT=1) /* Alt Gr + R Shift */
{ACTION_KEY(KC_NO)} /* pointless key */
else if (RALT=1;LSFT=1;RSFT=1) /* Alt Gr + L Shift + L Shift */
{ACTION_KEY(KC_NO)} /* pointless key */
else /* – */
{ACTION_KEY(KC_ESC)} /* “Escape” key */
}

I think this 2.b) is better now (if I can write an if/elseif/else function in the definition of Fn2) but I still have doubts with the "if (RALT=1;LSFT=0;RSFT=0)" parts.

obones

13 Jan 2016, 10:49

No you can't, you should use an ACTION_FUNCTION with your own implementation of the

Code: Select all

void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
callback
Have a look at the following page, section 2.4:
https://github.com/tmk/tmk_keyboard/blo ... /keymap.md

You'll find some sample code at the end of this file:
https://github.com/tmk/tmk_keyboard/blo ... map_hasu.c

Aenuriel

13 Jan 2016, 11:32

Very nice answer, thank you.

But ouch, I have some difficulties to understand it ^^
Can I launch a macro by pressing on 2 keys (Shift + Esc) ?

Aenuriel

13 Jan 2016, 14:20

Hi again,

Can a macro definition like this work?

/* Macro definition */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch (id) {
case DEL_INS :
/*
* NOTHING => DEL
* RALT => INS
*/
if (Keyboard.IsKeyDown(Key.RightAlt)) {
ACTION_KEY(KC_INS)
} else {
ACTION_KEY(KC_DEL)
}
break;
}
}

studyourheart

14 Jan 2016, 06:49

I figured it out! Typing this on a fresh handwired TKL build around the stainless plates from wafflepc's groupbuy. Stay tuned on that thread for an update in a few days! And thanks for the heads up about the 17 column workaround obones!

wes1099

20 Jan 2016, 02:51

I am building a hand wired numpad using a teensy 2.0. I was told that I could just use the lightpad TMK firmware if I just wired everything to the same pins. From what I understand, columns 0, 1, 2, and 3 are on pins PF0, PF1, PC7, and PC6 respectively, and rows 0, 1, 2, 3, 4, and 5 are on pins D0, D1, D2, D3, D5, and B7 respectively. Is that correct? Also, I am supposed to put the diodes on the rows not the columns correct?

wes1099

20 Jan 2016, 03:06

And one more question, is row 0 the top row or the bottom row? Same for columns (is column 0 the left or the right?).

Post Reply

Return to “Workshop”