CORDIC - sin cos for graphics etc.

Post your cool example code here.
User avatar
Pito
Posts: 535
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

CORDIC - sin cos for graphics etc.

Postby Pito » Tue Nov 01, 2016 5:18 pm

This is a simple example of CORDIC SIN and COS calculation which could be used when fast calc is required (ie for TFT graphics).
Other math functions like TAN could be calculated with Cordic too, afaik..
https://en.wikipedia.org/wiki/CORDIC

The below Example compares CORDIC 16bit calculation against floating point sin() and cos().
Mind the below 10-iteration cordic is ~3digits precise (you may increase the precision with more iterations), it returns BOTH sin and cos, and it is ~8-10x faster than the floating point (Maple Mini STM32 @72MHz)..

32bit CORDIC and a routine for the coef calc is here http://www.dcs.gla.ac.uk/~jhw/cordic/

Code: Select all

// CORDIC based SIN and COS in 16 bit signed fixed point math
// Based on http://www.dcs.gla.ac.uk/~jhw/cordic/
// Pito 11/2016, for Maple Mini @72MHz
// Function is valid for arguments in range -pi/2 -- pi/2
// For values pi/2--pi: value = half_pi-(theta-half_pi) and similarly for values -pi---pi/2
//
// 1.0 = 16384
// 1/k = 0.6072529350088812561694
// pi = 3.1415926536897932384626
// Some useful Constants
#define cordic_1K 0x000026DD
#define half_pi 0x00006487
#define MUL 16384.000000
#define CORDIC_NTAB 16
int cordic_ctab [] = {0x00003243, 0x00001DAC, 0x00000FAD, 0x000007F5, 0x000003FE,
0x000001FF, 0x000000FF, 0x0000007F, 0x0000003F, 0x0000001F, 0x0000000F, 0x00000007,
0x00000003, 0x00000001, 0x00000000, 0x00000000, };

void cordic(int theta, int *s, int *c, int n)
{
  int k, d, tx, ty, tz;
  int x=cordic_1K,y=0,z=theta;
  n = (n>CORDIC_NTAB) ? CORDIC_NTAB : n;
  for (k=0; k<n; ++k)
  {
    d = z>>15;
    //get sign. for other architectures, you might want to use the more portable version
    //d = z>=0 ? 0 : -1;
    tx = x - (((y>>k) ^ d) - d);
    ty = y + (((x>>k) ^ d) - d);
    tz = z - ((cordic_ctab[k] ^ d) - d);
    x = tx; y = ty; z = tz;
  } 
 *c = x; *s = y;
}


void setup() {
  // put your setup code here, to run once:
 
     Serial1.begin(115200);  // Serial1 used here

    float p, p1;
    volatile float dummy;
    int s, c;
    int i, t, t1;   
    // make a few calculations in form of a Table to compare results and speed
    for(i=0;i<50;i++)
    {
        p = (i/50.0)*M_PI/2;
        p1 = p * MUL;   
           
        t = micros();
        cordic(p1, &s, &c, 10); // 10 Cordic iterations
        t = micros() - t;
       
        t1 = micros();
        dummy = sin(p);
        dummy = cos(p);
        t1 = micros() - t1;
               
        Serial1.print(p,4);
        Serial1.print("   sin ");
        Serial1.print(s/MUL,4);
        Serial1.print(" ");
        Serial1.print(sin(p),4);
        Serial1.print("   cos ");
        Serial1.print(c/MUL,4);
        Serial1.print(" ");
        Serial1.print(cos(p),4);
        Serial1.print("  COR_micros= ");
        Serial1.print(t);
        Serial1.print("  FP_micros= ");
        Serial1.println(t1);
       
    }   

        while(1);
}

void loop() {
  // put your main code here, to run repeatedly:

}


10 iterations:

Code: Select all

0.0000   sin 0.0013 0.0000   cos 0.9999 1.0000  COR_micros= 8  FP_micros= 5
0.0314   sin 0.0326 0.0314   cos 0.9994 0.9995  COR_micros= 8  FP_micros= 59
0.0628   sin 0.0637 0.0628   cos 0.9980 0.9980  COR_micros= 8  FP_micros= 57
0.0942   sin 0.0939 0.0941   cos 0.9955 0.9956  COR_micros= 8  FP_micros= 57
0.1257   sin 0.1249 0.1253   cos 0.9921 0.9921  COR_micros= 8  FP_micros= 57
0.1571   sin 0.1557 0.1564   cos 0.9878 0.9877  COR_micros= 8  FP_micros= 58
0.1885   sin 0.1865 0.1874   cos 0.9825 0.9823  COR_micros= 8  FP_micros= 57
0.2199   sin 0.2169 0.2181   cos 0.9761 0.9759  COR_micros= 8  FP_micros= 59
0.2513   sin 0.2474 0.2487   cos 0.9689 0.9686  COR_micros= 7  FP_micros= 58
0.2827   sin 0.2775 0.2790   cos 0.9606 0.9603  COR_micros= 8  FP_micros= 57
0.3142   sin 0.3109 0.3090   cos 0.9504 0.9511  COR_micros= 8  FP_micros= 63
0.3456   sin 0.3398 0.3387   cos 0.9405 0.9409  COR_micros= 8  FP_micros= 64
0.3770   sin 0.3689 0.3681   cos 0.9294 0.9298  COR_micros= 8  FP_micros= 63
0.4084   sin 0.3978 0.3971   cos 0.9175 0.9178  COR_micros= 8  FP_micros= 63
0.4398   sin 0.4262 0.4258   cos 0.9047 0.9048  COR_micros= 8  FP_micros= 64
0.4712   sin 0.4543 0.4540   cos 0.8909 0.8910  COR_micros= 8  FP_micros= 63
0.5027   sin 0.4818 0.4818   cos 0.8763 0.8763  COR_micros= 8  FP_micros= 63
0.5341   sin 0.5089 0.5090   cos 0.8608 0.8607  COR_micros= 8  FP_micros= 63
0.5655   sin 0.5356 0.5358   cos 0.8445 0.8443  COR_micros= 8  FP_micros= 64
0.5969   sin 0.5609 0.5621   cos 0.8278 0.8271  COR_micros= 8  FP_micros= 63
0.6283   sin 0.5864 0.5878   cos 0.8100 0.8090  COR_micros= 7  FP_micros= 63
0.6597   sin 0.6113 0.6129   cos 0.7913 0.7902  COR_micros= 8  FP_micros= 63
0.6912   sin 0.6389 0.6374   cos 0.7693 0.7705  COR_micros= 7  FP_micros= 63
0.7226   sin 0.6627 0.6613   cos 0.7490 0.7501  COR_micros= 7  FP_micros= 63
0.7540   sin 0.6857 0.6845   cos 0.7279 0.7290  COR_micros= 8  FP_micros= 63
0.7854   sin 0.7062 0.7071   cos 0.7081 0.7071  COR_micros= 7  FP_micros= 60
0.8168   sin 0.7279 0.7290   cos 0.6857 0.6845  COR_micros= 8  FP_micros= 92
0.8482   sin 0.7490 0.7501   cos 0.6627 0.6613  COR_micros= 8  FP_micros= 91
0.8796   sin 0.7693 0.7705   cos 0.6389 0.6374  COR_micros= 8  FP_micros= 91
0.9111   sin 0.7913 0.7902   cos 0.6113 0.6129  COR_micros= 8  FP_micros= 91
0.9425   sin 0.8100 0.8090   cos 0.5864 0.5878  COR_micros= 8  FP_micros= 91
0.9739   sin 0.8278 0.8271   cos 0.5609 0.5621  COR_micros= 8  FP_micros= 91
1.0053   sin 0.8445 0.8443   cos 0.5356 0.5358  COR_micros= 7  FP_micros= 91
1.0367   sin 0.8608 0.8607   cos 0.5089 0.5090  COR_micros= 7  FP_micros= 92
1.0681   sin 0.8763 0.8763   cos 0.4818 0.4818  COR_micros= 8  FP_micros= 92
1.0996   sin 0.8909 0.8910   cos 0.4543 0.4540  COR_micros= 8  FP_micros= 92
1.1310   sin 0.9047 0.9048   cos 0.4262 0.4258  COR_micros= 7  FP_micros= 92
1.1624   sin 0.9175 0.9178   cos 0.3978 0.3971  COR_micros= 8  FP_micros= 92
1.1938   sin 0.9294 0.9298   cos 0.3689 0.3681  COR_micros= 7  FP_micros= 92
1.2252   sin 0.9405 0.9409   cos 0.3398 0.3387  COR_micros= 8  FP_micros= 92
1.2566   sin 0.9515 0.9511   cos 0.3072 0.3090  COR_micros= 8  FP_micros= 92
1.2881   sin 0.9606 0.9603   cos 0.2775 0.2790  COR_micros= 8  FP_micros= 88
1.3195   sin 0.9689 0.9686   cos 0.2474 0.2487  COR_micros= 8  FP_micros= 88
1.3509   sin 0.9761 0.9759   cos 0.2169 0.2181  COR_micros= 8  FP_micros= 88
1.3823   sin 0.9825 0.9823   cos 0.1865 0.1874  COR_micros= 8  FP_micros= 87
1.4137   sin 0.9878 0.9877   cos 0.1557 0.1564  COR_micros= 8  FP_micros= 88
1.4451   sin 0.9921 0.9921   cos 0.1249 0.1253  COR_micros= 7  FP_micros= 88
1.4765   sin 0.9955 0.9956   cos 0.0939 0.0941  COR_micros= 8  FP_micros= 87
1.5080   sin 0.9980 0.9980   cos 0.0637 0.0628  COR_micros= 8  FP_micros= 90
1.5394   sin 0.9994 0.9995   cos 0.0326 0.0314  COR_micros= 8  FP_micros= 88


14 iterations:

Code: Select all

0.0000   sin 0.0001 0.0000   cos 0.9999 1.0000  COR_micros= 10  FP_micros= 5
0.0314   sin 0.0315 0.0314   cos 0.9994 0.9995  COR_micros= 10  FP_micros= 59
0.0628   sin 0.0630 0.0628   cos 0.9980 0.9980  COR_micros= 10  FP_micros= 59
0.0942   sin 0.0941 0.0941   cos 0.9954 0.9956  COR_micros= 10  FP_micros= 59
0.1257   sin 0.1255 0.1253   cos 0.9921 0.9921  COR_micros= 10  FP_micros= 59
0.1571   sin 0.1564 0.1564   cos 0.9877 0.9877  COR_micros= 10  FP_micros= 59
0.1885   sin 0.1876 0.1874   cos 0.9823 0.9823  COR_micros= 10  FP_micros= 59
0.2199   sin 0.2181 0.2181   cos 0.9758 0.9759  COR_micros= 10  FP_micros= 59
0.2513   sin 0.2489 0.2487   cos 0.9686 0.9686  COR_micros= 10  FP_micros= 59
0.2827   sin 0.2791 0.2790   cos 0.9602 0.9603  COR_micros= 10  FP_micros= 59
0.3142   sin 0.3093 0.3090   cos 0.9509 0.9511  COR_micros= 10  FP_micros= 63
0.3456   sin 0.3387 0.3387   cos 0.9409 0.9409  COR_micros= 10  FP_micros= 63
0.3770   sin 0.3682 0.3681   cos 0.9297 0.9298  COR_micros= 10  FP_micros= 63
0.4084   sin 0.3973 0.3971   cos 0.9177 0.9178  COR_micros= 10  FP_micros= 63
0.4398   sin 0.4259 0.4258   cos 0.9048 0.9048  COR_micros= 10  FP_micros= 63
0.4712   sin 0.4541 0.4540   cos 0.8911 0.8910  COR_micros= 10  FP_micros= 64
0.5027   sin 0.4820 0.4818   cos 0.8761 0.8763  COR_micros= 10  FP_micros= 63
0.5341   sin 0.5091 0.5090   cos 0.8607 0.8607  COR_micros= 10  FP_micros= 63
0.5655   sin 0.5361 0.5358   cos 0.8442 0.8443  COR_micros= 10  FP_micros= 64
0.5969   sin 0.5623 0.5621   cos 0.8269 0.8271  COR_micros= 10  FP_micros= 64
0.6283   sin 0.5877 0.5878   cos 0.8090 0.8090  COR_micros= 10  FP_micros= 63
0.6597   sin 0.6127 0.6129   cos 0.7903 0.7902  COR_micros= 10  FP_micros= 63
0.6912   sin 0.6375 0.6374   cos 0.7704 0.7705  COR_micros= 10  FP_micros= 63
0.7226   sin 0.6615 0.6613   cos 0.7501 0.7501  COR_micros= 10  FP_micros= 63
0.7540   sin 0.6846 0.6845   cos 0.7289 0.7290  COR_micros= 9  FP_micros= 63
0.7854   sin 0.7071 0.7071   cos 0.7072 0.7071  COR_micros= 10  FP_micros= 60
0.8168   sin 0.7290 0.7290   cos 0.6845 0.6845  COR_micros= 10  FP_micros= 91
0.8482   sin 0.7501 0.7501   cos 0.6615 0.6613  COR_micros= 10  FP_micros= 91
0.8796   sin 0.7704 0.7705   cos 0.6375 0.6374  COR_micros= 9  FP_micros= 91
0.9111   sin 0.7903 0.7902   cos 0.6127 0.6129  COR_micros= 10  FP_micros= 91
0.9425   sin 0.8090 0.8090   cos 0.5877 0.5878  COR_micros= 10  FP_micros= 92
0.9739   sin 0.8270 0.8271   cos 0.5621 0.5621  COR_micros= 10  FP_micros= 91
1.0053   sin 0.8444 0.8443   cos 0.5359 0.5358  COR_micros= 17  FP_micros= 92
1.0367   sin 0.8607 0.8607   cos 0.5091 0.5090  COR_micros= 10  FP_micros= 91
1.0681   sin 0.8765 0.8763   cos 0.4816 0.4818  COR_micros= 10  FP_micros= 92
1.0996   sin 0.8911 0.8910   cos 0.4540 0.4540  COR_micros= 10  FP_micros= 92
1.1310   sin 0.9048 0.9048   cos 0.4259 0.4258  COR_micros= 10  FP_micros= 92
1.1624   sin 0.9177 0.9178   cos 0.3972 0.3971  COR_micros= 10  FP_micros= 91
1.1938   sin 0.9298 0.9298   cos 0.3679 0.3681  COR_micros= 10  FP_micros= 92
1.2252   sin 0.9409 0.9409   cos 0.3386 0.3387  COR_micros= 10  FP_micros= 92
1.2566   sin 0.9511 0.9511   cos 0.3088 0.3090  COR_micros= 10  FP_micros= 93
1.2881   sin 0.9602 0.9603   cos 0.2789 0.2790  COR_micros= 10  FP_micros= 88
1.3195   sin 0.9686 0.9686   cos 0.2487 0.2487  COR_micros= 10  FP_micros= 88
1.3509   sin 0.9758 0.9759   cos 0.2180 0.2181  COR_micros= 10  FP_micros= 88
1.3823   sin 0.9824 0.9823   cos 0.1872 0.1874  COR_micros= 10  FP_micros= 88
1.4137   sin 0.9877 0.9877   cos 0.1563 0.1564  COR_micros= 10  FP_micros= 87
1.4451   sin 0.9921 0.9921   cos 0.1252 0.1253  COR_micros= 10  FP_micros= 88
1.4765   sin 0.9954 0.9956   cos 0.0941 0.0941  COR_micros= 11  FP_micros= 88
1.5080   sin 0.9980 0.9980   cos 0.0630 0.0628  COR_micros= 10  FP_micros= 88
1.5394   sin 0.9994 0.9995   cos 0.0314 0.0314  COR_micros= 10  FP_micros= 88
Last edited by Pito on Wed Nov 02, 2016 6:19 pm, edited 1 time in total.

User avatar
RogerClark
Posts: 5044
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: CORDIC - sin cos for graphics etc.

Postby RogerClark » Tue Nov 01, 2016 7:43 pm

Thanks

I am sure that will be useful for some projects in the future

User avatar
zoomx
Posts: 331
Joined: Mon Apr 27, 2015 2:28 pm
Location: Mt.Etna, Italy

Re: CORDIC - sin cos for graphics etc.

Postby zoomx » Wed Nov 02, 2016 11:49 am

I agree!

User avatar
mankan
Posts: 18
Joined: Tue Oct 13, 2015 7:57 pm

Re: CORDIC - sin cos for graphics etc.

Postby mankan » Wed Nov 02, 2016 6:14 pm

Depending on precision needed the following sequence could do: 1,2,2,3,2,2,1,-1,-2,-2,-3,-2,-2,-1. I used it once in a SW modem on PIC.
/Marcus

User avatar
Pito
Posts: 535
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: CORDIC - sin cos for graphics etc.

Postby Pito » Wed Nov 02, 2016 6:23 pm

BTW I did above CORDIC on Xilinx Spartan6 and it returned 5digits precise sin() and cos() in 200ns (no overclocking) :)

Depending on precision needed the following sequence could do: 1,2,2,3,2,2,1,-1,-2,-2,-3,-2,-2,-1. I used it once in a SW modem on PIC.

It could be done with an 1,0,1,0 sequence and a simple RC low pass filter too :P


Return to “Code snipplets”

Who is online

Users browsing this forum: No registered users and 1 guest