LCOV - code coverage report
Current view: top level - src/AH/Hardware/ExtendedInputOutput - ExtendedInputOutput.cpp (source / functions) Hit Total Coverage
Test: bf14c9fae556d77e8c4ecd719832b25959f10ebc Lines: 98 98 100.0 %
Date: 2022-05-29 00:36:34 Functions: 16 16 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.15