1
\$\begingroup\$

I am getting started learning more about AVR ATMEGA programming. Reading an article about the inner workings of Arduinos, I am learning how the shiftOut method is structured. I am kind of familiar with bitwise operations so far, but I have an expression I do not understand yet:

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST) {
            PORTD |= !!(val & (HIGH << i)); 
        } else {
            PORTD |= !!(val & (HIGH << (7 - i)));           
        }   
        PORTB |= (HIGH << clockPin);
        PORTB ^= (HIGH << clockPin);
    }
}

The line PORTD |= !!(val & (HIGH << i)); is not 100% clear to me. I understand that i set the i-th bit High on PORTD but what das the !! mean and val&(HIGH <<i))

I know this might sound basic, but can you please help me out?

\$\endgroup\$
1
\$\begingroup\$

In C, ! is the logical negation operator: !x has the value 1 if x is falsy (i.e. zero), and the value 0 if x is truthy (i.e. non-zero). !!x has just two negations back-to-back, which gives the same logical truth value as x itself, but it collapses all true values to 1. (It's worth remembering that e.g. 2, 0x1000, and -123 are all true in C.)

(val & (HIGH << i))

This is just HIGH shifted left by i bits, and that value anded with val. i.e. if HIGH is 1, it picks the ith bit of val (counting from zero).

So, e.g. if i is 3, (val & (1 << i)) might be 0x08, and the following !! would collapse that to 1.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.