Part Number: TMS320F28379D
Tool/software: Code Composer Studio
Dear all,
I'm trying to configure the TMS320F28379D PWM generator, but I can't get the desired behavior. Let me describe how I configured a PWM channel:
1. PWM channel is configured to operate at 20 kHz (50 us) frequency in up-down-count mode.
2. PWM channel needs to work in a complementary mode, i.e. B output is inverted A output. A and B are outputs of a PWM channel.
3. Dead-time needs to be inserted on the rising edge for both PWM channels, and it should not be inserted on the falling edge. I'm not sure if I did this properly. According to Figure 14-33. Configuration Options for the Dead-Band Submodule, pp. 1717/2668, in Technical Reference Manual - SPRUHM8G, it seems that this can be achieved in four ways:
(3-1) OutA = PWMxA, OutB = PWMxA***, where PWMxA*** is delayed (both falling and rising edge) and inverted PWMxA signal
(3-2) OutA = PWMxB***, OutB = PWMxB, where PWMxB*** is delayed (both falling and rising edge) and inverted PWMxB signal
(3-3) OutA = PWMxA*, OutB = PWMxA**, where PWMxA* is delayed (rising edge) PWMxA, and PWMxA** is delayed (falling edge) and inverted PWMxA signal
(3-4) OutA = PWMxB**, OutB = PWMxB*, where PWMxB* is delayed (rising edge) PWMxB, and PWMxB** is delayed (falling edge) and inverted PWMxB signal
There are few other similar possibilities due to the OUTSWAP bits, but the problem remains the same. What is the problem? Well the problem is that in all dead-band modes only one signal, PWMxA or PWMxB, is used as a source to generate both outputs. You will see why is this a problem in bullet 4.
4. I want to be able to manually disconnect PWM channels from the output, but the PWM channel should still be running, because I use PWM as a source for ADC trigger and some other stuff. Now there is AQCSFRC register with CSFB and CSFA bits to force PWMxA and PWMxB to a certain state, without having to stop the PWM module clock. However, this register comes before the dead-band submodule, which means that it affects PWMxA and PWMxB on the input of the dead-band submodule. If you consider for example that OutA = PWMxA and OutB = PWMxA***, it is obvious that CSFB does not affect OutB, which means that if I force a high or low state on OutA = PWMxA using CSFA, the OutB will be in the opposite state of OutA.
Question is: How should I approach this? Is there any other way to configure dead-band generator to get the dead-time insertion, and to be able to use AQCSFRC to force both PWMxA and PWMxB to low state when needed? Or if this is not an option, what should I use to "disconnect PWM from GPIO"? Should I reconfigure GPIO directly (I don't like this approach)?
Here is my function used to configure a PWM channel.
void Inverter_InitEPwm(volatile struct EPWM_REGS *EPwmRegs)
{
// The ePWM time base clock is determined by the following
// parameters: EPWMCLK, CLKDIV, and HSPCLKDIV
// EPWMCLK = PLLCLK/EPWMCLKDIV (200 MHz)
// TBCLK = EPWMCLK/(HSPCLKDIV*CLKDIV) (200 MHz)
// Action qualifier continuous S/W force register
//EPwmRegs->AQCSFRC.bit.CSFB = 0b01; // Forces a continuous low on output B
//EPwmRegs->AQCSFRC.bit.CSFA = 0b01; // Forces a continuous low on output A
// Time base control register (1)
//EPwmRegs->TBCTL.bit.FREE_SOFT = 0b11; // Free run (#update)
EPwmRegs->TBCTL.bit.PHSDIR = 0b1; // Count up after a synchronization event
EPwmRegs->TBCTL.bit.CLKDIV = 0b000; // Time base clock prescale: /1
EPwmRegs->TBCTL.bit.HSPCLKDIV = 0b000; // High speed time base clock prescale: /1
EPwmRegs->TBCTL.bit.SYNCOSEL = 0b01; // Sync output select: TBCTR=0x00
EPwmRegs->TBCTL.bit.PRDLD = 0b0; // The TBPRD is loaded from its shadow register when TBCTR=0x00
EPwmRegs->TBCTL.bit.PHSEN = 0b0; // Do not load the TBCTR from TBPHS
EPwmRegs->TBCTL.bit.CTRMODE = 0b10; // Counter mode: up-down-count mode
// Time base control register (2)
EPwmRegs->TBCTL2.bit.PRDLDSYNC = 0b00; // Shadow to active load of TBPRD occurs only when TBCTR=0x00
// Counter compare control register (1)
EPwmRegs->CMPCTL.bit.LOADBSYNC = 0b00; // Shadow to active CMPB:CMPBHR occurs according to LOADBMODE bits
EPwmRegs->CMPCTL.bit.LOADASYNC = 0b00; // Shadow to active CMPA:CMPAHR occurs according to LOADAMODE bits
EPwmRegs->CMPCTL.bit.SHDWBMODE = 0b0; // Shadow mode is used for CMPB:CMPBHR registers
EPwmRegs->CMPCTL.bit.SHDWAMODE = 0b0; // Shadow mode is used for CMPA:CMPAHR registers
EPwmRegs->CMPCTL.bit.LOADBMODE = 0b00; // Load CMPB:CMPBHR on TBCTR=0x00
EPwmRegs->CMPCTL.bit.LOADAMODE = 0b00; // Load CMPA:CMPAHR on TBCTR=0x00
// Dead-band generator control register (1)
EPwmRegs->DBCTL.bit.HALFCYCLE = 0b0; // The dead-band counters are clocked at the TBCLK rate
EPwmRegs->DBCTL.bit.DEDB_MODE = 0b0; // not used
EPwmRegs->DBCTL.bit.OUTSWAP = 0b00; // PathA->OutA, PathB->OutB
EPwmRegs->DBCTL.bit.SHDWDBFEDMODE = 0b0; // Shadow register is not used for DBFED register
EPwmRegs->DBCTL.bit.SHDWDBREDMODE = 0b0; // Shadow register is not used for DBRED register
EPwmRegs->DBCTL.bit.IN_MODE = 0b00; // EPWMxA is source for falling- and rising-edge delay
EPwmRegs->DBCTL.bit.POLSEL = 0b10; // EPWMxB is inverted EPWMxA
EPwmRegs->DBCTL.bit.OUT_MODE = 0b11; // DBM is fully enabled (both RED and FED)
// Action qualifier control register for output A
EPwmRegs->AQCTLA.bit.CAD = 0b10; // Force ePWMxA to high (down-count)
EPwmRegs->AQCTLA.bit.CAU = 0b01; // Force ePWMxA to low (up-count)
// Dead-band generator rising edge delay
// In up-down-count mode:
// Tdly = (DBRED+DBFED)/(2*TBCTR)*TBCLK (2.5 us)
EPwmRegs->DBRED.bit.DBRED = 250;
EPwmRegs->DBFED.bit.DBFED = 250;
// Time base counter register
EPwmRegs->TBCTR = 0x0000; // Clear counter
// Time base period register
// Up-count or down-count mode: TPWM = (TBCPRD+1)*TBCLK
// Up-down-count mode: TPWM = (2*TBCTR)*TBCLK
EPwmRegs->TBPRD = 5000; // PWM period (50 us)
// Counter compare A register
EPwmRegs->CMPA.bit.CMPA = 0; // Duty-cycle of ePWMxA output
}