Reputation: 821
I have some microcontroller code that uses some header files where GPIO pins are defined like this:
#define PA3 GPIO(GPIO_PORTA, 3)
Using the IDE, I can navigate to the implementation of GPIO
and I find this:
#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
Where pin
is defined as:
const uint8_t pin
and port
is an enum
defined as:
enum gpio_port { GPIO_PORTA, GPIO_PORTB, GPIO_PORTC, GPIO_PORTD, GPIO_PORTE }
I would like to create an array of all the GPIO defins (PA3
, PA4
, etc.) that can be indexed by an integer passed over a serial port.
I tried the following:
GPIO knavePinList[] = {PA3, PA4, PA21, PB4, PHY_RESET_PIN, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9};
But this obviously doesn't work as GPIO
is not a recognized C-type, but in fact a macro. While trying to build, I receive this error message:
unknown type name 'GPIO'
Is it even possible for me to declare an array of macros? If so, how would I note the type for what I'm working with?
Thanks.
Upvotes: 0
Views: 1292
Reputation: 12718
The array you post is perfectly legal, I think you have not tested it. Anyway, it is best to ask with a testable example, (see How to create a Minimal, Complete, and Verifiable example) but the code:
GPIO knavePinList[] = {PA3, PA4, PA21, PB4, PHY_RESET_PIN, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9};
will produce a perfectly legally initialized array of integers, with the bitwise values of the constants you have expanded from the macros. Try to use
cpp source.c | more
to see how the array declaration is actually expanded. By the way, you have another, different problem in your code... you are using the same identifier, GPIO
, to indicate the GPIO
macro name, and the type of the array elements, so when the macro processor encounters it, it sees no parameters, which is not how you have #define
d it, and complaints about a two parameter macro GPIO
called with no parameters at all.
You have to test your code... and send 1. what you expect... and 2. what you get instead... because the error should be evident, if you had simply stopped to read it.
A solution to your problem is to rename the macro GPIO
to GPIO_BITS
for example... and then change all the definitions:
#define GPIO_BITS(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
...
#define PA3 GPIO_BITS(GPIO_PORTA, 3)
so when you encounter the array definition, the type name is not tried to expand as a macro.
Upvotes: 1
Reputation: 123596
No, you cannot create an array of macros like that.
If you want to execute a particular macro based on an input, you will need to use an if-else
or switch
statement. If the input is an integer, you could do something like:
switch( input )
{
case 0: PA3; break;
case 1: PA4; break;
case 2: PA21; break;
...
}
Upvotes: 1
Reputation: 729
#define
statements perform text replacement, they have no inherent type. As you noted, GPIO
is not a valid type, it's a macro that appears to calculate pin numbers/addresses (actually GPIO
is undefined, while GPIO(a,b)
is the macro).
If you want to store an array of many of these, then you need to know what actual type they all evaluate to. Given that the GPIO
macro returns a sum of a port
and a pin
value, where port
is an enum, whose underlying type is int
(technically, it's an implementation specific integral type - see What is the underlying type of a c++ enum?) and pin
is a uint8_t
, the actual type of your array values would also be an integer type - which one specifically depends on your implementation and the range of possible values.
Upvotes: 2