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.

TMS320F28069 Delay Us is not working

Other Parts Discussed in Thread: TMS320F28069, CONTROLSUITE

Hello All,

One my client is facing issue related to DelayUs in TMS320F28069.

He have taken one example program from controlsuite and modified it according to my application requirement. This example is for RAM so it has RAM cmd file for memory mapping, the all function were working OK. But when the same program is going in to illegal instruction routine. When he did step debugging he observed it is when the Delay Us.asm is called during ADC initialization. When the same delay is generated using "for loop" flash cmd file is working.
Kindly help me for the same.

Below is the modified example code.

// TI File $Revision: /main/3 $
// Checkin $Date: January 5, 2011   17:08:18 $
//###########################################################################
//
// FILE:   Example_2806xAdcTempSensor.c
//
// TITLE:  F2806x ADC Temperatrue Sensor Example Program.
//
// ASSUMPTIONS:
//
//   This program requires the F2806x header files.
//
//   Make sure the CPU clock speed is properly defined in
//   F2806x_Examples.h before compiling this example.
//
//
//    $Boot_Table:
//
//    While an emulator is connected to your device, the TRSTn pin = 1,
//    which sets the device into EMU_BOOT boot mode. In this mode, the
//    peripheral boot modes are as follows:
//
//      Boot Mode:       EMU_KEY        EMU_BMODE
//                       (0xD00)	     (0xD01)
//      ---------------------------------------
//      Wait             !=0x55AA        X
//      I/O              0x55AA	         0x0000
//      SCI              0x55AA	         0x0001
//      Wait             0x55AA	         0x0002
//      Get_Mode         0x55AA	         0x0003
//      SPI              0x55AA	         0x0004
//      I2C              0x55AA	         0x0005
//      OTP              0x55AA	         0x0006
//      ECANA            0x55AA	         0x0007
//      SARAM            0x55AA	         0x000A	  <-- "Boot to SARAM"
//      Flash            0x55AA	         0x000B
//      Wait             0x55AA          Other
//
//   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
//   according to the Boot Mode Table above. Build/Load project,
//   Reset the device, and Run example
//
//   $End_Boot_Table
//
//
// Description:
//
//   This example sets up the PLL in x16/2 mode.
//
//   For 80 MHz devices (default)
//   (assuming a 10Mhz input clock).
//
//   Interrupts are enabled and the ePWM1 is set up to generate a periodic
//   ADC SOC interrupt - ADCINT1. One channel is converted -  ADCINA5, which is internally
//	 connected to the temperature sensor.
//
//   Watch Variables:
//
//         TempSensorVoltage[10] Last 10 ADCRESULT0 values
//         ConversionCount  Current result number 0-9
//         LoopCount        Idle loop counter
//
//
//###########################################################################
// $TI Release: 2806x C/C++ Header Files and Peripheral Examples V1.00 $
// $Release Date: January 11, 2011 $
//###########################################################################

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include  "F2806x_Adc.h"
// Prototype statements for functions found within this file.
interrupt void adc_isr(void);

// Global variables used in this example:

Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 TempSensorVoltage[10];
Uint16 duty_cycle_A=2500;
Uint16 duty_cycle_B=2500;

Uint16 RED_delay=50;
Uint16 FED_delay=50;
Uint16 Ramp;
Uint16 Phasedelay=0;
Uint16 AdcResults[16];
Uint16 msec=0;
Uint16 msecflag=0;
Uint16 sec2flag=0;
Uint16 PSP1FAILFLAG=0;
Uint16 PSP2FAILFLAG=0;
Uint16 PSP3FAILFLAG=0;
Uint16 PSPALLFAILFLAG=1;
Uint16 MIN=10;
Uint16 MINCH=0;
Uint16 PSP1=1;
Uint16 PSP2=3;
Uint16 PSP3=4;
Uint16	VFB;
Uint16 VOUT;
Uint16 PSPFAIL=5;







__interrupt void cpu_timer0_isr(void);
__interrupt void cpu_timer1_isr(void);
__interrupt void cpu_timer2_isr(void);






