硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1810|回复: 2
收起左侧

[DSP] STM32H7的硬件双精度浮点终于有用武之地了,新版DSP库已经支持了64位浮点FFT函数arm_cfft_f64

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2021-5-21 15:37:48 | 显示全部楼层 |阅读模式

这个确实不错,准备测试下。

  1. /* ----------------------------------------------------------------------
  2. * Project:      CMSIS DSP Library
  3. * Title:        arm_cfft_f64.c
  4. * Description:  Combined Radix Decimation in Frequency CFFT Double Precision Floating point processing function
  5. *
  6. * $Date:        29. November 2019
  7. * $Revision:    V1.0.0
  8. *
  9. * Target Processor: Cortex-M cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the License); you may
  17. * not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */

  28. #include "arm_math.h"
  29. #include "arm_common_tables.h"


  30. extern void arm_radix4_butterfly_f64(
  31.         float64_t * pSrc,
  32.         uint16_t fftLen,
  33.   const float64_t * pCoef,
  34.         uint16_t twidCoefModifier);

  35. extern void arm_bitreversal_64(
  36.         uint64_t * pSrc,
  37.   const uint16_t   bitRevLen,
  38.   const uint16_t * pBitRevTable);

  39. /**
  40. * @} end of ComplexFFT group
  41. */

  42. /* ----------------------------------------------------------------------
  43. * Internal helper function used by the FFTs
  44. * ---------------------------------------------------------------------- */

  45. /*
  46. * @brief  Core function for the Double Precision floating-point CFFT butterfly process.
  47. * @param[in, out] *pSrc            points to the in-place buffer of F64 data type.
  48. * @param[in]      fftLen           length of the FFT.
  49. * @param[in]      *pCoef           points to the twiddle coefficient buffer.
  50. * @param[in]      twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
  51. * @return none.
  52. */

  53. void arm_radix4_butterfly_f64(
  54.         float64_t * pSrc,
  55.         uint16_t fftLen,
  56.   const float64_t * pCoef,
  57.         uint16_t twidCoefModifier)
  58. {

  59.    float64_t co1, co2, co3, si1, si2, si3;
  60.    uint32_t ia1, ia2, ia3;
  61.    uint32_t i0, i1, i2, i3;
  62.    uint32_t n1, n2, j, k;

  63.    float64_t t1, t2, r1, r2, s1, s2;


  64.    /*  Initializations for the fft calculation */
  65.    n2 = fftLen;
  66.    n1 = n2;
  67.    for (k = fftLen; k > 1U; k >>= 2U)
  68.    {
  69.       /*  Initializations for the fft calculation */
  70.       n1 = n2;
  71.       n2 >>= 2U;
  72.       ia1 = 0U;

  73.       /*  FFT Calculation */
  74.       j = 0;
  75.       do
  76.       {
  77.          /*  index calculation for the coefficients */
  78.          ia2 = ia1 + ia1;
  79.          ia3 = ia2 + ia1;
  80.          co1 = pCoef[ia1 * 2U];
  81.          si1 = pCoef[(ia1 * 2U) + 1U];
  82.          co2 = pCoef[ia2 * 2U];
  83.          si2 = pCoef[(ia2 * 2U) + 1U];
  84.          co3 = pCoef[ia3 * 2U];
  85.          si3 = pCoef[(ia3 * 2U) + 1U];

  86.          /*  Twiddle coefficients index modifier */
  87.          ia1 = ia1 + twidCoefModifier;

  88.          i0 = j;
  89.          do
  90.          {
  91.             /*  index calculation for the input as, */
  92.             /*  pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
  93.             i1 = i0 + n2;
  94.             i2 = i1 + n2;
  95.             i3 = i2 + n2;

  96.             /* xa + xc */
  97.             r1 = pSrc[(2U * i0)] + pSrc[(2U * i2)];

  98.             /* xa - xc */
  99.             r2 = pSrc[(2U * i0)] - pSrc[(2U * i2)];

  100.             /* ya + yc */
  101.             s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U];

  102.             /* ya - yc */
  103.             s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U];

  104.             /* xb + xd */
  105.             t1 = pSrc[2U * i1] + pSrc[2U * i3];

  106.             /* xa' = xa + xb + xc + xd */
  107.             pSrc[2U * i0] = r1 + t1;

  108.             /* xa + xc -(xb + xd) */
  109.             r1 = r1 - t1;

  110.             /* yb + yd */
  111.             t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U];

  112.             /* ya' = ya + yb + yc + yd */
  113.             pSrc[(2U * i0) + 1U] = s1 + t2;

  114.             /* (ya + yc) - (yb + yd) */
  115.             s1 = s1 - t2;

  116.             /* (yb - yd) */
  117.             t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U];

  118.             /* (xb - xd) */
  119.             t2 = pSrc[2U * i1] - pSrc[2U * i3];

  120.             /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
  121.             pSrc[2U * i1] = (r1 * co2) + (s1 * si2);

  122.             /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
  123.             pSrc[(2U * i1) + 1U] = (s1 * co2) - (r1 * si2);

  124.             /* (xa - xc) + (yb - yd) */
  125.             r1 = r2 + t1;

  126.             /* (xa - xc) - (yb - yd) */
  127.             r2 = r2 - t1;

  128.             /* (ya - yc) -  (xb - xd) */
  129.             s1 = s2 - t2;

  130.             /* (ya - yc) +  (xb - xd) */
  131.             s2 = s2 + t2;

  132.             /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
  133.             pSrc[2U * i2] = (r1 * co1) + (s1 * si1);

  134.             /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
  135.             pSrc[(2U * i2) + 1U] = (s1 * co1) - (r1 * si1);

  136.             /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
  137.             pSrc[2U * i3] = (r2 * co3) + (s2 * si3);

  138.             /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
  139.             pSrc[(2U * i3) + 1U] = (s2 * co3) - (r2 * si3);

  140.             i0 += n1;
  141.          } while ( i0 < fftLen);
  142.          j++;
  143.       } while (j <= (n2 - 1U));
  144.       twidCoefModifier <<= 2U;
  145.    }
  146. }

  147. /*
  148. * @brief  Core function for the Double Precision floating-point CFFT butterfly process.
  149. * @param[in, out] *pSrc            points to the in-place buffer of F64 data type.
  150. * @param[in]      fftLen           length of the FFT.
  151. * @param[in]      *pCoef           points to the twiddle coefficient buffer.
  152. * @param[in]      twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
  153. * @return none.
  154. */

  155. void arm_cfft_radix4by2_f64(
  156.     float64_t * pSrc,
  157.     uint32_t fftLen,
  158.     const float64_t * pCoef)
  159. {
  160.     uint32_t i, l;
  161.     uint32_t n2, ia;
  162.     float64_t xt, yt, cosVal, sinVal;
  163.     float64_t p0, p1,p2,p3,a0,a1;

  164.     n2 = fftLen >> 1;
  165.     ia = 0;
  166.     for (i = 0; i < n2; i++)
  167.     {
  168.         cosVal = pCoef[2*ia];
  169.         sinVal = pCoef[2*ia + 1];
  170.         ia++;

  171.         l = i + n2;

  172.         /*  Butterfly implementation */
  173.         a0 = pSrc[2 * i] + pSrc[2 * l];
  174.         xt = pSrc[2 * i] - pSrc[2 * l];

  175.         yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  176.         a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];

  177.         p0 = xt * cosVal;
  178.         p1 = yt * sinVal;
  179.         p2 = yt * cosVal;
  180.         p3 = xt * sinVal;

  181.         pSrc[2 * i]     = a0;
  182.         pSrc[2 * i + 1] = a1;

  183.         pSrc[2 * l]     = p0 + p1;
  184.         pSrc[2 * l + 1] = p2 - p3;

  185.     }

  186.     // first col
  187.     arm_radix4_butterfly_f64( pSrc, n2, (float64_t*)pCoef, 2U);
  188.     // second col
  189.     arm_radix4_butterfly_f64( pSrc + fftLen, n2, (float64_t*)pCoef, 2U);

  190. }

  191. /**
  192.   @addtogroup ComplexFFT
  193.   @{
  194. */

  195. /**
  196.   @brief         Processing function for the Double Precision floating-point complex FFT.
  197.   @param[in]     S              points to an instance of the Double Precision floating-point CFFT structure
  198.   @param[in,out] p1             points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place
  199.   @param[in]     ifftFlag       flag that selects transform direction
  200.                    - value = 0: forward transform
  201.                    - value = 1: inverse transform
  202.   @param[in]     bitReverseFlag flag that enables / disables bit reversal of output
  203.                    - value = 0: disables bit reversal of output
  204.                    - value = 1: enables bit reversal of output
  205.   @return        none
  206. */

  207. void arm_cfft_f64(
  208.   const arm_cfft_instance_f64 * S,
  209.         float64_t * p1,
  210.         uint8_t ifftFlag,
  211.         uint8_t bitReverseFlag)
  212. {
  213.     uint32_t  L = S->fftLen, l;
  214.     float64_t invL, * pSrc;

  215.     if (ifftFlag == 1U)
  216.     {
  217.         /*  Conjugate input data  */
  218.         pSrc = p1 + 1;
  219.         for(l=0; l<L; l++)
  220.         {
  221.             *pSrc = -*pSrc;
  222.             pSrc += 2;
  223.         }
  224.     }

  225.     switch (L)
  226.     {
  227.         case 16:
  228.         case 64:
  229.         case 256:
  230.         case 1024:
  231.         case 4096:
  232.         arm_radix4_butterfly_f64  (p1, L, (float64_t*)S->pTwiddle, 1U);
  233.         break;

  234.         case 32:
  235.         case 128:
  236.         case 512:
  237.         case 2048:
  238.         arm_cfft_radix4by2_f64  ( p1, L, (float64_t*)S->pTwiddle);
  239.         break;

  240.     }

  241.     if ( bitReverseFlag )
  242.         arm_bitreversal_64((uint64_t*)p1, S->bitRevLength,S->pBitRevTable);

  243.     if (ifftFlag == 1U)
  244.     {
  245.         invL = 1.0 / (float64_t)L;
  246.         /*  Conjugate and scale output data */
  247.         pSrc = p1;
  248.         for(l=0; l<L; l++)
  249.         {
  250.             *pSrc++ *=   invL ;
  251.             *pSrc  = -(*pSrc) * invL;
  252.             pSrc++;
  253.         }
  254.     }
  255. }

  256. /**
  257.   @} end of ComplexFFT group
  258. */
复制代码


回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2021-6-5 16:30:22 | 显示全部楼层
老本测好没,怎么下载这个库啊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2021-6-6 08:35:24 | 显示全部楼层
LILINKING 发表于 2021-6-5 16:30
老本测好没,怎么下载这个库啊

已经配套好例子,可下载:

事隔五年之后,开启第2版DSP数字信号处理和CMSIS-NN神经网络教程,同步开启三代示波器,更至31章(2021-05-30)
http://www.armbbs.cn/forum.php?m ... 4547&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-19 08:18 , Processed in 0.152770 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表