keybrd library is an open source library for creating custom-keyboard firmware.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
Este repositório está arquivado. Você pode visualizar os arquivos e realizar clone, mas não poderá realizar push nem abrir issues e pull requests.

RowBase.cpp 4.3KB

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