I think it's good to have a stringifying macro in your utils header:
#define STR_IMPL_(x) #x //stringify argument
#define STR(x) STR_IMPL_(x) //indirection to expand argument macros
Then you can keep the macro numerical and stringify it on the spot:
#define LEDS 48
int x = LEDS;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, "STR(LEDS)" \n\t"
...
}
The above preprocesses to:
int x = 48;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, ""48"" \n\t"
...
}
which relies on the fact that adjacent string literals get concatenated.
You can avoid the stringification macro mess if you use a constraint:
#define LEDS 48
void DrawFrame()
{
asm volatile(
"ldi R18, %[leds]"
: : [leds] "M" (LEDS) : "r18");
}
You need two auxiliary macros for this to work. Then you can take advantage of automatic string concatenation:
#define STR(x) #x
#define EXPAND(x) STR(x)
#define LEDS 48
int x = LEDS;
void DrawFrame()
{
asm(
"ldi R27, 0x00 \n\t"
"ldi R26, 0x00 \n\t"
"ldi R18, " EXPAND(LEDS) " \n\t"
...
}
The reason for using two macros is that the first alone won't expand the parameter passed in.
If you just did this:
printf("LEDS = " STR(LEDS) "\n");
It would expand to this:
printf("LEDS = " "LEDS" "\n");
The EXPAND
macro allows the parameter passed in to be substituted as well.
So then this:
printf("LEDS = " EXPAND(LEDS) "\n");
Would expand to this:
printf("LEDS = " "48" "\n");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With