Merge branch 'master' into flicker-fix
commit
78192791bc
@ -0,0 +1,323 @@
|
||||
# Quantum Hand-wiring Guide
|
||||
|
||||
Parts list:
|
||||
* *x* keyswitches (MX, Matias, Gateron, etc)
|
||||
* *x* diodes
|
||||
* Keyboard plate (metal, plastic, cardboard, etc)
|
||||
* Wire (strained for wiring to the Teensy, anything for the rows/columns)
|
||||
* Soldering iron set at 600ºF or 315ºC (if temperature-controlled)
|
||||
* Resin-cored solder (leaded or lead-free)
|
||||
* Adequate ventilation/a fan
|
||||
* Tweezers (optional)
|
||||
* Wire cutters/snippers
|
||||
|
||||
## How the matrix works (why we need diodes)
|
||||
|
||||
The microcontroller (in this case, the Teensy 2.0) will be setup up via the firmware to send a logical 1 to the columns, one at a time, and read from the rows, all at once - this process is called matrix scanning. The matrix is a bunch of open switches that, by default, don't allow any current to pass through - the firmware will read this as no keys being pressed. As soon as you press one key down, the logical 1 that was coming from the column the keyswitch is attached to gets passed through the switch and to the corresponding row - check out the following 2x2 example:
|
||||
|
||||
Column 0 being scanned Column 1 being scanned
|
||||
x x
|
||||
col0 col1 col0 col1
|
||||
| | | |
|
||||
row0 ---(key0)---(key1) row0 ---(key0)---(key1)
|
||||
| | | |
|
||||
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
||||
|
||||
The `x` represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an `x`. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column.
|
||||
|
||||
When we press `key0`, `col0` gets connected to `row0`, so the values that the firmware receives for that row is `0b01` (the `0b` here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected:
|
||||
|
||||
Column 0 being scanned Column 1 being scanned
|
||||
x x
|
||||
col0 col1 col0 col1
|
||||
| | | |
|
||||
x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1)
|
||||
| | | |
|
||||
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
||||
|
||||
We can now see that `row0` has an `x`, so has the value of 1. As a whole, the data the firmware receives when `key0` is pressed is
|
||||
|
||||
col0: 0b01
|
||||
col1: 0b00
|
||||
│└row0
|
||||
└row1
|
||||
|
||||
A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious:
|
||||
|
||||
Column 0 being scanned Column 1 being scanned
|
||||
x x
|
||||
col0 col1 col0 col1
|
||||
| | | |
|
||||
x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1)
|
||||
| | | |
|
||||
x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3)
|
||||
|
||||
Remember that this ^ is still connected to row1
|
||||
|
||||
The data we get from that is:
|
||||
|
||||
col0: 0b11
|
||||
col1: 0b11
|
||||
│└row0
|
||||
└row1
|
||||
|
||||
Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this;
|
||||
|
||||
Column 0 being scanned Column 1 being scanned
|
||||
x x
|
||||
col0 col1 col0 col1
|
||||
│ │ | │
|
||||
(key0) (key1) (key0) (key1)
|
||||
! │ ! │ ! | ! │
|
||||
row0 ─────┴────────┘ │ row0 ─────┴────────┘ │
|
||||
│ │ | │
|
||||
(key2) (key3) (key2) (key3)
|
||||
! ! ! !
|
||||
row1 ─────┴────────┘ row1 ─────┴────────┘
|
||||
|
||||
In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|`
|
||||
|
||||
Now when we press the three keys, invoking what would be a ghosting scenario:
|
||||
|
||||
Column 0 being scanned Column 1 being scanned
|
||||
x x
|
||||
col0 col1 col0 col1
|
||||
│ │ │ │
|
||||
(┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1)
|
||||
! │ ! │ ! │ ! │
|
||||
x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │
|
||||
│ │ │ │
|
||||
(key2) (┌─┘3) (key2) (┌─┘3)
|
||||
! ! ! !
|
||||
row1 ─────┴────────┘ x row1 ─────┴────────┘
|
||||
|
||||
Things act as they should! Which will get us the following data:
|
||||
|
||||
col0: 0b01
|
||||
col1: 0b11
|
||||
│└row0
|
||||
└row1
|
||||
|
||||
The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS.
|
||||
|
||||
## The actual hand-wiring
|
||||
|
||||
### Getting things in place
|
||||
|
||||
When starting this, you should have all of your stabilisers and keyswitches already installed (and optionally keycaps). If you're using a Cherry-type stabiliser (plate-mounted only, obviously), you'll need to install that before your keyswitches. If you're using Costar ones, you can installed them afterwards.
|
||||
|
||||
To make things easier on yourself, make sure all of the keyswitches are oriented the same way (if they can be - not all layouts support this). Despite this, it's important to remember that the contacts on the keyswitches are completely symmetrical. We'll be using the keyswitch's left side contact for wiring the rows, and the right side one for wiring the columns.
|
||||
|
||||
Get your soldering iron heated-up and collect the rest of the materials from the part list at the beginning of the guide. Place your keyboard so that the bottoms of the keyswitches are accessible - it may be a good idea to place it on a cloth to protect your keyswitches/keycaps.
|
||||
|
||||
Before continuing, plan out where you're going to place your Teensy. If you're working with a board that has a large (6.25u) spacebar, it may be a good idea to place it in-between switches against the plate. Otherwise, you may want to trim some of the leads on the keyswitches where you plan on putting it - this will make it a little harder to solder the wire/diodes, but give you more room to place the Teensy.
|
||||
|
||||
### Preparing the diodes
|
||||
|
||||
It's a little easier to solder the diodes in place if you bend them at a 90º angle immediately after the black line - this will help to make sure you put them on the right way (direction matters), and in the correct position. The diodes will look like this when bent (with longer leads):
|
||||
|
||||
┌─────┬─┐
|
||||
───┤ │ ├─┐
|
||||
└─────┴─┘ │
|
||||
│
|
||||
|
||||
We'll be using the long lead at the bent end to connect it to the elbow (bent part) of the next diode, creating the row.
|
||||
|
||||
### Soldering the diodes
|
||||
|
||||
Starting at the top-left switch, place the diode (with tweezers if you have them) on the switch so that the diode itself is vertically aligned, and the black line is facing toward you. The straight end of the diode should be touching the left contact on the switch, and the bent end should be facing to the right and resting on the switch there, like this:
|
||||
|
||||
│o
|
||||
┌┴┐ o
|
||||
│ │ O
|
||||
├─┤
|
||||
└┬┘
|
||||
└─────────────
|
||||
|
||||
Letting the diode rest, grab your solder, and touch both it and the soldering iron to the left contact at the same time - the rosin in the solder should make it easy for the solder to flow over both the diode and the keyswitch contact. The diode may move a little, and if it does, carefully position it back it place by grabbing the bent end of the diode - the other end will become hot very quickly. If you find that it's moving too much, using needle-nose pliers of some sort may help to keep the diode still when soldering.
|
||||
|
||||
The smoke that the rosin releases is harmful, so be careful not to breath it or get it in your eyes/face.
|
||||
|
||||
After soldering things in place, it may be helpful to blow on the joint to push the smoke away from your face, and cool the solder quicker. You should see the solder develop a matte (not shiney) surface as it solidifies. Keep in mind that it will still be very hot afterwards, and will take a couple minutes to be cool to touch. Blow on it will accelerate this process.
|
||||
|
||||
When the first diode is complete, the next one will need to be soldered to both the keyswitch, and the previous diode at the new elbow. That will look something like this:
|
||||
|
||||
│o │o
|
||||
┌┴┐ o ┌┴┐ o
|
||||
│ │ O │ │ O
|
||||
├─┤ ├─┤
|
||||
└┬┘ └┬┘
|
||||
└────────────────┴─────────────
|
||||
|
||||
After completing a row, use the wire cutters to trim the excess wire from the tops of the diodes, and from the right side on the final switch. This process will need to completed for each row you have.
|
||||
|
||||
When all of the diodes are completely soldered, it's a good idea to quickly inspect each one to ensure that your solder joints are solid and sturdy - repairing things after this is possible, but more difficult.
|
||||
|
||||
### Soldering the columns
|
||||
|
||||
You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch.
|
||||
|
||||
If you're using stranded wire, it's probably easiest to just use a lot of small wires to connect each keyswitch along the column. It's possible to use one and melt through the insulation, but this isn't recommended, will produce even more harmful fumes, and can ruin your soldering iron.
|
||||
|
||||
Before beginning to solder, it helps to have your wire pre-bent (if using single-cored), or at least have an idea of how you're going to route the column (especially if you're making a staggered board). Where you go in particular doesn't matter too much, as we'll be basing our keymap definitions on how it was wired - just make sure every key in a particular row is in a unique column, and that they're in order from left to right.
|
||||
|
||||
If you're not using any insulation, you can try to keep the column wires elevated, and solder them near the tips of the keyswitch contacts - if the wires are sturdy enough, they won't short out to the row wiring an diodes.
|
||||
|
||||
### Wiring things to the Teensy
|
||||
|
||||
Now that the matrix itself is complete, it's time to connect what you've done to the Teensy. You'll be needing the number of pins equal to your number of columns + your number of rows. There are some pins on the Teensy that are special, like D6 (the LED on the chip), or some of the UART, SPI, I2C, or PWM channels, but only avoid those if you're planning something in addition to a keyboard. If you're unsure about wanting to add something later, you should have enough pins in total to avoid a couple.
|
||||
|
||||
The pins you'll absolutely have to avoid are: GND, VCC, AREF, and RST - all the others are usable and accessible in the firmware.
|
||||
|
||||
Place the Teensy where you plan to put it - you'll have to cut wires to length in the next step, and you'll want to make sure they reach.
|
||||
|
||||
Starting with the first column on the right side, measure out how much wire you'll need to connect it to the first pin on the Teensy - it helps to pick a side that you'll be able to work down, to keep the wires from overlapping too much. It may help to leave a little bit of slack so things aren't too tight. Cut the piece of wire, and solder it to the Teensy, and then the column - you can solder it anywhere along the column, but it may be easiest at the keyswitch. Just be sure the wire doesn't separate from the keyswitch when soldering.
|
||||
|
||||
As you move from column to column, it'll be helpful to write the locations of the pins down. We'll use this data to setup the matrix in the future.
|
||||
|
||||
When you're done with the columns, start with the rows in the same process, from top to bottom, and write them all down. Again, you can solder anywhere along the row, as long as it's after the diode - soldering before the diode (on the keyswitch side) will cause that row not to work.
|
||||
|
||||
As you move along, be sure that the Teensy is staying in place - recutting and soldering the wires is a pain!
|
||||
|
||||
### Getting some basic firmware set-up
|
||||
|
||||
From here, you should have a working keyboard with the correct firmware. Before we attach the Teensy permanently to the keyboard, let's quickly get some firmware loaded onto the Teensy so we can test each keyswitch.
|
||||
|
||||
To start out, download [the firmware](https://github.com/jackhumbert/qmk_firmware/) - we'll be using my (Jack's) fork of TMK called QMK/Quantum. We'll be doing a lot from the Terminal/command prompt, so get that open, along with a decent text editor like [Sublime Text](http://www.sublimetext.com/).
|
||||
|
||||
The first thing we're going to do is create a new project using the script in the root directory of the firmware. In your terminal, run this command with `<project_name>` replaced by the name of your project - it'll need to be different from any other project in the `keyboard/` folder:
|
||||
|
||||
./new_project.sh <project_name>
|
||||
|
||||
You'll want to navigate to the `keyboard/<project_name>/` folder by typing, like the print-out from the script specifies:
|
||||
|
||||
cd keyboard/<project_name>
|
||||
|
||||
#### config.h
|
||||
|
||||
The first thing we're going to want to modify is the `config.h` file. On line 32 and 33, you'll see `MATRIX_ROWS` and `MATRIX_COLS` - set both these variables to however many rows and columns you have on your keyboard.
|
||||
|
||||
On line 38 and 39 you'll see the `COLS` and `ROWS` definitions - this is where you'll enter the pins you used, in order (left-to-right when looking at the top of the keyboard, but right-to-left when looking at the bottom).
|
||||
|
||||
There are some other variables that you'll be able to modify (lines 23-29), but it's not necessary to do that now (or ever, really).
|
||||
|
||||
#### \<project_name\>.h
|
||||
|
||||
The next file you'll want to look at is `<project_name>.h`. You're going to want to rewrite the `KEYMAP` definition - the format and syntax here is extremely important, so pay attention to how things are setup. The first half of the definition are considered the arguments - this is the format that you'll be following in your keymap later on, so you'll want to have as many k*xy* variables here as you do keys. The second half is the part that the firmware actually looks at, and will contain gaps depending on how you wired your matrix.
|
||||
|
||||
We'll dive into how this will work with the following example. Say we have a keyboard like this:
|
||||
|
||||
┌───┬───┬───┐
|
||||
│ │ │ │
|
||||
├───┴─┬─┴───┤
|
||||
│ │ │
|
||||
└─────┴─────┘
|
||||
|
||||
This can be described by saying the top row is 3 1u keys, and the bottom row is 2 1.5u keys. The difference between the two rows is important, because the bottom row has an unused column spot (3 v 2). Let's say that this is how we wired the columns:
|
||||
|
||||
┌───┬───┬───┐
|
||||
│ ┋ │ ┋ │ ┋ │
|
||||
├─┋─┴─┬─┴─┋─┤
|
||||
│ ┋ │ ┋ │
|
||||
└─────┴─────┘
|
||||
|
||||
The middle column is unused on the bottom row in this example. Our `KEYMAP` definition would look like this:
|
||||
|
||||
#define KEYMAP( \
|
||||
k00, k01, k02, \
|
||||
k10, k11, \
|
||||
) \
|
||||
{ \
|
||||
{ k00, k01, k02 }, \
|
||||
{ k10, KC_NO, k11 }, \
|
||||
}
|
||||
|
||||
Notice how the top half is spaced to resemble our physical layout - this helps us understand which keys are associated with which columns. The bottom half uses the keycode `KC_NO` where there is no keyswitch wired in. It's easiest to keep the bottom half aligned in a grid to help us make sense of how the firmware actually sees the wiring.
|
||||
|
||||
Let's say that instead, we wired our keyboard like this (a fair thing to do):
|
||||
|
||||
┌───┬───┬───┐
|
||||
│ ┋ │ ┋│ ┋ │
|
||||
├─┋─┴─┬┋┴───┤
|
||||
│ ┋ │┋ │
|
||||
└─────┴─────┘
|
||||
|
||||
This would require our `KEYMAP` definition to look like this:
|
||||
|
||||
#define KEYMAP( \
|
||||
k00, k01, k02, \
|
||||
k10, k11, \
|
||||
) \
|
||||
{ \
|
||||
{ k00, k01, k02 }, \
|
||||
{ k10, k11, KC_NO }, \
|
||||
}
|
||||
|
||||
Notice how the `k11` and `KC_NO` switched places to represent the wiring, and the unused final column on the bottom row. Sometimes it'll make more sense to put a keyswitch on a particular column, but in the end, it won't matter, as long as all of them are accounted for. You can use this process to write out the `KEYMAP` for your entire keyboard - be sure to remember that your keyboard is actually backwards when looking at the underside of it.
|
||||
|
||||
#### keymaps/default.c
|
||||
|
||||
This is the actual keymap for your keyboard, and the main place you'll make changes as you perfect your layout. `default.c` is the file that gets pull by default when typing `make`, but you can make other files as well, and specify them by typing `make KEYMAP=<variant>`, which will pull `keymaps/<variant>.c`.
|
||||
|
||||
The basis of a keymap is its layers - by default, layer 0 is active. You can activate other layers, the highest of which will be referenced first. Let's start with our base layer.
|
||||
|
||||
Using our previous example, let's say we want to create the following layout:
|
||||
|
||||
┌───┬───┬───┐
|
||||
│ A │ 1 │ H │
|
||||
├───┴─┬─┴───┤
|
||||
│ TAB │ SPC │
|
||||
└─────┴─────┘
|
||||
|
||||
This can be accomplished by using the following `keymaps` definition:
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = KEYMAP( /* Base */
|
||||
KC_A, KC_1, KC_H, \
|
||||
KC_TAB, KC_SPC \
|
||||
),
|
||||
};
|
||||
|
||||
Note that the layout of the keycodes is similar to the physical layout of our keyboard - this make it much easier to see what's going on. A lot of the keycodes should be fairly obvious, but for a full list of them, check out [tmk_code/doc/keycode.txt](https://github.com/jackhumbert/qmk_firmware/blob/master/tmk_core/doc/keycode.txt) - there are also a lot of aliases to condense your keymap file.
|
||||
|
||||
It's also important to use the `KEYMAP` function we defined earlier - this is what allows the firmware to associate our intended readable keymap with the actual wiring.
|
||||
|
||||
#### Compiling your firmware
|
||||
|
||||
After you've written out your entire keymap, you're ready to get the firmware compiled and onto your Teensy. Before compiling, you'll need to get your [development environment set-up](https://github.com/jackhumbert/qmk_firmware/blob/master/keyboard/planck/PCB_GUIDE.md#setting-up-the-environment) - you can skip the dfu-programmer instructions, but you'll need to download and install the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to get the firmware on your Teensy.
|
||||
|
||||
Once everything is installed, running `make` in the terminal should get you some output, and eventually a `<project_name>.hex` file in that folder. If you're having trouble with this step, see the end of the guide for the trouble-shooting section.
|
||||
|
||||
Once you have your `<project_name>.hex` file, open up the Teensy loader application, and click the file icon. From here, navigate to your `QMK/keyboard/<project_name>/` folder, and select the `<project_name>.hex` file. Plug in your keyboard and press the button on the Teensy - you should see the LED on the device turn off once you do. The Teensy Loader app will change a little, and the buttons should be clickable - click the download button (down arrow), and then the reset button (right arrow), and your keyboard should be ready to go!
|
||||
|
||||
#### Testing your firmware
|
||||
|
||||
Carefully flip your keyboard over, open up a new text document, and try typing - you should get the characters that you put into your keymap. Test each key, and note the ones that aren't working. Here's a quick trouble-shooting guide for non-working keys:
|
||||
|
||||
0. Flip the keyboard back over and short the keyswitch's contacts with a piece wire - this will eliminate the possibility of the keyswitch being bad and needing to be replaced.
|
||||
1. Check the solder points on the keyswitch - these need to be plump and whole. If you touch it with a moderate amount of force and it comes apart, it's not strong enough.
|
||||
2. Check the solder joints on the diode - if the diode is loose, part of your row may register, while the other may not.
|
||||
3. Check the solder joints on the columns - if your column wiring is loose, part or all of the column may not work.
|
||||
4. Check the solder joints on both sides of the wires going to/from the Teensy - the wires need to be fully soldered and connect to both sides.
|
||||
5. Check the <project_name>.h file for errors and incorrectly placed `KC_NO`s - if you're unsure where they should be, instead duplicate a k*xy* variable.
|
||||
6. Check to make sure you actually compiled the firmware and flashed the Teensy correctly. Unless you got error messages in the terminal, or a pop-up during flashing, you probably did everything correctly.
|
||||
|
||||
If you've done all of these things, keep in mind that sometimes you might have had multiple things affecting the keyswitch, so it doesn't hurt to test the keyswitch by shorting it out at the end.
|
||||
|
||||
#### Securing the Teensy, finishing your hardware, getting fancier firmware
|
||||
|
||||
Now that you have a working board, it's time to get things in their permanent positions. I've often used liberal amounts of hot glue to secure and insulate things, so if that's your style, start spreading that stuff like butter. Otherwise, double-sided tape is always an elegant solution, and electrical tape is a distant second. Due to the nature of these builds, a lot of this part is up to you and how you planned (or didn't plan) things out.
|
||||
|
||||
There are a lot of possibilities inside the firmware - check out the [README](https://github.com/jackhumbert/qmk_firmware/blob/master/README.md) for a full feature list, and dive into the different project (Planck, Ergodox EZ, etc) to see how people use all of them. You can always stop by [the OLKB subreddit for help!](http://reddit.com/r/olkb)
|
||||
|
||||
## Trouble-shooting compiling
|
||||
|
||||
### Windows
|
||||
|
||||
#### fork: Resource temporarily unavailable
|
||||
|
||||
http://www.avrfreaks.net/forum/windows-81-compilation-error
|
||||
|
||||
### Mac
|
||||
|
||||
### Linux
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,184 @@
|
||||
#include "ergodox_ez.h"
|
||||
#include "debug.h"
|
||||
#include "action_layer.h"
|
||||
|
||||
#define BASE 0 // default layer
|
||||
#define SYMB 1 // symbols
|
||||
#define MDIA 2 // media keys
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Keymap 0: Basic layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | = | 1 | 2 | 3 | 4 | 5 | LEFT | | RIGHT| 6 | 7 | 8 | 9 | 0 | - |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | Del | Q | W | F | P | G | L1 | | L1 | J | L | U | Y | ; | \ |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | BkSp | A | R | S | T | D |------| |------| H | N | E | I |O / L2| ' |
|
||||
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
|
||||
* | LShift |Z/Ctrl| X | C | V | B | | | | K | M | , | . |//Ctrl| RShift |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* |Grv/L1| '" |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | App | LGui | | Alt |Ctrl/Esc|
|
||||
* ,------|------|------| |------+--------+------.
|
||||
* | | | Home | | PgUp | | |
|
||||
* | Space|Backsp|------| |------| Tab |Enter |
|
||||
* | |ace | End | | PgDn | | |
|
||||
* `--------------------' `----------------------'
|
||||
*/
|
||||
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
|
||||
// Otherwise, it needs KC_*
|
||||
[BASE] = KEYMAP( // layer 0 : default
|
||||
// left hand
|
||||
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
|
||||
KC_DELT, KC_Q, KC_W, KC_F, KC_P, KC_G, TG(SYMB),
|
||||
KC_BSPC, KC_A, KC_R, KC_S, KC_T, KC_D,
|
||||
KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
|
||||
LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_LEFT,KC_RGHT,
|
||||
ALT_T(KC_APP), KC_LGUI,
|
||||
KC_HOME,
|
||||
KC_SPC,KC_BSPC,KC_END,
|
||||
// right hand
|
||||
KC_RGHT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
|
||||
TG(SYMB), KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSLS,
|
||||
KC_H, KC_N, KC_E, KC_I, LT(MDIA, KC_O), KC_QUOT,
|
||||
MEH_T(KC_NO),KC_K, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
|
||||
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1,
|
||||
KC_LALT, CTL_T(KC_ESC),
|
||||
KC_PGUP,
|
||||
KC_PGDN,KC_TAB, KC_ENT
|
||||
),
|
||||
/* Keymap 1: Symbol Layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | | | | | . | 0 | = | |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | | | |
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | | | |
|
||||
* | | |------| |------| | |
|
||||
* | | | | | | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// SYMBOLS
|
||||
[SYMB] = KEYMAP(
|
||||
// left hand
|
||||
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
|
||||
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
|
||||
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
|
||||
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
// right hand
|
||||
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
|
||||
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
|
||||
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
|
||||
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
|
||||
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS
|
||||
),
|
||||
/* Keymap 2: Media and mouse keys
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | | | | | | | | | | | | | | |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | | | MsUp | | | | | | | | | | | |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | | | | | | | | | | | Prev | Next | | |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | | | |
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | | |Brwser|
|
||||
* | | |------| |------| |Back |
|
||||
* | | | | | | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// MEDIA AND MOUSE
|
||||
[MDIA] = KEYMAP(
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
// right hand
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
|
||||
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_WBAK
|
||||
),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM fn_actions[] = {
|
||||
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
|
||||
};
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
// MACRODOWN only works in this function
|
||||
switch(id) {
|
||||
case 0:
|
||||
if (record->event.pressed) {
|
||||
register_code(KC_RSFT);
|
||||
} else {
|
||||
unregister_code(KC_RSFT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return MACRO_NONE;
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void * matrix_init_user(void) {
|
||||
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void * matrix_scan_user(void) {
|
||||
|
||||
uint8_t layer = biton32(layer_state);
|
||||
|
||||
ergodox_board_led_off();
|
||||
ergodox_right_led_1_off();
|
||||
ergodox_right_led_2_off();
|
||||
ergodox_right_led_3_off();
|
||||
switch (layer) {
|
||||
// TODO: Make this relevant to the ErgoDox EZ.
|
||||
case 1:
|
||||
ergodox_right_led_1_on();
|
||||
break;
|
||||
case 2:
|
||||
ergodox_right_led_2_on();
|
||||
break;
|
||||
default:
|
||||
// none
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
# ErgoDox EZ Colemak Configuration
|
||||
|
||||
Colemak layout with same layers as default ergodox ez keymap.
|
||||
|
@ -0,0 +1,136 @@
|
||||
# TypeMatrix™ 2030 inspired layout
|
||||
|
||||
This is a [TypeMatrix™ 2030](http://typematrix.com/2030/features.php) inspired layout for the ErgoDox EZ. The _TypeMatrix_ is a nice small ergonomic keyboard with a matrix layout, and it provides several nice features like `enter`, `backspace` and `delete` at the center, bigger `shift` keys and international `cut`, `copy` and `paste` keys.
|
||||
|
||||
The idea in this ErgoDox layout is to make it is as close as possible to the TM2030, such that it would be easy to switch between the TM and the ErgoDox. No _fancy_ features have been implemented, as this is intended to be a base for further customization if desired. Some keys have been duplicated in order to accomodate for most people.
|
||||
|
||||
Most of the TM2030 features are supported except
|
||||
* automatic window switching (alt-tab key, at the left of the space key)
|
||||
* show desktop key (at the right of the space key)
|
||||
* 102/106 modes
|
||||
|
||||
Dvorak mode is even supported by pressing [`Magic`](/TMK_README.md#magic-commands)+`1` (`Magic` is by default `LShift`+`RShift`)
|
||||
|
||||
Some keys had to be moved around to fit into the ErgoDox, especially the `F1`-`F12` keys and the arrow keys.
|
||||
|
||||
## Base Layer
|
||||
This is the default layer, close to the TM with the following differences:
|
||||
|
||||
- Top row (with the `F`-keys) and rightmost column (with application shortcuts) are removed, the corresponding keys are displaced elsewhere.
|
||||
- Bottom-left keys are reorganized on a single row as: `Ctrl`, `fn`, `Gui`, `Play`, `App`/`Alt`.
|
||||
- `shuffle` and `desktop` are not supported.
|
||||
- `right-shift` is moved on `'`, `\` and on the right thumb (the latter is actually the only _true_ `right-shift`, and must be used in the `Magic` key combination).
|
||||
- `right-ctrl` is moved on `End`.
|
||||
- `]` is moved in place of the dash (`-`).
|
||||
- Dash (`-`) and `=` are moved on bottom right row.
|
||||
- Arrows and `PgUp`/`PgDn` are moved on the thumbs.
|
||||
|
||||
```
|
||||
,--------------------------------------------------. ,--------------------------------------------------.
|
||||
| ` | 1 | 2 | 3 | 4 | 5 | Del | | Del | 6 | 7 | 8 | 9 | 0 | ] |
|
||||
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
| Tab | Q | W | E | R | T |Backsp| |Backsp| Y | U | I | O | P | [ |
|
||||
|--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
|
||||
| LShift | A | S | D | F | G |------| |------| H | J | K | L | ; | '/Shift|
|
||||
|--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
|
||||
| LShift | Z | X | C | V | B | | | | N | M | , | . | / | \/Shift|
|
||||
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
|LCtrl | fn | LGui | Play |App/Alt| | RAlt | - | Home | = |End/Ctl|
|
||||
`-----------------------------------' `-----------------------------------'
|
||||
,--------------. ,-------------.
|
||||
|Esc/Alt| num | | Left |Right |
|
||||
,------+-------+------| |------+------+------.
|
||||
| | | PgUp | | Up | | |
|
||||
|Space |LShift |------| |------|RShift|Space |
|
||||
| | | PgDn | | Down | | |
|
||||
`---------------------' `--------------------'
|
||||
```
|
||||
|
||||
### Layer Switching
|
||||
- Use `num` to toggle the Numeric Layer.
|
||||
- Hold `fn` to temporarily activate the Numeric & Fn Layers.
|
||||
|
||||
As on the original TM 2030, when `num` layer is activated, holding `fn` disables it but enables the other `fn` keys.
|
||||
|
||||
## Dvorak Layer
|
||||
Same as Layer 0 but with _Dvorak_ layout, to use with QWERTY OS layout.
|
||||
|
||||
Enable Dvorak layout with [`Magic`](/TMK_README.md#magic-commands+`1` (`LShift`+`RShift`+`1`), disable with `Magic`-`0`.
|
||||
|
||||
The middle (green) led indicates when the Dvorak layer is activated.
|
||||
|
||||
,--------------------------------------------------. ,--------------------------------------------------.
|
||||
| ` | 1 | 2 | 3 | 4 | 5 | Del | | Del | 6 | 7 | 8 | 9 | 0 | = |
|
||||
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
| Tab | ' | , | . | P | Y |Backsp| |Backsp| F | G | C | R | L | / |
|
||||
|--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
|
||||
| LShift | A | O | E | U | I |------| |------| D | H | T | N | S | -/Shift|
|
||||
|--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
|
||||
| LShift | ; | Q | J | K | X | | | | B | M | W | V | Z | \/Shift|
|
||||
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
|LCtrl | fn | LGui | Play |App/Alt| | RAlt | [ | Home | ] |End/Ctl|
|
||||
`-----------------------------------' `-----------------------------------'
|
||||
,--------------. ,-------------.
|
||||
|Esc/Alt| num | | Left |Right |
|
||||
,------+-------+------| |------+------+------.
|
||||
| | | PgUp | | Up | | |
|
||||
|Space |LShift |------| |------|RShift|Space |
|
||||
| | | PgDn | | Down | | |
|
||||
`---------------------' `--------------------'
|
||||
|
||||
## Numeric Layer
|
||||
Numeric layer close to the TM when toggling `num`, with the following differences:
|
||||
|
||||
- Numpad is displaced by 1 to the top left.
|
||||
- Arrows are displaced by 1 to the left.
|
||||
- Provides access to `F1`-`F12`, `caps-lock` and `num-lock`.
|
||||
|
||||
The numeric layer is indicated with the left (red) led. Caps-lock is indicated with the right (blue) led.
|
||||
|
||||
,--------------------------------------------------. ,--------------------------------------------------.
|
||||
| | F1 | F2 | F3 | F4 | F5 | | | | | | Tab | / | * | - |
|
||||
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
| | F6 | F7 | F8 | F9 | F10 | | | | | Home | 7 | 8 | 9 | + |
|
||||
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
| | F11 | F12 | | | |------| |------| Up | End | 4 | 5 | 6 | + |
|
||||
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
| | | | | | | | | Left | Down | Right| 1 | 2 | 3 |KpEnter |
|
||||
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
| | | | | | | | 0 | 00 | . |Etr/Ctl|
|
||||
`----------------------------------' `-----------------------------------'
|
||||
,-------------. ,-------------.
|
||||
| | | |n.lock|c.lock|
|
||||
,------|------|------| |------+------+------.
|
||||
| | | | | | | |
|
||||
| | |------| |------| | |
|
||||
| | | | | | | |
|
||||
`--------------------' `--------------------'
|
||||
|
||||
## Fn Layer
|
||||
Activated simultaneously with the Numeric layer when holding the `fn` key. As on the TM, it provides access to the following features:
|
||||
- `cut`, `copy` and `paste`
|
||||
- `volume up`, `volume down` and `mute` — as opposed to the TM, these are only on left hand
|
||||
- `previous track` and `next track`
|
||||
- `calculator`, `mail` and `browser home`
|
||||
- `insert`, `power`, `sleep`, `wake`, `print screen`, `scroll-lock` and `pause`
|
||||
|
||||
Note: the `eject` key does not work due to jackhumbert/qmk_firmware#82
|
||||
|
||||
,--------------------------------------------------. ,--------------------------------------------------.
|
||||
| | | | | | |Insert| |Insert|Eject |Power |Sleep | Wake |PrtScr|ScrollLk|
|
||||
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
| | | | | | |VolUp | | | | | | | | Pause |
|
||||
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
| | | | Calc | Mail |Browsr|------| |------| | | | | | |
|
||||
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
| | | cut | copy |paste | Mute |VolDn | | | | | | | | |
|
||||
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
| | | | | | | | | | | |
|
||||
`----------------------------------' `----------------------------------'
|
||||
,-------------. ,-------------.
|
||||
| | | | | |
|
||||
,------|------|------| |------+------+------.
|
||||
| | | | | Next | | |
|
||||
| Mute | |------| |------| | |
|
||||
| | | | | Prev | | |
|
||||
`--------------------' `--------------------'
|
@ -0,0 +1,258 @@
|
||||
/* TypeMatrix-2030-like keymap */
|
||||
#include "ergodox_ez.h"
|
||||
#include "debug.h"
|
||||
#include "action_layer.h"
|
||||
#include "led.h"
|
||||
|
||||
#define BASE 0 // default layer
|
||||
#define DVRK 1 // Dvorak layer
|
||||
#define NUMR 8 // numeric layer
|
||||
#define FNLR 9 // fn layer
|
||||
|
||||
#define MDBL0 1
|
||||
#define MFNLR 2
|
||||
#define MCUT 3
|
||||
#define MCOPY 4
|
||||
#define MPSTE 5
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Basic layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | Del | | Del | 6 | 7 | 8 | 9 | 0 | ] |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | Tab | Q | W | E | R | T |Backsp| |Backsp| Y | U | I | O | P | [ |
|
||||
* |--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
|
||||
* | LShift | A | S | D | F | G |------| |------| H | J | K | L | ; | '/Shift|
|
||||
* |--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
|
||||
* | LShift | Z | X | C | V | B | | | | N | M | , | . | / | \/Shift|
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* |LCtrl | fn | LGui | Play |App/Alt| | RAlt | - | Home | = |End/Ctl|
|
||||
* `-----------------------------------' `-----------------------------------'
|
||||
* ,--------------. ,-------------.
|
||||
* |Esc/Alt| num | | Left |Right |
|
||||
* ,------+-------+------| |------+------+------.
|
||||
* | | | PgUp | | Up | | |
|
||||
* |Space |LShift |------| |------|RShift|Space |
|
||||
* | | | PgDn | | Down | | |
|
||||
* `---------------------' `--------------------'
|
||||
*/
|
||||
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
|
||||
// Otherwise, it needs KC_*
|
||||
[BASE] = KEYMAP( // layer 0 : default
|
||||
// left hand
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_DELT,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_BSPC,
|
||||
KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_ENT,
|
||||
KC_LCTL, M(MFNLR), KC_LGUI,KC_MPLY,ALT_T(KC_APP),
|
||||
|
||||
ALT_T(KC_ESC), TG(NUMR),
|
||||
KC_PGUP,
|
||||
KC_SPC, KC_LSFT, KC_PGDN,
|
||||
|
||||
// right hand
|
||||
KC_DELT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_RBRC,
|
||||
KC_BSPC, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
|
||||
KC_H, KC_J, KC_K, KC_L, KC_SCLN, SFT_T(KC_QUOT),
|
||||
KC_ENT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_T(KC_BSLS),
|
||||
KC_RALT, KC_MINS, KC_HOME, KC_EQL, CTL_T(KC_END),
|
||||
|
||||
KC_LEFT, KC_RGHT,
|
||||
KC_UP,
|
||||
KC_DOWN, KC_RSFT, KC_SPC
|
||||
),
|
||||
/* Dvorak layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | Del | | Del | 6 | 7 | 8 | 9 | 0 | = |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | Tab | ' | , | . | P | Y |Backsp| |Backsp| F | G | C | R | L | / |
|
||||
* |--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
|
||||
* | LShift | A | O | E | U | I |------| |------| D | H | T | N | S | -/Shift|
|
||||
* |--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
|
||||
* | LShift | ; | Q | J | K | X | | | | B | M | W | V | Z | \/Shift|
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* |LCtrl | fn | LGui | Play |App/Alt| | RAlt | [ | Home | ] |End/Ctl|
|
||||
* `-----------------------------------' `-----------------------------------'
|
||||
* ,--------------. ,-------------.
|
||||
* |Esc/Alt| num | | Left |Right |
|
||||
* ,------+-------+------| |------+------+------.
|
||||
* | | | PgUp | | Up | | |
|
||||
* |Space |LShift |------| |------|RShift|Space |
|
||||
* | | | PgDn | | Down | | |
|
||||
* `---------------------' `--------------------'
|
||||
*/
|
||||
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
|
||||
// Otherwise, it needs KC_*
|
||||
[DVRK] = KEYMAP( // layer 0 : default
|
||||
// left hand
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_DELT,
|
||||
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_BSPC,
|
||||
KC_LSFT, KC_A, KC_O, KC_E, KC_U, KC_I,
|
||||
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_ENT,
|
||||
KC_LCTL, M(MFNLR), KC_LGUI, KC_MPLY, ALT_T(KC_APP),
|
||||
|
||||
ALT_T(KC_ESC), TG(NUMR),
|
||||
KC_PGUP,
|
||||
KC_SPC, KC_LSFT, KC_PGDN,
|
||||
|
||||
// right hand
|
||||
KC_DELT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL,
|
||||
KC_BSPC, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH,
|
||||
KC_D, KC_H, KC_T, KC_N, KC_S, SFT_T(KC_MINS),
|
||||
KC_ENT, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_T(KC_BSLS),
|
||||
KC_RALT, KC_LBRC, KC_HOME, KC_RBRC, CTL_T(KC_END),
|
||||
|
||||
KC_LEFT, KC_RGHT,
|
||||
KC_UP,
|
||||
KC_DOWN, KC_RSFT, KC_SPC
|
||||
),
|
||||
/* Numeric Layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | F1 | F2 | F3 | F4 | F5 | | | | | | Tab | / | * | - |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | F6 | F7 | F8 | F9 | F10 | | | | | Home | 7 | 8 | 9 | + |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | F11 | F12 | | | |------| |------| Up | End | 4 | 5 | 6 | + |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | | | | | | | | Left | Down | Right| 1 | 2 | 3 |KpEnter |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | | | | | 0 | 00 | . |Etr/Ctl|
|
||||
* `----------------------------------' `-----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | |n.lock|c.lock|
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | | | |
|
||||
* | | |------| |------| | |
|
||||
* | | | | | | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// SYMBOLS
|
||||
[NUMR] = KEYMAP(
|
||||
// left hand
|
||||
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
|
||||
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
|
||||
KC_TRNS, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
|
||||
KC_TRNS,KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,
|
||||
// right hand
|
||||
KC_INS, KC_F6, KC_F7, KC_TAB, KC_PSLS, KC_PAST, KC_PMNS,
|
||||
KC_TRNS, KC_TRNS, KC_HOME, KC_P7, KC_P8, KC_P9, KC_PPLS,
|
||||
KC_UP, KC_END, KC_P4, KC_P5, KC_P6, KC_PPLS,
|
||||
KC_LEFT, KC_DOWN, KC_RGHT, KC_P1, KC_P2, KC_P3, KC_PENT,
|
||||
KC_TRNS, KC_P0, M(MDBL0),KC_PDOT, CTL_T(KC_PENT),
|
||||
|
||||
KC_NLCK, KC_CAPS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS
|
||||
),
|
||||
/* fn layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | | | | | |Insert| |Insert|Eject |Power |Sleep | Wake |PrtScr|ScrollLk|
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | | | | | |VolUp | | | | | | | | Pause |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | | | Calc | Mail |Browsr|------| |------| | | | | | |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | | cut | copy |paste | Mute |VolDn | | | | | | | | |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | | | | | | | | |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | | | |
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | Next | | |
|
||||
* | Mute | |------| |------| | |
|
||||
* | | | | | Prev | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// MEDIA AND MOUSE
|
||||
[FNLR] = KEYMAP(
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_CALC, KC_MAIL, KC_WHOM,
|
||||
KC_TRNS, KC_TRNS, M(MCUT), M(MCOPY), M(MPSTE), KC_MUTE, KC_VOLD,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_MUTE, KC_TRNS, KC_TRNS,
|
||||
// right hand
|
||||
KC_INS, KC_EJCT, KC_PWR, KC_SLEP, KC_WAKE, KC_PSCR, KC_SLCK,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PAUS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_MPRV,
|
||||
KC_MNXT, KC_TRNS, KC_TRNS
|
||||
),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM fn_actions[] = {
|
||||
};
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
// MACRODOWN only works in this function
|
||||
switch(id) {
|
||||
case MDBL0:
|
||||
if (record->event.pressed) {
|
||||
return MACRO( I(25), T(P0), T(P0), END );
|
||||
}
|
||||
break;
|
||||
case MFNLR:
|
||||
layer_state ^= (1 << NUMR) | (1 << FNLR);
|
||||
break;
|
||||
case MCUT:
|
||||
if (record->event.pressed) {
|
||||
return MACRO(D(LSFT), T(DELT), U(LSFT), END);
|
||||
}
|
||||
break;
|
||||
case MCOPY:
|
||||
if (record->event.pressed) {
|
||||
return MACRO(D(LCTL), T(INS), U(LCTL), END);
|
||||
}
|
||||
break;
|
||||
case MPSTE:
|
||||
if (record->event.pressed) {
|
||||
return MACRO(D(LSFT), T(INS), U(LSFT), END);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return MACRO_NONE;
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void * matrix_init_user(void) {
|
||||
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void * matrix_scan_user(void) {
|
||||
|
||||
ergodox_board_led_off();
|
||||
ergodox_right_led_1_off();
|
||||
ergodox_right_led_2_off();
|
||||
ergodox_right_led_3_off();
|
||||
// led 1: numeric layer
|
||||
if (layer_state & (1 << NUMR)) {
|
||||
ergodox_right_led_1_on();
|
||||
}
|
||||
// led 2: Dvorak layer
|
||||
if (default_layer_state == 1 << DVRK) {
|
||||
ergodox_right_led_2_on();
|
||||
}
|
||||
// led 3: caps lock
|
||||
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
|
||||
ergodox_right_led_3_on();
|
||||
}
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,184 @@
|
||||
#include "ergodox_ez.h"
|
||||
#include "debug.h"
|
||||
#include "action_layer.h"
|
||||
|
||||
#define BASE 0 // default layer
|
||||
#define SYMB 1 // symbols
|
||||
#define MDIA 2 // media keys
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Keymap 0: Basic layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | Esc | 1 | 2 | 3 | 4 | 5 | = | | - | 6 | 7 | 8 | 9 | 0 | Enter |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | Tab | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \ |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | BkSp | A | S | D | F | G |------| |------| H | J | K | L | ; | '" |
|
||||
* |--------+------+------+------+------+------| LGui | | LGui |------+------+------+------+------+--------|
|
||||
* | LShift | Z | X | C | V | B | | | | N | M | , | . | / | RShift |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | L1 | ` | { | } | '" | | Left | Up | Down | Right| L2 |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | Del | Alt | | Alt | Ctrl |
|
||||
* ,------|------|------| |------+--------+------.
|
||||
* | | | Home | | PgUp | | |
|
||||
* | Space|Backsp|------| |------| Tab |Enter |
|
||||
* | |ace | End | | PgDn | | |
|
||||
* `--------------------' `----------------------'
|
||||
*/
|
||||
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
|
||||
// Otherwise, it needs KC_*
|
||||
[BASE] = KEYMAP( // layer 0 : default
|
||||
// left hand
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_EQL,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
|
||||
KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LGUI,
|
||||
TG(SYMB), KC_GRV, KC_LBRC, KC_RBRC,KC_QUOT,
|
||||
KC_DELT,KC_LALT,
|
||||
KC_HOME,
|
||||
KC_SPC,KC_BSPC,KC_END,
|
||||
// right hand
|
||||
KC_MINS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_ENT,
|
||||
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
|
||||
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
|
||||
KC_LGUI, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT,
|
||||
KC_LEFT,KC_UP, KC_DOWN,KC_RIGHT, TG(MDIA),
|
||||
KC_RALT, KC_RCTL,
|
||||
KC_PGUP,
|
||||
KC_PGDN,KC_TAB, KC_ENT
|
||||
),
|
||||
/* Keymap 1: Symbol Layer
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | | | | | . | 0 | = | |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | | | |
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | | | |
|
||||
* | | |------| |------| | |
|
||||
* | | | | | | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// SYMBOLS
|
||||
[SYMB] = KEYMAP(
|
||||
// left hand
|
||||
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
|
||||
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
|
||||
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
|
||||
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
// right hand
|
||||
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
|
||||
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
|
||||
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
|
||||
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
|
||||
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS
|
||||
),
|
||||
/* Keymap 2: Media and mouse keys
|
||||
*
|
||||
* ,--------------------------------------------------. ,--------------------------------------------------.
|
||||
* | | | | | | | | | | | | | | | |
|
||||
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
|
||||
* | | | | MsUp | | | | | | | | | | | |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
|
||||
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
|
||||
* | | | | | | | | | | | | Prev | Next | | |
|
||||
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|
||||
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
|
||||
* `----------------------------------' `----------------------------------'
|
||||
* ,-------------. ,-------------.
|
||||
* | | | | | |
|
||||
* ,------|------|------| |------+------+------.
|
||||
* | | | | | | |Brwser|
|
||||
* | | |------| |------| |Back |
|
||||
* | | | | | | | |
|
||||
* `--------------------' `--------------------'
|
||||
*/
|
||||
// MEDIA AND MOUSE
|
||||
[MDIA] = KEYMAP(
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
// right hand
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
|
||||
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,
|
||||
KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_WBAK
|
||||
),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM fn_actions[] = {
|
||||
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
|
||||
};
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
// MACRODOWN only works in this function
|
||||
switch(id) {
|
||||
case 0:
|
||||
if (record->event.pressed) {
|
||||
register_code(KC_RSFT);
|
||||
} else {
|
||||
unregister_code(KC_RSFT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return MACRO_NONE;
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void * matrix_init_user(void) {
|
||||
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void * matrix_scan_user(void) {
|
||||
|
||||
uint8_t layer = biton32(layer_state);
|
||||
|
||||
ergodox_board_led_off();
|
||||
ergodox_right_led_1_off();
|
||||
ergodox_right_led_2_off();
|
||||
ergodox_right_led_3_off();
|
||||
switch (layer) {
|
||||
// TODO: Make this relevant to the ErgoDox EZ.
|
||||
case 1:
|
||||
ergodox_right_led_1_on();
|
||||
break;
|
||||
case 2:
|
||||
ergodox_right_led_2_on();
|
||||
break;
|
||||
default:
|
||||
// none
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
# ErgoDox EZ OS X Simplified Configuration
|
||||
|
||||
This keyboard configuration replaces the hyper and meh keys with the command key. It also removes all of the meta keys that require a "hold" because I found that I hesitate when I type, which can accidentally fire those combinations. On the upper left of the left hand, I mimicked the Mac placement of tab and escape, and on the upper right of the right hand, I placed an additional enter key for convenience when breezing through prompts.
|
||||
|
||||
This is my standard working configuration for now, but I can see myself tweaking it as I use it more. I highly recommend you do the same.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
||||
# The Default Planck Layout
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[_QW] = { /* Qwerty */
|
||||
{KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
|
||||
{KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
|
||||
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
|
||||
{M(0), KC_LCTL, KC_LALT, KC_LGUI, MO(_LW), KC_SPC, KC_SPC, MO(_RS), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
|
||||
},
|
||||
[_CM] = { /* Colemak */
|
||||
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
|
||||
{KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
|
||||
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
|
||||
{M(0), KC_LCTL, KC_LALT, KC_LGUI, MO(_LW), KC_SPC, KC_SPC, MO(_RS), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
|
||||
},
|
||||
[_DV] = { /* Dvorak */
|
||||
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
|
||||
{KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH},
|
||||
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT },
|
||||
{M(0), KC_LCTL, KC_LALT, KC_LGUI, MO(_LW), KC_SPC, KC_SPC, MO(_RS), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
|
||||
},
|
||||
[_RS] = { /* RAISE */
|
||||
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
|
||||
{KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
|
||||
{KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, DF(_QW), DF(_CM), DF(_DV), RESET, KC_TRNS},
|
||||
{KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
|
||||
},
|
||||
[_LW] = { /* LOWER */
|
||||
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
|
||||
{KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
|
||||
{KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, DF(_QW), DF(_CM), DF(_DV), RESET, KC_TRNS},
|
||||
{KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
|
||||
}
|
||||
};
|
@ -1,50 +0,0 @@
|
||||
#include "keymap_common.h"
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = { /* Jack soft-coded colemak */
|
||||
{KC_TAB, CM_Q, CM_W, CM_F, CM_P, CM_G, CM_J, CM_L, CM_U, CM_Y, CM_SCLN, KC_BSPC},
|
||||
{KC_ESC, CM_A, CM_R, CM_S, CM_T, CM_D, CM_H, CM_N, CM_E, CM_I, CM_O, KC_QUOT},
|
||||
{KC_LSFT, CM_Z, CM_X, CM_C, CM_V, CM_B, CM_K, CM_M, CM_COMM, CM_DOT, CM_SLSH, KC_ENT},
|
||||
{BL_STEP, KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
|
||||
// Space is repeated to accommadate for both spacebar wiring positions
|
||||
},
|
||||
[1] = { /* Jack hard-coded colemak */
|
||||
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
|
||||
{KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
|
||||
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT},
|
||||
{KC_FN3, KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
|
||||
},
|
||||
[2] = { /* Jack RAISE */
|
||||
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
|
||||
{KC_TRNS, FUNC(3), FUNC(4), LSFT(RSFT(KC_PAUSE)), KC_TRNS, KC_TRNS, KC_TRNS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
|
||||
{KC_TRNS, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_TRNS},
|
||||
{KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(1), KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
|
||||
},
|
||||
[3] = { /* Jack LOWER */
|
||||
{S(KC_GRV), S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), S(KC_9), S(KC_0), KC_BSPC},
|
||||
{KC_TRNS, FUNC(3), FUNC(4), LSFT(RSFT(KC_PAUSE)), KC_TRNS, KC_TRNS, KC_TRNS, S(KC_MINS), S(KC_EQL), S(KC_LBRC), S(KC_RBRC), S(KC_BSLS)},
|
||||
{KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS},
|
||||
{KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(2), KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const uint16_t PROGMEM fn_actions[] = {
|
||||
[1] = ACTION_LAYER_MOMENTARY(2), // to Fn overlay
|
||||
[2] = ACTION_LAYER_MOMENTARY(3), // to Fn overlay
|
||||
|
||||
[3] = ACTION_DEFAULT_LAYER_SET(0),
|
||||
[4] = ACTION_DEFAULT_LAYER_SET(1),
|
||||
|
||||
};
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
// MACRODOWN only works in this function
|
||||
switch(id) {
|
||||
case 0:
|
||||
return MACRODOWN(T(CM_T), END);
|
||||
break;
|
||||
}
|
||||
return MACRO_NONE;
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
# Lock layout
|
||||
|
||||
This layout is designed for having a lock switch in the lower-left-hand corner, and for experimenting with MIDI/audio features. It's constantly in development, so don't expect anything to work/be documented correctly!
|
Binary file not shown.
After Width: | Height: | Size: 284 KiB |
Binary file not shown.
After Width: | Height: | Size: 335 KiB |
@ -0,0 +1,362 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "audio.h"
|
||||
#include "keymap_common.h"
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
// #define PWM_AUDIO
|
||||
|
||||
#ifdef PWM_AUDIO
|
||||
#include "wave.h"
|
||||
#define SAMPLE_DIVIDER 39
|
||||
#define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048)
|
||||
// Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
|
||||
#endif
|
||||
|
||||
void delay_us(int count) {
|
||||
while(count--) {
|
||||
_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
int voices = 0;
|
||||
int voice_place = 0;
|
||||
double frequency = 0;
|
||||
int volume = 0;
|
||||
long position = 0;
|
||||
|
||||
double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
bool sliding = false;
|
||||
|
||||
int max = 0xFF;
|
||||
float sum = 0;
|
||||
int value = 128;
|
||||
float place = 0;
|
||||
float places[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
uint16_t place_int = 0;
|
||||
bool repeat = true;
|
||||
uint8_t * sample;
|
||||
uint16_t sample_length = 0;
|
||||
|
||||
|
||||
bool notes = false;
|
||||
bool note = false;
|
||||
float note_frequency = 0;
|
||||
float note_length = 0;
|
||||
uint16_t note_position = 0;
|
||||
float (* notes_pointer)[][2];
|
||||
uint8_t notes_length;
|
||||
bool notes_repeat;
|
||||
uint8_t current_note = 0;
|
||||
|
||||
void stop_all_notes() {
|
||||
voices = 0;
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
#else
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
TCCR3A &= ~_BV(COM3A1);
|
||||
#endif
|
||||
notes = false;
|
||||
note = false;
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void stop_note(double freq) {
|
||||
#ifdef PWM_AUDIO
|
||||
freq = freq / SAMPLE_RATE;
|
||||
#endif
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (frequencies[i] == freq) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
for (int j = i; (j < 7); j++) {
|
||||
frequencies[j] = frequencies[j+1];
|
||||
frequencies[j+1] = 0;
|
||||
volumes[j] = volumes[j+1];
|
||||
volumes[j+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
voices--;
|
||||
if (voices < 0)
|
||||
voices = 0;
|
||||
if (voices == 0) {
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
#else
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
TCCR3A &= ~_BV(COM3A1);
|
||||
#endif
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
note = false;
|
||||
} else {
|
||||
double freq = frequencies[voices - 1];
|
||||
int vol = volumes[voices - 1];
|
||||
double starting_f = frequency;
|
||||
if (frequency < freq) {
|
||||
sliding = true;
|
||||
for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
|
||||
frequency = f;
|
||||
}
|
||||
sliding = false;
|
||||
} else if (frequency > freq) {
|
||||
sliding = true;
|
||||
for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
|
||||
frequency = f;
|
||||
}
|
||||
sliding = false;
|
||||
}
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
}
|
||||
}
|
||||
|
||||
void init_notes() {
|
||||
|
||||
#ifdef PWM_AUDIO
|
||||
PLLFRQ = _BV(PDIV2);
|
||||
PLLCSR = _BV(PLLE);
|
||||
while(!(PLLCSR & _BV(PLOCK)));
|
||||
PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
|
||||
|
||||
/* Init a fast PWM on Timer4 */
|
||||
TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
|
||||
TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
|
||||
OCR4A = 0;
|
||||
|
||||
/* Enable the OC4A output */
|
||||
DDRC |= _BV(PORTC6);
|
||||
|
||||
TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
|
||||
|
||||
TCCR3A = 0x0; // Options not needed
|
||||
TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
|
||||
OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
|
||||
#else
|
||||
DDRC |= _BV(PORTC6);
|
||||
|
||||
TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
|
||||
|
||||
TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ISR(TIMER3_COMPA_vect) {
|
||||
|
||||
if (note) {
|
||||
#ifdef PWM_AUDIO
|
||||
if (voices == 1) {
|
||||
// SINE
|
||||
OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2;
|
||||
|
||||
// SQUARE
|
||||
// if (((int)place) >= 1024){
|
||||
// OCR4A = 0xFF >> 2;
|
||||
// } else {
|
||||
// OCR4A = 0x00;
|
||||
// }
|
||||
|
||||
// SAWTOOTH
|
||||
// OCR4A = (int)place / 4;
|
||||
|
||||
// TRIANGLE
|
||||
// if (((int)place) >= 1024) {
|
||||
// OCR4A = (int)place / 2;
|
||||
// } else {
|
||||
// OCR4A = 2048 - (int)place / 2;
|
||||
// }
|
||||
|
||||
place += frequency;
|
||||
|
||||
if (place >= SINE_LENGTH)
|
||||
place -= SINE_LENGTH;
|
||||
|
||||
} else {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < voices; i++) {
|
||||
// SINE
|
||||
sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2;
|
||||
|
||||
// SQUARE
|
||||
// if (((int)places[i]) >= 1024){
|
||||
// sum += 0xFF >> 2;
|
||||
// } else {
|
||||
// sum += 0x00;
|
||||
// }
|
||||
|
||||
places[i] += frequencies[i];
|
||||
|
||||
if (places[i] >= SINE_LENGTH)
|
||||
places[i] -= SINE_LENGTH;
|
||||
}
|
||||
OCR4A = sum;
|
||||
}
|
||||
#else
|
||||
if (frequency > 0) {
|
||||
// ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period
|
||||
// OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period
|
||||
if (place > 10) {
|
||||
voice_place = (voice_place + 1) % voices;
|
||||
place = 0.0;
|
||||
}
|
||||
ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period
|
||||
OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1; // Set compare to half the period
|
||||
place++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// SAMPLE
|
||||
// OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
|
||||
|
||||
// place_int++;
|
||||
|
||||
// if (place_int >= sample_length)
|
||||
// if (repeat)
|
||||
// place_int -= sample_length;
|
||||
// else
|
||||
// TIMSK3 &= ~_BV(OCIE3A);
|
||||
|
||||
|
||||
if (notes) {
|
||||
#ifdef PWM_AUDIO
|
||||
OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
|
||||
|
||||
place += note_frequency;
|
||||
if (place >= SINE_LENGTH)
|
||||
place -= SINE_LENGTH;
|
||||
#else
|
||||
if (note_frequency > 0) {
|
||||
ICR3 = (int)(((double)F_CPU) / note_frequency); // Set max to the period
|
||||
OCR3A = (int)(((double)F_CPU) / note_frequency) >> 1; // Set compare to half the period
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
note_position++;
|
||||
if (note_position >= note_length) {
|
||||
current_note++;
|
||||
if (current_note >= notes_length) {
|
||||
if (notes_repeat) {
|
||||
current_note = 0;
|
||||
} else {
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
#else
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
TCCR3A &= ~_BV(COM3A1);
|
||||
#endif
|
||||
notes = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef PWM_AUDIO
|
||||
note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
|
||||
note_length = (*notes_pointer)[current_note][1];
|
||||
#else
|
||||
note_frequency = (*notes_pointer)[current_note][0];
|
||||
note_length = (*notes_pointer)[current_note][1] / 4;
|
||||
#endif
|
||||
note_position = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
|
||||
if (note)
|
||||
stop_all_notes();
|
||||
notes = true;
|
||||
|
||||
notes_pointer = np;
|
||||
notes_length = n_length;
|
||||
notes_repeat = n_repeat;
|
||||
|
||||
place = 0;
|
||||
current_note = 0;
|
||||
#ifdef PWM_AUDIO
|
||||
note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
|
||||
note_length = (*notes_pointer)[current_note][1];
|
||||
#else
|
||||
note_frequency = (*notes_pointer)[current_note][0];
|
||||
note_length = (*notes_pointer)[current_note][1] / 4;
|
||||
#endif
|
||||
note_position = 0;
|
||||
|
||||
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
#else
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
TCCR3A |= _BV(COM3A1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void play_sample(uint8_t * s, uint16_t l, bool r) {
|
||||
stop_all_notes();
|
||||
place_int = 0;
|
||||
sample = s;
|
||||
sample_length = l;
|
||||
repeat = r;
|
||||
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void play_note(double freq, int vol) {
|
||||
if (notes)
|
||||
stop_all_notes();
|
||||
note = true;
|
||||
#ifdef PWM_AUDIO
|
||||
freq = freq / SAMPLE_RATE;
|
||||
#endif
|
||||
if (freq > 0) {
|
||||
if (frequency != 0) {
|
||||
double starting_f = frequency;
|
||||
if (frequency < freq) {
|
||||
for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
|
||||
frequency = f;
|
||||
}
|
||||
} else if (frequency > freq) {
|
||||
for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
|
||||
frequency = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
|
||||
frequencies[voices] = frequency;
|
||||
volumes[voices] = volume;
|
||||
voices++;
|
||||
}
|
||||
|
||||
#ifdef PWM_AUDIO
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
#else
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
TCCR3A |= _BV(COM3A1);
|
||||
#endif
|
||||
|
||||
}
|
@ -1,246 +0,0 @@
|
||||
#include "beeps.h"
|
||||
#include <math.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
void delay_us(int count) {
|
||||
while(count--) {
|
||||
_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
int voices = 0;
|
||||
double frequency = 0;
|
||||
int volume = 0;
|
||||
int position = 0;
|
||||
|
||||
double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
bool sliding = false;
|
||||
#define RANGE 1000
|
||||
volatile int i=0; //elements of the wave
|
||||
|
||||
|
||||
void beeps() {
|
||||
play_notes();
|
||||
}
|
||||
|
||||
void send_freq(double freq, int vol) {
|
||||
int duty = (((double)F_CPU) / freq);
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> (0x10 - vol); // Set compare to half the period
|
||||
}
|
||||
|
||||
void stop_all_notes() {
|
||||
voices = 0;
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void stop_note(double freq) {
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (frequencies[i] == freq) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
for (int j = i; (j < 7); j++) {
|
||||
frequencies[j] = frequencies[j+1];
|
||||
frequencies[j+1] = 0;
|
||||
volumes[j] = volumes[j+1];
|
||||
volumes[j+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
voices--;
|
||||
if (voices < 0)
|
||||
voices = 0;
|
||||
if (voices == 0) {
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
} else {
|
||||
double freq = frequencies[voices - 1];
|
||||
int vol = volumes[voices - 1];
|
||||
if (frequency < freq) {
|
||||
sliding = true;
|
||||
for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
sliding = false;
|
||||
} else if (frequency > freq) {
|
||||
sliding = true;
|
||||
for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
sliding = false;
|
||||
}
|
||||
send_freq(freq, vol);
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
}
|
||||
}
|
||||
|
||||
void init_notes() {
|
||||
// TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (1 << WGM10);
|
||||
// TCCR1B = (1 << COM1B1) | (0 << COM1A0) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
|
||||
|
||||
// DDRC |= (1<<6);
|
||||
|
||||
// TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
// TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
|
||||
|
||||
// ICR3 = 0xFFFF;
|
||||
// OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element
|
||||
|
||||
|
||||
// cli();
|
||||
|
||||
// /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz,
|
||||
// this gives a timer interrupt at 15625Hz. */
|
||||
// TIMSK3 = (1 << OCIE3A);
|
||||
|
||||
// /* clear/reset timer on match */
|
||||
// // TCCR3A = 1<<WGM31 | 0<<WGM30; CTC mode, reset on match
|
||||
// // TCCR3B = 0<<CS32 | 1<<CS31 | 0<<CS30; /* clk, /8 prescaler */
|
||||
|
||||
// TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
// TCCR3B = (0 << WGM33) | (0 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
|
||||
|
||||
|
||||
// TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
|
||||
// TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
|
||||
// // SPCR = 0x50;
|
||||
// // SPSR = 0x01;
|
||||
// DDRC |= (1<<6);
|
||||
// // ICR3 = 0xFFFF;
|
||||
// // OCR3A=80;
|
||||
// PORTC |= (1<<6);
|
||||
|
||||
// sei();
|
||||
}
|
||||
|
||||
// #define highByte(c) ((c >> 8) & 0x00FF)
|
||||
// #define lowByte(c) (c & 0x00FF)
|
||||
|
||||
ISR(TIMER3_COMPA_vect) {
|
||||
|
||||
if (ICR3 > 0 && !sliding) {
|
||||
switch (position) {
|
||||
case 0: {
|
||||
int duty = (((double)F_CPU) / (frequency));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
int duty = (((double)F_CPU) / (frequency*2));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
int duty = (((double)F_CPU) / (frequency*3));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
}
|
||||
position = (position + 1) % 3;
|
||||
}
|
||||
// /* OCR2A has been cleared, per TCCR2A above */
|
||||
// // OCR3A = 127;
|
||||
|
||||
// // pos1 += incr1;
|
||||
// // pos2 += incr2;
|
||||
// // pos3 += incr3;
|
||||
|
||||
// // sample = sinewave[highByte(pos1)] + sinewave[highByte(pos2)] + sinewave[highByte(pos3)];
|
||||
|
||||
// // OCR3A = sample;
|
||||
|
||||
|
||||
// OCR3A=pgm_read_byte(&sinewave[pos1]);
|
||||
// pos1++;
|
||||
// // PORTC &= ~(1<<6);
|
||||
|
||||
// /* buffered, 1x gain, active mode */
|
||||
// // SPDR = highByte(sample) | 0x70;
|
||||
// // while (!(SPSR & (1<<SPIF)));
|
||||
|
||||
// // SPDR = lowByte(sample);
|
||||
// // while (!(SPSR & (1<<SPIF)));
|
||||
|
||||
// // PORTC |= (1<<6);
|
||||
}
|
||||
|
||||
void play_note(double freq, int vol) {
|
||||
|
||||
if (freq > 0) {
|
||||
DDRC |= (1<<6);
|
||||
|
||||
TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
|
||||
|
||||
if (frequency != 0) {
|
||||
if (frequency < freq) {
|
||||
for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
} else if (frequency > freq) {
|
||||
for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
}
|
||||
}
|
||||
send_freq(freq, vol);
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
|
||||
frequencies[voices] = frequency;
|
||||
volumes[voices] = volume;
|
||||
voices++;
|
||||
}
|
||||
// ICR3 = 0xFFFF;
|
||||
// for (int i = 0; i < 10000; i++) {
|
||||
// OCR3A = round((sin(i*freq)*.5)+.5)*0xFFFF;
|
||||
// // _delay_us(50);
|
||||
// }
|
||||
|
||||
// TCCR3A = 0;
|
||||
// TCCR3B = 0;
|
||||
}
|
||||
|
||||
// void note(int x, float length) {
|
||||
// DDRC |= (1<<6);
|
||||
// int t = (int)(440*pow(2,-x/12.0)); // starting note
|
||||
// for (int y = 0; y < length*1000/t; y++) { // note length
|
||||
// PORTC |= (1<<6);
|
||||
// delay_us(t);
|
||||
// PORTC &= ~(1<<6);
|
||||
// delay_us(t);
|
||||
// }
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
||||
|
||||
// void true_note(float x, float y, float length) {
|
||||
// for (uint32_t i = 0; i < length * 50; i++) {
|
||||
// uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8));
|
||||
// for (int u = 0; u < 8; u++) {
|
||||
// if (v & (1 << u) && !(PORTC&(1<<6)))
|
||||
// PORTC |= (1<<6);
|
||||
// else if (PORTC&(1<<6))
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
||||
// }
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* light weight WS2812 lib V2.0b
|
||||
*
|
||||
* Controls WS2811/WS2812/WS2812B RGB-LEDs
|
||||
* Author: Tim (cpldcpu@gmail.com)
|
||||
*
|
||||
* Jan 18th, 2014 v2.0b Initial Version
|
||||
* Nov 29th, 2015 v2.3 Added SK6812RGBW support
|
||||
*
|
||||
* License: GNU GPL v2 (see License.txt)
|
||||
*/
|
||||
|
||||
#include "light_ws2812.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "debug.h"
|
||||
|
||||
// Setleds for standard RGB
|
||||
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds)
|
||||
{
|
||||
ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
|
||||
}
|
||||
|
||||
void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask)
|
||||
{
|
||||
ws2812_DDRREG |= pinmask; // Enable DDR
|
||||
ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask);
|
||||
_delay_us(50);
|
||||
}
|
||||
|
||||
// Setleds for SK6812RGBW
|
||||
void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
|
||||
{
|
||||
ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
|
||||
ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(ws2812_pin));
|
||||
_delay_us(80);
|
||||
}
|
||||
|
||||
void ws2812_sendarray(uint8_t *data,uint16_t datlen)
|
||||
{
|
||||
ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin));
|
||||
}
|
||||
|
||||
/*
|
||||
This routine writes an array of bytes with RGB values to the Dataout pin
|
||||
using the fast 800kHz clockless WS2811/2812 protocol.
|
||||
*/
|
||||
|
||||
// Timing in ns
|
||||
#define w_zeropulse 350
|
||||
#define w_onepulse 900
|
||||
#define w_totalperiod 1250
|
||||
|
||||
// Fixed cycles used by the inner loop
|
||||
#define w_fixedlow 2
|
||||
#define w_fixedhigh 4
|
||||
#define w_fixedtotal 8
|
||||
|
||||
// Insert NOPs to match the timing, if possible
|
||||
#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000)
|
||||
#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000)
|
||||
#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000)
|
||||
|
||||
// w1 - nops between rising edge and falling edge - low
|
||||
#define w1 (w_zerocycles-w_fixedlow)
|
||||
// w2 nops between fe low and fe high
|
||||
#define w2 (w_onecycles-w_fixedhigh-w1)
|
||||
// w3 nops to complete loop
|
||||
#define w3 (w_totalcycles-w_fixedtotal-w1-w2)
|
||||
|
||||
#if w1>0
|
||||
#define w1_nops w1
|
||||
#else
|
||||
#define w1_nops 0
|
||||
#endif
|
||||
|
||||
// The only critical timing parameter is the minimum pulse length of the "0"
|
||||
// Warn or throw error if this timing can not be met with current F_CPU settings.
|
||||
#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
|
||||
#if w_lowtime>550
|
||||
#error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
|
||||
#elif w_lowtime>450
|
||||
#warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
|
||||
#warning "Please consider a higher clockspeed, if possible"
|
||||
#endif
|
||||
|
||||
#if w2>0
|
||||
#define w2_nops w2
|
||||
#else
|
||||
#define w2_nops 0
|
||||
#endif
|
||||
|
||||
#if w3>0
|
||||
#define w3_nops w3
|
||||
#else
|
||||
#define w3_nops 0
|
||||
#endif
|
||||
|
||||
#define w_nop1 "nop \n\t"
|
||||
#define w_nop2 "rjmp .+0 \n\t"
|
||||
#define w_nop4 w_nop2 w_nop2
|
||||
#define w_nop8 w_nop4 w_nop4
|
||||
#define w_nop16 w_nop8 w_nop8
|
||||
|
||||
void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
|
||||
{
|
||||
uint8_t curbyte,ctr,masklo;
|
||||
uint8_t sreg_prev;
|
||||
|
||||
masklo =~maskhi&ws2812_PORTREG;
|
||||
maskhi |= ws2812_PORTREG;
|
||||
sreg_prev=SREG;
|
||||
cli();
|
||||
|
||||
while (datlen--) {
|
||||
curbyte=*data++;
|
||||
|
||||
asm volatile(
|
||||
" ldi %0,8 \n\t"
|
||||
"loop%=: \n\t"
|
||||
" out %2,%3 \n\t" // '1' [01] '0' [01] - re
|
||||
#if (w1_nops&1)
|
||||
w_nop1
|
||||
#endif
|
||||
#if (w1_nops&2)
|
||||
w_nop2
|
||||
#endif
|
||||
#if (w1_nops&4)
|
||||
w_nop4
|
||||
#endif
|
||||
#if (w1_nops&8)
|
||||
w_nop8
|
||||
#endif
|
||||
#if (w1_nops&16)
|
||||
w_nop16
|
||||
#endif
|
||||
" sbrs %1,7 \n\t" // '1' [03] '0' [02]
|
||||
" out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low
|
||||
" lsl %1 \n\t" // '1' [04] '0' [04]
|
||||
#if (w2_nops&1)
|
||||
w_nop1
|
||||
#endif
|
||||
#if (w2_nops&2)
|
||||
w_nop2
|
||||
#endif
|
||||
#if (w2_nops&4)
|
||||
w_nop4
|
||||
#endif
|
||||
#if (w2_nops&8)
|
||||
w_nop8
|
||||
#endif
|
||||
#if (w2_nops&16)
|
||||
w_nop16
|
||||
#endif
|
||||
" out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high
|
||||
#if (w3_nops&1)
|
||||
w_nop1
|
||||
#endif
|
||||
#if (w3_nops&2)
|
||||
w_nop2
|
||||
#endif
|
||||
#if (w3_nops&4)
|
||||
w_nop4
|
||||
#endif
|
||||
#if (w3_nops&8)
|
||||
w_nop8
|
||||
#endif
|
||||
#if (w3_nops&16)
|
||||
w_nop16
|
||||
#endif
|
||||
|
||||
" dec %0 \n\t" // '1' [+2] '0' [+2]
|
||||
" brne loop%=\n\t" // '1' [+3] '0' [+4]
|
||||
: "=&d" (ctr)
|
||||
: "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo)
|
||||
);
|
||||
}
|
||||
|
||||
SREG=sreg_prev;
|
||||
}
|
@ -0,0 +1,505 @@
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "progmem.h"
|
||||
#include "timer.h"
|
||||
#include "rgblight.h"
|
||||
#include "debug.h"
|
||||
|
||||
const uint8_t DIM_CURVE[] PROGMEM = {
|
||||
0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||
8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15,
|
||||
15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20,
|
||||
20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
|
||||
27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35,
|
||||
36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47,
|
||||
48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
|
||||
63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82,
|
||||
83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109,
|
||||
110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144,
|
||||
146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190,
|
||||
193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255,
|
||||
};
|
||||
const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,100,97,93,90,88,85,82,79,76,73,70,67,65,62,59,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23,21,20,18,17,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0};
|
||||
const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
|
||||
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
|
||||
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
|
||||
rgblight_config_t rgblight_config;
|
||||
rgblight_config_t inmem_config;
|
||||
struct cRGB led[RGBLED_NUM];
|
||||
uint8_t rgblight_inited = 0;
|
||||
|
||||
|
||||
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
|
||||
/* convert hue, saturation and brightness ( HSB/HSV ) to RGB
|
||||
The DIM_CURVE is used only on brightness/value and on saturation (inverted).
|
||||
This looks the most natural.
|
||||
*/
|
||||
uint8_t r, g, b;
|
||||
|
||||
val = pgm_read_byte(&DIM_CURVE[val]);
|
||||
sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]);
|
||||
|
||||
uint8_t base;
|
||||
|
||||
if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
|
||||
r = val;
|
||||
g = val;
|
||||
b = val;
|
||||
} else {
|
||||
base = ((255 - sat) * val) >> 8;
|
||||
|
||||
switch (hue / 60) {
|
||||
case 0:
|
||||
r = val;
|
||||
g = (((val - base)*hue) / 60) + base;
|
||||
b = base;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
r = (((val - base)*(60 - (hue % 60))) / 60) + base;
|
||||
g = val;
|
||||
b = base;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = base;
|
||||
g = val;
|
||||
b = (((val - base)*(hue % 60)) / 60) + base;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r = base;
|
||||
g = (((val - base)*(60 - (hue % 60))) / 60) + base;
|
||||
b = val;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r = (((val - base)*(hue % 60)) / 60) + base;
|
||||
g = base;
|
||||
b = val;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
r = val;
|
||||
g = base;
|
||||
b = (((val - base)*(60 - (hue % 60))) / 60) + base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setrgb(r,g,b, led1);
|
||||
}
|
||||
|
||||
void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) {
|
||||
(*led1).r = r;
|
||||
(*led1).g = g;
|
||||
(*led1).b = b;
|
||||
}
|
||||
|
||||
|
||||
uint32_t eeconfig_read_rgblight(void) {
|
||||
return eeprom_read_dword(EECONFIG_RGBLIGHT);
|
||||
}
|
||||
void eeconfig_write_rgblight(uint32_t val) {
|
||||
eeprom_write_dword(EECONFIG_RGBLIGHT, val);
|
||||
}
|
||||
void eeconfig_write_rgblight_default(void) {
|
||||
dprintf("eeconfig_write_rgblight_default\n");
|
||||
rgblight_config.enable = 1;
|
||||
rgblight_config.mode = 1;
|
||||
rgblight_config.hue = 200;
|
||||
rgblight_config.sat = 204;
|
||||
rgblight_config.val = 204;
|
||||
eeconfig_write_rgblight(rgblight_config.raw);
|
||||
}
|
||||
void eeconfig_debug_rgblight(void) {
|
||||
dprintf("rgblight_config eprom\n");
|
||||
dprintf("rgblight_config.enable = %d\n", rgblight_config.enable);
|
||||
dprintf("rghlight_config.mode = %d\n", rgblight_config.mode);
|
||||
dprintf("rgblight_config.hue = %d\n", rgblight_config.hue);
|
||||
dprintf("rgblight_config.sat = %d\n", rgblight_config.sat);
|
||||
dprintf("rgblight_config.val = %d\n", rgblight_config.val);
|
||||
}
|
||||
|
||||
void rgblight_init(void) {
|
||||
debug_enable = 1; // Debug ON!
|
||||
dprintf("rgblight_init called.\n");
|
||||
rgblight_inited = 1;
|
||||
dprintf("rgblight_init start!\n");
|
||||
if (!eeconfig_is_enabled()) {
|
||||
dprintf("rgblight_init eeconfig is not enabled.\n");
|
||||
eeconfig_init();
|
||||
eeconfig_write_rgblight_default();
|
||||
}
|
||||
rgblight_config.raw = eeconfig_read_rgblight();
|
||||
if (!rgblight_config.mode) {
|
||||
dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n");
|
||||
eeconfig_write_rgblight_default();
|
||||
rgblight_config.raw = eeconfig_read_rgblight();
|
||||
}
|
||||
eeconfig_debug_rgblight(); // display current eeprom values
|
||||
|
||||
rgblight_timer_init(); // setup the timer
|
||||
|
||||
if (rgblight_config.enable) {
|
||||
rgblight_mode(rgblight_config.mode);
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_increase(void) {
|
||||
uint8_t mode;
|
||||
if (rgblight_config.mode < RGBLIGHT_MODES) {
|
||||
mode = rgblight_config.mode + 1;
|
||||
}
|
||||
rgblight_mode(mode);
|
||||
}
|
||||
|
||||
void rgblight_decrease(void) {
|
||||
uint8_t mode;
|
||||
if (rgblight_config.mode > 1) { //mode will never < 1, if mode is less than 1, eeprom need to be initialized.
|
||||
mode = rgblight_config.mode-1;
|
||||
}
|
||||
rgblight_mode(mode);
|
||||
}
|
||||
|
||||
void rgblight_step(void) {
|
||||
uint8_t mode;
|
||||
mode = rgblight_config.mode + 1;
|
||||
if (mode > RGBLIGHT_MODES) {
|
||||
mode = 1;
|
||||
}
|
||||
rgblight_mode(mode);
|
||||
}
|
||||
|
||||
void rgblight_mode(uint8_t mode) {
|
||||
if (!rgblight_config.enable) {
|
||||
return;
|
||||
}
|
||||
if (mode<1) {
|
||||
rgblight_config.mode = 1;
|
||||
} else if (mode > RGBLIGHT_MODES) {
|
||||
rgblight_config.mode = RGBLIGHT_MODES;
|
||||
} else {
|
||||
rgblight_config.mode = mode;
|
||||
}
|
||||
eeconfig_write_rgblight(rgblight_config.raw);
|
||||
dprintf("rgblight mode: %u\n", rgblight_config.mode);
|
||||
if (rgblight_config.mode == 1) {
|
||||
rgblight_timer_disable();
|
||||
} else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) {
|
||||
// MODE 2-5, breathing
|
||||
// MODE 6-8, rainbow mood
|
||||
// MODE 9-14, rainbow swirl
|
||||
// MODE 15-20, snake
|
||||
// MODE 21-23, knight
|
||||
rgblight_timer_enable();
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
|
||||
void rgblight_toggle(void) {
|
||||
rgblight_config.enable ^= 1;
|
||||
eeconfig_write_rgblight(rgblight_config.raw);
|
||||
dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
if (rgblight_config.enable) {
|
||||
rgblight_mode(rgblight_config.mode);
|
||||
} else {
|
||||
rgblight_timer_disable();
|
||||
_delay_ms(50);
|
||||
rgblight_set();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rgblight_increase_hue(void){
|
||||
uint16_t hue;
|
||||
hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360;
|
||||
rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
void rgblight_decrease_hue(void){
|
||||
uint16_t hue;
|
||||
if (rgblight_config.hue-RGBLIGHT_HUE_STEP <0 ) {
|
||||
hue = (rgblight_config.hue+360-RGBLIGHT_HUE_STEP) % 360;
|
||||
} else {
|
||||
hue = (rgblight_config.hue-RGBLIGHT_HUE_STEP) % 360;
|
||||
}
|
||||
rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
void rgblight_increase_sat(void) {
|
||||
uint8_t sat;
|
||||
if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) {
|
||||
sat = 255;
|
||||
} else {
|
||||
sat = rgblight_config.sat+RGBLIGHT_SAT_STEP;
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val);
|
||||
}
|
||||
void rgblight_decrease_sat(void){
|
||||
uint8_t sat;
|
||||
if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) {
|
||||
sat = 0;
|
||||
} else {
|
||||
sat = rgblight_config.sat-RGBLIGHT_SAT_STEP;
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val);
|
||||
}
|
||||
void rgblight_increase_val(void){
|
||||
uint8_t val;
|
||||
if (rgblight_config.val + RGBLIGHT_VAL_STEP > 255) {
|
||||
val = 255;
|
||||
} else {
|
||||
val = rgblight_config.val+RGBLIGHT_VAL_STEP;
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val);
|
||||
}
|
||||
void rgblight_decrease_val(void) {
|
||||
uint8_t val;
|
||||
if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = rgblight_config.val-RGBLIGHT_VAL_STEP;
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val);
|
||||
}
|
||||
|
||||
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val){
|
||||
inmem_config.raw = rgblight_config.raw;
|
||||
if (rgblight_config.enable) {
|
||||
struct cRGB tmp_led;
|
||||
sethsv(hue, sat, val, &tmp_led);
|
||||
inmem_config.hue = hue;
|
||||
inmem_config.sat = sat;
|
||||
inmem_config.val = val;
|
||||
// dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val);
|
||||
rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
|
||||
}
|
||||
}
|
||||
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){
|
||||
if (rgblight_config.enable) {
|
||||
if (rgblight_config.mode == 1) {
|
||||
// same static color
|
||||
rgblight_sethsv_noeeprom(hue, sat, val);
|
||||
} else {
|
||||
// all LEDs in same color
|
||||
if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
|
||||
// breathing mode, ignore the change of val, use in memory value instead
|
||||
val = rgblight_config.val;
|
||||
} else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) {
|
||||
// rainbow mood and rainbow swirl, ignore the change of hue
|
||||
hue = rgblight_config.hue;
|
||||
}
|
||||
}
|
||||
rgblight_config.hue = hue;
|
||||
rgblight_config.sat = sat;
|
||||
rgblight_config.val = val;
|
||||
eeconfig_write_rgblight(rgblight_config.raw);
|
||||
dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b){
|
||||
// dprintf("rgblight set rgb: %u,%u,%u\n", r,g,b);
|
||||
for (uint8_t i=0;i<RGBLED_NUM;i++) {
|
||||
led[i].r = r;
|
||||
led[i].g = g;
|
||||
led[i].b = b;
|
||||
}
|
||||
rgblight_set();
|
||||
|
||||
}
|
||||
|
||||
void rgblight_set(void) {
|
||||
if (rgblight_config.enable) {
|
||||
ws2812_setleds(led, RGBLED_NUM);
|
||||
} else {
|
||||
for (uint8_t i=0;i<RGBLED_NUM;i++) {
|
||||
led[i].r = 0;
|
||||
led[i].g = 0;
|
||||
led[i].b = 0;
|
||||
}
|
||||
ws2812_setleds(led, RGBLED_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
// Animation timer -- AVR Timer3
|
||||
void rgblight_timer_init(void) {
|
||||
static uint8_t rgblight_timer_is_init = 0;
|
||||
if (rgblight_timer_is_init) {
|
||||
return;
|
||||
}
|
||||
rgblight_timer_is_init = 1;
|
||||
/* Timer 3 setup */
|
||||
TCCR3B = _BV(WGM32) //CTC mode OCR3A as TOP
|
||||
| _BV(CS30); //Clock selelct: clk/1
|
||||
/* Set TOP value */
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
OCR3AH = (RGBLED_TIMER_TOP>>8)&0xff;
|
||||
OCR3AL = RGBLED_TIMER_TOP&0xff;
|
||||
SREG = sreg;
|
||||
}
|
||||
void rgblight_timer_enable(void) {
|
||||
TIMSK3 |= _BV(OCIE3A);
|
||||
dprintf("TIMER3 enabled.\n");
|
||||
}
|
||||
void rgblight_timer_disable(void) {
|
||||
TIMSK3 &= ~_BV(OCIE3A);
|
||||
dprintf("TIMER3 disabled.\n");
|
||||
}
|
||||
void rgblight_timer_toggle(void) {
|
||||
TIMSK3 ^= _BV(OCIE3A);
|
||||
dprintf("TIMER3 toggled.\n");
|
||||
}
|
||||
|
||||
ISR(TIMER3_COMPA_vect) {
|
||||
// Mode = 1, static light, do nothing here
|
||||
if (rgblight_config.mode>=2 && rgblight_config.mode<=5) {
|
||||
// mode = 2 to 5, breathing mode
|
||||
rgblight_effect_breathing(rgblight_config.mode-2);
|
||||
|
||||
} else if (rgblight_config.mode>=6 && rgblight_config.mode<=8) {
|
||||
rgblight_effect_rainbow_mood(rgblight_config.mode-6);
|
||||
} else if (rgblight_config.mode>=9 && rgblight_config.mode<=14) {
|
||||
rgblight_effect_rainbow_swirl(rgblight_config.mode-9);
|
||||
} else if (rgblight_config.mode>=15 && rgblight_config.mode<=20) {
|
||||
rgblight_effect_snake(rgblight_config.mode-15);
|
||||
} else if (rgblight_config.mode>=21 && rgblight_config.mode<=23) {
|
||||
rgblight_effect_knight(rgblight_config.mode-21);
|
||||
}
|
||||
}
|
||||
|
||||
// effects
|
||||
void rgblight_effect_breathing(uint8_t interval) {
|
||||
static uint8_t pos = 0;
|
||||
static uint16_t last_timer = 0;
|
||||
|
||||
if (timer_elapsed(last_timer)<pgm_read_byte(&RGBLED_BREATHING_INTERVALS[interval])) return;
|
||||
last_timer = timer_read();
|
||||
|
||||
rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos]));
|
||||
pos = (pos+1) % 256;
|
||||
}
|
||||
|
||||
void rgblight_effect_rainbow_mood(uint8_t interval) {
|
||||
static uint16_t current_hue=0;
|
||||
static uint16_t last_timer = 0;
|
||||
|
||||
if (timer_elapsed(last_timer)<pgm_read_byte(&RGBLED_RAINBOW_MOOD_INTERVALS[interval])) return;
|
||||
last_timer = timer_read();
|
||||
rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val);
|
||||
current_hue = (current_hue+1) % 360;
|
||||
}
|
||||
|
||||
void rgblight_effect_rainbow_swirl(uint8_t interval) {
|
||||
static uint16_t current_hue=0;
|
||||
static uint16_t last_timer = 0;
|
||||
uint16_t hue;
|
||||
uint8_t i;
|
||||
if (timer_elapsed(last_timer)<pgm_read_byte(&RGBLED_RAINBOW_MOOD_INTERVALS[interval/2])) return;
|
||||
last_timer = timer_read();
|
||||
for (i=0; i<RGBLED_NUM; i++) {
|
||||
hue = (360/RGBLED_NUM*i+current_hue)%360;
|
||||
sethsv(hue, rgblight_config.sat, rgblight_config.val, &led[i]);
|
||||
}
|
||||
rgblight_set();
|
||||
|
||||
if (interval % 2) {
|
||||
current_hue = (current_hue+1) % 360;
|
||||
} else {
|
||||
if (current_hue -1 < 0) {
|
||||
current_hue = 359;
|
||||
} else {
|
||||
current_hue = current_hue - 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void rgblight_effect_snake(uint8_t interval) {
|
||||
static uint8_t pos=0;
|
||||
static uint16_t last_timer = 0;
|
||||
uint8_t i,j;
|
||||
int8_t k;
|
||||
int8_t increament = 1;
|
||||
if (interval%2) increament = -1;
|
||||
if (timer_elapsed(last_timer)<pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval/2])) return;
|
||||
last_timer = timer_read();
|
||||
for (i=0;i<RGBLED_NUM;i++) {
|
||||
led[i].r=0;
|
||||
led[i].g=0;
|
||||
led[i].b=0;
|
||||
for (j=0;j<RGBLIGHT_EFFECT_SNAKE_LENGTH;j++) {
|
||||
k = pos+j*increament;
|
||||
if (k<0) k = k+RGBLED_NUM;
|
||||
if (i==k) {
|
||||
sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), &led[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
rgblight_set();
|
||||
if (increament == 1) {
|
||||
if (pos - 1 < 0) {
|
||||
pos = RGBLED_NUM-1;
|
||||
} else {
|
||||
pos -= 1;
|
||||
}
|
||||
} else {
|
||||
pos = (pos+1)%RGBLED_NUM;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rgblight_effect_knight(uint8_t interval) {
|
||||
static int8_t pos=0;
|
||||
static uint16_t last_timer = 0;
|
||||
uint8_t i,j,cur;
|
||||
int8_t k;
|
||||
struct cRGB preled[RGBLED_NUM];
|
||||
static int8_t increament = -1;
|
||||
if (timer_elapsed(last_timer)<pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) return;
|
||||
last_timer = timer_read();
|
||||
for (i=0;i<RGBLED_NUM;i++) {
|
||||
preled[i].r=0;
|
||||
preled[i].g=0;
|
||||
preled[i].b=0;
|
||||
for (j=0;j<RGBLIGHT_EFFECT_KNIGHT_LENGTH;j++) {
|
||||
k = pos+j*increament;
|
||||
if (k<0) k = 0;
|
||||
if (k>=RGBLED_NUM) k=RGBLED_NUM-1;
|
||||
if (i==k) {
|
||||
sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) {
|
||||
for (i=0;i<RGBLED_NUM;i++) {
|
||||
cur = (i+RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
|
||||
led[i].r = preled[cur].r;
|
||||
led[i].g = preled[cur].g;
|
||||
led[i].b = preled[cur].b;
|
||||
}
|
||||
}
|
||||
rgblight_set();
|
||||
if (increament == 1) {
|
||||
if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) {
|
||||
pos = 0- RGBLIGHT_EFFECT_KNIGHT_LENGTH;
|
||||
increament = -1;
|
||||
} else {
|
||||
pos -= 1;
|
||||
}
|
||||
} else {
|
||||
if (pos+1>RGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH) {
|
||||
pos = RGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH-1;
|
||||
increament = 1;
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
#ifndef RGBLIGHT_H
|
||||
#define RGBLIGHT_H
|
||||
|
||||
#ifndef RGBLIGHT_MODES
|
||||
#define RGBLIGHT_MODES 23
|
||||
#endif
|
||||
|
||||
#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH
|
||||
#define RGBLIGHT_EFFECT_SNAKE_LENGTH 7
|
||||
#endif
|
||||
|
||||
#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH
|
||||
#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 7
|
||||
#endif
|
||||
#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET
|
||||
#define RGBLIGHT_EFFECT_KNIGHT_OFFSET 9
|
||||
#endif
|
||||
|
||||
#ifndef RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH
|
||||
#define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4
|
||||
#endif
|
||||
|
||||
#ifndef RGBLIGHT_HUE_STEP
|
||||
#define RGBLIGHT_HUE_STEP 10
|
||||
#endif
|
||||
#ifndef RGBLIGHT_SAT_STEP
|
||||
#define RGBLIGHT_SAT_STEP 17
|
||||
#endif
|
||||
#ifndef RGBLIGHT_VAL_STEP
|
||||
#define RGBLIGHT_VAL_STEP 17
|
||||
#endif
|
||||
|
||||
#define RGBLED_TIMER_TOP F_CPU/(256*64)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "eeconfig.h"
|
||||
#include "light_ws2812.h"
|
||||
|
||||
typedef union {
|
||||
uint32_t raw;
|
||||
struct {
|
||||
bool enable :1;
|
||||
uint8_t mode :6;
|
||||
uint16_t hue :9;
|
||||
uint8_t sat :8;
|
||||
uint8_t val :8;
|
||||
};
|
||||
} rgblight_config_t;
|
||||
|
||||
void rgblight_init(void);
|
||||
void rgblight_increase(void);
|
||||
void rgblight_decrease(void);
|
||||
void rgblight_toggle(void);
|
||||
void rgblight_step(void);
|
||||
void rgblight_mode(uint8_t mode);
|
||||
void rgblight_set(void);
|
||||
void rgblight_increase_hue(void);
|
||||
void rgblight_decrease_hue(void);
|
||||
void rgblight_increase_sat(void);
|
||||
void rgblight_decrease_sat(void);
|
||||
void rgblight_increase_val(void);
|
||||
void rgblight_decrease_val(void);
|
||||
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
|
||||
void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
#define EECONFIG_RGBLIGHT (uint8_t *)7
|
||||
uint32_t eeconfig_read_rgblight(void);
|
||||
void eeconfig_write_rgblight(uint32_t val);
|
||||
void eeconfig_write_rgblight_default(void);
|
||||
void eeconfig_debug_rgblight(void);
|
||||
|
||||
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1);
|
||||
void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1);
|
||||
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
|
||||
|
||||
void rgblight_timer_init(void);
|
||||
void rgblight_timer_enable(void);
|
||||
void rgblight_timer_disable(void);
|
||||
void rgblight_timer_toggle(void);
|
||||
void rgblight_effect_breathing(uint8_t interval);
|
||||
void rgblight_effect_rainbow_mood(uint8_t interval);
|
||||
void rgblight_effect_rainbow_swirl(uint8_t interval);
|
||||
void rgblight_effect_snake(uint8_t interval);
|
||||
void rgblight_effect_knight(uint8_t interval);
|
||||
|
||||
#endif
|
@ -0,0 +1,265 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define SINE_LENGTH 2048
|
||||
|
||||
const uint8_t sinewave[] PROGMEM= //2048 values
|
||||
{
|
||||
0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,
|
||||
0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85,
|
||||
0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88,
|
||||
0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c,
|
||||
0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f,
|
||||
0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92,
|
||||
0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95,
|
||||
0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98,
|
||||
0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b,
|
||||
0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e,
|
||||
0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1,
|
||||
0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4,
|
||||
0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7,
|
||||
0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa,
|
||||
0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad,
|
||||
0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0,
|
||||
0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3,
|
||||
0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6,
|
||||
0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8,
|
||||
0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb,
|
||||
0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe,
|
||||
0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1,
|
||||
0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3,
|
||||
0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6,
|
||||
0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9,
|
||||
0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb,
|
||||
0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce,
|
||||
0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0,
|
||||
0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2,
|
||||
0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5,
|
||||
0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7,
|
||||
0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9,
|
||||
0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc,
|
||||
0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde,
|
||||
0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0,
|
||||
0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2,
|
||||
0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4,
|
||||
0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6,
|
||||
0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8,
|
||||
0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9,
|
||||
0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb,
|
||||
0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed,
|
||||
0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee,
|
||||
0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1,
|
||||
0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3,
|
||||
0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4,
|
||||
0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5,
|
||||
0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,
|
||||
0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
|
||||
0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,
|
||||
0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
|
||||
0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,
|
||||
0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,
|
||||
0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,
|
||||
0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
|
||||
0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
|
||||
0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,
|
||||
0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
|
||||
0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
|
||||
0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb,
|
||||
0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa,
|
||||
0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,
|
||||
0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
|
||||
0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,
|
||||
0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
|
||||
0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5,
|
||||
0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4,
|
||||
0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3,
|
||||
0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,
|
||||
0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef,
|
||||
0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed,
|
||||
0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb,
|
||||
0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea,
|
||||
0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,
|
||||
0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,
|
||||
0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4,
|
||||
0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2,
|
||||
0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0,
|
||||
0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde,
|
||||
0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc,
|
||||
0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda,
|
||||
0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8,
|
||||
0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5,
|
||||
0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3,
|
||||
0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1,
|
||||
0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce,
|
||||
0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc,
|
||||
0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9,
|
||||
0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7,
|
||||
0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4,
|
||||
0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1,
|
||||
0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf,
|
||||
0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc,
|
||||
0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9,
|
||||
0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6,
|
||||
0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4,
|
||||
0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1,
|
||||
0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae,
|
||||
0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab,
|
||||
0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8,
|
||||
0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5,
|
||||
0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2,
|
||||
0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f,
|
||||
0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c,
|
||||
0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99,
|
||||
0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96,
|
||||
0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93,
|
||||
0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f,
|
||||
0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c,
|
||||
0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89,
|
||||
0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86,
|
||||
0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83,
|
||||
0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80,
|
||||
0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,
|
||||
0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a,
|
||||
0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77,
|
||||
0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73,
|
||||
0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70,
|
||||
0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d,
|
||||
0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a,
|
||||
0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67,
|
||||
0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64,
|
||||
0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61,
|
||||
0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e,
|
||||
0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b,
|
||||
0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58,
|
||||
0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55,
|
||||
0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52,
|
||||
0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f,
|
||||
0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c,
|
||||
0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49,
|
||||
0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47,
|
||||
0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44,
|
||||
0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41,
|
||||
0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e,
|
||||
0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c,
|
||||
0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39,
|
||||
0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36,
|
||||
0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34,
|
||||
0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31,
|
||||
0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f,
|
||||
0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d,
|
||||
0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a,
|
||||
0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28,
|
||||
0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26,
|
||||
0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23,
|
||||
0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21,
|
||||
0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f,
|
||||
0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d,
|
||||
0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b,
|
||||
0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19,
|
||||
0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17,
|
||||
0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16,
|
||||
0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14,
|
||||
0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12,
|
||||
0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11,
|
||||
0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf,
|
||||
0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe,
|
||||
0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc,
|
||||
0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb,
|
||||
0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa,
|
||||
0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9,
|
||||
0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
|
||||
0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,
|
||||
0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
|
||||
0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,
|
||||
0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4,
|
||||
0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,
|
||||
0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,
|
||||
0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,
|
||||
0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1,
|
||||
0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
|
||||
0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
|
||||
0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,
|
||||
0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
|
||||
0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
|
||||
0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,
|
||||
0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,
|
||||
0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3,
|
||||
0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4,
|
||||
0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5,
|
||||
0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,
|
||||
0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
|
||||
0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7,
|
||||
0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
|
||||
0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,
|
||||
0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb,
|
||||
0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc,
|
||||
0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd,
|
||||
0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf,
|
||||
0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10,
|
||||
0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12,
|
||||
0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14,
|
||||
0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15,
|
||||
0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17,
|
||||
0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19,
|
||||
0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b,
|
||||
0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d,
|
||||
0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f,
|
||||
0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21,
|
||||
0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23,
|
||||
0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,
|
||||
0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27,
|
||||
0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a,
|
||||
0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,
|
||||
0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,
|
||||
0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31,
|
||||
0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,
|
||||
0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36,
|
||||
0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
|
||||
0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,
|
||||
0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,
|
||||
0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
|
||||
0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,
|
||||
0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,
|
||||
0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49,
|
||||
0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,
|
||||
0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,
|
||||
0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51,
|
||||
0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,
|
||||
0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,
|
||||
0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a,
|
||||
0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,
|
||||
0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,
|
||||
0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,
|
||||
0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,
|
||||
0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69,
|
||||
0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c,
|
||||
0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70,
|
||||
0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73,
|
||||
0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76,
|
||||
0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,
|
||||
0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,
|
||||
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f
|
||||
};
|
Loading…
Reference in New Issue