PDA

View Full Version : Pic FPU



Art
- 2nd November 2013, 12:44
Hi Guys,

Has anyone considered writing an FPU for a pic to run side by side another pic
so that a PBP program can request results for floating point operations (trig functions) ?
I figure a 4 or 8 bit interface to a fast chip would be much faster than having the
same chip doing cordic trig, but of course, would add expense by requiring another chip.

I'm working on a project currently for dsPic33FJ128GP802, which is pin for pin compatible
with some other devices of more or less specification such as memory space.
These kind of operations are child's play in Microchip's C, but I never thought to make a
slave math device for another pic running a PBP program.

Only issue is the device I'm using is 3.6Volts (or 3.3).. I didn't have to make the circuit,
I just have to expand on the thing which is a single chip web server.
I haven't looked into a PBP compatible pic that operates on the lower voltage.
Are these abundant?
Cheers, B.

Darrel Taylor
- 2nd November 2013, 15:18
That's exactly what the uM-FPU (http://www.micromegacorp.com/umfpu-v3.html) does ... and a lot more.
It's made from a dsPIC.

They are about $20 each.
But if you consider the time it will take you to recreate one (several months) then they're extremely cheap.

It's pretty cool, because it has a utility that writes your PBP side code for you.

I've only used it once for a Quaternion to Euler Angle convertor, but it worked great.

You enter math like ...
X = (2 * qYF * qWF) - (2 * qXF * qZF)
Y = 1 - ((2 * (qYF * qYF)) - (2 * (qZF * qZF)))
heading = DEGREES(ATAN2(X,Y))
attitude = DEGREES(asin((2*qXF*qYF) + (2*qZF*qWF)))

X = (2 * qXF * qWF) - (2 * qYF * qZF)
Y = 1 - ((2 * (qXF * qXF)) - (2 * (qZF * qZF)))

banking = DEGREES(ATAN2(X,Y))

Angle = heading * 10
And it spits out PBP code like this ...
' X = (2 * qYF * qWF) - (2 * qXF * qZF)
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, X, LEFT, FSETI, 2, FMUL, qYF,_
FMUL, qWF, RIGHT, FSET0, LEFT, FSETI, 2, FMUL, qXF, FMUL, qZF, RIGHT, FSUB0]
' Y = 1 - ((2 * (qYF * qYF)) - (2 * (qZF * qZF)))
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, Y, FSETI, 1, LEFT, LEFT,_
FSETI, 2, LEFT, FSET, qYF, FMUL, qYF, RIGHT, FMUL0, RIGHT, FSET0, LEFT,_
FSETI, 2, LEFT, FSET, qZF, FMUL, qZF, RIGHT, FMUL0, RIGHT, FSUB0, RIGHT,_
FSUB0]
' heading = DEGREES(ATAN2(X,Y))
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, heading, LEFT, LEFT, FSET, X,_
ATAN2, Y, RIGHT, FSET0, DEGREES, RIGHT, FSET0]
' attitude = DEGREES(asin((2*qXF*qYF) + (2*qZF*qWF)))
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, attitude, LEFT, LEFT, LEFT,_
FSETI, 2, FMUL, qXF, FMUL, qYF, RIGHT, FSET0, LEFT, FSETI, 2, FMUL, qZF,_
FMUL, qWF, RIGHT, FADD0, ASIN, RIGHT, FSET0, DEGREES, RIGHT, FSET0]
'
' X = (2 * qXF * qWF) - (2 * qYF * qZF)
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, X, LEFT, FSETI, 2, FMUL, qXF,_
FMUL, qWF, RIGHT, FSET0, LEFT, FSETI, 2, FMUL, qYF, FMUL, qZF, RIGHT, FSUB0]
' Y = 1 - ((2 * (qXF * qXF)) - (2 * (qZF * qZF)))
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, Y, FSETI, 1, LEFT, LEFT,_
FSETI, 2, LEFT, FSET, qXF, FMUL, qXF, RIGHT, FMUL0, RIGHT, FSET0, LEFT,_
FSETI, 2, LEFT, FSET, qZF, FMUL, qZF, RIGHT, FMUL0, RIGHT, FSUB0, RIGHT,_
FSUB0]
'
' banking = DEGREES(ATAN2(X,Y))
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, banking, LEFT, LEFT, FSET, X,_
ATAN2, Y, RIGHT, FSET0, DEGREES, RIGHT, FSET0]
'
' Angle = heading * 10
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [SELECTA, 0, LEFT, FSET, heading,_
FMULI, 10, RIGHT, FIX]
GOSUB Fpu_Wait
I2CWRITE Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [LREAD0]
GOSUB Fpu_ReadDelay
I2CREAD Fpu_SDA, Fpu_SCL, Fpu_ID, 0, [Angle(3), Angle(2), Angle(1), Angle(0)]


