Added all the F4 libraries to the project
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / StatisticsFunctions / arm_rms_q15.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_rms_q15.c   
9 *   
10 * Description:  Root Mean Square of the elements of a Q15 vector. 
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  * @addtogroup RMS   
34  * @{   
35  */
36
37 /**   
38  * @brief Root Mean Square of the elements of a Q15 vector.   
39  * @param[in]       *pSrc points to the input vector   
40  * @param[in]       blockSize length of the input vector   
41  * @param[out]      *pResult rms value returned here   
42  * @return none.   
43  *   
44  * @details   
45  * <b>Scaling and Overflow Behavior:</b>   
46  *   
47  * \par   
48  * The function is implemented using a 64-bit internal accumulator.   
49  * The input is represented in 1.15 format.   
50  * Intermediate multiplication yields a 2.30 format, and this   
51  * result is added without saturation to a 64-bit accumulator in 34.30 format.   
52  * With 33 guard bits in the accumulator, there is no risk of overflow, and the   
53  * full precision of the intermediate multiplication is preserved.   
54  * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower    
55  * 15 bits, and then saturated to yield a result in 1.15 format.   
56  *   
57  */
58
59 void arm_rms_q15(
60   q15_t * pSrc,
61   uint32_t blockSize,
62   q15_t * pResult)
63 {
64   q63_t sum = 0;                                 /* accumulator */
65
66 #ifndef ARM_MATH_CM0
67
68   /* Run the below code for Cortex-M4 and Cortex-M3 */
69
70   q31_t in;                                      /* temporary variable to store the input value */
71   q15_t in1;                                     /* temporary variable to store the input value */
72   uint32_t blkCnt;                               /* loop counter */
73
74   /* loop Unrolling */
75   blkCnt = blockSize >> 2u;
76
77   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
78    ** a second loop below computes the remaining 1 to 3 samples. */
79   while(blkCnt > 0u)
80   {
81     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
82     /* Compute sum of the squares and then store the results in a temporary variable, sum */
83     in = *__SIMD32(pSrc)++;
84     sum = __SMLALD(in, in, sum);
85     in = *__SIMD32(pSrc)++;
86     sum = __SMLALD(in, in, sum);
87
88     /* Decrement the loop counter */
89     blkCnt--;
90   }
91
92   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
93    ** No loop unrolling is used. */
94   blkCnt = blockSize % 0x4u;
95
96   while(blkCnt > 0u)
97   {
98     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
99     /* Compute sum of the squares and then store the results in a temporary variable, sum */
100     in1 = *pSrc++;
101     sum = __SMLALD(in1, in1, sum);
102
103     /* Decrement the loop counter */
104     blkCnt--;
105   }
106
107   /* Truncating and saturating the accumulator to 1.15 format */
108   sum = __SSAT((q31_t) (sum >> 15), 16);
109
110   in1 = (q15_t) (sum / blockSize);
111
112   /* Store the result in the destination */
113   arm_sqrt_q15(in1, pResult);
114
115 #else
116
117   /* Run the below code for Cortex-M0 */
118
119   q15_t in;                                      /* temporary variable to store the input value */
120   uint32_t blkCnt;                               /* loop counter */
121
122   /* Loop over blockSize number of values */
123   blkCnt = blockSize;
124
125   while(blkCnt > 0u)
126   {
127     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
128     /* Compute sum of the squares and then store the results in a temporary variable, sum */
129     in = *pSrc++;
130     sum += ((q31_t) in * in);
131
132     /* Decrement the loop counter */
133     blkCnt--;
134   }
135
136   /* Truncating and saturating the accumulator to 1.15 format */
137   sum = __SSAT((q31_t) (sum >> 15), 16);
138
139   in = (q15_t) (sum / blockSize);
140
141   /* Store the result in the destination */
142   arm_sqrt_q15(in, pResult);
143
144 #endif /* #ifndef ARM_MATH_CM0 */
145
146 }
147
148 /**   
149  * @} end of RMS group   
150  */