Welcome to the Parallax Discussion Forums, sign-up to participate.

# snippet to learn about the cordic solver

Posts: 444
Hello forumists,
before I get my P2 silicon, I'm learning a bit of P2 theory. I am particularly interested in the Cordic solver.
That's why I write a few lines to learn the function. Maybe it is useful for others too.
The easy use of the cordic excites me.

Reinhard

• Posts: 10,271
edited 2019-12-02 - 16:52:30
I'm just trying to figure out P2 stuff myself.

I was under the impressing 90 was \$4000_0000 instead of \$3FFF_FFFF.
I believe I saw a post from Chip where he used \$2000_0000 for 45 degrees.
I think a full 360 angle can't be stored in 32-bits. The way I understand it, \$FFFF_FFFF is one bit less than a full circle.

Edit: Forgot a zero in \$4000_0000.
• Posts: 1,087
@Duane Degn

Long time no see!
• Posts: 10,271
Chip lists some angles in this post: https://forums.parallax.com/discussion/comment/1179680/#Comment_1179680

Here's the section of code listing some degrees.
```QSINCOS/QARCTAN/QROTATE usage:

For the circular functions, angles are 32-bits and roll over at 360-degrees:

\$00000000 = 0 degrees                (360 * \$00000000 / \$1_00000000)
\$00000001 = ~0.000000083819 degrees  (360 * \$00000001 / \$1_00000000)
\$00B60B61 = ~1 degree                (360 * \$00B60B61 / \$1_00000000)
\$20000000 = 45 degrees               (360 * \$20000000 / \$1_00000000)
\$40000000 = 90 degrees               (360 * \$40000000 / \$1_00000000)
\$80000000 = 180 degrees              (360 * \$80000000 / \$1_00000000)
\$C0000000 = 270 degrees              (360 * \$C0000000 / \$1_00000000)
\$FFFFFFFF = ~359.9999999162 degrees  (360 * \$FFFFFFFF / \$1_00000000)
```
• Posts: 10,271
Long time no see!

Life has been crazy busy.

I'm trying to figure out how to use the P2 so I'll likely be on the forum a lot more than I have the last few years.
• Posts: 1,428
Duane Degn wrote: »
I'm just trying to figure out P2 stuff myself.

I was under the impressing 90 was \$4000_0000 instead of \$3FFF_FFFF.
I believe I saw a post from Chip where he used \$2000_0000 for 45 degrees.
I think a full 360 angle can't be stored in 32-bits. The way I understand it, \$FFFF_FFFF is one bit less than a full circle.

Edit: Forgot a zero in \$4000_0000.

360 degrees is the same as 0 degrees, so you store it as \$0000_0000. The beauty of binary radians is that equivalent angles have equivalent representations.
• Posts: 13,053
If you want to synthesize some frequency, you just add the frequency-proportional value into an accumulator and use the accumulator as the angle each time. Rollover is welcome.
• Posts: 444
Thank's to all for the helpfull tips.
in my learning snippet i make following modifications:

mov x,#100
mov y,#100
the vector is obviously 100*sqrt(2) long and the angle is 45°

' (X,Y) in polar coordinates
qvector x,y
getqx _abs '-> show me \$8D ... exact...
getqy _arg '-> show me \$2000_0000 ... exact...
now the rotation
rot90 'rotate (X,Y) 90 Degrees counterclockwise, math. positive
setq y 'Y = 100
qrotate x,angle 'X = 100 angle = \$4000_0000
getqx x ' show me \$FFFF_FF9C = -\$64 ... exact...
getqy y ' show me \$63 ...small error...
'show (X,Y) in polar coordinates
qvector x,y
getqx _abs '-> \$8D ... exact...
getqy _arg '-> \$603469DC = 135,2879° ...small error...

I think the small errors are not important in a real application.
Best regards
Reinhard
• Posts: 13,053
edited 2019-12-04 - 01:26:44
Reinhard, I'm not seeing that small error in \$63. I'm getting \$64:
```dat		org

setq	#100
qrotate	#100,##\$4000_0000
getqy	x
setbyte	outb,x,#3
setbyte	dirb,#\$FF,#3
jmp	 #\$

x		res	1
```

Also, this produces the correct angle of \$6000_0000:
```dat		org

qvector	##-100,#100
getqy	x
shr	x,#24
setbyte	outb,x,#3
setbyte	dirb,#\$FF,#3
jmp	 #\$

x		res	1
```

Could you check your setup and confirm you are getting errors? It's working correctly for me.
• Posts: 444
currently i test only with spinsim

if i code this:
```dat
org

set_point
mov	x,#100
mov	y,#100

rot90					'rotate (X,Y) 90 Degrees counterclockwise, math. positive
setq	y
qrotate	x,angle
getqx	x
getqy	y

loop	jmp	#loop

angle	       long	 \$4000_0000

_abs		res	1
_arg		res	1
x		res	1
y		res	1
```

i get this
```Cog  0: 00000037 0004 fd601418                 getqx   \$a, cram[a] = ffffff9c
Cog  0: 00000038 0005 fd601619 F               getqy   \$b
Cog  0: 00000039 0005 fd601619                 getqy   \$b, cram[b] = 63

```

if i code this
```dat
org

set_point
mov	x,#100
mov	y,#100

rot90					'rotate (X,Y) 90 Degrees counterclockwise, math. positive
setq	y
qrotate	x,##\$4000_0000
getqx	x
getqy	y

loop	jmp	#loop

angle	long	\$4000_0000

_abs		res	1
_arg		res	1
x		res	1
y		res	1

```

i get this
```Cog  0: 00000037 0005 fd601618                 getqx   \$b, cram[b] = 0
Cog  0: 00000038 0006 fd601819 F               getqy   \$c
Cog  0: 00000039 0006 fd601819                 getqy   \$c, cram[c] = 64
```
• Posts: 4,397
@Reinhard : I don't think spinsim's cordic implementation has been tested to be bit-accurate with the actual hardware. So I wouldn't read too much into small differences.

Do you have a real P2 to test with?

• Posts: 444
I have not a real P2 at the moment.
But i hope to get one soon.
I know that I can only test correctly if I have a P2.
Until then, I try to get into programming with spinsim.

Thanks
Reinhard
• Posts: 13,053
edited 2019-12-04 - 06:08:27
Reinhard wrote: »
I have not a real P2 at the moment.
But i hope to get one soon.
I know that I can only test correctly if I have a P2.
Until then, I try to get into programming with spinsim.

Thanks
Reinhard

Man, I didn't catch that you were using a simulator. I spent years fiddling with CORDIC stuff to get it working as bit-perfectly as I could, so I was surprised you were seeing the \$63, instead of the \$64.

That's great we've got a simulator, anyway.
• Posts: 444
But I wrote at the very beginning of the post I use a simulator.

I think the P2 is a great processor.
Unfortunately, at the moment I only have the opportunity to test with a simulator.
sorry again.
Reinhard
• Posts: 6,139
Spinsim uses C floating point functions to simulate the cordic instructions. This causes the results to be slightly different. I could make spinsim bit-exact if I implemented the cordic resolver the same way it is implemented in the chip. However, I don't recall whether the precise implementation has ever been published.
• Posts: 444
Dave, I have seen the cordic-implementation in the spinsim sources.
I think you must not do the effort to implement it bit-exact.
It's precise enough how it is.
I did not want to do a big drama about it either.
By the way, the spinsim is (not only for me) the only way to see what is going on in the P2.
Thank you for this helpful tool.
Reinhard