Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "arm_math.h"
00025
00068 void arm_lms_norm_q15(
00069 arm_lms_norm_instance_q15 * S,
00070 q15_t * pSrc,
00071 q15_t * pRef,
00072 q15_t * pOut,
00073 q15_t * pErr,
00074 uint32_t blockSize)
00075 {
00076 q15_t *pState = S->pState;
00077 q15_t *pCoeffs = S->pCoeffs;
00078 q15_t *pStateCurnt;
00079 q15_t *px, *pb;
00080 q15_t mu = S->mu;
00081 uint32_t numTaps = S->numTaps;
00082 uint32_t tapCnt, blkCnt;
00083 q31_t energy;
00084 q63_t acc;
00085 q15_t e = 0, d = 0;
00086 q15_t w = 0, in;
00087 q15_t x0;
00088 q15_t errorXmu, oneByEnergy;
00089 q15_t postShift;
00090 q31_t coef;
00091 q31_t x1, x2;
00092 q31_t c0, c1;
00093 q31_t coef0, coef1;
00094 q31_t acc_l, acc_h;
00095 int32_t lShift = (15 - (int32_t) S->postShift);
00096 int32_t uShift = (32 - lShift);
00097
00098 energy = S->energy;
00099 x0 = S->x0;
00100
00101
00102
00103 pStateCurnt = &(S->pState[(numTaps - 1u)]);
00104
00105
00106 blkCnt = blockSize;
00107
00108 while(blkCnt > 0u)
00109 {
00110
00111 *pStateCurnt++ = *pSrc;
00112
00113
00114 px = pState;
00115
00116
00117 pb = (pCoeffs);
00118
00119
00120 in = *pSrc++;
00121
00122
00123 energy -= (((q31_t) x0 * (x0)) >> 15);
00124 energy += (((q31_t) in * (in)) >> 15);
00125
00126
00127 acc = 0;
00128
00129
00130 tapCnt = numTaps >> 2;
00131
00132 while(tapCnt > 0u)
00133 {
00134
00135 x1 = _SIMD32_OFFSET(px);
00136 c0 = *__SIMD32(pb)++;
00137
00138
00139 x2 = _SIMD32_OFFSET(px + 2u);
00140 c1 = *__SIMD32(pb)++;
00141
00142 px += 4u;
00143
00144
00145
00146 acc = __SMLALD(x1, c0, acc);
00147 acc = __SMLALD(x2, c1, acc);
00148
00149
00150 tapCnt--;
00151 }
00152
00153
00154 tapCnt = numTaps % 0x4u;
00155
00156 while(tapCnt > 0u)
00157 {
00158
00159 acc += (((q31_t) * px++ * (*pb++)));
00160
00161
00162 tapCnt--;
00163 }
00164
00165
00166 acc_l = acc & 0xffffffff;
00167
00168
00169 acc_h = (acc >> 32) & 0xffffffff;
00170
00171
00172 acc = (uint32_t)acc_l >> lShift | acc_h << uShift;
00173
00174
00175 #ifdef CCS
00176 acc = __SSATA(acc, 0, 16u);
00177 #else
00178 acc = __SSAT(acc, 16u);
00179 #endif
00180
00181
00182 *pOut++ = (q15_t) acc;
00183
00184
00185 d = *pRef++;
00186 e = d - (q15_t) acc;
00187 *pErr++ = e;
00188
00189
00190 postShift = arm_recip_q15((q15_t) energy + DELTA_Q15,
00191 &oneByEnergy, S->recipTable);
00192
00193
00194 errorXmu = (q15_t) (((q31_t) e * mu) >> 15);
00195
00196
00197 acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift));
00198
00199
00200 #ifdef CCS
00201 w = (q15_t) __SSATA((q31_t) acc, 0, 16);
00202 #else
00203 w = (q15_t) __SSAT((q31_t) acc, 16);
00204 #endif
00205
00206 px = pState;
00207
00208
00209 pb = (pCoeffs);
00210
00211
00212 tapCnt = numTaps >> 2;
00213
00214
00215 while(tapCnt > 0u)
00216 {
00217
00218
00219
00220
00221 x1 = *px;
00222 x2 = *(px + 1u);
00223 c0 = *pb;
00224 c1 = *(pb + 1u);
00225
00226
00227
00228 coef0 = (q31_t) c0 + (((q31_t) w * x1) >> 15);
00229 coef1 = (q31_t) c1 + (((q31_t) w * x2) >> 15);
00230
00231 #ifdef CCS
00232 c0 = (q15_t) __SSATA((coef0), 0, 16);
00233 c1 = (q15_t) __SSATA((coef1), 0, 16);
00234 #else
00235 c0 = (q15_t) __SSAT((coef0), 16);
00236 c1 = (q15_t) __SSAT((coef1), 16);
00237 #endif
00238
00239
00240 *pb = c0;
00241 *(pb + 1u) = c1;
00242
00243
00244 x1 = *(px + 2u);
00245 x2 = *(px + 3u);
00246 c0 = *(pb + 2u);
00247 c1 = *(pb + 3u);
00248
00249
00250
00251 coef0 = (q31_t) c0 + (((q31_t) w * x1) >> 15);
00252 coef1 = (q31_t) c1 + (((q31_t) w * x2) >> 15);
00253
00254 #ifdef CCS
00255 c0 = (q15_t) __SSATA((coef0), 0, 16);
00256 c1 = (q15_t) __SSATA((coef1), 0, 16);
00257 #else
00258 c0 = (q15_t) __SSAT((coef0), 16);
00259 c1 = (q15_t) __SSAT((coef1), 16);
00260 #endif
00261
00262
00263 *(pb + 2u) = c0;
00264 *(pb + 3u) = c1;
00265
00266
00267 px += 4u;
00268 pb += 4u;
00269
00270
00271 tapCnt--;
00272 }
00273
00274
00275 tapCnt = numTaps % 0x4u;
00276
00277 while(tapCnt > 0u)
00278 {
00279
00280 coef = *pb + (((q31_t) w * (*px++)) >> 15);
00281
00282 #ifdef CCS
00283 *pb++ = (q15_t) __SSATA((coef), 0, 16);
00284 #else
00285 *pb++ = (q15_t) __SSAT((coef), 16);
00286 #endif
00287
00288
00289 tapCnt--;
00290 }
00291
00292
00293 x0 = *pState;
00294
00295
00296 pState = pState + 1u;
00297
00298
00299 blkCnt--;
00300 }
00301
00302
00303 S->energy = (q15_t) energy;
00304 S->x0 = x0;
00305
00306
00307
00308
00309
00310
00311 pStateCurnt = S->pState;
00312
00313
00314 tapCnt = (numTaps - 1u) >> 2;
00315
00316 while(tapCnt > 0u)
00317 {
00318
00319 #ifndef UNALIGNED_SUPPORT_DISABLE
00320
00321 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
00322 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
00323
00324 #else
00325
00326 *pStateCurnt++ = *pState++;
00327 *pStateCurnt++ = *pState++;
00328 *pStateCurnt++ = *pState++;
00329 *pStateCurnt++ = *pState++;
00330
00331 #endif
00332
00333 tapCnt--;
00334
00335 }
00336
00337
00338 tapCnt = (numTaps - 1u) % 0x4u;
00339
00340
00341 while(tapCnt > 0u)
00342 {
00343 *pStateCurnt++ = *pState++;
00344
00345
00346 tapCnt--;
00347 }
00348
00349
00350 }
00351
00352