who can explain this code ???? thx

#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) 0
#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) // AVR_ATmega32U4 has an unusual mapping of pins to channels extern const uint8_t PROGMEM analog_pin_to_channel_PGM;
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )

Do you recognize the ternary operator being used? Do you know what it does?

This code defines several pseudo-functions, which have the effect of mapping some kind of pin number to some different kind of pin number.

Maybe, from the arduino board pin number to the atmel chip pin number. Or the other way around.

The #define creates a text substitution in the C/C++ preprocessor by which, if you use one these pseudo-functions in your code, your apparent function call to the pseudo-function gets textually replaced by all the crap you see there.

Ternary operator

<condition> ? <true_statement> : <false statement>

is the same as

if <condition> 
  <true_statement>
else
  <false_statement>

Looks like stuff written by someone who thought that he would look more important if he wrote incomprehensible code.

...R

Robin2: Looks like stuff written by someone who thought that he would look more important if he wrote incomprehensible code.

...R

Arduino stuff? :)

It is probably snippet from pins_arduino.h or something like this for board variant. It's definition for the Pin Change Interrupt Control Register.

Hi, Looks like its written to try and save space, it probably does in the IDE editor, but the compiler probably undoes it all to a HEX code the same as the if else etc etc. That is if it does compile.

Tom.... :)

That is if it does compile.

If it's a simple copy of the code in pins_arduino.h, I think it's fairly safe to assume it compiles.

Amarino:
#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))

Sometimes lines like these are messy, but the most truthful description of what is going on. So what I do, is use multiple lines to make it more readable. Code generally allows whitespace, but #defines require the \ line continuator:

#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) \
                                 || ((p) >= 14 && (p) <= 17) \
                                 || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))

Isn’t that a whole lot better?

Isn’t that a whole lot better?

It’s better, but what would have been a whole lot better was for the original author to have spent 30 seconds writing some comments.

PaulS: It's better, but what would have been a whole lot better was for the original author to have spent 30 seconds writing some comments.

I completely agree, I thought of comments but forgot to mention it.

#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))

This means that Pins 8-11, 14-17, and A8-A10 use the Pin Change Interrupt Control Register named “PCICR” and all other pins don’t support Pin Change Interrupts.

#define digitalPinToPCICRbit(p) 0

This means that bit 0 is the bit of the PCICR that controls the pin change interrupt.

#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))

This means that Pins 8-11, 14-17, and A8-A10 use the Pin Change Maskl Register named “PCMSK0” and all other pins don’t support Pin Change Interrupts.

#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))

This maps the pin number to the bit within the mask register:
8 → 4
9 → 5
10 → 6
11 → 7
14 → 3
15 → 1
16 → 2
17 → 0
A8 → 4
A9 → 5
A10 → 6

 // __AVR_ATmega32U4__ has an unusual mapping of pins to channels 
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; 
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )

This all means that the mapping from analog input pins to analog input multiplexer channels is too complex to put in a macro so they put it in a lookup table in PROGMEM.