Giter Club home page Giter Club logo

keyplus's People

Contributors

ahtn avatar angustrau avatar emilytrau avatar jschloer avatar merlin04 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keyplus's Issues

Proper unicode support for USB strings

Implement proper unicode support for USB string descriptors. Currently, the code assumes strings stored in the device configuration are assumed to be ASCII. However, according to the USB spec, strings should be encoded in UTF-16LE.

The layout generator will also need to correctly encode and decode strings these strings when generating/parsing the device settings.

References

Make I2C code more robust

Recover from SDA stuck low:

From section 3.1.16 of the I2C spec:

If the data line (SDA) is stuck LOW, the master should send nine clock pulses. The device
that held the bus LOW should release it sometime within those nine clocks. If not, then
use the HW reset or cycle power to clear the bus.

Refrences:

Add system to automate unicode character input

It would be convenient if you could enter any unicode character into a layout file, and then if the character is not supported by the current keyboard layout / language map, then the software automatically generate a key sequence to input the character using the current OS supported input method.

Since each OS has its own method of inputting unicode characters, there's probably a need to track the current OS in the firmware. Then unicode character macro could use the appropriate method to input the character. This value could be switched with keycodes or in the flasher (this value could also be used to swap modifier keys on MacOS).

For, reference here's how unicode characters can be input on different OS's:

Ability to run keyplus as an OS driver for use with any keyboard

Instead of running keyplus on the keyboard microcontroller itself, keyplus could be run on the host OS and remap keycodes in software. This would allow the code to be used with keyboards that do not have support for custom firmware, and it could potentially make debugging keycode handlers easier than on microcontrollers which have poorer debug support. It would also make the output of unicode characters easier. Once a reliable way of reading/writing keycodes to the host OS is found, it is not too difficult to implement either.

A long time ago I had a working demo of this which used libxdo to generate keycodes and read the keyboard input from /dev/hidraw. It worked reasonably well, but it was running in user space so it occasionally had latency issues. Also, it only worked in X, since it relied on libxdo to generate output. So a lower level approach, like a kernel driver would probably be needed to make this work well. Right now I can't find the relevant commit to this code in my old repository.

This project would not be super serious and would mostly be a fun way to learn about Linux driver development, more than it would be to make something useful.

Add mechanisms to prevent flashing the wrong hex file.

Issue

The flasher should display a warning if a hex file is not intended for the current mcu/board. Since there isn't really a way to add metadata to hex files, it will be necessary to either use the file nameor by extending the hex file format. Extending the hex file format is probably the more robust solution, but the extra data might need to be removed to flash the file with external tools.

Recover from loading a bad hex file

If you accidentally load a bad hex file, you can force the device to enter bootloader mode by following these steps:

  1. Connect the USB port.
  2. Short the GND and RST pins of the board once.
  3. Open the flasher and program the new hex file.

force_bootloader

bootloader_device_in_flasher

Allow build system to use layout files when compiling firmware

Currently when building the firmware it can only include settings defined in the source code. It would be much more convinent to build the firmware with a layout file "pre-loaded" into the target hex file. This should easily be done with a python script.

Get USB VID:PID pairs for keyplus projects

