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.

Compilation Error #10056, don't understand where it's coming from.

Hey there,

I'm developing a project with the F28377S c2000 launchpad. I just converted some exploratory code into a more streamlined library for my application. When I try and compile the project, I get the compilation error #10056 saying that I first defined a symbol in one library, and then tried to redefine it in another. I have included the pragma statements such as:

#ifndef F28X_PROJECT_H
#include "F28x_Project.h"
#endif

for all my includes and header files, but the error is still there. I'm not sure what i'm doing wrong. Here is the error CCS is giving me:

>> Compilation failure
error #10056: symbol "_TICK_EVENTS" redefined: first defined in "./Scan.obj"; redefined in "./main.obj"
error #10056: symbol "_servo1" redefined: first defined in "./Scan.obj"; redefined in "./main.obj"
error #10010: errors encountered during linking; "AssistiveMeasure-rev-0.out" not built
gmake: *** [AssistiveMeasure-rev-0.out] Error 1

and here is the code which seems to be giving me the issue:

global.h file:

#ifndef F28X_PROJECT_H
#include "F28x_Project.h"
#endif


#ifndef GLOBAL_H_
#define GLOBAL_H_



    				// Device Headerfile and Examples Include File
//#include "pinmux_qep_epwm.c"				// Pin Configuration VIA pinmux.
//#include "F2837xS_I2C.c"

//#include "lcd.h"
//#include "I2C.h"

typedef struct
{
	Uint32	Scan_TS;						// Time stamp used to trigger a delayed event

	Uint32	TickCount;						// The Systems Tick Count
	Uint32	TickCountCMP;					// Used to determine if a System Tick has occured since last pass.

}Events;

typedef struct
{
	float angle;
	float distance;
}Measurement;



// Global Variables
Events TICK_EVENTS;


#endif /* GLOBAL_H_ */


Main:

//#######################
// Global Include Section
// global includes everything for the project.
//#######################
#ifndef SERVOCONTROL_H_
#include "ServoControl.h"
#endif
#include "lcd.h"
#ifndef GLOBAL_H_
#include "global.h"
#endif
//#include "scan.h"



/*/////////////////////
 * Interrupt Prototypes
 */////////////////////
__interrupt void epwm1_isr(void);
__interrupt void eqep1_isr(void);
__interrupt void SysTick_ISR(void);
/*
 * Extern Function definitions
 */
extern void servoInit(Servo *servo);
extern void setServoAngle(Servo *servo);
extern void quadInit(void);
extern void InitEQep3Gpio(void);
extern __interrupt void i2c_int1a_isr(void);
extern __interrupt void measure_isr(void);
extern void test(void);
extern void I2CA_Init(void);
extern void InitECapture();



/*////////////////////////
 * Global Variables
 *////////////////////////
extern Servo servo1;




Uint16		testCount = 0;
Uint16		SysTickCount = 0;
Uint16		MeasureCount = 0;
Uint16		MeasureFlags = 0x0000;
Uint16		pos	= 0;
int i = 0;
float temp = 0.0;


