This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28379D:将 FFT 从 CPU1移动到 CLA (计算错误)

Guru**** 2253580 points
Other Parts Discussed in Thread: TMS320F28379D
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/989978/tms320f28379d-moving-fft-from-cpu1-to-cla-bad-computation

器件型号:TMS320F28379D

大家好、我在 CPU1中完成了 FFT 计算、其中有2048个样本与 DMA 配合使用、我从 ADC 中获取了样本并将其放入缓冲器中、我从中进行了计算。 现在我想将 FFT 移动到 CLA (以节省时间)、但它对我来说不能正常工作。 在 CLA 中、我使用1024个样本、我将填充的缓冲器从 DMA 复制到 IOBuffer、并在 CLA 中计算 FFT。 在计算完成后,我得到 ISR,在这里我计算幅度,然后再从中进行其他计算(rms、能量、相移等)。 我在这里看到了错误 对于50Hz (20ms)正弦信号、我使用 ePWM 作为 ADC 触发器来计算所需样本的确切数量(现在为1024)(ePWM TBCLK = 100MHz;CLKDIV = 0;TBPRD = 1953;CMPA = 977;)。

RFFTmag 还必须位于 LS RAM 中? 因为我没有足够的空间、所以我将其放置在 GSram 中。

我的链接器: e2e.ti.com/.../2837xD_5F00_FLASH_5F00_lnk_5F00_cpu1.rar


我的 CLA 代码:

/*----------------- *
//FFT CLA
/*----------------- *
RFFT_F32_struct rfft;// FFT 对象

#pragma DATA_SECTION (IOBuffer、"IOBuffer");  //输入数组的缓冲区对齐、
float32 IOBuffer[RFFT_SIZE];                  //RFFT_f32u (可选)、RFFT_F32 (必需)
                                            // FFT 的输出会覆盖输入 IF
                                           //RFFT_STOPENAINAINESDON_STOPEN
#pragma DATA_SECTION (IOBuffer2、"IOBuffer");
float32 IOBuffer2[RFFT_SIZE];                 //此处的 FFT 输出(如果 RFFT_STOPENAINAINSES偶 数)

#pragma DATA_SECTION (RFFTmagBuff、"RFFTmag");
float32 RFFTmagBuff[RFFT_SIZE/2+1];           //幅度计算中使用的附加缓冲器

#pragma DATA_SECTION (RFFTF32Coef、"RFFTTwides");
float32 RFFTF32Coef[512];                //Twiddle 缓冲器

空 init_cla (空)

   extern uint32_t Cla1funcsRunStart、Cla1funcsLoadStart、Cla1funcsLoadSize;
   extern uint32_t Cla1ConstRunStart、Cla1ConstLoadStart、Cla1ConstLoadSize;

   EALLOW;

#ifdef _flash
   //CLA 存储器初始化
   memcpy (((uint32_t *)&Cla1funcsRunStart、(uint32_t *)&Cla1funcsLoadStart、(uint32_t)&Cla1funcsLoadSize);
   memcpy (((uint32_t *)&Cla1ConstRunStart、(uint32_t *)&Cla1ConstLoadStart、(uint32_t)&Cla1ConstLoadSize);
#endif

   //初始化并等待 CLA1ToCPUMsgRAM
   MemCfgRegs.MSGxINIT.bit.init_CLA1TOCPU = 1;
   while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU!= 1){};

   //初始化并等待 CPUToCLA1MsgRAM
   MemCfgRegs.MSGxINIT.bit.init_CPUTOCLA1 = 1;
   while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1!= 1){};

   //LS RAM 控制 PRE CLA

   //程序空间
   MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 1;

   MemCfgRegs.LSxMSEL.bit.MSEL_LS3 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS3 = 1;

   //数据空间
   MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0;

   MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0;

   MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 0;

   MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1;
   MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 0;

   EDIS;

   //任务
   EALLOW;
   Cla1Regs.MVECT1 =(uint16_t)(&Cla1Task1);
// Cla1Regs.MVECT2 =(uint16_t)(&Cla1Task2);
// Cla1Regs.MVECT3 =(uint16_t)(&Cla1Task3);
// Cla1Regs.MVECT4 =(uint16_t)(&Cla1Task4);
// Cla1Regs.MVECT5 =(uint16_t)(&Cla1Task5);
// Cla1Regs.MVECT6 =(uint16_t)(&Cla1Task6);
// Cla1Regs.MVECT7 =(uint16_t)(&Cla1Task7);
   Cla1Regs.MVECT8 =(uint16_t)(&Cla1Task8);


   //触发集
   DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.task1 = CLA_TRIG_NOPERPH;
   DmaClaSrcSelRegs.CLA1TASSKSRCSEL2.bit.TASK8 = CLA_TRIG_NOPERPH;
   Cla1Regs.MIER =                          (M_INT1 | M_INT8);

   //SW 任务组启用
   Cla1Regs.MCTL.bit.IACKE = 1;

   //CLA ISR
   PieVectTable.CLA1_1_INT         =&cla1Isr1;
   PieCtrlRegs.PIEIER11.bit.INTx1  = 0x01;
   IER |=(M_INT11);
   EDIS;



void init_ClaFFT (void)

   memset (&IOBuffer、0、sizeof (IOBuffer));
   memset (&IOBuffer2、0、sizeof (IOBuffer2));
   memset (&RFFTmagBuff、0、sizeof (RFFTmagBuff));

   rfft.FFTize  = RFFT_SIZE;//(1 << RFFT_STACTS)
   rfft.FFTStages = RFFT_STACages;//(10U)
   rfft.InBuf    =&IOBuffer[0];    //输入缓冲区
   rfft.OutBuf   =&IOBuffer2[0];   //输出缓冲区
   rfft.CosSinBuf =&RFFTF32Coef[0]; //Twiddle 因子缓冲器
   rfft.MagBuf   =&RFFTmagBuff[0]; //Magnitude buffer

   RFFT_F32_SINCOSTable (&rfft);      //计算旋转因子

CLA:

_interrupt void Cla1Task1 (void)

  //_mdebugstop();
  CLA_CFFT_run512Pt ();
  CLA_CFFT_unpack512Pt ();

_interrupt void cla1Isr1 ()

   if (CLASignalType = 0)
   {
       ///Volt 结构
       FFT_COMPUTATION_CLA (&volt1、rfft.OutBuf);//Harmonic from rfft.OutBuf
   }
   其他
   {
       if (CLASignalType = 1)
       {
           //当前结构
           FFT_COMPUTATION_CLA (&curr1、rfft.OutBuf);
       }
   }

   ClaComputationDone = true;
   PieCtrlRegs.PIEACK.ALL = M_INT11;


用于比较 CLA 和旧 CPU 计算(效果良好)的图形 rfft.MagBuf、相同的正弦信号50Hz、CLA 1024个样本 FFT、CPU 2048个样本 FFT。



感谢您的建议、Marek。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Marek、

    如果 CLA 要访问 RFFTmag、则必须将其放置在 LSx 存储器中。 请参阅 TMS320F28379D 技术参考手册的第6.3.1节。

    https://www.ti.com/lit/ug/spruhm8i/spruhm8i.pdf

    此外、以下帖子还提供了更多信息、包括可能有所帮助的资源链接:

    https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/786227/faq-cla-frequently-asked-questions

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我试过它、但这更糟糕。 我在 CPU1中的 ISR 中计算 RFFTMag。 在 FFT_COMPUTATION_CLA ()中;使用命令 RFFT_F32_MAG_TMU0 (&rfft)的函数;

    我在 Lsrams 中没有空间、我尝试削减一半 Ls (例如、Ls 3)并将其分配给另一个 RAMS (例如、我的链接器中的 Ls4_5)、但这会影响整个 Ls 和 CLA 程序、 因为它们未对齐、我告诉寄存器 LS3用于程序存储器而不是数据(我不能告诉一半 LS3用于程序、一半用于数据)。

    专家能否检查我的链接器、是否一切正常?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    LSx 块不能拆分、它们必须作为数据或程序分配。 此外、将在 CLA 侧使用的所有全局变量都必须映射到指定为数据的 LSx 块或 CPU-CLA 消息 RAM。

    谢谢、
    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、但我不能将所有缓冲区移动到 Ls... 如何操作?

    我甚至没有全范围(1024)的双围因子。 我很不明白,我不知道该怎么做...  

    我的内存分配:





    例如、来自 Vishal Coelho (CLA_HandsOnWorkshop)的 TwiddlesFactors 被放置在 GSram 中。 对我来说毫无意义

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Marek、

    我查看了 CLA_code 配置的 CLAHandsOn 解决方案。 在该实现中、2个 IOBuffers 被放置在 LS RAM 中。 我认为这是 CLA 端使用的唯一共享 FFT 数据结构。  RFFTMag 和 RFFTTwidages"被放置在 GSRAM 中、因为在  main 中执行 RFFT 幅度时、只有代码的 C28端需要这些代码。 因此、分区是有道理的。 如果这是您的实现所执行的操作、则可以遵循相同的操作。

    有关您在以下两行中共享的代码片段的一个问题。 如何触发任务1和任务8? 您是否确认正在运行 CLA1任务?

    //触发集
       DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.task1 = CLA_TRIG_NOPERPH;
       DmaClaSrcSelRegs.CLA1TASSKSRCSEL2.bit.TASK8 = CLA_TRIG_NOPERPH;

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、感谢您的回答。 我使用 DMA 进行乒乓缓冲、因此在我向本地缓冲器(例如、InBuf_Volt1)填充1024个样本后、我将值复制到 IOBuffer 和 inc Task1。 任务1完成 FFT 后、我得到了 CLA ISR、其中程序计算幅度和相位。

    如下所示:

    DMA

    Fullscreen
    1
    2
    3
    4
    5
    while( (Cla1Regs.MIRUN.bit.INT1 == 1) && (ClaComputationDone == false) ){;}
    memcpy(IOBuffer, InBuf_Volt1, sizeof IOBuffer*sizeof(float32));
    ClaComputationDone = false;
    CLASignalType = 0;
    Cla1ForceTask1();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    CLA FFT:
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    __interrupt void Cla1Task1 ( void )
    {
    //__mdebugstop();
    CLA_CFFT_run512Pt();
    CLA_CFFT_unpack512Pt();
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    CLA ISR:
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    __interrupt void cla1Isr1 ()
    {
    if(CLASignalType == 0)
    {
    //Volt struct
    FFT_Computation_Cla(&volt1, rfft.MagBuf); //Calculating mag and phs
    }
    else
    {
    if(CLASignalType == 1)
    {
    //Curr struct
    FFT_Computation_Cla(&curr1, rfft.MagBuf); //Calculating mag and phs
    }
    }
    ClaComputationDone = true;
    PieCtrlRegs.PIEACK.all = M_INT11;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    另一个错误... 我的 accessViolationISR 检测 CLA 违规故障。 但是在 fetchAddressCLAISR 中、我有0值(那么地址0x0?)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    在 DMA 代码片段行1中:当 CLA 任务1正在运行时、while 条件为 true、并且标志为 false。 我想知道是否会有一个竞争条件、在 CLA 任务结束时、while 条件变为 false 并在 cla1Isr1被触发前继续运行。 也许有人建议尝试将条件更改为仅检查 ClaComputationDone 标志并删除 MIRUN.INT1检查?

    关于访问冲突-它是否表示 CLA 读取或写入或提取故障?

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、是的、我可以编辑此条件。 但这不应导致问题。 我使用正弦信号尝试了解决方案程序(CLAHandsOn 解决方案)、结果与主程序中的结果完全相同。 我在 MATLAB FFT 中有相同的信号(用于比较),在 CLA 中,一些采样/谐波是好的,一些是坏的(例如,在 MATLAB FFT[1]= 51444.12和 CLA FFT[1]= 0.0中)。  

    它可能是获取故障。

    我的朋友告诉我、TwiddlesFactors 必须位于 LSram 中(检查 RFFT_F32.asm 文件)。 但是、如果它在 GS 或 LS 中、结果不会改变。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请看、这是我的正弦 LSB 表:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    float32 sineLSB[]=
    {
    32768,32969,33170,33371,33572,33774,33975,34176,
    34377,34578,34779,34980,35180,35381,35582,35782,
    35982,36183,36383,36583,36782,36982,37182,37381,
    37580,37779,37978,38177,38375,38573,38771,38969,
    39166,39364,39561,39757,39954,40150,40346,40542,
    40737,40932,41127,41321,41515,41709,41903,42096,
    42288,42481,42673,42864,43056,43247,43437,43627,
    43817,44006,44195,44383,44571,44759,44946,45133,
    45319,45504,45690,45874,46058,46242,46425,46608,
    46790,46972,47153,47333,47513,47693,47872,48050,
    48228,48405,48582,48758,48933,49108,49282,49455,
    49628,49800,49972,50143,50313,50483,50652,50820,
    50988,51155,51321,51487,51651,51815,51979,52142,
    52303,52465,52625,52785,52944,53102,53259,53416,
    53572,53727,53881,54035,54188,54339,54491,54641,
    54790,54939,55087,55234,55380,55525,55669,55813,
    55955,56097,56238,56378,56517,56655,56793,56929,
    57065,57199,57333,57466,57597,57728,57858,57987,
    58115,58242,58368,58493,58618,58741,58863,58984,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    MATLAB FFT (前10个 HARM):
    FFT[0]= 33553921.000000;FFT[1]= 51446.738829;  
    FFT[2]=-133.278611; FFT[3]=-112.275631;  
    FFT[4]=-106.212885; FFT[5]=-103.780600;  
    FFT[6]=-102.510888; FFT[7]=-101.740960;  
    FFT[8]=-101.371433;FFT[9]=-100.479893;

    --------------------------------------------------
    CLA FFT (任务1完成后的 IOBuffer2):
    FFT[0]= 33553920.0;FFT[1]= 0.0;  
    FFT[2]= 51445.25; FFT[3]=-16768642.0;  
    FFT[4]=-133.279663; FFT[5]= 21883.7246;  
    FFT[6]=-111.808167; FFT[7]= 12307.0195;  
    FFT[8]=-106.212616;FFT[9]= 8736.04883;

    那么、请告诉我、为什么每二次谐波中都有很高的值? 当它们不在这里时、它将是良好的 FFT。
    我在 CPU1中有2048个 FFT (出于测试目的、MATLAB 与 CPU1是正确的)

    CLA 项目中使用的库:
    rts2800_fpu32.lib
    C28x_CLA_DSP_library_datarom.lib
    C28x_FPU_DSP_library.lib
    IQMath_fpu32.lib
    F2837xRevB_c1bootROM_CLADataROMSymbols_fpu32.lib

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    CLA FFT API 库是为技术讲座示例创建的、不属于我们官方软件支持的一部分。 因此、我对实现没有可见性、也不知道这是否是预期的。 我正在与其他团队成员联系、并将告诉您我发现的内容。

    同时、也许可以检查共享数据类型、看看它们在 C28和 CLA 上的大小是相同的。 您可以在以下链接中找到相关信息:

    https://software-dl.ti.com/C2000/docs/cla_software_dev_guide/faq.html#how-are-data-types-different-on-c28x-and-cla

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢您的观看、非常乐意为我提供帮助。 我将等待回复:)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    以下是我从团队那里得到的一个意见、您能否检查您是否确实如此:

    C28 FPU32 RFFT 输出:实数占用缓冲区的前半部分、虚数占用第二个部分(顺序相反):

     

    OutBuf[0]=实数[0]

    OutBuf[1]=实数[1]

    OutBuf[2]=实数[2]

    ………μ A

    OutBuf[N/2]=实数[N/2]

    OutBuf[N/2+1]= imag[N/2-1]

    ………μ A

    OutBuf[N-3]= imag[3]

    OutBuf[N-2]= imag[2]

    OutBuf[N-1]= imag[1]

     

    基于 CFFT+Unpackt 的 CLA RFFT:实数+虚数对:

     

    OutBuf[0]=实数[0]

    OutBuf[1]= imag[0]

    OutBuf[2]=实数[1]

    OutBuf[3]= imag[1]

    ………μ A

    OutBuf[N-2]=实数[N-1]

    OutBuf[N-1]= imag[N-1]

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、我现在已经把它弄清楚了。

    我是否还应该为阶段运行整个 IOBuffer2? 或者,我是否应该首先获取实部(到本地缓冲区)并开始运行相位函数? (笑声) 或者,我是否只能在计算后为实际零件选择角度?  

    你给我带来了问题,非常感谢,哦:)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    相关知识。 我向专家询问您的问题、并在听到反馈后通知您。

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    您将使用哪种 API 进行幅度计算? 如果它是 RFFT_F32_MAG_TMU0、与车间应用相同、则 IOBuffer2实值和虚值必须与 RFFT 在 C28上输出的布局相同。 因此、需要对 CLA CFFT 中的缓冲区进行后处理并以相同的方式进行订购、这是很好的。

    谢谢、

    Ashwini

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、是的、我使用此 API。 因此,实数部分将位于前512个数组位置或否?

    编辑:好的、我明白了。 Thx

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marek:

    太棒了、我将继续并结束这条线程。

    谢谢、
    Ashwini