Part Number: TMS320F28377D
Hello,
In my application, I want to synchronize and send SCI data between 2 to 3 DSPs (one per phase of an inverter). Thus far I only have 2 DSP modules and each one is operated by an independent debugger, yet, I connected TX (DSP1) and RX (DSP2) pins of SCI to enable communication and ECAP1SYNCOUT (through output Xbar2 of DSP1) to EXTSYNCIN1 (through input Xbar5) to receive a pulse that would synchronize all ePWMs and eCAP1_APWMs of both DSPs at the software command of EPWM1_SWSYNC from DSP 1.
The problem I have is that for some reason I cannot figure out yet, the PLLSYSCLK seems to vary randomly at some point after resetting and restarting the debugger. Given my settings PLLSYSCLK = 200 MHz, which yields 5ns of the period. In some cases, with my PRD settings for the EPWMs and APWMs, I obtain the desired periods of 10 us for EPWMS and 16.666ms for APWMs. However, without any change of the same code, suddenly, the periods I obtain get quite large, which from my calculations correspond to having a PLLSYSCLK = 5 MHz which does not make sense. Basically, sometimes it seems to be okay with 5ns period and some other times wring with 200ns.
Could this be a problem of connecting both digital grounds of DSP1 and DSP2, as I am doing now? Is there any mechanism I am not aware of that will force the clock to run at such a low speed? What could be the best way to connect 2 DSP modules and have them synchronized as I want?
Here I place some parts of my code for the receptor (DSP2):
---------------------------------------------------------------------
section from main()
// Configurations for peripherals
ConfigureEPWM();
ConfigureECAP();
scid_init2();
SetupSDFM();
ledInitGpio();
// enable PIE interrupt PLLSYSCLKDIV
IER |= M_INT3; //Enable group 3 interrupts for EPWM1
IER |= M_INT8; //Enable group 8 interrupts for SCI_RX
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //3.1 EPWM1
PieCtrlRegs.PIEIER8.bit.INTx7 = 1; // 8.7 SCI_RX
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// peripheral clock initialization
EALLOW;
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 1; // SYSCLK = 200 MHz (400/2)
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; // 0: SYSCLK , 1:SYSCLK/2 (EPWMCLK max = 100 MHz)
EDIS;
---------------------------------------------------------------------------------
APWM configuration:
void ConfigureECAP(void)
{
EALLOW;
CpuSysRegs.PCLKCR3.bit.ECAP1 = 1; // ECap1 clock enabled
// Set Output_Xbar2 to pin GPIO37
GpioCtrlRegs.GPBGMUX1.bit.GPIO37 = 0;/// output APWM
GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 1;
// MUX ECAP1OUT to XBar2
OutputXbarRegs.OUTPUT2MUX0TO15CFG.bit.MUX0 = 3; // squarewave out to measure fundamental frequency
OutputXbarRegs.OUTPUT2MUXENABLE.bit.MUX0 = 1;
EDIS;
ECAP_PRD = 3333333; //16.6666 ms period
ECAP_CMP = 1666667;
ECAP_PHS = 1111111; // +120 deg phase = 1111111 ; -120 deg phase = 2222222
//////////////////////////////ECAP as APWM///////////////////////////////////////
ECap1Regs.CAP1 = ECAP_PRD; /// Period register
ECap1Regs.CAP2 = ECAP_CMP; /// compare register
ECap1Regs.CAP3 = ECAP_PRD; /// Period register
ECap1Regs.CAP4 = ECAP_CMP; /// compare register
ECap1Regs.CTRPHS = ECAP_PHS; /// counter phase
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; /// counter stopped
ECap1Regs.ECCTL2.bit.APWMPOL = 0; /// active high operation
ECap1Regs.ECCTL2.bit.CAP_APWM = 1; /// APWM mode operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; /// Enable phase loading on synchronization event
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 3; /// Synchronization output disabled
}
--------------------------------------------------------------------------------------------------
EPWM configuration:
void ConfigureEPWM(void)
{
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
InitEPwm4Gpio();
InitEPwm5Gpio();
InitEPwm6Gpio();
InitEPwm7Gpio();
InitEPwm8Gpio();
InitEPwm9Gpio();
InitEPwm10Gpio();
EALLOW;
// enable clocking (CLK setting for acheiving TBPRD:1000 = 10us = 100 kHz)
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // System clock stops
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // EPWM1 clock enabled
// enable buffer to bypass 3.3V to 5V conversion in external chip
GpioCtrlRegs.GPCMUX2.bit.GPIO81 = 0; // Configure as I/O BUF_A
GpioCtrlRegs.GPCDIR.bit.GPIO81 = 1; // 1 = output
/// Configure GPIO58 for Sync in Input
GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;
GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 0;
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0; // Configure GPIO58 as Sync In pin
GpioCtrlRegs.GPBDIR.bit.GPIO58 = GPIO_INPUT;
GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = GPIO_ASYNC;
////////// SYNC IN selection///////
InputXbarRegs.INPUT5SELECT = 58;//Xbar1 pin works as ExtSyncIn1(marked as SIMO GPIO58)
SyncSocRegs.SYNCSELECT.bit.ECAP1SYNCIN = 5; ///Sync input source: ExtSyncIn1
SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 5; ///Sync input source: ExtSyncIn1
SyncSocRegs.SYNCSELECT.bit.EPWM7SYNCIN = 5; ///Sync input source: ExtSyncIn1
SyncSocRegs.SYNCSELECT.bit.EPWM10SYNCIN = 5; ///Sync input source: ExtSyncIn1
EDIS;
PWM_A_BUF_ENA;
EPWM_TBPRD_ISR = 1000; // Interrupt routine frequency: 100 kHz (1000 = 10us)
TBPRD_HIGH = 100; // 100 = 1us = 1000kHz
EPWM_InitCMPA = 500;
EPWM_InitCMPB = 500;
////////////// EPWM1 configuration for ISR ///////////////////////////////////////
EPwm1Regs.TBPRD = EPWM_TBPRD_ISR-1; // sampling period set 1000 = 10us (100 kHz) f=f_clk/(TBPRD+1) // before f=99.9 kHz
EPwm1Regs.TBCTL.bit.CTRMODE = TB_FREEZE; // freeze counter
EPwm1Regs.TBCTL.bit.PHSEN = 0; // Enable phase loading from Phase Reg at Sync event
EPwm1Regs.TBCTL.bit.PHSDIR = 1; // count-up after sync event occurs
EPwm1Regs.TBPHS.all = 0; // Start from 0 at Sync event
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable ePWM1 interrupt
EPwm1Regs.ETSEL.bit.INTSEL = 1; // Enable ePWM1 interrupt when TBCTR=0
EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate interrupt on 1st event of INTSEL
EPwm1Regs.ETPS.bit.INTPSSEL = 0; // Frequency of event are between 0 - 3 (1st event this case)
EPwm1Regs.ETCLR.bit.INT = 1; // Enable further interrupts
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT= 100 MHz
// Setup shadow register load on ZERO
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow/buffer mode enabled
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load Buffer to CMPA/B register when TBCTR=0
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values (Initial value)
EPwm1Regs.CMPA.bit.CMPA = EPWM_InitCMPA; // Set Compare A value (50%)
EPwm1Regs.CMPB.bit.CMPB = EPWM_InitCMPB; // Set Compare B value
// Set actions
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM2B to high when CTR meet zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM2B to low when CTR meet CMPA on upcount
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM2B to high when CTR meet zero
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM2B to low when CTR meet CMPA on upcount
.
.
.
.
}
--------------------------------------------------------------------------------------------------------------------
Both DSPs have nearly the same configuration with the only difference of Xbars to allow send/receive Sync Events and SCI pins. Also, both experience the same problem mentioned above. DSP1 uses XDS100v2 and DSP2 uses the XDS110 probe for debugging. I hope someone can help me solve this issue,
Thank you very much,
Bryan