void initialize(void) {




	// Initialize System Control:
	// PLL, WatchDog, enable Peripheral Clocks
	// Modified for 200 MHz Sysclock
	    InitSysCtrl();

	// Initialize GPIO:

	    /*
	     * This needs to be cleaned up
	     * Functions defined where InitGpio is
	     * can easily be used to configure the peripherals i'm
	     * interested in
	     *
	     * GPIO_setPinMuxConfig is currently  setting up the ePWM for the servo
	     * InitEQep3Gpio is setting up the eQEP, I want to keep that.
	     */

	    InitGpio();								// General IO Setup
	    //GPIO_setPinMuxConfig();					// Pin Multiplex Information.
		InitEPwm2Gpio();
	    InitEQep3Gpio();						// Initialize the eQEP module
	    I2cAGpioConfig(I2C_A_GPIO91_GPIO92);	// Configure I2C A module for pins 91 & 92
	    InitECap1Gpio(71);						// Conigure eCap Pin
		GPIO_SetupPinOptions(90, output, NOFLAGS);	// Configure pins for eCap operations
		//GPIO_SetupPinOptions(71, input, NOFLAGS);	// Configure pins for eCAP operations

	// Disable CPU interrupts
	    DINT;

	// Initialize the PIE control registers to their default state.
	// The default state is all PIE interrupts disabled and flags
	// are cleared.
	// This function is found in the F2837xS_PieCtrl.c file.
	    InitPieCtrl();

	// Disable CPU interrupts and clear all CPU interrupt flags:
	    IER = 0x0000;
	    IFR = 0x0000;

	// Initialize the PIE vector table with pointers to the shell Interrupt
	// Service Routines (ISR).
	// This will populate the entire table, even if the interrupt
	// is not used in this example.  This is useful for debug purposes.
	// The shell ISR routines are found in F2837xS_DefaultIsr.c.
	// This function is found in F2837xS_PieVect.c.
	    InitPieVectTable();

	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
		EALLOW; // This is needed to write to EALLOW protected registers
		PieVectTable.TIMER0_INT = &SysTick_ISR;
		PieVectTable.EPWM2_INT = &epwm1_isr;
		PieVectTable.EQEP3_INT = &eqep1_isr;
		PieVectTable.I2CA_INT = &i2c_int1a_isr;
		PieVectTable.ECAP1_INT = &measure_isr;
		EDIS;   // This is needed to disable write to EALLOW protected registers

		// Initialize the system's peripherals for components.
		InitCpuTimers();
		servoInit(&servo1);				// Load ePWM for Servo
		quadInit();						// Load eQEP for Motor angle.
		I2CA_Init();					// Initialize I2C module
		InitECapture();					// Initialize eCAP module
		//LCDInit();						// LCD Initialization


		// Configure System Tick here
		ConfigCpuTimer(&CpuTimer0, 200, 5000);	// Configure system tick for 5ms.

		CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

	// Step 4. User specific code, enable interrupts:

	// Enable CPU Interrupt groups for interrupts.
		IER |= M_INT1;			// Ground 1 for Timer 0
		IER |= M_INT3;			// Ground 3 for PWM interrupts
		IER |= M_INT4;			// Group 4 for eCAP interrupts
		IER |= M_INT8;			// Group 8 for I2C interrupts

	// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
		PieCtrlRegs.PIEIER1.bit.INTx7 = 1;	// Enable interrupt for Timer 0.
		PieCtrlRegs.PIEIER3.bit.INTx2 = 1; // Enable PWM 2 Interrupt
		PieCtrlRegs.PIEIER5.bit.INTx3 = 1;	// eQEP Interrupt
		PieCtrlRegs.PIEIER8.bit.INTx1 = 1; // Enable I2C interrupt
		PieCtrlRegs.PIEIER4.bit.INTx1 = 1; // Enable eCAP1 Interrupt

	// Enable Clock to Peripherals
	    CpuSysRegs.PCLKCR2.bit.EPWM2=1;
	    CpuSysRegs.PCLKCR4.bit.EQEP3=1;
	    CpuSysRegs.PCLKCR3.bit.ECAP1=1;
	    //CpuSysRegs.PCLKCR0.bit.CPUTIMER0 = 1;


	// Enable global Interrupts and higher priority real-time debug events:
	    EINT;  // Enable Global interrupt INTM
	    ERTM;  // Enable Global realtime interrupt DBGM



	    EnableInterrupts();


	return;
}



void main(void)
{

	initialize();		// Perform all initializations

// main loop.
    for(;;)
    {

      	//testLidar();


    }
    	//putrsLCD("-");
}

