Merge branch 'jnosky/master'
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / SupportFunctions / arm_float_to_q7.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_float_to_q7.c   
9 *   
10 * Description:  Converts the elements of the floating-point vector to Q7 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  * @ingroup groupSupport   
34  */
35
36 /**   
37  * @addtogroup float_to_x   
38  * @{   
39  */
40
41 /**   
42  * @brief Converts the elements of the floating-point vector to Q7 vector.   
43  * @param[in]       *pSrc points to the floating-point input vector   
44  * @param[out]      *pDst points to the Q7 output vector  
45  * @param[in]       blockSize length of the input vector   
46  * @return none.   
47  *   
48  *\par Description:   
49  * \par  
50  * The equation used for the conversion process is:   
51  * <pre>   
52  *      pDst[n] = (q7_t)(pSrc[n] * 128);   0 <= n < blockSize.   
53  * </pre>   
54  * \par Scaling and Overflow Behavior:   
55  * \par   
56  * The function uses saturating arithmetic.   
57  * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.   
58  * \note  
59  * In order to apply rounding, the library should be rebuilt with the ROUNDING macro    
60  * defined in the preprocessor section of project options.    
61  */
62
63
64 void arm_float_to_q7(
65   float32_t * pSrc,
66   q7_t * pDst,
67   uint32_t blockSize)
68 {
69   float32_t *pIn = pSrc;                         /* Src pointer */
70   uint32_t blkCnt;                               /* loop counter */
71
72 #ifdef ARM_MATH_ROUNDING
73
74   float32_t in;
75
76 #endif /*      #ifdef ARM_MATH_ROUNDING        */
77
78 #ifndef ARM_MATH_CM0
79
80   /* Run the below code for Cortex-M4 and Cortex-M3 */
81
82   /*loop Unrolling */
83   blkCnt = blockSize >> 2u;
84
85   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
86    ** a second loop below computes the remaining 1 to 3 samples. */
87   while(blkCnt > 0u)
88   {
89
90 #ifdef ARM_MATH_ROUNDING
91     /* C = A * 128 */
92     /* convert from float to q7 and then store the results in the destination buffer */
93     in = *pIn++;
94     in = (in * 128);
95     in += in > 0 ? 0.5 : -0.5;
96     *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
97
98     in = *pIn++;
99     in = (in * 128);
100     in += in > 0 ? 0.5 : -0.5;
101     *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
102
103     in = *pIn++;
104     in = (in * 128);
105     in += in > 0 ? 0.5 : -0.5;
106     *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
107
108     in = *pIn++;
109     in = (in * 128);
110     in += in > 0 ? 0.5 : -0.5;
111     *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
112
113 #else
114
115     /* C = A * 128 */
116     /* convert from float to q7 and then store the results in the destination buffer */
117     *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
118     *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
119     *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
120     *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
121
122 #endif /*      #ifdef ARM_MATH_ROUNDING        */
123
124     /* Decrement the loop counter */
125     blkCnt--;
126   }
127
128   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
129    ** No loop unrolling is used. */
130   blkCnt = blockSize % 0x4u;
131
132   while(blkCnt > 0u)
133   {
134
135 #ifdef ARM_MATH_ROUNDING
136     /* C = A * 128 */
137     /* convert from float to q7 and then store the results in the destination buffer */
138     in = *pIn++;
139     in = (in * 128);
140     in += in > 0 ? 0.5 : -0.5;
141     *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
142
143 #else
144
145     /* C = A * 128 */
146     /* convert from float to q7 and then store the results in the destination buffer */
147     *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
148
149 #endif /*      #ifdef ARM_MATH_ROUNDING        */
150
151     /* Decrement the loop counter */
152     blkCnt--;
153   }
154
155
156 #else
157
158   /* Run the below code for Cortex-M0 */
159
160
161   /* Loop over blockSize number of values */
162   blkCnt = blockSize;
163
164   while(blkCnt > 0u)
165   {
166 #ifdef ARM_MATH_ROUNDING
167     /* C = A * 128 */
168     /* convert from float to q7 and then store the results in the destination buffer */
169     in = *pIn++;
170     in = (in * 128.0f);
171     in += in > 0 ? 0.5f : -0.5f;
172     *pDst++ = (q7_t) (__SSAT((q31_t) (in), 8));
173
174 #else
175
176     /* C = A * 128 */
177     /* convert from float to q7 and then store the results in the destination buffer */
178     *pDst++ = (q7_t) __SSAT((q31_t) (*pIn++ * 128.0f), 8);
179
180 #endif /*      #ifdef ARM_MATH_ROUNDING        */
181
182     /* Decrement the loop counter */
183     blkCnt--;
184   }
185
186 #endif /* #ifndef ARM_MATH_CM0 */
187
188 }
189
190 /**   
191  * @} end of float_to_x group   
192  */