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.
