Branch data Line data Source code
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 : 0 : struct cordic_iq cordic_calc_iq(s32 theta) 47 : : { 48 : 0 : struct cordic_iq coord; 49 : 0 : s32 angle, valtmp; 50 : 0 : unsigned iter; 51 : 0 : int signx = 1; 52 : 0 : int signtheta; 53 : : 54 : 0 : coord.i = CORDIC_ANGLE_GEN; 55 : 0 : coord.q = 0; 56 : 0 : angle = 0; 57 : : 58 : 0 : theta = CORDIC_FIXED(theta); 59 [ # # ]: 0 : signtheta = (theta < 0) ? -1 : 1; 60 : 0 : theta = ((theta + CORDIC_FIXED(180) * signtheta) % CORDIC_FIXED(360)) - 61 : 0 : CORDIC_FIXED(180) * signtheta; 62 : : 63 [ # # # # ]: 0 : if (CORDIC_FLOAT(theta) > 90) { 64 : 0 : theta -= CORDIC_FIXED(180); 65 : 0 : signx = -1; 66 [ # # # # ]: 0 : } else if (CORDIC_FLOAT(theta) < -90) { 67 : 0 : theta += CORDIC_FIXED(180); 68 : 0 : signx = -1; 69 : : } 70 : : 71 [ # # ]: 0 : for (iter = 0; iter < CORDIC_NUM_ITER; iter++) { 72 [ # # ]: 0 : if (theta > angle) { 73 : 0 : valtmp = coord.i - (coord.q >> iter); 74 : 0 : coord.q += (coord.i >> iter); 75 : 0 : angle += arctan_table[iter]; 76 : : } else { 77 : 0 : valtmp = coord.i + (coord.q >> iter); 78 : 0 : coord.q -= (coord.i >> iter); 79 : 0 : angle -= arctan_table[iter]; 80 : : } 81 : 0 : coord.i = valtmp; 82 : : } 83 : : 84 : 0 : coord.i *= signx; 85 : 0 : coord.q *= signx; 86 : 0 : 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");