0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/module.h>
0017 #include <linux/cordic.h>
0018
0019 static const s32 arctan_table[] = {
0020 2949120,
0021 1740967,
0022 919879,
0023 466945,
0024 234379,
0025 117304,
0026 58666,
0027 29335,
0028 14668,
0029 7334,
0030 3667,
0031 1833,
0032 917,
0033 458,
0034 229,
0035 115,
0036 57,
0037 29
0038 };
0039
0040
0041
0042
0043
0044
0045
0046 struct cordic_iq cordic_calc_iq(s32 theta)
0047 {
0048 struct cordic_iq coord;
0049 s32 angle, valtmp;
0050 unsigned iter;
0051 int signx = 1;
0052 int signtheta;
0053
0054 coord.i = CORDIC_ANGLE_GEN;
0055 coord.q = 0;
0056 angle = 0;
0057
0058 theta = CORDIC_FIXED(theta);
0059 signtheta = (theta < 0) ? -1 : 1;
0060 theta = ((theta + CORDIC_FIXED(180) * signtheta) % CORDIC_FIXED(360)) -
0061 CORDIC_FIXED(180) * signtheta;
0062
0063 if (CORDIC_FLOAT(theta) > 90) {
0064 theta -= CORDIC_FIXED(180);
0065 signx = -1;
0066 } else if (CORDIC_FLOAT(theta) < -90) {
0067 theta += CORDIC_FIXED(180);
0068 signx = -1;
0069 }
0070
0071 for (iter = 0; iter < CORDIC_NUM_ITER; iter++) {
0072 if (theta > angle) {
0073 valtmp = coord.i - (coord.q >> iter);
0074 coord.q += (coord.i >> iter);
0075 angle += arctan_table[iter];
0076 } else {
0077 valtmp = coord.i + (coord.q >> iter);
0078 coord.q -= (coord.i >> iter);
0079 angle -= arctan_table[iter];
0080 }
0081 coord.i = valtmp;
0082 }
0083
0084 coord.i *= signx;
0085 coord.q *= signx;
0086 return coord;
0087 }
0088 EXPORT_SYMBOL(cordic_calc_iq);
0089
0090 MODULE_DESCRIPTION("CORDIC algorithm");
0091 MODULE_AUTHOR("Broadcom Corporation");
0092 MODULE_LICENSE("Dual BSD/GPL");