Other Parts Discussed in Thread: C2000WARE
I have modified RFFT example code for calculating 64 point RFFT in TMS320F280025C. The complete main code file that implements RFFT is shown below:
//############################################################################# // // FILE: main.c // // // //############################################################################# // $TI Release: F28002x Support Library v3.04.00.00 $ // $Release Date: Fri Feb 12 18:58:34 IST 2021 $ // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // // Select the global Q value to use: #define GLOBAL_Q 17 #define FFT_SIZE 64 //long GlobalQ = GLOBAL_Q; // Used for legacy GEL & Graph Debug. #include "driverlib.h" #include "device.h" #include "board.h" #include "IQmathLib.h" #include <stdio.h> #include <file.h> #include "sci_io_driverlib.h" #include "fft.h" #include "fft_hamming_Q31.h" #include "math.h" // // Globals // uint16_t sData[32]; // Send data buffer for DMA transmission uint16_t rData[32]; // Receive data buffer for DMA reception //Defining FFT sections #pragma DATA_SECTION(ipcb, "FFTipcb"); int32_t ipcb[FFT_SIZE+2]; //Calculations buffer #pragma DATA_SECTION(ipcbsrc, "FFTipcbsrc"); int32_t ipcbsrc[FFT_SIZE]; //Sampled input signal //Defining real fft object for 64 point calculations RFFT32 rfft = RFFT32_64P_DEFAULTS; // Place buffers in GSRAM so that DMA can access these #pragma DATA_SECTION(sData, "ramgs0"); #pragma DATA_SECTION(rData, "ramgs0"); // // Function Prototypes void init_SPI_FIFO(void); // // Function Prototypes for Interrupt // extern __interrupt void controlISR(void); extern __interrupt void jemADCISR(void); extern __interrupt void cpuTimer0ISR(void); extern __interrupt void dmaCh5ISR(void); extern __interrupt void dmaCh6ISR(void); void initCPUTimers(void); void configCPUTimer(uint32_t, float, float); const long win[FFT_SIZE/2]=HAMMING64; void main(void) { volatile int status = 0; volatile FILE *fid; int i = 0; // float RadStep = 0.1963495408494f; float Rad = 0.0f; float temp1; int temp2; // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull-ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_TIMER0, &cpuTimer0ISR); Interrupt_register(INT_ADCA1, &controlISR); Interrupt_register(INT_ADCA2, &jemADCISR); // // Configuring interrupts for DMA transmit and receive channels Interrupt_register(INT_DMA_CH5, &dmaCh5ISR); Interrupt_register(INT_DMA_CH6, &dmaCh6ISR); // // Configure all peripherals and analog/digital GPIOs // Board_init(); //Initialize ADCs. Not generated by the sysconfig tool. ADC_init(); // //EPWM initialization code.Needs to be configured separately as current // tool version does not support this module // EPWM_init(); // Set up DMA for SPI use, initialize the SPI for FIFO mode initDMA(); //initSPI(); // Enable interrupts required for DMA send and receive // Interrupt_enable(INT_DMA_CH5); Interrupt_enable(INT_DMA_CH6); //Initialize Timer initCPUTimers(); // Configure CPU-Timer 0 to interrupt every 100000 u seconds: // configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 100000); CPUTimer_enableInterrupt(CPUTIMER0_BASE); Interrupt_enable(INT_TIMER0); Interrupt_enable(INT_ADCA1); Interrupt_enable(INT_ADCA2); // // Enable Global Interrupt (INTM) and real time interrupt (DBGM) // EINT; ERTM; // Redirect STDOUT to SCI status = add_device("scia", _SSA, SCI_open, SCI_close, SCI_read, SCI_write, SCI_lseek, SCI_unlink, SCI_rename); fid = fopen("scia", "w"); freopen("scia:", "w", stdout); setvbuf(stdout, NULL, _IONBF, 0); //Prints welcome message on debug SCI printf("Skyelectric"); DEVICE_DELAY_US(10000); init_SPI_FIFO(); // Start the DMA channels // DMA_startChannel(DMA_CH6_BASE); DMA_startChannel(DMA_CH5_BASE); //------------------------------------ CPUTimer_startTimer(CPUTIMER0_BASE); //Temporary code for implementing FFT for (i=0;i<FFT_SIZE;i++) { ipcbsrc[i]=(long)(2147483648*sinf(Rad));//Q31 format Rad=Rad+0.09817; } printf("\r\nSample Input:\r\n"); for (i = 0; i < FFT_SIZE; i++) printf("%ld\r\n", ipcbsrc[i]); } RFFT32_brev(ipcbsrc, ipcb, FFT_SIZE); // real FFT bit reversing rfft.ipcbptr = ipcb; // FFT computation buffer rfft.magptr = ipcbsrc; // Magnitude output buffer rfft.winptr = (long *)win; // Window coefficient array rfft.init(&rfft); // Twiddle factor pointer initialization rfft.calc(&rfft); // Compute the FFT rfft.split(&rfft); // Post processing to get the correct spectrum rfft.mag(&rfft); // Q31 format (abs(ipcbsrc)/2^16).^2 printf("\r\nFFT Result:\r\n"); for (i = 0; i < FFT_SIZE; i++) { printf("%ld\r\n", ipcbsrc[i]); } for (;;) { DEVICE_DELAY_US(1000000); //one second delay } } void init_SPI_FIFO(void) { int i; for (i = 0; i < 32; i++) sData[i] = i; }
The compilation process throws a lots of errors as below:
The linker settings for the projects are shown below:
The linker command file is shown below to check if the FFT sections are properly allocated.
MEMORY { BEGIN : origin = 0x080000, length = 0x000002 BOOT_RSVD : origin = 0x00000002, length = 0x00000126 RAMM0 : origin = 0x00000128, length = 0x000002D8 RAMM1 : origin = 0x00000400, length = 0x000003F8 /* on-chip RAM block M1 */ // RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ /* RAMLS4 : origin = 0x0000A000, length = 0x00000800 RAMLS5 : origin = 0x0000A800, length = 0x00000800 RAMLS6 : origin = 0x0000B000, length = 0x00000800 RAMLS7 : origin = 0x0000B800, length = 0x00000800*/ /* Combining all the LS RAMs */ RAMLS4567 : origin = 0x0000A000, length = 0x00002000 RAMGS0 : origin = 0x0000C000, length = 0x000007F8 // RAMGS0_RSVD : origin = 0x0000C7F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ // FLASHBANK1 : origin = 0x00080000, length = 0x0000FFF0 // FLASH_BANK1_RSVD : origin = 0x0008FFF0, length = 0x00000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ BOOTROM : origin = 0x003F0000, length = 0x00008000 BOOTROM_EXT : origin = 0x003F8000, length = 0x00007FC0 RESET : origin = 0x003FFFC0, length = 0x00000002 /*IQMath table already exists in the BOOTROM section*/ //IQTABLES : origin = 0x3F1402, length = 0x0166D /* Flash sectors */ /* BANK 0 */ FLASH_BANK0_SEC0 : origin = 0x080002, length = 0x000FFE /* on-chip Flash */ FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC3_9 : origin = 0x083000, length = 0x007000 /* on-chip Flash */ FLASH_BANK0_SEC10_11 : origin = 0x08A000, length = 0x002000 /* on-chip Flash */ FLASH_BANK0_SEC12_15 : origin = 0x08C000, length = 0x003FF0 /* on-chip Flash */ // FLASH_BANK0_SEC15_RSVD : origin = 0x08FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ } SECTIONS { codestart : > BEGIN, ALIGN(8) .text : >> FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3_9 , ALIGN(8)//executable code >> operator splits code .cinit : > FLASH_BANK0_SEC1, ALIGN(8)//table that initializes global variables .switch : > FLASH_BANK0_SEC1, ALIGN(8) .reset : > RESET, TYPE = DSECT /* not used, Dummy Section*/ .stack : > RAMM1 .init_array : > FLASH_BANK0_SEC1, ALIGN(8) .bss : > RAMLS4567 //uninitialized global variables .bss:output : > RAMLS4567 .bss:cio : > RAMGS0 .const : > FLASH_BANK0_SEC10_11, ALIGN(8) .data : > RAMLS4567 //initialized data .sysmem : > RAMLS4567 ramgs0 : > RAMGS0 /* Allocate IQ math areas: */ IQmath : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4) /* Math Code */ //IQmathTables : > FLASH_BANK0_SEC2, PAGE = 0, ALIGN(4)/*This was working*/ IQmathTables : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4)/*Moved to sector 1 to run from RAM.Need verification*/ /* Allocating FFT areas: */ FFTipcb : >> RAMGS0, ALIGN(256) //64 points FFT FFTipcbsrc : >> RAMLS4567 FFTtf : > FLASH_BANK0_SEC12_15 .TI.ramfunc : LOAD = FLASH_BANK0_SEC1, //Flash bank0 sector 1 contaings time critical functions required to run from RAM RUN = RAMGS0, LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), ALIGN(8) } /* //=========================================================================== // End of file. //=========================================================================== */
Please note that I have started working with the TI controllers only one month ago and I am not well versed with linked command file so kindly verify if all sections are allocated correctly. I will highly appreciate if these allocations can be revised for better processing time and more efficient memory usage. Meanwhile I am looking into the "Fixed Point DSP Software Library" document from the C2000Ware directory to troubleshoot at my end. I have taken reference from "FixedPoint_RFFT" project written for f2838x controllers.