TMK keyboard firmware collection

User avatar
hasu

20 Jun 2014, 06:14

You need to set JTD bit of MCUCR yourself to use PF4-7 as GPIO. Those pins are configured to serve JTAG function by default. If you are using Teensy this isn't needed. Teensy is shipped with JTAGEN fuse bit unprogrammed to disable the function.

See this code.
https://github.com/tmk/tmk_keyboard/blo ... trix.c#L67

Code: Select all

    // JTAG disable for PORT F. write JTD bit twice within four cycles.
    MCUCR |= (1<<JTD);
    MCUCR |= (1<<JTD);
And read '26.5.1 MCU Control Register – MCUCR' of ATMega32U4 datasheet.

Other than that it looks to me like your code has no problem.

User avatar
uberben

20 Jun 2014, 06:45

I added those lines to my matrix init function, but that does not seem to have any impact to fix the backslash keys. The other keys that share the same rows and columns seem to work fine, which is odd.

I am using Adafruit's 32u4 breakout board (http://www.ladyada.net/products/atmega3 ... ifications) and I took a peek at the schematic. It looks like there is an LED connected to E6, so I switched to D4 which does not seem to have changed anything.

I just decided to try switching the BSLS mappings to A and now both switches show the A being pressed just fine, which leads me to believe there is something wrong with the BSLS mapping specifically. Similarly, I remapped the DOWN key to C and now it works as expected instead of releasing instantly. I'll have to dig through the code a bit more tomorrow to see if I can find any reason for this.

lakmeer

14 Aug 2014, 00:36

Hi, I have a question:

I really like the tapping functions ACTION_MODS_TAP_KEY and ACTION_LAYER_TAP_KEY, but I'd like to be able to send modified keys on tap as well as plain keys.

I solved this case for MODS_TAP_KEY by copying the lshift_to_lparen function in tmk/keyboards/hhkb/keymap_hasu.c and abstracting it into a function that takes any mod and any key, and then using ACTION_FUNCTION_TAP. I'd like to find a way to do the same for LAYER_TAP_KEY as well. Does something like that exist?

Alternatively, could I modify or extend my LAYER_TAP_KEY to trigger a ACTION_MACRO instead? Then I could use ACTION_MACRO to define whatever I needed, including mods and all sorts of things.

As you can probably tell, I'm not amazing with C ;) Any advice would be great :)

User avatar
hasu

14 Aug 2014, 03:03

Right, you need to wirte code yourself with ACTION_FUNCTION_TAP to send modified key with tapping. As for layer switch you also need your own code, you can use layer_on() and layer_off() function to change layers, instead of register_mods() and unregister_mods() of LSHIFT_LPAREN.

See common/action_layer.c for layer_* functions and common/action.c to know what ACTION_LAYER_TAP_KEY does.
https://github.com/tmk/tmk_keyboard/blo ... ion.c#L264

ACTION_MACRO is functionally equivalent to ACTION_FUNCTION and intended to be easy to write(but not as expected unfortunately). So I think you can write with ACTION_MACRO instead of ACTION_FUNCTION but you can't trigger ACTION_MACRO in ACTION_FUNCTION. Anyway macro feature is not fully tested and supported.

lakmeer

14 Aug 2014, 07:50

Thanks hasu, that totally worked! I think I got very close to that solution, but I was invoking it using ACTION_FUNCTION instead of ACTION_FUNCTION_TAP - is the difference just that FUNCTION_TAP provides the 'event' variable with the appropriate tap-related information (like tap_count), but FUNCTION doesn't?

User avatar
hasu

15 Aug 2014, 03:57

Right, you have to use ACTION_FUNCTION_TAP to define your own 'tap key', instead of ACTION_FUNCTION.

User avatar
elRetto

06 Oct 2014, 18:34

hey there,
when I try to compile I get this error message and I have no idea why.
Spoiler:
Image
is that my fault and if what can i do?

User avatar
hasu

06 Oct 2014, 22:53

I can compile GH60 firmware of master branch on Ubuntu, with avr-gcc/4.8.2, avr-binutils/2.23.1 and avr-libc/1.8.0.
If you are using latest source code you'll want to check your toolchain version.

User avatar
hasu

10 Oct 2014, 03:00

Ellipse did a nice job on 4704 converter. For future reference, I copied his post here.
http://deskthority.net/keyboards-f2/new ... ml#p187822
Ellipse wrote: Has anyone managed to get Hasu's 4704 Kishsaver tmk_keyboard converter working with the 107-key 4704 keyboard (keyboard ID A5)? Compiling the code on github without modification worked 95% for the main 62-key section of the 107-key keyboard, but two of my 107-key keyboards have the same keys not emitting values or key codes - the 8* key, the =+ key, and the left CTRL key produce nothing. On my third one, the 7&, -_, and right control key do not emit codes or matrix values. Adding scan codes to the keymap_common.h file did not fix these 3 keys (although they successfully added some codes for the other keys).

The matrix debug option viewed using hid_listen shows no activity for these keys but by pressing 7& and 9(, I can see that the 8* key probably should be column 1 row 1, the += key should be column 6 row 3, and the lower left control key should probably be column 1 row 6). The columns go from 0 through 7 and the rows go from 00 to 0F.

I carefully read through the source code and 4704-specific and TMK general readme files for this github project but cannot figure it out. I read that there is a way to get the 4704 keyboard to list all its break codes by sending the FC "set key flag" command to the keyboard but do not know how to do so (I could not figure out how to use the console option either).

