LCOV - code coverage report
Current view: top level - src/AH/Hardware/ExtendedInputOutput - ExtendedInputOutput.cpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 100.0 % 98 98
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 16 16
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #include "ExtendedInputOutput.hpp"
       2              : #include "ExtendedIOElement.hpp"
       3              : #include <AH/Error/Error.hpp>
       4              : 
       5              : BEGIN_AH_NAMESPACE
       6              : 
       7              : namespace ExtIO {
       8              : 
       9              : template <class T>
      10           90 : static bool inRange(T target, T start, T end) {
      11           90 :     return target >= start && target < end;
      12              : }
      13              : 
      14           80 : ExtendedIOElement *getIOElementOfPinOrNull(pin_t pin) {
      15           92 :     for (auto &el : ExtendedIOElement::getAll())
      16           91 :         if (pin < el.getStart())
      17            1 :             break;
      18           90 :         else if (inRange(pin, el.getStart(), el.getEnd()))
      19           78 :             return &el;
      20            2 :     return nullptr;
      21              : }
      22              : 
      23           80 : ExtendedIOElement *getIOElementOfPin(pin_t pin) {
      24           80 :     auto *el = getIOElementOfPinOrNull(pin);
      25           80 :     if (el == nullptr)
      26            2 :         FATAL_ERROR(
      27              :             F("The given pin does not correspond to an Extended IO element."),
      28              :             0x8888);
      29           78 :     return el;
      30              : }
      31              : 
      32          204 : void pinMode(pin_t pin, PinMode_t mode) {
      33          204 :     if (pin == NO_PIN)
      34              :         return; // LCOV_EXCL_LINE
      35          203 :     else if (isNativePin(pin)) {
      36          197 :         ::pinMode(arduino_pin_cast(pin), mode);
      37              :     } else {
      38            6 :         auto el = getIOElementOfPin(pin);
      39            6 :         el->pinMode(pin - el->getStart(), mode);
      40              :     }
      41              : }
      42              : 
      43          203 : void digitalWrite(pin_t pin, PinStatus_t val) {
      44          203 :     if (pin == NO_PIN)
      45              :         return; // LCOV_EXCL_LINE
      46          202 :     else if (isNativePin(pin)) {
      47          181 :         ::digitalWrite(arduino_pin_cast(pin), val);
      48              :     } else {
      49           21 :         auto el = getIOElementOfPin(pin);
      50           21 :         el->digitalWrite(pin - el->getStart(), val);
      51              :     }
      52              : }
      53              : 
      54          303 : PinStatus_t digitalRead(pin_t pin) {
      55          303 :     if (pin == NO_PIN)
      56              :         return LOW; // LCOV_EXCL_LINE
      57          302 :     else if (isNativePin(pin)) {
      58          293 :         return ::digitalRead(arduino_pin_cast(pin));
      59              :     } else {
      60            9 :         auto el = getIOElementOfPin(pin);
      61            7 :         return el->digitalRead(pin - el->getStart());
      62              :     }
      63              : }
      64              : 
      65           85 : analog_t analogRead(pin_t pin) {
      66           85 :     if (pin == NO_PIN)
      67              :         return 0; // LCOV_EXCL_LINE
      68           84 :     else if (isNativePin(pin)) {
      69           69 :         return ::analogRead(arduino_pin_cast(pin));
      70              :     } else {
      71           15 :         auto el = getIOElementOfPin(pin);
      72           15 :         return el->analogRead(pin - el->getStart());
      73              :     }
      74              : }
      75              : 
      76           14 : void analogWrite(pin_t pin, analog_t val) {
      77           14 :     if (pin == NO_PIN)
      78              :         return; // LCOV_EXCL_LINE
      79           13 :     else if (isNativePin(pin)) {
      80              : #ifndef ESP32
      81            8 :         ::analogWrite(arduino_pin_cast(pin), val);
      82              : #endif
      83              :     } else {
      84            5 :         auto el = getIOElementOfPin(pin);
      85            5 :         el->analogWrite(pin - el->getStart(), val);
      86              :     }
      87              : }
      88           11 : void analogWrite(pin_t pin, int val) { analogWrite(pin, (analog_t)val); }
      89              : 
      90            3 : void pinModeBuffered(pin_t pin, PinMode_t mode) {
      91            3 :     if (pin == NO_PIN)
      92              :         return; // LCOV_EXCL_LINE
      93            3 :     else if (isNativePin(pin)) {
      94            1 :         ::pinMode(arduino_pin_cast(pin), mode);
      95              :     } else {
      96            2 :         auto el = getIOElementOfPin(pin);
      97            2 :         el->pinModeBuffered(pin - el->getStart(), mode);
      98              :     }
      99              : }
     100              : 
     101            2 : void digitalWriteBuffered(pin_t pin, PinStatus_t val) {
     102            2 :     if (pin == NO_PIN)
     103              :         return; // LCOV_EXCL_LINE
     104            2 :     else if (isNativePin(pin)) {
     105            1 :         ::digitalWrite(arduino_pin_cast(pin), val);
     106              :     } else {
     107            1 :         auto el = getIOElementOfPin(pin);
     108            1 :         el->digitalWriteBuffered(pin - el->getStart(), val);
     109              :     }
     110              : }
     111              : 
     112            3 : PinStatus_t digitalReadBuffered(pin_t pin) {
     113            3 :     if (pin == NO_PIN)
     114              :         return LOW; // LCOV_EXCL_LINE
     115            3 :     else if (isNativePin(pin)) {
     116            1 :         return ::digitalRead(arduino_pin_cast(pin));
     117              :     } else {
     118            2 :         auto el = getIOElementOfPin(pin);
     119            2 :         return el->digitalReadBuffered(pin - el->getStart());
     120              :     }
     121              : }
     122              : 
     123            3 : analog_t analogReadBuffered(pin_t pin) {
     124            3 :     if (pin == NO_PIN)
     125              :         return 0; // LCOV_EXCL_LINE
     126            3 :     else if (isNativePin(pin)) {
     127            1 :         return ::analogRead(arduino_pin_cast(pin));
     128              :     } else {
     129            2 :         auto el = getIOElementOfPin(pin);
     130            2 :         return el->analogReadBuffered(pin - el->getStart());
     131              :     }
     132              :     return 0;
     133              : }
     134              : 
     135            4 : void analogWriteBuffered(pin_t pin, analog_t val) {
     136            4 :     if (pin == NO_PIN)
     137              :         return; // LCOV_EXCL_LINE
     138            4 :     else if (isNativePin(pin)) {
     139              : #ifndef ESP32
     140            2 :         ::analogWrite(arduino_pin_cast(pin), val);
     141              : #endif
     142              :     } else {
     143            2 :         auto el = getIOElementOfPin(pin);
     144            2 :         el->analogWriteBuffered(pin - el->getStart(), val);
     145              :     }
     146              : }
     147            2 : void analogWriteBuffered(pin_t pin, int val) {
     148            2 :     analogWriteBuffered(pin, (analog_t)val);
     149            2 : }
     150              : 
     151            6 : void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) {
     152            6 :     if (dataPin == NO_PIN || clockPin == NO_PIN)
     153            1 :         return;
     154              :     // Native version
     155            5 :     if (isNativePin(dataPin) && isNativePin(clockPin)) {
     156            1 :         ::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin),
     157              :                    bitOrder, val);
     158              :     }
     159              :     // ExtIO version
     160            4 :     else if (!isNativePin(dataPin) && !isNativePin(clockPin)) {
     161            2 :         auto dataEl = getIOElementOfPin(dataPin);
     162            2 :         auto dataPinN = dataPin - dataEl->getStart();
     163            2 :         auto clockEl = getIOElementOfPin(clockPin);
     164            2 :         auto clockPinN = clockPin - clockEl->getStart();
     165           18 :         for (uint8_t i = 0; i < 8; i++) {
     166           16 :             uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
     167           16 :             dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW);
     168           16 :             clockEl->digitalWrite(clockPinN, HIGH);
     169           16 :             clockEl->digitalWrite(clockPinN, LOW);
     170              :         }
     171              :     }
     172              :     // Mixed version (slow)
     173              :     else {
     174           18 :         for (uint8_t i = 0; i < 8; i++) {
     175           16 :             uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i));
     176           16 :             digitalWrite(dataPin, (val & mask) ? HIGH : LOW);
     177           16 :             digitalWrite(clockPin, HIGH);
     178           16 :             digitalWrite(clockPin, LOW);
     179              :         }
     180              :     }
     181              : }
     182              : 
     183              : } // namespace ExtIO
     184              : 
     185              : END_AH_NAMESPACE
        

Generated by: LCOV version 2.4-beta