Compare commits
16 Commits
main
...
hardware/p
Author | SHA1 | Date |
---|---|---|
Gergely Nagy | 6db44b88ba | 2 years ago |
Gergely Nagy | 0d9550a5cb | 2 years ago |
Gergely Nagy | 9fbb820638 | 2 years ago |
Gergely Nagy | d5e75e2ed7 | 2 years ago |
Gergely Nagy | 7939dc015a | 2 years ago |
Gergely Nagy | 0926aba479 | 2 years ago |
Gergely Nagy | 31e4a54e3c | 2 years ago |
Gergely Nagy | d81cdaeb77 | 2 years ago |
Gergely Nagy | 4f98813695 | 2 years ago |
Gergely Nagy | 6033b05cba | 2 years ago |
Gergely Nagy | f87ff8ae18 | 2 years ago |
Gergely Nagy | 4c10038dbb | 2 years ago |
Gergely Nagy | 63d96c0059 | 2 years ago |
Gergely Nagy | 2464ef59db | 2 years ago |
Gergely Nagy | 0944fc3b1e | 2 years ago |
Gergely Nagy | 4ef189c0b1 | 2 years ago |
@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# focus-send - Trivial Focus testing tool
|
||||
# Copyright (C) 2018-2022 Keyboard.io, Inc.
|
||||
#
|
||||
# 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, version 3.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
set -e
|
||||
|
||||
OS=$(uname -s)
|
||||
|
||||
# igncr absorbs CR from Focus CRLF line endings
|
||||
# -echo is needed because raw doesn't turn it off on Linux
|
||||
STTY_ARGS="9600 raw igncr -echo"
|
||||
|
||||
case ${OS} in
|
||||
Linux)
|
||||
DEVICE="${DEVICE:-/dev/ttyACM0}"
|
||||
;;
|
||||
Darwin)
|
||||
# bash on macOS has a bug that randomly drops serial input
|
||||
if [ -n "$BASH_VERSION" ] && [ -x /bin/dash ]; then
|
||||
# Prevent loop in case someone exported it
|
||||
export -n BASH_VERSION
|
||||
exec /bin/dash "$0" "$@"
|
||||
fi
|
||||
DEVICE="${DEVICE:-/dev/cu.usbmodemCkbio01E}"
|
||||
;;
|
||||
*)
|
||||
echo "Error Unknown OS : ${OS}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Redirect prior to running stty, because macOS sometimes resets termios
|
||||
# state upon last close of a terminal device.
|
||||
exec < "${DEVICE}"
|
||||
# shellcheck disable=SC2086 # intentional word splitting
|
||||
stty $STTY_ARGS
|
||||
|
||||
read_reply () {
|
||||
while read -r line; do
|
||||
if [ "${line}" = "." ]; then
|
||||
break
|
||||
fi
|
||||
echo "${line}"
|
||||
done
|
||||
}
|
||||
|
||||
# Flush any invalid commands out of input buffer.
|
||||
# This could happen after a failed upload.
|
||||
echo ' ' > "${DEVICE}"
|
||||
read_reply > /dev/null
|
||||
echo "$@" >"${DEVICE}"
|
||||
read_reply
|
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# focus-test - Trivial Focus testing tool
|
||||
# Copyright (C) 2018 Keyboard.io, Inc.
|
||||
#
|
||||
# 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, version 3.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
set -e
|
||||
|
||||
OS=$(uname -s)
|
||||
|
||||
case ${OS} in
|
||||
Linux)
|
||||
DEVICE="${DEVICE:-/dev/ttyACM0}"
|
||||
stty -F "${DEVICE}" 9600 raw -echo
|
||||
;;
|
||||
Darwin)
|
||||
DEVICE="${DEVICE:-/dev/cu.usbmodemCkbio01E}"
|
||||
stty -f "${DEVICE}" 9600 raw -echo
|
||||
;;
|
||||
*)
|
||||
echo "Error Unknown OS : ${OS}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
exec 3<"${DEVICE}"
|
||||
echo "$@" >"${DEVICE}"
|
||||
|
||||
while read -r line <&3; do
|
||||
line="$(echo -n "${line}" | tr -d '\r')"
|
||||
if [ "${line}" == "." ]; then
|
||||
break
|
||||
fi
|
||||
echo "${line}"
|
||||
done
|
@ -0,0 +1,48 @@
|
||||
# This makefile for a Kaleidoscope sketch pulls in all the targets
|
||||
# required to build the example
|
||||
|
||||
|
||||
|
||||
|
||||
ifneq ($(KALEIDOSCOPE_DIR),)
|
||||
search_path += $(KALEIDOSCOPE_DIR)
|
||||
endif
|
||||
|
||||
ifneq ($(ARDUINO_DIRECTORIES_USER),)
|
||||
search_path += $(ARDUINO_DIRECTORIES_USER)/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
search_path += $(HOME)/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
else
|
||||
search_path += $(HOME)/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
sketch_makefile := etc/makefiles/sketch.mk
|
||||
|
||||
$(foreach candidate, $(search_path), $(if $(wildcard $(candidate)/$(sketch_makefile)), $(eval ks_dir ?= $(candidate))))
|
||||
|
||||
ifneq ($(ks_dir),)
|
||||
|
||||
$(info Using Kaleidoscope from $(ks_dir))
|
||||
|
||||
export KALEIDOSCOPE_DIR := $(ks_dir)
|
||||
include $(ks_dir)/$(sketch_makefile)
|
||||
|
||||
else
|
||||
|
||||
$(info I can't find your Kaleidoscope installation.)
|
||||
$(info )
|
||||
$(info I tried looking in:)
|
||||
$(info )
|
||||
$(foreach candidate, $(search_path), $(info $(candidate)))
|
||||
$(info )
|
||||
$(info The easiest way to fix this is to set the 'KALEIDOSCOPE_DIR' environment)
|
||||
$(info variable to the location of your Kaleidoscope directory.)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
null-target:
|
||||
$(info You should never see this message)
|
||||
@:
|
@ -0,0 +1,120 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
#include <stdint.h> // for uint16_t, uint8_t
|
||||
|
||||
#include "pins_and_ports.h" // IWYU pragma: keep
|
||||
#include <avr/wdt.h>
|
||||
|
||||
extern "C" {
|
||||
#include "adns5050.h"
|
||||
}
|
||||
|
||||
#define BOOTLOADER_RESET_KEY 0xB007B007
|
||||
static uint32_t reset_key __attribute__((section(".noinit")));
|
||||
|
||||
/*
|
||||
* This function runs before main(), and jumps to the bootloader after a reset
|
||||
* initiated by .resetDevice().
|
||||
*/
|
||||
static void _bootloader_jump_after_watchdog_reset()
|
||||
__attribute__((used, naked, section(".init3")));
|
||||
static void _bootloader_jump_after_watchdog_reset() {
|
||||
if ((MCUSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
|
||||
reset_key = 0;
|
||||
|
||||
((void (*)(void))(((FLASHEND + 1L) - 4096) >> 1))();
|
||||
}
|
||||
}
|
||||
|
||||
void rebootBootloader() {
|
||||
reset_key = BOOTLOADER_RESET_KEY;
|
||||
wdt_enable(WDTO_250MS);
|
||||
while (true) {} // This infinite loop ensures nothing else
|
||||
// happens before the watchdog reboots us
|
||||
}
|
||||
|
||||
static constexpr uint8_t direct_pins[5] = {PIN_D4, PIN_D2, PIN_E6, PIN_B6, PIN_D7};
|
||||
static constexpr uint8_t unused_pins[14] = {PIN_B5, PIN_C7, PIN_D0, PIN_D1, PIN_D3, PIN_D5, PIN_D6, PIN_F1, PIN_F3, PIN_F5, PIN_F6, PIN_F7, PIN_F0, PIN_F4};
|
||||
|
||||
void mcuSetup() {
|
||||
wdt_disable();
|
||||
|
||||
// disable jtag
|
||||
MCUCR |= (1 << JTD);
|
||||
MCUCR |= (1 << JTD);
|
||||
|
||||
// disable clock division
|
||||
CLKPR = (1 << CLKPCE);
|
||||
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
|
||||
}
|
||||
|
||||
void buttonSetup() {
|
||||
// Initialize keyscanner
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(unused_pins); i++) {
|
||||
DDR_OUTPUT(unused_pins[i]);
|
||||
DISABLE_PULLUP(unused_pins[i]);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(direct_pins); i++) {
|
||||
DDR_INPUT(direct_pins[i]);
|
||||
ENABLE_PULLUP(direct_pins[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
mcuSetup();
|
||||
Serial.begin(9600);
|
||||
buttonSetup();
|
||||
|
||||
adns5050_init();
|
||||
//delay(100);
|
||||
//adns5050_sync();
|
||||
adns5050_set_cpi(CPI375);
|
||||
//adns5050_read_burst();
|
||||
|
||||
while (!Serial);
|
||||
|
||||
uint8_t pid = adns5050_read_reg(0x00);
|
||||
uint8_t rid = adns5050_read_reg(0x01);
|
||||
uint8_t pid2 = adns5050_read_reg(0x3e);
|
||||
|
||||
Serial.print("pid=");
|
||||
Serial.print(pid, HEX);
|
||||
Serial.print("; rid=");
|
||||
Serial.print(rid, HEX);
|
||||
Serial.print("; pid2=");
|
||||
Serial.println(pid2);
|
||||
}
|
||||
|
||||
void handleSerial() {
|
||||
if (Serial.available() == 0) return;
|
||||
|
||||
uint8_t b = Serial.read();
|
||||
|
||||
if (b == 'r') rebootBootloader();
|
||||
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
handleSerial();
|
||||
|
||||
#if 1
|
||||
report_adns5050_t r = adns5050_read_burst();
|
||||
if (r.dx != 0 || r.dy != 0) {
|
||||
Serial.println(r.dx);
|
||||
Serial.println(r.dy);
|
||||
}
|
||||
#else
|
||||
|
||||
uint8_t dx = adns5050_read_reg(0x03); // DELTA_X
|
||||
uint8_t dy = adns5050_read_reg(0x04); // DELTA_Y
|
||||
|
||||
Serial.print(dx);
|
||||
Serial.print(",");
|
||||
Serial.println(dy);
|
||||
#endif
|
||||
|
||||
delay(10);
|
||||
}
|
@ -0,0 +1,238 @@
|
||||
/* Copyright 2021 Colin Lam (Ploopy Corporation)
|
||||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||
* Copyright 2019 Sunjun Kim
|
||||
* Copyright 2019 Hiroyuki Okada
|
||||
*
|
||||
* 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 "adns5050.h"
|
||||
#include "Arduino.h"
|
||||
#include "pins_and_ports.h"
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#define wait_ms(ms) \
|
||||
do { \
|
||||
if (__builtin_constant_p(ms)) { \
|
||||
_delay_ms(ms); \
|
||||
} else { \
|
||||
for (uint16_t i = ms; i > 0; i--) { \
|
||||
_delay_ms(1); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define wait_us(us) \
|
||||
do { \
|
||||
if (__builtin_constant_p(us)) { \
|
||||
_delay_us(us); \
|
||||
} else { \
|
||||
for (uint16_t i = us; i > 0; i--) { \
|
||||
_delay_us(1); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Registers
|
||||
// clang-format off
|
||||
#define REG_PRODUCT_ID 0x00
|
||||
#define REG_REVISION_ID 0x01
|
||||
#define REG_MOTION 0x02
|
||||
#define REG_DELTA_X 0x03
|
||||
#define REG_DELTA_Y 0x04
|
||||
#define REG_SQUAL 0x05
|
||||
#define REG_SHUTTER_UPPER 0x06
|
||||
#define REG_SHUTTER_LOWER 0x07
|
||||
#define REG_MAXIMUM_PIXEL 0x08
|
||||
#define REG_PIXEL_SUM 0x09
|
||||
#define REG_MINIMUM_PIXEL 0x0a
|
||||
#define REG_PIXEL_GRAB 0x0b
|
||||
#define REG_MOUSE_CONTROL 0x0d
|
||||
#define REG_MOUSE_CONTROL2 0x19
|
||||
#define REG_LED_DC_MODE 0x22
|
||||
#define REG_CHIP_RESET 0x3a
|
||||
#define REG_PRODUCT_ID2 0x3e
|
||||
#define REG_INV_REV_ID 0x3f
|
||||
#define REG_MOTION_BURST 0x63
|
||||
// clang-format on
|
||||
|
||||
void adns5050_init(void) {
|
||||
// Initialize the ADNS serial pins.
|
||||
DDR_OUTPUT(ADNS5050_SCLK_PIN);
|
||||
DDR_OUTPUT(ADNS5050_SDIO_PIN);
|
||||
DDR_OUTPUT(ADNS5050_CS_PIN);
|
||||
|
||||
// reboot the adns.
|
||||
// if the adns hasn't initialized yet, this is harmless.
|
||||
adns5050_write_reg(REG_CHIP_RESET, 0x5a);
|
||||
|
||||
// wait maximum time before adns is ready.
|
||||
// this ensures that the adns is actuall ready after reset.
|
||||
wait_ms(55);
|
||||
|
||||
// read a burst from the adns and then discard it.
|
||||
// gets the adns ready for write commands
|
||||
// (for example, setting the dpi).
|
||||
adns5050_read_burst();
|
||||
}
|
||||
|
||||
// Perform a synchronization with the ADNS.
|
||||
// Just as with the serial protocol, this is used by the slave to send a
|
||||
// synchronization signal to the master.
|
||||
void adns5050_sync(void) {
|
||||
OUTPUT_LOW(ADNS5050_CS_PIN);
|
||||
wait_us(1);
|
||||
OUTPUT_HIGH(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
void adns5050_cs_select(void) {
|
||||
OUTPUT_LOW(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
void adns5050_cs_deselect(void) {
|
||||
OUTPUT_HIGH(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
uint8_t adns5050_serial_read(void) {
|
||||
DDR_INPUT(ADNS5050_SDIO_PIN);
|
||||
DISABLE_PULLUP(ADNS5050_SDIO_PIN);
|
||||
|
||||
uint8_t byte = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
OUTPUT_LOW(ADNS5050_SCLK_PIN);
|
||||
wait_us(1);
|
||||
|
||||
byte = (byte << 1) | READ_PIN(ADNS5050_SDIO_PIN);
|
||||
|
||||
OUTPUT_HIGH(ADNS5050_SCLK_PIN);
|
||||
wait_us(1);
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
void adns5050_serial_write(uint8_t data) {
|
||||
DDR_OUTPUT(ADNS5050_SDIO_PIN);
|
||||
|
||||
for (int8_t b = 7; b >= 0; b--) {
|
||||
OUTPUT_LOW(ADNS5050_SCLK_PIN);
|
||||
|
||||
if (data & (1 << b))
|
||||
OUTPUT_HIGH(ADNS5050_SDIO_PIN);
|
||||
else
|
||||
OUTPUT_LOW(ADNS5050_SDIO_PIN);
|
||||
|
||||
wait_us(2);
|
||||
|
||||
OUTPUT_HIGH(ADNS5050_SCLK_PIN);
|
||||
}
|
||||
|
||||
// tSWR. See page 15 of the ADNS spec sheet.
|
||||
// Technically, this is only necessary if the next operation is an SDIO
|
||||
// read. This is not guaranteed to be the case, but we're being lazy.
|
||||
wait_us(4);
|
||||
|
||||
// Note that tSWW is never necessary. All write operations require at
|
||||
// least 32us, which exceeds tSWW, so there's never a need to wait for it.
|
||||
}
|
||||
|
||||
// Read a byte of data from a register on the ADNS.
|
||||
// Don't forget to use the register map (as defined in the header file).
|
||||
uint8_t adns5050_read_reg(uint8_t reg_addr) {
|
||||
adns5050_cs_select();
|
||||
|
||||
adns5050_serial_write(reg_addr);
|
||||
|
||||
// We don't need a minimum tSRAD here. That's because a 4ms wait time is
|
||||
// already included in adns5050_serial_write(), so we're good.
|
||||
// See page 10 and 15 of the ADNS spec sheet.
|
||||
// wait_us(4);
|
||||
|
||||
uint8_t byte = adns5050_serial_read();
|
||||
|
||||
// tSRW & tSRR. See page 15 of the ADNS spec sheet.
|
||||
// Technically, this is only necessary if the next operation is an SDIO
|
||||
// read or write. This is not guaranteed to be the case.
|
||||
// Honestly, this wait could probably be removed.
|
||||
wait_us(1);
|
||||
|
||||
adns5050_cs_deselect();
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
void adns5050_write_reg(uint8_t reg_addr, uint8_t data) {
|
||||
adns5050_cs_select();
|
||||
adns5050_serial_write(0b10000000 | reg_addr);
|
||||
adns5050_serial_write(data);
|
||||
adns5050_cs_deselect();
|
||||
}
|
||||
|
||||
report_adns5050_t adns5050_read_burst(void) {
|
||||
adns5050_cs_select();
|
||||
|
||||
report_adns5050_t data;
|
||||
data.dx = 0;
|
||||
data.dy = 0;
|
||||
|
||||
adns5050_serial_write(REG_MOTION_BURST);
|
||||
wait_us(4);
|
||||
|
||||
// We don't need a minimum tSRAD here. That's because a 4ms wait time is
|
||||
// already included in adns5050_serial_write(), so we're good.
|
||||
// See page 10 and 15 of the ADNS spec sheet.
|
||||
// wait_us(4);
|
||||
|
||||
uint8_t x = adns5050_serial_read();
|
||||
uint8_t y = adns5050_serial_read();
|
||||
|
||||
// Burst mode returns a bunch of other shit that we don't really need.
|
||||
// Setting CS to high ends burst mode early.
|
||||
adns5050_cs_deselect();
|
||||
|
||||
data.dx = convert_twoscomp(x);
|
||||
data.dy = convert_twoscomp(y);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// Convert a two's complement byte from an unsigned data type into a signed
|
||||
// data type.
|
||||
int8_t convert_twoscomp(uint8_t data) {
|
||||
if ((data & 0x80) == 0x80)
|
||||
return -128 + (data & 0x7F);
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
// Don't forget to use the definitions for CPI in the header file.
|
||||
void adns5050_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / 125), 0x1, 0xD); // limits to 0--119
|
||||
|
||||
adns5050_write_reg(REG_MOUSE_CONTROL2, 0b10000 | cpival);
|
||||
}
|
||||
|
||||
uint16_t adns5050_get_cpi(void) {
|
||||
uint8_t cpival = adns5050_read_reg(REG_MOUSE_CONTROL2);
|
||||
return (uint16_t)((cpival & 0b10000) * 125);
|
||||
}
|
||||
|
||||
bool adns5050_check_signature(void) {
|
||||
uint8_t pid = adns5050_read_reg(REG_PRODUCT_ID);
|
||||
uint8_t rid = adns5050_read_reg(REG_REVISION_ID);
|
||||
uint8_t pid2 = adns5050_read_reg(REG_PRODUCT_ID2);
|
||||
|
||||
return (pid == 0x12 && rid == 0x01 && pid2 == 0x26);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/* Copyright 2021 Colin Lam (Ploopy Corporation)
|
||||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||
* Copyright 2019 Sunjun Kim
|
||||
* Copyright 2019 Hiroyuki Okada
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "pins_and_ports.h"
|
||||
|
||||
// CPI values
|
||||
// clang-format off
|
||||
#define CPI125 0x11
|
||||
#define CPI250 0x12
|
||||
#define CPI375 0x13
|
||||
#define CPI500 0x14
|
||||
#define CPI625 0x15
|
||||
#define CPI750 0x16
|
||||
#define CPI875 0x17
|
||||
#define CPI1000 0x18
|
||||
#define CPI1125 0x19
|
||||
#define CPI1250 0x1a
|
||||
#define CPI1375 0x1b
|
||||
// clang-format on
|
||||
|
||||
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
|
||||
|
||||
#if 0
|
||||
// Definitions for the ADNS serial line.
|
||||
#ifndef ADNS5050_SCLK_PIN
|
||||
# error "No clock pin defined -- missing ADNS5050_SCLK_PIN"
|
||||
#endif
|
||||
|
||||
#ifndef ADNS5050_SDIO_PIN
|
||||
# error "No data pin defined -- missing ADNS5050_SDIO_PIN"
|
||||
#endif
|
||||
|
||||
#ifndef ADNS5050_CS_PIN
|
||||
# error "No chip select pin defined -- missing ADNS5050_CS_PIN"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ADNS5050_SCLK_PIN PIN_B7
|
||||
#define ADNS5050_SDIO_PIN PIN_C6
|
||||
#define ADNS5050_CS_PIN PIN_B4
|
||||
|
||||
typedef struct {
|
||||
int8_t dx;
|
||||
int8_t dy;
|
||||
} report_adns5050_t;
|
||||
|
||||
// A bunch of functions to implement the ADNS5050-specific serial protocol.
|
||||
// Note that the "serial.h" driver is insufficient, because it does not
|
||||
// manually manipulate a serial clock signal.
|
||||
void adns5050_init(void);
|
||||
void adns5050_sync(void);
|
||||
uint8_t adns5050_serial_read(void);
|
||||
void adns5050_serial_write(uint8_t data);
|
||||
uint8_t adns5050_read_reg(uint8_t reg_addr);
|
||||
void adns5050_write_reg(uint8_t reg_addr, uint8_t data);
|
||||
report_adns5050_t adns5050_read_burst(void);
|
||||
void adns5050_set_cpi(uint16_t cpi);
|
||||
uint16_t adns5050_get_cpi(void);
|
||||
int8_t convert_twoscomp(uint8_t data);
|
||||
bool adns5050_check_signature(void);
|
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
echo "* Building"
|
||||
make OUTPUT_PATH=$(pwd)/_build
|
||||
|
||||
echo "* Jumping to bootloader..."
|
||||
DEVICE=/dev/ttyACM1 focus r
|
||||
sleep 2s
|
||||
|
||||
echo "* Flashing..."
|
||||
dfu-programmer atmega32u4 erase && dfu-programmer atmega32u4 flash _build/*-latest.hex && dfu-programmer atmega32u4 start
|
@ -0,0 +1,164 @@
|
||||
/* This file originated in QMK. https://github.com/qmk/qmk_firmware
|
||||
* quantum/config_common.h 73e634482ea8f57d1f1a5f1e16bc3ffd74f84b8e
|
||||
*
|
||||
* Original copyright statement:
|
||||
*
|
||||
* Copyright 2015-2018 Jack Humbert
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__ASSEMBLER__) && !defined(KALEIDOSCOPE_VIRTUAL_BUILD)
|
||||
#include <avr/io.h>
|
||||
#endif
|
||||
#define PORT_SHIFTER 4 // this may be 4 for all AVR chips
|
||||
|
||||
// If you want to add more to this list, reference the PINx definitions in these header
|
||||
// files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
|
||||
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
|
||||
#define ADDRESS_BASE 0x00
|
||||
#define PINB_ADDRESS 0x3
|
||||
#define PINC_ADDRESS 0x6
|
||||
#define PIND_ADDRESS 0x9
|
||||
#define PINE_ADDRESS 0xC
|
||||
#define PINF_ADDRESS 0xF
|
||||
#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__)
|
||||
#define ADDRESS_BASE 0x00
|
||||
#define PINB_ADDRESS 0x3
|
||||
#define PINC_ADDRESS 0x6
|
||||
#define PIND_ADDRESS 0x9
|
||||
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__)
|
||||
#define ADDRESS_BASE 0x00
|
||||
#define PINA_ADDRESS 0x0
|
||||
#define PINB_ADDRESS 0x3
|
||||
#define PINC_ADDRESS 0x6
|
||||
#define PIND_ADDRESS 0x9
|
||||
#define PINE_ADDRESS 0xC
|
||||
#define PINF_ADDRESS 0xF
|
||||
#elif defined(__AVR_ATmega32A__)
|
||||
#define ADDRESS_BASE 0x10
|
||||
#define PIND_ADDRESS 0x0
|
||||
#define PINC_ADDRESS 0x3
|
||||
#define PINB_ADDRESS 0x6
|
||||
#define PINA_ADDRESS 0x9
|
||||
#elif !defined(KALEIDOSCOPE_VIRTUAL_BUILD)
|
||||
#error "Pins are not defined"
|
||||
#endif
|
||||
|
||||
/* I/O pins */
|
||||
#ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
#define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin)
|
||||
#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
#define PINDEF(port, pin) 0
|
||||
#define PORTA
|
||||
#define PORTB
|
||||
#define PORTC
|
||||
#define PORTD
|
||||
#define PORTE
|
||||
#define PORTF
|
||||
#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
|
||||
#ifdef PORTA
|
||||
#define PIN_A0 PINDEF(A, 0)
|
||||
#define PIN_A1 PINDEF(A, 1)
|
||||
#define PIN_A2 PINDEF(A, 2)
|
||||
#define PIN_A3 PINDEF(A, 3)
|
||||
#define PIN_A4 PINDEF(A, 4)
|
||||
#define PIN_A5 PINDEF(A, 5)
|
||||
#define PIN_A6 PINDEF(A, 6)
|
||||
#define PIN_A7 PINDEF(A, 7)
|
||||
#endif
|
||||
#ifdef PORTB
|
||||
#define PIN_B0 PINDEF(B, 0)
|
||||
#define PIN_B1 PINDEF(B, 1)
|
||||
#define PIN_B2 PINDEF(B, 2)
|
||||
#define PIN_B3 PINDEF(B, 3)
|
||||
#define PIN_B4 PINDEF(B, 4)
|
||||
#define PIN_B5 PINDEF(B, 5)
|
||||
#define PIN_B6 PINDEF(B, 6)
|
||||
#define PIN_B7 PINDEF(B, 7)
|
||||
#endif
|
||||
#ifdef PORTC
|
||||
#define PIN_C0 PINDEF(C, 0)
|
||||
#define PIN_C1 PINDEF(C, 1)
|
||||
#define PIN_C2 PINDEF(C, 2)
|
||||
#define PIN_C3 PINDEF(C, 3)
|
||||
#define PIN_C4 PINDEF(C, 4)
|
||||
#define PIN_C5 PINDEF(C, 5)
|
||||
#define PIN_C6 PINDEF(C, 6)
|
||||
#define PIN_C7 PINDEF(C, 7)
|
||||
#endif
|
||||
#ifdef PORTD
|
||||
#define PIN_D0 PINDEF(D, 0)
|
||||
#define PIN_D1 PINDEF(D, 1)
|
||||
#define PIN_D2 PINDEF(D, 2)
|
||||
#define PIN_D3 PINDEF(D, 3)
|
||||
#define PIN_D4 PINDEF(D, 4)
|
||||
#define PIN_D5 PINDEF(D, 5)
|
||||
#define PIN_D6 PINDEF(D, 6)
|
||||
#define PIN_D7 PINDEF(D, 7)
|
||||
#endif
|
||||
#ifdef PORTE
|
||||
#define PIN_E0 PINDEF(E, 0)
|
||||
#define PIN_E1 PINDEF(E, 1)
|
||||
#define PIN_E2 PINDEF(E, 2)
|
||||
#define PIN_E3 PINDEF(E, 3)
|
||||
#define PIN_E4 PINDEF(E, 4)
|
||||
#define PIN_E5 PINDEF(E, 5)
|
||||
#define PIN_E6 PINDEF(E, 6)
|
||||
#define PIN_E7 PINDEF(E, 7)
|
||||
#endif
|
||||
#ifdef PORTF
|
||||
#define PIN_F0 PINDEF(F, 0)
|
||||
#define PIN_F1 PINDEF(F, 1)
|
||||
#define PIN_F2 PINDEF(F, 2)
|
||||
#define PIN_F3 PINDEF(F, 3)
|
||||
#define PIN_F4 PINDEF(F, 4)
|
||||
#define PIN_F5 PINDEF(F, 5)
|
||||
#define PIN_F6 PINDEF(F, 6)
|
||||
#define PIN_F7 PINDEF(F, 7)
|
||||
#endif
|
||||
|
||||
/* converting pins to ports */
|
||||
enum { PIN_OFFSET,
|
||||
DDR_OFFSET,
|
||||
PORT_OFFSET };
|
||||
|
||||
#define PIN_ADDRESS_MASK 0xF
|
||||
|
||||
#define PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset)
|
||||
#define PIN_REG_FOR_PIN(pin) PIN_ADDRESS(pin, PIN_OFFSET)
|
||||
#define DDR_REG_FOR_PIN(pin) PIN_ADDRESS(pin, DDR_OFFSET)
|
||||
#define PORT_REG_FOR_PIN(pin) PIN_ADDRESS(pin, PORT_OFFSET)
|
||||
#define PIN_NUM_FOR_PIN(pin) (pin & PIN_ADDRESS_MASK)
|
||||
#define PIN_MASK_FOR_PIN(pin) _BV(PIN_NUM_FOR_PIN(pin))
|
||||
|
||||
#define DDR_INPUT(pin) (DDR_REG_FOR_PIN(pin) &= ~(PIN_MASK_FOR_PIN(pin)))
|
||||
#define DDR_OUTPUT(pin) (DDR_REG_FOR_PIN(pin) |= (PIN_MASK_FOR_PIN(pin)))
|
||||
|
||||
|
||||
#define ENABLE_PULLUP(pin) (PORT_REG_FOR_PIN(pin) |= (PIN_MASK_FOR_PIN(pin)))
|
||||
#define DISABLE_PULLUP(pin) (PORT_REG_FOR_PIN(pin) &= ~(PIN_MASK_FOR_PIN(pin)))
|
||||
|
||||
|
||||
#define OUTPUT_HIGH(pin) (PORT_REG_FOR_PIN(pin) |= (PIN_MASK_FOR_PIN(pin)))
|
||||
#define OUTPUT_LOW(pin) (PORT_REG_FOR_PIN(pin) &= ~(PIN_MASK_FOR_PIN(pin)))
|
||||
#define OUTPUT_TOGGLE(pin) (PORT_REG_FOR_PIN(pin) ^= (PIN_MASK_FOR_PIN(pin)))
|
||||
|
||||
#define READ_PIN(pin) (!!(PIN_REG_FOR_PIN(pin) & PIN_MASK_FOR_PIN(pin)))
|
||||
|
||||
#define NO_PIN (uint8_t)(~0)
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cpu": {
|
||||
"fqbn": "keyboardio:avr:ploopy_mini",
|
||||
"port": ""
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
# This makefile for a Kaleidoscope sketch pulls in all the targets
|
||||
# required to build the example
|
||||
|
||||
|
||||
|
||||
|
||||
ifneq ($(KALEIDOSCOPE_DIR),)
|
||||
search_path += $(KALEIDOSCOPE_DIR)
|
||||
endif
|
||||
|
||||
ifneq ($(ARDUINO_DIRECTORIES_USER),)
|
||||
search_path += $(ARDUINO_DIRECTORIES_USER)/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
search_path += $(HOME)/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
else
|
||||
search_path += $(HOME)/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
sketch_makefile := etc/makefiles/sketch.mk
|
||||
|
||||
$(foreach candidate, $(search_path), $(if $(wildcard $(candidate)/$(sketch_makefile)), $(eval ks_dir ?= $(candidate))))
|
||||
|
||||
ifneq ($(ks_dir),)
|
||||
|
||||
$(info Using Kaleidoscope from $(ks_dir))
|
||||
|
||||
export KALEIDOSCOPE_DIR := $(ks_dir)
|
||||
include $(ks_dir)/$(sketch_makefile)
|
||||
|
||||
else
|
||||
|
||||
$(info I can't find your Kaleidoscope installation.)
|
||||
$(info )
|
||||
$(info I tried looking in:)
|
||||
$(info )
|
||||
$(foreach candidate, $(search_path), $(info $(candidate)))
|
||||
$(info )
|
||||
$(info The easiest way to fix this is to set the 'KALEIDOSCOPE_DIR' environment)
|
||||
$(info variable to the location of your Kaleidoscope directory.)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
null-target:
|
||||
$(info You should never see this message)
|
||||
@:
|
@ -0,0 +1,65 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
#include "Kaleidoscope.h"
|
||||
#include "Kaleidoscope-FocusSerial.h"
|
||||
#include "Kaleidoscope-EEPROM-Settings.h"
|
||||
#include "Kaleidoscope-EEPROM-Keymap.h"
|
||||
#include "Kaleidoscope-MouseKeys.h"
|
||||
#include "Kaleidoscope-Macros.h"
|
||||
|
||||
KEYMAPS(
|
||||
[0] = KEYMAP(M(0), Key_B, Key_C, Key_D, Key_E, Key_NoKey),
|
||||
);
|
||||
|
||||
#define OPT_ENC1 PIN_F0
|
||||
#define OPT_ENC2 PIN_F4
|
||||
#define OPT_ENC1_MUX 0
|
||||
#define OPT_ENC2_MUX 4
|
||||
|
||||
void handleEncoder() {
|
||||
uint16_t p1 = analogRead(OPT_ENC1_MUX);
|
||||
uint16_t p2 = analogRead(OPT_ENC2_MUX);
|
||||
|
||||
if (p1 != 0 || p2 != 0) {
|
||||
Focus.send("p1=", p1, "p2=", p2, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
|
||||
if (!keyToggledOn(event.state)) {
|
||||
return MACRO_NONE;
|
||||
}
|
||||
|
||||
switch (macro_id) {
|
||||
case 0:
|
||||
handleEncoder();
|
||||
break;
|
||||
}
|
||||
|
||||
return MACRO_NONE;
|
||||
}
|
||||
|
||||
KALEIDOSCOPE_INIT_PLUGINS(
|
||||
Focus,
|
||||
EEPROMSettings,
|
||||
EEPROMKeymap,
|
||||
MouseKeys,
|
||||
Macros
|
||||
);
|
||||
|
||||
void setup() {
|
||||
Kaleidoscope.setup();
|
||||
EEPROMKeymap.setup(5);
|
||||
|
||||
DDR_INPUT(OPT_ENC1);
|
||||
ENABLE_PULLUP(OPT_ENC1);
|
||||
DDR_INPUT(OPT_ENC2);
|
||||
ENABLE_PULLUP(OPT_ENC2);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Kaleidoscope.loop();
|
||||
|
||||
handleEncoder();
|
||||
delay(10);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
echo "* Building"
|
||||
make OUTPUT_PATH=$(pwd)/_build
|
||||
|
||||
echo "* Jumping to bootloader..."
|
||||
DEVICE=/dev/ttyACM1 focus device.reset
|
||||
sleep 2s
|
||||
|
||||
echo "* Flashing..."
|
||||
dfu-programmer atmega32u4 erase && dfu-programmer atmega32u4 flash _build/*-latest.hex && dfu-programmer atmega32u4 start
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cpu": {
|
||||
"fqbn": "keyboardio:avr:ploopy_mini",
|
||||
"port": ""
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
# This makefile for a Kaleidoscope sketch pulls in all the targets
|
||||
# required to build the example
|
||||
|
||||
|
||||
|
||||
|
||||
ifneq ($(KALEIDOSCOPE_DIR),)
|
||||
search_path += $(KALEIDOSCOPE_DIR)
|
||||
endif
|
||||
|
||||
ifneq ($(ARDUINO_DIRECTORIES_USER),)
|
||||
search_path += $(ARDUINO_DIRECTORIES_USER)/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
search_path += $(HOME)/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
else
|
||||
search_path += $(HOME)/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
|
||||
endif
|
||||
|
||||
sketch_makefile := etc/makefiles/sketch.mk
|
||||
|
||||
$(foreach candidate, $(search_path), $(if $(wildcard $(candidate)/$(sketch_makefile)), $(eval ks_dir ?= $(candidate))))
|
||||
|
||||
ifneq ($(ks_dir),)
|
||||
|
||||
$(info Using Kaleidoscope from $(ks_dir))
|
||||
|
||||
export KALEIDOSCOPE_DIR := $(ks_dir)
|
||||
include $(ks_dir)/$(sketch_makefile)
|
||||
|
||||
else
|
||||
|
||||
$(info I can't find your Kaleidoscope installation.)
|
||||
$(info )
|
||||
$(info I tried looking in:)
|
||||
$(info )
|
||||
$(foreach candidate, $(search_path), $(info $(candidate)))
|
||||
$(info )
|
||||
$(info The easiest way to fix this is to set the 'KALEIDOSCOPE_DIR' environment)
|
||||
$(info variable to the location of your Kaleidoscope directory.)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
null-target:
|
||||
$(info You should never see this message)
|
||||
@:
|
@ -0,0 +1,100 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
#include "Kaleidoscope.h"
|
||||
#include "Kaleidoscope-FocusSerial.h"
|
||||
#include "Kaleidoscope-EEPROM-Settings.h"
|
||||
#include "Kaleidoscope-EEPROM-Keymap.h"
|
||||
#include "Kaleidoscope-MouseKeys.h"
|
||||
#include "Kaleidoscope-Macros.h"
|
||||
|
||||
#include "kaleidoscope/driver/sensor/ADNS5050.h"
|
||||
|
||||
struct PTBMProps : kaleidoscope::driver::sensor::ADNS5050BaseProps {
|
||||
struct pin {
|
||||
static constexpr uint8_t SCLK = PIN_B7;
|
||||
static constexpr uint8_t SDIO = PIN_C6;
|
||||
static constexpr uint8_t NCS = PIN_B4;
|
||||
};
|
||||
};
|
||||
|
||||
typedef kaleidoscope::driver::sensor::ADNS5050<PTBMProps> SensorT;
|
||||
SensorT Sensor;
|
||||
|
||||
KEYMAPS(
|
||||
[0] = KEYMAP(M(0), M(1), M(2), Key_D, Key_E, Key_NoKey),
|
||||
);
|
||||
|
||||
void deltaX() {
|
||||
uint8_t dx = Sensor.readRegister(Sensor.Register::DELTA_X);
|
||||
Serial.print("dx = ");
|
||||
Serial.println(dx);
|
||||
}
|
||||
|
||||
void deltaY() {
|
||||
uint8_t dy = Sensor.readRegister(Sensor.Register::DELTA_Y);
|
||||
Serial.print("dy = ");
|
||||
Serial.println(dy);
|
||||
}
|
||||
|
||||
void getPID() {
|
||||
uint8_t pid = Sensor.readRegister(Sensor.Register::PRODUCT_ID);
|
||||
uint8_t rid = Sensor.readRegister(Sensor.Register::REVISION_ID);
|
||||
uint8_t pid2 = Sensor.readRegister(Sensor.Register::PRODUCT_ID2);
|
||||
Focus.send("pid=", pid, "rid=", rid, "pid2=", pid2, "\n");
|
||||
}
|
||||
|
||||
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
|
||||
if (!keyToggledOn(event.state)) {
|
||||
return MACRO_NONE;
|
||||
}
|
||||
|
||||
switch (macro_id) {
|
||||
case 0:
|
||||
deltaX();
|
||||
break;
|
||||
case 1:
|
||||
deltaY();
|
||||
break;
|
||||
case 2:
|
||||
getPID();
|
||||
break;
|
||||
}
|
||||
|
||||
return MACRO_NONE;
|
||||
}
|
||||
|
||||
KALEIDOSCOPE_INIT_PLUGINS(
|
||||
Focus,
|
||||
EEPROMSettings,
|
||||
EEPROMKeymap,
|
||||
MouseKeys,
|
||||
Macros
|
||||
);
|
||||
|
||||
void setup() {
|
||||
Kaleidoscope.setup();
|
||||
EEPROMKeymap.setup(5);
|
||||
|
||||
Sensor.setup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
SensorT::Report report;
|
||||
|
||||
Kaleidoscope.loop();
|
||||
|
||||
report = Sensor.readReport();
|
||||
|
||||
if (report.dx != -1) {
|
||||
Serial.print("dx = ");
|
||||
Serial.print(report.dx);
|
||||
Serial.print(" ");
|
||||
}
|
||||
if (report.dy != -1) {
|
||||
Serial.print("dy = ");
|
||||
Serial.print(report.dy);
|
||||
}
|
||||
if (report.dy != -1 || report.dx != -1) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
echo "* Building"
|
||||
make OUTPUT_PATH=$(pwd)/_build >/dev/null 2>LOG
|
||||
|
||||
echo "* Jumping to bootloader..."
|
||||
DEVICE=/dev/ttyACM1 focus device.reset
|
||||
sleep 2s
|
||||
|
||||
echo "* Flashing..."
|
||||
dfu-programmer atmega32u4 erase && dfu-programmer atmega32u4 flash _build/PloopyMini-latest.hex && dfu-programmer atmega32u4 start
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cpu": {
|
||||
"fqbn": "keyboardio:avr:ploopy_mini",
|
||||
"port": ""
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
name=Kaleidoscope-LayerNames
|
||||
name=Kaleidoscope-Hardware-Ploopy-Trackball-Mini
|
||||
version=0.0.0
|
||||
sentence=Kaleidoscope plugin that lets one set custom layer names
|
||||
sentence=Ploopy Trackball Mini hardware support for Kaleidoscope
|
||||
maintainer=Kaleidoscope's Developers <jesse@keyboard.io>
|
||||
url=https://github.com/keyboardio/Kaleidoscope
|
||||
author=Keyboardio
|
@ -0,0 +1,21 @@
|
||||
/* -*- mode: c++ -*-
|
||||
* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope/device/ploopy/TrackballMini.h" // IWYU pragma: export
|
@ -0,0 +1,67 @@
|
||||
/* -*- mode: c++ -*-
|
||||
* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc
|
||||
*
|
||||
* 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 3 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 KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
#ifdef ARDUINO_AVR_PLOOPY_MINI
|
||||
|
||||
#include "kaleidoscope/Runtime.h"
|
||||
#include "kaleidoscope/driver/keyscanner/Base_Impl.h"
|
||||
|
||||
// Here, we set up aliases to the device's KeyScanner and KeyScannerProps
|
||||
// in the global namespace within the scope of this file. We'll use these
|
||||
// aliases to simplify some template initialization code below.
|
||||
using KeyScannerProps = typename kaleidoscope::device::ploopy::TrackballMiniProps::KeyScannerProps;
|
||||
using KeyScanner = typename kaleidoscope::device::ploopy::TrackballMiniProps::KeyScanner;
|
||||
|
||||
namespace kaleidoscope {
|
||||
namespace device {
|
||||
namespace ploopy {
|
||||
|
||||
// `KeyScannerProps` here refers to the alias set up above. We do not need to
|
||||
// prefix the `matrix_rows` and `matrix_columns` names within the array
|
||||
// declaration, because those are resolved within the context of the class, so
|
||||
// the `matrix_rows` in `KeyScannerProps::matrix_row_pins[matrix_rows]` gets
|
||||
// resolved as `KeyScannerProps::matrix_rows`.
|
||||
const uint8_t KeyScannerProps::matrix_rows;
|
||||
const uint8_t KeyScannerProps::matrix_columns;
|
||||
constexpr uint8_t KeyScannerProps::direct_pins[];
|
||||
constexpr uint8_t KeyScannerProps::unused_pins[];
|
||||
|
||||
// `KeyScanner` here refers to the alias set up above, just like in the
|
||||
// `KeyScannerProps` case above.
|
||||
template<>
|
||||
KeyScanner::pin_state_t KeyScanner::pin_state_ = {};
|
||||
|
||||
// We set up the TIMER1 interrupt vector here. Due to dependency reasons, this
|
||||
// cannot be in a header-only driver, and must be placed here.
|
||||
//
|
||||
// Timer1 is responsible for setting a property on the KeyScanner, which will
|
||||
// tell it to do a scan. We use this to make sure that scans happen at roughly
|
||||
// the intervals we want. We do the scan outside of the interrupt scope for
|
||||
// practical reasons: guarding every codepath against interrupts that can be
|
||||
// reached from the scan is far too tedious, for very little gain.
|
||||
ISR(TIMER1_OVF_vect) {
|
||||
Runtime.device().keyScanner().do_scan_ = true;
|
||||
}
|
||||
|
||||
} // namespace ploop
|
||||
} // namespace device
|
||||
} // namespace kaleidoscope
|
||||
|
||||
#endif
|
||||
#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
@ -0,0 +1,84 @@
|
||||
/* -*- mode: c++ -*-
|
||||
* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ARDUINO_AVR_PLOOPY_MINI
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define KALEIDOSCOPE_BOOTLOADER_FLIP_WORKAROUND 1
|
||||
|
||||
#include "kaleidoscope/device/ATmega32U4Keyboard.h"
|
||||
#include "kaleidoscope/driver/bootloader/avr/FLIP.h"
|
||||
#include "kaleidoscope/driver/keyscanner/ATmegaDirect.h"
|
||||
|
||||
namespace kaleidoscope {
|
||||
namespace device {
|
||||
namespace ploopy {
|
||||
|
||||
struct TrackballMiniProps : kaleidoscope::device::ATmega32U4KeyboardProps {
|
||||
struct MCUProps : public kaleidoscope::driver::mcu::ATmega32U4Props {
|
||||
static constexpr bool disable_jtag = true;
|
||||
static constexpr bool disable_clock_division = true;
|
||||
};
|
||||
typedef kaleidoscope::driver::mcu::ATmega32U4<MCUProps> MCU;
|
||||
|
||||
struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaDirectProps {
|
||||
static constexpr uint8_t matrix_rows = 1;
|
||||
static constexpr uint8_t matrix_columns = 6;
|
||||
typedef MatrixAddr<matrix_rows, matrix_columns> KeyAddr;
|
||||
|
||||
#ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
static constexpr uint8_t direct_pins[5] = {PIN_D4, PIN_D2, PIN_E6, PIN_B6, PIN_D7};
|
||||
static constexpr uint8_t unused_pins[12] = {PIN_B5, PIN_C7, PIN_D0, PIN_D1, PIN_D3, PIN_D5, PIN_D6, PIN_F1, PIN_F3, PIN_F5, PIN_F6, PIN_F7};
|
||||
#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
};
|
||||
|
||||
typedef kaleidoscope::driver::keyscanner::ATmegaDirect<KeyScannerProps> KeyScanner;
|
||||
typedef kaleidoscope::driver::bootloader::avr::FLIP Bootloader;
|
||||
static constexpr const char *short_name = "ploopy_mini";
|
||||
};
|
||||
|
||||
#ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
class TrackballMini : public kaleidoscope::device::ATmega32U4Keyboard<TrackballMiniProps> {};
|
||||
#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
/* Device definition omitted for virtual device builds.
|
||||
* We need to forward declare the device name, though, as there are
|
||||
* some legacy extern references to boards whose definition
|
||||
* depends on this.
|
||||
*/
|
||||
class TrackballMini;
|
||||
|
||||
#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define PER_KEY_DATA(dflt, P1, P2, P3, P4, P5, SENSOR) \
|
||||
P1, P2, P3, P4, P5, SENSOR
|
||||
|
||||
// clang-format on
|
||||
|
||||
} // namespace keyboardio
|
||||
} // namespace device
|
||||
|
||||
EXPORT_DEVICE(kaleidoscope::device::ploopy::TrackballMini)
|
||||
|
||||
} // namespace kaleidoscope
|
||||
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
# LayerNames
|
||||
|
||||
This plugin provides a [Focus][plugin:focus]-based interface for storing custom
|
||||
layer names, to be used by software such as [Chrysalis][chrysalis]. The firmware
|
||||
itself does nothing with the layer names, it is purely for use by applications
|
||||
on the host side.
|
||||
|
||||
[chrysalis]: https://github.com/keyboardio/Chrysalis
|
||||
|
||||
## Using the plugin
|
||||
|
||||
To use the plugin, we need to include the header, initialize the plugin with
|
||||
`KALEIDOSCOPE_INIT_PLUGINS()`, and reserve storage space for the names. This is
|
||||
best illustrated with an example:
|
||||
|
||||
```c++
|
||||
#include <Kaleidoscope.h>
|
||||
#include <Kaleidoscope-EEPROMSettings.h>
|
||||
#include <Kaleidoscope-FocusSerial.h>
|
||||
#include <Kaleidoscope-LayerNames.h>
|
||||
|
||||
KALEIDOSCOPE_INIT_PLUGINS(
|
||||
EEPROMSettings,
|
||||
Focus,
|
||||
LayerNames
|
||||
);
|
||||
|
||||
void setup() {
|
||||
Kaleidoscope.setup();
|
||||
|
||||
LayerNames.reserve_storage(128);
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin methods
|
||||
|
||||
The plugin provides a `LayerNames` object, with the following method available:
|
||||
|
||||
### `.reserve_storage(size)`
|
||||
|
||||
> Reserves `size` bytes of storage for layer names. This must be called from the
|
||||
> `setup()` method of your sketch.
|
||||
|
||||
## Focus commands
|
||||
|
||||
The plugin provides a single Focus command: `keymap.layerNames`.
|
||||
|
||||
### `keymap.layerNames [name_length name]...`
|
||||
|
||||
> Without arguments, displays all the stored layer names. Each layer is printed
|
||||
> on its own line, preceded by its length. At the end, the plugin will also
|
||||
> print an extra line with a name length of zero, followed by the string
|
||||
> "size=", and then the total size of the storage reserved for layer names.
|
||||
>
|
||||
> To set custom names, a list of length & name pairs must be given. The plugin
|
||||
> stops processing arguments when it encounters a name length of 0.
|
||||
|
||||
#### Example
|
||||
|
||||
```
|
||||
> keymap.layerNames
|
||||
< 6 Qwerty
|
||||
< 6 Numpad
|
||||
< 8 Function
|
||||
< 0 size=128
|
||||
< .
|
||||
|
||||
> keymap.layerNames 6 Dvorak 6 Numpad 8 Function 0
|
||||
< .
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md)
|
||||
* [Kaleidoscope-FocusSerial](Kaleidoscope-FocusSerial.md)
|
@ -1,19 +0,0 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc.
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope/plugin/LayerNames.h" // IWYU pragma: export
|
@ -1,98 +0,0 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc.
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 "kaleidoscope/plugin/LayerNames.h"
|
||||
|
||||
#include <Arduino.h> // for delay, PSTR, F, __FlashStri...
|
||||
#include <Kaleidoscope-FocusSerial.h> // for Focus, FocusSerial
|
||||
|
||||
#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_
|
||||
#include "kaleidoscope/plugin/EEPROM-Settings.h" // for EEPROMSettings
|
||||
|
||||
namespace kaleidoscope {
|
||||
namespace plugin {
|
||||
|
||||
// =============================================================================
|
||||
|
||||
EventHandlerResult LayerNames::onNameQuery() {
|
||||
return ::Focus.sendName(F("LayerNames"));
|
||||
}
|
||||
|
||||
EventHandlerResult LayerNames::onFocusEvent(const char *input) {
|
||||
const char *cmd_layerNames = PSTR("keymap.layerNames");
|
||||
|
||||
if (::Focus.inputMatchesHelp(input))
|
||||
return ::Focus.printHelp(cmd_layerNames);
|
||||
|
||||
if (!::Focus.inputMatchesCommand(input, cmd_layerNames))
|
||||
return EventHandlerResult::OK;
|
||||
|
||||
if (::Focus.isEOL()) {
|
||||
uint16_t pos = 0;
|
||||
while (pos < storage_size_) {
|
||||
uint8_t name_size = Runtime.storage().read(storage_base_ + pos++);
|
||||
|
||||
if (name_size == 0 || name_size == 255) break;
|
||||
|
||||
::Focus.send(name_size);
|
||||
|
||||
for (uint8_t i = 0; i < name_size; i++) {
|
||||
uint8_t b = Runtime.storage().read(storage_base_ + pos++);
|
||||
::Focus.sendRaw(static_cast<char>(b));
|
||||
}
|
||||
::Focus.sendRaw(::Focus.NEWLINE);
|
||||
}
|
||||
::Focus.sendRaw(0, ::Focus.SEPARATOR, F("size="), storage_size_);
|
||||
} else {
|
||||
uint16_t pos = 0;
|
||||
|
||||
while (pos < storage_size_) {
|
||||
uint8_t name_size;
|
||||
::Focus.read(name_size);
|
||||
|
||||
// size is followed by a space, ignore that.
|
||||
char spc;
|
||||
::Focus.read(spc);
|
||||
|
||||
Runtime.storage().update(storage_base_ + pos++, name_size);
|
||||
|
||||
if (name_size == 0 ||
|
||||
name_size == ::EEPROMSettings.EEPROM_UNINITIALIZED_BYTE)
|
||||
break;
|
||||
|
||||
for (uint8_t i = 0; i < name_size; i++) {
|
||||
char c;
|
||||
::Focus.read(c);
|
||||
|
||||
Runtime.storage().update(storage_base_ + pos++, c);
|
||||
}
|
||||
}
|
||||
Runtime.storage().commit();
|
||||
}
|
||||
|
||||
return EventHandlerResult::EVENT_CONSUMED;
|
||||
}
|
||||
|
||||
// public
|
||||
void LayerNames::reserve_storage(uint16_t size) {
|
||||
storage_base_ = ::EEPROMSettings.requestSlice(size);
|
||||
storage_size_ = size;
|
||||
}
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace kaleidoscope
|
||||
|
||||
kaleidoscope::plugin::LayerNames LayerNames;
|
@ -1,42 +0,0 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2022 Keyboard.io, Inc.
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h> // for uint16_t, uint8_t
|
||||
|
||||
#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult
|
||||
#include "kaleidoscope/plugin.h" // for Plugin
|
||||
|
||||
namespace kaleidoscope {
|
||||
namespace plugin {
|
||||
|
||||
class LayerNames : public kaleidoscope::Plugin {
|
||||
public:
|
||||
EventHandlerResult onNameQuery();
|
||||
EventHandlerResult onFocusEvent(const char *input);
|
||||
|
||||
void reserve_storage(uint16_t size);
|
||||
|
||||
private:
|
||||
uint16_t storage_base_;
|
||||
uint16_t storage_size_;
|
||||
};
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace kaleidoscope
|
||||
|
||||
extern kaleidoscope::plugin::LayerNames LayerNames;
|
@ -1,144 +0,0 @@
|
||||
/* -*- mode: c++ -*-
|
||||
* Kaleidoscope-MouseKeys -- Mouse keys for Kaleidoscope.
|
||||
* Copyright (C) 2022 Keyboard.io, Inc
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 "kaleidoscope/plugin/MouseKeys.h" // IWYU pragma: associated
|
||||
|
||||
#include <Arduino.h> // for PSTR, strcmp_P, strncmp_P
|
||||
#include <Kaleidoscope-EEPROM-Settings.h> // for EEPROMSettings
|
||||
#include <Kaleidoscope-FocusSerial.h> // for Focus, FocusSerial
|
||||
#include <stdint.h> // for uint16_t, uint32_t, uint8_t
|
||||
|
||||
#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_
|
||||
#include "kaleidoscope/device/device.h" // for VirtualProps::Storage, Base<>::Storage
|
||||
#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult, EventHandlerResult::OK
|
||||
|
||||
namespace kaleidoscope {
|
||||
namespace plugin {
|
||||
|
||||
// =============================================================================
|
||||
// MouseKeys configurator
|
||||
|
||||
EventHandlerResult MouseKeysConfig::onSetup() {
|
||||
settings_addr_ = ::EEPROMSettings.requestSlice(sizeof(MouseKeys::Settings));
|
||||
uint32_t checker;
|
||||
|
||||
Runtime.storage().get(settings_addr_, checker);
|
||||
|
||||
// If the EEPROM is empty, storre the default settings.
|
||||
if (checker == 0xffffffff) {
|
||||
Runtime.storage().put(settings_addr_, ::MouseKeys.settings_);
|
||||
Runtime.storage().commit();
|
||||
}
|
||||
|
||||
Runtime.storage().get(settings_addr_, ::MouseKeys.settings_);
|
||||
return EventHandlerResult::OK;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
EventHandlerResult MouseKeysConfig::onFocusEvent(const char *command) {
|
||||
// If the focus command is a request for help, provide the list of valid
|
||||
// commands.
|
||||
if (::Focus.handleHelp(command, PSTR("mousekeys.scroll_interval\n"
|
||||
"mousekeys.init_speed\n"
|
||||
"mousekeys.base_speed\n"
|
||||
"mousekeys.accel_duration")))
|
||||
return EventHandlerResult::OK;
|
||||
|
||||
// The length of the string `mousekeys.`:
|
||||
constexpr uint8_t base_cmd_len = 10;
|
||||
|
||||
// If this is not a MouseKeys command, do nothing.
|
||||
if (strncmp_P(command, PSTR("mousekeys."), base_cmd_len) != 0)
|
||||
return EventHandlerResult::OK;
|
||||
// Otherwise, advance the pointer to the subcommand.
|
||||
command += base_cmd_len;
|
||||
|
||||
enum Command : uint8_t {
|
||||
SCROLL_INTERVAL,
|
||||
INIT_SPEED,
|
||||
BASE_SPEED,
|
||||
ACCEL_DURATION,
|
||||
};
|
||||
Command cmd;
|
||||
|
||||
// Parse the (sub)command. If it's not a valid command, abort.
|
||||
if (strcmp_P(command, PSTR("scroll_interval")) == 0)
|
||||
cmd = Command::SCROLL_INTERVAL;
|
||||
else if (strcmp_P(command, PSTR("init_speed")) == 0)
|
||||
cmd = Command::INIT_SPEED;
|
||||
else if (strcmp_P(command, PSTR("base_speed")) == 0)
|
||||
cmd = Command::BASE_SPEED;
|
||||
else if (strcmp_P(command, PSTR("accel_duration")) == 0)
|
||||
cmd = Command::ACCEL_DURATION;
|
||||
else
|
||||
return EventHandlerResult::ABORT;
|
||||
|
||||
if (::Focus.isEOL()) {
|
||||
// If there is no argument given, we send back the current value of the
|
||||
// setting that was requested.
|
||||
uint16_t val;
|
||||
switch (cmd) {
|
||||
case Command::SCROLL_INTERVAL:
|
||||
val = ::MouseKeys.getScrollInterval();
|
||||
break;
|
||||
case Command::INIT_SPEED:
|
||||
val = ::MouseKeys.getCursorInitSpeed();
|
||||
break;
|
||||
case Command::BASE_SPEED:
|
||||
val = ::MouseKeys.getCursorBaseSpeed();
|
||||
break;
|
||||
case Command::ACCEL_DURATION:
|
||||
val = ::MouseKeys.getCursorAccelDuration();
|
||||
break;
|
||||
default:
|
||||
return EventHandlerResult::ABORT;
|
||||
}
|
||||
::Focus.send(val);
|
||||
return EventHandlerResult::EVENT_CONSUMED;
|
||||
} else {
|
||||
// If there is an argument, we read it, then pass it to the corresponding
|
||||
// setter method of MouseKeys.
|
||||
uint16_t arg;
|
||||
::Focus.read(arg);
|
||||
|
||||
switch (cmd) {
|
||||
case Command::SCROLL_INTERVAL:
|
||||
::MouseKeys.setScrollInterval(arg);
|
||||
break;
|
||||
case Command::INIT_SPEED:
|
||||
::MouseKeys.setCursorInitSpeed(arg);
|
||||
break;
|
||||
case Command::BASE_SPEED:
|
||||
::MouseKeys.setCursorBaseSpeed(arg);
|
||||
break;
|
||||
case Command::ACCEL_DURATION:
|
||||
::MouseKeys.setCursorAccelDuration(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update settings stored in EEPROM, and indicate that this Focus event has
|
||||
// been handled successfully.
|
||||
Runtime.storage().put(settings_addr_, ::MouseKeys.settings_);
|
||||
Runtime.storage().commit();
|
||||
return EventHandlerResult::EVENT_CONSUMED;
|
||||
}
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace kaleidoscope
|
||||
|
||||
kaleidoscope::plugin::MouseKeysConfig MouseKeysConfig;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue