1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010 ARM Limited. All rights reserved.
7 * Project: CMSIS DSP Library
8 * Title: arm_sqrt_q15.c
10 * Description: Q15 square root function.
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 * Version 1.0.10 2011/7/15
15 * Big Endian support added and Merged M0 and M3/M4 Source code.
17 * Version 1.0.3 2010/11/29
18 * Re-organized the CMSIS folders and updated documentation.
20 * Version 1.0.2 2010/11/11
21 * Documentation updated.
23 * Version 1.0.1 2010/10/05
24 * Production release and review comments incorporated.
26 * Version 1.0.0 2010/09/20
27 * Production release and review comments incorporated.
28 * -------------------------------------------------------------------- */
31 #include "arm_common_tables.h"
35 * @ingroup groupFastMath
44 * @brief Q15 square root function.
45 * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
46 * @param[out] *pOut square root of input value.
47 * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
48 * <code>in</code> is negative value and returns zero output for negative values.
51 arm_status arm_sqrt_q15(
61 /* Run the below code for Cortex-M4 and Cortex-M3 */
67 /* run for ten iterations */
69 /* Take initial guess as half of the input and first iteration */
70 out = ((q31_t) in >> 1u) + 0x3FFF;
72 /* Calculation of reciprocal of out */
73 /* oneByOut contains reciprocal of out which is in 2.14 format
74 and oneByOut should be upscaled by signBits */
75 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
79 /* prevOut = 0.5 * out + (in * (oneByOut << signBits))) */
80 prevOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
83 sign_bits = arm_recip_q15((q15_t) prevOut, &oneByOut, armRecipTableQ15);
84 prevOut = prevOut >> 1u;
85 out = prevOut + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
87 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
89 prevOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
92 sign_bits = arm_recip_q15((q15_t) prevOut, &oneByOut, armRecipTableQ15);
93 prevOut = prevOut >> 1u;
94 out = prevOut + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
96 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
98 prevOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
100 /* Seventh iteration */
101 sign_bits = arm_recip_q15((q15_t) prevOut, &oneByOut, armRecipTableQ15);
102 prevOut = prevOut >> 1u;
103 out = prevOut + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
105 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
107 prevOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
109 sign_bits = arm_recip_q15((q15_t) prevOut, &oneByOut, armRecipTableQ15);
110 prevOut = prevOut >> 1u;
111 out = prevOut + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
113 /* tenth iteration */
114 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
116 *pOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
118 return (ARM_MATH_SUCCESS);
123 /* Run the below code for Cortex-M0 */
125 q31_t out, loopVar; /* Temporary variable for output, loop variable */
128 /* run for ten iterations */
130 /* Take initial guess as half of the input and first iteration */
131 out = ((q31_t) in >> 1u) + 0x3FFF;
133 /* Calculation of reciprocal of out */
135 /* oneByOut contains reciprocal of out which is in 2.14 format
136 and oneByOut should be upscaled by sign bits */
137 sign_bits = arm_recip_q15((q15_t) out, &oneByOut, armRecipTableQ15);
141 /* prevOut = 0.5 * out + (in * oneByOut) << signbits))) */
142 prevOut = out + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
144 /* loop for third iteration to tenth iteration */
146 for (loopVar = 1; loopVar <= 8; loopVar++)
149 sign_bits = arm_recip_q15((q15_t) prevOut, &oneByOut, armRecipTableQ15);
150 /* 0.5 * (prevOut) */
151 prevOut = prevOut >> 1u;
152 /* prevOut = 0.5 * prevOut+ (in * oneByOut) << signbits))) */
154 prevOut + (((q15_t) (((q31_t) in * oneByOut) >> 16)) << sign_bits);
159 /* output is moved to pOut pointer */
162 return (ARM_MATH_SUCCESS);
165 #endif /* #ifndef ARM_MATH_CM0 */
171 return (ARM_MATH_ARGUMENT_ERROR);
177 * @} end of SQRT group