__interrupt void epwm1_isr(void)
{
    // Acknowledge this interrupt to receive more interrupts from group 3
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

__interrupt void eqep1_isr(void) {

	//servo1.angle= (EQep1Regs.QPOSILAT) / 2 ;
	//setServoAngle(&servo1);
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP5;

}

__interrupt void SysTick_ISR(void) {
	// Here's are system tick folks

	if (TICK_EVENTS.TickCount != 0xFFFFFFFF)
	{
		TICK_EVENTS.TickCount++;
	} else {
		TICK_EVENTS.TickCount = 0;
	}
	//CpuTimer0.RegsAddr->TCR.bit.TIF = 0;
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;	// Ack this interrupt.

}

Scan.h:

#ifndef F28X_PROJECT_H
#include "F28x_Project.h"
#endif
#ifndef GLOBAL_H_
#include "global.h"
#endif
#ifndef SERVOCONTROL_H_
#include "ServoControl.h"
#endif




#ifndef SCAN_H_
#define SCAN_H_

#define	SCAN_EN		0x0001				// Flag that a scan has started
#define SCAN_SAMPLE	0x0002				// Flag that a sample has started
#define SCAN_FIN	0x0010				// Flag that a scan has completed




#define FIRSTDELAY	200					// Number of tick counts before the first scan is to start
#define MOVEDELAY	20					// Number of ticks used in between measurements
#define SCAN_LIMIT	8					// Number of scan cycles for each measurement, hopefully this artificually increases accuracy.


Uint16 			ScanFlags;						// Flags used within the Scan Cycle
unsigned char 	SampleCount;					// Capture the Sampling Cycle Count
unsigned char 	MeasurementCount;				//
float			MeasurementBuffer[SCAN_LIMIT];	// Measurement Buffer
Measurement 	testMeasurements[360];	// scan Measurements

void InitECapture( void );			// Initialize the Capture Module
void StartScan( void );				// Used to initiate a full scan.
void ScanEvent( void );				// Used to handle a scan event
float sumBuffer (float Buffer[]);	// Sum the Sample Measurements
__interrupt void measure_isr(void);	// Interrupt for Capture Module



#endif /* SCAN_H_ */

Scan.c:

/*
 * Scan.c
 *
 *  Created on: Mar 8, 2016
 *      Author: user
 */

//#ifndef GLOBAL_H_
//#include "global.h"
//#endif
//#ifndef SERVOCONTROL_H_
///#include "ServoControl.h"
//#endif
#include "Scan.h"

// External Variables
extern Servo servo1;


void InitECapture()
{
   ECap1Regs.ECEINT.all = 0x0000;             // Disable all capture __interrupts
   ECap1Regs.ECCLR.all = 0xFFFF;              // Clear all CAP __interrupt flags
   ECap1Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loads
   ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped

   // Configure peripheral registers
   ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;      // One-shot
   ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 events
   ECap1Regs.ECCTL1.bit.CAP1POL = 0;          // R edge
   ECap1Regs.ECCTL1.bit.CAP2POL = 1;          // F edge
   ECap1Regs.ECCTL1.bit.CAP3POL = 0;          // R edge
   ECap1Regs.ECCTL1.bit.CAP4POL = 1;          // F edge
   ECap1Regs.ECCTL1.bit.CTRRST1 = 1;          // Difference operation Ressets counter after event
   ECap1Regs.ECCTL1.bit.CTRRST2 = 1;          // Difference operation
   ECap1Regs.ECCTL1.bit.CTRRST3 = 1;          // Difference operation
   ECap1Regs.ECCTL1.bit.CTRRST4 = 1;          // Difference operation
   ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;         //
   ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass through
   ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture units

   ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
   ECap1Regs.ECCTL2.bit.REARM = 1;            // arm one-shot
   ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
   ECap1Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = __interrupt
   return;
}

// Start Scan
// This is used to initiate a scan
void StartScan( void )
{
	int i;
	for (i = 0; i < SCAN_LIMIT; i++)
	{
		MeasurementBuffer[i] = 0;
	}
	for (i = 0; i < servoSteps; i++) {
			testMeasurements[i].angle = 0;
			testMeasurements[i].distance = 0;
	}

	SampleCount = 0;											// Clear the Sample count
	MeasurementCount = 0;										// Clear the Measurement Count
	servo1.angle = 0;											// Set the servo Angle to 0
	setServoAngle(&servo1);										// Update the Servo angle
	TICK_EVENTS.Scan_TS = TICK_EVENTS.TickCount + FIRSTDELAY;	// Stamp the Next event time.
	ScanFlags |= SCAN_EN;										// Set the scanning flag

}

// Scan Event, this is used to handle the events that take place during a scan
void ScanEvent( void ){

	if (TICK_EVENTS.Scan_TS == TICK_EVENTS.TickCount)			// Check to see if it's time to handle the event.
	{
		if ((ScanFlags & SCAN_SAMPLE) == 0) 					// If there isn't a sample happening
		{
			if (SampleCount < SCAN_LIMIT)						// Check for number of scan cycles.
			{
				GPIO_WritePin(90, 0);							// Not Done Measuring, Start the Sample again
				ScanFlags |= SCAN_SAMPLE;						// Flag a sample has started

			} else {

				ScanFlags &= ~SCAN_SAMPLE;						// Acknowledge the sample is done

				testMeasurements[MeasurementCount].distance = sumBuffer(MeasurementBuffer);
				testMeasurements[MeasurementCount].angle = servo1.angle;

				if (servo1.angle == 180)										// Reached the scan limit?
				{
					ScanFlags &= ~SCAN_EN;										// Clear the Scan Flag
					ScanFlags |= SCAN_FIN;
				} else {
					servo1.angle += servoResolution;							// Increment the angle fo the servo motor.
					setServoAngle(&servo1);										// Set the angle
					TICK_EVENTS.Scan_TS = TICK_EVENTS.TickCount + MOVEDELAY;	// Stamp the tick count for the next event
				}

			}
		}
	}

}

float sumBuffer (float Buffer[])
{
	float result;
	int i;

	for (i = 0; i < SCAN_LIMIT; i++)			// Sum the measurements
	{
		result += Buffer[i];
	}
	result /= SCAN_LIMIT;

	return result;

}

__interrupt void measure_isr(void) {

	GPIO_WritePin(90, 1);			// Stop the Lidar Module

	//MeasurementBuffer[SampleCount].angle = servo1.angle;
	MeasurementBuffer[SampleCount] = (ECap1Regs.CAP2 + ECap1Regs.CAP4) / 4000; // Add the two capture events and average the result. Clean this computation up
	SampleCount++;

	// Rearm the eCAP
	ECap1Regs.ECCLR.all = 0xFFFF;				// Clear ALL flags
	ECap1Regs.ECCTL2.bit.REARM = 1;            	// arm one-shot
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;

}

Servo.h:

#include "F28x_Project.h"

#ifndef SERVOCONTROL_H_
#define SERVOCONTROL_H_

typedef struct
{
	volatile struct EPWM_REGS *EPwmRegHandle;
	float angle;
	uint16_t CaptureValue;
	uint16_t flags;
}Servo;

Servo servo1;

void servoInit(Servo *servo);
void setServoAngle(Servo *servo);

// Configure the period for each timer
#define SERVO_PRD		   	62500  										// Period register
#define servoResolution		0.5											// Resolution in Degrees
#define servo180Cal			7385										// ePWM count for 180'
#define servo0Cal			1850										// ePWM count for 0'
#define servoSteps			(180 / servoResolution)						// nummber of steps for set res.

#define EPWM1_MIN_CMPA      7385										// Initial Value
#define EPWM1_MIN_CMPB     	7385										// Initial Value

#define SERVO_UPDATE_CAPVAL 0x01

#define angleStep			((servo180Cal - servo0Cal) / servoSteps)		// ePWM count inc/dec for a single step

#endif /* SERVOCONTROL_H_ */

and servo.c:

#ifndef SERVOCONTROL_H_
#include "ServoControl.h"
#endif

void servoInit(Servo *servo)
{
(*servo).EPwmRegHandle = &EPwm2Regs;
(*servo).CaptureValue = 0;
(*servo).angle = 0.0;
(*servo).flags = 0x00;
// Setup TBCLK
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0x1; // Make sure 200MHz clock is divided by 2.
(*servo).EPwmRegHandle->TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
(*servo).EPwmRegHandle->TBPRD = SERVO_PRD; // Set timer period
(*servo).EPwmRegHandle->TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
(*servo).EPwmRegHandle->TBPHS.bit.TBPHS = 0x0000; // Phase is 0
(*servo).EPwmRegHandle->TBCTR = 0x0000; // Clear counter
(*servo).EPwmRegHandle->TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
(*servo).EPwmRegHandle->TBCTL.bit.CLKDIV = 0x5; // 101 sets to div 32. input clk = 3.125MHz

// Setup shadow register load on ZERO
(*servo).EPwmRegHandle->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*servo).EPwmRegHandle->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
(*servo).EPwmRegHandle->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
(*servo).EPwmRegHandle->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

// Set Compare values
//(*servo).angle = 90.0;
//setServoAngle(servo);

// Set actions
(*servo).EPwmRegHandle->AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero
(*servo).EPwmRegHandle->AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count
(*servo).EPwmRegHandle->AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero
(*servo).EPwmRegHandle->AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, up count

// Interrupt where we will change the Compare Values
//(*servo).EPwmRegHandle->ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
//(*servo).EPwmRegHandle->ETSEL.bit.INTEN = 1; // Enable INT
//(*servo).EPwmRegHandle->ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
return;
}


