In the FFT.h library I find:
#define STRINGIFY_(a) #a
#define STRINGIFY(a) STRINGIFY_(a)
and later I find
// do first set of butterflies - all real, no multiplies
// initialize
** asm volatile (**
** "clr r15 \n" // clear the null register**
** "ldi r16, "STRINGIFY(FFT_N/2)" \n" // prep loop counter**
** "ldi r28, lo8(fft_input) \n" //set to beginning of data space**
** "ldi r29, hi8(fft_input) \n"**
Is there a different way I can do this? I have written my share of assembly languange, but never in Arduino so I don't recognize what is happening when doing #FFT_N/2
It would appear to be a roundabout way of getting the compiler to calculate FFT_N divided by 2, where FFT_N is probably an #define somewhere else, and then load that number as an immediate operand into register 16.
Why you would have one pseudo function macro invoke another one like that, I don't know.
If you want to do this "another way", I'd suggest picking your FFT_N ( 32, 64, 128 probably ) and then writing half that value directly into the embedded assembly code, so the line will probably look like this
"ldi r16, #32\n" for example, if your FFTN_N is 64
Actually, disregard that last suggestion. It would appear that there is no # required in that assembly language LDI command.
You might find a better answer here.
http://www.avr-asm-tutorial.net/avr_en/beginner/REGISTER.html
The # pre-processor operator turns a literal into a string. So, whatever follows the # gets put into quotes:
#define foo(s) #s
foo(hello) becomes "hello"
One common use for this is to get strings corresponding to the names of members of an enum, without having to manually create an array of strings.
The example in the OP is more complicated, because there are rules for the order in which pre-processor substitutions are carried out, and I'm too lazy to figure out exactly what's going on in the OP. But, I would guess it's creating a string literal from the result of a calculation.
Regards,
Ray L.
#define STRINGIFY_(a) #a
#define STRINGIFY(a) STRINGIFY_(a)
Here's my guess:
First, this:
"ldi r16, "STRINGIFY(FFT_N/2)" \n" // prep loop counter
gets replaced with this:
"ldi r16, "STRINGIFY_(FFT_N/2)" \n" // prep loop counter
which then gets replaced with this:
"ldi r16, ""FFT_N/2"" \n" // prep loop counter
which is interpreted as this:
"ldi r16, FFT_N/2 \n" // prep loop counter
This appears to be loading register 16 with the address of FFT_N, whatever that is....
Regards,
Ray L.
Here's my guess:
First, this:
"ldi r16, "STRINGIFY(FFT_N/2)" \n" // prep loop counter
gets replaced with this:
"ldi r16, "STRINGIFY_(FFT_N/2)" \n" // prep loop counter
which then gets replaced with this:
"ldi r16, ""FFT_N/2"" \n" // prep loop counter
which is interpreted as this:
"ldi r16, FFT_N/2 \n" // prep loop counter
This appears to be loading register 16 with the address of FFT_N, whatever that is....
Regards,
Ray L.
Indeed. Replacing "STRINGIFY(...)" with the actual number, say "128", does compile nicely.
Thanks.
This appears to be loading register 16 with the address of FFT_N, whatever that is....
Why would you think that this is loading the address ?