LCOV - code coverage report
Current view: top level - src/AH/Hardware - ButtonMatrix.ipp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 97.4 % 38 37
Test Date: 2026-06-06 17:44:35 Functions: 41.7 % 72 30
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta