EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Controlling PWM Waves With DSP 2028

Started by gare...@live.uwe.ac.uk April 23, 2008
Hello,
I am fairly new but have a simple background to DSP.
My problem I am faced with is being able to output a certain number of PWM waves from the DSP, I wish to trigger this from an interrupt caused from a peripheral pin,
Basically I set up the two examples from TI and I have successfully got the PWM and ADC examples working correctly.
My problem comes when I wish to use the two examples together I have put all the necessary files into the project and put the code all together,
When I run the program I measure the value on an input pin and when it gets to say 2volts (for now) I activate the PWM waves this works as expected but when I turn the PWM waves off and the ADC back on I get an unexpected outcome. I have a feeling this is something to do with the register or peripheral setting up I am doing inside the program but I am not sure.
Can anyone help me I have included my code...
Many Thanks in advance, I am extremely grateful,
// Prototype statements for functions found within this file.

void main(void)
{
delaycount = 0;
//
// run adc.c and stay there till zcd decteted
// ie until a variable becomes 1

adcmain();

//
// run the pwm.c

// pwmmain();
}

void adcmain(void)
{

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

// For this example, set HSPCLK to SYSCLKOUT / 6 (25Mhz assuming 150Mhz SYSCLKOUT)
EALLOW;
SysCtrlRegs.HISPCP.all = 0x3; // HSPCLK = SYSCLKOUT/6
EDIS;

// 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 DSP281x_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 DSP281x_DefaultIsr.c.
// This function is found in DSP281x_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.ADCINT = &adc_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP281x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitAdc(); // For this example, init the ADC

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

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

LoopCount = 0;
ConversionCount = 0;

// Configure ADC
AdcRegs.ADCMAXCONV.all = 0x0001; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // Setup ADCINA3 as 1st SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

// Configure EVA
// Assumes EVA Clock is already enabled in InitSysCtrl();
EvaRegs.T1CMPR = 0x0080; // Setup T1 compare value
EvaRegs.T1PR = 0xFFFF; // Setup period register
EvaRegs.GPTCONA.bit.T1TOADC = 1; // Enable EVASOC in EVA
EvaRegs.T1CON.all = 0x1042; // Enable timer 1 compare (upcount mode)

// Wait for ADC interrupt
if (myvoltage!=0)
{
}

}
interrupt void adc_isr(void)
{

Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;

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

// Reinitialize for next ADC sequence

averageval=(Voltage1[0]+Voltage1[1]+Voltage1[2]+Voltage1[3]+Voltage1[4]+Voltage1[5]+Voltage1[6]+Voltage1[7]+Voltage1[8]+Voltage1[9])/10;

volt3rd=(averageval/4095);

myvoltage=(volt3rd*3);

if (myvoltage<1)
{
pwmmain();
}

AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

return;
}

void pwmmain(void)

{
testtest = 1;

tim=1;
time=1;
Ti=1;
test=1;
SDtim=1;
SDtime=1;
SDTi=1;
SDtest=1;

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

// Initialize only GPAMUX and GPBMUX for this test
EALLOW;
// Enable PWM pins
GpioMuxRegs.GPAMUX.all = 0x00FF; // EVA PWM 1-6 pins
GpioMuxRegs.GPBMUX.all = 0x00FF; // EVB PWM 7-12 pins
EDIS;

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize 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 DSP281x_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 DSP281x_DefaultIsr.c.
// This function is found in DSP281x_PieVect.c.
InitPieVectTable();

stat_com(); //call my statcom contrlling program

// Step 5. User specific code, enable interrupts:
// Just sit and loop forever:
// PWM pins can be observed with a scope.
for(;;);

}

void stat_com() //The statcom controlling program ere
{

// hex1=0x0F64; // timer1 periods
// hex2=0x07B2; //timer1 comparing
// T2hexP=0x0F64; // timer2 periods
// T2hexC=0x07B2; //timer2 comparing
//
// init_eva(); //enabiling pwm1 p15
// init_evb(); //enabiling pwm2 p16
//
//
//
//
// delay(); //delaying
//
// hex1=0x0000; // timer1 periods
// hex2=0x0000; //timer1 comparing
// init_eva(); //enabiling pwm1 p15
// init_evb(); //enabiling pwm2 p16
//
//
// controlling the pwm waves perfect :)
while (delaycount<10)
{
//timer pwms both offffffffff
hex1=0x0000; // timer1 periods
hex2=0x0000; //timer1 comparing
init_eva(); //enabiling pwm1 p15
init_evb(); //enabiling pwm2 p16
T2hexP=0x0000; // timer1 periods
T2hexC=0xFFFF; //timer1 comparing
init_eva(); //enabiling pwm1 p15
init_evb(); //enabiling pwm2 p16
SafeDelay(); //Safety Delay Between Switching

// timer 1 pwm wave back on

hex1=0x0F64; // timer1 periods
hex2=0x07B2; //timer1 comparing
init_eva(); //enabiling pwm1 p15
init_evb(); //enabiling pwm2 p16
delay(); //delaying

//timer pwms both offffffffff
hex1=0x0000; // timer1 periods
hex2=0x0000; //timer1 comparing
init_eva(); //enabiling pwm1 p15

init_evb(); //enabiling pwm2 p16

T2hexP=0x0000; // timer1 periods
T2hexC=0xFFFF; //timer1 comparing
init_eva(); //enabiling pwm1 p15
init_evb(); //enabiling pwm2 p16
SafeDelay(); //Safety Delay Between Switching

//timer 2 pwm wave back on
T2hexP=0x0F64; // timer1 periods
T2hexC=0x07B2; //timer1 comparing
init_eva(); //enabiling pwm1 p15
init_evb(); //enabiling pwm2 p16
delay(); //delaying

}

main();

}

