Subversion Repositories FuelGauge

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* ----------------------------------------------------------------------
2
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
3
*
4
* $Date:        17. January 2013
5
* $Revision:    V1.4.0  b
6
*
7
* Project:          CMSIS DSP Library
8
*
9
* Title:            math_helper.c
10
*
11
* Description:  Definition of all helper functions required.
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
*               Include standard header files
44
* -------------------------------------------------------------------- */
45
#include<math.h>
46
 
47
/* ----------------------------------------------------------------------
48
*               Include project header files
49
* -------------------------------------------------------------------- */
50
#include "math_helper.h"
51
 
52
/**
53
 * @brief  Caluclation of SNR
54
 * @param[in]  pRef     Pointer to the reference buffer
55
 * @param[in]  pTest    Pointer to the test buffer
56
 * @param[in]  buffSize total number of samples
57
 * @return     SNR
58
 * The function Caluclates signal to noise ratio for the reference output
59
 * and test output
60
 */
61
 
62
float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
63
{
64
  float EnergySignal = 0.0, EnergyError = 0.0;
65
  uint32_t i;
66
  float SNR;
67
  int temp;
68
  int *test;
69
 
70
  for (i = 0; i < buffSize; i++)
71
    {
72
          /* Checking for a NAN value in pRef array */
73
          test =   (int *)(&pRef[i]);
74
      temp =  *test;
75
 
76
          if (temp == 0x7FC00000)
77
          {
78
                        return(0);
79
          }
80
 
81
          /* Checking for a NAN value in pTest array */
82
          test =   (int *)(&pTest[i]);
83
      temp =  *test;
84
 
85
          if (temp == 0x7FC00000)
86
          {
87
                        return(0);
88
          }
89
      EnergySignal += pRef[i] * pRef[i];
90
      EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
91
    }
92
 
93
        /* Checking for a NAN value in EnergyError */
94
        test =   (int *)(&EnergyError);
95
    temp =  *test;
96
 
97
    if (temp == 0x7FC00000)
98
    {
99
                return(0);
100
    }
101
 
102
 
103
  SNR = 10 * log10 (EnergySignal / EnergyError);
104
 
105
  return (SNR);
106
 
107
}
108
 
109
 
110
/**
111
 * @brief  Provide guard bits for Input buffer
112
 * @param[in,out]  input_buf   Pointer to input buffer
113
 * @param[in]       blockSize  block Size
114
 * @param[in]       guard_bits guard bits
115
 * @return none
116
 * The function Provides the guard bits for the buffer
117
 * to avoid overflow
118
 */
119
 
120
void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
121
                            uint32_t guard_bits)
122
{
123
  uint32_t i;
124
 
125
  for (i = 0; i < blockSize; i++)
126
    {
127
      input_buf[i] = input_buf[i] >> guard_bits;
128
    }
129
}
130
 
131
/**
132
 * @brief  Converts float to fixed in q12.20 format
133
 * @param[in]  pIn         pointer to input buffer
134
 * @param[out] pOut        pointer to outputbuffer
135
 * @param[in]  numSamples  number of samples in the input buffer
136
 * @return none
137
 * The function converts floating point values to fixed point(q12.20) values
138
 */
139
 
140
void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
141
{
142
  uint32_t i;
143
 
144
  for (i = 0; i < numSamples; i++)
145
    {
146
          /* 1048576.0f corresponds to pow(2, 20) */
147
      pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
148
 
149
      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
150
 
151
      if (pIn[i] == (float) 1.0)
152
        {
153
          pOut[i] = 0x000FFFFF;
154
        }
155
    }
156
}
157
 
158
/**
159
 * @brief  Compare MATLAB Reference Output and ARM Test output
160
 * @param[in]  pIn         Pointer to Ref buffer
161
 * @param[in]  pOut        Pointer to Test buffer
162
 * @param[in]  numSamples  number of samples in the buffer
163
 * @return maximum difference
164
 */
165
 
166
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t *pOut, uint32_t numSamples)
167
{
168
  uint32_t i;
169
  int32_t diff, diffCrnt = 0;
170
  uint32_t maxDiff = 0;
171
 
172
  for (i = 0; i < numSamples; i++)
173
  {
174
        diff = pIn[i] - pOut[i];
175
        diffCrnt = (diff > 0) ? diff : -diff;
176
 
177
        if (diffCrnt > maxDiff)
178
        {
179
                maxDiff = diffCrnt;
180
        }
181
  }
182
 
183
  return(maxDiff);
184
}
185
 
186
/**
187
 * @brief  Compare MATLAB Reference Output and ARM Test output
188
 * @param[in]  pIn         Pointer to Ref buffer
189
 * @param[in]  pOut        Pointer to Test buffer
190
 * @param[in]  numSamples number of samples in the buffer
191
 * @return maximum difference
192
 */
193
 
194
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
195
{
196
  uint32_t i;
197
  int32_t diff, diffCrnt = 0;
198
  uint32_t maxDiff = 0;
199
 
200
  for (i = 0; i < numSamples; i++)
201
  {
202
        diff = pIn[i] - pOut[i];
203
        diffCrnt = (diff > 0) ? diff : -diff;
204
 
205
        if (diffCrnt > maxDiff)
206
        {
207
                maxDiff = diffCrnt;
208
        }
209
  }
210
 
211
  return(maxDiff);
212
}
213
 
214
/**
215
 * @brief  Provide guard bits for Input buffer
216
 * @param[in,out]  input_buf   Pointer to input buffer
217
 * @param[in]       blockSize  block Size
218
 * @param[in]       guard_bits guard bits
219
 * @return none
220
 * The function Provides the guard bits for the buffer
221
 * to avoid overflow
222
 */
223
 
224
void arm_provide_guard_bits_q31 (q31_t * input_buf,
225
                                                                 uint32_t blockSize,
226
                                 uint32_t guard_bits)
227
{
228
  uint32_t i;
229
 
230
  for (i = 0; i < blockSize; i++)
231
    {
232
      input_buf[i] = input_buf[i] >> guard_bits;
233
    }
234
}
235
 
236
/**
237
 * @brief  Provide guard bits for Input buffer
238
 * @param[in,out]  input_buf   Pointer to input buffer
239
 * @param[in]       blockSize  block Size
240
 * @param[in]       guard_bits guard bits
241
 * @return none
242
 * The function Provides the guard bits for the buffer
243
 * to avoid overflow
244
 */
245
 
246
void arm_provide_guard_bits_q7 (q7_t * input_buf,
247
                                                                uint32_t blockSize,
248
                                uint32_t guard_bits)
249
{
250
  uint32_t i;
251
 
252
  for (i = 0; i < blockSize; i++)
253
    {
254
      input_buf[i] = input_buf[i] >> guard_bits;
255
    }
256
}
257
 
258
 
259
 
260
/**
261
 * @brief  Caluclates number of guard bits
262
 * @param[in]  num_adds         number of additions
263
 * @return guard bits
264
 * The function Caluclates the number of guard bits
265
 * depending on the numtaps
266
 */
267
 
268
uint32_t arm_calc_guard_bits (uint32_t num_adds)
269
{
270
  uint32_t i = 1, j = 0;
271
 
272
  if (num_adds == 1)
273
    {
274
      return (0);
275
    }
276
 
277
  while (i < num_adds)
278
    {
279
      i = i * 2;
280
      j++;
281
    }
282
 
283
  return (j);
284
}
285
 
286
/**
287
 * @brief  Apply guard bits to buffer
288
 * @param[in,out]  pIn         pointer to input buffer
289
 * @param[in]      numSamples  number of samples in the input buffer
290
 * @param[in]      guard_bits  guard bits
291
 * @return none
292
 */
293
 
294
void arm_apply_guard_bits (float32_t *pIn,
295
                                                   uint32_t numSamples,
296
                                                   uint32_t guard_bits)
297
{
298
  uint32_t i;
299
 
300
  for (i = 0; i < numSamples; i++)
301
    {
302
      pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
303
    }
304
}
305
 
306
/**
307
 * @brief  Calculates pow(2, numShifts)
308
 * @param[in]  numShifts        number of shifts
309
 * @return pow(2, numShifts)
310
 */
311
uint32_t arm_calc_2pow(uint32_t numShifts)
312
{
313
 
314
  uint32_t i, val = 1;
315
 
316
  for (i = 0; i < numShifts; i++)
317
    {
318
      val = val * 2;
319
    }
320
 
321
  return(val);
322
}
323
 
