Question about digital(Read/write)fast

manicksan

Well-known member
I don't really understand how digitalWriteFast should make it faster,
it's fast for the first set of pins

but for pin 54 it have to go through all the first 0-53 pins so there is a shift in time which pin you use,
in VHDL it's another matter because there everything "executes" at the same time.

Code:
static inline void digitalWriteFast(uint8_t pin, uint8_t val)
{
    if (__builtin_constant_p(pin)) {
        if (val) {
            if (pin == 0) {
                CORE_PIN0_PORTSET = CORE_PIN0_BITMASK;
            } else if (pin == 1) {
                CORE_PIN1_PORTSET = CORE_PIN1_BITMASK;
            } else if (pin == 2) {
                CORE_PIN2_PORTSET = CORE_PIN2_BITMASK;
            } else if (pin == 3) {
                CORE_PIN3_PORTSET = CORE_PIN3_BITMASK;
            } else if (pin == 4) {
                CORE_PIN4_PORTSET = CORE_PIN4_BITMASK;
            } else if (pin == 5) {
                CORE_PIN5_PORTSET = CORE_PIN5_BITMASK;
            } else if (pin == 6) {
                CORE_PIN6_PORTSET = CORE_PIN6_BITMASK;
            } else if (pin == 7) {
                CORE_PIN7_PORTSET = CORE_PIN7_BITMASK;
            } else if (pin == 8) {
                CORE_PIN8_PORTSET = CORE_PIN8_BITMASK;
            } else if (pin == 9) {
                CORE_PIN9_PORTSET = CORE_PIN9_BITMASK;
            } else if (pin == 10) {
                CORE_PIN10_PORTSET = CORE_PIN10_BITMASK;
            } else if (pin == 11) {
                CORE_PIN11_PORTSET = CORE_PIN11_BITMASK;
            } else if (pin == 12) {
                CORE_PIN12_PORTSET = CORE_PIN12_BITMASK;
            } else if (pin == 13) {
                CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;
            } else if (pin == 14) {
                CORE_PIN14_PORTSET = CORE_PIN14_BITMASK;
            } else if (pin == 15) {
                CORE_PIN15_PORTSET = CORE_PIN15_BITMASK;
            } else if (pin == 16) {
                CORE_PIN16_PORTSET = CORE_PIN16_BITMASK;
            } else if (pin == 17) {
                CORE_PIN17_PORTSET = CORE_PIN17_BITMASK;
            } else if (pin == 18) {
                CORE_PIN18_PORTSET = CORE_PIN18_BITMASK;
            } else if (pin == 19) {
                CORE_PIN19_PORTSET = CORE_PIN19_BITMASK;
            } else if (pin == 20) {
                CORE_PIN20_PORTSET = CORE_PIN20_BITMASK;
            } else if (pin == 21) {
                CORE_PIN21_PORTSET = CORE_PIN21_BITMASK;
            } else if (pin == 22) {
                CORE_PIN22_PORTSET = CORE_PIN22_BITMASK;
            } else if (pin == 23) {
                CORE_PIN23_PORTSET = CORE_PIN23_BITMASK;
            } else if (pin == 24) {
                CORE_PIN24_PORTSET = CORE_PIN24_BITMASK;
            } else if (pin == 25) {
                CORE_PIN25_PORTSET = CORE_PIN25_BITMASK;
            } else if (pin == 26) {
                CORE_PIN26_PORTSET = CORE_PIN26_BITMASK;
            } else if (pin == 27) {
                CORE_PIN27_PORTSET = CORE_PIN27_BITMASK;
            } else if (pin == 28) {
                CORE_PIN28_PORTSET = CORE_PIN28_BITMASK;
            } else if (pin == 29) {
                CORE_PIN29_PORTSET = CORE_PIN29_BITMASK;
            } else if (pin == 30) {
                CORE_PIN30_PORTSET = CORE_PIN30_BITMASK;
            } else if (pin == 31) {
                CORE_PIN31_PORTSET = CORE_PIN31_BITMASK;
            } else if (pin == 32) {
                CORE_PIN32_PORTSET = CORE_PIN32_BITMASK;
            } else if (pin == 33) {
                CORE_PIN33_PORTSET = CORE_PIN33_BITMASK;
            } else if (pin == 34) {
                CORE_PIN34_PORTSET = CORE_PIN34_BITMASK;
            } else if (pin == 35) {
                CORE_PIN35_PORTSET = CORE_PIN35_BITMASK;
            } else if (pin == 36) {
                CORE_PIN36_PORTSET = CORE_PIN36_BITMASK;
            } else if (pin == 37) {
                CORE_PIN37_PORTSET = CORE_PIN37_BITMASK;
            } else if (pin == 38) {
                CORE_PIN38_PORTSET = CORE_PIN38_BITMASK;
            } else if (pin == 39) {
                CORE_PIN39_PORTSET = CORE_PIN39_BITMASK;
#if CORE_NUM_DIGITAL >= 55
            } else if (pin == 40) {
                CORE_PIN40_PORTSET = CORE_PIN40_BITMASK;
            } else if (pin == 41) {
                CORE_PIN41_PORTSET = CORE_PIN41_BITMASK;
            } else if (pin == 42) {
                CORE_PIN42_PORTSET = CORE_PIN42_BITMASK;
            } else if (pin == 43) {
                CORE_PIN43_PORTSET = CORE_PIN43_BITMASK;
            } else if (pin == 44) {
                CORE_PIN44_PORTSET = CORE_PIN44_BITMASK;
            } else if (pin == 45) {
                CORE_PIN45_PORTSET = CORE_PIN45_BITMASK;
            } else if (pin == 46) {
                CORE_PIN46_PORTSET = CORE_PIN46_BITMASK;
            } else if (pin == 47) {
                CORE_PIN47_PORTSET = CORE_PIN47_BITMASK;
            } else if (pin == 48) {
                CORE_PIN48_PORTSET = CORE_PIN48_BITMASK;
            } else if (pin == 49) {
                CORE_PIN49_PORTSET = CORE_PIN49_BITMASK;
            } else if (pin == 50) {
                CORE_PIN50_PORTSET = CORE_PIN50_BITMASK;
            } else if (pin == 51) {
                CORE_PIN51_PORTSET = CORE_PIN51_BITMASK;
            } else if (pin == 52) {
                CORE_PIN52_PORTSET = CORE_PIN52_BITMASK;
            } else if (pin == 53) {
                CORE_PIN53_PORTSET = CORE_PIN53_BITMASK;
            } else if (pin == 54) {
                CORE_PIN54_PORTSET = CORE_PIN54_BITMASK;
#endif

but in the original
it uses a big lockup table which "generates" the same timing for each pin

its very messy but a similar structure could be used for the fast variants?

Code:
void digitalWrite(uint8_t pin, uint8_t val)
{
    const struct digital_pin_bitband_and_config_table_struct *p;
    uint32_t pinmode, mask;

    if (pin >= CORE_NUM_DIGITAL) return;
    p = digital_pin_to_info_PGM + pin;
    pinmode = *(p->reg + 1);
    mask = p->mask;
    if (pinmode & mask) {
        // pin is configured for output mode
        if (val) {
            *(p->reg + 0x21) = mask; // set register
        } else {
            *(p->reg + 0x22) = mask; // clear register
        }
    } else {
        // pin is configured for input mode
        // value controls PULLUP/PULLDOWN resistors
        if (val) {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
        } else {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS;
        }
    }
}


/jannik
 
but for pin 54 it have to go through all the first 0-53 pins so there is a shift in time which pin you use,

No. The compiler is much smarter at optimizing. It automatically removes the code for all the other cases which don't apply. That is the nature of "__builtin_constant_p", it detects when the compiler is able to know the actual value at compile time.

All pins are treated the same fast timing, because the compiler throws away all the other code and only uses the 1 which actually applies.
 
OK thanks,
I did not know that __builtin_constant_p was a compiler directive.
That is a very smart solution.

/jannik
 
Back
Top