void main()
{

#define period 5000;
//Uint16 Phasedelay=600;


// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
   InitSysCtrl();


// Step 2. Initialize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:
// 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 F2806x_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 F2806x_DefaultIsr.c.
// This function is found in F2806x_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 register
   PieVectTable.ADCINT1 = &adc_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize the ADC:
// This function is found in F2806x_Adc.c
   InitAdc();  // For this example, init the ADC

// Step 5. Configure ADC to sample the temperature sensor on ADCIN5:
// The output of Piccolo temperature sensor can be internally connected to the ADC through ADCINA5
// via the TEMPCONV bit in the ADCCTL1 register. When this bit is set, any voltage applied to the external
// ADCIN5 pin is ignored.
	EALLOW;
	AdcRegs.ADCCTL1.bit.TEMPCONV 	= 1;	//Connect internal temp sensor to channel ADCINA5.
	EDIS;

// Step 6. Continue configuring ADC to sample the temperature sensor on ADCIN5:
// Since the temperature sensor is connected to ADCIN5, configure the ADC to sample channel ADCIN5
// as well as the ADC SOC trigger and ADCINTs preferred. This example uses EPWM1A to trigger the ADC
// to start a conversion and trips ADCINT1 at the end of the conversion.

// ADC Configuration for Temp Sensor	
/*	EALLOW;
	AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;	//ADCINT1 trips after AdcResults latch
	AdcRegs.INTSEL1N2.bit.INT1E     = 1;	//Enabled ADCINT1
	AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;	//Disable ADCINT1 Continuous mode
	AdcRegs.INTSEL1N2.bit.INT1SEL	= 0;	//setup EOC0 to trigger ADCINT1 to fire
	AdcRegs.ADCSOC0CTL.bit.CHSEL 	= 5;	//set SOC0 channel select to ADCINA5 (which is internally connected to the temperature sensor)
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL 	= 5;	//set SOC0 start trigger on EPWM1A
	AdcRegs.ADCSOC0CTL.bit.ACQPS 	= 25;	//set SOC0 S/H Window to 26 ADC Clock Cycles, (25 ACQPS plus 1)
	EDIS;

*/
// Step 7. User specific code, enable interrupts:

// Enable ADCINT1 in PIE
   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;	// Enable INT 1.1 in the PIE
   IER |= M_INT1; 						// Enable CPU Interrupt 1
   EINT;          						// Enable Global interrupt INTM
   ERTM;          						// Enable Global realtime interrupt DBGM

   LoopCount = 0;
   ConversionCount = 0;


// Assumes ePWM1 clock is already enabled in InitSysCtrl();
   EPwm1Regs.ETSEL.bit.SOCAEN	= 1;		// Enable SOC on A group
   EPwm1Regs.ETSEL.bit.SOCASEL	= 4;		// Select SOC from from CPMA on upcount
   EPwm1Regs.ETPS.bit.SOCAPRD 	= 1;		// Generate pulse on 1st event
   EPwm1Regs.CMPA.half.CMPA 	= 0x0080;	// Set compare A value
   EPwm1Regs.TBPRD 				= 0xFFFF;	// Set period for ePWM1
   EPwm1Regs.TBCTL.bit.CTRMODE 	= 0;		// count up and start




   //===============================================================================///
   //CPU TIMER CODE
   //================================================================================///

   // 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 F2806x_DefaultIsr.c.
   // This function is found in F2806x_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.TINT0 = &cpu_timer0_isr;
      PieVectTable.TINT1 = &cpu_timer1_isr;
      PieVectTable.TINT2 = &cpu_timer2_isr;
      EDIS;    // This is needed to disable write to EALLOW protected registers

   // Step 4. Initialize the Device Peripheral. This function can be
   //         found in F2806x_CpuTimers.c
      InitCpuTimers();   // For this example, only initialize the Cpu Timers

   // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
   // 80MHz CPU Freq, 1 second Period (in uSeconds)

      ConfigCpuTimer(&CpuTimer0, 80, 1000000);
      ConfigCpuTimer(&CpuTimer1, 80, 1000000);
      ConfigCpuTimer(&CpuTimer2, 80, 1000000);

   // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
   // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in F2806x_CpuTimers.h), the
   // below settings must also be updated.

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

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


   // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
   // which is connected to CPU-Timer 1, and CPU int 14, which is connected
   // to CPU-Timer 2:
      IER |= M_INT1;
      IER |= M_INT13;
      IER |= M_INT14;

   // Enable TINT0 in the PIE: Group 1 interrupt 7
      PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

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

   // Step 6. IDLE loop. Just sit and loop forever (optional):




   //===========================================================================
   // No more.
   //===========================================================================






   //=====================================================================
   // Config
   //=====================================================================
   // Initialization Time
   //=====================================================================
   // EPWM Module 1 config
   EPwm1Regs.TBPRD = period; // Period = 1201 TBCLK counts
   //EPwm1Regs.CMPA = 2400; // Set 50% fixed duty for EPWM1A
   EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
   EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
   EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
   EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A
   EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
   EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
   EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
   EPwm1Regs.DBFED = 50; // FED = 50 TBCLKs initially
   EPwm1Regs.DBRED = 70; // RED = 70 TBCLKs initially



   // EPWM Module 2 config
   EPwm2Regs.TBPRD = period; // Period = 1201 TBCLK counts
   EPwm2Regs.CMPA.half.CMPA = duty_cycle_A; // Set 50% fixed duty EPWM2A
   EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero initially
   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
   EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
   EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
   EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
   EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
   EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
   EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
   EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM2A
   EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
   EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
   EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
   EPwm2Regs.DBFED = FED_delay; // FED = 30 TBCLKs initially
   EPwm2Regs.DBRED = RED_delay; // RED = 40 TBCLKs initially
   // Run Time (Note: Example execution of one run-time instant)
   //============================================================
   EPwm2Regs.TBPHS.half.TBPHS = Phasedelay; // Set Phase reg to 300/1200 * 360 = 90 deg
   //EPwm1Regs.DBFED = FED1_NewValue; // Update ZVS transition interval
   //EPwm1Regs.DBRED = RED1_NewValue; // Update ZVS transition interval
   //EPwm2Regs.DBFED = FED2_NewValue; // Update ZVS transition interval
   //EPwm2Regs.DBRED = RED2_NewValue; // Update ZVS transition interval
   EPwm1Regs.CMPA.half.CMPA = duty_cycle_A;
   EPwm1Regs.CMPB = duty_cycle_B; // adjust point-in-time for ADCSOC trigger




// Wait for ADC interrupt
 /*  for(;;)
   {
      LoopCount++;
   }

}

*/
	AdcRegs.ADCSOCFRC1.all = 0x1000;  	// kick start ADC by causing a SOC12 event

		Phasedelay=100;


		EPwm1Regs.AQCSFRC.bit.CSFA =00;
		EPwm1Regs.AQCSFRC.bit.CSFB =00;
		EPwm2Regs.AQCSFRC.bit.CSFA =00;
		EPwm2Regs.AQCSFRC.bit.CSFB =00;

//=================================
//	Forever LOOP
//=================================
// Just sit and loop forever:
// No interrups needed in this example.
// PWM pins can be observed with a scope.

	for(;;)
	{
	Phasedelay=	AdcResult.ADCRESULT0;
	if(Phasedelay>=2399)
		{
		Phasedelay=2399;
		}
	if(Phasedelay<=0)
		{
		Phasedelay=50;
		}

 //EPwm2Regs.TBPHS.half.TBPHS = Phasedelay;
		Ramp=AdcResult.ADCRESULT1;

	/*if(Phasedelay<Ramp)
		{
		Phasedelay= Phasedelay+0.1;

		} */

	 EPwm2Regs.TBPHS.half.TBPHS = Phasedelay; //AdcResult.ADCRESULT2;
	 EPwm2Regs.CMPA.half.CMPA = duty_cycle_A;      // Add duty_cycle_A to watch window
	 EPwm2Regs.CMPB = duty_cycle_B;				// Add duty_cycle_B to watch window

	 EPwm1Regs.CMPA.half.CMPA = duty_cycle_A;    // Set duty 50% initially
 //EPwm1Regs.CMPB = duty_cycle_B;	            // Set duty 50% initially


	AdcResults[0] = AdcResult.ADCRESULT0;   // ADC-B7 NOT AVAILABLE on controlSTICK
	AdcResults[1] = AdcResult.ADCRESULT1;
	AdcResults[2] = AdcResult.ADCRESULT2;
	AdcResults[3] = 0;						// ADC-A3 NOT AVAILABLE on controlSTICK
	AdcResults[4] = AdcResult.ADCRESULT4;
	AdcResults[5] = AdcResult.ADCRESULT5;
	AdcResults[6] = AdcResult.ADCRESULT6;
	AdcResults[7] = 0;						// ADC-A7 NOT AVAILABLE on controlSTICK
	AdcResults[8] = AdcResult.ADCRESULT8;
	AdcResults[9] = AdcResult.ADCRESULT9;
	AdcResults[10] = AdcResult.ADCRESULT10;
	AdcResults[11] = 0;						// ADC-B3 NOT AVAILABLE on controlSTICK
	AdcResults[12] = AdcResult.ADCRESULT12;
	AdcResults[13] = 0;						// ADC-B5 NOT AVAILABLE on controlSTICK
	AdcResults[14] = AdcResult.ADCRESULT14;
	AdcResults[15] = 0;

//============================================================//
//						10Sec JOB
//============================================================//

	if(msecflag>=1)
	{
	GpioDataRegs.GPASET.bit.GPIO6 = 1;

	}
	else
	{
	GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
	}

/*
	if(GpioDataRegs.GPADAT.bit.GPIO7==1)

	{
		 EPwm1Regs.AQCSFRC.bit.CSFA =01;
		 EPwm1Regs.AQCSFRC.bit.CSFB =01;
		 EPwm2Regs.AQCSFRC.bit.CSFA =01;
		 EPwm2Regs.AQCSFRC.bit.CSFB =01;
	}
	*/

 if(sec2flag==1)
	{
		 EPwm1Regs.AQCSFRC.bit.CSFA =00;
		 EPwm1Regs.AQCSFRC.bit.CSFB =00;
		 EPwm2Regs.AQCSFRC.bit.CSFA =00;
		 EPwm2Regs.AQCSFRC.bit.CSFB =00;
	}


	else{
		 EPwm1Regs.AQCSFRC.bit.CSFA =01;
		 EPwm1Regs.AQCSFRC.bit.CSFB =01;
		 EPwm2Regs.AQCSFRC.bit.CSFA =01;
		 EPwm2Regs.AQCSFRC.bit.CSFB =01;
		}

										  // and change its value to see the effect

	if(PSP1<=PSPFAIL)

	{
		PSP1FAILFLAG=1;
		GpioDataRegs.GPADAT.bit.GPIO13=1;

	}
	if(PSP2<=PSPFAIL)

	{
		PSP2FAILFLAG=1;
		GpioDataRegs.GPADAT.bit.GPIO14=1;

	}
	if(PSP3<=PSPFAIL)

	{
		PSP3FAILFLAG=1;
		GpioDataRegs.GPADAT.bit.GPIO15=1;
	}

	if(PSP1FAILFLAG==0 && MIN>=PSP1)
		{
			MIN=PSP1;
			MINCH=1;

		}
	if(PSP2FAILFLAG==0 && MIN>=PSP2)
		{
			MIN=PSP2;
			MINCH=2;
		}

	if(PSP3FAILFLAG==0 && MIN>=PSP3)
		{
			MIN=PSP3;
			MINCH=3;
		}



	if(PSP1FAILFLAG==1 && PSP1FAILFLAG==1 && PSP1FAILFLAG==1)
	{
	PSPALLFAILFLAG=1;
	GpioDataRegs.GPADAT.bit.GPIO16=1;
	}




	if(GpioDataRegs.GPADAT.bit.GPIO8==1 && PSPALLFAILFLAG==0) //auto mode bit set then select auto mode

			{
				if(GpioDataRegs.GPADAT.bit.GPIO9==1)          // if minimum PSP bit is set then find minimum PSP

				{
					//Find minimum PSP voltage channel
					/*if(PSP1FAILFLAG==0 && MIN>PSP1)
					{
						MIN=PSP1;
						MINCH=1;
					}
					elseif(PSP2FAILFLAG==0 && MIN>PSP2)
					{
						MIN=PSP2;
						MINCH=2;
					}
					elseif(PSP3FAILFLAG==0 && MIN>PSP3)
					{
						MIN=PSP3;
						MINCH=3;
					}  */
					VFB=MIN;
				}

				else if(GpioDataRegs.GPADAT.bit.GPIO10==1 && PSP1FAILFLAG==0)	//PSP1 CH SELECT GPIO
				{
					VFB=PSP1;

				}
				else if(GpioDataRegs.GPADAT.bit.GPIO11==1 && PSP2FAILFLAG==0)	//PSP2 CH SELECT GPIO

				{
					VFB=PSP2;

				}
				else if(GpioDataRegs.GPADAT.bit.GPIO10==1 && PSP3FAILFLAG==0)	//PSP3 CH SELECT GPIO

				{
					VFB=PSP3;

				}
				else
				{
					VFB=0;
				}
			}

	else if(GpioDataRegs.GPADAT.bit.GPIO12==1)	// CVCC MODE SELECTION GPIO
			{
			VFB=VOUT;
			}


}  //END OF FOR LOOP


}  // END OF MAIN LOOP




interrupt void  adc_isr(void)
{

  TempSensorVoltage[ConversionCount] = AdcResult.ADCRESULT0;

  // If 20 conversions have been logged, start over
  if(ConversionCount == 9)
  {
     ConversionCount = 0;
  }
  else ConversionCount++;

  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;		//Clear ADCINT1 flag reinitialize for next SOC
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  return;
}

__interrupt void cpu_timer0_isr(void)
{
   CpuTimer0.InterruptCount++;

   // Acknowledge this interrupt to receive more interrupts from group 1
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
   msec=msec+1;
   if(msec>=5)
   {
	   sec2flag=1;
   }

   if(msec>=10)
   {
	   if(msecflag>=1)
	   {
		   msecflag=0;
	   }
	   else
	   	{
	   		   msecflag=1;
	   	 }
	   msec=0;

	   }

}




__interrupt void cpu_timer1_isr(void)
{
   CpuTimer1.InterruptCount++;
   // The CPU acknowledges the interrupt.
   EDIS;
}

__interrupt void cpu_timer2_isr(void)
{  EALLOW;
   CpuTimer2.InterruptCount++;
   // The CPU acknowledges the interrupt.
   EDIS;
}

Awaiting for your valuable response