Right now keyplus is using the VID:0x6666 which is USB-IF official VID for prototype products. To avoid conflicts with other USB devices in the field, keyplus should have VID/PID for core devices (keyplus mini controller, xusb-boot, nrf24lu1p-512-bootloader, keyplus nRF24LU1+ dongle, generic xmega keyplus device). Buying a VID from USB-IF is expensive, but their are some free/cheap options for open source/small projects:

  • 0x1209: pid.codes (requires OSS and OSHW)
  • 0x1457, 0x1d50: openmoko (requires only OSS or OSHW)
  • MCS Electronics (costs money, technically revoked but in practice that doesn't make a difference as VID:PID pairs should still be unique which is all we care about)
  • 0x04d8, 0x03eb: Microchip/Atmel usb sublicensing (xmega/avr only)

Extend modkeys to support both left and right modifiers

The current implementation of modkeys only supports left or right modifiers but not both.

To allow both kinds of modifiers at once, we would need to use extended keycodes (EKC). An extended keycode for modkeys would look like this:

[0x00] -> KC_MODKEY
[0x02] -> 8-bit modifier mask
[0x03] -> 8-bit HID keycode

And the modkey handler would need to be extended appropriately.

Since modkeys account for the majority off key presses when typing, I'd like to build this implementation on top of the current one, as using EKC's have a little bit of extra overhead in terms of code size and speed.

make program-boot fails

 > sudo make BOARD=keyplus_mini program-boot
python3 ../host-software/keyplus-cli program \
	 \
	--new-id 0 \
	--layout "../layouts/basic_split_test.yaml" \
	--rf "../layouts/test_rf_config.yaml" \
	--fw-hex "build/keyplus_mini-atxmega32a4u/xmega_keyplus-keyplus_mini-atxmega32a4u.hex" \
	-M 0x7600 0x7800 0x0800 \
	-o ""build/keyplus_mini-atxmega32a4u/xmega_keyplus-keyplus_mini-atxmega32a4u-basic_split_test.hex"" \
	-F chip_name="ATxmega32A4U" \
	-F scan_method=fast_row_col \

# ./scripts/flash_hex.sh "build/keyplus_mini-atxmega32a4u/xmega_keyplus-keyplus_mini-atxmega32a4u-basic_split_test.hex" atxmega32a4u
python3 ../host-software/keyplus-cli bootloader -p ATxmega32A4U | sleep 1.5
Error: Couldn't find any matching devices.
python3 ./xusb-boot/scripts/bin/xusbboot-cli -f "build/keyplus_mini-atxmega32a4u/xmega_keyplus-keyplus_mini-atxmega32a4u-basic_split_test.hex" -mcu atxmega32a4u
Traceback (most recent call last):
  File "./xusb-boot/scripts/bin/xusbboot-cli", line 183, in <module>
    if (dev.vendor_id, dev.product_id) in xusbboot.DEFAULT_USB_IDS:
AttributeError: module 'xusbboot' has no attribute 'DEFAULT_USB_IDS'
Makefile:227: recipe for target 'program-boot' failed
make: *** [program-boot] Error 1

Can't obtain USB HID interface number on OS X with HIDAPI

OS X has not always exposed the interface number of HID devices. The current master branch of HIDAPI has a workaround for this, but the current homebrew formula builds from a really old commit in the HIDAPI repo (0.8.0-rc1from 2013).

It looks like there is a proper fix here which requires patching this line.

To make things easier for OS X users, a static build needs to be made for OS X which bundles a recent/patched version of the HIDAPI library.

Make list of keycodes

I'm configuring my keyplus mini firmware, but I don't know what the keycodes are. There should be a list of them.

Need to utilize IRQ pin of nRF24L01+ in xmega implementation

Currently the xmega doesn't use the nRF24L01+ IRQ pin. The built in packet FIFO of the nRF24L01+ can only store 3 packets at a time, so it's possible that packets will be dropped if we do not process them fast enough. This didn't use to be an issue, but after some other changes to the RF protocol I'm now noticing dropped packets when the xmega is acting as an RF receiver.

Also, with the IRQ pin it will be possible to better utilize sleep modes for improved power efficiency when acting as a wireless transmit.

Allow flashing firmware updates of nRF24LU1+ devices in the GUI tool

The GUI tool should be able to flash nRF24LU1+ devices, and should ideally handle:

  • Flashing firmware to the nrf24lu1p-512-bootloader raw HID bootloader
  • Flashing firmware to the Logitech Unifying receiver bootloader
  • Reseting a Logitech Unifying receiver into its bootloader

Uniflash Issues

[sudo] password for : 
Traceback (most recent call last):
  File "uniflash.py", line 372, in <module>
    detach_kernel_drivers(boot_dev, [0, 1])
  File "uniflash.py", line 33, in detach_kernel_drivers
    if dev.is_kernel_driver_active(i):
AttributeError: 'NoneType' object has no attribute 'is_kernel_driver_active'

Invalid packets are parsed by the nRF receiver breaking keyboard input

I connected a device that was sending invalid packets to the nRF receiver, and this broke keyboard input after the receiver seemed to try parse the packets as keyboard packets. The RF packet parser needs to be made more robust as these packets where not even a valid size for keyboard input. Also, it seems that the parser would attempt to scan these packets even when no devices had been paired, which should not be possible when the pairing algorithm is working correctly.

To detect and debug issues of this nature, it would be good to write a packet fuzzer that can send malformed/random packets to the receiver at different rates.

Add support for different language keymaps in the config file format

The config file format should support using different language modes. The idea is to add a default language field like default_lang: 'de', which would then select the default keymap lookup table from the python script for the corresponding language. So with that set, the user would be able to just type ö into their keymap, and it would look for ö in the keymap table and generate the corresponding key(s) when generating the layout file, adding AltGr, Shift, etc. as necessary.

It would be good to support changing the language map on a per key and per layer basis as well.

Add more documentation

  • How to build the code
  • How to use the host-software utilities
  • How the configuration file format works
  • Basic overview of how split keyboard support works and limitations.
  • How to flash the nRF24LU1+ code on a unifying receiver
  • Notes about using a unifying mouse
  • Document the security model

ATmega32u4 support

Why support

The ATmega32u4 does not have many significant advantages compared to other architectues, however it is the most popular controller currently being used in hobbiest keyboard projects thanks to the Teensy and Arduino Pro Micro dev boards in addition to having lots of firmware support.

Feature support

  • Full feature support may be difficult as there is potentially only 28kB of flash available after the bootloader is accounted for.
  • Battery mode would not be supported.
  • Writting to flash requires bootloader support, so only 1kB of EEPROM can be used for layout and settings storage with most bootloaders. The default Atmel DFU bootoloader does have support for writing from flash, but no other bootloaders support this that I am aware of.
  • Would have to support many different bootloaders (Teensy Half-key, Arduino Caterina, Atmel DFU, LUFA DFU) each probably requiring driver support on Windows.

Notes:

Updating bootloader without an external programmer

It might be possible to update the bootloader without needing an external programmer. There's a program BootJacker that can run from application space, find the spm instruction used by the current bootloader, and use it to write to flash. However, if the device has certain lock bits set, this hack won't work. Source code.

If the device doesn't have lock bits protecting the bootloader section, then it should be possible to replace the bootloader. I've corrupted pro micro's before by writing a flash files that overlapped with the bootloader section, so I think this hack might work for them. If this hack can work reliably, then an Arduino script could be used to replace the pro micro bootloader with a better one.

Progress

  • Support for DFU bootloader for writing flash
  • 1kB driverless HID bootloader with SPM interface for writing to flash from application section.
  • Write Arduino script that can upgrade Pro Micro bootloader
  • Matrix scanning
  • RF code for using nRF24L01+ and a Pro Micro as a USB dongle
  • Wired split keyboard support using I2C
  • Use EEPROM for storing layouts unsupported bootloaders (might not do this)

References

Add support for WS2812B RGB LEDs

Pretty much the title. Support WS2812B RGB LEDs that are commonly used for underglow. One common use is to indicate the active layer, so this relates somewhat to #12.

USB commands on vendor endpoint need blocking or buffering

The USB vendor IN endpoint is unbuffered. This can cause issuse when the host sends commands and expects a response but the device overwrites the pending message on the IN endpoint. The code should either lock the endpoint when it is in use by a command, or the vendor IN messages need to be buffered.

Clean up flasher code

Recently I rewrote most of the python API for controlling keyboards, but have yet to integrate most of the features into the layout flasher. There's a lot of code left over from the old system that needs to be removed.

Also, the GUI code was hacked together as I added features so the code has become quite messy and needs to be cleaned up. Should try to aim to break it up into separate files and make it reusable in a GUI editor in the future.

v0.2.2 doesn't detect any devices; can't use 0.3

I can't use version 0.3 because my keyplus mini boards have version 0.2.2, and I don't have an avr programmer to update it. The keyplus app doesn't detect any devices. No error messages are shown.

Improve USB port detection

When a device is powerd on and detects USB voltage on its VBUS check pin, it needs to decide whether it has connection to a USB host, or if it only has I2C connections to other devices. This is important because only the device with the host connection should enable its NRF24 module. If multiple nRF24 modules are active simultaneously, they will interfer with each others auto-ack functionality.

When the device only has one USB port, this should not be too difficult, as it can leave it's USB data lines active at all times and only run the initialization code after a IRQ, but continue operating as normal.

However, if the DUAL_USB feature is used, then that implementation cannot be used, since the USB data lines need to be switched to I2C. So in this case, the device should active an I2C connection on each of its ports in turn and ping for other devices. In this way, it can deduce that a port is I2C. Whenever a device, finds out that it has a USB port, it should ping the other devices, so that they know that all their other ports can be switched to I2C.

uniflash.py big_endian_u16 is not defined

Using Python 3.5.2 and trying to run the uniflash info command, I get the failure at line 206. I can comment it out and keep moving, but I think I need the results of that to know whether to use the 16 or 32 hex file.

nRF52840 support

Why Support

Advantages of nRF52840:

  • 32-bit ARM Cortex-M4F @ 64MHz
  • 1MB flash and 256kB RAM
  • FS USB
  • 1.7-5.5V supply Voltage
  • Has Bluetooth 5 support.
  • Has nRF24 support.

Feature Support

  • Can support all keyplus split connectivity features in a single chip.
  • It would also be the first microcontroller to support Bluetooth.
  • It would require adding support for ARM, so might take more work to port

Notes

  • The nRF52840 can use the nRF24 protocol internally compared to the nRF24L01+ and nRF24LU1+ where the RF module is controlled over a SPI interface. For this reason, it will probably be better to not reuse the nRF24 API with the nRF51/nRF52 boards. Also, it would be good to support both kinds of interfaces simultaneously which would allow for nRF52840 and nRF24L01+ to be used together in a full wireless Bluetooth solution.

Refrences

Add better buffering for nRF24 matrix transmissions

The nRF24 has an internal FIFO for storing up to 3 packets. Currently when sending a matrix packet, the code doesn't check if the FIFO is full. So if RF packets are not transmitted fast enough (could easily happen if there is other RF interference), then packets will be dropped.

Instead the code should check if the FIFO is full, and if it is, it should use a separate FIFO on the microcontroller to hold packets and add them to the nRF24 FIFO when space becomes available.

Another potential issue that may arise from buffering, is the receiver may try to apply several matrix packets at a time. In the worst case, this could cause keys to be missed (it applies a key down and key up at the same time), so it might be beneficial for the receiver to read one matrix packet at a time and send any USB keycodes that are generated before moving to the next packet.

Relevant code

Add timer event system

Many system need to perform task when a timer expiers. Currently most of the system that use this now are each running their own tasks that are checking if their timers have expired. Generalizing the system would allow them to share code and the memory used to track timers.

It would make it easier to use interrupt timers instead of relying on polling to check if the tasks should be triggered. The interrupt system would only need to be set for the timer that is closest to expiring. When that timer expires, the interrupt would be called, the appropriate task run, and the interrupt would be reset to the next timer. This would benefit a future bluetooth implementation as it would allow the code to sleep much more than the current system.

Add `preset` option to keyboard layout files

Current for each board define, it is required to provided the explicit matrix scan mapping for each device in the layout file:

    scan_mode:
      mode: col_row # options: col_row, pins, none
      rows: 4
      cols: 6
      # maps how keys are physically wired, to how they appear visually
      matrix_map: [
        r2c2, r2c1, r2c0, r2c3, r2c4, r2c5,
        r3c2, r3c1, r3c0, r3c3, r3c4, r3c5,
        r1c2, r1c1, r1c0, r1c3, r1c4, r1c5,
        r0c2, r0c1, r0c0, r0c3, r0c4, r0c5,
      ]

However, if the keyboard is using a PCB with a fix layout, it would be easier if the user could load a preset matrix map for their board, with one line:

    presets: <BOARD_NAME>

It would be easiest to bundle the preset configurations with the loader. If this list of presets is updated frequently, then it would be convinent to have a command in the loader to download the latest version.

Figure out what is required to flash Unifying receivers from Windows

Unlike Linux and OS X, on Windows it is always necessary to have a driver to communicate with a USB device, so the uniflash.py script probably won't work on Windows without a driver for the Unifying receiver.

To get the script to work, it might be as simple as installing the Logitech drivers for the Unifying receiver. If that doesn't work, it might be necessary to use zadig to apply a generic libusb driver to communicate with the Unifying receiver.

In editor python file, pyslide should be pyside

Also, when I try to install pyside, it gives errors:

    -- Could NOT find LibXslt (missing: LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIR) (Required is at least version "1.1.19")
    Qt QTGUI library not found.
    Qt QTXML library not found.
    Qt QTCORE library not found.
    CMake Error at ApiExtractor/CMakeLists.txt:82 (qt4_add_resources):
      Unknown CMake command "qt4_add_resources".

Security

In your blog post, you mentioned that the firmware can be updated wirelessly, and that that's important so that it's possible to "apply security updates for the wireless protocol". That begs two questions.

  1. What is the wireless protocol currently doing for security? I wouldn't want my keyboard to blast every character I type through the air in cleartext.
  2. What safeguards are there to prevent an attacker from "updating" my firmware wirelessly without my consent to, for example, turn off the encryption? I'm guessing there must at least be a reset button or key combo to put the board in bootloader mode.

Add LED indicator support and configuration

Currently the code has indicator LED's added in the HID descriptor, but it has no way to use them yet. It would also be good if the indicator LED's can work with user define layers.

I would like indicator LED's to be easily configurable from the yaml config file. The pins on the controller would be allocated in a similar way as the row and column pins of the matrix. That is the controller would map a list of LED pins LED0, LED1, ... to a dedicated list of LED hardware pins on the controller C0, C1, ... based on the number of LED's describe in the config file.

The user would then define roles to the LEDx pins in the config file something like this for each device:

keyboard_device:
   # ...
   num_leds: 4
   led0: caps_lock
   led1: num_lock
   led2: kana
   led3: layer2
   # ...

Consider switching from pyside to PyQt5 for the GUI

PyQt5 has better support on MacOS and the newest versions of python3. Originally I choose to use pyside because it is basically equivalent to PyQt5 just with LGPL instead of GPL. However, the license difference is not an issue for the host software. Since PyQt5 is easier to support it makes sense to switch to it.

Before switching, need to check everything is working correctly on Linux and Windows under PyQt5.

efm8 support

Why support them

The efm8 series of 8051 microprocessors by Silicon Labs are probably the cheapest, smallest and simplest FS USB capable micoprocessors on the market. Some highlights include:

  • Power directly from USB 5V with internal regulator.
  • The only external components necessary for FS USB support are 4 decoupling capacitors.
  • Preloaded USB HID bootloader
  • In volume they can be potentially be purchased for about 1USD.
  • Smallest package is a 3x3mm QFN20 with 13 GPIO
  • Also come in 24-QSOP, 32QFN, 32QFP, 48QFP
  • Flash sizes range from 8-64kB.
  • 8051 based core runs at 48MHz.
  • UART, SPI, I2C

Feature support

The efm8 series would be best suited for USB only keyboards, but could also support I2C split and maybe nRF24 receiver mode. Battery mode would probably not be implemented for efm8.

According to Silcon Lab's documentation, their USB SDK can be compiled with SDCC. So it should be quite easy to add support.

Progress

  • USB communication working
  • Reading/Writing layouts
  • EFM8 factory bootloader support in GUI
  • Handle shared HID descriptors for media, nkro and mouse control.
  • Matrix scanning

References

  • efm8ub1 (harder to support, since they only have max 16kB flash)
  • efm8ub2 (32-64kB, QFN32, QFP32, QFP48)
  • efm8ub3 (40kB, QFN20, QSOP24, QFN24)
  • c8051f380 (Note: older more expensive, no bootloader from factory, but can sink 100mA on IO pins and 5 PWM pins)

Add support for monitoring device status

The master device should be able to provide status information for connected slave devices:

  • Tell what devices are connected
  • How they are connected: i2c, wired, wireless, USB
  • Obtain current battery levels

Improve the matrix pin customization

Something things that I would like the matrix scanner configuration to support:

  • Ability to skip pins
  • Allow more rows and columns by allowing SPI pins to be used as columns if they are not used.
  • Add pin scanning mode (i.e. no matrix direct wiring to GND)

Implement frequency hoping

Currently the code only use a fixed RF channel for the nRF24 radio. To improve RF performance in noisy environments it would be benefical to implement some form of channel hoping. The implementation would have need to be compatible with the unifying protocol.

Frequency hoping benefits the mouse more than the keyboard, and it adds a certain amount of overhead that is not present when using a fixed channel approach. So, ideally we should support both approaches.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.