There are other great 4704 converters out there but I would like to get this one working beyond 95%. In my testing over a few days it produced no ghosting or transposed characters while typing at 80+ wpm.

The hid_listen message when plugging in the keyboard:
IBM 4704 Converter
Keyboard ID: A5
Enable break: x36 zc65:rFD c6B:rFD End

(Does FD in the row codes above indicate an error?)

my adjusted keymap_common.h file is below. I added some codes for 103 keys since I got an error when trying to add more than that. Pressing some keys outside of the main 62-key section result in Error: 78 or Error: 79 both with the unmodified compiled hex file and my adjusted one below.
Spoiler:
/*
Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>

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

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

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

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


// 32*8(256) byte array which converts PS/2 code into USB code
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* Original keys */
#define KEYMAP( \
K00,K18,K19,K1A,K10,K11,K12,K08,K09,K0A,K0F,K1F,K0D,K0C,K0E,K07,K0B,K1E,K2E,K43,K44,K45,K46,K47, \
K04,K05,K06,K13,K14,K15,K16,K17,K01,K02,K03,K1B,K1C,K1D, K48,K49,K4A,K4B,K4C,K4D,K4E,K4F,K50, \
K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K2A,K2B,K2C,K2D, K51,K52,K53,K54,K55,K56,K57,K58,K59, \
K30,K3E,K32,K33,K34,K35,K36,K37,K38,K39,K3A,K3B,K3C,K3D, K5A,K5B,K5C,K5D,K5E,K5F,K60,K61,K62, \
K31,K41,K3F, K40, K42,K2F, K63,K64,K65,K66 \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
{ KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
{ KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_NO, KC_##K1F }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
{ KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
{ KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
{ KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47 }, \
{ KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F }, \
{ KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
{ KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F }, \
{ KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
}

#endif

/*
{ K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
{ K50, K51, K52, K53, K54, K55, K56, K57 }, \
{ K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
{ K60, K61, K62, K63, K64, K65, K66, K67 }, \
{ K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
{ K70, K71, K72, K73, K74, K75, K76, K77 }, \
{ K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }, \
*/

User avatar
hasu

10 Oct 2014, 03:06

http://deskthority.net/keyboards-f2/new ... ml#p187824
hasu wrote: Ellipse, nice job!
I got a bit talk about 107-key with REVENGE on IRC just a few days ago. This is a coincidence!? :o
I carefully read through the source code and 4704-specific and TMK general readme files for this github project but cannot figure it out. I read that there is a way to get the 4704 keyboard to list all its break codes by sending the FC "set key flag" command to the keyboard but do not know how to do so (I could not figure out how to use the console option either).
Feel free to ask me. And I'll be happy to improve the docs and my Engrish writing skill :D
See enable_break() in matrix.c, this function does the job.
And I can send you 4704 firmware dis-assembled list via PM for reference, if you want let me know.

The hid_listen message when plugging in the keyboard:
IBM 4704 Converter
Keyboard ID: A5
Enable break: x36 zc65:rFD c6B:rFD End

(Does FD in the row codes above indicate an error?)
FD means 'out of bound' or invalid scan code. You can ignore them, and I also had these on my KSaver IIRC.

my adjusted keymap_common.h file is below. I added some codes for 103 keys since I got an error when trying to add more than that. Pressing some keys outside of the main 62-key section result in Error: 78 or Error: 79 both with the unmodified compiled hex file and my adjusted one below.
In 50, 62 and 77-key keyboards 00-77h are valid scan codes and my converter supports those codes only. You need to fix to support scan codes beyond 77h. I guess valid scan codes are 00-7ch but not sure, you will need to do trial and error.

These lines should be fixed.
https://github.com/tmk/tmk_keyboard/blo ... trix.c#L73
https://github.com/tmk/tmk_keyboard/blo ... rix.c#L119

User avatar
hasu

10 Oct 2014, 03:08

hasu wrote:
REVENGE wrote:
hasu wrote: Ellipse, nice job!
I got a bit talk about 107-key with REVENGE on IRC just a few days ago. This is a coincidence!? :o
A nice coincidence indeed. 8-)

Is there an option for your converter to output the data coming from the 4704 controller in HID listen?
You can apply this patch to see scan codes from 4704.
http://deskthority.net/keyboards-f2/new ... ml#p188064

Code: Select all

diff --git a/converter/ibm4704_usb/matrix.c b/converter/ibm4704_usb/matrix.c
index 0bfda2b..aa54ac0 100644
--- a/converter/ibm4704_usb/matrix.c
+++ b/converter/ibm4704_usb/matrix.c
@@ -118,12 +118,14 @@ uint8_t matrix_scan(void)
         return 0;
     } else if ((code&0x78)==0x78) {
         // 0xFF-F8 and 0x7F-78 is not scancode
-        xprintf("Error: %0X\n", code);
+        xprintf("Error: %02X\n", code);
         matrix_clear();
         return 0;
     } else if (code&0x80) {
+        dprintf("%02X\n", code);
         matrix_make(code);
     } else {
+        dprintf("%02X\n", code);
         matrix_break(code);
     }
     return 1;

Ellipse

10 Oct 2014, 07:08

Thanks for your help Hasu! I have tried adjusting lines 73 and 119 with some different values but the 8*, =+, and left CTRL keys still do not work.

Your matrix.c patch above worked perfectly to see the scan codes though! I can see that even the problematic keys on my 107 key 4704 keyboard produce a scan code.

I believe the problem is that for those keys above that do not work, they do not emit a code when releasing the key - a scan code is only emitted when the key is pressed down. All the other working keys emit a code when pressing down on the key and another code when releasing the key. For example, in hid_listen the 7& key emits 88 when pressed and 08 when released, the (problematic) 8* key emits only 09 when pressed and nothing when released, and the 0) key emits 8F when pressed and 0F when released. The problematic =+ key emits only 0D when pressed and nothing when released.

Is there a way to enable the break codes when releasing the problematic keys?

REVENGE

10 Oct 2014, 10:28

Ellipse wrote: Thanks for your help Hasu! I have tried adjusting lines 73 and 119 with some different values but the 8*, =+, and left CTRL keys still do not work.

Your matrix.c patch above worked perfectly to see the scan codes though! I can see that even the problematic keys on my 107 key 4704 keyboard produce a scan code.

I believe the problem is that for those keys above that do not work, they do not emit a code when releasing the key - a scan code is only emitted when the key is pressed down. All the other working keys emit a code when pressing down on the key and another code when releasing the key. For example, in hid_listen the 7& key emits 88 when pressed and 08 when released, the (problematic) 8* key emits only 09 when pressed and nothing when released, and the 0) key emits 8F when pressed and 0F when released. The problematic =+ key emits only 0D when pressed and nothing when released.

Is there a way to enable the break codes when releasing the problematic keys?
You probably need to issue commands to enable break for those codes in the function:

Code: Select all

static void enable_break(void)
{
    uint8_t ret;
    print("Enable break: ");
    // valid scancode: 00-77h
    for (uint8_t code = 0; code < 0x78; code++) {
        while (ibm4704_send(0x80|code) != 0) {
            print("z");
            _delay_us(500);
        }
        _delay_us(2000);
        ret = ibm4704_recv();
        if (ret != 0xff) {
            xprintf("c%02X:r%02X ", code, ret);
        }
        _delay_us(1000);
    }
    _delay_us(1000);
    while (ibm4704_send(0xFF) != 0) { _delay_us(500); } // End
    print("End\n");
}
With the raw codes printed, you can probably determine the range of valid scan codes.

User avatar
hasu

10 Oct 2014, 20:12

hmm, enable_break() enables release code for scan code 00-77h by default, so those problematic keys should send release code. Perhaps enable_break() fails on those problematic keys.

Can you post debug print at startup?
In case of my 62-key it is like this. FD is not harmful it just means scan code does not exist in this keyboard.

Code: Select all

Waiting for new device:..
Listening:
USB configured.
M 4704 converter
Keyboard ID: A3
Enable break: c07:rFD c0B:rFD c1E:rFD c2E:rFD c43:rFD c44:rFD c45:rFD c46:rFD c47:rFD c48:rFD c49:rFD c4A:rFD c4B:rFD c4C:rFD c4D:rFD c4E:rFD c4F:rFD c50:rFD c51:rFD c52:rFD c53:rFD c54:rFD c55:rFD c56:rFD c57:rFD c58:rFD c59:rFD c5A:rFD c5B:rFD c5C:rFD c5D:rFD c5E:rFD c5F:rFD c60:rFD c61:rFD c62:rFD c63:rFD c64:rFD c65:rFD c66:rFD c67:rFD c68:rFD c69:rFD c6A:rFD c6B:rFD c6C:rFD c6D:rFD c6E:rFD c6F:rFD c70:rFD c71:rFD c72:rFD c73:rFD c74:rFD c75:rFD c76:rFD c77:rFD End
Keyboard start.

Ellipse

11 Oct 2014, 07:57

Below is the debug print. Thanks to Hasu's matrix.c patch I found out that my 107-key keyboard emits hexadecimal scan codes up to F9 and so I have adjusted lines 73 and 119 of the matrix.c code to the next hexadecimal value FA. Now no keys produce error codes. The key to the left of the left shift key produces no pressed or released scan code at all.

Code: Select all

Waiting for device:...
Listening:
IBM 4704 converter
Keyboard ID: A5
Enable break: x36 zx36 zc65:rFD c6B:rFD c7E:rFD c7F:rFE x36 zcE5:rFD cEB:rFD End

Keyboard start.
The following 7 non-working keys all emit what should be the release code to hid_listen when they are pressed and do not emit any codes when the key is released. Interestingly, pressed code 65 with release code E5 and pressed code 66 with released code 66 worked fine before I adjusted the hexadecimal values on lines 73 and 119 of matrix.c, but now they have the same issues as the other keys. Maybe there is an issue with 7F during the matrix scan since it reports FE ("Read/Parity error in receive from host")?
  • 1. When the key corresponding to release code 09 (the 8* key) is pressed it emits 09 and emits nothing when released. When pressed it should emit code 89 and then emit code 09 when released.
    2. The =+ key emits 0D when pressed when it should emit 8D when pressed and 0D when released.
    3. The key two keys to the right of backspace emits 6B when pressed when it should emit EB pressed and 6B released.
    4. The key one key to the left of Tab emits 66 when pressed when it should emit E6 pressed and 66 released.
    5. The key two keys to the right of Enter emits 65 when pressed when it should emit E5 pressed and 65 released.
    6. The key five keys to the right of Enter emits 51 when pressed when it should emit D1 pressed and 51 when released.
    7. The key two keys to the right of Right Shift emits 75 when pressed when it should emit F5 pressed and 75 when released.
Here is my updated matrix.c code, updated with Hasu's patch for hid_listen (enable_break) and with updated hexadecimal values on lines 73 and 119.

Code: Select all

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

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

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

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

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


static void matrix_make(uint8_t code);
static void matrix_break(uint8_t code);
static void matrix_clear(void);


/*
 * Matrix Array usage:
 * IBM 4704 scan codes are assigned into 128(16x8)-cell matrix.
 *
 *    8bit wide
 *   +---------+
 *  0|         |
 *  :|   XX    | 00-7F
 *  f|         |
 *   +---------+
 *
 * Exceptions:
 */
static uint8_t matrix[MATRIX_ROWS];

// scan code bits  7654 3210
// R:row/C:column  -RRR RCCC
#define ROW(code)      ((code>>3)&0x0f)
#define COL(code)      (code&0x07)


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

static void enable_break(void)
{
    uint8_t ret;
    print("Enable break: ");
    // valid scancode: 00-77h
    for (uint8_t code = 0; code < 0xFA; code++) {
        while (ibm4704_send(0x80|code) != 0) {
            print("z");
            _delay_us(500);
        }
        _delay_us(2000);
        ret = ibm4704_recv();
        if (ret != 0xff) {
            xprintf("c%02X:r%02X ", code, ret);
        }
        _delay_us(1000);
    }
    _delay_us(1000);
    while (ibm4704_send(0xFF) != 0) { _delay_us(500); } // End
    print("End\n");
}

void matrix_init(void)
{
    uint8_t ret;
    debug_enable = true;

    ibm4704_init();
    matrix_clear();

    // read keyboard id
    while ((ret = ibm4704_recv()) == 0xFF) {
        ibm4704_send(0xFE);
        _delay_us(100);
    }

    _delay_ms(2000);    // wait for starting up debug console 
    print("IBM 4704 converter\n");
    xprintf("Keyboard ID: %02X\n", ret);
    enable_break();
}

/*
 * IBM 4704 Scan Code
 */
uint8_t matrix_scan(void)
{
    uint8_t code = ibm4704_recv();
    if (code==0xFF) {
        // Not receivd
        return 0;
    } else if ((code&0xFA)==0xFA) {
        // 0xFF-F8 and 0x7F-78 is not scancode
        xprintf("Error: %02X\n", code);
        matrix_clear();
        return 0;
    } else if (code&0x80) {
        dprintf("%02X\n", code);
        matrix_make(code);
    } else {
        dprintf("%02X\n", code);
        matrix_break(code);
    }
    return 1;
}

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

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

void matrix_print(void)
{
    print("\nr/c 01234567\n");
    for (uint8_t row = 0; row < matrix_rows(); row++) {
        xprintf("%02X: %08b\n", row, bitrev(matrix_get_row(row)));
    }
}



inline
static void matrix_make(uint8_t code)
{
    matrix[ROW(code)] |= 1<<COL(code);
}

inline
static void matrix_break(uint8_t code)
{
    matrix[ROW(code)] &= ~(1<<COL(code));
}

inline
static void matrix_clear(void)
{
    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
}
Last edited by Ellipse on 27 Oct 2014, 03:00, edited 1 time in total.

User avatar
hasu

18 Oct 2014, 03:17

I found out that my 107-key keyboard emits hexadecimal scan codes up to F9 and so I have adjusted lines 73 and 119 of the matrix.c code to the next hexadecimal value FA.
You better use 7A instead of FA because commands are sent twice when using FA.




hmm, this debug print indicates it fails to send some enable_break commands. 'x36' means stop bit error. My code sends command repeatedly until done successfully, so it won't be harm virtually... But the code may be need to be refined.

Probably 7A?-7F and 80-FF are ilegal in enable_break command, I think this is why you get c7F:rFE error in debug print.
Enable break: x36 zx36 zc65:rFD c6B:rFD c7E:rFD c7F:rFE x36 zcE5:rFD cEB:rFD End

Code: Select all

diff --git a/converter/ibm4704_usb/matrix.c b/converter/ibm4704_usb/matrix.c
index 0bfda2b..369db9d 100644
--- a/converter/ibm4704_usb/matrix.c
+++ b/converter/ibm4704_usb/matrix.c
@@ -70,7 +70,7 @@ static void enable_break(void)
     uint8_t ret;
     print("Enable break: ");
     // valid scancode: 00-77h
-    for (uint8_t code = 0; code < 0x78; code++) {
+    for (uint8_t code = 0; code < 0x7A; code++) {
         while (ibm4704_send(0x80|code) != 0) {
             print("z");
             _delay_us(500);
@@ -116,14 +116,16 @@ uint8_t matrix_scan(void)
     if (code==0xFF) {
         // Not receivd
         return 0;
-    } else if ((code&0x78)==0x78) {
-        // 0xFF-F8 and 0x7F-78 is not scancode
-        xprintf("Error: %0X\n", code);
+    } else if ((code&0x7F) >= 0x7A) {
+        // 0xFF-FA and 0x7F-7A is not scancode
+        xprintf("Error: %02X\n", code);
         matrix_clear();
         return 0;
     } else if (code&0x80) {
+        dprintf("%02X\n", code);
         matrix_make(code);
     } else {
+        dprintf("%02X\n", code);
         matrix_break(code);
     }
     return 1;

Ellipse

18 Oct 2014, 04:55

I updated the code and now the enable break line in hid_listen just says Enable break: End. Keyboard start. (Meaning there are no errors at boot!)

I also sometimes get x18 and x28 errors when pressing keys.

With Hasu's new patch, the following keys are emitting the release code when pressed and nothing when released. These were the same keys when I tested this keyboard last week. (I am now trying it on my 107-key 4704 keyboard that does not emit 7& or -_ keys. Earlier I tried it on one that did not emit 8* or += keys.)
1. The key two keys to the left of the 1! key. Emits 64 when pressed when it should emit E4 when pressed and 64 when released.
2. The key two keys to the left of the left shift key. Emits 44 when pressed when it should emit C4 when pressed and 44 when released.
3. The 7& key. Emits 08 when pressed when it should emit 88 when pressed and 08 when released.
4. The -_ key. Emits 1F when pressed when it should emit 9F when pressed and 1F when released.
5. The right CTRL key. Emits 2F when pressed when it should emit AF when pressed and 2F when released.
6. The key one key to the right of the right shift key. Emits 74 when pressed when it should emit F4 when pressed and 74 when released.
7. The key four keys to the right of the enter key. Emits 50 when pressed when it should emit D0 when pressed and 50 when released.

After your new patch, every key now emits a scan code meaning we are close!

I am thinking that if we are unable to get these keys to emit a release code, as a last resort maybe there could be exceptions added to the code for any problematic keys? For example the exception code could perform this function: "if the scan code 08 is received, then emit 88 as a PRESSED code and then 08 as the RELEASED code" so that the computer thinks the release code was correctly emitted for the key and this key would be emitted to a program. And so on for each problematic key.

User avatar
hasu

19 Oct 2014, 17:17

I also sometimes get x18 and x28 errors when pressing keys.
I have those errors too, the code may need to be improved. Do you have pull-up resistors on signal lines? just in case.
hmm, I have no idea about why those keys dont work there, now :(
I am thinking that if we are unable to get these keys to emit a release code, as a last resort maybe there could be exceptions added to the code for any problematic keys? For example the exception code could perform this function: "if the scan code 08 is received, then emit 88 as a PRESSED code and then 08 as the RELEASED code" so that the computer thinks the release code was correctly emitted for the key and this key would be emitted to a program. And so on for each problematic key.
yes, it is possible but really a last resort.

Ellipse

26 Oct 2014, 03:16

I tried using 10K and 1K resistors on my 4704 keyboard but they had no effect unfortunately.

Also I am now getting the issue where different keys are occasionally being dropped as I type. This is odd because previously I did not have this issue even at 80+ wpm. I even reflashed the old hex files that were working, and also a hex file with no code alterations, but there were still dropped keys.

I can confirm that this converter works for the 77-key 4704 keyboard and there are no missing break or release codes. Unfortunately dropped keys also happen using that one.

The GH ADB to USB keyboard thread (link below) discusses blargg's related work with the ADB part of the TMK converter (possibly adjusting things for Interrupt or changing the polling rate?) and the successful fix of the dropped keys. Is there a way to apply those fixes to the 4704 project if it has not been done already? http://geekhack.org/index.php?topic=14290.210

Since those same keys do not work I am wondering how to code the "last resort" option mentioned earlier involving IF statements for the problematic keys? What would be the best way to do that? Then all keys would be working with this IF statement fix.

User avatar
hasu

26 Oct 2014, 21:39

Can you post KEYMAP macro code for 77-key and 107-key? so that I can know extended scancodes of those keyobard.

107-key uses different firmware from other 50, 62, 77-key keyboards and behaves a little differently somehow. We may have to look into its firmware of ROM because no technical documentation of 4704 can not be found on the net.


In the end ADB conveter needed 12ms delffay between pollings to avoid overload keyboard controller, I think you can add a delay to 4704 like this.

Code: Select all

diff --git a/converter/ibm4704_usb/matrix.c b/converter/ibm4704_usb/matrix.c
index 0bfda2b..8ff9955 100644
--- a/converter/ibm4704_usb/matrix.c
+++ b/converter/ibm4704_usb/matrix.c
@@ -69,8 +69,8 @@ static void enable_break(void)
 {
     uint8_t ret;
     print("Enable break: ");
-    // valid scancode: 00-77h
-    for (uint8_t code = 0; code < 0x78; code++) {
+    // valid scancode: 00-7Ah
+    for (uint8_t code = 0; code < 0x7A; code++) {
         while (ibm4704_send(0x80|code) != 0) {
             print("z");
             _delay_us(500);
@@ -115,15 +115,18 @@ uint8_t matrix_scan(void)
     uint8_t code = ibm4704_recv();
     if (code==0xFF) {
         // Not receivd
+        _delay_ms(10);
         return 0;
-    } else if ((code&0x78)==0x78) {
-        // 0xFF-F8 and 0x7F-78 is not scancode
-        xprintf("Error: %0X\n", code);
+    } else if ((code&0x7F) >= 0x7A) {
+        // 0xFF-FA and 0x7F-7A is not scancode
+        xprintf("Error: %02X\n", code);
         matrix_clear();
         return 0;
     } else if (code&0x80) {
+        dprintf("%02X\n", code);
         matrix_make(code);
     } else {
+        dprintf("%02X\n", code);
         matrix_break(code);
     }
     return 1;
Ellipse wrote: Since those same keys do not work I am wondering how to code the "last resort" option mentioned earlier involving IF statements for the problematic keys? What would be the best way to do that? Then all keys would be working with this IF statement fix.
YOu can write action_function in keymap.c for the problematic keys. When it receives scancode from keyboard you can send press and release events to host. This can not work for modifiers. This may work for you or give you a clue at least.

Code: Select all

/*                                                         
 * user defined action function                            
 */                                                        
enum function_id {                                         
    PROBLEMATIC_KEY,                                       
};                                                         
                                                           
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
{                                                          
    switch (id) {                                          
        case PROBLEMATIC_KEY:                              
            // when released                               
            if (!record->event.pressed) {                  
                add_key(opt);                              
                send_keyboard_report();                    
                del_key(opt);                              
                send_keyboard_report();                    
            }                                              
            break;                                         
    }                                                      
}                                                          
 
/*                                                         
 * Fn action definition                                    
 */                                                        
const uint16_t PROGMEM fn_actions[] = {                    
    [0] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_7),       // for 7& key
    [1] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_MINUS),   // for -_ key 
};

Ellipse

27 Oct 2014, 00:18

Here is the 77 key keymap_common:

Code: Select all

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

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

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

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

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


// 32*8(256) byte array which converts PS/2 code into USB code
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* Original keys */
#define KEYMAP( \
    K00,K18,K19,K1A,K10,K11,K12,K08,K09,K0A,K0F,K1F,K0D,K0C,K0E,K44,K45,K46, \
    K04,K05,K06,K13,K14,K15,K16,K17,K01,K02,K03,K1B,K1C,K1D,    K54,K55,K56, \
    K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K2A,K2B,K2C,K2D,    K64,K65,K66, \
    K30,K3E,K32,K33,K34,K35,K36,K37,K38,K39,K3A,K3B,K3C,K3D,    K74,K75,K76, \
    K31,K41,K3F,        K40,                    K42,K2F,        K77,K67,K71 \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_NO }, \
    { KC_##K08, KC_##K09, KC_##K0A, KC_NO,    KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
    { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_NO,    KC_##K1F }, \
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
    { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_NO,    KC_##K2F }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
    { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
    { KC_##K40, KC_##K41, KC_##K42, KC_NO,    KC_##K44, KC_##K45, KC_##K46, KC_NO }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_##K54, KC_##K55, KC_##K56, KC_NO }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
    { KC_NO,    KC_##K71, KC_NO,    KC_NO,    KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
}

#endif

/*
    { K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
    { K50, K51, K52, K53, K54, K55, K56, K57 }, \
    { K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
    { K60, K61, K62, K63, K64, K65, K66, K67 }, \
    { K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
    { K70, K71, K72, K73, K74, K75, K76, K77 }, \
    { K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }, \
*/
And here is the 107 key keymap_common:

Code: Select all

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

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

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

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

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


// 32*8(256) byte array which converts PS/2 code into USB code
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* Original keys */
#define KEYMAP( \
    K00,K18,K19,K1A,K10,K11,K12,K08,K09,K0A,K0F,K1F,K0D,K0C,K0E,K46,K64,NO,K6B,K6C,K47,K48,K49,K4A, \
    K04,K05,K06,K13,K14,K15,K16,K17,K01,K02,K03,K1B,K1C,K1D,K56,K66,K6D,K6E,K6F,K4B,K4C,K4D,K4E, \
    K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K2A,K2B,K2C,K2D,K71,K77,K70,K65,K72,K50,K51,K52,K53, \
    K30,K3E,K32,K33,K34,K35,K36,K37,K38,K39,K3A,K3B,K3C,K3D,K44,    K74,K75,K76,K5E,K58,K59,K5A, \
    K31,K41,K3F,        K40,                    K42,K2F,K54,K55,K78,K67,K79,K5B,K5C,K5D,K57 \
) { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_NO }, \
    { KC_##K08, KC_##K09, KC_##K0A, KC_NO,    KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
    { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_NO,    KC_##K1F }, \
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
    { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_NO,    KC_##K2F }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
    { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
    { KC_##K40, KC_##K41, KC_##K42, KC_NO,    KC_##K44, KC_NO,    KC_##K46, KC_##K47 }, \
    { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_NO }, \
    { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
    { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_NO }, \
    { KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
    { KC_NO,    KC_NO,    KC_NO, KC_##K6B, KC_##K6C, KC_##K6D, KC_##K6E, KC_##K6F }, \
    { KC_##K70, KC_##K71, KC_##K72, KC_NO,    KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
    { KC_##K78, KC_##K79, KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO,    KC_NO }, \
}

#endif

/*
    { K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
    { K50, K51, K52, K53, K54, K55, K56, K57 }, \
    { K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
    { K60, K61, K62, K63, K64, K65, K66, K67 }, \
    { K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
    { K70, K71, K72, K73, K74, K75, K76, K77 }, \
    { K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }, \
*/
Adding the 10ms delay made the 4704 keyboard skip more keys. I also tried 5ms. Maybe the delay should be added to another place in the code or Interrupt should be used?

I added the problematic key code but nothing changed: it still only emits the release code when the key is pressed and nothing when the key is released. Maybe there is another way to code "if 08 is received, emit 88 pressed code and 08 release code"? Here is my keymap.c file in the common folder:

Code: Select all

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

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

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

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/pgmspace.h>
#include "keymap.h"
#include "report.h"
#include "keycode.h"
#include "action_layer.h"
#include "action.h"
#include "action_macro.h"
#include "debug.h"


static action_t keycode_to_action(uint8_t keycode);


/* converts key to action */
action_t action_for_key(uint8_t layer, key_t key)
{
    uint8_t keycode = keymap_key_to_keycode(layer, key);
    switch (keycode) {
        case KC_FN0 ... KC_FN31:
            return keymap_fn_to_action(keycode);
#ifdef BOOTMAGIC_ENABLE
        case KC_CAPSLOCK:
        case KC_LOCKING_CAPS:
            if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
                return keycode_to_action(KC_LCTL);
            }
            return keycode_to_action(keycode);
        case KC_LCTL:
            if (keymap_config.swap_control_capslock) {
                return keycode_to_action(KC_CAPSLOCK);
            }
            return keycode_to_action(KC_LCTL);
        case KC_LALT:
            if (keymap_config.swap_lalt_lgui) {
                if (keymap_config.no_gui) {
                    return keycode_to_action(ACTION_NO);
                }
                return keycode_to_action(KC_LGUI);
            }
            return keycode_to_action(KC_LALT);
        case KC_LGUI:
            if (keymap_config.swap_lalt_lgui) {
                return keycode_to_action(KC_LALT);
            }
            if (keymap_config.no_gui) {
                return keycode_to_action(ACTION_NO);
            }
            return keycode_to_action(KC_LGUI);
        case KC_RALT:
            if (keymap_config.swap_ralt_rgui) {
                if (keymap_config.no_gui) {
                    return keycode_to_action(ACTION_NO);
                }
                return keycode_to_action(KC_RGUI);
            }
            return keycode_to_action(KC_RALT);
        case KC_RGUI:
            if (keymap_config.swap_ralt_rgui) {
                return keycode_to_action(KC_RALT);
            }
            if (keymap_config.no_gui) {
                return keycode_to_action(ACTION_NO);
            }
            return keycode_to_action(KC_RGUI);
        case KC_GRAVE:
            if (keymap_config.swap_grave_esc) {
                return keycode_to_action(KC_ESC);
            }
            return keycode_to_action(KC_GRAVE);
        case KC_ESC:
            if (keymap_config.swap_grave_esc) {
                return keycode_to_action(KC_GRAVE);
            }
            return keycode_to_action(KC_ESC);
        case KC_BSLASH:
            if (keymap_config.swap_backslash_backspace) {
                return keycode_to_action(KC_BSPACE);
            }
            return keycode_to_action(KC_BSLASH);
        case KC_BSPACE:
            if (keymap_config.swap_backslash_backspace) {
                return keycode_to_action(KC_BSLASH);
            }
            return keycode_to_action(KC_BSPACE);
#endif
        default:
            return keycode_to_action(keycode);
    }
}


/* Macro */
__attribute__ ((weak))
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
    return MACRO_NONE;
}

/* Function */
/*                                                         
 * user defined action function                            
 */                                                        
enum function_id {                                         
    PROBLEMATIC_KEY,                                       
};                                                         
                                                           
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
{                                                          
    switch (id) {                                          
        case PROBLEMATIC_KEY:                              
            // when released                               
            if (!record->event.pressed) {                  
                add_key(opt);                              
                send_keyboard_report();                    
                del_key(opt);                              
                send_keyboard_report();                    
            }                                              
            break;                                         
    }                                                      
}                                                          
 
const uint16_t PROGMEM fn_actions[] = {
    [0] = ACTION_LAYER_MOMENTARY(1),       
    [2] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_7),       // for 7& key
    [3] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_MINUS),   // for -_ key 
    [4] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_MPLY), 
    [5] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_F3), 
    [6] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_RCTL), 
    [7] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_F10), 
    [8] = ACTION_FUNCTION_OPT(PROBLEMATIC_KEY, KC_P4), 
};



/* translates keycode to action */
static action_t keycode_to_action(uint8_t keycode)
{
    action_t action;
    switch (keycode) {
        case KC_A ... KC_EXSEL:
        case KC_LCTRL ... KC_RGUI:
            action.code = ACTION_KEY(keycode);
            break;
        case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
            action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
            break;
        case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
            action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
            break;
        case KC_MS_UP ... KC_MS_ACCEL2:
            action.code = ACTION_MOUSEKEY(keycode);
            break;
        case KC_TRNS:
            action.code = ACTION_TRANSPARENT;
            break;
        default:
            action.code = ACTION_NO;
            break;
    }
    return action;
}

#ifdef USE_LEGACY_KEYMAP
/*
 * Legacy keymap support
 *      Consider using new keymap API instead.
 */
__attribute__ ((weak))
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
{
    return keymap_get_keycode(layer, key.row, key.col);
}


/* Legacy keymap support */
__attribute__ ((weak))
action_t keymap_fn_to_action(uint8_t keycode)
{
    action_t action = { .code = ACTION_NO };
    switch (keycode) {
        case KC_FN0 ... KC_FN31:
            {
                uint8_t layer = keymap_fn_layer(FN_INDEX(keycode));
                uint8_t key = keymap_fn_keycode(FN_INDEX(keycode));
                if (key) {
                    action.code = ACTION_LAYER_TAP_KEY(layer, key);
                } else {
                    action.code = ACTION_LAYER_MOMENTARY(layer);
                }
            }
            return action;
        default:
            return action;
    }
}
#endif
Last edited by Ellipse on 27 Oct 2014, 02:48, edited 1 time in total.

User avatar
hasu

27 Oct 2014, 00:45

'Spoiler' is not useful to share code it removes indentation, use 'code' tag plz.

Yes, interrupt should be the way to go now, do you want to write code? I think most of existent code can be reused for this. if you are not sure about the protocol I can give you annotated ROM dump list.

I added the problematic key code but nothing changed: it still only emits the release code when the key is pressed and nothing when the key is released. Maybe there is another way to code "if 08 is received, emit 88 pressed code and 08 release code"? Here is my keymap.c file in the common folder:
As for keymap function you may need to read doc/keymap.md. Add it in your keymap file instead of common/keymap.c and you have to place FN0 and FN1 on '7&' and '-_' key locations of your keymap.

My code will work like this; sends press and release events of *USB keycode* 'KC_7' to host at once when it receives *4704 scancode* '08' of 7& key from your keyboard.

User avatar
hasu

28 Oct 2014, 01:16

hasu wrote: Yes, interrupt should be the way to go now, do you want to write code? I think most of existent code can be reused for this. if you are not sure about the protocol I can give you annotated ROM dump list.
OK. I'm working on interrupt version now and don't see any significant differences in terms of its result yet. But I have parity errors occasionally and its cause is unclear to me yet.

Hang on.

User avatar
hasu

28 Oct 2014, 06:53

This branch has code to handle IBM4704 protocol using interrupt. I couldn't remove parity error completely, I wrote code like; when error comes up it tries to get scancode again with 'resend' command. It works well somehow but not sure this is better than original busywait version.

https://github.com/tmk/tmk_keyboard/tree/ibm4704_ext
https://github.com/tmk/tmk_keyboard/com ... dc245ea22a

Ellipse

02 Nov 2014, 00:00

Thanks Hasu. I downloaded a zip of the new TMK code and ran make to make a new hex file, unaltered just to see if the main 62 key section of my 107 key 4704 keyboard still has skipped keys.

Unfortunately there is more skipping with the updated code than with the original version.

User avatar
idollar
i$

02 Nov 2014, 01:11

Hello,

Thanks for all the work !

One question: I have not found in the code any reference to "auxiliary" LEDs. I have procured an IBM 122 without LEDs. I thought that I could add some CapsLoc and NumLock LEDs.

Have I missed something ?

I am also trying to use "hid_listen". I have the Magic key well configured (I can lock the keyboard), CONSOLE_ENABLE=yes but still does not connects. Am I again missing something ?

Many thanks

i$

User avatar
hasu

02 Nov 2014, 03:00

Ellipse wrote: Thanks Hasu. I downloaded a zip of the new TMK code and ran make to make a new hex file, unaltered just to see if the main 62 key section of my 107 key 4704 keyboard still has skipped keys.

Unfortunately there is more skipping with the updated code than with the original version.
Thanks for testing.
We will need some another eyes to evolve this, now. I'll post our result on 4704 converter thread on Geekhack.

User avatar
hasu

02 Nov 2014, 03:17

Which firmware are you using? PS/2 converter or Terminal converter?
Both support control of LED indicator of lock keys on each protocol and you can find code in led.c. With change code of led.c you will be able to control you own LEDs.

Your 122 is model M or F?
If it is M you may suffer from 2KRO limit of membrane switch. Probably you can avoid this with using Lcontrol+Rshift or Ralt+Rcontrol instead of Lshift + Rshift. Or you can change IS_COMMAND macro in config.h.

Hope it helps.
idollar wrote: Hello,

Thanks for all the work !

One question: I have not found in the code any reference to "auxiliary" LEDs. I have procured an IBM 122 without LEDs. I thought that I could add some CapsLoc and NumLock LEDs.

Have I missed something ?

I am also trying to use "hid_listen". I have the Magic key well configured (I can lock the keyboard), CONSOLE_ENABLE=yes but still does not connects. Am I again missing something ?

Many thanks

i$

User avatar
idollar
i$

02 Nov 2014, 08:17

Hello again:

Thanks for your answer. It is clear that I have not explained myself properly. Sorry.

I am testing your firmware/s with a ps2, awaiting for my IBM 122 keys to arrive. I still do not have the 122 but I wanted to test it before.

The first question (auxiliary LEDs):

I am testing this because my future IBM-122 does not have led indicators.
At the minute am testing the ps2-usb with a ps2 keyboard

I would like to add three leds (with resistors) additional to the ones that the keyboard already has, in the box in which I have installed my electronics, outside the keyboard. But I have seen no reference to the pins in the teensy that I should use in config.h.

Currently, I am physically testing the ps2-usb converter (with a ps2 keyboard). Reading the code (led.c) I believe that this is not supported by the firmware. I also searched in the terminal-usb code for the support. I could not find it.

Is this feature supported ? Am I missing something ?

Regarding the second question - hid_listen:

Using my ps2 keyboard still and the ps2-usb converter.

I install various versions of the firmware and they works. I have tried the LUFA and the PJRC (un-supported) versions, with both, the PS2_USE_USART and PS2_USE_INT options.
I have confirmed that the "CONSOLE_ENABLE = yes" is set.
I could confirm that the "magic" key works. I can lock the keyboard using (RSHIFT-LSHIFT-Caps).

Until here no problem.

I then start "hid_listen" in a terminal. Press "RSHIFT-LSHIFT-h but nothing is shown in the screen. I keep receiving "Waiting for device:........".

What am I doing wrong ?

Many thanks in advance.

i$

User avatar
hasu

02 Nov 2014, 11:38

1)
TMK converter doesn't support external LEDs by default, you need to write code yourself. If you want to use the LEDs as normal indicators like caps lock, scroll lock, and num lock, you should place the code in led.c.

2)
Seems to me like Rshift+LShift+h doesn't work due to your keyboard limitation of key roll over(KRO).
What kind of keyboard are you using with converter? Membrane switch or Mechanical switch? Keyboard has diodes?

Or does hid_listen really work? It displays something?
If you are on Unix like system you will need super user privilege to execute the command.

Post Reply

Return to “Workshop”