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

# snippet to learn about the cordic solver

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

• 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.
• @Duane Degn

Long time no see!
• 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)
```
• 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.
• 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.
• 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.
• 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
• 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.
• 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
```
• @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?

• 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
• 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.
But I wrote at the very beginning of the post I use a simulator.