Subversion Repositories FuelGauge

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
  3. *
  4. * $Date:         17. January 2013
  5. * $Revision:     V1.4.0
  6. *
  7. * Project:       CMSIS DSP Library
  8. * Title:         arm_signal_converge_example_f32.c
  9. *
  10. * Description:   Example code demonstrating convergence of an adaptive
  11. *                filter.
  12. *
  13. * Target Processor: Cortex-M4/Cortex-M3
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. *   - Redistributions of source code must retain the above copyright
  19. *     notice, this list of conditions and the following disclaimer.
  20. *   - Redistributions in binary form must reproduce the above copyright
  21. *     notice, this list of conditions and the following disclaimer in
  22. *     the documentation and/or other materials provided with the
  23. *     distribution.
  24. *   - Neither the name of ARM LIMITED nor the names of its contributors
  25. *     may be used to endorse or promote products derived from this
  26. *     software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  29. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  30. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  31. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  32. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  33. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  34. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  38. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40.  * -------------------------------------------------------------------- */
  41.  
  42. /**
  43.  * @ingroup groupExamples
  44.  */
  45.  
  46. /**
  47.  * @defgroup SignalConvergence Signal Convergence Example
  48.  *
  49.  * \par Description:
  50.  * \par
  51.  * Demonstrates the ability of an adaptive filter to "learn" the transfer function of
  52.  * a FIR lowpass filter using the Normalized LMS Filter, Finite Impulse
  53.  * Response (FIR) Filter, and Basic Math Functions.
  54.  *
  55.  * \par Algorithm:
  56.  * \par
  57.  * The figure below illustrates the signal flow in this example. Uniformly distributed white
  58.  * noise is passed through an FIR lowpass filter. The output of the FIR filter serves as the
  59.  * reference input of the adaptive filter (normalized LMS filter). The white noise is input
  60.  * to the adaptive filter. The adaptive filter learns the transfer function of the FIR filter.
  61.  * The filter outputs two signals: (1) the output of the internal adaptive FIR filter, and
  62.  * (2) the error signal which is the difference between the adaptive filter and the reference
  63.  * output of the FIR filter. Over time as the adaptive filter learns the transfer function
  64.  * of the FIR filter, the first output approaches the reference output of the FIR filter,
  65.  * and the error signal approaches zero.
  66.  * \par
  67.  * The adaptive filter converges properly even if the input signal has a large dynamic
  68.  * range (i.e., varies from small to large values). The coefficients of the adaptive filter
  69.  * are initially zero, and then converge over 1536 samples. The internal function test_signal_converge()
  70.  * implements the stopping condition. The function checks if all of the values of the error signal have a
  71.  * magnitude below a threshold DELTA.
  72.  *
  73.  * \par Block Diagram:
  74.  * \par
  75.  * \image html SignalFlow.gif
  76.  *
  77.  *
  78.  * \par Variables Description:
  79.  * \par
  80.  * \li \c testInput_f32 points to the input data
  81.  * \li \c firStateF32 points to FIR state buffer
  82.  * \li \c lmsStateF32 points to Normalised Least mean square FIR filter state buffer
  83.  * \li \c FIRCoeff_f32 points to coefficient buffer
  84.  * \li \c lmsNormCoeff_f32 points to Normalised Least mean square FIR filter coefficient buffer
  85.  * \li \c wire1, wir2, wire3 temporary buffers
  86.  * \li \c errOutput, err_signal temporary error buffers
  87.  *
  88.  * \par CMSIS DSP Software Library Functions Used:
  89.  * \par
  90.  * - arm_lms_norm_init_f32()
  91.  * - arm_fir_init_f32()
  92.  * - arm_fir_f32()
  93.  * - arm_lms_norm_f32()
  94.  * - arm_scale_f32()
  95.  * - arm_abs_f32()
  96.  * - arm_sub_f32()
  97.  * - arm_min_f32()
  98.  * - arm_copy_f32()
  99.  *
  100.  * <b> Refer  </b>
  101.  * \link arm_signal_converge_example_f32.c \endlink
  102.  *
  103.  */
  104.  
  105.  
  106. /** \example arm_signal_converge_example_f32.c
  107.   */
  108.  
  109. #include "arm_math.h"
  110. #include "math_helper.h"
  111.  
  112. /* ----------------------------------------------------------------------
  113. ** Global defines for the simulation
  114. * ------------------------------------------------------------------- */
  115.  
  116. #define TEST_LENGTH_SAMPLES 1536
  117. #define NUMTAPS               32
  118. #define BLOCKSIZE             32
  119. #define DELTA_ERROR         0.000001f
  120. #define DELTA_COEFF         0.0001f
  121. #define MU                  0.5f
  122.  
  123. #define NUMFRAMES (TEST_LENGTH_SAMPLES / BLOCKSIZE)
  124.  
  125. /* ----------------------------------------------------------------------
  126. * Declare FIR state buffers and structure
  127. * ------------------------------------------------------------------- */
  128.  
  129. float32_t firStateF32[NUMTAPS + BLOCKSIZE];
  130. arm_fir_instance_f32 LPF_instance;
  131.  
  132. /* ----------------------------------------------------------------------
  133. * Declare LMSNorm state buffers and structure
  134. * ------------------------------------------------------------------- */
  135.  
  136. float32_t lmsStateF32[NUMTAPS + BLOCKSIZE];
  137. float32_t errOutput[TEST_LENGTH_SAMPLES];
  138. arm_lms_norm_instance_f32 lmsNorm_instance;
  139.  
  140.  
  141. /* ----------------------------------------------------------------------
  142. * Function Declarations for Signal Convergence Example
  143. * ------------------------------------------------------------------- */
  144.  
  145. arm_status test_signal_converge_example( void );
  146.  
  147.  
  148. /* ----------------------------------------------------------------------
  149. * Internal functions
  150. * ------------------------------------------------------------------- */
  151. arm_status test_signal_converge(float32_t* err_signal,
  152.                         uint32_t blockSize);
  153.  
  154. void getinput(float32_t* input,
  155.      uint32_t fr_cnt,
  156.           uint32_t blockSize);
  157.  
  158. /* ----------------------------------------------------------------------
  159. * External Declarations for FIR F32 module Test
  160. * ------------------------------------------------------------------- */
  161. extern float32_t testInput_f32[TEST_LENGTH_SAMPLES];
  162. extern float32_t lmsNormCoeff_f32[32];
  163. extern const float32_t FIRCoeff_f32[32];
  164. extern arm_lms_norm_instance_f32 lmsNorm_instance;
  165.  
  166. /* ----------------------------------------------------------------------
  167. * Declare I/O buffers
  168. * ------------------------------------------------------------------- */
  169.  
  170. float32_t wire1[BLOCKSIZE];
  171. float32_t wire2[BLOCKSIZE];
  172. float32_t wire3[BLOCKSIZE];
  173. float32_t err_signal[BLOCKSIZE];
  174.  
  175. /* ----------------------------------------------------------------------
  176. * Signal converge test
  177. * ------------------------------------------------------------------- */
  178.  
  179. int32_t main(void)
  180. {
  181.   uint32_t i;
  182.   arm_status status;
  183.   uint32_t index;
  184.   float32_t minValue;
  185.  
  186.   /* Initialize the LMSNorm data structure */
  187.   arm_lms_norm_init_f32(&lmsNorm_instance, NUMTAPS, lmsNormCoeff_f32, lmsStateF32, MU, BLOCKSIZE);
  188.  
  189.   /* Initialize the FIR data structure */
  190.   arm_fir_init_f32(&LPF_instance, NUMTAPS, (float32_t *)FIRCoeff_f32, firStateF32, BLOCKSIZE);
  191.  
  192.   /* ----------------------------------------------------------------------
  193.   * Loop over the frames of data and execute each of the processing
  194.   * functions in the system.
  195.   * ------------------------------------------------------------------- */
  196.  
  197.   for(i=0; i < NUMFRAMES; i++)
  198.   {
  199.     /* Read the input data - uniformly distributed random noise - into wire1 */
  200.     arm_copy_f32(testInput_f32 + (i * BLOCKSIZE), wire1, BLOCKSIZE);
  201.  
  202.     /* Execute the FIR processing function.  Input wire1 and output wire2 */
  203.     arm_fir_f32(&LPF_instance, wire1, wire2, BLOCKSIZE);
  204.  
  205.     /* Execute the LMS Norm processing function*/
  206.  
  207.     arm_lms_norm_f32(&lmsNorm_instance, /* LMSNorm instance */
  208.          wire1,                         /* Input signal */
  209.          wire2,                         /* Reference Signal */
  210.          wire3,                         /* Converged Signal */
  211.          err_signal,                    /* Error Signal, this will become small as the signal converges */
  212.          BLOCKSIZE);                    /* BlockSize */
  213.  
  214.     /* apply overall gain */
  215.     arm_scale_f32(wire3, 5, wire3, BLOCKSIZE);   /* in-place buffer */
  216.   }
  217.  
  218.   status = ARM_MATH_SUCCESS;
  219.  
  220.   /* -------------------------------------------------------------------------------
  221.   * Test whether the error signal has reached towards 0.
  222.   * ----------------------------------------------------------------------------- */
  223.  
  224.   arm_abs_f32(err_signal, err_signal, BLOCKSIZE);
  225.   arm_min_f32(err_signal, BLOCKSIZE, &minValue, &index);
  226.  
  227.   if (minValue > DELTA_ERROR)
  228.   {
  229.     status = ARM_MATH_TEST_FAILURE;
  230.   }
  231.  
  232.   /* ----------------------------------------------------------------------
  233.   * Test whether the filter coefficients have converged.
  234.   * ------------------------------------------------------------------- */
  235.  
  236.   arm_sub_f32((float32_t *)FIRCoeff_f32, lmsNormCoeff_f32, lmsNormCoeff_f32, NUMTAPS);
  237.  
  238.   arm_abs_f32(lmsNormCoeff_f32, lmsNormCoeff_f32, NUMTAPS);
  239.   arm_min_f32(lmsNormCoeff_f32, NUMTAPS, &minValue, &index);
  240.  
  241.   if (minValue > DELTA_COEFF)
  242.   {
  243.     status = ARM_MATH_TEST_FAILURE;
  244.   }
  245.  
  246.   /* ----------------------------------------------------------------------
  247.   * Loop here if the signals did not pass the convergence check.
  248.   * This denotes a test failure
  249.   * ------------------------------------------------------------------- */
  250.  
  251.   if ( status != ARM_MATH_SUCCESS)
  252.   {
  253.     while (1);
  254.   }
  255.  
  256.   while (1);                             /* main function does not return */
  257. }
  258.  
  259.  /** \endlink */
  260.