There are some variables to set up too.
The chip does the rest.

Art
- 2nd November 2013, 16:24
I did figure the only difficulty is coming up with a protocol
to speak between the two.
Obviously have to tell it what operation to do,
and the FPU part has to cram the float into the best possible integer.

Was thinking simpler than that, one operation at a time, but free code in the end.

I2C I didn't consider. Not sure if I have I2C slave code on the C side.

andywpg
- 2nd November 2013, 22:04
That's exactly what the uM-FPU (http://www.micromegacorp.com/umfpu-v3.html) does ... and a lot more.
It's made from a dsPIC.

They are about $20 each.
But if you consider the time it will take you to recreate one (several months) then they're extremely cheap.

I was going to suggest the exact same thing.....



I've only used it once for a Quaternion to Euler Angle convertor, but it worked great.


So I says: "Pardon? Was that in English??" :eek: Honestly, I don't have the FAINTEST idea what that means!

Art
- 3rd November 2013, 02:08
Maybe it would be easier instead to focus on gfx displays so no floats ever have to
be transmitted, but rather, only integer screen coordinates.

Say you wanted a clock face with hands you could send the coordinates of the
point you want rotated, and the angle of rotation, the coordinates of the origin,
and the chip provides the new coordinate integers.

I know there is a clock example here, but without looking I'd say a number
of points about the clock face are pre-defined.
I'll bet it cannot currently have a sweeping second hand (for example).

Darrel Taylor
- 3rd November 2013, 02:16
So I says: "Pardon? Was that in English??" :eek:
Probably not ...

Quaternions were developed by an Irish mathematician, and Euler Angles (pronounced Oiler Angle) were from a Swiss mathematician.

Play around with Digital Gyro's and Accelerometers, and you're sure to come across them.

They are used in rotating 3D objects too.

Normnet
- 3rd November 2013, 13:57
Art

As a side note is there a reason you require floats in place of Longs?
Couldn't a Long result be used as a float by determining the decimal point by division by a multiple of 10?

For larger values Darrel's lesser known N-Bit_MATH (http://www.picbasic.co.uk/forum/showthread.php?t=12433&highlight=N-Bit_MATH) could be utilized.


Norm

Art
- 3rd November 2013, 23:05
Hi,
It's not the numbers that are needed, but the math,
and in particular, of interest to me, trigonometric functions
not implemented in PBP such as: sin, cos, tan, etc.
needed for calculations such as distance,bearing,foot of perpendicular,
anything to do with angles in games (ball bouncing of a wall at the inverse angle), etc.

Normnet
- 3rd November 2013, 23:15
Hi,
It's not the numbers that are needed, but the math,
and in particular, of interest to me, trigonometric functions
not implemented in PBP such as: sin, cos, tan, etc.
needed for calculations such as distance,bearing,foot of perpendicular,
anything to do with angles in games (ball bouncing of a wall at the inverse angle), etc.
Your saying calculations like sin etc. require floating point in place of the use of Longs?

Norm

Art
- 4th November 2013, 02:09
No, because I've seen that cordic trig has been implemented with PicBASIC,
and is demonstrated by a program that can calculate distance and bearing
given a set of geo-coordinates.

I'm saying any purely PBP implementation I've seen is slow and memory consuming,
and unsuitable for anything requiring the speed for a graphics display.

The dspic at 40MIPS should really be doing the whole job,
but in reality, I'd get the job done quicker with a low end pic using PBP
when it comes to interfaces and talking to other devices,
but that could change if one became familiar with the C libraries used
for the communication. A large part of what PBP is, is a collection of
similar libraries in RISC asm.

I think it would be easiest to emulate the comms of LCDOUT/LCDIN
with 8 bit interface, so you could use LCDOUT to talk to it.