324
 
325
 
326
/**
327
 * @brief  Converts float to fixed q14
328
 * @param[in]  pIn         pointer to input buffer
329
 * @param[out] pOut        pointer to output buffer
330
 * @param[in]  numSamples  number of samples in the buffer
331
 * @return none
332
 * The function converts floating point values to fixed point values
333
 */
334
 
335
void arm_float_to_q14 (float *pIn, q15_t *pOut, uint32_t numSamples)
336
{
337
  uint32_t i;
338
 
339
  for (i = 0; i < numSamples; i++)
340
    {
341
          /* 16384.0f corresponds to pow(2, 14) */
342
      pOut[i] = (q15_t) (pIn[i] * 16384.0f);
343
 
344
      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
345
 
346
      if (pIn[i] == (float) 2.0)
347
        {
348
          pOut[i] = 0x7FFF;
349
        }
350
 
351
    }
352
 
353
}
354
 
355
 
356
/**
357
 * @brief  Converts float to fixed q30 format
358
 * @param[in]  pIn         pointer to input buffer
359
 * @param[out] pOut        pointer to output buffer
360
 * @param[in]  numSamples  number of samples in the buffer
361
 * @return none
362
 * The function converts floating point values to fixed point values
363
 */
364
 
365
void arm_float_to_q30 (float *pIn, q31_t * pOut, uint32_t numSamples)
366
{
367
  uint32_t i;
368
 
369
  for (i = 0; i < numSamples; i++)
370
    {
371
          /* 1073741824.0f corresponds to pow(2, 30) */
372
      pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
373
 
374
      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
375
 
376
      if (pIn[i] == (float) 2.0)
377
        {
378
          pOut[i] = 0x7FFFFFFF;
379
        }
380
    }
381
}
382
 
383
/**
384
 * @brief  Converts float to fixed q30 format
385
 * @param[in]  pIn         pointer to input buffer
386
 * @param[out] pOut        pointer to output buffer
387
 * @param[in]  numSamples  number of samples in the buffer
388
 * @return none
389
 * The function converts floating point values to fixed point values
390
 */
391
 
392
void arm_float_to_q29 (float *pIn, q31_t *pOut, uint32_t numSamples)
393
{
394
  uint32_t i;
395
 
396
  for (i = 0; i < numSamples; i++)
397
    {
398
          /* 1073741824.0f corresponds to pow(2, 30) */
399
      pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
400
 
401
      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
402
 
403
      if (pIn[i] == (float) 4.0)
404
        {
405
          pOut[i] = 0x7FFFFFFF;
406
        }
407
    }
408
}
409
 
410
 
411
/**
412
 * @brief  Converts float to fixed q28 format
413
 * @param[in]  pIn         pointer to input buffer
414
 * @param[out] pOut        pointer to output buffer
415
 * @param[in]  numSamples  number of samples in the buffer
416
 * @return none
417
 * The function converts floating point values to fixed point values
418
 */
419
 
420
void arm_float_to_q28 (float *pIn, q31_t *pOut, uint32_t numSamples)
421
{
422
  uint32_t i;
423
 
424
  for (i = 0; i < numSamples; i++)
425
    {
426
        /* 268435456.0f corresponds to pow(2, 28) */
427
      pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
428
 
429
      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
430
 
431
      if (pIn[i] == (float) 8.0)
432
        {
433
          pOut[i] = 0x7FFFFFFF;
434
        }
435
    }
436
}
437
 
438
/**
439
 * @brief  Clip the float values to +/- 1
440
 * @param[in,out]  pIn           input buffer
441
 * @param[in]      numSamples    number of samples in the buffer
442
 * @return none
443
 * The function converts floating point values to fixed point values
444
 */
445
 
446
void arm_clip_f32 (float *pIn, uint32_t numSamples)
447
{
448
  uint32_t i;
449
 
450
  for (i = 0; i < numSamples; i++)
451
    {
452
      if (pIn[i] > 1.0f)
453
          {
454
            pIn[i] = 1.0;
455
          }
456
          else if ( pIn[i] < -1.0f)
457
          {
458
            pIn[i] = -1.0;
459
          }
460
 
461
    }
462
}
463
 
464
 
465
 
466