keybrd library is an open source library for creating custom-keyboard firmware.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
Dieses Repo ist archiviert. Du kannst Dateien sehen und es klonen, kannst aber nicht pushen oder Issues/Pull-Requests öffnen.

RowBase.cpp 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "RowBase.h"
  2. /*
  3. scans the row and calls any newly pressed or released keys.
  4. */
  5. void RowBase::process(const bool activeHigh)
  6. {
  7. //these variables are all bitwise, one bit per key
  8. uint8_t rowState; //1 means pressed, 0 means released
  9. uint16_t rowEnd; //1 bit marks positioned after last key of row
  10. uint8_t newDebounced; //1 means pressed, 0 means released
  11. uint8_t isFallingEdge; //1 means falling edge
  12. uint8_t isRisingEdge; //1 means rising edge
  13. scan(activeHigh); //save column-port-pin values to portState
  14. rowState = getRowState(rowEnd, activeHigh);
  15. newDebounced = debounce(rowState);
  16. detectEdge(newDebounced, isFallingEdge, isRisingEdge);
  17. pressRelease(rowEnd, isFallingEdge, isRisingEdge);
  18. }
  19. /*
  20. Strobes the row and reads the columns.
  21. Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch.
  22. */
  23. void RowBase::scan(const bool activeHigh)
  24. {
  25. //strobe row on
  26. if (activeHigh)
  27. {
  28. refRowPort.setActivePinHigh(rowPin);
  29. }
  30. else //activeLow
  31. {
  32. refRowPort.setActivePinLow(rowPin);
  33. }
  34. //read all the column ports
  35. for (uint8_t i=0; i < colPortCount; i++)
  36. {
  37. ptrsColPorts[i]->read();
  38. }
  39. //strobe row off
  40. if (activeHigh)
  41. {
  42. refRowPort.setActivePinLow(rowPin);
  43. }
  44. else //activeLow
  45. {
  46. refRowPort.setActivePinHigh(rowPin);
  47. }
  48. }
  49. /*
  50. Copies column pins to rowState. Unused column pins are not copied.
  51. Sets rowEnd and returns rowState.
  52. rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row.
  53. rowEnd and rowMask are larger type than portMask so that they can not overflow.
  54. */
  55. uint8_t RowBase::getRowState(uint16_t& rowEnd, const bool activeHigh)
  56. {
  57. uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1
  58. uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed
  59. for (uint8_t i=0; i < colPortCount; i++) //for each col port
  60. {
  61. //bitwise colPins, 1 means pin is connected to column
  62. uint8_t colPins = ptrsColPorts[i]->getColPins();
  63. //bitwise colPortState, pin values where set in ColPort::read(), get them now
  64. uint8_t colPortState = ptrsColPorts[i]->getPortState();
  65. if (activeHigh)
  66. {
  67. colPortState = ~colPortState;
  68. }
  69. for ( uint8_t portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow
  70. { //for each pin of col port
  71. if (portMask & colPins) //if pin is connected to column
  72. {
  73. if (portMask & ~colPortState) //if pin detected a key press
  74. {
  75. rowState |= rowMask; //set rowState bit for that key
  76. }
  77. rowMask <<= 1; //shift rowMask to next key
  78. }
  79. }
  80. }
  81. rowEnd = rowMask;
  82. return rowState;
  83. }
  84. /*
  85. Computes isFallingEdge and isRisingEdge.
  86. All 3 parameters are bitwise.
  87. */
  88. void RowBase::detectEdge(uint8_t newDebounced, uint8_t& isFallingEdge, uint8_t& isRisingEdge)
  89. {
  90. uint8_t debouncedChanged; //bitwise
  91. debouncedChanged = newDebounced xor debounced;
  92. debounced = newDebounced;
  93. //bit=1 if last debounced changed from 1 to 0, else bit=0
  94. isFallingEdge = debouncedChanged & ~debounced;
  95. //bit=1 if last debounced changed from 0 to 1, else bit=0
  96. isRisingEdge = debouncedChanged & debounced;
  97. }
  98. /*
  99. calls key's press() or release() function if it was pressed or released.
  100. All 3 parameters are bitwise.
  101. */
  102. void RowBase::pressRelease(const uint16_t rowEnd, const uint8_t isFallingEdge,
  103. const uint8_t isRisingEdge)
  104. {
  105. uint8_t rowMask; //bitwise, active col bit is 1
  106. uint8_t col; //index for ptrsKeys[col] array
  107. for (rowMask=1, col=0; rowMask<rowEnd; rowMask<<=1, col++) //for each key in row
  108. {
  109. //release before press avoids impossible key sequence
  110. if (rowMask & isFallingEdge) //if key was released
  111. {
  112. ptrsKeys[col]->release();
  113. }
  114. if (rowMask & isRisingEdge) //if key was pressed
  115. {
  116. ptrsKeys[col]->press();
  117. keyWasPressed();
  118. }
  119. }
  120. }
  121. void RowBase::keyWasPressed()
  122. {
  123. //empty in RowBase class. To unstick sticky keys, override keyWasPressed() in derived class.
  124. }