CMSIS DSP Software Library: arm_fir_lattice_f32.c Source File

- Main Page
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

# arm_fir_lattice_f32.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------
    00002 * Copyright (C) 2010 ARM Limited. All rights reserved.
    00003 *
    00004 * $Date:        15. July 2011
    00005 * $Revision:    V1.0.10
    00006 *
    00007 * Project:      CMSIS DSP Library
    00008 * Title:        arm_fir_lattice_f32.c
    00009 *
    00010 * Description:  Processing function for the floating-point FIR Lattice filter.
    00011 *
    00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
    00013 *
    00014 * Version 1.0.10 2011/7/15
    00015 *    Big Endian support added and Merged M0 and M3/M4 Source code.
    00016 *
    00017 * Version 1.0.3 2010/11/29
    00018 *    Re-organized the CMSIS folders and updated documentation.
    00019 *
    00020 * Version 1.0.2 2010/11/11
    00021 *    Documentation updated.
    00022 *
    00023 * Version 1.0.1 2010/10/05
    00024 *    Production release and review comments incorporated.
    00025 *
    00026 * Version 1.0.0 2010/09/20
    00027 *    Production release and review comments incorporated
    00028 *
    00029 * Version 0.0.7  2010/06/10
    00030 *    Misra-C changes done
    00031 * -------------------------------------------------------------------- */
    00032
    00033 #include "arm_math.h"
    00034
    00121 void arm_fir_lattice_f32(
    00122   const arm_fir_lattice_instance_f32 * S,
    00123   float32_t * pSrc,
    00124   float32_t * pDst,
    00125   uint32_t blockSize)
    00126 {
    00127   float32_t *pState;                             /* State pointer */
    00128   float32_t *pCoeffs = S->pCoeffs;               /* Coefficient pointer */
    00129   float32_t *px;                                 /* temporary state pointer */
    00130   float32_t *pk;                                 /* temporary coefficient pointer */
    00131
    00132
    00133 #ifndef ARM_MATH_CM0
    00134
    00135   /* Run the below code for Cortex-M4 and Cortex-M3 */
    00136
    00137   float32_t fcurr1, fnext1, gcurr1, gnext1;      /* temporary variables for first sample in loop unrolling */
    00138   float32_t fcurr2, fnext2, gnext2;              /* temporary variables for second sample in loop unrolling */
    00139   float32_t fcurr3, fnext3, gnext3;              /* temporary variables for third sample in loop unrolling */
    00140   float32_t fcurr4, fnext4, gnext4;              /* temporary variables for fourth sample in loop unrolling */
    00141   uint32_t numStages = S->numStages;             /* Number of stages in the filter */
    00142   uint32_t blkCnt, stageCnt;                     /* temporary variables for counts */
    00143
    00144   gcurr1 = 0.0f;
    00145   pState = &S->pState[0];
    00146
    00147   blkCnt = blockSize >> 2;
    00148
    00149   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00150      a second loop below computes the remaining 1 to 3 samples. */
    00151   while(blkCnt > 0u)
    00152   {
    00153
    00154     /* Read two samples from input buffer */
    00155     /* f0(n) = x(n) */
    00156     fcurr1 = *pSrc++;
    00157     fcurr2 = *pSrc++;
    00158
    00159     /* Initialize coeff pointer */
    00160     pk = (pCoeffs);
    00161
    00162     /* Initialize state pointer */
    00163     px = pState;
    00164
    00165     /* Read g0(n-1) from state */
    00166     gcurr1 = *px;
    00167
    00168     /* Process first sample for first tap */
    00169     /* f1(n) = f0(n) +  K1 * g0(n-1) */
    00170     fnext1 = fcurr1 + ((*pk) * gcurr1);
    00171     /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00172     gnext1 = (fcurr1 * (*pk)) + gcurr1;
    00173
    00174     /* Process second sample for first tap */
    00175     /* for sample 2 processing */
    00176     fnext2 = fcurr2 + ((*pk) * fcurr1);
    00177     gnext2 = (fcurr2 * (*pk)) + fcurr1;
    00178
    00179     /* Read next two samples from input buffer */
    00180     /* f0(n+2) = x(n+2) */
    00181     fcurr3 = *pSrc++;
    00182     fcurr4 = *pSrc++;
    00183
    00184     /* Copy only last input samples into the state buffer
    00185        which will be used for next four samples processing */
    00186     *px++ = fcurr4;
    00187
    00188     /* Process third sample for first tap */
    00189     fnext3 = fcurr3 + ((*pk) * fcurr2);
    00190     gnext3 = (fcurr3 * (*pk)) + fcurr2;
    00191
    00192     /* Process fourth sample for first tap */
    00193     fnext4 = fcurr4 + ((*pk) * fcurr3);
    00194     gnext4 = (fcurr4 * (*pk++)) + fcurr3;
    00195
    00196     /* Update of f values for next coefficient set processing */
    00197     fcurr1 = fnext1;
    00198     fcurr2 = fnext2;
    00199     fcurr3 = fnext3;
    00200     fcurr4 = fnext4;
    00201
    00202     /* Loop unrolling.  Process 4 taps at a time . */
    00203     stageCnt = (numStages - 1u) >> 2u;
    00204
    00205     /* Loop over the number of taps.  Unroll by a factor of 4.
    00206      ** Repeat until we've computed numStages-3 coefficients. */
    00207
    00208     /* Process 2nd, 3rd, 4th and 5th taps ... here */
    00209     while(stageCnt > 0u)
    00210     {
    00211       /* Read g1(n-1), g3(n-1) .... from state */
    00212       gcurr1 = *px;
    00213
    00214       /* save g1(n) in state buffer */
    00215       *px++ = gnext4;
    00216
    00217       /* Process first sample for 2nd, 6th .. tap */
    00218       /* Sample processing for K2, K6.... */
    00219       /* f2(n) = f1(n) +  K2 * g1(n-1) */
    00220       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00221       /* Process second sample for 2nd, 6th .. tap */
    00222       /* for sample 2 processing */
    00223       fnext2 = fcurr2 + ((*pk) * gnext1);
    00224       /* Process third sample for 2nd, 6th .. tap */
    00225       fnext3 = fcurr3 + ((*pk) * gnext2);
    00226       /* Process fourth sample for 2nd, 6th .. tap */
    00227       fnext4 = fcurr4 + ((*pk) * gnext3);
    00228
    00229       /* g2(n) = f1(n) * K2  +  g1(n-1) */
    00230       /* Calculation of state values for next stage */
    00231       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00232       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00233       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00234       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00235
    00236
    00237       /* Read g2(n-1), g4(n-1) .... from state */
    00238       gcurr1 = *px;
    00239
    00240       /* save g2(n) in state buffer */
    00241       *px++ = gnext4;
    00242
    00243       /* Sample processing for K3, K7.... */
    00244       /* Process first sample for 3rd, 7th .. tap */
    00245       /* f3(n) = f2(n) +  K3 * g2(n-1) */
    00246       fcurr1 = fnext1 + ((*pk) * gcurr1);
    00247       /* Process second sample for 3rd, 7th .. tap */
    00248       fcurr2 = fnext2 + ((*pk) * gnext1);
    00249       /* Process third sample for 3rd, 7th .. tap */
    00250       fcurr3 = fnext3 + ((*pk) * gnext2);
    00251       /* Process fourth sample for 3rd, 7th .. tap */
    00252       fcurr4 = fnext4 + ((*pk) * gnext3);
    00253
    00254       /* Calculation of state values for next stage */
    00255       /* g3(n) = f2(n) * K3  +  g2(n-1) */
    00256       gnext4 = (fnext4 * (*pk)) + gnext3;
    00257       gnext3 = (fnext3 * (*pk)) + gnext2;
    00258       gnext2 = (fnext2 * (*pk)) + gnext1;
    00259       gnext1 = (fnext1 * (*pk++)) + gcurr1;
    00260
    00261
    00262       /* Read g1(n-1), g3(n-1) .... from state */
    00263       gcurr1 = *px;
    00264
    00265       /* save g3(n) in state buffer */
    00266       *px++ = gnext4;
    00267
    00268       /* Sample processing for K4, K8.... */
    00269       /* Process first sample for 4th, 8th .. tap */
    00270       /* f4(n) = f3(n) +  K4 * g3(n-1) */
    00271       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00272       /* Process second sample for 4th, 8th .. tap */
    00273       /* for sample 2 processing */
    00274       fnext2 = fcurr2 + ((*pk) * gnext1);
    00275       /* Process third sample for 4th, 8th .. tap */
    00276       fnext3 = fcurr3 + ((*pk) * gnext2);
    00277       /* Process fourth sample for 4th, 8th .. tap */
    00278       fnext4 = fcurr4 + ((*pk) * gnext3);
    00279
    00280       /* g4(n) = f3(n) * K4  +  g3(n-1) */
    00281       /* Calculation of state values for next stage */
    00282       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00283       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00284       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00285       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00286
    00287       /* Read g2(n-1), g4(n-1) .... from state */
    00288       gcurr1 = *px;
    00289
    00290       /* save g4(n) in state buffer */
    00291       *px++ = gnext4;
    00292
    00293       /* Sample processing for K5, K9.... */
    00294       /* Process first sample for 5th, 9th .. tap */
    00295       /* f5(n) = f4(n) +  K5 * g4(n-1) */
    00296       fcurr1 = fnext1 + ((*pk) * gcurr1);
    00297       /* Process second sample for 5th, 9th .. tap */
    00298       fcurr2 = fnext2 + ((*pk) * gnext1);
    00299       /* Process third sample for 5th, 9th .. tap */
    00300       fcurr3 = fnext3 + ((*pk) * gnext2);
    00301       /* Process fourth sample for 5th, 9th .. tap */
    00302       fcurr4 = fnext4 + ((*pk) * gnext3);
    00303
    00304       /* Calculation of state values for next stage */
    00305       /* g5(n) = f4(n) * K5  +  g4(n-1) */
    00306       gnext4 = (fnext4 * (*pk)) + gnext3;
    00307       gnext3 = (fnext3 * (*pk)) + gnext2;
    00308       gnext2 = (fnext2 * (*pk)) + gnext1;
    00309       gnext1 = (fnext1 * (*pk++)) + gcurr1;
    00310
    00311       stageCnt--;
    00312     }
    00313
    00314     /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */
    00315     stageCnt = (numStages - 1u) % 0x4u;
    00316
    00317     while(stageCnt > 0u)
    00318     {
    00319       gcurr1 = *px;
    00320
    00321       /* save g value in state buffer */
    00322       *px++ = gnext4;
    00323
    00324       /* Process four samples for last three taps here */
    00325       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00326       fnext2 = fcurr2 + ((*pk) * gnext1);
    00327       fnext3 = fcurr3 + ((*pk) * gnext2);
    00328       fnext4 = fcurr4 + ((*pk) * gnext3);
    00329
    00330       /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00331       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00332       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00333       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00334       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00335
    00336       /* Update of f values for next coefficient set processing */
    00337       fcurr1 = fnext1;
    00338       fcurr2 = fnext2;
    00339       fcurr3 = fnext3;
    00340       fcurr4 = fnext4;
    00341
    00342       stageCnt--;
    00343
    00344     }
    00345
    00346     /* The results in the 4 accumulators, store in the destination buffer. */
    00347     /* y(n) = fN(n) */
    00348     *pDst++ = fcurr1;
    00349     *pDst++ = fcurr2;
    00350     *pDst++ = fcurr3;
    00351     *pDst++ = fcurr4;
    00352
    00353     blkCnt--;
    00354   }
    00355
    00356   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00357    ** No loop unrolling is used. */
    00358   blkCnt = blockSize % 0x4u;
    00359
    00360   while(blkCnt > 0u)
    00361   {
    00362     /* f0(n) = x(n) */
    00363     fcurr1 = *pSrc++;
    00364
    00365     /* Initialize coeff pointer */
    00366     pk = (pCoeffs);
    00367
    00368     /* Initialize state pointer */
    00369     px = pState;
    00370
    00371     /* read g2(n) from state buffer */
    00372     gcurr1 = *px;
    00373
    00374     /* for sample 1 processing */
    00375     /* f1(n) = f0(n) +  K1 * g0(n-1) */
    00376     fnext1 = fcurr1 + ((*pk) * gcurr1);
    00377     /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00378     gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00379
    00380     /* save g1(n) in state buffer */
    00381     *px++ = fcurr1;
    00382
    00383     /* f1(n) is saved in fcurr1
    00384        for next stage processing */
    00385     fcurr1 = fnext1;
    00386
    00387     stageCnt = (numStages - 1u);
    00388
    00389     /* stage loop */
    00390     while(stageCnt > 0u)
    00391     {
    00392       /* read g2(n) from state buffer */
    00393       gcurr1 = *px;
    00394
    00395       /* save g1(n) in state buffer */
    00396       *px++ = gnext1;
    00397
    00398       /* Sample processing for K2, K3.... */
    00399       /* f2(n) = f1(n) +  K2 * g1(n-1) */
    00400       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00401       /* g2(n) = f1(n) * K2  +  g1(n-1) */
    00402       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00403
    00404       /* f1(n) is saved in fcurr1
    00405          for next stage processing */
    00406       fcurr1 = fnext1;
    00407
    00408       stageCnt--;
    00409
    00410     }
    00411
    00412     /* y(n) = fN(n) */
    00413     *pDst++ = fcurr1;
    00414
    00415     blkCnt--;
    00416
    00417   }
    00418
    00419 #else
    00420
    00421   /* Run the below code for Cortex-M0 */
    00422
    00423   float32_t fcurr, fnext, gcurr, gnext;          /* temporary variables */
    00424   uint32_t numStages = S->numStages;             /* Length of the filter */
    00425   uint32_t blkCnt, stageCnt;                     /* temporary variables for counts */
    00426
    00427   pState = &S->pState[0];
    00428
    00429   blkCnt = blockSize;
    00430
    00431   while(blkCnt > 0u)
    00432   {
    00433     /* f0(n) = x(n) */
    00434     fcurr = *pSrc++;
    00435
    00436     /* Initialize coeff pointer */
    00437     pk = pCoeffs;
    00438
    00439     /* Initialize state pointer */
    00440     px = pState;
    00441
    00442     /* read g0(n-1) from state buffer */
    00443     gcurr = *px;
    00444
    00445     /* for sample 1 processing */
    00446     /* f1(n) = f0(n) +  K1 * g0(n-1) */
    00447     fnext = fcurr + ((*pk) * gcurr);
    00448     /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00449     gnext = (fcurr * (*pk++)) + gcurr;
    00450
    00451     /* save f0(n) in state buffer */
    00452     *px++ = fcurr;
    00453
    00454     /* f1(n) is saved in fcurr
    00455        for next stage processing */
    00456     fcurr = fnext;
    00457
    00458     stageCnt = (numStages - 1u);
    00459
    00460     /* stage loop */
    00461     while(stageCnt > 0u)
    00462     {
    00463       /* read g2(n) from state buffer */
    00464       gcurr = *px;
    00465
    00466       /* save g1(n) in state buffer */
    00467       *px++ = gnext;
    00468
    00469       /* Sample processing for K2, K3.... */
    00470       /* f2(n) = f1(n) +  K2 * g1(n-1) */
    00471       fnext = fcurr + ((*pk) * gcurr);
    00472       /* g2(n) = f1(n) * K2  +  g1(n-1) */
    00473       gnext = (fcurr * (*pk++)) + gcurr;
    00474
    00475       /* f1(n) is saved in fcurr1
    00476          for next stage processing */
    00477       fcurr = fnext;
    00478
    00479       stageCnt--;
    00480
    00481     }
    00482
    00483     /* y(n) = fN(n) */
    00484     *pDst++ = fcurr;
    00485
    00486     blkCnt--;
    00487
    00488   }
    00489
    00490 #endif /*   #ifndef ARM_MATH_CM0 */
    00491
    00492 }
    00493

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines