# Introduction

![](/files/-LFmqxAwBUVE26tbZCGS)

A *mechanical*, *layered*, *programmable*, *ergonomic*, *hackable* [keyboard](http://venabili.sillybytes.net).

Named after *Dors Venabili*, a fictional character from Isaac Asimov's *Foundation* Series of novels. Venabili is a 40% mechanical keyboard with ergonomic keys layout.

Being a fully programmable keyboard, it gives you the ability to create layers of functionality, declare multifunction keys that can operate as both modifiers and normal keys, control the mouse, define macros, and more.

## How to Get One?

Venabili is not a commercial keyboard, you cannot buy neither a fully assembled one nor a DIY kit. Instead, the project provides: hardware designs, circuitry schematics, firmware, and very detailed instructions on how to build your own in the [Building Guide](/building).

The whole project is released under FOSS and CC licences, so you can tweak every aspect of it to adapt it to your needs and liking.

## Features

* Free as in Freedom
  * FOSS hardware and software
* Ergonomic
  * Vertically Staggered
  * Fixed-split
* Programmable
  * Custom keys placement
  * Up to 256 key layers
  * Dual function keys
  * Pre-modified keys
  * Double-shift CapsLock
  * Macros
  * Mouse control
* Hackable

## Lacking features

There are some things that are yet to be implemented, namely:

* Boot keyboard support.- It will probably not work for configuring the BIOS. Moreover, you'll probably have to plug in the keyboard *after* the OS has booted.
* Volume and music control keys
* Windows build support.- In order to build the firmware and customize the keyboard you'll need a \*NIX OS


# Building Guide

Because Venabili is a hand-wired keyboard, you can be creative with the materials you want to use, is it going to be made of wood? Acrylic? Metal? Will it be Cherry MX switches? Zealios? Kailhs? You choose!

## Materials

* 48 Switches (any switches that fit in Cherry MX profile holes will do)
* 48 Key caps
* 48 1N4148 diodes
* 1 STM32F103 MCU (bluepill)
* 1 ST-LINK
* Thin wire
* Case pieces (any material that you can either laser-cut or hand-cut will do)

Both the *"bluepill"* board and the *ST-LINK* programmer can be bought for cheap from online stores.

## Tools

* Soldering Iron
* Tweezers


# Firmware

The firmware that makes Venabili work is actually made of two parts: the *bootloader* and the *main firmware*, where the actual useful stuff is.

When the microcontroller is brand-new, you need to flash both parts on it using special (although very inexpensive) hardware. After that, only new versions of the *main firmware* need to be flashed whenever you change your layers, macros, etc; And the special programming hardware is no longer needed, you can do it pretty easily and quickly with your keyboard plugged in as normal.

Throughout these documents, the process of flashing for the first time with special hardware will be known as *"low level"* flashing. And the process of flashing the main firmware each time you want to change your keyboard's behaviour as *"user level"* flashing.

Because we're still building the keyboard, we're only going to address the first-time-only low level flashing here and let the user level flashing for the [Customizing Guide](/customizing).

## Preparing the software

We're gonna need the latest version of the Venabili's firmware and the compiler/tools to build it and flash it to the controller board.

The process will be described assuming you're on a \*NIX Operating System (Linux, BSDs, Mac OS, etc), this will not work on Windows.

### Tools

#### GCC ARM port

Some package managers will make it available as a set of packages:

* arm-none-eabi-gcc
* arm-none-eabi-bintuils
* arm-none-eabi-newlib

Others will bundle all this in some repository. In Ubuntu, for instance you can get it with:

```
$ sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
$ sudo apt-get update
$ sudo apt-get install gcc-arm-none-eabi
```

#### stlink (Low level flashing software)

For this you can follow its own installation guide here: <https://github.com/texane/stlink#installation>

#### dfu-util (User level flashing software)

This on is available in most package managers. Alternatively refer to the project page: <http://dfu-util.sourceforge.net/>

### Firmware

Either clone the Venabili's code repository from here: <https://github.com/alx741/venabili> or download a ZIP package of it here: <https://github.com/alx741/venabili/archive/master.zip>

The only two directories you care about right now are `bootloader` and `src`.

## Compiling

While in the Venabili source code directory, run:

```
$ cd lib/libopencm3
$ make
$ cd ../../bootloader
$ make
$ cd ../../src
$ make
```

If no errors are reported you're done, if something complains along the way is likely you're tools are not installed properly.

## Preparing the connections

Start by connecting the *ST-LINK* to the bottom pin header of the controller board. Make sure you use the `3.3v` of the *ST-LINK*.

* STM32 Board   <-->   ST-LINK
* GND         <-->     GND
* CLk         <-->    SWDCLK
* IO          <-->    SWDIO
* 3.3         <-->    3.3v

**Warning** (avoiding the magic smoke)

* Do not use the `5v` pin of the *ST-LINK* for this process
* Do not connect the board USB port to anything for this process

![](/files/-LIh3pJw9vXf5Gcgix8f) ![](/files/-LIh3pJyhuEpXOw7h7na)

## Low level flashing

Connect the *ST-LINK* (NOT the controller board) to a USB port on your computer.

While in the Venabili source code directory a, run:

```
$ cd bootloader
$ make burn
$ cd ../src
$ make burn_low
```

If no errors are reported then you're done with the flashing and ready to use the controller board on your keyboard.


# Hardware

Now is when we actually build it: First we're gonna need a case to put the switches on, then we need to solder the switches with some diodes and onto the controller board.

During the building process, always refer to the circuit diagram below. [Here is the PDF version for convenience](https://github.com/alx741/venabili/blob/master/schematics/schematic.pdf)

The labels in the diagram correspond to the white pin labels on the board.

![Circuit Diagram](/files/-LLCWyO7hYoJicSSCdNr)

## Case

The case is made of a 4-piece sandwich of the material of your choice.

![Case pieces](/files/-LFwqsnESzSkocJ2b7Vh)

Here are the pieces as real scale PDFs, ready to take to the laser cutter for instance.

* [Top](https://github.com/alx741/venabili-doc/tree/b35edb994452bbed39f357d2896e9922f7e0b897/case/top.pdf)
* [Middle 1](https://github.com/alx741/venabili-doc/tree/b35edb994452bbed39f357d2896e9922f7e0b897/case/middle1.pdf)
* [Middle 2](https://github.com/alx741/venabili-doc/tree/b35edb994452bbed39f357d2896e9922f7e0b897/case/middle2.pdf)
* [Bottom](https://github.com/alx741/venabili-doc/tree/b35edb994452bbed39f357d2896e9922f7e0b897/case/bottom.pdf)

### Customizing

The default design is a 24deg fixed-split, 3mm vertically staggered layout; You can change it at will by modifying the [SVG vector design](https://github.com/alx741/venabili/blob/master/design/layout.svg).

## MCU preparation

The *BluePill* board has this yellow pin headers that will get in the way, so start by desoldering those:

![](/files/-LFwqsnIWyJDqC7vhoCC) ![](/files/-LFwqsnKzr2bce2j6ewl)

Now put a solder bridge between the upper pads to make up for the removed jumper caps:

![](/files/-LFwqsnM0e6vAJ9CalQQ)

Desolder the reset push button as well, then solder the USB connector (follow the circuit diagram), and finally solder a *1.8k* resistor between the `A12` and `3.3V` pads (I've used a 1k and 0.8k resistors in series).

![](/files/-LFwqsnO33x9xIFg4-Wm)

## Wiring

Once you have the case pieces ready, put the switches in. It's a good idea to hold them in place with some hot glue, so they don't pop out when replacing key caps.

![](/files/-LFwqsnQYhcUc4FfIfTC) ![](/files/-LFwqsnS_HsizMpRj7x6) ![](/files/-LFwqsnUtHFn8swnuZ1S)

Bend the diodes like this:

![](/files/-LFwqsnW06bVp3M7zFjL)

And use them to connect the switches in columns:

![](/files/-LFwqsnYav24EgvXAFeG) ![](/files/-LFwqsn_gWVz_RWwIHQI) ![](/files/-LFwqsnb1opeTkkKPwkS)

Solder wires to the bottoms of each column like so:

![](/files/-LFwqsnddn3kMwm1LLZi) ![](/files/-LFwqsnfXWmDXzAijQRu)

Now put a 3mm LED in one of the switches, together with a `330 ohm` resistor and make sure to isolate it:

![](/files/-LFwqsnhAv7d6n5wmUv_) ![](/files/-LFwqsnj5Wu4a7mfm6R_)

### MCU wiring

Now is just a matter of following the circuit diagram to solder the right wires on the right pads:

![](/files/-LFwqsnlxGaGQ6HnXAwN) ![](/files/-LFwqsnnV07dqDB5HXzA)

You might want to trim the flashing pin header at the bottom of the board to have an easy fit inside the case, but don't get rid of them completely as you might need them in the future if you manage to brick the bootloader when hacking it :)

## Key caps

Use screws to attach the bottom cover; using glue is discouraged as you might need to get inside in the future without destroying the case in the process.

Put some nice key caps on, and you're ready to type!

![](/files/-LYwaj34pFXckDQVmrj_)


# Customizing Guide

The common things that you want to do, without going as far has hacking Venabili's code, is define your own key layers and macros.

Changing what the keyboard does is quick and simple, you won't even need to unplug it, and making small incremental tweaks every time you think of a way to make your typing a little bit faster and/or comfortable is highly encouraged!

The process goes like so:

* Edit the `venabili.c` with your own layers and macros
* Recompile the firmware
* Enter flash mode
* Flash the new firmware


# Compiling & Flashing

When you're happy with your new `venabili.c`, compile it with:

```
$ cd src
$ make
```

Notice that some checks will run and let you know if you forgot to put some important keys in your layers.

If everything went right and no errors are displayed, you may now flash the new firmware into your keyboard. To do so, the keyboard needs to be in *flash mode* first, there are two ways:

1. Plug in the keyboard while pressing the top left key (the keyboard needs to

   be unplugged beforehand)
2. Use the *flash mode key* (`c_flash_mode`) if it's already declared in your

   layers (No need to unplug the keyboard)

Then flash the new firmware with:

```
$ cd src
$ make burn
```

When the process is finished your keyboard will be back online and ready to use.


# Layers

Venabili uses a nested layers mechanism to not only give you access to all the keys that you might need, but also to distribute them in a way that is the most comfortable and fast to reach, even if means duplicating keys just to have them in different places for different situations.

## Defining layers

Layers are defined in the `venabili.c` file as 4x12 matrices of keys that match the position of the physical switches.

Take a look at the default layer:

```c
Layer l0 =
{
    { k_tab, k_q, k_w, k_e, k_r, k_t, k_y, k_u, k_i, k_o, k_p, k_hyphen},
    { HLctrl(k_escape), k_a, k_s, k_d, k_f, k_g, k_h, k_j, k_k, k_l, k_semicolon, HRctrl(k_enter)},
    { m_lshift, k_z, k_x, k_c, k_v, k_b, k_n, k_m, k_comma, k_dot, k_slash, m_rshift},
    { m_lsuper, m_lalt, m_ralt, LS(3, k_empty), LS(2, k_empty), LS(1, k_space), k_space, LS(2, k_empty), LS(4, k_empty), m_ralt, m_lalt, m_rsuper},
};
```

Each row is inside braces `{}` and each key is separated by a comma `,`, these are just normal *C* arrays.

After you've defined some layers you need to register them with the `add_layer(name)` function like so:

```c
// Layer l0 = ...
// Layer l1 = ...
// Layer numbers = ...
// Layer symbols = ...

add_layer(l0);
add_layer(l1);
add_layer(numbers);
add_layer(symbols);
```

Each layer you register will acquire an identifier that increments from 0.

Once you're happy with your layers, make sure to set the `N_LAYERS` number in the `config.h` file to match the number of layers you have registered.

## Switching between layers

To allow you to switch between layers you need to include `Layer Selection` keys `LS(id, key)`, where *id* is the layer number that key will take you to and *key* is the normal key to be triggered if you press and release the key without using any of the keys *inside* that layer. A great example of this is:

```c
LS(1, k_space)
```

This key will put a space if you press it and release it quickly, but will let you access layer number 1 (that is the second layer) if you hold it and press some other key at the same time.

Notice that if the same physical key that has the `Layer Selection` key in one layer, has some other key in the upper layer, that key will also be pressed as soon as you enter the layer. To avoid this have that key to be `k_empty` in the upper layer like so:

```c
Layer l0 =
{
    { LS(1, k_space), ... },
    // ...
};

Layer l1 =
{
    { k_empty, ... },
    // ...
};
```

### Locking

When you enter a layer by holding its `Layer Selection` key, you will go back to the default layer (the very first layer that you declared) as soon as you release it. There are however some use case scenarios where you might want to stay in a layer without having to hold any key.

For instance, this is useful if you define a layer that has hotkeys for some sort of editing software or video game in the left half of the keyboard, allowing you to use any keyboard shortcut you might need while holding the mouse with your right hand.

You can achieve this by having a `Layer Lock` key *inside* the target layer:

```c
Layer l1 =
{
    { c_layer_lock, ... },
    // ...
};
```

This way if you hold your `LS(1, k_space)` key in layer 0 and then press the your `c_layer_lock` key that is inside layer 1 the keyboard will stay in layer 1 when you release all the keys.

Now you can use any other key you have in layer 1 without having to keep holding some other key at the same time.

To release the lock just press your `Layer Lock` key once again and you'll be back to the default layer.


# Macros

Venabili lets you define keys that automatically press multiple keys in sequence for you (a "macro"). This could be used to perform a sequence of key presses that you normally do over and over again by hand, or to store commonly used text strings like passwords, phone number, email addresses, etc.

## Defining macros

Macros are defined in the `venabili.c` file as arrays of keys.

Take a look at this macro that will do `Ctrl + c` and `Ctrl + v` on a single keystroke:

```c
Macro m1 = { Rctrl(k_c), Rctrl(k_v), k_empty };
```

After you've defined some macros you need to register them with the `add_macro(name)` function like so:

```c
// Macro m0 = ...
// Macro m1 = ...

add_macro(m0);
add_macro(m1);
```

If you need a macro that only consists of text strings, use the `add_string_macro` instead:

```c
add_string_macro("email@example.com");
add_string_macro("08764208");
add_string_macro("Some street in some avenue");
add_string_macro("This@is_n0t_a_pa$$word");
```

Each macro you register will acquire an identifier that increments from 0.

Once you're happy with your macros, make sure to set the `N_MACROS` number in the `config.h` file to match the number of macros you have registered.

## Using macros

In order to trigger macros, use the `MACRO(id)` key in your layers, where *id* is the number of the macro you want to use.


# Keys

The `keys.h` file contains an exhaustive list of the keys you have available for use in your layers. You could also take a look at the [Available Keys](/available_keys) section.

As you may have notice, normal keys have a `k_` prefix, there is no much about them other than the fact that you have independent keys for lower and upper case letters, and other symbols that would require to *shift* in a normal keyboard, here you can have them as a key on their own, no *shift*ing needed.

If you want to leave a key unused, make it a `k_empty`, a special key that does nothing.

## Modifiers

Modifiers like *Control*, *Shift*, *Alt*, *Super* have a `m_` prefix and act like modifiers in a normal keyboard: you hold it and then press some other key to *modify* it.

### Pre-modified

Venabili lets you define keys that are already *modified*, for instance this key:

```c
Lctrl(k_c);
```

Will trigger `Ctrl + c` in a single key press.

### Multifunction modifiers

We can go further still and define keys that will act as a modifier when held, but be a normal key when pressed and release quickly.

Take for instance the key:

```c
HLctrl(k_escape);
```

Will trigger `escape` when tapped (pressed and released quickly) but will behave as `Ctrl` when you hold it and press some other key at the same time. This one is particularly useful.

## Mouse control

There are 5 different mouse buttons prefixed by `m_click_`. The common ones being:

* 1 = left click
* 2 = right click
* 3 = middle click

In order to move the pointer use the following keys:

* MU(speed): Up
* MD(speed): Down
* MR(speed): Right
* ML(speed): Left
* MWU(speed): Wheel up
* MWD(speed): Wheel down

Where `speed` is number between 0 and 15 to describe how fast the pointer should move.

## Layers

As described in the [Layers](/customizing/layers) section, the `Layer Selection` key (`LS(id, key)`) lets you switch to the *id* layer when held or trigger *key* when tapped.

The `Layer Lock` key (`c_layer_lock`) allows you to lock in the current layer and release the lock when pressed again.

## Macros

As described in the [Macros](/customizing/macros) section, the `Macro Selection` key (`MACRO(id)`) lets you trigger the *id* macro.

## Special

If you want to be able to enter *Flash mode* without having to unplug the keyboard, make sure to include the `c_flash_mode` key in one of your layers. When pressed the keyboard will enter *Flash mode* and be ready to receive a firmware update.


# Configuration

The `config.h` file lets you specify how many layers and macros are you using:

* N\_LAYERS
* N\_MACROS

But there are some other things you can change to tweak the behaviour of the keyboard:

* MAX\_MACRO\_LENGTH: Maximum length for macros (in characters)
* TAP\_TIMEOUT\_MS: How many milliseconds a double-function key should be held

  before assuming you don't want it to do anything.
* LAYER\_DROPPING\_TIMEOUT\_MS: How many milliseconds to wait after a layer drop

  before start accepting new keys to avoid unintentional pressing of default

  layer keys.
* ENABLE\_DOUBLE\_SHIFT\_CAPS\_LOCK: Pressing both left and right shift keys at the

  same time toggles *Caps Lock*.


# Available Keys

These are the keys at your disposal for defining layers in the `venabili.c` file.

## Layers control keys

Layer `n = 0` is the first (main) layer.

* LS(n): Select `n`th layer (0 <= n < 256)
* c\_layer\_lock
* c\_flash\_mode

## Mouse control keys

### Movement

Valid `speed`s are numbers between `0` and `15`

* MU(speed): Up
* MD(speed): Down
* MR(speed): Right
* ML(speed): Left
* MWU(speed): Wheel up
* MWD(speed): Wheel down

### Clicks

* m\_click\_1
* m\_click\_2
* m\_click\_3
* m\_click\_4
* m\_click\_5

## Macro keys

* MACRO(id): select `id` macro (0 <= id < 26)

## Modifiers

These only send a key press of a modifier key, but will not actually *modify* any Key.

* m\_lctrl
* m\_lshift
* m\_lalt
* m\_lsuper
* m\_rctrl
* m\_rshift
* m\_ralt
* m\_rsuper

### Apply modifiers to a key

e.g. Rctrl(Lshift(k\_a)) = CTRL + SHIFT + a

* Lctrl(key)
* Lshift(key)
* Lalt(key)
* Lsuper(key)
* Rctrl(key)
* Rshift(key)
* Ralt(key)
* Rsuper(key)

### Make a key behave like a modifier when held

e.g. HRshift(k\_a) = 'a' when tapped, RShift when held

* HLctrl(key)
* HLshift(key)
* HLalt(key)
* HLsuper(key)
* HRctrl(key)
* HRshift(key)
* HRalt(key)
* HRsuper(key)

## Normal keys

### Empty key

A key that does nothing

* k\_empty

### Letters

#### Lower case

* k\_a
* k\_b
* k\_c
* k\_d
* k\_e
* k\_f
* k\_g
* k\_h
* k\_i
* k\_j
* k\_k
* k\_l
* k\_m
* k\_n
* k\_o
* k\_p
* k\_q
* k\_r
* k\_s
* k\_t
* k\_u
* k\_v
* k\_w
* k\_x
* k\_y
* k\_z

#### Upper case

* k\_A
* k\_B
* k\_C
* k\_D
* k\_E
* k\_F
* k\_G
* k\_H
* k\_I
* k\_J
* k\_K
* k\_L
* k\_M
* k\_N
* k\_O
* k\_P
* k\_Q
* k\_R
* k\_S
* k\_T
* k\_U
* k\_V
* k\_W
* k\_X
* k\_Y
* k\_Z

### Numbers

* k\_0
* k\_1
* k\_2
* k\_3
* k\_4
* k\_5
* k\_6
* k\_7
* k\_8
* k\_9

### Symbols

* k\_back\_quote
* k\_double\_quote
* k\_single\_quote
* k\_tilde
* k\_bang
* k\_at
* k\_hash
* k\_dollar
* k\_percent
* k\_caret
* k\_ampersand
* k\_asterisk
* k\_hyphen
* k\_under\_score
* k\_equal
* k\_plus
* k\_semicolon
* k\_colon
* k\_dot
* k\_comma
* k\_slash
* k\_question\_mark
* k\_backslash
* k\_pipe
* k\_greater\_than
* k\_less\_than
* k\_open\_paren
* k\_close\_paren
* k\_open\_bracket
* k\_close\_bracket
* k\_open\_brace
* k\_close\_brace

### Non-printables

* k\_print\_screen
* k\_scroll\_lock
* k\_pause
* k\_insert
* k\_delete
* k\_home
* k\_end
* k\_pageup
* k\_pagedown
* k\_arrow\_up
* k\_arrow\_down
* k\_arrow\_left
* k\_arrow\_right
* k\_menu
* k\_select
* K\_stop
* k\_enter
* k\_escape
* k\_backspace
* k\_tab
* k\_space
* k\_caps
* k\_undo
* k\_cut
* k\_copy
* k\_paste
* k\_find
* k\_mute
* k\_vol\_up
* k\_vol\_down
* k\_again
* k\_f1
* k\_f2
* k\_f3
* k\_f4
* k\_f5
* k\_f6
* k\_f7
* k\_f8
* k\_f9
* k\_f10
* k\_f11
* k\_f12
* k\_f13
* k\_f14
* k\_f15
* k\_f16
* k\_f17
* k\_f18
* k\_f19
* k\_f20
* k\_f21
* k\_f22
* k\_f23
* k\_f24


