LCOV - code coverage report
Current view: top level - src/Hardware - ButtonMatrix.ipp (source / functions) Hit Total Coverage
Test: 19d2efc7037c2e176feca44750a12594c76f466f Lines: 42 43 97.7 %
Date: 2019-11-24 14:50:27 Functions: 9 16 56.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "ButtonMatrix.hpp"
       2             : #include <Hardware/ExtendedInputOutput/ExtendedInputOutput.hpp>
       3             : #include <string.h>
       4             : 
       5             : BEGIN_CS_NAMESPACE
       6             : 
       7             : using namespace ExtIO;
       8             : 
       9             : template <uint8_t nb_rows, uint8_t nb_cols>
      10           9 : ButtonMatrix<nb_rows, nb_cols>::ButtonMatrix(const PinList<nb_rows> &rowPins,
      11             :                                              const PinList<nb_cols> &colPins)
      12          18 :     : rowPins(rowPins), colPins(colPins) {
      13           9 :     memset(prevStates, 0xFF, sizeof(prevStates));
      14           9 : }
      15             : 
      16             : template <uint8_t nb_rows, uint8_t nb_cols>
      17          10 : void ButtonMatrix<nb_rows, nb_cols>::refresh() {
      18          10 :     unsigned long now = millis();
      19             :     // only update 25 ms after previous change (crude software debounce).
      20             :     // Edit this in Settings/Settings.hpp
      21          10 :     if (now - prevRefresh < BUTTON_DEBOUNCE_TIME)
      22           0 :         return;
      23             : 
      24          40 :     for (size_t row = 0; row < nb_rows; row++) { // scan through all rows
      25          30 :         pinMode(rowPins[row], OUTPUT);           // make the current row Lo-Z 0V
      26          90 :         for (size_t col = 0; col < nb_cols; col++) { // scan through all columns
      27          60 :             bool state = digitalRead(colPins[col]);  // read the state
      28          60 :             if (state != getPrevState(col, row)) {
      29             :                 // if the state changed since last time
      30             :                 // execute the handler
      31          10 :                 onButtonChanged(row, col, state);
      32          10 :                 setPrevState(col, row, state); // remember the state
      33          10 :                 prevRefresh = now;
      34          10 :             }
      35          60 :         }
      36          30 :         pinMode(rowPins[row], INPUT); // make the current row Hi-Z again
      37          30 :     }
      38          10 : }
      39             : 
      40             : template <uint8_t nb_rows, uint8_t nb_cols>
      41           3 : void ButtonMatrix<nb_rows, nb_cols>::begin() {
      42             :     // make all columns input pins and enable
      43             :     // the internal pull-up resistors
      44           9 :     for (const pin_t &colPin : colPins)
      45           6 :         pinMode(colPin, INPUT_PULLUP);
      46             :     // make all rows Hi-Z
      47          12 :     for (const pin_t &rowPin : rowPins)
      48           9 :         pinMode(rowPin, INPUT);
      49           3 : }
      50             : 
      51             : template <uint8_t nb_rows, uint8_t nb_cols>
      52          70 : inline uint8_t ButtonMatrix<nb_rows, nb_cols>::positionToBits(uint8_t col,
      53             :                                                               uint8_t row) {
      54             :     // map from a 2D array of bits to a flat array of bits
      55          70 :     return col * nb_rows + row;
      56             : }
      57             : 
      58             : template <uint8_t nb_rows, uint8_t nb_cols>
      59          70 : inline uint8_t ButtonMatrix<nb_rows, nb_cols>::bitsToIndex(uint8_t bits) {
      60          70 :     return bits >> 3; // bits / 8
      61             : }
      62             : 
      63             : template <uint8_t nb_rows, uint8_t nb_cols>
      64          70 : inline uint8_t ButtonMatrix<nb_rows, nb_cols>::bitsToBitmask(uint8_t bits) {
      65          70 :     return 1 << (bits & 7); // bits % 8
      66             : }
      67             : 
      68             : template <uint8_t nb_rows, uint8_t nb_cols>
      69          60 : bool ButtonMatrix<nb_rows, nb_cols>::getPrevState(uint8_t col, uint8_t row) {
      70          60 :     uint8_t bits = positionToBits(col, row);
      71          60 :     return !!(prevStates[bitsToIndex(bits)] & bitsToBitmask(bits));
      72             : }
      73           9 : 
      74             : template <uint8_t nb_rows, uint8_t nb_cols>
      75          10 : void ButtonMatrix<nb_rows, nb_cols>::setPrevState(uint8_t col, uint8_t row,
      76             :                                                   bool state) {
      77          10 :     uint8_t bits = positionToBits(col, row);
      78          10 :     if (state)
      79           5 :         prevStates[bitsToIndex(bits)] |= bitsToBitmask(bits);
      80             :     else
      81           5 :         prevStates[bitsToIndex(bits)] &= ~bitsToBitmask(bits);
      82          10 : }
      83             : 
      84             : END_CS_NAMESPACE

Generated by: LCOV version 1.14-5-g4ff2ed6