1 /* 2 * Copyright (c) 2011 Broadcom Corporation 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 #include <linux/module.h> 17 #include <linux/cordic.h> 18 19 static const s32 arctan_table[] = { 20 2949120, 21 1740967, 22 919879, 23 466945, 24 234379, 25 117304, 26 58666, 27 29335, 28 14668, 29 7334, 30 3667, 31 1833, 32 917, 33 458, 34 229, 35 115, 36 57, 37 29 38 }; 39 40 /* 41 * cordic_calc_iq() - calculates the i/q coordinate for given angle 42 * 43 * theta: angle in degrees for which i/q coordinate is to be calculated 44 * coord: function output parameter holding the i/q coordinate 45 */ 46 struct cordic_iq cordic_calc_iq(s32 theta) 47 { 48 struct cordic_iq coord; 49 s32 angle, valtmp; 50 unsigned iter; 51 int signx = 1; 52 int signtheta; 53 54 coord.i = CORDIC_ANGLE_GEN; 55 coord.q = 0; 56 angle = 0; 57 58 theta = CORDIC_FIXED(theta); 59 signtheta = (theta < 0) ? -1 : 1; 60 theta = ((theta + CORDIC_FIXED(180) * signtheta) % CORDIC_FIXED(360)) - 61 CORDIC_FIXED(180) * signtheta; 62 63 if (CORDIC_FLOAT(theta) > 90) { 64 theta -= CORDIC_FIXED(180); 65 signx = -1; 66 } else if (CORDIC_FLOAT(theta) < -90) { 67 theta += CORDIC_FIXED(180); 68 signx = -1; 69 } 70 71 for (iter = 0; iter < CORDIC_NUM_ITER; iter++) { 72 if (theta > angle) { 73 valtmp = coord.i - (coord.q >> iter); 74 coord.q += (coord.i >> iter); 75 angle += arctan_table[iter]; 76 } else { 77 valtmp = coord.i + (coord.q >> iter); 78 coord.q -= (coord.i >> iter); 79 angle -= arctan_table[iter]; 80 } 81 coord.i = valtmp; 82 } 83 84 coord.i *= signx; 85 coord.q *= signx; 86 return coord; 87 } 88 EXPORT_SYMBOL(cordic_calc_iq); 89 90 MODULE_DESCRIPTION("CORDIC algorithm"); 91 MODULE_AUTHOR("Broadcom Corporation"); 92 MODULE_LICENSE("Dual BSD/GPL"); 93