Merge branch 'jnosky/master'
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / ComplexMathFunctions / arm_cmplx_dot_prod_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_cmplx_dot_prod_q15.c   
9 *   
10 * Description:  Processing function for the Q15 Complex Dot product   
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 groupCmplxMath   
34  */
35
36 /**   
37  * @addtogroup cmplx_dot_prod   
38  * @{   
39  */
40
41 /**   
42  * @brief  Q15 complex dot product   
43  * @param  *pSrcA points to the first input vector   
44  * @param  *pSrcB points to the second input vector   
45  * @param  numSamples number of complex samples in each vector   
46  * @param  *realResult real part of the result returned here   
47  * @param  *imagResult imaginary part of the result returned here   
48  * @return none.   
49  *   
50  * <b>Scaling and Overflow Behavior:</b>   
51  * \par   
52  * The function is implemented using an internal 64-bit accumulator.   
53  * The intermediate 1.15 by 1.15 multiplications are performed with full precision and yield a 2.30 result.   
54  * These are accumulated in a 64-bit accumulator with 34.30 precision.   
55  * As a final step, the accumulators are converted to 8.24 format.   
56  * The return results <code>realResult</code> and <code>imagResult</code> are in 8.24 format.   
57  */
58
59 void arm_cmplx_dot_prod_q15(
60   q15_t * pSrcA,
61   q15_t * pSrcB,
62   uint32_t numSamples,
63   q31_t * realResult,
64   q31_t * imagResult)
65 {
66   q63_t real_sum = 0, imag_sum = 0;              /* Temporary result storage */
67
68 #ifndef ARM_MATH_CM0
69
70   /* Run the below code for Cortex-M4 and Cortex-M3 */
71   uint32_t blkCnt;                               /* loop counter */
72
73
74   /*loop Unrolling */
75   blkCnt = numSamples >> 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     /* CReal = A[0]* B[0] + A[2]* B[2] + A[4]* B[4] + .....+ A[numSamples-2]* B[numSamples-2] */
82     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
83
84     /* CImag = A[1]* B[1] + A[3]* B[3] + A[5]* B[5] + .....+ A[numSamples-1]* B[numSamples-1] */
85     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
86
87     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
88     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
89
90     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
91     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
92
93     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
94     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
95
96     /* Decrement the loop counter */
97     blkCnt--;
98   }
99
100   /* If the numSamples is not a multiple of 4, compute any remaining output samples here.   
101    ** No loop unrolling is used. */
102   blkCnt = numSamples % 0x4u;
103
104   while(blkCnt > 0u)
105   {
106     /* CReal = A[0]* B[0] + A[2]* B[2] + A[4]* B[4] + .....+ A[numSamples-2]* B[numSamples-2] */
107     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
108     /* CImag = A[1]* B[1] + A[3]* B[3] + A[5]* B[5] + .....+ A[numSamples-1]* B[numSamples-1] */
109     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
110
111     /* Decrement the loop counter */
112     blkCnt--;
113   }
114
115 #else
116
117   /* Run the below code for Cortex-M0 */
118
119   while(numSamples > 0u)
120   {
121     /* CReal = A[0]* B[0] + A[2]* B[2] + A[4]* B[4] + .....+ A[numSamples-2]* B[numSamples-2] */
122     real_sum += ((q31_t) * pSrcA++ * *pSrcB++);
123     /* CImag = A[1]* B[1] + A[3]* B[3] + A[5]* B[5] + .....+ A[numSamples-1]* B[numSamples-1] */
124     imag_sum += ((q31_t) * pSrcA++ * *pSrcB++);
125
126     /* Decrement the loop counter */
127     numSamples--;
128   }
129
130 #endif /* #ifndef ARM_MATH_CM0 */
131
132   /* Store the real and imaginary results in 8.24 format  */
133   /* Convert real data in 34.30 to 8.24 by 6 right shifts */
134   *realResult = (q31_t) (real_sum) >> 6;
135   /* Convert imaginary data in 34.30 to 8.24 by 6 right shifts */
136   *imagResult = (q31_t) (imag_sum) >> 6;
137 }
138
139 /**   
140  * @} end of cmplx_dot_prod group   
141  */