Hi Guys,
I'm working on a project where I need to take 1024 samples from an ADC and do an FFT of the data. I have a working program on the Raspberry Pi and wanted to just port the C code from there to the Arduino so I copied and pasted in the FFT routine However, it wont compile and I just get the following error: unable to find a register to spill in class 'POINTER_REGS' so I went through the code commenting out line by line to see where the faiult lies and there are two lines which if commented out, will compile. This is the code
void dofft(double *xreal,int n)
{
int n0, k0 = 0, sby2, p, q, s, index, jndex, itemp, i, j, l;
static int first_call_flag = 1, l2n;
static double gain, angle, re, im;
double xtempreal, xtempimag, treal, timag, vreal, vimag;
double wreal, wimag, temp, wrtemp, *ximag,*ureal,*uimag;
ximag = (double *) calloc(2*n+1,sizeof(double));
ureal = (double *) calloc(n/2+1,sizeof(double));
uimag = (double *) calloc(n/2+1,sizeof(double));
if (ximag == NULL || ureal == NULL || uimag == NULL) abort();
if ( first_call_flag == 1)
{
l2n = 0;
n0 = 1;
do
{
l2n += 1;
n0 = n0 + n0;
}
while (n0 < n);
gain = 1.0 / n;
angle = 2.0 * M_PI * gain;
re = cos(angle);
im = sin(angle);
}
/* Compute the complex exponentials if this is the first call */
if (first_call_flag ==1 && k0 < 1)
{
ureal[1] = re;
uimag[1] = -fabs (im);
for ( i = 2; i <= l2n; ++i )
{
ureal[i] = ureal[i-1] * ureal[i-1] - uimag[i-1] * uimag[i-1];
uimag[i] = 2. * ureal[i-1] * uimag[i-1];
}
k0 = 1;
}
/**************** Main loop ****************/
sby2 = n;
for ( j = 1; j <= l2n; ++j )
{
vreal = ureal[j];
vimag = uimag[j];
wreal = 1;
wimag = 0;
s = sby2;
sby2 = s / 2;
for ( l = 1; l <= sby2; ++l )
{
for ( i = 1; i <= n; i = i + s )
{
p = i + l - 1;
q = p + sby2;
treal = xreal[p] + xreal[q];
timag = ximag[p] + ximag[q];
temp = xreal[q];
xreal[q] = (xreal[p] - xreal[q]) * wreal - (ximag[p] - ximag[q]) * wimag;
ximag[q] = (ximag[p] - ximag[q]) * wreal + (xreal[p] - temp) * wimag;
xreal[p] = treal;
ximag[p] = timag;
}
wrtemp = wreal;
wreal=wreal*vreal-wimag*vimag;
wimag=wrtemp*vimag+wimag*vreal;
}
}
/* Reorder the elements using bit reversal */
for ( i = 1; i <= n; ++i )
{
index = i - 1;
jndex = 0;
for ( j = 1; j <= l2n; ++j )
{
jndex = jndex + jndex;
itemp = index / 2;
if ( itemp + itemp != index) jndex +=1;
index = itemp;
}
j = jndex + 1;
if ( j >= i)
{
xtempreal = xreal[j];
xtempimag = ximag[j];
xreal[j] = xreal[i];
ximag[j] = ximag[i];
xreal[i] = xtempreal;
ximag[i] = xtempimag;
}
}
for ( i = 1; i <= n; ++i )
xreal[n+i] = ximag[i];
for( i=1; i<=n; i++ )
xreal[i]=absolute( xreal[i],ximag[i])*gain;
free(uimag);
free(ureal);
free(ximag);
}
and if I comment out
wreal=wrealvreal-wimagvimag;
wimag=wrtempvimag+wimagvreal;
it will compile but obviously not to the fft correctly.
The full error message is
C:\Users\Steve\Documents\Arduino\ADCFFT\ADCFFT.ino: In function 'void dofft(double*, int)':
ADCFFT:162: error: unable to find a register to spill in class 'POINTER_REGS'
}
^
ADCFFT:162: error: this is the insn:
(insn 163 162 165 15 (set (reg/v:SF 89 [ vreal ])
(mem:SF (post_inc:HI (reg:HI 157 [ ivtmp.141 ])) [3 MEM[base: _96, offset: 0B]+0 S4 A8])) C:\Users\Steve\Documents\Arduino\ADCFFT\ADCFFT.ino:103 99 {*movsf}
(expr_list:REG_INC (reg:HI 157 [ ivtmp.141 ])
(nil)))
C:\Users\Steve\Documents\Arduino\ADCFFT\ADCFFT.ino:162: confused by earlier errors, bailing out
Using library MCP3208 in folder: C:\Users\Steve\Documents\Arduino\libraries\MCP3208 (legacy)
Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI
exit status 1
unable to find a register to spill in class 'POINTER_REGS'
Now, I've googled this problem and found may instances and several remedies but none that have worked for me. Can anyone please throw any light on the matter?
Thanks, Steve.