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 7.2KB

keybrd Library Developer’s Guide

This guide contains diagrams, naming conventions, and a style guide.

This guide will help you design custom classes to interface with the keybrd library. The most common need for custom 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, developers, and anyone that wants to extend the keybrd library. 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.

Custom keybrd classes

Please refer to tutorial_7a_using_someone_else’s_keybrd_extension_library.md

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 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 elements 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 (to make 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

keybrd sketches

keybrd sketch naming convention is described in the keybrd_library_user_guide “Sample keybrd sketches”.

The head of sketch should contain latest version of keybrd lib that sketch was test on:

tested on keybrd v1.1 by wolfv6

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>