I am writing a driver for avr gpio, I have a function that takes an input which is an enum. I made a macro that calls this function after concatenating the port name with "__" so I can always use initPort(PORTA,1,...).
#define initPort(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)
typedef enum {
PORTA__,
PORTB__,
PORTC__,
PORTD__
} PORT;
void GPIO_Init(PORT p, uint8_t pins, Direction dir,uint8_t pullup) {
switch (p) {
case PORTA__:
now when I want to use that function I use: initPort(PORTA,1,...) and this works fine. The problem is when I want to use something like:
#define LED_PORT PORTA
initPort(LED_PORT,1,...)
what happens now is that the argument of GPIO_Init is now LED_PORT__ and not PORTA__
is it possible to fix this or I have to use another way?
You actually can do it by forcing the preprocessor to perform an extra pass before:
#define initPortS(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)
#define initPort(...) initPortS(__VA_ARGS__)
#define LED_PORT PORTA
initPort(LED_PORT,1,2,3);
This will do:
1st pass:
initPort(LED_PORT,1,2,3); -> initPortS(PORTA,1,2,3);
2nd pass:
initPortS(PORTA,1,2,3); -> GPIO_Init(PORTA__,1,2,3);
Possible pitfall:
If PORTA
is a defined symbol, it will get expanded too on the second pass. So if you have a line such as
#define PORTA XXX
somewhere in the code, it will expand into
GPIO_Init(XXX__,1,2,3);