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

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. keybrd Library Developer's Guide
  2. ================================
  3. This guide if for maintaining and writing new classes for the keybrd library and its extension libraries.
  4. The most common reason for new classes are:
  5. * Port classes for micro controller or I/O expanders
  6. * custom layer schemes for multi-layer keyboards
  7. * experimental features
  8. ## Who this guide is for
  9. This guide is for the maintainers and developers of the keybrd library and it's extensions.
  10. It is assumed the reader is familiar with C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum.
  11. Debouncer and I/O expander use bit manipulation.
  12. ## Custom Row classes
  13. The keybrd library is flexible for designing custom Rows
  14. * RowBase functions can be overridden in a derived class
  15. * choice of Debouncers
  16. * choice of Scanners
  17. this example illustrates the custom Row classes for a fictional keybrd_Ext extension library
  18. the keybrd_Ext library is for a split keyboard with a matrix on each hand
  19. other custom Row classes would have a similar structure
  20. Row_Ext::keyWasPressed() overrides RowBase::keyWasPressed()
  21. Row_Ext::keyWasPressed() is used to unstick sticky keys
  22. Row_Ext_uC scans the primary matrix
  23. Row_Ext_ShiftRegisters scans the secondary matrix
  24. Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes
  25. Class inheritance diagram
  26. ```
  27. RowBase
  28. |
  29. Row_Ext (override RowBase::keyWasPressed() )
  30. / \
  31. Row_Ext_uC Row_Ext_ShiftRegisters (inherit Row_Ext::keyWasPressed() )
  32. RowScannerInterface
  33. / \
  34. RowScanner_PinsArray RowScanner_SPIShiftRegisters
  35. ```
  36. Dependency diagram
  37. ```
  38. ________ Row_Ext_uC[1] _______________
  39. / \ \
  40. RowScanner_PinsArray[1] Debouncer_Samples[1] Key[1..*]
  41. / \ |
  42. strobePin[1] readPins[1..*] Code[1..*]
  43. _____ Row_Ext_ShiftRegisters[1] ___________
  44. / \ \
  45. RowScanner_SPIShiftRegisters[1] Debouncer_Samples[1] Key[1..*]
  46. / \ |
  47. strobePin[1] ROW_END[1] Code[1..*]
  48. ```
  49. ## Class inheritance diagrams
  50. Keybrd library class inheritance diagram
  51. ```
  52. _______ RowBase ________
  53. / | \
  54. Row_uC Row_ShiftRegisters Row_IOE
  55. _____ RowScannerInterface ______
  56. / | \
  57. RowScanner_PinsArray RowScanner_PinsBitwise RowScanner_SPIShiftRegisters
  58. IOExpanderPort
  59. RowPort
  60. |
  61. RowPort_PCA9655E (one RowPort class for each IOE type)
  62. ColPort
  63. |
  64. ColPort_PCA9655E (one ColPort class for each IOE type)
  65. ____ LED ____
  66. / \
  67. LED_PinNumber LED_PCA9655E
  68. DebouncerInterface
  69. |
  70. Debouncer_4Samples
  71. ScanDelay
  72. LayerStateInterface
  73. |
  74. LayerState
  75. Key __
  76. | \
  77. | Key_LayeredKeysArray
  78. |
  79. Code
  80. |_____________________
  81. | \ \
  82. | Code_LayerLock Code_LayerHold
  83. |
  84. |___________________________
  85. | \ \
  86. | Code_LayeredScScBase Code_LayeredCodeScBase
  87. | | |
  88. | Code_LayeredScSc Code_LayeredCodeSc
  89. |
  90. |__________________________________________
  91. \ \ \ \
  92. Code_Sc Code_Shift Code_AutoShift Code_LEDLock
  93. / | \
  94. Code_ScS Code_ScNS Code_ScNS_00
  95. ```
  96. ## Dependency diagrams
  97. Example single-layer dependency diagram with LEDs
  98. ```
  99. ___ Row_uC[1..*] ________
  100. / \ \
  101. RowScanner_PinsArray Debouncer Keys[1..*] __
  102. | \
  103. Code[1..*] Code_LEDLock[1..*]
  104. |
  105. LED_PinNumber[1]
  106. ```
  107. Example multi-layer dependency diagram with layer LEDs
  108. ```
  109. LayerStates[1..*]
  110. ________ Row_uC[1..*] _____________________/__ | \
  111. / \ \ / \ | \
  112. RowScanner_PinsArray[1] Debouncer[1] Keys[1..*] / Code_Layer[1..*] LED_PinNumber[0..*]
  113. | /
  114. Code[1..*]
  115. ```
  116. Example secondary matrix with shift registers dependency diagram
  117. ```
  118. Row_ShiftRegisters[1..*]
  119. / \ \
  120. RowScanner_ShiftRegisters Debouncer Keys[1..*]
  121. |
  122. Code[1..*]
  123. ```
  124. Example secondary matrix with I/O Expander dependency diagram with LEDs
  125. ```
  126. ___ Row_IOE[1..*] _________
  127. / \ \
  128. RowScanner_PinsBitwise[1] Debouncer[1] Keys[1..*] __
  129. / | \ | \
  130. RowPort[1] RowPin[1] ColPort[1] Code[1..*] Code_LEDLock[1..*]
  131. \ / \ |
  132. \ / ColPins[1..*] LED[1]
  133. \ /
  134. IOExpanderPort[0..*]
  135. ```
  136. ## Class naming conventions
  137. Class names start with upper case letter.
  138. Most derived-class names start with the base class name followed by "_" and a name e.g.
  139. ```
  140. Code
  141. |
  142. Code_LayerLock
  143. ```
  144. This convention leads to class names that convey information about the classes inheritance.
  145. Underscore delineates base class name and sub-class name. Capital letters delineate words.
  146. ## Layer-class naming conventions
  147. *Code_Layer* class names are concatenations of "Code_", "Layer" or layer name, and persistence.
  148. Example persistences are:
  149. * "Lock" - layer remains active after the layer key is released
  150. * "Hold" - layer is active for as long as layer key is held down
  151. Example Code_Layer class names:
  152. * Code_LayerHold
  153. * Code_LayerLock
  154. *LayerState* class names start with "LayerState" and end with a descriptive name.
  155. Example LayerState class names:
  156. * LayerState - basic LayerState class in keybrd library
  157. * LayerState_DH - main LayerState for the keybrd_DH library
  158. * LayerState_MF - LayerState for Mouse Function sub-layers in the keybrd_DH library
  159. *Code_Layered* class names start with "Code_Layered" and end with a descriptive name.
  160. Example Code_Layered class names:
  161. * Code_LayeredScSc
  162. * Key_LayeredKeysArray
  163. ## Style guide
  164. Following the style guide makes it easier for the next programmer to understand your code.
  165. * For class names, see above section "Class naming conventions"
  166. * For member names, use camelCase starting with lowercase letter.
  167. * Use constants rather than macros, except for header guards.
  168. * For constant names that could be macros, use ALL_CAPS_AND_UNDERSCORE.
  169. * **ITEM_COUNT** is a constant number of items.
  170. * **itemCount** is a variable number of items.
  171. * Use header guards CLASS_NAME_H.
  172. * Prefix pointer name with "ptr" e.g. ptrRow = &row;
  173. * Name arrays using the plural of element name e.g. Row* const = ptrsRows { &row0, &row1 };
  174. * Pass arrays using array notation rather than pointer notation. Use
  175. ```
  176. void printArray(char[] array);
  177. not
  178. void printArray( char* array);
  179. ```
  180. * In constructor's initialization list, use same names for fields and constructor parameters.
  181. * Do not use new or malloc (making memory leaks impossible).
  182. * Document class interface in .h file, above the class declaration.
  183. * 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.
  184. * Code is automatically formated before being pushed to the keybrd repository.
  185. The [astyle_cpp](astyle_cpp) file specifies the format:
  186. * Allman style indentation
  187. * indent 4 spaces
  188. * replace tabs with spaces
  189. * maximum code width of 100 columns
  190. <!-- http://stackoverflow.com/questions/2198241/best-practice-for-c-function-commenting -->
  191. ## Trace of keybrd scan
  192. Arduino does not have a debugger.
  193. So here is the next best thing; a list of functions in the order that they are called.
  194. The trace is of a single-layer keybrd scan (no LEDs and no I/O expander).
  195. Refer to it like a table of contents while reading the keybrd library.
  196. ```
  197. loop() for each row
  198. RowBase::process()
  199. RowScanner_PinsArray::scan() strobe row on
  200. for each readPin
  201. set rowState bit
  202. strobe row off
  203. Debouncer_4Samples::debounce() debounce
  204. RowBase::pressRelease() for each key in row
  205. if falling edge
  206. Key_*::release() scanCode->release()
  207. Code_*::release() Keyboard.release(scancode)
  208. if rising edge
  209. Key_*::press() scanCode->press()
  210. Code_*::press() Keyboard.press(scancode)
  211. scanDelay.delay();
  212. ```
  213. ## The Arduino libraries
  214. The keybrd libraries compile on the Arduino IDE and make extensive use of the following [Arduino libraries](https://www.arduino.cc/en/Reference/Libraries):
  215. #include <Arduino.h>
  216. #include <Wire.h>
  217. #include <Keyboard.h>
  218. #include <Mouse.h>
  219. <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.