keybrd library is an open source library for creating custom-keyboard firmware.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

keybrd_library_developer_guide.md 6.9KB

keybrd Library Developer’s Guide

This guide contains diagrams, naming conventions, and a style guide, which are useful when designing new classes for the keybrd library and its extension libraries. The most common reason for new classes are:

  • Port classes for micro controller or I/O expanders
  • 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 C++ language including pointers, objects, classes, static class variables, composition, inheritance, polymorphism, and enum. Some classes use bit manipulation.

Class diagrams

Keybrd library class inheritance diagram

    Matrix

    Row

    IOExpanderPort

             _______ RowPort _______
            /          |            \
    RowPort_AVR  RowPort_MCP23018  RowPort_PCA9655E     (one RowPort class for each type of IC)
 
              _______ ColPort _______
             /          |            \
    ColPort_AVR  ColPort_MCP23018  ColPort_PCA9655E     (one ColPort class for each type of IC)
 
           _____ LED ______
          /       |        \
    LED_AVR  LED_MCP23018  LED_PCA9655E                 (one LED class for each type of IC)


    StateLayersInterface
        |
    StateLayers


    Key __
     |    \
     |   Key_LayeredKeysArray
     |
    Code
     |_____________________
     |     \               \
     |   Code_LayerLock  Code_LayerHold
     |
     |___________________________
     |     \                     \
     |   Code_LayeredScScBase  Code_LayeredCodeScBase
     |      |                     |
     |   Code_LayeredScSc      Code_LayeredCodeSc
     |
     |__________________________________________
           \           \            \           \
         Code_Sc  Code_Shift  Code_AutoShift  Code_LockLED
                             /      |      \
                      Code_ScS  Code_ScNS  Code_ScNS_00

Association diagrams

single-layer Keybrd association diagram with LEDs

    keybrd[1]
      |
    matrix[1..*]
      |
    row[1..*]_____________________________
      |          \          \             \
    rowPort[1]  rowPin[1]  colPort[1]     keys[1]
                             |             |
                           colPins[1..*]  code[1..*]
                                           |
                                          LED[1]

multi-layer Keybrd association diagram with LEDs and I/O Expander


    keybrd[1]
      |
    matrix[1..*]
      |                                                stateLayers[1..*]
    row[1..*]_________________________________________/__    |         \
      |          \          \                \       /   \   |          \
    rowPort[1]  rowPin[1]  colPort[1]       keys[1] / code_layer[1..*]  LED[0..*]
       \                  /   \               |    /                    /
        \                /   colPins[1..*]  key[1..*]                  /
         \              /                     |                       /
          \            /                    code[1..*]               /
           \          /       ______________________________________/
          IOExpanderPort[0..*] 

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_Sc

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.

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”
  • For member names, use camelCase starting with lowercase letter.
  • Use constants rather than macros, except for header guards.
  • For constant names that could be macros, use ALL_CAPS_AND_UNDERSCORE.
    • ITEM_COUNT is a constant number of items.
    • itemCount is a variable number of items.
  • Use header guards CLASS_NAME_H.
  • Prefix pointer name with “ptr” e.g. ptrRow = &row
  • Name arrays using the plural of element name e.g. Row* const = ptrsRows { &row0, &row1 };
  • Pass arrays using array notation rather than pointer notation. Use 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 (making memory leaks impossible).
  • If class has any non-POD data members, do not inline constructors and destructors.
  • Document class interface in .h file, above the class declaration.
  • Code should be self-documenting. The only comments should be things that may need clarification. A simple function with a good name needs no comment. <-- http://stackoverflow.com/questions/2198241/best-practice-for-c-function-commenting !-->
  • Code is automatically formated before being pushed to the keybrd repository The options file doc/astyle_cpp 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. Refer to it like a table of contents while reading the keybrd library.

Keybrd::scan()                          for each matrix
    Matrix::scan()                          for each row
        Row::process()
            Row::scan()
                RowPort_*::setActivePin*()      strobe row on
                                                for each col port
                    ColPort_*::read()               read col port
                RowPort_*::setActivePin*()      strobe row off
            Row::getRowState()                  for each col port
                                                    for each connected col pin
                                                        if key is pressed
                                                            set rowState bit
            Row::debounce()                     debounce
            Row::detectEdge()                   detect edge
            Row::pressRelease()                 for each key in row
                                                    if rising edge
                Key_*::press()                          scanCode->press()
                    Code_*::press()                         Keyboard.press(scancode)

The Arduino libraries

The keybrd libraries compile on the Arduino IDE and make extensive use of the following Arduino libraries:

#include <Arduino.h>
#include <Wire.h>
#include <Keyboard.h>
#include <Mouse.h>