/* Projekt: maweig-Motor mit Delfino-Launchpad
* Teil: Trip-Steuerung = automatische Abschaltvorkerhungen für PWM
*/
#include "Settings.h"
#include "regdef2.h"
// Define the base quantites
namespace nsBASE{
//const float VOLTAGE = 236.14; // Base peak phase voltage (volt), Vdc/sqrt(3)
const float SHUNT_CURRENT =9.95; // Base peak phase current (amp), Max. measurable peak curr.
const float LEM_CURRENT =12.0; // ----- do -----
//const float TORQUE = // Base torque (N.m)
//const float FLUX = // Base flux linkage (volt.sec/rad)
}
// ****************************************************************************
// Variables for current measurement
// ****************************************************************************
static const float curLimit = 8.0;
// LEM 1.0pu current ==> 12.0A -> 2048 counts ==> 8A -> 1365
// SHUNT 1.0pu current ==> 9.95A -> 2048 counts ==> 8A -> 1647
inline int LEM(float A) {return 2048*A/nsBASE::LEM_CURRENT;}
inline int SHUNT(float A) {return 2048*A/nsBASE::SHUNT_CURRENT;}
// CMPSS parameters for Overcurrent Protection
static const Uint16
clkPrescale = 20,
sampwin = 30,
thresh = 18;
static const Uint16
LEM_curHi = 2048 + LEM(curLimit),
LEM_curLo = 2048 - LEM(curLimit),
SHUNT_curHi = 2048 + SHUNT(curLimit),
SHUNT_curLo = 2048 - SHUNT(curLimit);
// ****************************************************************************
// Flag variables
// ****************************************************************************
MONITOR bool TripFlag; // PWM trip status
MONITOR bool TripFlagClear; // PWM trip clear (from debugger)
// Setup OCP limits and digital filter parameters of CMPSS
static void CMPSS_DIG_FILTER(volatile CMPSS_REGS®s, Uint16 curHi, Uint16 curLo) {
// comparator references
regs.DACHVALS.bit.DACVAL = curHi; // positive max current limit
regs.DACLVALS.bit.DACVAL = curLo; // negative max current limit
// digital filter settings - HIGH side
regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = clkPrescale; // set time between samples, max : 1023
regs.CTRIPHFILCTL.bit.SAMPWIN = sampwin; // # of samples in window, max : 31
regs.CTRIPHFILCTL.bit.THRESH = thresh; // recommended : thresh > sampwin/2
// digital filter settings - LOW side
regs.CTRIPLFILCLKCTL.bit.CLKPRESCALE = clkPrescale; // Max count of 1023 */
regs.CTRIPLFILCTL.bit.SAMPWIN = sampwin; // # of samples in window, max : 31
regs.CTRIPLFILCTL.bit.THRESH = thresh; // recommended : thresh > sampwin/2
}
void Trip::Check() {
// *******************************************************
// Current limit setting / tuning in Debug environment
// *******************************************************
if (BUILDLEVEL>1) {
EALLOW;
// LEM_curHi = 2048 + LEM(curLimit);
// LEM_curLo = 2048 - LEM(curLimit);
// SHUNT_curHi = 2048 + SHUNT(curLimit);
// SHUNT_curLo = 2048 - SHUNT(curLimit);
if (SENSES & bit(LEM_CURRENT_SENSE)) {
CMPSS_DIG_FILTER(Cmpss1Regs, LEM_curHi, LEM_curLo); // LEM - V
CMPSS_DIG_FILTER(Cmpss3Regs, LEM_curHi, LEM_curLo); // LEM - W
}
if (SENSES & bit(SHUNT_CURRENT_SENSE)) {
CMPSS_DIG_FILTER(Cmpss2Regs, SHUNT_curHi, SHUNT_curLo); // SHUNT - V
CMPSS_DIG_FILTER(Cmpss6Regs, SHUNT_curHi, SHUNT_curLo); // SHUNT - U
}
EDIS;
// Check for PWM trip due to over current or over speed
if (!TripFlag) TripFlag = EPwm1Regs.TZFLG.all
|| EPwm2Regs.TZFLG.all
|| EPwm3Regs.TZFLG.all; // Trip on DMC (halt and IPM fault trip )
}
if (TripFlag) {
// if any EPwm's OST is set, force OST on all three to DISABLE inverter
EALLOW;
EPwm1Regs.TZFRC.all = 1<<2;
EPwm2Regs.TZFRC.all = 1<<2;
EPwm3Regs.TZFRC.all = 1<<2;
EDIS;
RunMotor = false;
}
// If clear cmd received, reset PWM trip
if (TripFlagClear) {
TripFlag = false;
TripFlagClear = false;
EALLOW;
// clear OST and DCAEVT1 flags
EPwm1Regs.TZCLR.all = EPwm1Regs.TZFLG.all;
EPwm2Regs.TZCLR.all = EPwm2Regs.TZFLG.all;
EPwm3Regs.TZCLR.all = EPwm3Regs.TZFLG.all;
// clear LLATCH and HLATCH - (not in TRIP gen path)
Cmpss1Regs.COMPSTSCLR.all = 1<<1 | 1<<9;
Cmpss3Regs.COMPSTSCLR.all = 1<<1 | 1<<9;
Cmpss2Regs.COMPSTSCLR.all = 1<<1 | 1<<9;
Cmpss6Regs.COMPSTSCLR.all = 1<<1 | 1<<9;
EDIS;
}
}
// Note that the vectorial sum of d-q PI outputs should be less than 1.0 which
// refers to maximum duty cycle for SVGEN.
// Another duty cycle limiting factor is current sense
// through shunt resistors which depends on hardware/software implementation.
// Depending on the application requirements 3,2 or a single
// shunt resistor can be used for current waveform reconstruction.
// The higher number of shunt resistors allow the higher duty cycle operation
// and better dc bus utilization.
// The users should adjust the PI saturation levels carefully during
// open loop tests (i.e pi_id.Umax, pi_iq.Umax and Umins) as in project manuals.
// Violation of this procedure yields distorted current
// waveforms and unstable closed loop operations which may damage the inverter.
// DMC Protection Against Over Current Protection
static void cmpssConfig(volatile CMPSS_REGS®s, int16 Hi, int16 Lo) {
// Set up COMPCTL register
regs.COMPCTL.bit.COMPDACE = 1; // Enable CMPSS
regs.COMPCTL.bit.COMPLSOURCE = 0; // NEG signal from DAC for COMP-L
regs.COMPCTL.bit.COMPHSOURCE = 0; // NEG signal from DAC for COMP-H
regs.COMPCTL.bit.COMPHINV = 0; // COMP-H output is NOT inverted
regs.COMPCTL.bit.COMPLINV = 1; // COMP-L output is inverted
regs.COMPCTL.bit.ASYNCHEN = 0; // Disable aynch COMP-H ouput
regs.COMPCTL.bit.ASYNCLEN = 0; // Disable aynch COMP-L ouput
regs.COMPCTL.bit.CTRIPHSEL = 2; // Dig filter output ==> CTRIPH
regs.COMPCTL.bit.CTRIPOUTHSEL = 2; // Dig filter output ==> CTRIPOUTH
regs.COMPCTL.bit.CTRIPLSEL = 2; // Dig filter output ==> CTRIPL
regs.COMPCTL.bit.CTRIPOUTLSEL = 2; // Dig filter output ==> CTRIPOUTL
// Set up COMPHYSCTL register
regs.COMPHYSCTL.bit.COMPHYS = 2; // COMP hysteresis set to 2x typical value
// set up COMPDACCTL register
regs.COMPDACCTL.bit.SELREF = 0; // VDDA is REF for CMPSS DACs
regs.COMPDACCTL.bit.SWLOADSEL = 0; // DAC updated on sysclock
regs.COMPDACCTL.bit.DACSOURCE = 0; // Ramp bypassed
// Load DACs - High and Low
regs.DACHVALS.bit.DACVAL = Hi; // Set DAC-H to allowed MAX +ve current
regs.DACLVALS.bit.DACVAL = Lo; // Set DAC-L to allowed MAX -ve current
// digital filter settings - HIGH side
regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = clkPrescale; // set time between samples, max : 1023
regs.CTRIPHFILCTL.bit.SAMPWIN = sampwin; // # of samples in window, max : 31
regs.CTRIPHFILCTL.bit.THRESH = thresh; // recommended : thresh > sampwin/2
regs.CTRIPHFILCTL.bit.FILINIT = 1; // Init samples to filter input value
// digital filter settings - LOW side
regs.CTRIPLFILCLKCTL.bit.CLKPRESCALE = clkPrescale; // set time between samples, max : 1023
regs.CTRIPLFILCTL.bit.SAMPWIN = sampwin; // # of samples in window, max : 31
regs.CTRIPLFILCTL.bit.THRESH = thresh; // recommended : thresh > sampwin/2
regs.CTRIPLFILCTL.bit.FILINIT = 1; // Init samples to filter input value
// Clear the status register for latched comparator events
regs.COMPSTSCLR.bit.HLATCHCLR = 1;
regs.COMPSTSCLR.bit.LLATCHCLR = 1;
}
static void InitPwmTrip(volatile EPWM_REGS®s,Uint16 tzsel) {
regs.DCTRIPSEL.all = 3<<0; // Digital Comparator A High Input kommt von TripIn 4
regs.TZDCSEL.all = TZ_DCAH_HI<<0; // Digital Comparator A Event 1 Select: DCAH==H && DCAL=x
regs.DCACTL.all = DC_EVT_ASYNC<<1; // asynchron
regs.TZSEL.all = tzsel;
regs.TZCTL.all= TZ_FORCE_HI<<0 | TZ_FORCE_HI<<2; // Ausgang A und B auf HIGH wenn One-Shot-Trip kommt
regs.TZCLR.all = 1<<2 | 1<<3; // Clear any spurious OV trip
}
void Trip::InitAll() {
// Digitale Eingänge für das Abschalten der PWM bereitstellen
configGpioIn(14,false); // mit Eingangsinvertierung und Pullup
configGpioIn(24,false); // TODO: Erst mal low-aktiver Trip damit der Eingang offen bleiben kann
// GpioCtrlRegs.GPAINV.all |= bit(14)|bit(24); // High = PWM Stop
// GpioCtrlRegs.GPAPUD.all &=~(bit(14)|bit(24)); // offener Eingang = PWM Stop
InputXbarRegs.INPUT1SELECT = 24; // Select GPIO24 as INPUTXBAR1 = !TZ1 for tripping PWM1..3
InputXbarRegs.INPUT2SELECT = 14; // Select GPIO14 as INPUTXBAR2 = !TZ2 for tripping PWM4..6
if (BUILDLEVEL>1) {
//Clearing the Fault(active low), GPIO41,
// Configure as Output
// GpioCtrlRegs.GPBPUD.bit.GPIO41 = 1; // disable pull ups
// GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 0; // choose GPIO for mux option
configGpioOut(41);
GpioDataRegsA.doSET(41);
// GpioCtrlRegs.GPBDIR.bit.GPIO41 = 1; // set as output
// GpioDataRegs.GPBSET.bit.GPIO41 = 1;
// LEM Current phase V(ADC A2, COMP1) and W(ADC B2, COMP3), High Low Compare event trips
if (SENSES & bit(LEM_CURRENT_SENSE)) {
// LEM_curHi = 2048 + LEM(curLimit);
// LEM_curLo = 2048 - LEM(curLimit);
cmpssConfig(Cmpss1Regs, LEM_curHi, LEM_curLo); //Enable CMPSS1 - LEM V
cmpssConfig(Cmpss3Regs, LEM_curHi, LEM_curLo); //Enable CMPSS3 - LEM W
}
if (SENSES & bit(SHUNT_CURRENT_SENSE)) {
// Shunt Current phase V(ADC A4, COMP2) and W(ADC C2, COMP6), High Low Compare event trips
// SHUNT_curHi = 2048 + SHUNT(curLimit);
// SHUNT_curLo = 2048 - SHUNT(curLimit);
cmpssConfig(Cmpss2Regs, SHUNT_curHi, SHUNT_curLo); //Enable CMPSS2 - Shunt V
cmpssConfig(Cmpss6Regs, SHUNT_curHi, SHUNT_curLo); //Enable CMPSS6 - Shunt U
}
// Configure TRIP 4 to OR the High and Low trips from both comparator 1 & 3
EPwmXbarRegs.TRIP4MUX0TO15CFG.all = bit(0) | bit(4) | bit(2) | bit(10) | bit(3);
EPwmXbarRegs.TRIP4MUX16TO31CFG.all = 0;
// Enable Muxes for ored input of CMPSS1H and 1L, i.e. .1 mux for Mux0
// MUX0 = 1; //cmpss1 - tripH or tripL
// MUX4 = 1; //cmpss3 - tripH or tripL
// MUX2 = 1; //cmpss2 - tripH or tripL
// MUX10 = 1; //cmpss6 - tripH or tripL
// MUX3 = 1; //inputxbar2 trip
// Enable Mux 0 OR Mux 4 to generate TRIP4
EPwmXbarRegs.TRIP4MUXENABLE.all = bit(0) | bit(4) | bit(2) | bit(10) | bit(1);
}
InitPwmTrip(EPwm1Regs,1<<14 | 1<<0 | 1<<5); // Bit 14: DCAEVT1 = Quelle für Dauer-Aus
InitPwmTrip(EPwm2Regs,1<<14 | 1<<0 | 1<<5); // Bit 8: TZ1 (GPIO24) = Quelle für Dauer-Aus
InitPwmTrip(EPwm3Regs,1<<14 | 1<<0 | 1<<5); // Bit 5: TZ6 = Quelle für Zyklus-Aus
InitPwmTrip(EPwm4Regs,1<<14 | 1<<1 | 1<<5); // Bit 14: DCAEVT1 = Quelle für Dauer-Aus
InitPwmTrip(EPwm5Regs,1<<14 | 1<<1 | 1<<5); // Bit 9: TZ2 (GPIO14) = Quelle für Dauer-Aus
InitPwmTrip(EPwm6Regs,1<<14 | 1<<1 | 1<<5); // Bit 5: TZ6 = Quelle für Zyklus-Aus
// What do we want the OST/CBC events to do?
// TZA events can force EPWMxA
// TZB events can force EPWMxB
}
Detected encoding: ASCII (7 bit) | 8
|