keybrd library is an open source library for creating custom-keyboard firmware.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
Это архивный репозиторий. Вы можете его клонировать или просматривать файлы, но не вносить изменения или открывать задачи/запросы на слияние.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "RowBase.h"
  2. /*
  3. process() scans the row and calls any newly pressed or released keys.
  4. */
  5. void RowBase::process()
  6. {
  7. //these variables are all bitwise, one bit per key
  8. read_pins_t rowState; //1 means pressed, 0 means released
  9. read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row
  10. read_pins_t debouncedChanged; //1 means debounced changed
  11. wait();
  12. rowState = scan(rowEnd);
  13. debouncedChanged = debounce(rowState, debounced);
  14. pressRelease(rowEnd, debouncedChanged);
  15. }
  16. /* wait() delay's scan to give switches time to debounce.
  17. This version of wait() is very simple. More sophisticated versions can override this one.
  18. For fastest response time, wait() should be placed before scan() or after pressRelease()
  19. (waiting between strobe and send would unnecessarily delay send).
  20. DELAY_MICROSECONDS explained
  21. ----------------------------
  22. A keyboard with a faster scan rate responds faster.
  23. Follow these step to tune DELAY_MICROSECONDS for maximum scan rate for a given SAMPLE_COUNT:
  24. Initialize DELAY_MICROSECONDS in your sketch:
  25. const unsigned int RowBase::DELAY_MICROSECONDS = 1000;
  26. Add this to the sketch's loop() function:
  27. debug.print_microseconds_per_scan();
  28. Compile and load the sketch into the microcontroller; microseconds_per_scan is printed every second.
  29. Adjust the value of DELAY_MICROSECONDS and repeat until:
  30. debug.print_microseconds_per_scan() <= DEBOUNCE_TIME / SAMPLE_COUNT
  31. DEBOUNCE_TIME can be obtained from the switch's datasheet. Some switch bounce times are:
  32. Cherry MX specifies 5msec bounce time http://www.cherrycorp.com/english/switches/key/mx.htm
  33. hasu measured Cherry MX bounce times .3ms to 1.4ms http://geekhack.org/index.php?topic=42385.0
  34. Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures/MJTP_6MM.pdf
  35. Avoid sampling the switch input at a rate synchronous to events in the environment
  36. that might create periodic EMI. For instance, 50 and 60 Hz.
  37. The largest allowable DELAY_MICROSECONDS is 65535 (.065535 seconds).
  38. Polling I2C may slow the scan rate enough so that no additional delay is needed:
  39. const unsigned int RowBase::DELAY_MICROSECONDS = 0;
  40. */
  41. void RowBase::wait()
  42. {
  43. delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches
  44. }
  45. /*
  46. pressRelease() calls key's press() or release() function if it was pressed or released.
  47. Both parameters are bitwise.
  48. rowEnd bit marks positioned immediatly after last key of row.
  49. */
  50. void RowBase::pressRelease(const read_pins_mask_t rowEnd, const read_pins_t debouncedChanged)
  51. {
  52. read_pins_t isFallingEdge; //bitwise, 1 means falling edge
  53. read_pins_t isRisingEdge; //bitwise, 1 means rising edge
  54. read_pins_mask_t rowMask; //bitwise, active col bit is 1
  55. uint8_t col; //index for ptrsKeys[col] array
  56. //bit=1 if last debounced changed from 1 to 0, else bit=0
  57. isFallingEdge = debouncedChanged & ~debounced;
  58. //bit=1 if last debounced changed from 0 to 1, else bit=0
  59. isRisingEdge = debouncedChanged & debounced;
  60. for (rowMask=1, col=0; rowMask<rowEnd; rowMask<<=1, col++) //for each key in row
  61. {
  62. //release before press avoids impossible key sequence
  63. if (rowMask & isFallingEdge) //if key was released
  64. {
  65. ptrsKeys[col]->release();
  66. }
  67. if (rowMask & isRisingEdge) //if key was pressed
  68. {
  69. ptrsKeys[col]->press();
  70. keyWasPressed();
  71. }
  72. }
  73. }
  74. void RowBase::keyWasPressed()
  75. {
  76. //empty in RowBase class. To unstick sticky keys, override keyWasPressed() in derived class.
  77. }