Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Custom digitalReadFast()

  1. #1
    Senior Member
    Join Date
    Jan 2015
    Posts
    176

    Custom digitalReadFast()

    Hello,

    As writen in the core_pins.h header file, this is the digitalReadFast() function content:

    Code:
    static inline uint8_t digitalReadFast(uint8_t pin)
    {
    	if (__builtin_constant_p(pin)) {
    		if (pin == 0) {
    			return (CORE_PIN0_PINREG & CORE_PIN0_BITMASK) ? 1 : 0;
    		} else if (pin == 1) {
    			return (CORE_PIN1_PINREG & CORE_PIN1_BITMASK) ? 1 : 0;
    		} else if (pin == 2) {
    			return (CORE_PIN2_PINREG & CORE_PIN2_BITMASK) ? 1 : 0;
    		} else if (pin == 3) {
    			return (CORE_PIN3_PINREG & CORE_PIN3_BITMASK) ? 1 : 0;
    		} else if (pin == 4) {
    			return (CORE_PIN4_PINREG & CORE_PIN4_BITMASK) ? 1 : 0;
    		} else if (pin == 5) {
    			return (CORE_PIN5_PINREG & CORE_PIN5_BITMASK) ? 1 : 0;
    		} else if (pin == 6) {
    			return (CORE_PIN6_PINREG & CORE_PIN6_BITMASK) ? 1 : 0;
    		} else if (pin == 7) {
    			return (CORE_PIN7_PINREG & CORE_PIN7_BITMASK) ? 1 : 0;
    		} else if (pin == 8) {
    			return (CORE_PIN8_PINREG & CORE_PIN8_BITMASK) ? 1 : 0;
    		} else if (pin == 9) {
    			return (CORE_PIN9_PINREG & CORE_PIN9_BITMASK) ? 1 : 0;
    		} else if (pin == 10) {
    			return (CORE_PIN10_PINREG & CORE_PIN10_BITMASK) ? 1 : 0;
    		} else if (pin == 11) {
    			return (CORE_PIN11_PINREG & CORE_PIN11_BITMASK) ? 1 : 0;
    		} else if (pin == 12) {
    			return (CORE_PIN12_PINREG & CORE_PIN12_BITMASK) ? 1 : 0;
    		} else if (pin == 13) {
    			return (CORE_PIN13_PINREG & CORE_PIN13_BITMASK) ? 1 : 0;
    		} else if (pin == 14) {
    			return (CORE_PIN14_PINREG & CORE_PIN14_BITMASK) ? 1 : 0;
    		} else if (pin == 15) {
    			return (CORE_PIN15_PINREG & CORE_PIN15_BITMASK) ? 1 : 0;
    		} else if (pin == 16) {
    			return (CORE_PIN16_PINREG & CORE_PIN16_BITMASK) ? 1 : 0;
    		} else if (pin == 17) {
    			return (CORE_PIN17_PINREG & CORE_PIN17_BITMASK) ? 1 : 0;
    		} else if (pin == 18) {
    			return (CORE_PIN18_PINREG & CORE_PIN18_BITMASK) ? 1 : 0;
    		} else if (pin == 19) {
    			return (CORE_PIN19_PINREG & CORE_PIN19_BITMASK) ? 1 : 0;
    		} else if (pin == 20) {
    			return (CORE_PIN20_PINREG & CORE_PIN20_BITMASK) ? 1 : 0;
    		} else if (pin == 21) {
    			return (CORE_PIN21_PINREG & CORE_PIN21_BITMASK) ? 1 : 0;
    		} else if (pin == 22) {
    			return (CORE_PIN22_PINREG & CORE_PIN22_BITMASK) ? 1 : 0;
    		} else if (pin == 23) {
    			return (CORE_PIN23_PINREG & CORE_PIN23_BITMASK) ? 1 : 0;
    		} else if (pin == 24) {
    			return (CORE_PIN24_PINREG & CORE_PIN24_BITMASK) ? 1 : 0;
    		} else if (pin == 25) {
    			return (CORE_PIN25_PINREG & CORE_PIN25_BITMASK) ? 1 : 0;
    		} else if (pin == 26) {
    			return (CORE_PIN26_PINREG & CORE_PIN26_BITMASK) ? 1 : 0;
    		}
    		#if defined(CORE_PIN27_PINREG)
    		  else if (pin == 27) {
    			return (CORE_PIN27_PINREG & CORE_PIN27_BITMASK) ? 1 : 0;
    		} else if (pin == 28) {
    			return (CORE_PIN28_PINREG & CORE_PIN28_BITMASK) ? 1 : 0;
    		} else if (pin == 29) {
    			return (CORE_PIN29_PINREG & CORE_PIN29_BITMASK) ? 1 : 0;
    		} else if (pin == 30) {
    			return (CORE_PIN30_PINREG & CORE_PIN30_BITMASK) ? 1 : 0;
    		} else if (pin == 31) {
    			return (CORE_PIN31_PINREG & CORE_PIN31_BITMASK) ? 1 : 0;
    		} else if (pin == 32) {
    			return (CORE_PIN32_PINREG & CORE_PIN32_BITMASK) ? 1 : 0;
    		} else if (pin == 33) {
    			return (CORE_PIN33_PINREG & CORE_PIN33_BITMASK) ? 1 : 0;
    		}
    		#endif
    		  else {
    			return 0;
    		}
    	} else {
    		#if defined(KINETISK)
    		return *portInputRegister(pin);
    		#else
    		return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
    		#endif
    	}
    }
    Apart from some preprocessor directives which slighty reduce the length of code, there are _alot_ of time consuming "else if" instructions.

    In my current project, I only need to read two digital pins (2 and 3). I thought of writing a custom "warpRead" or "blazingFastRead" function to eliminate those unuseful steps.

    What do I actually need from the function above? By example, if I want to read pin 2, the above function returns:

    Code:
    return (CORE_PIN2_PINREG & CORE_PIN2_BITMASK) ? 1 : 0;
    That's it? I only have to do this registry operation?

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,349
    The compiler already does this if "pin" is a constant.

  3. #3
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Thanks, Frank! But for the record, it only takes that registry operation?

    So this two lines:

    Code:
    pin2 = (CORE_PIN2_PINREG & CORE_PIN2_BITMASK) ? 1 : 0;
    
    pin2 = digitalReadFast(2);
    should be identical (compiler wise)?

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,092
    Yes, the generated code should be identical.

    From a source code perspective, this makes your code less readable and more difficult to modify for other pins. Hardly seems like progress.

  5. #5
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Thanks for confirmation, Paul. If the generated code is identical, case closed.

    (as for the source code, I thought about using some inline #define directive for that registry operation)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •