keybrd Library Developer's Guide ================================ This guide if for maintaining and writing new classes for the keybrd library and its extension libraries. The most common reason for adding new classes are: * I/O expander classes * custom layer schemes for multi-layer keyboards * experimental features Who this guide is for --------------------- This guide is for the maintainers and developers of the keybrd library and it's extensions. It is assumed the reader is familiar with the C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum. Row, Scanner, and Debouncer classes use bit manipulation. Class inheritance diagrams -------------------------- Keybrd library class inheritance diagram ``` Row ___ ScannerInterface ___ / | \ Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO PortWriteInterface / \ PortInterface Port_ShiftRegs (Port class for MOSI shift registers) / \ Port_PCA9655E Port_MCP23S17 (one Port class for each IOE type) LEDInterface / \ LED_uC LED_Port DebouncerInterface | Debouncer_Samples ScanDelay LayerStateInterface | LayerState Key |____ | \ | Key_LayeredKeysBase | \____________________ | / \ | Key_LayeredKeys Key_LayeredKeys1 | |___________________________ | \ \ | Key_LayeredScScBase Key_LayeredCodeScBase | | | | Key_LayeredScSc Key_LayeredCodeSc | Code |_____________________ | \ \ | Code_LayerLock Code_LayerHold | \________________________________________________________ \ \ \ \ \ Code_Sc Code_Shift Code_AutoShift Code_LEDLock Code_Null / \ Code_ScS Code_ScNS ``` Dependency diagrams ------------------- Dependency diagram of example single-layer keyboard with LEDs ``` ____ Row ______ / | \ Scanner_uC Debouncer Key ___ | | \ readPins Code Code_LEDLock | LED_PinNumber ``` Dependency diagram of example multi-layer keyboard with layer LEDs ``` LayerStates ___________ Row ________________/__ | \ / / \ / \ | \ Scanner_uC Debouncer Key_LayeredKeys / Code_Layer LED_PinNumber | \ / readPins Code ``` Dependency diagram of example shift registers Row ``` _______ Row _______ / | \ RowScanner_ShiftRegsPISO Debouncer Key | Code ``` Dependency diagram of example I/O expander matrix with LEDs ``` _________ Row ________ / \ \ __ Scanner_IOE __ Debouncer Key / | \ / \ strobePin PortWrite PortRead Code Code_LEDLock | \ / \ | | PortIOE readPins LED_Port \___________________________/ \ pin ``` Class naming conventions ------------------------ 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 | Code_LayerLock ``` This convention leads to class names that convey information about the classes inheritance. Underscore delineates base class name and sub-class name. Capital letters delineate words. Interface class names end with "Interface". Except for Key, to reduce clutter because sketches define so many Key[] arrays. Layer-class naming conventions ------------------------------ Layer classes are explained in [tutorial_3a_multi-layer_keyboard.md](../tutorials/tutorial_3a_multi-layer_keyboard.md). *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 *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 *Key_Layered* class names start with "Key_Layered" and end with a descriptive name. Example Key_Layered class names: * Key_LayeredScSc * Key_LayeredKeys Style guide ----------- Following the style guide makes it easier for the next programmer to understand your code. * For class names, see above section "Class naming conventions". * Member names use camelCase starting with lowercase letter. * Use constants rather than macros, except for header guards. * Global const names and static const names use ALL_CAPS_WITH_UNDERSCORE. * Macros use ALL_CAPS_WITH_UNDERSCORE and have _MACRO suffix e.g. SAMPLE_COUNT_MACRO * Header guards have _H suffix e.g. #ifndef FILE_NAME_H * Pointer names are prefixed with "ptr" e.g. ptrRow = &row; * Arrays names use the plural of the element name e.g. Row* const = ptrsRows { &row0, &row1 }; * Pass arrays using array notation rather than pointer notation: ``` void printArray(char[] array); not void printArray( char* array); ``` * In constructor's initialization list, use same names for fields and constructor parameters. * Do not use new or malloc (make memory leaks impossible). * Document class interface in .h file, above the class declaration. * 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. The [astyle_cpp](astyle_cpp) file specifies the format: * Allman style indentation * indent 4 spaces * replace tabs with spaces * maximum code width of 100 columns Trace of keybrd scan -------------------- Arduino does not have a debugger. So here is a list of functions in the order that they are called. The trace is of a one-row single-layer keybrd scan. ``` loop() for each row Row::process() Scanner_uC::scan() strobe row on for each readPin set readState bit strobe row off Debouncer_Samples::debounce() debounce Row::send() for each key in row if falling edge Key_*::release() scanCode->release() Code_*::release() Keyboard.release(scancode) if rising edge Key_*::press() scanCode->press() Code_*::press() Keyboard.press(scancode) scanDelay.delay(); ``` The Arduino libraries --------------------- 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 #include #include #include Creative Commons License
keybrd guide by Wolfram Volpi is licensed under a Creative Commons Attribution 4.0 International License.
Permissions beyond the scope of this license may be available at https://github.com/wolfv6/keybrd/issues/new.