1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

自作トラックポイント1

Last updated at Posted at 2021-01-24

さて分割キーボードもひと段落したので次の課題に取り組もうと思う。

トラックポイントを分割キーボードの右側に取り付けたい。

gammy_basic.png

普通のThinkpadキーボードはH,J,Nの間にあるが、狭いし
ちょうど基盤の回路を引いた線が邪魔で穴があけられない。次回Kicadで設計するときは避けるようにしよう。

トラックポイントの生贄

thinkpad1.jpg

すでに壊れてたので、本物のthinkpadキーボードから部品を拝借。

開封

thinkpad2.jpg

Trackポイント ハック

上のサイトからどれが何ピンなのか理解する

以降写真撮り忘れたが、

ファームウェアを焼く

トラックポイントの実装

今回はQMKFirmwareにPS2 Mouseで接続する方法が載ってる
https://github.com/qmk/qmk_firmware/blob/master/docs/ja/feature_ps2_mouse.md

マウスホイールの実装

以下は実際に動いたサンプルソース

rules.mk

# トラックポイント接続用設定
PS2_MOUSE_ENABLE = yes
PS2_USE_BUSYWAIT = yes # <- 非推奨だが、空きポートを確保できないためこれで
#PS2_USE_INT = yes
#PS2_USE_USART = yes
OLED_DRIVER_ENABLE = no


# スクロールホイール用
MOUSEKEY_ENABLE = yes
ENCODER_ENABLE = yes

config.h


#pragma once


/*
 * Busywait Version :id=busywait-version
 * Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
 */

/*
トラックポイント接続はここでハマった。PORTD,PIND,DDRDと公式ドキュメントに例が載ってるが、
CLOCK_BITの数字がPromicroのピン番号を表しているのかと思ったらそうではなかった。

最後のアルファベットが例えばATMega32U4上のD3ピンに接続したければ最後の一文字を「D」とし
PS2_CLOCK_BIT   3とするということだった。
これがドキュメント見ても理解できず時間を無駄にした。
QMKのドキュメントは説明が全然足りないよ。
 */

#ifdef PS2_USE_BUSYWAIT
#   define PS2_CLOCK_PORT  PORTD
#   define PS2_CLOCK_PIN   PIND
#   define PS2_CLOCK_DDR   DDRD
#   define PS2_CLOCK_BIT   3
#   define PS2_DATA_PORT   PORTB
#   define PS2_DATA_PIN    PINB
#   define PS2_DATA_DDR    DDRB
#   define PS2_DATA_BIT    1
#endif



/*
 * Interrupt Version :id=interrupt-version
 * The following example uses B5 for clock and B6 for data. You can use any INT or PCINT pin for clock, and any pin for data.
 */

#ifdef PS2_USE_INT
#   define PS2_CLOCK_PORT  PORTB
#   define PS2_CLOCK_PIN   PINB
#   define PS2_CLOCK_DDR   DDRB
#   define PS2_CLOCK_BIT   5
#   define PS2_DATA_PORT   PORTB
#   define PS2_DATA_PIN    PINB
#   define PS2_DATA_DDR    DDRB
#   define PS2_DATA_BIT    6

#   define PS2_INT_INIT()  do {    \
       PCICR |= (1<<PCIE0);        \
    } while (0)
#   define PS2_INT_ON()  do {      \
       PCMSK0 |= (1<<PCINT5);      \
    } while (0)
#   define PS2_INT_OFF() do {      \
       PCMSK0 &= ~(1<<PCINT5);     \
    } while (0)
#   define PS2_INT_VECT   PCINT0_vect
#endif

/*
 * USART Version :id=usart-version
 * To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
 *   synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge
 *   set DDR of CLOCK as input to be slave
 */

#ifdef PS2_USE_USART
#   define PS2_CLOCK_PORT  PORTD
#   define PS2_CLOCK_PIN   PIND
#   define PS2_CLOCK_DDR   DDRD
#   define PS2_CLOCK_BIT   5
#   define PS2_DATA_PORT   PORTD
#   define PS2_DATA_PIN    PIND
#   define PS2_DATA_DDR    DDRD
#   define PS2_DATA_BIT    2

#   define PS2_USART_INIT() do {   \
       PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);   \
       PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);     \
       UCSR1C = ((1 << UMSEL10) |  \
                 (3 << UPM10)   |  \
                 (0 << USBS1)   |  \
                 (3 << UCSZ10)  |  \
                 (0 << UCPOL1));   \
       UCSR1A = 0;                 \
       UBRR1H = 0;                 \
       UBRR1L = 0;                 \
    } while (0)
#   define PS2_USART_RX_INT_ON() do {  \
       UCSR1B = ((1 << RXCIE1) |       \
                 (1 << RXEN1));        \
    } while (0)
#   define PS2_USART_RX_POLL_ON() do { \
       UCSR1B = (1 << RXEN1);          \
    } while (0)
#   define PS2_USART_OFF() do {    \
       UCSR1C = 0;                 \
       UCSR1B &= ~((1 << RXEN1) |  \
                   (1 << TXEN1));  \
    } while (0)
#   define PS2_USART_RX_READY      (UCSR1A & (1<<RXC1))
#   define PS2_USART_RX_DATA       UDR1
#   define PS2_USART_ERROR         (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
#   define PS2_USART_RX_VECT       USART1_RX_vect
#endif


#ifdef ENCODER_ENABLE
#  define ENCODERS_PAD_A { F6 }
#  define ENCODERS_PAD_B { F7 }

#  define ENCODER_RESOLUTION 2

#endif

keymap.c

#include QMK_KEYBOARD_H
#include "keymap.h"

// Defines names for use in layer keycodes and the keymap
enum layer_names {
    _BASE
};

// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
    QMKBEST = SAFE_RANGE,
    QMKURL
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* Base */
    [_BASE] = LAYOUT(
        KC_A, KC_B, \
        KC_C, KC_D \
    )
};



bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {

  }
  return true;
}

void matrix_init_user(void) {
	// put your keyboard start-up code here
	// runs once when the firmware starts up
}

void matrix_scan_user(void) {
	// put your looping keyboard code here
	// runs every cycle (a lot)
}

void encoder_update_user(uint8_t index, bool clockwise) {
    // put your scroll wheel
    
    if (index == 0) { /* First encoder */
        if (clockwise) {
            tap_code(KC_MS_WH_DOWN);
        } else {
            tap_code(KC_MS_WH_UP);
        }
    } else if (index == 1) { /* Second encoder */
        if (clockwise) {
            tap_code(KC_DOWN);
        } else {
            tap_code(KC_UP);
        }
    }
}

ブレッドボードに組み込んだ様子

ごちゃごちゃだけど、キーボードも、トラックポイントもマウスホイールもちゃんと動く。

IMG_20210126_224741.jpg

IMG_20210126_224752.jpg

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?