cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 DSP lib question

guyvo67
Associate II
Posted on February 26, 2009 at 05:02

STM32 DSP lib question

6 REPLIES 6
guyvo67
Associate II
Posted on May 17, 2011 at 13:03

Hi,

I'm recently in a project using a cortex where I need to build-in a FIR filter to make a LP filter on my captured ADC signal. I downloaded the DSP lib files from the ST site. ( FIR , IIR , ... )

I only use the following function which is in fact implemented in assembler for optimization reasons in T2:

typedef struct {

u16 *h;

u32 nh;

} COEFS;

void fir_16by16_stm32(int *a,short *x,struct COEFS *p,unsigned int N)

It's implementation is based on the well known book ''ARM System Developer's Guide'' page (I'm using Ride7/gcc as IDE)

When I write this:

int y[4];

short x[7] = {1,1,1,1,1,1,1};

short hc[4]= {1,1,1,1};

COEFS c;

int main(void)

{

c.h = hc;

c.nh = 4;

fir_16by16_stm32(y, x, c, M);

}

This does not work as it should be why ? Well I will try to explain here what I saw using the Ride simulator:

Out of the filter assembler code the load of the first coefficients (fir_stms)

...

LDRSH r3, [r2], 2 /* Load c_0 */

LDRSH r12, [r2], 2 /* Load c_1 */

...

The LDRSH instruction loads the value at address [R2] but this is not correctly filled as the first 4 bytes point to the the array's address but not to the actual coeff data.

When I change the snippet into:

int y[M];

short x[7] = {1,1,1,1,1,1,1};

short hc[M+1]= {1,1,1,1,4}; --> simulated the struct holder

int main(void)

{

fir_16by16_stm32(y, x, (COEFS *)hc, M);

}

The LDRSH instructions takes the pointer value as it should be now because it's address is not indirectly set and point straight to the array elements.

My questions:

- Is that due to compiler settings because I call assembler form C ?

- Or is this maybe a small bug in the assembler code ?

( where to post that kind of bugs ?)

( attached to this post:

- the FIR assembler code

- PDF description of the lib)

Thanks

Guy

address

mailto:null

Code:

Code:

guyvo67
Associate II
Posted on May 17, 2011 at 13:03

Hi,

I checked the code double and I found a small bug in the DSP lib FIR assembler implementation:

on line 47:

LDMIA r2, {r2, r4} /* Get base address and number of oefficients */

MUST BE:

LDMIA r2!, {r2, r4} /* Get base address and number of oefficients */

All works now.

Any address where I can post this bug fix ?

-G

16-32micros
Associate III
Posted on May 17, 2011 at 13:03

Hi Guy,

Thank you for pointing this issue, I believe it is a minor mistake in the assembly file. I will double check with my colleagues and let you know the status next week.

Cheers,

STOne-32.

guyvo67
Associate II
Posted on May 17, 2011 at 13:03

thanks to look into.

As additional information I can say that if I patch the code I get an assembler warning:

Warning: base register should not be in register list when written back

But this may be due to the fact that the routine is already taken all free registers and it's not possible here to take a free register. As far as I can see the overwrite for R2! does not induce other problems so for this is go.

-G

16-32micros
Associate III
Posted on May 17, 2011 at 13:03

Hi Guy,

After full checking of the issue ; We have found that this behavior is caused by the GNU compiler, whereas with Keil/ARMCC it works perfectly.

In fact, the instruction is correct because R2 is listed in the registers to copy in, so we do not have to put the operator ''!'' for the update.

LDMIA r2, {r2, r4} /* Get base address and number of coefficients */ has been changed by the GNU compiler to LDMIA r2!, {r2, r4} which is incorrect and causes the problem.

So for the workaround, we have to use another register instead of r2, and to modify the assembly code due to that update, we will do it in future and escalate this behavior to GNU/Codesourcery as well for double-check and explanation ?

Hope this helps you !

Cheers,

STOne-32.

guyvo67
Associate II
Posted on May 17, 2011 at 13:03

Quote:

After full checking of the issue ; We have found that this behavior is caused by the GNU compiler, whereas with Keil/ARMCC it works perfectly.

In fact, the instruction is correct because R2 is listed in the registers to copy in, so we do not have to put the operator ''!'' for the update.

LDMIA r2, {r2, r4} /* Get base address and number of coefficients */ has been changed by the GNU compiler to LDMIA r2!, {r2, r4} which is incorrect and causes the problem.

I patched the code like writing:

LDMIA r2!, {r2, r4}

So if I understand you well the gnu compiler changes this finally into :

LDMIA r2, {r2, r4}

I didn't check the lst file actually will do that later on.

Thanks for threating my issue.

Addional info for people with cortex/DSP interest;

I do a filter of type FIR 34 taps in fixed point Q15 in 7µs !

To give you an idea it costs the cortex 5µs todo only one single floating point MAC.

I still have a question/request on th DSP / ADC though:

I'm using the ADC/DMA combination to handle my aquisitions and the use of the cyclic buffer which works great but it's pitty that the cyclic buffer

cannot be directly feed into the DSP functions as an input buffer because it's shifted the other way around.

X0

X1 X0

X2 X1 X0 ....

So my question to the DSP group is it possible to consider this hardware buffer order into the next version of the DSP library ?

Because now I must still shift my input filter buffer and it's a waste compared with the fast memory copy via DMA.

Thanks

-G