Skip to content

Commit

Permalink
Merge pull request #30 from minipadKB/master
Browse files Browse the repository at this point in the history
Release firmware version `2023.516.1`
  • Loading branch information
minisbett authored May 16, 2023
2 parents f3445d3 + 9ac29b6 commit 31ef8d4
Show file tree
Hide file tree
Showing 25 changed files with 575 additions and 331 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pio-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ jobs:
run: pip install --upgrade platformio

- name: Build 2K Firmware
run: pio run --environment minipad-2k --verbose
run: pio run --environment minipad-2k-prod --verbose

- name: Build 3K Firmware
run: pio run --environment minipad-3k --verbose
run: pio run --environment minipad-3k-prod --verbose

- name: Create Release
uses: actions/create-release@v1
Expand Down
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"array": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp"
"utility": "cpp",
"ranges": "cpp",
"iosfwd": "cpp",
"limits": "cpp",
"streambuf": "cpp"
},
"cmake.configureOnOpen": false
}
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# 2023.516.1 - Digital key support, support for more keys!

This release adds support for digital keys, which might not be useful for minipad owners *yet*, but is for people DIY-ing a keypad or messing around with the firmware, as well as the collaboratoring commercial products of the Minipad Project.

This release also prepares the communication with minitility, our configuration software which is coming closer to be ready to use.

## Features

- Added support for digital keys (push buttons, mechanical switches, ...)
- Added debounce for digital keys with a default of 50ms
- Made the amount of hall effect/digital keys fully dynamic, not limited to 2-3 but rather limited to the hardware specifications of the RP2040 micro controller

## Bug Fixes

- Refactored `getArgumentAt` function
- Fix `name` command not null-terminating

## Changes

- Migrated info retrieved via the `ping` to the `get` command
- Split the `key` identifier in the serial protocol into `hkey` (hall effect) and `dkey` (digital)
- Changed the command for changing the key pressed from `key` to `char`
- Removed config versions other than the main `Configuration` object, removed mutations
- Switched from hardcoded pin arrays to a formula macro
- Changed the default values for rest and down positions to 4095 and 0 respectively
- Added definition for reversing the sensor values

# 2023.410.1 - Initial release!

Initial release.
Expand Down
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,49 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
<a href="https://discord.gg/minipad"><img src="https://discordapp.com/api/guilds/1056311828344483840/widget.png"></a>


# minipad-firmware

