Blame view

lib/math/cordic.c 2.22 KB
10f8113ec   Arend van Spriel   lib: cordic: add ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (c) 2011 Broadcom Corporation
   *
   * Permission to use, copy, modify, and/or distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
   * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  #include <linux/module.h>
  #include <linux/cordic.h>
10f8113ec   Arend van Spriel   lib: cordic: add ...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  static const s32 arctan_table[] = {
  	2949120,
  	1740967,
  	919879,
  	466945,
  	234379,
  	117304,
  	58666,
  	29335,
  	14668,
  	7334,
  	3667,
  	1833,
  	917,
  	458,
  	229,
  	115,
  	57,
  	29
  };
  
  /*
   * cordic_calc_iq() - calculates the i/q coordinate for given angle
   *
   * theta: angle in degrees for which i/q coordinate is to be calculated
   * coord: function output parameter holding the i/q coordinate
   */
  struct cordic_iq cordic_calc_iq(s32 theta)
  {
  	struct cordic_iq coord;
  	s32 angle, valtmp;
  	unsigned iter;
  	int signx = 1;
  	int signtheta;
  
  	coord.i = CORDIC_ANGLE_GEN;
  	coord.q = 0;
  	angle = 0;
58d81d64e   Priit Laes   lib: cordic: Move...
56
  	theta = CORDIC_FIXED(theta);
10f8113ec   Arend van Spriel   lib: cordic: add ...
57
  	signtheta = (theta < 0) ? -1 : 1;
58d81d64e   Priit Laes   lib: cordic: Move...
58
59
  	theta = ((theta + CORDIC_FIXED(180) * signtheta) % CORDIC_FIXED(360)) -
  		CORDIC_FIXED(180) * signtheta;
10f8113ec   Arend van Spriel   lib: cordic: add ...
60

58d81d64e   Priit Laes   lib: cordic: Move...
61
62
  	if (CORDIC_FLOAT(theta) > 90) {
  		theta -= CORDIC_FIXED(180);
10f8113ec   Arend van Spriel   lib: cordic: add ...
63
  		signx = -1;
58d81d64e   Priit Laes   lib: cordic: Move...
64
65
  	} else if (CORDIC_FLOAT(theta) < -90) {
  		theta += CORDIC_FIXED(180);
10f8113ec   Arend van Spriel   lib: cordic: add ...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  		signx = -1;
  	}
  
  	for (iter = 0; iter < CORDIC_NUM_ITER; iter++) {
  		if (theta > angle) {
  			valtmp = coord.i - (coord.q >> iter);
  			coord.q += (coord.i >> iter);
  			angle += arctan_table[iter];
  		} else {
  			valtmp = coord.i + (coord.q >> iter);
  			coord.q -= (coord.i >> iter);
  			angle -= arctan_table[iter];
  		}
  		coord.i = valtmp;
  	}
  
  	coord.i *= signx;
  	coord.q *= signx;
  	return coord;
  }
  EXPORT_SYMBOL(cordic_calc_iq);
d89ce936b   Michael Witten   Docs: wording: fu...
87
  MODULE_DESCRIPTION("CORDIC algorithm");
10f8113ec   Arend van Spriel   lib: cordic: add ...
88
89
  MODULE_AUTHOR("Broadcom Corporation");
  MODULE_LICENSE("Dual BSD/GPL");