void setServoAngle(Servo *servo) {

uint16_t pAngle = (uint16_t)((*servo).angle * 10);
//uint16_t mod; // Not super need
//float angleStepVar = angleStep;
//float servoStepsVar = servoSteps;
// Remove 'inbetween' angle settings by subtracting the modulus of the
// servo resolution
//mod = (pAngle % (int)(servoResolution * 10));
//pAngle -= (pAngle % (int)(servoResolution * 10));


// Prevent any errors
if (pAngle > 1800) {
pAngle = 1800;
}

// Convert to number of angle steps
pAngle /= (int)(servoResolution * 10);

// Calculate the compare value for the desired angle
// 0' compare value + ((Angle * 10) * compare values per angle value)
(*servo).CaptureValue = servo0Cal + (pAngle * angleStep);

// Set Compare values
(*servo).EPwmRegHandle->CMPA.bit.CMPA = (*servo).CaptureValue; // Set compare A value
(*servo).EPwmRegHandle->CMPB.bit.CMPB = (*servo).CaptureValue; // Set Compare B value


return;
}

I'm super stuck with this and need a helping hand to point me in the right direction.

Thanks.

  • The method of "Inclusion Locking" requires that the symbol be defined if it is determined to be not defined:

    #ifndef F28X_PROJECT_H
    #define  F28X_PROJECT_H  // This needs to be defined now so that the file is included only once
    #include "F28x_Project.h"
    #endif

    To avoid doing this every time you include the file, simply add it to the "F28x_Project.h" file instead. Inside of F28x_Project.h,

    #ifndef F28X_PROJECT_H
    #define  F28X_PROJECT_H

    // All your header file definitions go here


    #endif

    All header files (C/C++) should use the second method. If inclusion locking is not done, then re-definition errors will occur.