Created
January 22, 2020 13:58
-
-
Save standarddeviant/b40b3889fb5c1c79698e579842d53de0 to your computer and use it in GitHub Desktop.
CORDIC convenience , adapted from http://www.dcs.gla.ac.uk/~jhw/cordic/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> // for printf | |
#include <math.h> // for testing only, not used by cordic | |
#include "cordic-32bit.h" // for actual cordic algo | |
//Print out sin(x) vs fp CORDIC sin(x) | |
int main(int argc, char **argv) | |
{ | |
float p; | |
// sin_int, cos_in; | |
float sin_float, cos_float, mathh_sin_float; | |
int i; | |
for(i=0;i<100;i++) | |
{ | |
p = -4*M_PI + (i/100.0)*8*M_PI; | |
// how to use 'raw' cordic | |
// cordic((p*MUL), &sin_int, &cos_int, 32); | |
// how to use 'convenient' cordic | |
cordic_float_convenience(p, &sin_float, &cos_float, 32); | |
//these values should be nearly equal | |
mathh_sin_float = sin(p); | |
printf("SIN(% 2.6f * PI), cordic = % 2.6f, math.h = % 2.6f, error = % e\n", | |
p/M_PI, sin_float, mathh_sin_float, sin_float - mathh_sin_float); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cordic-32bit.h | |
#ifndef CORDIC_32_BIT_H | |
#define CORDIC_32_BIT_H | |
#include <math.h> | |
// #define M_PI 3.1415926535897932384626 | |
#define K1 0.6072529350088812561694 | |
//Cordic in 32 bit signed fixed point math | |
//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 = 1073741824 | |
// 1/k = 0.6072529350088812561694 | |
// pi = 3.1415926535897932384626 | |
//Constants | |
#define cordic_1K 0x26DD3B6A | |
#define half_pi 0x6487ED51 | |
#define CORDIC_MUL 1073741824.000000 | |
#define CORDIC_NTAB 32 | |
int cordic_ctab [] = {0x3243F6A8, 0x1DAC6705, 0x0FADBAFC, 0x07F56EA6, 0x03FEAB76, 0x01FFD55B, | |
0x00FFFAAA, 0x007FFF55, 0x003FFFEA, 0x001FFFFD, 0x000FFFFF, 0x0007FFFF, 0x0003FFFF, | |
0x0001FFFF, 0x0000FFFF, 0x00007FFF, 0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF, | |
0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F, 0x0000003F, 0x0000001F, 0x0000000F, | |
0x00000008, 0x00000004, 0x00000002, 0x00000001, 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>>31; | |
//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 cordic_float_convenience(float theta, float *sin_float, float *cos_float, int n) { | |
int sin_int, cos_int; | |
float sign_mult; | |
float tm = fmodf(theta + M_PI/2, 2*M_PI); | |
if(tm >= 0) { // POS THETA BRANCH | |
if(tm <= M_PI) { // POS OUT CASE | |
sign_mult = 1.0f; | |
theta = tm - M_PI/2; | |
} | |
else { // NEG OUT CASE | |
sign_mult = -1.0f; | |
theta = tm - 3*M_PI/2; | |
} | |
} | |
else { // NEG THETA BRANCH | |
if(tm >= -M_PI) { // NEG OUT CASE | |
sign_mult = -1.0; | |
theta = tm + M_PI/2; | |
} | |
else { // POS OUT CASE | |
sign_mult = 1.0; | |
theta = tm + 3*M_PI/2; | |
} | |
} | |
cordic(theta*CORDIC_MUL, &sin_int, &cos_int, n); | |
*sin_float = sign_mult * sin_int/CORDIC_MUL; | |
*cos_float = sign_mult * cos_int/CORDIC_MUL; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment