CMSIS DSP Library from CMSIS 2.0. See http://www.onarm.com/cmsis/ for full details

Dependents:   K22F_DSP_Matrix_least_square BNO055-ELEC3810 1BNO055 ECE4180Project--Slave2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_sin_q31.c Source File

arm_sin_q31.c

00001 /* ----------------------------------------------------------------------  
00002 * Copyright (C) 2010 ARM Limited. All rights reserved.  
00003 *  
00004 * $Date:        29. November 2010  
00005 * $Revision:    V1.0.3  
00006 *  
00007 * Project:      CMSIS DSP Library  
00008 * Title:        arm_sin_q31.c  
00009 *  
00010 * Description:  Fast sine calculation for Q31 values. 
00011 *  
00012 * Target Processor: Cortex-M4/Cortex-M3
00013 *  
00014 * Version 1.0.3 2010/11/29 
00015 *    Re-organized the CMSIS folders and updated documentation.  
00016 *   
00017 * Version 1.0.2 2010/11/11  
00018 *    Documentation updated.   
00019 *  
00020 * Version 1.0.1 2010/10/05   
00021 *    Production release and review comments incorporated.  
00022 *  
00023 * Version 1.0.0 2010/09/20   
00024 *    Production release and review comments incorporated.  
00025 * -------------------------------------------------------------------- */ 
00026  
00027 #include "arm_math.h" 
00028  
00029 /**  
00030  * @ingroup groupFastMath  
00031  */ 
00032  
00033  /**  
00034  * @addtogroup sin  
00035  * @{  
00036  */ 
00037  
00038 /** 
00039  * \par  
00040  * Tables generated are in Q31(1.31 Fixed point format)  
00041  * Generation of sin values in floating point:  
00042  * <pre>tableSize = 256;    
00043  * for(n = -1; n < (tableSize + 1); n++)  
00044  * {  
00045  *  sinTable[n+1]= sin(2*pi*n/tableSize);  
00046  * } </pre>  
00047  * where pi value is  3.14159265358979  
00048  * \par  
00049  * Convert Floating point to Q31(Fixed point):  
00050  *  (sinTable[i] * pow(2, 31))  
00051  * \par  
00052  * rounding to nearest integer is done  
00053  *  sinTable[i] += (sinTable[i] > 0 ? 0.5 :-0.5);  
00054  */ 
00055  
00056 static const q31_t sinTableQ31 [259] = { 
00057   0xfcdbd541, 0x0, 0x3242abf, 0x647d97c, 0x96a9049, 0xc8bd35e, 0xfab272b, 
00058   0x12c8106f, 
00059   0x15e21445, 0x18f8b83c, 0x1c0b826a, 0x1f19f97b, 0x2223a4c5, 0x25280c5e, 
00060   0x2826b928, 0x2b1f34eb, 
00061   0x2e110a62, 0x30fbc54d, 0x33def287, 0x36ba2014, 0x398cdd32, 0x3c56ba70, 
00062   0x3f1749b8, 0x41ce1e65, 
00063   0x447acd50, 0x471cece7, 0x49b41533, 0x4c3fdff4, 0x4ebfe8a5, 0x5133cc94, 
00064   0x539b2af0, 0x55f5a4d2, 
00065   0x5842dd54, 0x5a82799a, 0x5cb420e0, 0x5ed77c8a, 0x60ec3830, 0x62f201ac, 
00066   0x64e88926, 0x66cf8120, 
00067   0x68a69e81, 0x6a6d98a4, 0x6c242960, 0x6dca0d14, 0x6f5f02b2, 0x70e2cbc6, 
00068   0x72552c85, 0x73b5ebd1, 
00069   0x7504d345, 0x7641af3d, 0x776c4edb, 0x78848414, 0x798a23b1, 0x7a7d055b, 
00070   0x7b5d039e, 0x7c29fbee, 
00071   0x7ce3ceb2, 0x7d8a5f40, 0x7e1d93ea, 0x7e9d55fc, 0x7f0991c4, 0x7f62368f, 
00072   0x7fa736b4, 0x7fd8878e, 
00073   0x7ff62182, 0x7fffffff, 0x7ff62182, 0x7fd8878e, 0x7fa736b4, 0x7f62368f, 
00074   0x7f0991c4, 0x7e9d55fc, 
00075   0x7e1d93ea, 0x7d8a5f40, 0x7ce3ceb2, 0x7c29fbee, 0x7b5d039e, 0x7a7d055b, 
00076   0x798a23b1, 0x78848414, 
00077   0x776c4edb, 0x7641af3d, 0x7504d345, 0x73b5ebd1, 0x72552c85, 0x70e2cbc6, 
00078   0x6f5f02b2, 0x6dca0d14, 
00079   0x6c242960, 0x6a6d98a4, 0x68a69e81, 0x66cf8120, 0x64e88926, 0x62f201ac, 
00080   0x60ec3830, 0x5ed77c8a, 
00081   0x5cb420e0, 0x5a82799a, 0x5842dd54, 0x55f5a4d2, 0x539b2af0, 0x5133cc94, 
00082   0x4ebfe8a5, 0x4c3fdff4, 
00083   0x49b41533, 0x471cece7, 0x447acd50, 0x41ce1e65, 0x3f1749b8, 0x3c56ba70, 
00084   0x398cdd32, 0x36ba2014, 
00085   0x33def287, 0x30fbc54d, 0x2e110a62, 0x2b1f34eb, 0x2826b928, 0x25280c5e, 
00086   0x2223a4c5, 0x1f19f97b, 
00087   0x1c0b826a, 0x18f8b83c, 0x15e21445, 0x12c8106f, 0xfab272b, 0xc8bd35e, 
00088   0x96a9049, 0x647d97c, 
00089   0x3242abf, 0x0, 0xfcdbd541, 0xf9b82684, 0xf6956fb7, 0xf3742ca2, 0xf054d8d5, 
00090   0xed37ef91, 
00091   0xea1debbb, 0xe70747c4, 0xe3f47d96, 0xe0e60685, 0xdddc5b3b, 0xdad7f3a2, 
00092   0xd7d946d8, 0xd4e0cb15, 
00093   0xd1eef59e, 0xcf043ab3, 0xcc210d79, 0xc945dfec, 0xc67322ce, 0xc3a94590, 
00094   0xc0e8b648, 0xbe31e19b, 
00095   0xbb8532b0, 0xb8e31319, 0xb64beacd, 0xb3c0200c, 0xb140175b, 0xaecc336c, 
00096   0xac64d510, 0xaa0a5b2e, 
00097   0xa7bd22ac, 0xa57d8666, 0xa34bdf20, 0xa1288376, 0x9f13c7d0, 0x9d0dfe54, 
00098   0x9b1776da, 0x99307ee0, 
00099   0x9759617f, 0x9592675c, 0x93dbd6a0, 0x9235f2ec, 0x90a0fd4e, 0x8f1d343a, 
00100   0x8daad37b, 0x8c4a142f, 
00101   0x8afb2cbb, 0x89be50c3, 0x8893b125, 0x877b7bec, 0x8675dc4f, 0x8582faa5, 
00102   0x84a2fc62, 0x83d60412, 
00103   0x831c314e, 0x8275a0c0, 0x81e26c16, 0x8162aa04, 0x80f66e3c, 0x809dc971, 
00104   0x8058c94c, 0x80277872, 
00105   0x8009de7e, 0x80000000, 0x8009de7e, 0x80277872, 0x8058c94c, 0x809dc971, 
00106   0x80f66e3c, 0x8162aa04, 
00107   0x81e26c16, 0x8275a0c0, 0x831c314e, 0x83d60412, 0x84a2fc62, 0x8582faa5, 
00108   0x8675dc4f, 0x877b7bec, 
00109   0x8893b125, 0x89be50c3, 0x8afb2cbb, 0x8c4a142f, 0x8daad37b, 0x8f1d343a, 
00110   0x90a0fd4e, 0x9235f2ec, 
00111   0x93dbd6a0, 0x9592675c, 0x9759617f, 0x99307ee0, 0x9b1776da, 0x9d0dfe54, 
00112   0x9f13c7d0, 0xa1288376, 
00113   0xa34bdf20, 0xa57d8666, 0xa7bd22ac, 0xaa0a5b2e, 0xac64d510, 0xaecc336c, 
00114   0xb140175b, 0xb3c0200c, 
00115   0xb64beacd, 0xb8e31319, 0xbb8532b0, 0xbe31e19b, 0xc0e8b648, 0xc3a94590, 
00116   0xc67322ce, 0xc945dfec, 
00117   0xcc210d79, 0xcf043ab3, 0xd1eef59e, 0xd4e0cb15, 0xd7d946d8, 0xdad7f3a2, 
00118   0xdddc5b3b, 0xe0e60685, 
00119   0xe3f47d96, 0xe70747c4, 0xea1debbb, 0xed37ef91, 0xf054d8d5, 0xf3742ca2, 
00120   0xf6956fb7, 0xf9b82684, 
00121   0xfcdbd541, 0x0, 0x3242abf 
00122 }; 
00123  
00124  
00125 /** 
00126  * @brief Fast approximation to the trigonometric sine function for Q31 data. 
00127  * @param[in] x Scaled input value in radians. 
00128  * @return  sin(x). 
00129  * 
00130  * The Q31 input value is in the range [0 +1) and is mapped to a radian value in the range [0 2*pi). 
00131  */ 
00132  
00133 q31_t arm_sin_q31( 
00134   q31_t x) 
00135 { 
00136   q31_t sinVal, fract, in, in2;                  /* Temporary variables for input, output */ 
00137   uint32_t index;                                /* Index variables */ 
00138   q31_t wa, wb, wc, wd;                          /* Cubic interpolation coefficients */ 
00139   q31_t a, b, c, d;                              /* Four nearest output values */ 
00140   q31_t *tablePtr;                               /* Pointer to table */ 
00141   q31_t fractCube, fractSquare;                  /* Temporary values for fractional value */ 
00142   q31_t oneBy6 = 0x15555555;                     /* Fixed point value of 1/6 */ 
00143   q31_t tableSpacing = TABLE_SPACING_Q31;        /* Table spacing */ 
00144   q31_t temp;                                    /* Temporary variable for intermediate process */ 
00145  
00146   in = x; 
00147  
00148   /* Calculate the nearest index */ 
00149   index = (uint32_t) in / (uint32_t) tableSpacing; 
00150  
00151   /* Calculate the nearest value of input */ 
00152   in2 = (q31_t) index *tableSpacing; 
00153  
00154   /* Calculation of fractional value */ 
00155   fract = (in - in2) << 8; 
00156  
00157   /* fractSquare = fract * fract */ 
00158   fractSquare = ((q31_t) (((q63_t) fract * fract) >> 32)); 
00159   fractSquare = fractSquare << 1; 
00160  
00161   /* fractCube = fract * fract * fract */ 
00162   fractCube = ((q31_t) (((q63_t) fractSquare * fract) >> 32)); 
00163   fractCube = fractCube << 1; 
00164  
00165   /* Initialise table pointer */ 
00166   tablePtr = (q31_t *) & sinTableQ31 [index]; 
00167  
00168   /* Cubic interpolation process */ 
00169   /* Calculation of wa */ 
00170   /* wa = -(oneBy6)*fractCube + (fractSquare >> 1u) - (0x2AAAAAAA)*fract; */ 
00171   wa = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32)); 
00172   temp = 0x2AAAAAAA; 
00173   wa = (q31_t) ((((q63_t) wa << 32) + ((q63_t) temp * fract)) >> 32); 
00174   wa = -(wa << 1u); 
00175   wa += (fractSquare >> 1u); 
00176  
00177   /* Read first nearest value of output from the sin table */ 
00178   a = *tablePtr++; 
00179  
00180   /* sinVal = a*wa */ 
00181   sinVal = ((q31_t) (((q63_t) a * wa) >> 32)); 
00182  
00183   /* q31(1.31) Fixed point value of 1 */ 
00184   temp = 0x7FFFFFFF; 
00185  
00186   /* Calculation of wb */ 
00187   wb = ((fractCube >> 1u) - (fractSquare + (fract >> 1u))) + temp; 
00188  
00189   /* Read second nearest value of output from the sin table */ 
00190   b = *tablePtr++; 
00191  
00192   /*  sinVal += b*wb */ 
00193   sinVal = (q31_t) ((((q63_t) sinVal << 32) + (q63_t) b * (wb)) >> 32); 
00194  
00195   /* Calculation of wc */ 
00196   wc = -fractCube + fractSquare; 
00197   wc = (wc >> 1u) + fract; 
00198  
00199   /* Read third nearest value of output from the sin table */ 
00200   c = *tablePtr++; 
00201  
00202   /*      sinVal += c*wc */ 
00203   sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) c * wc)) >> 32); 
00204  
00205   /* Calculation of wd */ 
00206   /* wd = (oneBy6) * fractCube - (oneBy6) * fract; */ 
00207   fractCube = fractCube - fract; 
00208   wd = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32)); 
00209   wd = (wd << 1u); 
00210  
00211   /* Read fourth nearest value of output from the sin table */ 
00212   d = *tablePtr++; 
00213  
00214   /* sinVal += d*wd; */ 
00215   sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) d * wd)) >> 32); 
00216  
00217   /* convert sinVal in 2.30 format to 1.31 format */ 
00218   return (sinVal << 1u); 
00219  
00220 } 
00221  
00222 /**  
00223  * @} end of sin group  
00224  */