This is the firmware for the minipad, an RP2040-based 2-to-3-key keypad for the rhythm game osu!.
This firmware is designed specifically to work with our open-source PCB, which can be found [here](https://github.com/minipadkb/minipad).

# Installation
Although this firmware is made for aforementioned PCB, it can be used for different kinds of (hall effect) keypad/keyboard projects due to it's support of both digital and hall effect buttons, as well as no real limitation on how many keys to use. Support for multiplexing is planned but has not started development.

# Features

- An unlimited amount of Hall Effect or Digital keys
- Rapid Trigger (explained [here](https://github.com/minipadKB/minipad-firmware/blob/master/src/handlers/keypad_handler.cpp#L13)) with 0.01mm resolution
- Flexible, configurable travel distance of switches
- Adjustable actuation point (0.01mm resolution)
- Software-based low pass filter for analog stability
- Configurable keychar pressed upon key interaction

Planned
-
- Support for RGB lights, including configurable colors and effects
- Usage of multiplexers to allow for more keys to be used on the hardware

# Installation on an RP2040 micro controller

To flash this firmware on your keypad, please refer to our [firmware installation guide](https://minipad.minii.moe/docs/minipad/install-firmware). In there, you can find the instructions on how to initially load the firmware on the keypad, and how to update it later on.
To flash this firmware on your minipad or other RP2040 board, please refer to our [firmware installation guide](https://minipad.minii.moe/docs/minipad/install-firmware). In there, you can find the instructions on how to initially load the firmware on the keypad, and how to update it later on.

# Setup
# Setup for development

Setting up this project is really simple. The repository is set up using PlatformIO, an IDE in form of an extension for Visual Studio Code.
You can find a download link for Visual Studio Code [here](https://code.visualstudio.com/). In there, search and install the extension `PlatformIO`.

After that is done, clone the repository with `git clone https://github.com/minipadkb/minipad-firmware` and open the cloned folder using Visual Studio Code. PlatformIO will perform an installation of all dependencies for this project (Arduino-Pico framework, various drivers, ...). This might take up to ~10 minutes, as a lot files need to be downloaded.
After that is done, clone the repository with `git clone https://github.com/minipadkb/minipad-firmware` and open the cloned folder using Visual Studio Code. PlatformIO will perform an installation of all dependencies for this project (Arduino-Pico framework, various drivers, ...). This might take up some time, depending on your network connection.

If you are not familiar with the usage of PlatformIO, a Quick Start guide can be found [here](https://docs.platformio.org/en/stable/integration/ide/vscode.html).

Note: Uploading the firmware only works if the micro controller is set into bootloader mode. This can be done using the BOOTSEL button on development boards or setting the minipad into bootloader mode via minitility. A guide on the latter can be found [here]().

# Licenses

[arduino-pico](https://github.com/minipadkb/arduino-pico) by [minipadkb](https://github.com/minipadkb), fork of [arduino-pico](https://github.com/earlephilhower/arduino-pico) by [earlephilhower](https://github.com/earlephilhower), distributed under [LGPL v2.1](https://github.com/earlephilhower/arduino-pico/blob/master/LICENSE)

[Keyboard](https://github.com/minipadKB/minipad-firmware) by [minipadkb](https://github.com/minipadKB), fork of [Keyboard](https://github.com/earlephilhower/Keyboard) by [earlephilhower](https://github.com/earlephilhower), distributed under [LGPL v3.0](https://github.com/minipadkb/Keyboard/blob/master/LICENSE)

At the bottom of Visual Studio Code, you can find three important buttons, you can see them below. The checkmark compiles the project on the currently selected environment (seen on the right, in this case "env:minipad-3k").</br>
The arrow to the right uploads the firmware to your RP2040-based device (e.g. our PCB), given that it is in bootloader mode. At the right, you can select the environment. You can choose between the 2k firmware, 3k firmware and it's development versions. The development versions enable certain features that helps while development. If you want to find out more, search for the `DEBUG` definition across the source code.
[pico-sdk](https://github.com/minipadKB/pico-sdk) by [minipadkb](https://github.com/minipadKB), fork of [pico-sdk](https://github.com/raspberry/pico-sdk) by [raspberry](https://github.com/raspberry), distributed under [BSD-3-Clause](https://github.com/minipadkb/pico-sdk/blob/master/LICENSE)

![PlatformIO Buttons](https://raw.githubusercontent.com/minipadKB/minipad-firmware/master/.github/images/platformio_buttons.png)
[Keyboard](https://github.com/minipadKB/minipad-firmware) by [minipadkb](https://github.com/minipadKB), fork of [Keyboard](https://github.com/earlephilhower/Keyboard) by [earlephilhower](https://github.com/earlephilhower), distributed under [LGPL v3.0](https://github.com/minipadkb/Keyboard/blob/master/LICENSE)
19 changes: 9 additions & 10 deletions include/config/configuration.hpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
#pragma once

#include "key.hpp"
#include "config/keys/he_key.hpp"
#include "config/keys/digital_key.hpp"

// Configuration for the whole firmware, containing the name of the keypad and it's configurations.
struct Configuration
{
// Version of the configuration, used to check whether the struct layout in the EEPROM is up-to-date.
uint32_t version;
uint32_t version = Configuration::getVersion();

// The name of the keypad, used to distinguish it from others.
char name[128];

// A list of all key configurations. (rapid trigger, hysteresis, calibration, ...)
Key keys[KEYS];
// A list of all hall effect key configurations. (rapid trigger, hysteresis, calibration, ...)
HEKey heKeys[HE_KEYS];

// A list of all digital key configurations. (key char, hid state, ...)
DigitalKey digitalKeys[DIGITAL_KEYS];

// Returns the version constant of the latest Configuration layout.
static uint32_t getVersion()
{
// Version of the configuration in the format YYMMDDhhmm (e.g. 2301030040 for 12:44am on the 3rd january 2023)
int64_t version = 2303171835;

// To reset the configuration if the user switches from a 2-key firmware to a 3-key, mutate the version.
#if KEYS == 3
version = -version;
#endif
int64_t version = 2304281204;

return version;
}
Expand Down
120 changes: 63 additions & 57 deletions include/config/configuration_controller.hpp
Original file line number Diff line number Diff line change
@@ -1,69 +1,75 @@
#pragma once

#include "config/configuration.hpp"

// Default configuration file loaded into the EEPROM if no configuration was saved yet. Also used to reset the keypad and calibration
// structs that might get modified on a firmware update and have to be reset back to their default values then later on.
inline Configuration defaultConfig =
{
.version = Configuration::getVersion(),
.name = {'m', 'i', 'n', 'i', 'p', 'a', 'd' },
.keys =
{
{
.version = Key::getVersion(),
.index = 0,
.rapidTrigger = false,
.continuousRapidTrigger = false,
.rapidTriggerUpSensitivity = 50,
.rapidTriggerDownSensitivity = 50,
.lowerHysteresis = 250,
.upperHysteresis = 300,
.keyChar = 'z',
.hidEnabled = false,
.restPosition = 1800,
.downPosition = 1100
},
{
.version = Key::getVersion(),
.index = 1,
.rapidTrigger = false,
.continuousRapidTrigger = false,
.rapidTriggerUpSensitivity = 50,
.rapidTriggerDownSensitivity = 50,
.lowerHysteresis = 250,
.upperHysteresis = 300,
.keyChar = 'x',
.hidEnabled = false,
.restPosition = 1800,
.downPosition = 1100
},
#if KEYS == 3
{
.version = Key::getVersion(),
.index = 2,
.rapidTrigger = false,
.continuousRapidTrigger = false,
.rapidTriggerUpSensitivity = 50,
.rapidTriggerDownSensitivity = 50,
.lowerHysteresis = 250,
.upperHysteresis = 300,
.keyChar = 'c',
.hidEnabled = false,
.restPosition = 1800,
.downPosition = 1100
}
#endif
}
};
#include "definitions.hpp"

inline class ConfigurationController
{
public:
ConfigurationController(Configuration *defaultConfig) : config(*defaultConfig) {};
ConfigurationController()
{
defaultConfig = getDefaultConfig();
config = defaultConfig;
}

void loadConfig();
void saveConfig();

Configuration config;
} ConfigController(&defaultConfig);

private:
Configuration defaultConfig;

// Default configuration loaded into the EEPROM if no configuration was saved yet. Also used to reset the keypad and calibration
// structs that might get modified on a firmware update and have to be reset back to their default values then later on.
Configuration getDefaultConfig()
{
Configuration config = {
.name = {'m', 'i', 'n', 'i', 'p', 'a', 'd'},
.heKeys = {},
.digitalKeys = {}
};

// Populate the hall effect keys array with the correct amount of hall effect keys.
for (uint8_t i = 0; i < HE_KEYS; i++)
{
config.heKeys[i] = HEKey();
config.heKeys[i].index = i;

// Assign the keys from z downwards. (z, y, x, w, v, ...)
// After 26 keys, stick to an 'a' key to not overflow.
config.heKeys[i].keyChar = i >= 26 ? 'a' : (char)('z' - i);

config.heKeys[i].hidEnabled = false;
config.heKeys[i].rapidTrigger = false;
config.heKeys[i].continuousRapidTrigger = false;

// For the default values of these values, a value depending on the total travel distance is being used.
config.heKeys[i].rapidTriggerUpSensitivity = TRAVEL_DISTANCE_IN_0_01MM / 10;
config.heKeys[i].rapidTriggerDownSensitivity = TRAVEL_DISTANCE_IN_0_01MM / 10;
config.heKeys[i].lowerHysteresis = (uint16_t)(TRAVEL_DISTANCE_IN_0_01MM * 0.55);
config.heKeys[i].upperHysteresis = (uint16_t)(TRAVEL_DISTANCE_IN_0_01MM * 0.675);

// Set the calibration values to the outer boundaries of the possible values to "disable" them.
config.heKeys[i].restPosition = pow(2, ANALOG_RESOLUTION) - 1;
config.heKeys[i].downPosition = 0;
}

// Populate the digital keys array with the correct amount of digital keys.
#pragma GCC diagnostic ignored "-Wtype-limits"
for (uint8_t i = 0; i < DIGITAL_KEYS; i++)
#pragma GCC diagnostic pop
{
config.digitalKeys[i] = DigitalKey();
config.digitalKeys[i].index = i;

// Assign the keys from a forwards. (a, b, c, d, e, ...)
// After 26 keys, stick to an 'z' key to not overflow.
config.digitalKeys[i].keyChar = i >= 26 ? 'z' : (char)('a' + i),
config.digitalKeys[i].hidEnabled = false;
}

return config;
};

} ConfigController;
50 changes: 0 additions & 50 deletions include/config/key.hpp

This file was deleted.

14 changes: 14 additions & 0 deletions include/config/keys/digital_key.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <stdint.h>
#include "config/keys/key.hpp"

// Configuration for the digital keys of the keypad.
struct DigitalKey : Key
{
// Initialize with the correct type for identifying the type of key that a Key object was initialized as (e.g. DigitalKey).
DigitalKey() { type = KeyType::Digital; }

// This struct is empty on purpose. The only purpose it serves is explicitly having
// a type for the digital keys, instead of differentiating between Key and DigitalKey.
};
34 changes: 34 additions & 0 deletions include/config/keys/he_key.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <stdint.h>
#include "config/keys/key.hpp"
#include "config/keys/key_type.hpp"

// Configuration for the hall effect keys of the keypad, containing the actuation points, calibration, sensitivities etc. of the key.
struct HEKey : Key
{
// Initialize with the correct type for identifying the type of key that a Key object was initialized as (e.g. HEKey).
HEKey() { type = KeyType::HallEffect; }

// Bool whether rapid trigger is enabled or not.
bool rapidTrigger;

// Bool whether continuous rapid trigger is enabled or not.
bool continuousRapidTrigger;

// The sensitivity of the rapid trigger algorithm when pressing up.
uint16_t rapidTriggerUpSensitivity;

// The sensitivity of the rapid trigger algorithm when pressing down.
uint16_t rapidTriggerDownSensitivity;

// The value below which the key is pressed and rapid trigger is active in rapid trigger mode.
uint16_t lowerHysteresis;

// The value below which the key is no longer pressed and rapid trigger is no longer active in rapid trigger mode.
uint16_t upperHysteresis;

// The value read when the keys are in rest position/all the way down.
uint16_t restPosition;
uint16_t downPosition;
};
Loading

0 comments on commit 31ef8d4

Please sign in to comment.