Hello all, I had a FFT calculation done in cpu1 with 2048 samples in cooperation with DMA, I obtained samples from the ADC into a buffer, from which I did calculations. Now I wanted to move the FFT to the CLA (to save time), but it doesn't work properly for me. In CLA I work with 1024 samples, I copy filled buffers from DMA to IOBuffer and calculate FFT in CLA. After the calculation I get the ISR, where I calculate the magnitudes, from which I then make other calculations (rms, energy, phase shifts, etc ...). And here I see mistakes.... I use ePWM for ADC trigger to calculate the exact number of required samples (now 1024) (ePWM TBCLK = 100MHz; CLKDIV = 0; TBPRD = 1953; CMPA = 977;) for 50Hz(20ms) sine signal.
RFFTmag must also be in the LS ram? Because I don't have enough space so I placed it in GSram.
My Linker: 2837xD_FLASH_lnk_cpu1.rar
My CLA code:
/*--------------------------------------------*/
//FFT CLA
/*--------------------------------------------*/
RFFT_F32_STRUCT rfft; // The FFT object
#pragma DATA_SECTION(IOBuffer,"IOBuffer"); //Buffer alignment for the input array,
float32 IOBuffer[RFFT_SIZE]; //RFFT_f32u(optional), RFFT_f32(required)
//Output of FFT overwrites input if
//RFFT_STAGES is ODD
#pragma DATA_SECTION(IOBuffer2,"IOBuffer");
float32 IOBuffer2[RFFT_SIZE]; //Output of FFT here if RFFT_STAGES is EVEN
#pragma DATA_SECTION(RFFTmagBuff,"RFFTmag");
float32 RFFTmagBuff[RFFT_SIZE/2+1]; //Additional Buffer used in Magnitude calc
#pragma DATA_SECTION(RFFTF32Coef,"RFFTtwiddles");
float32 RFFTF32Coef[512]; //Twiddle buffer
void init_Cla(void)
{
extern uint32_t Cla1funcsRunStart, Cla1funcsLoadStart, Cla1funcsLoadSize;
extern uint32_t Cla1ConstRunStart, Cla1ConstLoadStart, Cla1ConstLoadSize;
EALLOW;
#ifdef _FLASH
//CLA MEMORY INIT
memcpy((uint32_t *)&Cla1funcsRunStart, (uint32_t *)&Cla1funcsLoadStart, (uint32_t)&Cla1funcsLoadSize );
memcpy((uint32_t *)&Cla1ConstRunStart, (uint32_t *)&Cla1ConstLoadStart, (uint32_t)&Cla1ConstLoadSize );
#endif
// Initialize and wait for CLA1ToCPUMsgRAM
MemCfgRegs.MSGxINIT.bit.INIT_CLA1TOCPU = 1;
while(MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU != 1){};
// Initialize and wait for CPUToCLA1MsgRAM
MemCfgRegs.MSGxINIT.bit.INIT_CPUTOCLA1 = 1;
while(MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1 != 1){};
//LS RAM CONTROL pre CLA
//PROGRAM SPACE
MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 1;
MemCfgRegs.LSxMSEL.bit.MSEL_LS3 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS3 = 1;
//DATA SPACE
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;
//TASKS
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);
//Trigger set
DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK1 = CLA_TRIG_NOPERPH;
DmaClaSrcSelRegs.CLA1TASKSRCSEL2.bit.TASK8 = CLA_TRIG_NOPERPH;
Cla1Regs.MIER.all = (M_INT1 | M_INT8);
//Sw task force enable
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.FFTSize = RFFT_SIZE; //(1 << RFFT_STAGES)
rfft.FFTStages = RFFT_STAGES; //(10U)
rfft.InBuf = &IOBuffer[0]; //Input buffer
rfft.OutBuf = &IOBuffer2[0]; //Output buffer
rfft.CosSinBuf = &RFFTF32Coef[0]; //Twiddle factor buffer
rfft.MagBuf = &RFFTmagBuff[0]; //Magnitude buffer
RFFT_f32_sincostable(&rfft); //Calculate twiddle factor
}
CLA:
__interrupt void Cla1Task1 ( void )
{
//__mdebugstop();
CLA_CFFT_run512Pt();
CLA_CFFT_unpack512Pt();
}
__interrupt void cla1Isr1 ()
{
if(CLASignalType == 0)
{
//Volt struct
FFT_Computation_Cla(&volt1, rfft.OutBuf); //Harmonic from rfft.OutBuf
}
else
{
if(CLASignalType == 1)
{
//Curr struct
FFT_Computation_Cla(&curr1, rfft.OutBuf);
}
}
ClaComputationDone = true;
PieCtrlRegs.PIEACK.all = M_INT11;
}
For comparing CLA and old CPU calculations (which were good) graph rfft.MagBuf, same sine signal 50Hz, CLA 1024 samples fft, CPU 2048 samples fft.
Thanks for advices, Marek.