2016-05-09 14:05:08 +00:00
keybrd Library Developer's Guide
================================
2016-05-11 18:46:53 +00:00
This guide if for maintaining and writing new classes for the keybrd library and its extension libraries.
2016-07-18 02:26:00 +00:00
The most common reason for adding new classes are:
* I/O expander classes
2016-05-09 14:05:08 +00:00
* custom layer schemes for multi-layer keyboards
* experimental features
2016-07-18 02:26:00 +00:00
Who this guide is for
---------------------
2016-05-09 19:41:29 +00:00
This guide is for the maintainers and developers of the keybrd library and it's extensions.
2016-07-22 08:11:38 +00:00
It is assumed the reader is familiar with the C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum.
2016-07-18 02:26:00 +00:00
Row, Scanner, and Debouncer classes use bit manipulation.
2016-05-09 14:05:08 +00:00
2016-07-18 02:26:00 +00:00
Class inheritance diagrams
--------------------------
2016-07-04 03:26:38 +00:00
Keybrd library class inheritance diagram
```
2016-09-12 06:28:27 +00:00
Row
2016-07-07 21:31:34 +00:00
2016-09-12 06:28:27 +00:00
___ ScannerInterface ___
/ | \
Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO
2016-05-09 14:05:08 +00:00
2016-07-04 23:29:24 +00:00
2016-10-31 01:46:23 +00:00
PortWriteInterface
/ \
PortInterface Port_ShiftRegs (Port class for MOSI shift registers)
2016-09-25 03:03:08 +00:00
/ \
Port_PCA9655E Port_MCP23S17 (one Port class for each IOE type)
2016-05-09 14:05:08 +00:00
2016-09-25 03:03:08 +00:00
LEDInterface
2016-07-18 02:26:00 +00:00
/ \
2016-09-28 19:56:10 +00:00
LED_uC LED_Port
2016-05-09 14:05:08 +00:00
2016-06-11 02:12:56 +00:00
DebouncerInterface
|
2016-07-18 02:26:00 +00:00
Debouncer_Samples
2016-06-11 02:12:56 +00:00
2016-07-05 21:45:58 +00:00
ScanDelay
2016-06-11 02:12:56 +00:00
2016-05-28 21:16:32 +00:00
LayerStateInterface
2016-06-11 02:12:56 +00:00
|
2016-05-28 21:16:32 +00:00
LayerState
2016-05-09 14:05:08 +00:00
2016-09-17 21:47:37 +00:00
Key
|____
2016-05-09 14:05:08 +00:00
| \
2016-09-20 02:40:25 +00:00
| Key_LayeredKeysBase
| \____________________
| / \
| Key_LayeredKeys Key_LayeredKeys1
2016-05-09 14:05:08 +00:00
|
|___________________________
| \ \
2016-09-17 18:31:14 +00:00
| Key_LayeredScScBase Key_LayeredCodeScBase
2016-05-09 14:05:08 +00:00
| | |
2016-09-17 18:31:14 +00:00
| Key_LayeredScSc Key_LayeredCodeSc
2016-05-09 14:05:08 +00:00
|
2016-09-17 18:31:14 +00:00
Code
2016-09-17 21:47:37 +00:00
|_____________________
| \ \
| Code_LayerLock Code_LayerHold
|
2016-09-17 18:31:14 +00:00
\________________________________________________________
2016-09-01 02:29:59 +00:00
\ \ \ \ \
Code_Sc Code_Shift Code_AutoShift Code_LEDLock Code_Null
2016-07-18 02:26:00 +00:00
/ \
Code_ScS Code_ScNS
2016-05-09 14:05:08 +00:00
```
2016-07-18 02:26:00 +00:00
Dependency diagrams
-------------------
2016-05-09 14:05:08 +00:00
2016-07-18 02:26:00 +00:00
Dependency diagram of example single-layer keyboard with LEDs
2016-05-09 14:05:08 +00:00
```
2016-09-17 05:45:12 +00:00
____ Row ______
/ | \
2016-09-17 21:47:37 +00:00
Scanner_uC Debouncer Key ___
2016-09-17 05:45:12 +00:00
| | \
readPins Code Code_LEDLock
|
LED_PinNumber
2016-06-11 02:12:56 +00:00
```
2016-07-18 02:26:00 +00:00
Dependency diagram of example multi-layer keyboard with layer LEDs
2016-06-11 02:12:56 +00:00
```
2016-09-17 21:47:37 +00:00
LayerStates
___________ Row ________________ /__ | \
/ / \ / \ | \
Scanner_uC Debouncer Key_LayeredKeys / Code_Layer LED_PinNumber
| \ /
readPins Code
2016-06-11 02:12:56 +00:00
```
2016-09-17 05:45:12 +00:00
Dependency diagram of example shift registers Row
2016-07-04 03:26:38 +00:00
```
2016-09-17 05:45:12 +00:00
_______ Row _______
/ | \
2016-09-17 21:47:37 +00:00
RowScanner_ShiftRegsPISO Debouncer Key
2016-09-17 05:45:12 +00:00
|
Code
2016-07-04 03:26:38 +00:00
```
2016-09-17 05:45:12 +00:00
Dependency diagram of example I/O expander matrix with LEDs
2016-06-11 02:12:56 +00:00
```
2016-09-17 21:47:37 +00:00
_________ Row ________
/ \ \
__ Scanner_IOE __ Debouncer Key
2016-09-17 05:45:12 +00:00
/ | \ / \
strobePin PortWrite PortRead Code Code_LEDLock
| \ / \ |
2016-09-28 19:56:10 +00:00
| PortIOE readPins LED_Port
2016-09-17 05:45:12 +00:00
\___________________________/ \
pin
2016-05-09 14:05:08 +00:00
```
2016-07-18 02:26:00 +00:00
Class naming conventions
------------------------
2016-05-09 14:05:08 +00:00
Class names start with upper case letter.
Most derived-class names start with the base class name followed by "_" and a name e.g.
```
Code
|
2016-05-11 18:46:53 +00:00
Code_LayerLock
2016-05-09 14:05:08 +00:00
```
This convention leads to class names that convey information about the classes inheritance.
2016-05-09 19:41:29 +00:00
Underscore delineates base class name and sub-class name. Capital letters delineate words.
2016-05-09 14:05:08 +00:00
2016-09-01 07:08:52 +00:00
Interface class names end with "Interface".
2016-09-25 04:27:06 +00:00
Except for Key, to reduce clutter because sketches define so many Key[] arrays.
2016-09-01 07:08:52 +00:00
2016-07-18 02:26:00 +00:00
Layer-class naming conventions
------------------------------
2016-07-22 08:11:38 +00:00
Layer classes are explained in [tutorial_3a_multi-layer_keyboard.md ](../tutorials/tutorial_3a_multi-layer_keyboard.md ).
2016-05-28 18:37:40 +00:00
*Code_Layer* class names are concatenations of "Code_", "Layer" or layer name, and persistence.
Example persistences are:
* "Lock" - layer remains active after the layer key is released
* "Hold" - layer is active for as long as layer key is held down
Example Code_Layer class names:
* Code_LayerHold
* Code_LayerLock
2016-05-28 21:16:32 +00:00
*LayerState* class names start with "LayerState" and end with a descriptive name.
Example LayerState class names:
* LayerState - basic LayerState class in keybrd library
* LayerState_DH - main LayerState for the keybrd_DH library
* LayerState_MF - LayerState for Mouse Function sub-layers in the keybrd_DH library
2016-05-28 18:37:40 +00:00
2016-09-17 18:31:14 +00:00
*Key_Layered* class names start with "Key_Layered" and end with a descriptive name.
Example Key_Layered class names:
* Key_LayeredScSc
2016-09-18 06:42:21 +00:00
* Key_LayeredKeys
2016-05-28 18:37:40 +00:00
2016-07-18 02:26:00 +00:00
Style guide
-----------
2016-05-09 14:05:08 +00:00
Following the style guide makes it easier for the next programmer to understand your code.
2016-07-14 23:28:16 +00:00
* For class names, see above section "Class naming conventions".
* Member names use camelCase starting with lowercase letter.
2016-05-09 14:05:08 +00:00
* Use constants rather than macros, except for header guards.
2016-07-15 05:15:38 +00:00
* Global const names and static const names use ALL_CAPS_WITH_UNDERSCORE.
2016-07-14 23:28:16 +00:00
* Header guards have _H suffix e.g. #ifndef FILE_NAME_H
* Pointer names are prefixed with "ptr" e.g. ptrRow = &row;
2016-07-18 02:26:00 +00:00
* Arrays names use the plural of the element name e.g. Row* const = ptrsRows { & row0, & row1 };
2016-07-14 23:28:16 +00:00
* Pass arrays using array notation rather than pointer notation:
2016-05-09 14:05:08 +00:00
```
void printArray(char[] array);
not
void printArray( char* array);
```
2016-05-09 19:41:29 +00:00
* In constructor's initialization list, use same names for fields and constructor parameters.
2016-07-18 02:26:00 +00:00
* Do not use new or malloc (make memory leaks impossible).
2016-05-09 14:05:08 +00:00
* Document class interface in .h file, above the class declaration.
2016-07-14 23:28:16 +00:00
* Code should be self-documenting. A simple function with a good name needs no comment.
* Code is automatically formatted before being pushed to the keybrd repository.
2016-05-11 18:46:53 +00:00
The [astyle_cpp ](astyle_cpp ) file specifies the format:
2016-05-09 14:05:08 +00:00
* Allman style indentation
* indent 4 spaces
* replace tabs with spaces
* maximum code width of 100 columns
2016-05-09 21:38:10 +00:00
<!-- http://stackoverflow.com/questions/2198241/best - practice - for - c - function - commenting -->
2016-07-18 02:26:00 +00:00
Trace of keybrd scan
--------------------
2016-06-05 20:43:53 +00:00
Arduino does not have a debugger.
2016-09-01 02:29:59 +00:00
So here is a list of functions in the order that they are called.
2016-07-18 02:26:00 +00:00
The trace is of a one-row single-layer keybrd scan.
2016-05-09 14:05:08 +00:00
```
2016-07-04 23:29:24 +00:00
loop() for each row
2016-07-12 13:23:24 +00:00
Row::process()
2016-07-18 02:26:00 +00:00
Scanner_uC::scan() strobe row on
2016-06-11 02:12:56 +00:00
for each readPin
2016-07-18 02:26:00 +00:00
set readState bit
2016-06-11 02:12:56 +00:00
strobe row off
2016-07-18 02:26:00 +00:00
Debouncer_Samples::debounce() debounce
2016-07-14 10:47:23 +00:00
Row::send() for each key in row
2016-07-18 02:26:00 +00:00
if falling edge
Key_*::release() scanCode->release()
Code_*::release() Keyboard.release(scancode)
if rising edge
Key_*::press() scanCode->press()
Code_*::press() Keyboard.press(scancode)
2016-07-05 21:45:58 +00:00
scanDelay.delay();
2016-05-09 14:05:08 +00:00
```
2016-07-18 02:26:00 +00:00
The Arduino libraries
---------------------
2016-05-09 14:05:08 +00:00
The keybrd libraries compile on the Arduino IDE and make extensive use of the following [Arduino libraries ](https://www.arduino.cc/en/Reference/Libraries ):
#include < Arduino.h >
#include < Wire.h >
#include < Keyboard.h >
#include < Mouse.h >
2016-05-11 15:25:48 +00:00
2016-07-21 20:20:07 +00:00
< a rel = "license" href = "https://creativecommons.org/licenses/by/4.0/" > < img alt = "Creative Commons License" style = "border-width:0" src = "https://licensebuttons.net/l/by/4.0/88x31.png" / > < / a > < br / > < span xmlns:dct = "http://purl.org/dc/terms/" property = "dct:title" > keybrd guide< / span > by < a xmlns:cc = "https://creativecommons.org/ns" href = "https://github.com/wolfv6/keybrd" property = "cc:attributionName" rel = "cc:attributionURL" > Wolfram Volpi< / a > is licensed under a < a rel = "license" href = "https://creativecommons.org/licenses/by/4.0/" > Creative Commons Attribution 4.0 International License< / a > .< br / > Permissions beyond the scope of this license may be available at < a xmlns:cc = "https://creativecommons.org/ns" href = "https://github.com/wolfv6/keybrd/issues/new" rel = "cc:morePermissions" > https://github.com/wolfv6/keybrd/issues/new< / a > .