]> git.gag.com Git - fw/stlink/blob - exampleF4/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c
Added all the F4 libraries to the project
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / FastMathFunctions / arm_sin_q31.c
1 /* ----------------------------------------------------------------------   
2 * Copyright (C) 2010 ARM Limited. All rights reserved.   
3 *   
4 * $Date:        15. July 2011  
5 * $Revision:    V1.0.10  
6 *   
7 * Project:          CMSIS DSP Library   
8 * Title:                arm_sin_q31.c   
9 *   
10 * Description:  Fast sine calculation for Q31 values.  
11 *   
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 *  
14 * Version 1.0.10 2011/7/15 
15 *    Big Endian support added and Merged M0 and M3/M4 Source code.  
16 *   
17 * Version 1.0.3 2010/11/29  
18 *    Re-organized the CMSIS folders and updated documentation.   
19 *    
20 * Version 1.0.2 2010/11/11   
21 *    Documentation updated.    
22 *   
23 * Version 1.0.1 2010/10/05    
24 *    Production release and review comments incorporated.   
25 *   
26 * Version 1.0.0 2010/09/20    
27 *    Production release and review comments incorporated.   
28 * -------------------------------------------------------------------- */
29
30 #include "arm_math.h"
31
32 /**   
33  * @ingroup groupFastMath   
34  */
35
36  /**   
37  * @addtogroup sin   
38  * @{   
39  */
40
41 /**  
42  * \par   
43  * Tables generated are in Q31(1.31 Fixed point format)   
44  * Generation of sin values in floating point:   
45  * <pre>tableSize = 256;     
46  * for(n = -1; n < (tableSize + 1); n++)   
47  * {   
48  *      sinTable[n+1]= sin(2*pi*n/tableSize);   
49  * } </pre>   
50  * where pi value is  3.14159265358979   
51  * \par   
52  * Convert Floating point to Q31(Fixed point):   
53  *      (sinTable[i] * pow(2, 31))   
54  * \par   
55  * rounding to nearest integer is done   
56  *      sinTable[i] += (sinTable[i] > 0 ? 0.5 :-0.5);   
57  */
58
59 static const q31_t sinTableQ31[259] = {
60   0xfcdbd541, 0x0, 0x3242abf, 0x647d97c, 0x96a9049, 0xc8bd35e, 0xfab272b,
61   0x12c8106f,
62   0x15e21445, 0x18f8b83c, 0x1c0b826a, 0x1f19f97b, 0x2223a4c5, 0x25280c5e,
63   0x2826b928, 0x2b1f34eb,
64   0x2e110a62, 0x30fbc54d, 0x33def287, 0x36ba2014, 0x398cdd32, 0x3c56ba70,
65   0x3f1749b8, 0x41ce1e65,
66   0x447acd50, 0x471cece7, 0x49b41533, 0x4c3fdff4, 0x4ebfe8a5, 0x5133cc94,
67   0x539b2af0, 0x55f5a4d2,
68   0x5842dd54, 0x5a82799a, 0x5cb420e0, 0x5ed77c8a, 0x60ec3830, 0x62f201ac,
69   0x64e88926, 0x66cf8120,
70   0x68a69e81, 0x6a6d98a4, 0x6c242960, 0x6dca0d14, 0x6f5f02b2, 0x70e2cbc6,
71   0x72552c85, 0x73b5ebd1,
72   0x7504d345, 0x7641af3d, 0x776c4edb, 0x78848414, 0x798a23b1, 0x7a7d055b,
73   0x7b5d039e, 0x7c29fbee,
74   0x7ce3ceb2, 0x7d8a5f40, 0x7e1d93ea, 0x7e9d55fc, 0x7f0991c4, 0x7f62368f,
75   0x7fa736b4, 0x7fd8878e,
76   0x7ff62182, 0x7fffffff, 0x7ff62182, 0x7fd8878e, 0x7fa736b4, 0x7f62368f,
77   0x7f0991c4, 0x7e9d55fc,
78   0x7e1d93ea, 0x7d8a5f40, 0x7ce3ceb2, 0x7c29fbee, 0x7b5d039e, 0x7a7d055b,
79   0x798a23b1, 0x78848414,
80   0x776c4edb, 0x7641af3d, 0x7504d345, 0x73b5ebd1, 0x72552c85, 0x70e2cbc6,
81   0x6f5f02b2, 0x6dca0d14,
82   0x6c242960, 0x6a6d98a4, 0x68a69e81, 0x66cf8120, 0x64e88926, 0x62f201ac,
83   0x60ec3830, 0x5ed77c8a,
84   0x5cb420e0, 0x5a82799a, 0x5842dd54, 0x55f5a4d2, 0x539b2af0, 0x5133cc94,
85   0x4ebfe8a5, 0x4c3fdff4,
86   0x49b41533, 0x471cece7, 0x447acd50, 0x41ce1e65, 0x3f1749b8, 0x3c56ba70,
87   0x398cdd32, 0x36ba2014,
88   0x33def287, 0x30fbc54d, 0x2e110a62, 0x2b1f34eb, 0x2826b928, 0x25280c5e,
89   0x2223a4c5, 0x1f19f97b,
90   0x1c0b826a, 0x18f8b83c, 0x15e21445, 0x12c8106f, 0xfab272b, 0xc8bd35e,
91   0x96a9049, 0x647d97c,
92   0x3242abf, 0x0, 0xfcdbd541, 0xf9b82684, 0xf6956fb7, 0xf3742ca2, 0xf054d8d5,
93   0xed37ef91,
94   0xea1debbb, 0xe70747c4, 0xe3f47d96, 0xe0e60685, 0xdddc5b3b, 0xdad7f3a2,
95   0xd7d946d8, 0xd4e0cb15,
96   0xd1eef59e, 0xcf043ab3, 0xcc210d79, 0xc945dfec, 0xc67322ce, 0xc3a94590,
97   0xc0e8b648, 0xbe31e19b,
98   0xbb8532b0, 0xb8e31319, 0xb64beacd, 0xb3c0200c, 0xb140175b, 0xaecc336c,
99   0xac64d510, 0xaa0a5b2e,
100   0xa7bd22ac, 0xa57d8666, 0xa34bdf20, 0xa1288376, 0x9f13c7d0, 0x9d0dfe54,
101   0x9b1776da, 0x99307ee0,
102   0x9759617f, 0x9592675c, 0x93dbd6a0, 0x9235f2ec, 0x90a0fd4e, 0x8f1d343a,
103   0x8daad37b, 0x8c4a142f,
104   0x8afb2cbb, 0x89be50c3, 0x8893b125, 0x877b7bec, 0x8675dc4f, 0x8582faa5,
105   0x84a2fc62, 0x83d60412,
106   0x831c314e, 0x8275a0c0, 0x81e26c16, 0x8162aa04, 0x80f66e3c, 0x809dc971,
107   0x8058c94c, 0x80277872,
108   0x8009de7e, 0x80000000, 0x8009de7e, 0x80277872, 0x8058c94c, 0x809dc971,
109   0x80f66e3c, 0x8162aa04,
110   0x81e26c16, 0x8275a0c0, 0x831c314e, 0x83d60412, 0x84a2fc62, 0x8582faa5,
111   0x8675dc4f, 0x877b7bec,
112   0x8893b125, 0x89be50c3, 0x8afb2cbb, 0x8c4a142f, 0x8daad37b, 0x8f1d343a,
113   0x90a0fd4e, 0x9235f2ec,
114   0x93dbd6a0, 0x9592675c, 0x9759617f, 0x99307ee0, 0x9b1776da, 0x9d0dfe54,
115   0x9f13c7d0, 0xa1288376,
116   0xa34bdf20, 0xa57d8666, 0xa7bd22ac, 0xaa0a5b2e, 0xac64d510, 0xaecc336c,
117   0xb140175b, 0xb3c0200c,
118   0xb64beacd, 0xb8e31319, 0xbb8532b0, 0xbe31e19b, 0xc0e8b648, 0xc3a94590,
119   0xc67322ce, 0xc945dfec,
120   0xcc210d79, 0xcf043ab3, 0xd1eef59e, 0xd4e0cb15, 0xd7d946d8, 0xdad7f3a2,
121   0xdddc5b3b, 0xe0e60685,
122   0xe3f47d96, 0xe70747c4, 0xea1debbb, 0xed37ef91, 0xf054d8d5, 0xf3742ca2,
123   0xf6956fb7, 0xf9b82684,
124   0xfcdbd541, 0x0, 0x3242abf
125 };
126
127
128 /**  
129  * @brief Fast approximation to the trigonometric sine function for Q31 data.  
130  * @param[in] x Scaled input value in radians.  
131  * @return  sin(x).  
132  *  
133  * The Q31 input value is in the range [0 +1) and is mapped to a radian value in the range [0 2*pi).  
134  */
135
136 q31_t arm_sin_q31(
137   q31_t x)
138 {
139   q31_t sinVal, in, in2;                         /* Temporary variables for input, output */
140   uint32_t index;                                /* Index variables */
141   q31_t wa, wb, wc, wd;                          /* Cubic interpolation coefficients */
142   q31_t a, b, c, d;                              /* Four nearest output values */
143   q31_t *tablePtr;                               /* Pointer to table */
144   q31_t fract, fractCube, fractSquare;           /* Temporary values for fractional values */
145   q31_t oneBy6 = 0x15555555;                     /* Fixed point value of 1/6 */
146   q31_t tableSpacing = TABLE_SPACING_Q31;        /* Table spacing */
147   q31_t temp;                                    /* Temporary variable for intermediate process */
148
149   in = x;
150
151   /* Calculate the nearest index */
152   index = (uint32_t) in / (uint32_t) tableSpacing;
153
154   /* Calculate the nearest value of input */
155   in2 = (q31_t) index *tableSpacing;
156
157   /* Calculation of fractional value */
158   fract = (in - in2) << 8;
159
160   /* fractSquare = fract * fract */
161   fractSquare = ((q31_t) (((q63_t) fract * fract) >> 32));
162   fractSquare = fractSquare << 1;
163
164   /* fractCube = fract * fract * fract */
165   fractCube = ((q31_t) (((q63_t) fractSquare * fract) >> 32));
166   fractCube = fractCube << 1;
167
168   /* Initialise table pointer */
169   tablePtr = (q31_t *) & sinTableQ31[index];
170
171   /* Cubic interpolation process */
172   /* Calculation of wa */
173   /* wa = -(oneBy6)*fractCube + (fractSquare >> 1u) - (0x2AAAAAAA)*fract; */
174   wa = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32));
175   temp = 0x2AAAAAAA;
176   wa = (q31_t) ((((q63_t) wa << 32) + ((q63_t) temp * fract)) >> 32);
177   wa = -(wa << 1u);
178   wa += (fractSquare >> 1u);
179
180   /* Read first nearest value of output from the sin table */
181   a = *tablePtr++;
182
183   /* sinVal = a*wa */
184   sinVal = ((q31_t) (((q63_t) a * wa) >> 32));
185
186   /* q31(1.31) Fixed point value of 1 */
187   temp = 0x7FFFFFFF;
188
189   /* Calculation of wb */
190   wb = ((fractCube >> 1u) - (fractSquare + (fract >> 1u))) + temp;
191
192   /* Read second nearest value of output from the sin table */
193   b = *tablePtr++;
194
195   /*  sinVal += b*wb */
196   sinVal = (q31_t) ((((q63_t) sinVal << 32) + (q63_t) b * (wb)) >> 32);
197
198   /* Calculation of wc */
199   wc = -fractCube + fractSquare;
200   wc = (wc >> 1u) + fract;
201
202   /* Read third nearest value of output from the sin table */
203   c = *tablePtr++;
204
205   /*      sinVal += c*wc */
206   sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) c * wc)) >> 32);
207
208   /* Calculation of wd */
209   /* wd = (oneBy6) * fractCube - (oneBy6) * fract; */
210   fractCube = fractCube - fract;
211   wd = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32));
212   wd = (wd << 1u);
213
214   /* Read fourth nearest value of output from the sin table */
215   d = *tablePtr++;
216
217   /* sinVal += d*wd; */
218   sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) d * wd)) >> 32);
219
220   /* convert sinVal in 2.30 format to 1.31 format */
221   return (sinVal << 1u);
222
223 }
224
225 /**   
226  * @} end of sin group   
227  */