Question about adapting pins_arduino.h

Hello all,

I'm trying to use the Arduino IDE on several ATMega 169P devices and there for am trying to modify the pins_arduino.h file for this chip.

When looking at the pins_arduino.h used for the standard boards all the pin and port array things are straight forward even for me as an beginner, but I can't make out the logic in the following part of the code:

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))

#define digitalPinToInterrupt(p)  ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))

I do understand the function of PCICR and PCMSK for the pinchange interupt, but don't understand the pin/bit definition with the use of "<=", "?",">=", etc.
I hope someone can explain how the statemens are constructed so I can understand how to construct my own in realtion to the datasheet of the ATmega169P.

Manny thanks in advance.

if a then b else c

can be written in C++ as

a ? b : c

(((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

becomes

if ((p) >= 0 && (p) <= 21) then (&PCICR) else ((uint8_t *)0)

Hello Rob,

Thanks for your explaination, I addded some comments to the code, could you check if my understanding of it is correct?

//  select the interrupt  register for pins 0-21.
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

// select value 2 for pin 0-7, value for pin number higher then 13 and else value 1??
//  What does this do ??
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))

// Select the right interrupt mask: PCMSK2 for pins 0-7, select PCMSK0 for pins 13-21, select PCMSK1 for pin 21 and up.
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))

//Select the right bit in the mask: convert pin number to bit 0-7.
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))

// Assign interrupt numbers to pin 2 and 3
#define digitalPinToInterrupt(p)  ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))

think the names of the #defines are quite explicit

If you should explain something with comments it are the acronyms like PCICR

In general they translate the user level pin numbers to the underlying hardware registers / bits.