cancel
Showing results for 
Search instead for 
Did you mean: 

How to use the fpu in stm32f4xx ?

manes6969
Associate II
Posted on December 13, 2011 at 21:24

Hi,

How do I exactly use the fpu after enabled it ?

How do I for example put 5.5 into it and add 3.25 for example

Dooes my software have to do the conversion and just let the fpu cdo the addition , or is the fpu also capable of doing the conversion from 5.5 integer to float ?

Is there any good reference on this subject ?

Thanks!

Ronny Suy

#fpu-vfp
15 REPLIES 15
Posted on December 14, 2011 at 03:26

ARM's documentation might be a good start.

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439c/DDI0439C_cortex_m4_r0p1_trm.pdf

Yes, there are conversion instructions.

You should be able to write assembler instructions, if the assembler supports the M4.

You should be able to use float/double in C, and use the compiler options to use the intrinsic fpu instructions, instead of using the software floating point library it would utilize for M3 designs.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
manes6969
Associate II
Posted on December 14, 2011 at 19:32

Posted on December 14, 2011 at 21:00

Ok, well let's try this a different way.

If you want more of a background on floating point, and FPU operations in general, I'd recommend looking at some books/docs on the 80x87 and 68881/68882 type parts. That and the IEEE-754 standard.

http://en.wikipedia.org/wiki/IEEE_754-1985

The conversion of floats to/from ASCII-Decimal is a fairly complicated process, and not something implicitly done by the FPU. The FPU can do float-integer conversions, but clearly the range of a 32-bit integer is smaller than a float/double. The ASCII stuff will require that to multiple/divide by 10 and encode/extract the digits. To handle all cases it ends up as a non-trivial exercise. If you have some more constrained numbers, and output format, it can be somewhat simpler.

For ASCII to float, look at how this is done with atof() or strtod(), and dtoa() for the double to ASCII

http://www.jbox.dk/sanos/source/lib/strtod.c.html

http://www.exploringbinary.com/incorrect-directed-conversions-in-david-gays-strtod/

http://opensource.apple.com/source/JavaScriptCore/JavaScriptCore-1C25/kjs/dtoa.cpp

Unless you really want to get deep into it, and can do the appropriate testing, I would generally recommend the use of built-in functions, and scanf(), printf(), etc to do conversions. The FPU is designed to do the computational side of the work, the input/output side tends to be more inefficient.

http://forums.freescale.com/t5/Kinetis-ARM-Cortex-M4/Using-Cortex-M4-Single-Precision-Floating-point-unit/td-p/74149

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rm23
Associate II
Posted on December 15, 2011 at 12:51

Been there, seen it done it!!!

With the EWARM compiler, the normal maths functions, eg sin/exp etc assume long (8byte) reals, even when you have the compiler option 'USE FPU' switched on (theres a dialog for this), there will be no speed up unless you force your reals to be 4 byte by declaring them as float, and if you use trig functions use sinf rather than sin, lastly if you use constants in your expression, force all bits to be 4 byte by using 'float' in the expression, eg

with all reals declared as 'float'

    phinc=(float)0.001*expf(0.001856*adcvalue);

  and

    x=sinf(phase);

will run fast (approx 28MFlops)

but

    phinc=0.001*exp(0.001856*adcvalue);

  and

    x=sin(phase);

will run slow, not using the FPU even if enabled!!!!!

hope this helps

Posted on December 16, 2011 at 00:04

How do I for example put 5.5 into it and add 3.25 for example

VLDR.F32 s0,=5.5
VLDR.F32 s1,=3.25
VADD.F32 s3,s0,s1 ; s3 = s0 + s1
VCVT.SF32 s2,s3 ; Convert to integer s2 = (int)s3
VMOV r0,s2 ; Copy to ARM register

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
manes6969
Associate II
Posted on December 17, 2011 at 16:35

Dear Clive

Thanks very much for this example !

I tested it , and it really works

the result is 8 , so this is correct because of the rounding I guess.

If I skip the convert instruction , then the result in S3 = 410C0000 , which is , using a IEEE convertor exactly 8.75 !

For input I think I will use some simple multiply/divide by  power of ten and then let the fpu do the job.

Example : 17.3845 is the same as 173845 divided by 10000

Moving these to numbers to the fpu can easily be done , and then I let the fpu divide them

so the internal result will be 17.3845

At least , I hope so , I will test this very soon !

I you're interested , I will let you know the results

Thanks again for your help !

Ronny Suy

Posted on December 19, 2011 at 23:11

I tested it , and it really works

I do try <G>

As Richard points out, the 32-bit float subset supported by the M4 isn't that exciting. Then again the 68882 has 176K transistors, 352 Kflops @ 33 MHz, and had transcendental functions, and 32, 64 and 96-bit floats.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rm23
Associate II
Posted on December 20, 2011 at 23:19

Clive knows the real ins and outs, but I was impressed (~30MFlops), though its a lot slower than an amd/intel  pentium or motorola, its far far less power, and 32 bit reals are actually pretty good in practice - you can get your DSP stuff going without fearasome clipping, and then 'tune the gain' for 32bit integer.

dannym
Associate II
Posted on July 13, 2012 at 12:01

I am using C in Keil here, for the STM32F4 Discovery, with FPU being used.

My problem is attempting to assign a signed int or constant to a Float variable always resulted in the Float being 0.  I recast the int or constant as (float) on the righthand side.

int16_t myInt=0x12345;

float myFloat;

myFloat=(float)myInt;  //gets zero

Is this just a Keil problem, or do I need to be handling floats ''differently'' somehow?