Dear all,
I implemented voltage and current measurement on ADCINA5 and ADCINB5, respectively using simultaneous mode. The SOCA bit is generated by ePWM1 module, which is in up-count mode with 50% duty cycle. Furthermore, the SOCA bit is generated when COMPA and the time base counter (when incrementing) match. The PWM waveforms are as expected.
I also get proper ADC readings within the ADC ISR and am therefore now trying to measure the ISR execution time. For that, I set a GPIO at the beginning of the ISR, which I clear at the end of the ISR. However, my measurements show that the ISR is entered much more often than the ePWM is generated. I attached a waveform of the PWM (magenta, 50% duty with approx. 600ns dead band) and the GPIO within the ISR (blue).
I also attached my theoretical waveforms based on my understanding when reading the documents SPRU812A and SPRAAP6A.
Any ideas on what I am doing wrong? Much appreciated.
/*
* 23. Nov. 2016: Open loop for now - only PWM generation - no phase shift implemented
* 13. Dec. 2016: Program to flash functionality added
* 16. Dec. 2016: Phase shift for open loop PWM generation added
* 04. Jan. 2017: ADC measurements added - to be cont'd
*/
#include "DSP28x_Project.h"
void InitialADC();
void InitePWM1();
void InitePWM2();
void InitePWM5();
void InitePWM6();
__interrupt void ADC_isr();
// Flash functionality
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
// Variables
#define DT 100 // Dead time calc: DT = Value/CLKfreq -> 100/150MHz = 666ns
Uint16 phaseshift;
Uint16 ConversionCount;
Uint16 Voltage1[128];
Uint16 Current[128];
void main(void) {
// Initialize PLL, Watchdog, enable peripheral clocks
InitSysCtrl();
// Used to program to flash
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// Initialize ePWM
InitEPwmGpio();
// Initialize PIE control registers
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
// Initialize PIE vector table to default ISR
InitPieVectTable();
// Remap the ISR function to the PIE vector table
EALLOW;
PieVectTable.ADCINT = &ADC_isr;
EDIS;
// First step of setting up the ADC sampling rate
EALLOW;
SysCtrlRegs.HISPCP.all = 3; // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
EDIS;
// Synchronization already done in the InitSysCtrl() function --> Ask the TI support to verify
/*
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable time base clock synchronization with SYSCLKOUT from DSP
EDIS;
*/
InitFlash();
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // Group 1, bit 6 for ADC
IER |= M_INT1; // Sets the interrupt enable bit of group 1
EINT; // Enable global interrupts INTM
ConversionCount = 0; // Initialize the count
// Initialize the ADC
InitAdc();
phaseshift = 102; // Initializing the phase shift
InitialADC();
InitePWM1();
InitePWM2();
InitePWM5();
InitePWM6();
/*
* Set GPIO4 as output to measure execution time within ISR
*/
EALLOW;
// Set GPIO10 as a GPIO - already done in InitGpio()
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
// Set GPIO10 as an output
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
EDIS;
for(;;)
{
}
}
__interrupt void ADC_isr(void)
{
GpioDataRegs.GPASET.bit.GPIO4 = 1;
Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4; // Read value from ADCINA5
Current[ConversionCount] = AdcRegs.ADCRESULT1 >>4; // Read value from ADCINB5
// If 128 conversions have been logged, start over
if(ConversionCount == 127)
{
ConversionCount = 0;
}
else
{
ConversionCount++;
}
/*
* Calculating the phaseshift between two bridges
*/
EPwm5Regs.TBPHS.half.TBPHS = phaseshift;
EPwm6Regs.TBPHS.half.TBPHS = phaseshift;
// Re-initialize for next ADC
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clears the interrupt flag bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
}
void InitialADC(void)
{
// Configure ADC
AdcRegs.ADCTRL3.bit.ADCCLKPS = 12; // Set the ADC sampling rate: 25MHz/(2*12+1) = 1MHz
AdcRegs.ADCTRL1.bit.SEQ_CASC = 0; // Cascaded mode
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Continuous conversion mode
AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; // Simultaneous sampling mode
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // ePWM starts SOCA trigger
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0; // One conversion
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 5; // ADCINA5 and ADCINB5
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Interrupt request enabled
}
void InitePWM1(void)
{
// Enable SOCA for ADC measurements
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Generate SOCA pulse at 50% duty cycle
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.TBPRD = 1499; // Set the PWM period time
EPwm1Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count 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.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm1Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Sets pin when CTR=PRD
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clears pin when CTR=COMPA
EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm1Regs.DBCTL.bit.POLSEL = 2; // Active high complementary
EPwm1Regs.DBRED = DT;
EPwm1Regs.DBFED = DT;
}
void InitePWM2(void)
{
EPwm2Regs.TBPRD = 1499; // Set the PWM period time
EPwm2Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Master module
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm2Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Clears pin when CTR=PRD
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Sets pin when CTR=COMPA
EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm2Regs.DBCTL.bit.POLSEL = 2; // Active high complementary
EPwm2Regs.DBRED = DT;
EPwm2Regs.DBFED = DT;
}
void InitePWM5(void)
{
EPwm5Regs.TBPRD = 1499; // Set the PWM period time
EPwm5Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm5Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW;
//EPwm5Regs.TBCTL.bit.
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down-stream module
EPwm5Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm5Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm5Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Clears pin when CTR=PRD
EPwm5Regs.AQCTLA.bit.CAU = AQ_SET; // Sets pin when CTR=COMPA
EPwm5Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm5Regs.DBCTL.bit.POLSEL = 2; // Active high complementary
EPwm5Regs.DBRED = DT;
EPwm5Regs.DBFED = DT;
}
void InitePWM6(void)
{
EPwm6Regs.TBPRD = 1499; // Set the PWM period time
EPwm6Regs.CMPA.half.CMPA = (1499-1)/2;
EPwm6Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down-stream module
EPwm6Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm6Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET; // Sets pin when CTR=PRD
EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clears pin when CTR=COMPA
EPwm6Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm6Regs.DBCTL.bit.POLSEL = 2; // Active high complementary
EPwm6Regs.DBRED = DT;
EPwm6Regs.DBFED = DT;
}