void init_eva()
{

// EVA Configure T1PWM, T2PWM, PWM1-PWM6
// Initalize the timers
// Initalize EVA Timer1
EvaRegs.T1PR = hex1; // Timer1 period
EvaRegs.T1CMPR = hex2; // Timer1 compare
EvaRegs.T1CNT = 0x0000; // Timer1 counter
// TMODE = continuous up/down
// Timer enable
// Timer compare enable
EvaRegs.T1CON.all = 0x1042;
// Initalize EVA Timer2
EvaRegs.T2PR = T2hexP; // Timer2 period
EvaRegs.T2CMPR = T2hexC; // Timer2 compare
EvaRegs.T2CNT = 0x0000; // Timer2 counter
// TMODE = continuous up/down
// Timer enable
// Timer compare enable
EvaRegs.T2CON.all = 0x1042;
// Setup T1PWM and T2PWM
// Drive T1/T2 PWM by compare logic
EvaRegs.GPTCONA.bit.TCMPOE = 1;
// Polarity of GP Timer 1 Compare = Active low
EvaRegs.GPTCONA.bit.T1PIN = 1;
// Polarity of GP Timer 2 Compare = Active high
EvaRegs.GPTCONA.bit.T2PIN = 2;

// Enable compare for PWM1-PWM6
EvaRegs.CMPR1 = 0x0C00;
EvaRegs.CMPR2 = 0x3C00;
EvaRegs.CMPR3 = 0xFC00;

// Compare action control. Action that takes place
// on a cmpare event
// output pin 1 CMPR1 - active high
// output pin 2 CMPR1 - active low
// output pin 3 CMPR2 - active high
// output pin 4 CMPR2 - active low
// output pin 5 CMPR3 - active high
// output pin 6 CMPR3 - active low
EvaRegs.ACTRA.all = 0x0666;
EvaRegs.DBTCONA.all = 0x0000; // Disable deadband
EvaRegs.COMCONA.all = 0xA600;
}

void init_evb()
{

// EVB Configure T3PWM, T4PWM and PWM7-PWM12
// Step 1 - Initialize the Timers

// Initialize EVB Timer3
// Timer3 controls T3PWM and PWM7-12
EvbRegs.T3PR = 0x0F64; // Timer3 period
EvbRegs.T3CMPR = 0x07B2; // Timer3 compare
EvbRegs.T3CNT = 0x0000; // Timer3 counter
// TMODE = continuous up/down
// Timer enable
// Timer compare enable
EvbRegs.T3CON.all = 0x1042;

// Initialize EVB Timer4
// Timer4 controls T4PWM
EvbRegs.T4PR = 0x0F64; // Timer4 period
EvbRegs.T4CMPR = 0x07B2; // Timer4 compare
EvbRegs.T4CNT = 0x0000; // Timer4 counter
// TMODE = continuous up/down
// Timer enable
// Timer compare enable
EvbRegs.T4CON.all = 0x1042;

// Setup T3PWM and T4PWM
// Drive T3/T4 PWM by compare logic
EvbRegs.GPTCONB.bit.TCMPOE = 1;
// Polarity of GP Timer 3 Compare = Active low
EvbRegs.GPTCONB.bit.T3PIN = 1;
// Polarity of GP Timer 4 Compare = Active high
EvbRegs.GPTCONB.bit.T4PIN = 2;

// Enable compare for PWM7-PWM12
EvbRegs.CMPR4 = 0x0C00;
EvbRegs.CMPR5 = 0x3C00;
EvbRegs.CMPR6 = 0xFC00;

// Compare action control. Action that takes place
// on a cmpare event
// output pin 1 CMPR4 - active high
// output pin 2 CMPR4 - active low
// output pin 3 CMPR5 - active high
// output pin 4 CMPR5 - active low
// output pin 5 CMPR6 - active high
// output pin 6 CMPR6 - active low
EvbRegs.ACTRB.all = 0x0666;
EvbRegs.DBTCONB.all = 0x0000; // Disable deadband
EvbRegs.COMCONB.all = 0xA600;
}

void delay ()
{
tim=1;
time= 1;
Ti=1;
test=1;
for (tim = 1; tim <= 1; tim++)
{
for (time = 1; time <= 700; time++)
{
for (Ti = 1; Ti <= 1000; Ti++);
{
test = test+1;
}
}
}
}
void SafeDelay ()
{
delaycount++;

SDtim=1;
SDtime= 1;
SDTi=1;
SDtest=1;
for (SDtim = 1; SDtim <= 2; SDtim++)
{
for (SDtime = 1; SDtime <= 100; SDtime++)
{
for (SDTi = 1; SDTi <= 1000; SDTi++);
{
SDtest = SDtest+1;
}
}
}
}


OMAP35x EVM jump-starts low-power apps
The modular and extensible OMAP35x Evaluation Module (EVM) enables developers to start building applications based on the OMAP35x architecture: http://www.DSPRelated.com/omap35x

Memfault Beyond the Launch