Problem
Programming reusable modules for microcontrollers (AVR in my case) requires flexibility in common IO pins. Each pin is identified by a letter (AG) and a number (0-7). However, it is controlled by one bit in the same position in three registers. Thus, the configuration file should contain four entries (3 pointers to registers + 1 position), which is not so elegant.
An easy solution is to simply accept it, but since it is such a common problem, it deserves at least a little attention.
Idea
It would be nice if the precompiler did the repetitive work as follows:
//CONFIGURATION
The results should look like this:
PORT_(IO_NAME) => PORTB PIN_(IO_NAME) => PINB DDR_(IO_NAME) => DDRB BIT_(IO_NAME) => 5
The resulting expressions are defined in AVR Studio.
What i tried
I could not figure out how to ignore either the letter and not the number, so instead I tried concatention:
#define PORT_(REG, BIT) PORT_2(REG, BIT) #define PIN_(REG, BIT) PIN_2(REG, BIT) #define DDR_(REG, BIT) DDR_2(REG, BIT) #define PORT_2(REG, BIT) (PORT ## REG) #define PIN_2(REG, BIT) (PIN ## REG) #define DDR_2(REG, BIT) (DDR ## REG) #define BIT(REG, BIT) (BIT)
The extra layer should use any #defined value as REG or BIT.
The following code works as intended:
#define IO_NAME_REG B #define IO_NAME_BIT 5 PORT_(B, 5) => PORTB PORT_(IO_NAME_REG, IO_NAME_BIT) => PORTB
When I, however, try
#define IO_NAME B, 5 PORT_(IO_NAME)
this leads to an error:
macro "PORT_" requires 2 arguments, but only 1 given
As I understand it, the comma is interpreted as a comma operator, and therefore the left value is ignored. I did this in this experiment:
#define IO_NAME B, 5 PORT_(IO_NAME,) => PORT_5
Replacing a comma with a definition:
#define comma , #define IO_NAME B comma 5 PORT_(IO_NAME,) => PORT_5
leads to the same result
Bypass
Of course, you can divide “B” and “5” into two separate ones. Although this improvement is over four, it is still not so convenient.
Question
... is not limited to the title. Any solution that is shorter or simpler than
#define IO_NAME_REG B #define IO_NAME_BIT 5 PORT_(IO_NAME_REG, IO_NAME_BIT) => PORTB
Greetings to me.
If this is simply not possible, I would like to know the reasons why.