Compare commits

..
57 Commits
Author SHA1 Message Date
Jack Humbert cefc09ae7d adds option for alt pitch standards 2017-07-24 12:45:34 -04:00
Joe Wasson a543ad4c1d Fix minor formatting issue. 2017-07-23 15:10:27 -04:00
Jack Humbert 6bdf7482b1 update audio/music documentation 2017-07-23 14:59:29 -04:00
Jack Humbert 415d38ba9e adds music mode, music mode songs, music mask 2017-07-23 14:59:29 -04:00
Jack Humbert 9abbbe7089 update audio documentation 2017-07-23 14:59:29 -04:00
Jack Humbert f407f3e8de remove unneccesary headers 2017-07-23 14:59:29 -04:00
Jack Humbert 92ccc9a7b8 use automatic rests with songs (no more rest styles) 2017-07-23 14:59:29 -04:00
Jack Humbert f40ded7894 relocate keymap's useful tools 2017-07-23 14:59:29 -04:00
Jack Humbert fd664fe85b escape song playing in music 2017-07-23 14:59:29 -04:00
Jack Humbert fe113ebad5 start updating audio docs 2017-07-23 14:59:29 -04:00
Jack Humbert 6a3c66776c clean-up planck and preonic keymaps, move audio stuff around 2017-07-23 14:59:29 -04:00
Jack Humbert 8edb67b082 fix line-endings 2017-07-21 19:05:13 -04:00
rootuseralpha e26283e9e5 Update keymap.c 2017-07-20 21:52:13 -04:00
rootuseralpha 8deb405292 Add files via upload 2017-07-20 21:52:13 -04:00
rootuseralpha 4d665a99ae Add files via upload 2017-07-20 21:52:13 -04:00
rootuseralpha 4627cab49d Delete test 2017-07-20 21:52:13 -04:00
rootuseralpha e5f606558e Add files via upload 2017-07-20 21:52:13 -04:00
rootuseralpha f379f05c1e Create test 2017-07-20 21:52:13 -04:00
Maarten Dekkers 1524d29cfb Added some user customization 2017-07-20 10:18:00 -04:00
Maarten Dekkers 30efce5584 Changes to own keymap 2017-07-20 10:18:00 -04:00
Fred Sundvik a5b0f4de35 Add SRC and OPT_DEFS when building tests 2017-07-20 10:17:31 -04:00
Fred Sundvik 20696a9efe Fix building of multiple test directories 2017-07-20 10:17:31 -04:00
Jack Humbert 14c5160b1a Update _summary.md 2017-07-17 15:01:33 -04:00
Jack Humbert 000e749853 Rename docs/features/README.md to docs/features.md 2017-07-17 15:01:11 -04:00
Jack Humbert 7c0610b411 Merge pull request #1498 from That-Canadian/minidox
Minidox
2017-07-14 22:04:18 -04:00
That-Canadian b6d74b9bb9 Fixed typo in readme 2017-07-14 21:58:59 -04:00
That-Canadian 5e8594db82 Updated MiniDox readme 2017-07-14 21:57:41 -04:00
That-Canadian 6c9b69a4b6 Merge branch 'master' into minidox 2017-07-14 21:35:50 -04:00
That-Canadian 5412229603 Merge remote-tracking branch 'upstream/master' 2017-07-14 21:34:37 -04:00
That-Canadian e2e0f5d6d1 Merge branch 'minidox' of https://github.com/That-Canadian/qmk_firmware into minidox 2017-07-14 21:33:19 -04:00
That-Canadian 21b63d9243 Updated i2c and serial files to most recent from the lets split firmware. Also updated that_canadian keymap 2017-07-14 21:24:58 -04:00
Jack Humbert 6ed8ce4f59 Merge pull request #1491 from fredizzimo/msys2
Add support for msys2 build environment
2017-07-13 14:24:26 -04:00
ishtob 087af43dee fix implementation issues from SSD1306 clean up, added rotation (#1494)
* moved OLED update task to keymap

* fix splitting render display to keymap

* Added rotation option for OLED, fixed splitting display render update to keymap

* issues with attribute
2017-07-12 12:10:28 -04:00
Fred Sundvik b7d8dec7dc Fix printf error in make output on msys2 2017-07-12 13:04:50 +03:00
Fred Sundvik 7f67abd7d7 Fix bitfield problem when compiling in native mingw 2017-07-11 22:05:01 +03:00
Jack Humbert cc468523df clean up ssd1306 implementation 2017-07-11 14:23:26 -04:00
Fred Sundvik 78545b9509 Fix unreferenced errors with mingw compiler and unit tests 2017-07-11 19:41:04 +03:00
Fred Sundvik 5a25d50168 Add more dependencies, everything can be compiled now 2017-07-11 18:51:52 +03:00
Fred Sundvik 5c3fd67198 Add tools to the path 2017-07-11 17:55:03 +03:00
Fred Sundvik 0d9e7f635e Extract flip 2017-07-11 17:32:58 +03:00
Fred Sundvik 76bd0d3e18 Install arm toolchain 2017-07-11 17:18:24 +03:00
Fred Sundvik b8c363099b Download and extract avr tools 2017-07-11 16:44:46 +03:00
Fred Sundvik b85ce4ce22 Fix overlong lines, and a few spelling errors 2017-07-11 16:26:29 +03:00
Fred Sundvik d47db637ed Use home directory for download on msys2 2017-07-11 16:11:37 +03:00
That-Canadian d73d30aa84 Merge remote-tracking branch 'upstream/master' 2017-07-10 21:24:20 -04:00
That-Canadian a4958a532d Fixed RGB being enabled by default, now it must be turned on at the keymap level 2017-07-10 17:12:18 -04:00
That-Canadian df50260300 cleaned up that_canadian keymap comments 2017-07-10 16:59:20 -04:00
That-Canadian 55ed97af1e Merge branch 'master' into minidox 2017-07-10 16:53:49 -04:00
That-Canadian 07bf8522ca Merge remote-tracking branch 'upstream/master' 2017-07-10 16:52:56 -04:00
That-Canadian 1fdf3c84fe Updated minidox rev1 config, and readme. Also updated that_canadian keymap to include RGB 2017-07-10 16:51:37 -04:00
Fred Sundvik 32fc4da4a7 Install unzip 2017-07-10 18:16:35 +03:00
Fred Sundvik 861087096b Add symlinks only on WSL 2017-07-10 18:05:32 +03:00
Fred Sundvik 7bedf8f4f2 Fix launch of qmk_driver_installer on msys2 2017-07-10 17:51:59 +03:00
Fred Sundvik a2d3fc98b8 Initial structure for shared msys2 and wsl installation 2017-07-10 17:31:58 +03:00
That-Canadian 9312b9db6c Added MiniDox keyboard folder / configs / and some keymaps 2017-07-10 00:46:19 -04:00
That-Canadian 707f4efd99 line ending stuff 2017-07-10 00:30:40 -04:00
That-Canadian e7a5fee1f3 merge 2017-07-10 00:21:38 -04:00
56 changed files with 1423 additions and 587 deletions

No files matched your search

+1
View File
@@ -23,6 +23,7 @@ quantum/version.h
CMakeLists.txt CMakeLists.txt
.DS_STORE .DS_STORE
/util/wsl_downloaded /util/wsl_downloaded
/util/win_downloaded
# Eclipse/PyCharm/Other IDE Settings # Eclipse/PyCharm/Other IDE Settings
.cproject .cproject
+1 -1
View File
@@ -419,7 +419,7 @@ define BUILD_TEST
MAKE_TARGET := $2 MAKE_TARGET := $2
COMMAND := $1 COMMAND := $1
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_test.mk $$(MAKE_TARGET) MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_test.mk $$(MAKE_TARGET)
MAKE_VARS := TEST=$$(TEST_NAME) FULL_TESTS=$$(FULL_TESTS) MAKE_VARS := TEST=$$(TEST_NAME) FULL_TESTS="$$(FULL_TESTS)"
MAKE_MSG := $$(MSG_MAKE_TEST) MAKE_MSG := $$(MSG_MAKE_TEST)
$$(eval $$(call BUILD)) $$(eval $$(call BUILD))
ifneq ($$(MAKE_TARGET),clean) ifneq ($$(MAKE_TARGET),clean)
+2 -1
View File
@@ -21,12 +21,13 @@ $(TEST)_SRC= \
$(TEST_PATH)/keymap.c \ $(TEST_PATH)/keymap.c \
$(TMK_COMMON_SRC) \ $(TMK_COMMON_SRC) \
$(QUANTUM_SRC) \ $(QUANTUM_SRC) \
$(SRC) \
tests/test_common/matrix.c \ tests/test_common/matrix.c \
tests/test_common/test_driver.cpp \ tests/test_common/test_driver.cpp \
tests/test_common/keyboard_report_util.cpp \ tests/test_common/keyboard_report_util.cpp \
tests/test_common/test_fixture.cpp tests/test_common/test_fixture.cpp
$(TEST)_SRC += $(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp)) $(TEST)_SRC += $(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
$(TEST)_DEFS=$(TMK_COMMON_DEFS) $(TEST)_DEFS=$(TMK_COMMON_DEFS) $(OPT_DEFS)
$(TEST)_CONFIG=$(TEST_PATH)/config.h $(TEST)_CONFIG=$(TEST_PATH)/config.h
VPATH+=$(TOP_DIR)/tests/test_common VPATH+=$(TOP_DIR)/tests/test_common
+1 -1
View File
@@ -7,7 +7,7 @@
* [FAQ: Compiling QMK](faq_build.md) * [FAQ: Compiling QMK](faq_build.md)
* [How to Github](how_to_github.md) * [How to Github](how_to_github.md)
* [Features](features/README.md) * [Features](features.md)
* [Layer switching](key_functions.md) * [Layer switching](key_functions.md)
* [Leader Key](leader_key.md) * [Leader Key](leader_key.md)
* [Macros](macros.md) * [Macros](macros.md)
+1 -1
View File
@@ -36,7 +36,7 @@ enum my_keycodes {
## Programming The Behavior Of Any Keycode ## Programming The Behavior Of Any Keycode
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()' and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up you to send any key up or down events that are required. When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up you to send any key up or down events that are required.
These function are called every time a key is pressed or released. These function are called every time a key is pressed or released.
+1 -1
View File
@@ -102,4 +102,4 @@ case MACRO_RAISED:
update_tri_layer(LAYER_LOWER, LAYER_RAISED, LAYER_ADJUST); update_tri_layer(LAYER_LOWER, LAYER_RAISED, LAYER_ADJUST);
} }
break; break;
``` ```
+45 -30
View File
@@ -1,52 +1,52 @@
## Audio output from a speaker ## Audio output from a speaker
Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any keyboard that allows access to the C6 or B5 port (`#define C6_AUDIO` and `#define B5_AUDIO`), you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to the C6 or B5 port (`#define C6_AUDIO` and/or `#define B5_AUDIO`), you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes.
The audio code lives in [quantum/audio/audio.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/audio.h) and in the other files in the audio directory. It's enabled by default on the Planck [stock keymap](https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/default/keymap.c). Here are the important bits: If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration:
``` ```
#include "audio.h" STARTUP_SONG // plays when the keyboard starts up (audio.c)
GOODBYE_SONG // plays when you press the RESET key (quantum.c)
AG_NORM_SONG // plays when you press AG_NORM (quantum.c)
AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c)
MUSIC_ON_SONG // plays when music mode is activated (process_music.c)
MUSIC_OFF_SONG // plays when music mode is deactivated (process_music.c)
CHROMATIC_SONG // plays when the chromatic music mode is selected (process_music.c)
GUITAR_SONG // plays when the guitar music mode is selected (process_music.c)
VIOLIN_SONG // plays when the violin music mode is selected (process_music.c)
MAJOR_SONG // plays when the major music mode is selected (process_music.c)
``` ```
Then, lower down the file: You can override the default songs by doing something like this in your `config.h`:
``` ```c
float tone_startup[][2] = { #ifdef AUDIO_ENABLE
ED_NOTE(_E7 ), #define STARTUP_SONG SONG(STARTUP_SOUND)
E__NOTE(_CS7), #endif
E__NOTE(_E6 ),
E__NOTE(_A6 ),
M__NOTE(_CS7, 20)
};
``` ```
This is how you write a song. Each of these lines is a note, so we have a little ditty composed of five notes here. A full list of sounds can be found in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) - feel free to add your own to this list! All available notes can be seen in [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h).
Then, we have this chunk: To play a custom sound at a particular time, you can define a song like this (near the top of the file):
``` ```c
float tone_qwerty[][2] = SONG(QWERTY_SOUND); float my_song[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_plover[][2] = SONG(PLOVER_SOUND);
float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
float goodbye[][2] = SONG(GOODBYE_SOUND);
``` ```
Wherein we bind predefined songs (from [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h)) into named variables. This is one optimization that helps save on memory: These songs only take up memory when you reference them in your keymap, because they're essentially all preprocessor directives. And then play your song like this:
So now you have something called `tone_plover` for example. How do you make it play the Plover tune, then? If you look further down the keymap, you'll see this: ```c
PLAY_SONG(my_song);
```
PLAY_NOTE_ARRAY(tone_plover, false, 0); // Signature is: Song name, repeat, rest style
``` ```
This is inside one of the macros. So when that macro executes, your keyboard plays that particular chime. Alternatively, you can play it in a loop like this:
"Rest style" in the method signature above (the last parameter) specifies if there's a rest (a moment of silence) between the notes. ```c
PLAY_LOOP(my_song);
```
It's advised that you wrap all audio features in `#ifdef AUDIO_ENABLE` / `#endif` to avoid causing problems when audio isn't built into the keyboard.
## Music mode ## Music mode
@@ -59,6 +59,11 @@ Keycodes available:
* `MU_ON` - Turn music mode on * `MU_ON` - Turn music mode on
* `MU_OFF` - Turn music mode off * `MU_OFF` - Turn music mode off
* `MU_TOG` - Toggle music mode * `MU_TOG` - Toggle music mode
* `MU_MOD` - Cycle through the music modes:
* `CHROMATIC_MODE` - Chromatic scale, row changes the octave
* `GUITAR_MODE` - Chromatic scale, but the row changes the string (+5 st)
* `VIOLIN_MODE` - Chromatic scale, but the row changes the string (+7 st)
* `MAJOR_MODE` - Major scale
In music mode, the following keycodes work differently, and don't pass through: In music mode, the following keycodes work differently, and don't pass through:
@@ -68,6 +73,16 @@ In music mode, the following keycodes work differently, and don't pass through:
* `KC_UP` - speed-up playback * `KC_UP` - speed-up playback
* `KC_DOWN` - slow-down playback * `KC_DOWN` - slow-down playback
By default, `MUSIC_MASK` is set to `keycode < 0xFF` which means keycodes less than `0xFF` are turned into notes, and don't output anything. You can change this by defining this in your `config.h` like this:
#define MUSIC_MASK keycode != KC_NO
Which will capture all keycodes - be careful, this will get you stuck in music mode until you restart your keyboard!
The pitch standard (`PITCH_STANDARD_A`) is 440.0f by default - to change this, add something like this to your `config.h`:
#define PITCH_STANDARD_A 432.0f
## MIDI functionalty ## MIDI functionalty
This is still a WIP, but check out `quantum/keymap_midi.c` to see what's happening. Enable from the Makefile. This is still a WIP, but check out `quantum/keymap_midi.c` to see what's happening. Enable from the Makefile.
+22 -166
View File
@@ -1,7 +1,6 @@
#ifdef SSD1306OLED #ifdef SSD1306OLED
#include "ssd1306.h" #include "ssd1306.h"
#include "config.h"
#include "i2c.h" #include "i2c.h"
#include <string.h> #include <string.h>
#include "print.h" #include "print.h"
@@ -13,18 +12,7 @@
#include "lufa.h" #include "lufa.h"
#endif #endif
#include "sendchar.h" #include "sendchar.h"
#include "pincontrol.h" #include "timer.h"
//assign the right code to your layers
#define _BASE 0
#define _LOWER 8
#define _RAISE 16
#define _FNLAYER 64
#define _NUMLAY 128
#define _NLOWER 136
#define _NFNLAYER 192
#define _MOUSECURSOR 256
#define _ADJUST 65560
// Set this to 1 to help diagnose early startup problems // Set this to 1 to help diagnose early startup problems
// when testing power-on with ble. Turn it off otherwise, // when testing power-on with ble. Turn it off otherwise,
@@ -32,26 +20,6 @@
// with the matrix scan, causing keys to drop. // with the matrix scan, causing keys to drop.
#define DEBUG_TO_SCREEN 0 #define DEBUG_TO_SCREEN 0
// Controls the SSD1306 128x32 OLED display via i2c
#define i2cAddress 0x3C
#define DisplayHeight 32
#define DisplayWidth 128
#define FontHeight 8
#define FontWidth 6
#define MatrixRows (DisplayHeight / FontHeight)
#define MatrixCols (DisplayWidth / FontWidth)
struct CharacterMatrix {
uint8_t display[MatrixRows][MatrixCols];
uint8_t *cursor;
bool dirty;
};
static struct CharacterMatrix display;
//static uint16_t last_battery_update; //static uint16_t last_battery_update;
//static uint32_t vbat; //static uint32_t vbat;
//#define BatteryUpdateInterval 10000 /* milliseconds */ //#define BatteryUpdateInterval 10000 /* milliseconds */
@@ -61,54 +29,13 @@ static uint8_t displaying;
#endif #endif
static uint16_t last_flush; static uint16_t last_flush;
enum ssd1306_cmds {
DisplayOff = 0xAE,
DisplayOn = 0xAF,
SetContrast = 0x81,
DisplayAllOnResume = 0xA4,
DisplayAllOn = 0xA5,
NormalDisplay = 0xA6,
InvertDisplay = 0xA7,
SetDisplayOffset = 0xD3,
SetComPins = 0xda,
SetVComDetect = 0xdb,
SetDisplayClockDiv = 0xD5,
SetPreCharge = 0xd9,
SetMultiPlex = 0xa8,
SetLowColumn = 0x00,
SetHighColumn = 0x10,
SetStartLine = 0x40,
SetMemoryMode = 0x20,
ColumnAddr = 0x21,
PageAddr = 0x22,
ComScanInc = 0xc0,
ComScanDec = 0xc8,
SegRemap = 0xa0,
SetChargePump = 0x8d,
ExternalVcc = 0x01,
SwitchCapVcc = 0x02,
ActivateScroll = 0x2f,
DeActivateScroll = 0x2e,
SetVerticalScrollArea = 0xa3,
RightHorizontalScroll = 0x26,
LeftHorizontalScroll = 0x27,
VerticalAndRightHorizontalScroll = 0x29,
VerticalAndLeftHorizontalScroll = 0x2a,
};
// Write command sequence. // Write command sequence.
// Returns true on success. // Returns true on success.
static inline bool _send_cmd1(uint8_t cmd) { static inline bool _send_cmd1(uint8_t cmd) {
bool res = false; bool res = false;
if (i2c_start_write(i2cAddress)) { if (i2c_start_write(SSD1306_ADDRESS)) {
xprintf("failed to start write to %d\n", i2cAddress); xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
goto done; goto done;
} }
@@ -153,8 +80,6 @@ static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} #define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} #define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
static void matrix_clear(struct CharacterMatrix *matrix);
static void clear_display(void) { static void clear_display(void) {
matrix_clear(&display); matrix_clear(&display);
@@ -163,7 +88,7 @@ static void clear_display(void) {
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1); send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
if (i2c_start_write(i2cAddress)) { if (i2c_start_write(SSD1306_ADDRESS)) {
goto done; goto done;
} }
if (i2c_master_write(0x40)) { if (i2c_master_write(0x40)) {
@@ -209,14 +134,17 @@ bool iota_gfx_init(void) {
send_cmd2(SetChargePump, 0x14 /* Enable */); send_cmd2(SetChargePump, 0x14 /* Enable */);
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
/// Flips the display orientation 0 degrees #ifdef OLED_ROTATE180
send_cmd1(SegRemap | 0x1);
send_cmd1(ComScanDec);
/*
// the following Flip the display orientation 180 degrees // the following Flip the display orientation 180 degrees
send_cmd1(SegRemap); send_cmd1(SegRemap);
send_cmd1(ComScanInc); send_cmd1(ComScanInc);
// end flip */ #endif
#ifndef OLED_ROTATE180
// Flips the display orientation 0 degrees
send_cmd1(SegRemap | 0x1);
send_cmd1(ComScanDec);
#endif
send_cmd2(SetComPins, 0x2); send_cmd2(SetComPins, 0x2);
send_cmd2(SetContrast, 0x8f); send_cmd2(SetContrast, 0x8f);
send_cmd2(SetPreCharge, 0xf1); send_cmd2(SetPreCharge, 0xf1);
@@ -262,7 +190,7 @@ done:
return success; return success;
} }
static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
*matrix->cursor = c; *matrix->cursor = c;
++matrix->cursor; ++matrix->cursor;
@@ -275,7 +203,7 @@ static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
} }
} }
static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
matrix->dirty = true; matrix->dirty = true;
if (c == '\n') { if (c == '\n') {
@@ -296,7 +224,7 @@ void iota_gfx_write_char(uint8_t c) {
matrix_write_char(&display, c); matrix_write_char(&display, c);
} }
static void matrix_write(struct CharacterMatrix *matrix, const char *data) { void matrix_write(struct CharacterMatrix *matrix, const char *data) {
const char *end = data + strlen(data); const char *end = data + strlen(data);
while (data < end) { while (data < end) {
matrix_write_char(matrix, *data); matrix_write_char(matrix, *data);
@@ -308,7 +236,7 @@ void iota_gfx_write(const char *data) {
matrix_write(&display, data); matrix_write(&display, data);
} }
static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
while (true) { while (true) {
uint8_t c = pgm_read_byte(data); uint8_t c = pgm_read_byte(data);
if (c == 0) { if (c == 0) {
@@ -323,7 +251,7 @@ void iota_gfx_write_P(const char *data) {
matrix_write_P(&display, data); matrix_write_P(&display, data);
} }
static void matrix_clear(struct CharacterMatrix *matrix) { void matrix_clear(struct CharacterMatrix *matrix) {
memset(matrix->display, ' ', sizeof(matrix->display)); memset(matrix->display, ' ', sizeof(matrix->display));
matrix->cursor = &matrix->display[0][0]; matrix->cursor = &matrix->display[0][0];
matrix->dirty = true; matrix->dirty = true;
@@ -333,7 +261,7 @@ void iota_gfx_clear_screen(void) {
matrix_clear(&display); matrix_clear(&display);
} }
static void matrix_render(struct CharacterMatrix *matrix) { void matrix_render(struct CharacterMatrix *matrix) {
last_flush = timer_read(); last_flush = timer_read();
iota_gfx_on(); iota_gfx_on();
#if DEBUG_TO_SCREEN #if DEBUG_TO_SCREEN
@@ -344,7 +272,7 @@ static void matrix_render(struct CharacterMatrix *matrix) {
send_cmd3(PageAddr, 0, MatrixRows - 1); send_cmd3(PageAddr, 0, MatrixRows - 1);
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
if (i2c_start_write(i2cAddress)) { if (i2c_start_write(SSD1306_ADDRESS)) {
goto done; goto done;
} }
if (i2c_master_write(0x40)) { if (i2c_master_write(0x40)) {
@@ -379,84 +307,12 @@ void iota_gfx_flush(void) {
matrix_render(&display); matrix_render(&display);
} }
static void matrix_update(struct CharacterMatrix *dest, __attribute__ ((weak))
const struct CharacterMatrix *source) { void iota_gfx_task_user(void) {
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
memcpy(dest->display, source->display, sizeof(dest->display));
dest->dirty = true;
}
}
static void render_status_info(void) {
#if DEBUG_TO_SCREEN
if (debug_enable) {
return;
}
#endif
struct CharacterMatrix matrix;
matrix_clear(&matrix);
matrix_write_P(&matrix, PSTR("USB: "));
#ifdef PROTOCOL_LUFA
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
matrix_write_P(&matrix, PSTR("Unattached"));
break;
case DEVICE_STATE_Suspended:
matrix_write_P(&matrix, PSTR("Suspended"));
break;
case DEVICE_STATE_Configured:
matrix_write_P(&matrix, PSTR("Connected"));
break;
case DEVICE_STATE_Powered:
matrix_write_P(&matrix, PSTR("Powered"));
break;
case DEVICE_STATE_Default:
matrix_write_P(&matrix, PSTR("Default"));
break;
case DEVICE_STATE_Addressed:
matrix_write_P(&matrix, PSTR("Addressed"));
break;
default:
matrix_write_P(&matrix, PSTR("Invalid"));
}
#endif
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
char buf[40];
snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
matrix_write_P(&matrix, PSTR("\n\nLayer: "));
switch (layer_state) {
case _BASE:
matrix_write_P(&matrix, PSTR("Default"));
break;
case _RAISE:
matrix_write_P(&matrix, PSTR("Raise"));
break;
case _LOWER:
matrix_write_P(&matrix, PSTR("Lower"));
break;
case _ADJUST:
matrix_write_P(&matrix, PSTR("ADJUST"));
break;
default:
matrix_write(&matrix, buf);
}
// Host Keyboard LED Status
char led[40];
snprintf(led, sizeof(led), "\n%s %s %s",
(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
matrix_write(&matrix, led);
matrix_update(&display, &matrix);
} }
void iota_gfx_task(void) { void iota_gfx_task(void) {
render_status_info(); iota_gfx_task_user();
if (display.dirty) { if (display.dirty) {
iota_gfx_flush(); iota_gfx_flush();
+76
View File
@@ -3,6 +3,71 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "pincontrol.h"
#include "config.h"
enum ssd1306_cmds {
DisplayOff = 0xAE,
DisplayOn = 0xAF,
SetContrast = 0x81,
DisplayAllOnResume = 0xA4,
DisplayAllOn = 0xA5,
NormalDisplay = 0xA6,
InvertDisplay = 0xA7,
SetDisplayOffset = 0xD3,
SetComPins = 0xda,
SetVComDetect = 0xdb,
SetDisplayClockDiv = 0xD5,
SetPreCharge = 0xd9,
SetMultiPlex = 0xa8,
SetLowColumn = 0x00,
SetHighColumn = 0x10,
SetStartLine = 0x40,
SetMemoryMode = 0x20,
ColumnAddr = 0x21,
PageAddr = 0x22,
ComScanInc = 0xc0,
ComScanDec = 0xc8,
SegRemap = 0xa0,
SetChargePump = 0x8d,
ExternalVcc = 0x01,
SwitchCapVcc = 0x02,
ActivateScroll = 0x2f,
DeActivateScroll = 0x2e,
SetVerticalScrollArea = 0xa3,
RightHorizontalScroll = 0x26,
LeftHorizontalScroll = 0x27,
VerticalAndRightHorizontalScroll = 0x29,
VerticalAndLeftHorizontalScroll = 0x2a,
};
// Controls the SSD1306 128x32 OLED display via i2c
#ifndef SSD1306_ADDRESS
#define SSD1306_ADDRESS 0x3C
#endif
#define DisplayHeight 32
#define DisplayWidth 128
#define FontHeight 8
#define FontWidth 6
#define MatrixRows (DisplayHeight / FontHeight)
#define MatrixCols (DisplayWidth / FontWidth)
struct CharacterMatrix {
uint8_t display[MatrixRows][MatrixCols];
uint8_t *cursor;
bool dirty;
};
struct CharacterMatrix display;
bool iota_gfx_init(void); bool iota_gfx_init(void);
void iota_gfx_task(void); void iota_gfx_task(void);
@@ -14,4 +79,15 @@ void iota_gfx_write(const char *data);
void iota_gfx_write_P(const char *data); void iota_gfx_write_P(const char *data);
void iota_gfx_clear_screen(void); void iota_gfx_clear_screen(void);
void iota_gfx_task_user(void);
void matrix_clear(struct CharacterMatrix *matrix);
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c);
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c);
void matrix_write(struct CharacterMatrix *matrix, const char *data);
void matrix_write_P(struct CharacterMatrix *matrix, const char *data);
void matrix_render(struct CharacterMatrix *matrix);
#endif #endif
@@ -9,6 +9,7 @@
#define USE_I2C #define USE_I2C
#define SSD1306OLED #define SSD1306OLED
#define OLED_ROTATE180
/* ws2812 RGB LED*/ /* ws2812 RGB LED*/
#define RGB_DI_PIN D4 #define RGB_DI_PIN D4
+88
View File
@@ -406,3 +406,91 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO_NONE; return MACRO_NONE;
} }
void matrix_update(struct CharacterMatrix *dest,
const struct CharacterMatrix *source) {
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
memcpy(dest->display, source->display, sizeof(dest->display));
dest->dirty = true;
}
}
//assign the right code to your layers for OLED display
#define L_BASE 0
#define L_LOWER 8
#define L_RAISE 16
#define L_FNLAYER 64
#define L_NUMLAY 128
#define L_NLOWER 136
#define L_NFNLAYER 192
#define L_MOUSECURSOR 256
#define L_ADJUST 65560
void iota_gfx_task_user(void) {
#if DEBUG_TO_SCREEN
if (debug_enable) {
return;
}
#endif
struct CharacterMatrix matrix;
matrix_clear(&matrix);
matrix_write_P(&matrix, PSTR("USB: "));
#ifdef PROTOCOL_LUFA
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
matrix_write_P(&matrix, PSTR("Unattached"));
break;
case DEVICE_STATE_Suspended:
matrix_write_P(&matrix, PSTR("Suspended"));
break;
case DEVICE_STATE_Configured:
matrix_write_P(&matrix, PSTR("Connected"));
break;
case DEVICE_STATE_Powered:
matrix_write_P(&matrix, PSTR("Powered"));
break;
case DEVICE_STATE_Default:
matrix_write_P(&matrix, PSTR("Default"));
break;
case DEVICE_STATE_Addressed:
matrix_write_P(&matrix, PSTR("Addressed"));
break;
default:
matrix_write_P(&matrix, PSTR("Invalid"));
}
#endif
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
char buf[40];
snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
matrix_write_P(&matrix, PSTR("\n\nLayer: "));
switch (layer_state) {
case L_BASE:
matrix_write_P(&matrix, PSTR("Default"));
break;
case L_RAISE:
matrix_write_P(&matrix, PSTR("Raise"));
break;
case L_LOWER:
matrix_write_P(&matrix, PSTR("Lower"));
break;
case L_ADJUST:
matrix_write_P(&matrix, PSTR("ADJUST"));
break;
default:
matrix_write(&matrix, buf);
}
// Host Keyboard LED Status
char led[40];
snprintf(led, sizeof(led), "\n%s %s %s",
(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
matrix_write(&matrix, led);
matrix_update(&display, &matrix);
}
@@ -9,6 +9,7 @@
#define USE_I2C #define USE_I2C
#define SSD1306OLED #define SSD1306OLED
#define OLED_ROTATE180
/* ws2812 RGB LED*/ /* ws2812 RGB LED*/
#define RGB_DI_PIN D4 #define RGB_DI_PIN D4
@@ -416,3 +416,90 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO_NONE; return MACRO_NONE;
} }
void matrix_update(struct CharacterMatrix *dest,
const struct CharacterMatrix *source) {
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
memcpy(dest->display, source->display, sizeof(dest->display));
dest->dirty = true;
}
}
//assign the right code to your layers for OLED display
#define L_BASE 0
#define L_LOWER 8
#define L_RAISE 16
#define L_FNLAYER 64
#define L_NUMLAY 128
#define L_NLOWER 136
#define L_NFNLAYER 192
#define L_MOUSECURSOR 256
#define L_ADJUST 65560
void iota_gfx_task_user(void) {
#if DEBUG_TO_SCREEN
if (debug_enable) {
return;
}
#endif
struct CharacterMatrix matrix;
matrix_clear(&matrix);
matrix_write_P(&matrix, PSTR("USB: "));
#ifdef PROTOCOL_LUFA
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
matrix_write_P(&matrix, PSTR("Unattached"));
break;
case DEVICE_STATE_Suspended:
matrix_write_P(&matrix, PSTR("Suspended"));
break;
case DEVICE_STATE_Configured:
matrix_write_P(&matrix, PSTR("Connected"));
break;
case DEVICE_STATE_Powered:
matrix_write_P(&matrix, PSTR("Powered"));
break;
case DEVICE_STATE_Default:
matrix_write_P(&matrix, PSTR("Default"));
break;
case DEVICE_STATE_Addressed:
matrix_write_P(&matrix, PSTR("Addressed"));
break;
default:
matrix_write_P(&matrix, PSTR("Invalid"));
}
#endif
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
char buf[40];
snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
matrix_write_P(&matrix, PSTR("\n\nLayer: "));
switch (layer_state) {
case L_BASE:
matrix_write_P(&matrix, PSTR("Default"));
break;
case L_RAISE:
matrix_write_P(&matrix, PSTR("Raise"));
break;
case L_LOWER:
matrix_write_P(&matrix, PSTR("Lower"));
break;
case L_ADJUST:
matrix_write_P(&matrix, PSTR("ADJUST"));
break;
default:
matrix_write(&matrix, buf);
}
// Host Keyboard LED Status
char led[40];
snprintf(led, sizeof(led), "\n%s %s %s",
(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
matrix_write(&matrix, led);
matrix_update(&display, &matrix);
}
@@ -6,9 +6,6 @@
#define _FUN 3 #define _FUN 3
#define _MS 4 #define _MS 4
#define _______ KC_NO
#define XXXXXXX KC_TRNS
#define _DK_ACT 0 #define _DK_ACT 0
#define _DK_REL 1 #define _DK_REL 1
#define _KC_COMS 2 #define _KC_COMS 2
@@ -36,6 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define FLIP_HALF #define FLIP_HALF
#define SSD1306OLED #define SSD1306OLED
//#define OLED_ROTATE180
#define PREVENT_STUCK_MODIFIERS #define PREVENT_STUCK_MODIFIERS
@@ -357,3 +357,91 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO_NONE; return MACRO_NONE;
} }
void matrix_update(struct CharacterMatrix *dest,
const struct CharacterMatrix *source) {
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
memcpy(dest->display, source->display, sizeof(dest->display));
dest->dirty = true;
}
}
//assign the right code to your layers for OLED display
#define L_BASE 0
#define L_LOWER 8
#define L_RAISE 16
#define L_FNLAYER 64
#define L_NUMLAY 128
#define L_NLOWER 136
#define L_NFNLAYER 192
#define L_MOUSECURSOR 256
#define L_ADJUST 65560
void iota_gfx_task_user(void) {
#if DEBUG_TO_SCREEN
if (debug_enable) {
return;
}
#endif
struct CharacterMatrix matrix;
matrix_clear(&matrix);
matrix_write_P(&matrix, PSTR("USB: "));
#ifdef PROTOCOL_LUFA
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
matrix_write_P(&matrix, PSTR("Unattached"));
break;
case DEVICE_STATE_Suspended:
matrix_write_P(&matrix, PSTR("Suspended"));
break;
case DEVICE_STATE_Configured:
matrix_write_P(&matrix, PSTR("Connected"));
break;
case DEVICE_STATE_Powered:
matrix_write_P(&matrix, PSTR("Powered"));
break;
case DEVICE_STATE_Default:
matrix_write_P(&matrix, PSTR("Default"));
break;
case DEVICE_STATE_Addressed:
matrix_write_P(&matrix, PSTR("Addressed"));
break;
default:
matrix_write_P(&matrix, PSTR("Invalid"));
}
#endif
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
char buf[40];
snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
matrix_write_P(&matrix, PSTR("\n\nLayer: "));
switch (layer_state) {
case L_BASE:
matrix_write_P(&matrix, PSTR("Default"));
break;
case L_RAISE:
matrix_write_P(&matrix, PSTR("Raise"));
break;
case L_LOWER:
matrix_write_P(&matrix, PSTR("Lower"));
break;
case L_ADJUST:
matrix_write_P(&matrix, PSTR("ADJUST"));
break;
default:
matrix_write(&matrix, buf);
}
// Host Keyboard LED Status
char led[40];
snprintf(led, sizeof(led), "\n%s %s %s",
(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
matrix_write(&matrix, led);
matrix_update(&display, &matrix);
}
+19 -1
View File
@@ -16,7 +16,7 @@
#define SLAVE_BUFFER_SIZE 0x10 #define SLAVE_BUFFER_SIZE 0x10
// i2c SCL clock frequency // i2c SCL clock frequency
#define SCL_CLOCK 100000L #define SCL_CLOCK 400000L
extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
@@ -28,4 +28,22 @@ uint8_t i2c_master_read(int);
void i2c_reset_state(void); void i2c_reset_state(void);
void i2c_slave_init(uint8_t address); void i2c_slave_init(uint8_t address);
static inline unsigned char i2c_start_read(unsigned char addr) {
return i2c_master_start((addr << 1) | I2C_READ);
}
static inline unsigned char i2c_start_write(unsigned char addr) {
return i2c_master_start((addr << 1) | I2C_WRITE);
}
// from SSD1306 scrips
extern unsigned char i2c_rep_start(unsigned char addr);
extern void i2c_start_wait(unsigned char addr);
extern unsigned char i2c_readAck(void);
extern unsigned char i2c_readNak(void);
extern unsigned char i2c_read(unsigned char ack);
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
#endif #endif
@@ -25,6 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define USE_SERIAL #define USE_SERIAL
#define EE_HANDS
/* ws2812 RGB LED */ /* ws2812 RGB LED */
#define RGB_DI_PIN D7 #define RGB_DI_PIN D7
#define RGBLIGHT_TIMER #define RGBLIGHT_TIMER
@@ -40,7 +40,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | Z | X | C | V | B | | N | M | , | . | / | * | Z | X | C | V | B | | N | M | , | . | / |
* `----------------------------------' `----------------------------------' * `----------------------------------' `----------------------------------'
* ,--------------------. ,------,-------------. * ,--------------------. ,------,-------------.
<<<<<<< HEAD
* | Shift| LOWER| | | | RAISE| Ctrl |
=======
* | Ctrl | LOWER| | | | RAISE| Shift| * | Ctrl | LOWER| | | | RAISE| Shift|
>>>>>>> a4958a532da154b9dd6f6144836a73f9de641f74
* `-------------| Space| |BckSpc|------+------. * `-------------| Space| |BckSpc|------+------.
* | | | | * | | | |
* `------' `------' * `------' `------'
@@ -49,7 +53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, \ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, \
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, \ KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, \
KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, \ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, \
KC_LCTL, LOWER, KC_SPC, KC_BSPC, RAISE, OSM(MOD_LSFT) \ OSM(MOD_LSFT), LOWER, KC_SPC, KC_BSPC, RAISE, KC_LCTL \
), ),
/* Raise /* Raise
-2
View File
@@ -226,9 +226,7 @@ uint8_t matrix_scan(void)
TXLED0; TXLED0;
error_count = 0; error_count = 0;
} }
matrix_scan_quantum(); matrix_scan_quantum();
return ret; return ret;
} }
+62 -2
View File
@@ -1,5 +1,5 @@
ECO MiniDox
=== =====
![MimiDox](http://i.imgur.com/iWb3yO0.jpg) ![MimiDox](http://i.imgur.com/iWb3yO0.jpg)
@@ -13,3 +13,63 @@ Make example for this keyboard (after setting up your build environment):
make minidox-rev1-default make minidox-rev1-default
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
## Build Guide
A build guide for putting together the MiniDox v1 can be found here: [MiniDox Build Log / Guide](http://imgur.com/a/vImo6)
Flashing
-------
Note: Most of this is copied from the Let's Split readme, because it is awesome
From the keymap directory run `make SUBPROJECT-KEYMAP-avrdude` for automatic serial port resolution and flashing.
Example: `make rev1-default-avrdude`
Choosing which board to plug the USB cable into (choosing Master)
--------
Because the two boards are identical, the firmware has logic to differentiate the left and right board.
It uses two strategies to figure things out: look at the EEPROM (memory on the chip) or looks if the current board has the usb cable.
The EEPROM approach requires additional setup (flashing the eeeprom) but allows you to swap the usb cable to either side.
The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.
### Setting the left hand as master
If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.
### Setting the right hand as master
If you always plug the usb cable into the right board, add an extra flag to your `config.h`
```
#define MASTER_RIGHT
```
### Setting EE_hands to use either hands as master
If you define `EE_HANDS` in your `config.h`, you will need to set the
EEPROM for the left and right halves.
The EEPROM is used to store whether the
half is left handed or right handed. This makes it so that the same firmware
file will run on both hands instead of having to flash left and right handed
versions of the firmware to each half. To flash the EEPROM file for the left
half run:
```
avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-lefthand.eep
// or the equivalent in dfu-programmer
```
and similarly for right half
```
avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-righhand.eep
// or the equivalent in dfu-programmer
```
NOTE: replace `$(COM_PORT)` with the port of your device (e.g. `/dev/ttyACM0`)
After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.
Note that you need to program both halves, but you have the option of using
different keymaps for each half. You could program the left half with a QWERTY
layout and the right half with a Colemak layout using bootmagic's default layout option.
Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the
right half is connected.
+1 -1
View File
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define USE_SERIAL #define USE_SERIAL
// #define EE_HANDS //#define EE_HANDS
#define I2C_MASTER_LEFT #define I2C_MASTER_LEFT
//#define I2C_MASTER_RIGHT //#define I2C_MASTER_RIGHT
+5 -1
View File
@@ -21,7 +21,8 @@ static void setup_handedness(void) {
#ifdef EE_HANDS #ifdef EE_HANDS
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
#else #else
#ifdef I2C_MASTER_RIGHT // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
isLeftHand = !has_usb(); isLeftHand = !has_usb();
#else #else
isLeftHand = has_usb(); isLeftHand = has_usb();
@@ -32,6 +33,9 @@ static void setup_handedness(void) {
static void keyboard_master_setup(void) { static void keyboard_master_setup(void) {
#ifdef USE_I2C #ifdef USE_I2C
i2c_master_init(); i2c_master_init();
#ifdef SSD1306OLED
matrix_master_OLED_init ();
#endif
#else #else
serial_master_init(); serial_master_init();
#endif #endif
+2
View File
@@ -19,4 +19,6 @@ void split_keyboard_setup(void);
bool has_usb(void); bool has_usb(void);
void keyboard_slave_loop(void); void keyboard_slave_loop(void);
void matrix_master_OLED_init (void);
#endif #endif
+13
View File
@@ -3,6 +3,18 @@
#include "../../config.h" #include "../../config.h"
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
// #define STARTUP_SONG SONG(NO_SOUND)
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
SONG(COLEMAK_SOUND), \
SONG(DVORAK_SOUND) \
}
#endif
#define MUSIC_MASK (keycode != KC_NO)
/* /*
* MIDI options * MIDI options
*/ */
@@ -13,6 +25,7 @@
/* enable basic MIDI features: /* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on - MIDI notes can be sent when in Music mode is on
*/ */
#define MIDI_BASIC #define MIDI_BASIC
/* enable advanced MIDI features: /* enable advanced MIDI features:
+24 -80
View File
@@ -1,20 +1,24 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard, /* Copyright 2015-2017 Jack Humbert
// this is the style you want to emulate. *
* 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 "planck.h" #include "planck.h"
#include "action_layer.h" #include "action_layer.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
#include "eeconfig.h"
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
enum planck_layers { enum planck_layers {
_QWERTY, _QWERTY,
_COLEMAK, _COLEMAK,
@@ -36,10 +40,6 @@ enum planck_keycodes {
EXT_PLV EXT_PLV
}; };
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty /* Qwerty
@@ -164,7 +164,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/ */
[_ADJUST] = { [_ADJUST] = {
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL }, {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL },
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______}, {_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______}, {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
} }
@@ -173,50 +173,27 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
}; };
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
float plover_song[][2] = SONG(PLOVER_SOUND);
float tone_startup[][2] = SONG(STARTUP_SOUND); float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_plover[][2] = SONG(PLOVER_SOUND);
float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif #endif
void persistent_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) { switch (keycode) {
case QWERTY: case QWERTY:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_QWERTY);
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistent_default_layer_set(1UL<<_QWERTY);
} }
return false; return false;
break; break;
case COLEMAK: case COLEMAK:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_COLEMAK);
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistent_default_layer_set(1UL<<_COLEMAK);
} }
return false; return false;
break; break;
case DVORAK: case DVORAK:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_DVORAK);
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistent_default_layer_set(1UL<<_DVORAK);
} }
return false; return false;
break; break;
@@ -255,7 +232,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
stop_all_notes(); stop_all_notes();
PLAY_NOTE_ARRAY(tone_plover, false, 0); PLAY_SONG(plover_song);
#endif #endif
layer_off(_RAISE); layer_off(_RAISE);
layer_off(_LOWER); layer_off(_LOWER);
@@ -273,7 +250,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case EXT_PLV: case EXT_PLV:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_plover_gb, false, 0); PLAY_SONG(plover_gb_song);
#endif #endif
layer_off(_PLOVER); layer_off(_PLOVER);
} }
@@ -281,37 +258,4 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
break; break;
} }
return true; return true;
} }
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif
@@ -3,6 +3,18 @@
#include "../../config.h" #include "../../config.h"
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
// #define STARTUP_SONG SONG(NO_SOUND)
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
SONG(COLEMAK_SOUND), \
SONG(DVORAK_SOUND) \
}
#endif
#define MUSIC_MASK (keycode != KC_NO)
/* /*
* MIDI options * MIDI options
*/ */
@@ -13,6 +25,7 @@
/* enable basic MIDI features: /* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on - MIDI notes can be sent when in Music mode is on
*/ */
#define MIDI_BASIC #define MIDI_BASIC
/* enable advanced MIDI features: /* enable advanced MIDI features:
+20 -81
View File
@@ -1,14 +1,21 @@
/* Copyright 2015-2017 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/>.
*/
#include "preonic.h" #include "preonic.h"
#include "action_layer.h" #include "action_layer.h"
#include "eeconfig.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
enum preonic_layers { enum preonic_layers {
_QWERTY, _QWERTY,
@@ -28,10 +35,6 @@ enum preonic_keycodes {
BACKLIT BACKLIT
}; };
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty /* Qwerty
@@ -155,7 +158,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = { [_ADJUST] = {
{KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12}, {KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12},
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL}, {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______}, {_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______}, {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
} }
@@ -163,54 +166,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
}; };
#ifdef AUDIO_ENABLE
float tone_startup[][2] = {
{NOTE_B5, 20},
{NOTE_B6, 8},
{NOTE_DS6, 20},
{NOTE_B6, 8}
};
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
#endif
void persistent_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) { switch (keycode) {
case QWERTY: case QWERTY:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_QWERTY);
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistent_default_layer_set(1UL<<_QWERTY);
} }
return false; return false;
break; break;
case COLEMAK: case COLEMAK:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_COLEMAK);
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistent_default_layer_set(1UL<<_COLEMAK);
} }
return false; return false;
break; break;
case DVORAK: case DVORAK:
if (record->event.pressed) { if (record->event.pressed) {
#ifdef AUDIO_ENABLE set_single_persistent_default_layer(_DVORAK);
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistent_default_layer_set(1UL<<_DVORAK);
} }
return false; return false;
break; break;
@@ -248,36 +220,3 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
} }
return true; return true;
}; };
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif
@@ -0,0 +1,22 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
TAP_DANCE_ENABLE = yes # Enable Tap Dance functionality
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
@@ -0,0 +1,15 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here
#define TAPPING_TERM 175
#ifdef BACKLIGHT_ENABLE
#define BACKLIGHT_PIN B5
#define BACKLIGHT_LEVELS 3
#define BACKLIGHT_ON_STATE 0
#endif
#endif
@@ -0,0 +1,242 @@
#include "roadkit.h"
#include "action_layer.h"
#include "eeconfig.h"
extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _NP 0
#define _L1 1
#define _L2 2
#define _L3 3
// Macro name shortcuts
#define NUMPAD M(_NP)
#define LAYER1 M(_L1)
#define LAYER2 M(_L2)
#define LAYER3 M(_L3)
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
void matrix_init_user(void) {
backlight_level(4);
}
//Tap Dance Declarations
enum {
TD_EQUAL_NP = 0,
TD_KP_PLUS_L1,
TD_DOT_L2,
TD_0_L3
};
//Tap Dance Definitions
//TD equal to turn on layer NP
void _td_equal_tg_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code(KC_EQUAL);
} else if (state->count == 2) {
backlight_set(3);
layer_on(_NP);
layer_off(_L1);
layer_off(_L2);
layer_off(_L3);
}
}
void _td_equal_tg_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code(KC_EQUAL);
}
}
//TD kp plus to toggle layer 1
void _td_kp_plus_tg_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code(KC_KP_PLUS);
} else if (state->count == 2) {
// layer_invert(_L1);
backlight_set(2);
layer_on(_L1);
layer_off(_L2);
layer_off(_L3);
}
}
void _td_kp_plus_tg_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code(KC_KP_PLUS);
}
}
//TD dot to toggle layer 2
void _td_dot_tg_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code(KC_DOT);
} else if (state->count == 2) {
backlight_set(1);
layer_on(_L2);
layer_off(_L1);
layer_off(_L3);
}
}
void _td_dot_tg_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code(KC_DOT);
}
}
//TD 0 to toggle layer 3
void _td_0_tg_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code(KC_0);
} else if (state->count == 2) {
backlight_set(0);
layer_on(_L3);
layer_off(_L1);
layer_off(_L2);
}
}
void _td_0_tg_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code(KC_0);
}
}
//TD Actions
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_EQUAL_NP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, _td_equal_tg_finished, _td_equal_tg_reset),
[TD_KP_PLUS_L1] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, _td_kp_plus_tg_finished, _td_kp_plus_tg_reset),
[TD_DOT_L2] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, _td_dot_tg_finished, _td_dot_tg_reset),
[TD_0_L3] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, _td_0_tg_finished, _td_0_tg_reset)
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Numberpad
* ,-----------------------.
* | 7 | 8 | 9 | / |
* |-----`-----`-----`-----|
* | 4 | 5 | 6 | * |
* |-----`-----`-----`-----|
* | 1 | 2 | 3 | - |
* |-----`-----`-----`-----|
* | 0 | . | + | = |
* `-----`-----`-----`-----'
* Tapdances:
* | L3 | L2 | L1 | NP |
* `-----`-----`-----`-----'
*/
[_NP] = /* Numpad */
SINGLES_KEYMAP(KC_7, KC_8, KC_9, KC_SLASH, \
KC_4, KC_5, KC_6, KC_KP_ASTERISK, \
KC_1, KC_2, KC_3, KC_MINUS, \
TD(TD_0_L3), TD(TD_DOT_L2), TD(TD_KP_PLUS_L1), TD(TD_EQUAL_NP)),
/* L1
* ,-----------------------.
* | Esc |Bksp |Home |PgUp |
* |-----`-----`-----`-----|
* | Tab | Up | End |PgDn |
* |-----`-----`-----`-----|
* |Left |Down |Right|Enter|
* |-----`-----`-----`-----|
* | 0 | . | + | = |
* `-----`-----`-----`-----'
*/
[_L1] = /* LAYER 1 */
SINGLES_KEYMAP(KC_ESCAPE, KC_BSPACE, KC_HOME, KC_PGUP, \
KC_TAB, KC_UP, KC_END, KC_PGDOWN, \
KC_LEFT, KC_DOWN, KC_RIGHT, KC_KP_ENTER, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
/* L2
* ,-----------------------.
* |Sleep|LClik|RClik|VolUp|
* |-----`-----`-----`-----|
* |AltF4| F11 |WinTb|VolDn|
* |-----`-----`-----`-----|
* |PrvTk|Play |NxtTk|Mute |
* |-----`-----`-----`-----|
* | 0 | . | + | = |
* `-----`-----`-----`-----'
*/
[_L2] = /* LAYER 2 */
SINGLES_KEYMAP(KC_SYSTEM_SLEEP, KC_MS_BTN1, KC_MS_BTN2, KC_AUDIO_VOL_UP, \
LALT(KC_F4), KC_F11, LGUI(KC_TAB), KC_AUDIO_VOL_DOWN, \
KC_MEDIA_PREV_TRACK, KC_MEDIA_PLAY_PAUSE, KC_MEDIA_NEXT_TRACK, KC_AUDIO_MUTE, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
/* L3 needs cut, copy, paste, undo, again (redo), find, calc, www back, www forward, F5
* ,-----------------------.
* |WBack|WHome|WFor | F5 |
* |-----`-----`-----`-----|
* |Calc |Undo |Redo |WSrch|
* |-----`-----`-----`-----|
* | Cut |Copy |Paste|Find |
* |-----`-----`-----`-----|
* | 0 | . | + | = |
* `-----`-----`-----`-----'
*/
[_L3] = /* LAYER 3 */
SINGLES_KEYMAP(KC_WWW_BACK, KC_WWW_HOME, KC_WWW_FORWARD, KC_F5, \
KC_CALCULATOR, LCTL(KC_Z), LCTL(KC_Y), KC_WWW_SEARCH, \
LCTL(KC_X), LCTL(KC_C), LCTL(KC_V), LCTL(KC_F), \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
};
const uint16_t PROGMEM fn_actions[] = {
};
void persistent_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case _L3:
if (record->event.pressed) {
persistent_default_layer_set(1UL<<_L3);
}
break;
case _L2:
if (record->event.pressed) {
persistent_default_layer_set(1UL<<_L2);
}
break;
case _L1:
if (record->event.pressed) {
persistent_default_layer_set(1UL<<_L1);
}
break;
case _NP:
if (record->event.pressed) {
persistent_default_layer_set(1UL<<_NP);
}
break;
}
return MACRO_NONE;
};
@@ -0,0 +1,3 @@
# The singles keymap for roadkit
This keymap has a base layer with numpad functionality, and then a second layer with some additional keys. The user is encouraged to develop their own keymap using this as a starting point.
+15 -37
View File
@@ -30,15 +30,6 @@
#define LSHIFT OSM(MOD_LSFT) #define LSHIFT OSM(MOD_LSFT)
#define SPACE LT(_AR, KC_SPC) #define SPACE LT(_AR, KC_SPC)
#define MACRO_BREATH_TOGGLE 13
#define MACRO_BREATH_SPEED_INC 14
#define MACRO_BREATH_SPEED_DEC 15
#define MACRO_BREATH_DEFAULT 16
#define M_BRTOG M(MACRO_BREATH_TOGGLE)
#define M_BSPDU M(MACRO_BREATH_SPEED_INC)
#define M_BSPDD M(MACRO_BREATH_SPEED_DEC)
#define M_BDFLT M(MACRO_BREATH_DEFAULT)
static uint16_t key_timer; static uint16_t key_timer;
enum emoticons { enum emoticons {
@@ -76,7 +67,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |----------------------------------------------------------------| * |----------------------------------------------------------------|
* | |MsL|MsD|MsR| |_GA| | | | | | | |Hme | * | |MsL|MsD|MsR| |_GA| | | | | | | |Hme |
* |----------------------------------------------------------------| * |----------------------------------------------------------------|
* | | |BL-|BL+|BL |BR-|BR+|BR | |VoU|VoD|Mut| |MwU|End | * | | | | | | | | | |VoU|VoD|Mut| |MwU|End |
* |----------------------------------------------------------------| * |----------------------------------------------------------------|
* | | | | | | | |MwL|MwD|MwR | * | | | | | | | |MwL|MwD|MwR |
* `----------------------------------------------------------------' * `----------------------------------------------------------------'
@@ -84,13 +75,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_FL] = KEYMAP_ANSI( [_FL] = KEYMAP_ANSI(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, RESET, KC_PSCR, \ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, RESET, KC_PSCR, \
TRNS, KC_BTN1, KC_MS_U, KC_BTN2, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TO(_LO), \ TRNS, KC_BTN1, KC_MS_U, KC_BTN2, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TO(_LO), \
TRNS, KC_MS_L, KC_MS_D, KC_MS_R, TRNS, TG(_GA), TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, KC_HOME, \ TRNS, KC_MS_L, KC_MS_D, KC_MS_R, TRNS, TG(_GA), TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, KC_HOME, \
TRNS, TRNS, BL_DEC, BL_INC, BL_TOGG, M_BSPDD, M_BSPDU, M_BRTOG, TRNS, KC_VOLD, KC_VOLU, KC_MUTE, TRNS, KC_WH_U, KC_END, \ TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, KC_VOLD, KC_VOLU, KC_MUTE, TRNS, KC_WH_U, KC_END, \
TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, KC_WH_L, KC_WH_D, KC_WH_R), TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, KC_WH_L, KC_WH_D, KC_WH_R),
/* Keymap _AR: Arrow layer /* Keymap _AR: Arrow layer
* ,----------------------------------------------------------------. * ,----------------------------------------------------------------.
* | | | | | | | | | | | | | | | | * |~` | F1|F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12| | |
* |----------------------------------------------------------------| * |----------------------------------------------------------------|
* |Lenny| | | | | | | | | | | | | | | * |Lenny| | | | | | | | | | | | | | |
* |----------------------------------------------------------------| * |----------------------------------------------------------------|
@@ -102,7 +93,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `----------------------------------------------------------------' * `----------------------------------------------------------------'
*/ */
[_AR] = KEYMAP_ANSI( [_AR] = KEYMAP_ANSI(
TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, \ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, TRNS, TRNS, \
LENNY, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, \ LENNY, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, \
DWNHRT, TRNS, TRNS, TRNS, TRNS, TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, TRNS, TRNS, TRNS, TRNS, \ DWNHRT, TRNS, TRNS, TRNS, TRNS, TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, TRNS, TRNS, TRNS, TRNS, \
SHRUG, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, \ SHRUG, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, \
@@ -408,29 +399,16 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
} }
} }
break; break;
case MACRO_BREATH_TOGGLE:
if (record->event.pressed) {
breathing_toggle();
}
break;
case MACRO_BREATH_SPEED_INC:
if (record->event.pressed) {
breathing_speed_inc(1);
}
break;
case MACRO_BREATH_SPEED_DEC:
if (record->event.pressed) {
breathing_speed_dec(1);
}
break;
case MACRO_BREATH_DEFAULT:
if (record->event.pressed) {
breathing_defaults();
}
break;
} }
return MACRO_NONE; return MACRO_NONE;
}; };
void led_set_user(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// Turn capslock on
PORTB |= (1<<6);
} else {
// Turn capslock off
PORTB &= ~(1<<6);
}
}
+1
View File
@@ -27,4 +27,5 @@ void led_set_kb(uint8_t usb_led) {
// Turn capslock off // Turn capslock off
PORTB |= (1<<2); PORTB |= (1<<2);
} }
led_set_user(usb_led);
} }
+2 -2
View File
@@ -21,8 +21,8 @@ OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR)\n
ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR)\n ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR)\n
WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR)\n WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR)\n
TAB_LOG = printf "\n$$LOG\n\n" | $(AWK) '{ sub(/^/," | "); print }' TAB_LOG = printf "\n%s\n\n" "$$LOG" | $(AWK) '{ sub(/^/," | "); print }'
TAB_LOG_PLAIN = printf "$$LOG\n" TAB_LOG_PLAIN = printf "%s\n" "$$LOG"
AWK_STATUS = $(AWK) '{ printf " %-10s\n", $$1; }' AWK_STATUS = $(AWK) '{ printf " %-10s\n", $$1; }'
AWK_CMD = $(AWK) '{ printf "%-99s", $$0; }' AWK_CMD = $(AWK) '{ printf "%-99s", $$0; }'
PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) && $(ON_ERROR) PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) && $(ON_ERROR)
+41 -13
View File
@@ -13,6 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
//#include <math.h> //#include <math.h>
@@ -98,7 +99,6 @@ uint16_t note_position = 0;
float (* notes_pointer)[][2]; float (* notes_pointer)[][2];
uint16_t notes_count; uint16_t notes_count;
bool notes_repeat; bool notes_repeat;
float notes_rest;
bool note_resting = false; bool note_resting = false;
uint8_t current_note = 0; uint8_t current_note = 0;
@@ -119,9 +119,17 @@ audio_config_t audio_config;
uint16_t envelope_index = 0; uint16_t envelope_index = 0;
bool glissando = true; bool glissando = true;
#ifndef STARTUP_SONG
#define STARTUP_SONG SONG(STARTUP_SOUND)
#endif
float startup_song[][2] = STARTUP_SONG;
void audio_init() void audio_init()
{ {
if (audio_initialized)
return;
// Check EEPROM // Check EEPROM
if (!eeconfig_is_enabled()) if (!eeconfig_is_enabled())
{ {
@@ -169,6 +177,11 @@ void audio_init()
#endif #endif
audio_initialized = true; audio_initialized = true;
if (audio_config.enable) {
PLAY_SONG(startup_song);
}
} }
void stop_all_notes() void stop_all_notes()
@@ -402,9 +415,12 @@ ISR(TIMER3_COMPA_vect)
note_position++; note_position++;
bool end_of_note = false; bool end_of_note = false;
if (TIMER_3_PERIOD > 0) { if (TIMER_3_PERIOD > 0) {
end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); if (!note_resting)
end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
else
end_of_note = (note_position >= (note_length));
} else { } else {
end_of_note = (note_position >= (note_length * 0x7FF)); end_of_note = (note_position >= (note_length));
} }
if (end_of_note) { if (end_of_note) {
@@ -419,11 +435,16 @@ ISR(TIMER3_COMPA_vect)
return; return;
} }
} }
if (!note_resting && (notes_rest > 0)) { if (!note_resting) {
note_resting = true; note_resting = true;
note_frequency = 0;
note_length = notes_rest;
current_note--; current_note--;
if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
note_frequency = 0;
note_length = 1;
} else {
note_frequency = (*notes_pointer)[current_note][0];
note_length = 1;
}
} else { } else {
note_resting = false; note_resting = false;
envelope_index = 0; envelope_index = 0;
@@ -534,9 +555,12 @@ ISR(TIMER1_COMPA_vect)
note_position++; note_position++;
bool end_of_note = false; bool end_of_note = false;
if (TIMER_1_PERIOD > 0) { if (TIMER_1_PERIOD > 0) {
end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF)); if (!note_resting)
end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
else
end_of_note = (note_position >= (note_length));
} else { } else {
end_of_note = (note_position >= (note_length * 0x7FF)); end_of_note = (note_position >= (note_length));
} }
if (end_of_note) { if (end_of_note) {
@@ -551,11 +575,16 @@ ISR(TIMER1_COMPA_vect)
return; return;
} }
} }
if (!note_resting && (notes_rest > 0)) { if (!note_resting) {
note_resting = true; note_resting = true;
note_frequency = 0;
note_length = notes_rest;
current_note--; current_note--;
if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
note_frequency = 0;
note_length = 1;
} else {
note_frequency = (*notes_pointer)[current_note][0];
note_length = 1;
}
} else { } else {
note_resting = false; note_resting = false;
envelope_index = 0; envelope_index = 0;
@@ -624,7 +653,7 @@ void play_note(float freq, int vol) {
} }
void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
{ {
if (!audio_initialized) { if (!audio_initialized) {
@@ -649,7 +678,6 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
notes_pointer = np; notes_pointer = np;
notes_count = n_count; notes_count = n_count;
notes_repeat = n_repeat; notes_repeat = n_repeat;
notes_rest = n_rest;
place = 0; place = 0;
current_note = 0; current_note = 0;
+5 -3
View File
@@ -86,7 +86,7 @@ void play_sample(uint8_t * s, uint16_t l, bool r);
void play_note(float freq, int vol); void play_note(float freq, int vol);
void stop_note(float freq); void stop_note(float freq);
void stop_all_notes(void); void stop_all_notes(void);
void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat);
#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ #define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
@@ -98,8 +98,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
// length. This works around the limitation of C's sizeof operation on pointers. // length. This works around the limitation of C's sizeof operation on pointers.
// The global float array for the song must be used here. // The global float array for the song must be used here.
#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0]))))
#define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); #define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \
_Pragma ("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"")
#define PLAY_SONG(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), false)
#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true)
bool is_playing_notes(void); bool is_playing_notes(void);
-7
View File
@@ -51,12 +51,6 @@
#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) #define ED_NOTE(n) EIGHTH_DOT_NOTE(n)
#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n)
// Note Styles
// Staccato makes sure there is a rest between each note. Think: TA TA TA
// Legato makes notes flow together. Think: TAAA
#define STACCATO 0.01
#define LEGATO 0
// Note Timbre // Note Timbre
// Changes how the notes sound // Changes how the notes sound
#define TIMBRE_12 0.125 #define TIMBRE_12 0.125
@@ -65,7 +59,6 @@
#define TIMBRE_75 0.750 #define TIMBRE_75 0.750
#define TIMBRE_DEFAULT TIMBRE_50 #define TIMBRE_DEFAULT TIMBRE_50
// Notes - # = Octave // Notes - # = Octave
#define NOTE_REST 0.00 #define NOTE_REST 0.00
+69 -5
View File
@@ -18,9 +18,7 @@
#ifndef SONG_LIST_H #ifndef SONG_LIST_H
#define SONG_LIST_H #define SONG_LIST_H
#define COIN_SOUND \ #define NO_SOUND
E__NOTE(_A5 ),\
HD_NOTE(_E6 ),
#define ODE_TO_JOY \ #define ODE_TO_JOY \
Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \
@@ -55,18 +53,29 @@
E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \ E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \
E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4),
#define STARTUP_SOUND \
E__NOTE(_E6), \
E__NOTE(_A6), \
ED_NOTE(_E7),
#define GOODBYE_SOUND \ #define GOODBYE_SOUND \
E__NOTE(_E7), \ E__NOTE(_E7), \
E__NOTE(_A6), \ E__NOTE(_A6), \
ED_NOTE(_E6), ED_NOTE(_E6),
#define STARTUP_SOUND \ #define PLANCK_SOUND \
ED_NOTE(_E7 ), \ ED_NOTE(_E7 ), \
E__NOTE(_CS7), \ E__NOTE(_CS7), \
E__NOTE(_E6 ), \ E__NOTE(_E6 ), \
E__NOTE(_A6 ), \ E__NOTE(_A6 ), \
M__NOTE(_CS7, 20), M__NOTE(_CS7, 20),
#define PREONIC_SOUND \
M__NOTE(_B5, 20), \
E__NOTE(_B6), \
M__NOTE(_DS6, 20), \
E__NOTE(_B6),
#define QWERTY_SOUND \ #define QWERTY_SOUND \
E__NOTE(_GS6 ), \ E__NOTE(_GS6 ), \
E__NOTE(_A6 ), \ E__NOTE(_A6 ), \
@@ -107,7 +116,8 @@
S__NOTE(_REST), \ S__NOTE(_REST), \
ED_NOTE(_E7 ), ED_NOTE(_E7 ),
#define MUSIC_SCALE_SOUND \
#define MUSIC_ON_SOUND \
E__NOTE(_A5 ), \ E__NOTE(_A5 ), \
E__NOTE(_B5 ), \ E__NOTE(_B5 ), \
E__NOTE(_CS6), \ E__NOTE(_CS6), \
@@ -117,6 +127,50 @@
E__NOTE(_GS6), \ E__NOTE(_GS6), \
E__NOTE(_A6 ), E__NOTE(_A6 ),
#define MUSIC_SCALE_SOUND MUSIC_ON_SOUND
#define MUSIC_OFF_SOUND \
E__NOTE(_A6 ), \
E__NOTE(_GS6 ), \
E__NOTE(_FS6), \
E__NOTE(_E6 ), \
E__NOTE(_D6 ), \
E__NOTE(_CS6), \
E__NOTE(_B5), \
E__NOTE(_A5 ),
#define VOICE_CHANGE_SOUND \
Q__NOTE(_A5 ), \
Q__NOTE(_CS6), \
Q__NOTE(_E6 ), \
Q__NOTE(_A6 ),
#define CHROMATIC_SOUND \
Q__NOTE(_A5 ), \
Q__NOTE(_AS5 ), \
Q__NOTE(_B5), \
Q__NOTE(_C6 ), \
Q__NOTE(_CS6 ),
#define MAJOR_SOUND \
Q__NOTE(_A5 ), \
Q__NOTE(_B5 ), \
Q__NOTE(_CS6), \
Q__NOTE(_D6 ), \
Q__NOTE(_E6 ),
#define GUITAR_SOUND \
Q__NOTE(_E5 ), \
Q__NOTE(_A5), \
Q__NOTE(_D6 ), \
Q__NOTE(_G6 ),
#define VIOLIN_SOUND \
Q__NOTE(_G5 ), \
Q__NOTE(_D6), \
Q__NOTE(_A6 ), \
Q__NOTE(_E7 ),
#define CAPS_LOCK_ON_SOUND \ #define CAPS_LOCK_ON_SOUND \
E__NOTE(_A3), \ E__NOTE(_A3), \
E__NOTE(_B3), E__NOTE(_B3),
@@ -141,6 +195,16 @@
E__NOTE(_E5), \ E__NOTE(_E5), \
E__NOTE(_D5), E__NOTE(_D5),
#define AG_NORM_SOUND \
E__NOTE(_A5), \
E__NOTE(_A5),
#define AG_SWAP_SOUND \
SD_NOTE(_B5), \
SD_NOTE(_A5), \
SD_NOTE(_B5), \
SD_NOTE(_A5),
#define UNICODE_WINDOWS \ #define UNICODE_WINDOWS \
E__NOTE(_B5), \ E__NOTE(_B5), \
S__NOTE(_E6), S__NOTE(_E6),
+2
View File
@@ -100,4 +100,6 @@
#define API_SYSEX_MAX_SIZE 32 #define API_SYSEX_MAX_SIZE 32
#include "song_list.h"
#endif #endif
-1
View File
@@ -169,7 +169,6 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
} }
// translates key to keycode // translates key to keycode
__attribute__ ((weak))
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
{ {
// Read entire word (16bits) // Read entire word (16bits)
+14 -8
View File
@@ -1,10 +1,19 @@
#include "audio.h" #include "audio.h"
#include "process_audio.h" #include "process_audio.h"
#ifndef VOICE_CHANGE_SONG
#define VOICE_CHANGE_SONG SONG(VOICE_CHANGE_SOUND)
#endif
float voice_change_song[][2] = VOICE_CHANGE_SONG;
#ifndef PITCH_STANDARD_A
#define PITCH_STANDARD_A 440.0f
#endif
static float compute_freq_for_midi_note(uint8_t note) static float compute_freq_for_midi_note(uint8_t note)
{ {
// https://en.wikipedia.org/wiki/MIDI_tuning_standard // https://en.wikipedia.org/wiki/MIDI_tuning_standard
return pow(2.0, (note - 69) / 12.0) * 440.0f; return pow(2.0, (note - 69) / 12.0) * PITCH_STANDARD_A;
} }
bool process_audio(uint16_t keycode, keyrecord_t *record) { bool process_audio(uint16_t keycode, keyrecord_t *record) {
@@ -20,12 +29,9 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
} }
if (keycode == AU_TOG && record->event.pressed) { if (keycode == AU_TOG && record->event.pressed) {
if (is_audio_on()) if (is_audio_on()) {
{
audio_off(); audio_off();
} } else {
else
{
audio_on(); audio_on();
} }
return false; return false;
@@ -33,13 +39,13 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
if (keycode == MUV_IN && record->event.pressed) { if (keycode == MUV_IN && record->event.pressed) {
voice_iterate(); voice_iterate();
music_scale_user(); PLAY_SONG(voice_change_song);
return false; return false;
} }
if (keycode == MUV_DE && record->event.pressed) { if (keycode == MUV_DE && record->event.pressed) {
voice_deiterate(); voice_deiterate();
music_scale_user(); PLAY_SONG(voice_change_song);
return false; return false;
} }
+104 -55
View File
@@ -27,6 +27,7 @@
bool music_activated = false; bool music_activated = false;
uint8_t music_starting_note = 0x0C; uint8_t music_starting_note = 0x0C;
int music_offset = 7; int music_offset = 7;
uint8_t music_mode = MUSIC_MODE_CHROMATIC;
// music sequencer // music sequencer
static bool music_sequence_recording = false; static bool music_sequence_recording = false;
@@ -39,6 +40,39 @@ static uint8_t music_sequence_position = 0;
static uint16_t music_sequence_timer = 0; static uint16_t music_sequence_timer = 0;
static uint16_t music_sequence_interval = 100; static uint16_t music_sequence_interval = 100;
#ifdef AUDIO_ENABLE
#ifndef MUSIC_ON_SONG
#define MUSIC_ON_SONG SONG(MUSIC_ON_SOUND)
#endif
#ifndef MUSIC_OFF_SONG
#define MUSIC_OFF_SONG SONG(MUSIC_OFF_SOUND)
#endif
#ifndef CHROMATIC_SONG
#define CHROMATIC_SONG SONG(CHROMATIC_SOUND)
#endif
#ifndef GUITAR_SONG
#define GUITAR_SONG SONG(GUITAR_SOUND)
#endif
#ifndef VIOLIN_SONG
#define VIOLIN_SONG SONG(VIOLIN_SOUND)
#endif
#ifndef MAJOR_SONG
#define MAJOR_SONG SONG(MAJOR_SOUND)
#endif
float music_mode_songs[NUMBER_OF_MODES][5][2] = {
CHROMATIC_SONG,
GUITAR_SONG,
VIOLIN_SONG,
MAJOR_SONG
};
float music_on_song[][2] = MUSIC_ON_SONG;
float music_off_song[][2] = MUSIC_OFF_SONG;
#endif
#ifndef MUSIC_MASK
#define MUSIC_MASK keycode < 0xFF
#endif
static void music_noteon(uint8_t note) { static void music_noteon(uint8_t note) {
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
process_audio_noteon(note); process_audio_noteon(note);
@@ -79,70 +113,71 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
} }
if (keycode == MU_TOG && record->event.pressed) { if (keycode == MU_TOG && record->event.pressed) {
if (music_activated) if (music_activated) {
{
music_off(); music_off();
} } else {
else
{
music_on(); music_on();
} }
return false; return false;
} }
if (keycode == MU_MOD && record->event.pressed) {
music_mode_cycle();
return false;
}
if (music_activated) { if (music_activated) {
if (record->event.pressed) {
if (keycode == KC_LCTL) { // Start recording
music_all_notes_off();
music_sequence_recording = true;
music_sequence_recorded = false;
music_sequence_playing = false;
music_sequence_count = 0;
return false;
}
if (keycode == KC_LCTL && record->event.pressed) { // Start recording if (keycode == KC_LALT) { // Stop recording/playing
music_all_notes_off(); music_all_notes_off();
music_sequence_recording = true; if (music_sequence_recording) { // was recording
music_sequence_recorded = false; music_sequence_recorded = true;
music_sequence_playing = false; }
music_sequence_count = 0; music_sequence_recording = false;
return false; music_sequence_playing = false;
} return false;
}
if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
music_all_notes_off(); if (keycode == KC_LGUI && music_sequence_recorded) { // Start playing
if (music_sequence_recording) { // was recording music_all_notes_off();
music_sequence_recorded = true; music_sequence_recording = false;
music_sequence_playing = true;
music_sequence_position = 0;
music_sequence_timer = 0;
return false;
}
if (keycode == KC_UP) {
music_sequence_interval-=10;
return false;
}
if (keycode == KC_DOWN) {
music_sequence_interval+=10;
return false;
} }
music_sequence_recording = false;
music_sequence_playing = false;
return false;
} }
if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing uint8_t note;
music_all_notes_off(); if (music_mode == MUSIC_MODE_CHROMATIC)
music_sequence_recording = false; note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
music_sequence_playing = true; else if (music_mode == MUSIC_MODE_GUITAR)
music_sequence_position = 0; note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
music_sequence_timer = 0; else if (music_mode == MUSIC_MODE_VIOLIN)
return false; note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
} else if (music_mode == MUSIC_MODE_MAJOR)
note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
if (keycode == KC_UP) { else
if (record->event.pressed) note = music_starting_note;
music_sequence_interval-=10;
return false;
}
if (keycode == KC_DOWN) {
if (record->event.pressed)
music_sequence_interval+=10;
return false;
}
#define MUSIC_MODE_GUITAR
#ifdef MUSIC_MODE_CHROMATIC
uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
#elif defined(MUSIC_MODE_GUITAR)
uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
#elif defined(MUSIC_MODE_VIOLIN)
uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
#else
uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
#endif
if (record->event.pressed) { if (record->event.pressed) {
music_noteon(note); music_noteon(note);
@@ -154,7 +189,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
music_noteoff(note); music_noteoff(note);
} }
if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through if (MUSIC_MASK)
return false; return false;
} }
@@ -175,12 +210,26 @@ void music_toggle(void) {
void music_on(void) { void music_on(void) {
music_activated = 1; music_activated = 1;
#ifdef AUDIO_ENABLE
PLAY_SONG(music_on_song);
#endif
music_on_user(); music_on_user();
} }
void music_off(void) { void music_off(void) {
music_activated = 0;
music_all_notes_off(); music_all_notes_off();
music_activated = 0;
#ifdef AUDIO_ENABLE
PLAY_SONG(music_off_song);
#endif
}
void music_mode_cycle(void) {
music_all_notes_off();
music_mode = (music_mode + 1) % NUMBER_OF_MODES;
#ifdef AUDIO_ENABLE
PLAY_SONG(music_mode_songs[music_mode]);
#endif
} }
void matrix_scan_music(void) { void matrix_scan_music(void) {
+9
View File
@@ -21,6 +21,14 @@
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
enum music_modes {
MUSIC_MODE_CHROMATIC,
MUSIC_MODE_GUITAR,
MUSIC_MODE_VIOLIN,
MUSIC_MODE_MAJOR,
NUMBER_OF_MODES
};
bool process_music(uint16_t keycode, keyrecord_t *record); bool process_music(uint16_t keycode, keyrecord_t *record);
bool is_music_on(void); bool is_music_on(void);
@@ -31,6 +39,7 @@ void music_off(void);
void music_on_user(void); void music_on_user(void);
void music_scale_user(void); void music_scale_user(void);
void music_all_notes_off(void); void music_all_notes_off(void);
void music_mode_cycle(void);
void matrix_scan_music(void); void matrix_scan_music(void);
+43 -1
View File
@@ -30,6 +30,25 @@ extern backlight_config_t backlight_config;
#include "fauxclicky.h" #include "fauxclicky.h"
#endif #endif
#ifdef AUDIO_ENABLE
#ifndef GOODBYE_SONG
#define GOODBYE_SONG SONG(GOODBYE_SOUND)
#endif
#ifndef AG_NORM_SONG
#define AG_NORM_SONG SONG(AG_NORM_SOUND)
#endif
#ifndef AG_SWAP_SONG
#define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
#endif
#ifndef DEFAULT_LAYER_SONGS
#define DEFAULT_LAYER_SONGS { }
#endif
float goodbye_song[][2] = GOODBYE_SONG;
float ag_norm_song[][2] = AG_NORM_SONG;
float ag_swap_song[][2] = AG_SWAP_SONG;
float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
#endif
static void do_code16 (uint16_t code, void (*f) (uint8_t)) { static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
switch (code) { switch (code) {
case QK_MODS ... QK_MODS_MAX: case QK_MODS ... QK_MODS_MAX:
@@ -116,9 +135,15 @@ void reset_keyboard(void) {
clear_keyboard(); clear_keyboard();
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC)) #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
music_all_notes_off(); music_all_notes_off();
uint16_t timer_start = timer_read();
PLAY_SONG(goodbye_song);
shutdown_user(); shutdown_user();
#endif while(timer_elapsed(timer_start) < 250)
wait_ms(1);
stop_all_notes();
#else
wait_ms(250); wait_ms(250);
#endif
#ifdef CATERINA_BOOTLOADER #ifdef CATERINA_BOOTLOADER
*(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
#endif #endif
@@ -351,6 +376,9 @@ bool process_record_quantum(keyrecord_t *record) {
case MAGIC_SWAP_ALT_GUI: case MAGIC_SWAP_ALT_GUI:
keymap_config.swap_lalt_lgui = true; keymap_config.swap_lalt_lgui = true;
keymap_config.swap_ralt_rgui = true; keymap_config.swap_ralt_rgui = true;
#ifdef AUDIO_ENABLE
PLAY_SONG(ag_swap_song);
#endif
break; break;
case MAGIC_UNSWAP_CONTROL_CAPSLOCK: case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
keymap_config.swap_control_capslock = false; keymap_config.swap_control_capslock = false;
@@ -379,6 +407,9 @@ bool process_record_quantum(keyrecord_t *record) {
case MAGIC_UNSWAP_ALT_GUI: case MAGIC_UNSWAP_ALT_GUI:
keymap_config.swap_lalt_lgui = false; keymap_config.swap_lalt_lgui = false;
keymap_config.swap_ralt_rgui = false; keymap_config.swap_ralt_rgui = false;
#ifdef AUDIO_ENABLE
PLAY_SONG(ag_norm_song);
#endif
break; break;
case MAGIC_TOGGLE_NKRO: case MAGIC_TOGGLE_NKRO:
keymap_config.nkro = !keymap_config.nkro; keymap_config.nkro = !keymap_config.nkro;
@@ -521,6 +552,14 @@ void send_string_with_delay(const char *str, uint8_t interval) {
} }
} }
void set_single_persistent_default_layer(uint8_t default_layer) {
#ifdef AUDIO_ENABLE
PLAY_SONG(default_layer_songs[default_layer]);
#endif
eeconfig_update_default_layer(1U<<default_layer);
default_layer_set(1U<<default_layer);
}
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
layer_on(layer3); layer_on(layer3);
@@ -571,6 +610,9 @@ void matrix_init_quantum() {
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
backlight_init_ports(); backlight_init_ports();
#endif #endif
#ifdef AUDIO_ENABLE
audio_init();
#endif
matrix_init_kb(); matrix_init_kb();
} }
+3
View File
@@ -56,6 +56,7 @@ extern uint32_t default_layer_state;
#endif // MIDI_ENABLE #endif // MIDI_ENABLE
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
#include "audio.h"
#include "process_audio.h" #include "process_audio.h"
#endif #endif
@@ -103,6 +104,8 @@ void send_string_with_delay(const char *str, uint8_t interval);
// For tri-layer // For tri-layer
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
void set_single_persistent_default_layer(uint8_t default_layer);
void tap_random_base64(void); void tap_random_base64(void);
#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) #define IS_LAYER_ON(layer) (layer_state & (1UL << (layer)))
+7
View File
@@ -26,6 +26,10 @@
#endif #endif
#endif #endif
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
enum quantum_keycodes { enum quantum_keycodes {
// Ranges used in shortucuts - not to be used directly // Ranges used in shortucuts - not to be used directly
QK_TMK = 0x0000, QK_TMK = 0x0000,
@@ -128,6 +132,9 @@ enum quantum_keycodes {
MU_OFF, MU_OFF,
MU_TOG, MU_TOG,
// Music mode cycle
MU_MOD,
// Music voice iterate // Music voice iterate
MUV_IN, MUV_IN,
MUV_DE, MUV_DE,
+4 -1
View File
@@ -40,4 +40,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
} }
} }
return MACRO_NONE; return MACRO_NONE;
}; };
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
}
+3
View File
@@ -58,3 +58,6 @@ void release_key(uint8_t col, uint8_t row) {
void clear_all_keys(void) { void clear_all_keys(void) {
memset(matrix, 0, sizeof(matrix)); memset(matrix, 0, sizeof(matrix));
} }
void led_set(uint8_t usb_led) {
}
+2 -2
View File
@@ -44,8 +44,8 @@ void TestFixture::run_one_scan_loop() {
advance_time(1); advance_time(1);
} }
void TestFixture::idle_for(uint time) { void TestFixture::idle_for(unsigned time) {
for (uint i=0; i<time; i++) { for (unsigned i=0; i<time; i++) {
run_one_scan_loop(); run_one_scan_loop();
} }
} }
+1 -1
View File
@@ -26,5 +26,5 @@ public:
static void TearDownTestCase(); static void TearDownTestCase();
void run_one_scan_loop(); void run_one_scan_loop();
void idle_for(uint ms); void idle_for(unsigned ms);
}; };
+5
View File
@@ -1,3 +1,5 @@
SYSTEM_TYPE := $(shell gcc -dumpmachine)
CC = gcc CC = gcc
OBJCOPY = OBJCOPY =
OBJDUMP = OBJDUMP =
@@ -14,6 +16,9 @@ COMPILEFLAGS += -funsigned-bitfields
COMPILEFLAGS += -ffunction-sections COMPILEFLAGS += -ffunction-sections
COMPILEFLAGS += -fdata-sections COMPILEFLAGS += -fdata-sections
COMPILEFLAGS += -fshort-enums COMPILEFLAGS += -fshort-enums
ifneq ($(findstring mingw, ${SYSTEM_TYPE}),)
COMPILEFLAGS += -mno-ms-bitfields
endif
CFLAGS += $(COMPILEFLAGS) CFLAGS += $(COMPILEFLAGS)
CFLAGS += -fno-inline-small-functions CFLAGS += -fno-inline-small-functions
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
function export_variables {
local util_dir=~/qmk_utils
export PATH=$PATH:$util_dir/dfu-programmer
export PATH=$PATH:$util_dir/dfu-util-0.9-win64
export PATH=$PATH:$util_dir/flip/bin
export PATH=$PATH:$util_dir/avr8-gnu-toolchain/bin
export PATH=$PATH:$util_dir/gcc-arm-none-eabi/bin
}
export_variables
+117
View File
@@ -0,0 +1,117 @@
#!/bin/bash
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
download_dir=~/qmk_utils
avrtools=avr8-gnu-toolchain
armtools=gcc-arm-none-eabi
installflip=false
echo "Installing dependencies needed for the installation (quazip)"
pacman --needed -S msys/unzip msys/p7zip base-devel msys/git mingw-w64-x86_64-toolchain
source "$dir/win_shared_install.sh"
function install_avr {
rm -f -r "$avrtools"
wget "http://www.atmel.com/images/avr8-gnu-toolchain-installer-3.5.4.91-win32.any.x86.exe"
7z x avr8-gnu-toolchain-installer-3.5.4.91-win32.any.x86.exe
rm avr8-gnu-toolchain-installer-3.5.4.91-win32.any.x86.exe
}
function install_arm {
wget -O gcc-arm-none-eabi.zip "https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-win32.zip?product=GNU%20ARM%20Embedded%20Toolchain,ZIP,,Windows,6-2017-q2-update"
unzip -d gcc-arm-none-eabi gcc-arm-none-eabi.zip
rm gcc-arm-none-eabi.zip
}
function extract_flip {
rm -f -r flip
7z -oflip x FlipInstaller.exe
}
pushd "$download_dir"
if [ -f "FlipInstaller.exe" ]; then
echo
echo "Extracting flip"
extract_flip
fi
if [ ! -d "$avrtools" ]; then
while true; do
echo
echo "The AVR toolchain is not installed."
echo "This is needed for building AVR based keboards."
read -p "Do you want to install it? (Y/N) " res
case $res in
[Yy]* ) install_avr; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
else
while true; do
echo
echo "The AVR toolchain is already installed"
read -p "Do you want to reinstall? (Y/N) " res
case $res in
[Yy]* ) install_avr; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
fi
if [ ! -d "$armtools" ]; then
while true; do
echo
echo "The ARM toolchain is not installed."
echo "This is needed for building ARM based keboards."
read -p "Do you want to install it? (Y/N) " res
case $res in
[Yy]* ) install_arm; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
else
while true; do
echo
echo "The ARM toolchain is already installed"
read -p "Do you want to reinstall? (Y/N) " res
case $res in
[Yy]* ) install_arm; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
fi
popd
cp -f "$dir/activate_msys2.sh" "$download_dir/"
if grep "^source ~/qmk_utils/activate_msys2.sh$" ~/.bashrc
then
echo
echo "The line source ~/qmk_utils/activate_msys2.sh is already added to your /.bashrc"
echo "Not adding it twice!"
else
while true; do
echo
echo "Do you want to add 'source ~/qmk_utils/activate_msys2.sh' to the end of your"
echo ".bashrc file? Without this make won't find the needed utils, so if you don't"
echo "want to do it automatically, then you have to do it manually later."
read -p "(Y/N)? " res
case $res in
[Yy]* ) echo "source ~/qmk_utils/activate_msys2.sh" >> ~/.bashrc; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
fi
echo
echo "******************************************************************************"
echo "Installation completed!"
echo "Please close this Window and restart MSYS2 MinGW"
echo "******************************************************************************"
+80
View File
@@ -0,0 +1,80 @@
#!/bin/bash
function install_utils {
rm -f -r "$download_dir"
mkdir "$download_dir"
pushd "$download_dir"
echo "Installing dfu-programmer"
wget 'http://downloads.sourceforge.net/project/dfu-programmer/dfu-programmer/0.7.2/dfu-programmer-win-0.7.2.zip'
unzip -d dfu-programmer dfu-programmer-win-0.7.2.zip
echo "Installing dfu-util"
wget 'http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip'
unzip dfu-util-0.9-win64.zip
echo "Installing teensy_loader_cli"
wget 'https://www.pjrc.com/teensy/teensy_loader_cli_windows.zip'
unzip teensy_loader_cli_windows.zip
echo "Installing Atmel Flip"
wget 'http://www.atmel.com/images/Flip%20Installer%20-%203.4.7.112.exe'
mv Flip\ Installer\ \-\ 3.4.7.112.exe FlipInstaller.exe
echo "Downloading the QMK driver installer"
wget -qO- https://api.github.com/repos/qmk/qmk_driver_installer/releases | grep browser_download_url | head -n 1 | cut -d '"' -f 4 | wget -i -
rm -f *.zip
popd > /dev/null
}
function install_drivers {
pushd "$download_dir"
cp -f "$dir/drivers.txt" .
echo
cmd.exe /c "qmk_driver_installer.exe $1 $2 drivers.txt"
popd > /dev/null
}
pushd "$dir"
if [ ! -d "$download_dir" ]; then
install_utils
else
while true; do
echo
echo "The utils seem to already be downloaded."
read -p "Do you want to re-download them and update to the newest version (Y/N) " res
case $res in
[Yy]* ) install_utils; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
fi
while true; do
echo
echo "Which USB drivers do you want to install?"
echo "(A)all - All supported drivers will be installed"
echo "(C)onnected - Only drivers for connected keyboards (in bootloader/flashing mode)"
echo " will be installed"
echo "(F)force - Like all, but will also override existing drivers for connected"
echo " keyboards"
echo "(N)one - No drivers will be installed,"
echo " flashing your keyboard will most likely not work"
read -p "(A/C/F/N)? " res
case $res in
[Aa]* ) install_drivers --all; break;;
[Cc]* ) install_drivers; break;;
[Ff]* ) install_drivers --all --force; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
popd > /dev/null
+16 -78
View File
@@ -1,44 +1,7 @@
#!/bin/bash #!/bin/bash
download_dir=wsl_downloaded
function install_utils {
rm -f -r $download_dir
mkdir $download_dir
pushd $download_dir
echo "Installing dfu-programmer"
wget 'http://downloads.sourceforge.net/project/dfu-programmer/dfu-programmer/0.7.2/dfu-programmer-win-0.7.2.zip'
unzip -d dfu-programmer dfu-programmer-win-0.7.2.zip
echo "Installing dfu-util"
wget 'http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip'
unzip dfu-util-0.9-win64.zip
echo "Installing teensy_loader_cli"
wget 'https://www.pjrc.com/teensy/teensy_loader_cli_windows.zip'
unzip teensy_loader_cli_windows.zip
echo "Installing Atmel Flip"
wget 'http://www.atmel.com/images/Flip%20Installer%20-%203.4.7.112.exe'
mv Flip\ Installer\ \-\ 3.4.7.112.exe FlipInstaller.exe
echo "Downloading the QMK driver installer"
wget -qO- https://api.github.com/repos/qmk/qmk_driver_installer/releases | grep browser_download_url | head -n 1 | cut -d '"' -f 4 | wget -i -
rm -f *.zip
popd > /dev/null
}
function install_drivers {
pushd $download_dir
cmd.exe /C qmk_driver_installer.exe $1 $2 ../drivers.txt
popd > /dev/null
}
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
pushd "$dir";
if [[ $dir != /mnt/* ]]; if [[ $dir != /mnt/* ]];
then then
@@ -48,7 +11,6 @@ then
exit 1 exit 1
fi fi
pushd "$dir"
while true; do while true; do
echo echo
@@ -67,49 +29,25 @@ echo "Installing dependencies needed for the installation (unzip, wget)"
echo "This will ask for the sudo password" echo "This will ask for the sudo password"
sudo apt-get install unzip wget sudo apt-get install unzip wget
download_dir=wsl_downloaded
if [ ! -d "$download_dir" ]; then source "$dir/win_shared_install.sh"
install_utils
else
while true; do
echo
read -p "The utils seem to already be downloaded, do you want to re-download them and update to the newest version (Y/N) " res
case $res in
[Yy]* ) install_utils; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
fi
pushd "$download_dir"
while true; do while true; do
echo echo
read -p "Flip need to be installed if you want to use that for programming, do you want to install it now? (Y/N) " res echo "Flip need to be installed if you want to use that for programming."
echo "Please install it to the default location!"
read -p "Do you want to install it now? (Y/N) " res
case $res in case $res in
[Yy]* ) cmd.exe /c $download_dir\\FlipInstaller.exe; break;; [Yy]* ) cmd.exe /c FlipInstaller.exe; break;;
[Nn]* ) break;; [Nn]* ) break;;
* ) echo "Invalid answer";; * ) echo "Invalid answer";;
esac esac
done done
popd
while true; do
echo
echo "Which USB drivers do you want to install?"
echo "(A)all - All supported drivers will be installed"
echo "(C)onnected - Only drivers for connected keyboards (in bootloader/flashing mode) will be installed"
echo "(F)force - Like all, but will also override existing drivers for connected keyboards"
echo "(N)one - No drivers will be installed, flashing your keyboard will most likely not work"
read -p "(A/C/F/N)? " res
case $res in
[Aa]* ) install_drivers --all; break;;
[Cc]* ) install_drivers; break;;
[Ff]* ) install_drivers --all --force; break;;
[Nn]* ) break;;
* ) echo "Invalid answer";;
esac
done
echo echo
echo "Creating a softlink to the utils directory as ~/qmk_utils." echo "Creating a softlink to the utils directory as ~/qmk_utils."
echo "This is needed so that the the make system can find all utils it need." echo "This is needed so that the the make system can find all utils it need."
@@ -124,9 +62,9 @@ then
else else
while true; do while true; do
echo echo
echo "Do you want to add 'source ~/qmk_utils/activate_wsl.sh' to the end of you .bashrc file?" echo "Do you want to add 'source ~/qmk_utils/activate_wsl.sh' to the end of your"
echo "Without this make won't find the needed utils, so if you don't want to do it automatically," echo ".bashrc file? Without this make won't find the needed utils, so if you don't"
echo "then you have to do it manually." echo "want to do it automatically, then you have to do it manually later."
read -p "(Y/N)? " res read -p "(Y/N)? " res
case $res in case $res in
[Yy]* ) echo "source ~/qmk_utils/activate_wsl.sh" >> ~/.bashrc; break;; [Yy]* ) echo "source ~/qmk_utils/activate_wsl.sh" >> ~/.bashrc; break;;
@@ -138,9 +76,10 @@ fi
while true; do while true; do
echo echo
echo "Do you want to add a symlink to the QMK repository in your home directory for convenience?" echo "Do you want to add a symlink to the QMK repository in your home directory for"
echo "This will create a folder 'qmk_firmware' in your home directory." echo "convenience? This will create a folder 'qmk_firmware' in your home directory."
echo "In the future you can use this folder instead of the full path on your windows file system" echo "In the future you can use this folder instead of the full path on your Windows"
echo "file system."
read -p "(Y/N)? " res read -p "(Y/N)? " res
case $res in case $res in
[Yy]* ) ln -sfn "$dir/.." ~/qmk_firmware; break;; [Yy]* ) ln -sfn "$dir/.." ~/qmk_firmware; break;;
@@ -156,4 +95,3 @@ echo "You need to open a new batch command prompt for all the utils to work prop
echo "******************************************************************************" echo "******************************************************************************"
popd > /dev/null popd > /dev/null