This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EPWM-TB-Reset CTR=PRD

Guru 55913 points
Part Number: LAUNCHXL-F280049C
Other Parts Discussed in Thread: C2000WARE

CCS debug register CMPA 32 bit integer view memory mapped value of match counts are very high from 24 bit wide bus TBCTR up/down counts:

Condition 1: TB is not being reset on TBD counts. And CMPA match counts via bits (31:16) do not cause TB ctr_MAX status bit toggles, when CMPA matches occur below TBCTR=0xFFFF.

Undocumented errata seems to be present in EPWM type 4 module, silicon revision 3. 

1. Would a proper WA be to also leverage AQ sub module (CTR=PRD (Priorty 6)) as to augment (CTR=CMPA (Priority 5)) action qualifier in the event TB reset fails to toggle for preset TBD periods?

2. Would adding the second AQ then trim down an overflowing TB counts occurring presumably in the 24 bit decade counter chain of TB sub-module? 

Effect 1: Ignoring 24 bit wide TB counts masked via 16 bit tool chain registers seem to have unintended consequences of excessively long PWM cycles of TBD fixed periods.

Void of Action Event: TB module counter chain seems to overflow and reset is not clearing TBCTR counts upon CTR=PRD.

  

  • Hi,


    Condition 1: TB is not being reset on TDB counts. And CMPA match counts via bits (31:16) do not cause TB ctr_MAX status bit toggles, when CMPA matches occur below TBCTR=0xFFFF.

    I'm not sure i understand some of the acronyms in your question. what is TDB counts? what is ctr_MAX status?
    Why do you expect CMPA match to cause TB ctr_MAX?


    1. Would a proper WA be to also leverage AQ sub module (CTR=PRD (Priorty 6)) as to augment (CTR=CMPA (Priority 5)) action qualifier in the event TB reset fails to toggle for preset TBD periods?

    You mean, you would want to configure CTR=PRD with same action as CTR=CMPA? 
    TB reset, I presume you mean CTR=PRD, will occur when counter increments to period value. What failure condition are you referring to?
    What is WA?

    2. Would adding the second AQ then trim down an overflowing TB counts occurring presumably in the 24 bit decade counter chain of TB sub-module? 

    which 24-bit counter are you referring to? Timebase counter is 16-bits only.

  • Hello,

    what is ctr_MAX status?
    Why do you expect CMPA match to cause TB ctr_MAX?

    The max TBCTR count register status flag, if count ever = 0xFFFF MAX bit is set. TBD is used as a short for time base period in EWPM-A/B generated wave form figures. Work around, WA.

    which 24-bit counter are you referring to? Timebase counter is 16-bits only.

    X49c datasheet EPWM type 4 are noted 24 bit TBCTR register, (+8) for TBPRD Active register. 32 bit wide internal bus (uint32_t) to transport 24 bit counts from TBCTR bits 23:0, (not 15:0), when CMPA low register is bits (31:16).  There is no earthy way to get 24 bit count into a 16 bit bus and 16 bit counts can not latch 24 bit match compares, unless CMPA is 24 bits wide on TBCTR side. The TB module figures are not correct, /16 should be /24, then (-8) allow 16 bit low resolution TBCTR counts into 24 bit input CMPA, (-8) bits (15:0) for these matches, not 31:16.

    The TBCTR is in perpetual overflow viewed via 32 bit memory mapped value CCS debug. Reset is not clearing the count when CTR=PRD (red boxes) reaches 2500 count (reload), yet the period is spot on count. We have no way to verify reset running count ever happens but can see it often exceeds 16 bits via CCS debug. CMPA is latching the high order 16 bits in 24 bit counter chain on a 32 bit wide internal bus not 16 bit wide. Tool chain is masking TBCTR 32 bit wide bus via 16 bit register memory mapped location that is not aligned with the true count value.  

             /* set comparator load mode, shadow CMP-A */
             EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt],
    											  EPWM_COUNTER_COMPARE_A,
    											  EPWM_COMP_LOAD_ON_CNTR_PERIOD);//CTR=PRD

  • To make matters worse CMPA was memory mapped as high order bits (31:16), TBCTR bus structure shown to exist bits (15:0). So the load count TBCTR multiplies by 16 bits, via 32 bit CMPA/CMPAHR register pair.

    Seemingly if CCSM Reset did assert (CTR=PRD) then counts in register TBCTR can never exceed TB shadow load value. Using a 16 bit memory mapped register seems to mask foreground count events not the actual decade counter chain inside counter compare sub module (CCSM).

    Have also tried to assert  ACQSM TBCTL OR gate via EPWM1 Synchi events to trigger CCSM reload count Reset but it too fails. The PHSEN was made enabled (EPWM1) to allow the SW event and EPWM2/3 CMPA are linked. Perhaps CMPA register was memory mapped bits (31:16) as a WA but appears to causes millisecond voids after/before several PWM cycles. 

    Asserting reset should reload the pulse width PRD count when ever 2500 load count is reached?

  • Hi,


    So the load count TBCTR multiplies by 16 bits, via 32 bit CMPA/CMPAHR register pair.

    TBCTR increments up to TBPRD value. It doesn't multiply and it has nothing to do with CMPA/HR configuration.


    The TBCTR is in perpetual overflow viewed via 32 bit memory mapped value CCS debug.

    Did you try to read it from the CPU instead of viewing in the debugger? Is the PWM output getting generated as expected?


    Could you share your configuration code and PWM output waveforms where you are noticing a problem?
    If possible, please what is the PWM output you are trying to generate and where you are running into issues with the PWM generation.
    It would be even better if you start with some of the examples provided in C2000Ware and experiment with those configurations first.

    it'll be easier to debug one step at a time. First have the TBCTR issue resolved as timebase is fundamental to PWM generation.
    You can remove all other configuration and just have the TBCTR running and check via CPU read as well that it's not perpetually staying at 0xFFFF.

  • TBCTR increments up to TBPRD value. It doesn't multiply and it has nothing to do with CMPA/HR configuration.

    No but it has to do with CMPA being loaded Bits 31:16 when it is documented Bits 15:0. If  TB module is not resetting or resetting high in the count the duty cycle will exceed 100% as CMPA value is >TBPRD.  Somebody at TI has changed the tool chain counter intuitive to the documented TRM datasheet figures. Again we can't put 24 bits into a 16 bit pipe without some kind of compression write/read HW. The TBCTR 24 bit count at CMPA and 100% duty cycle seems to indicate TB reset fails due to high order bit matches, binary count values >16 bits.  

    Use up-down-count mode to generate a symmetric PWM:
    • If you load CMPA/CMPB on zero, then use CMPA/CMPB values greater than or equal to 1.
    If you load CMPA/CMPB on period, then use CMPA/CMPB values less than or equal to TBPRD-1.
    This means there will always be a pulse of at least one TBCLK cycle in a PWM period which, when very short, tend to be ignored by the system.

    Could you share your configuration code and PWM output waveforms where you are noticing a problem?
    If possible, please what is the PWM output you are trying to generate and where you are running into issues with the PWM generation.
    It would be even better if you start with some of the examples provided in C2000Ware and experiment with those configurations first.

    This 100% duty condition CMPA is occurring via motor SDK motion sensorless FOC applications V2.01 to V3.01. There 384µs EPWM interrupt load (main_ISR) loop loads CMPA. The resulting current waveform has DC 1/2 wave pulses mixed AC full wave and 100% duty 170ms periods.

     Note 100% duty CH2 should have pulse train 50µs periods regulated by PI speed controller. It tries but the dead band generator output is 100% duty indicates EPWM ignores the PI controller to fully control CMPA, since TBCTR value seems to exceed TBPRD in 32 bit view only.

    First have the TBCTR issue resolved as timebase is fundamental to PWM generation.
    You can remove all other configuration and just have the TBCTR running and check via CPU read as well that it's not perpetually staying at 0xFFFF.

    Can you please explain logic why CMPA location was moved x49c tool chain from bits (15:0) up to bits (31:16)? Fact move CMPA was done is a clue it may adversely cause TB reset failure as I explained many times. What other reason could there have been to move CMPA binary location, especially CMPAHR is documented x49 datasheet bits (15:0 +8) = bits (23:0)?

  • BTW:

    The point of CCS real time debug memory mapped set (uint_32t) was to show TBCTR counts exceed (uint16_t) tool chain mask of CMPA register view. We cant stop the counter incrementing >TB unless reset of CCSM occurs in overflow counts.

    In my mind this scenario seems to explain 170ms 100% dutycycle periods in capture CH2. The dead air time makes no sense to me as it relates to proper SVM space vector modulation. I don't see any timing issues in SW that may lead to 100% duty but the HW is ringing a loud bell in my opinion.

  • Hi,

    I believe the confusion may be because you are viewing CMPA:HR as one 32-bit number, but TBCNT is 16 bit.
    For the Counter Compare sub-module only CMPA 16-bits (no HR) is used for comparison with TBCNT 16 bits.
    The high resolution part can be treated as a fractional component. It doesn't come in the path of counter comparison.
    Regarding the SDK motion sensorless FOC applications V2.01 to V3.01 changes, i'll loop in the SDK experts.

  • Yet again CMPA register is not at 15:0, it was moved to bits 31:16 and CMPAHR bits 15:0 per x49c tool chain variant CCS project build. I could understand memory mapped 32 bit value being part of next register but that seems a stretch for CMPA register view.

    I captured CMPA load changes below and the SDK match count loads CMPA are not a problem as it seems. Hard to imagine 170ms PWM voids are caused by calculations (yellow box) for next period CMPA match events. The values are not deviating match count loads around 1250 by only very small duty cycle changes, assume from the PI speed controller.

  • Yes CMPA is bits 31-16.

  • Yes CMPA is bits 31-16

    You have stated this several times thus repeating the same nonsense shown in Fig.18-129. Analysis figures of CCSM shows register bus bits  15:0 +8. This is where CMPA should be in the tool chain x49 variant or change the CCSM datasheet and TRM figures to show 31:16 CMPA, (+8) CMPAHR.

    If we can't believe what was technical and factual disclosure, all logical deduction is lost for trouble shooting perceived and odd timing issues.

    Perhaps this figure needs to be updated:

  • The CMPA[15:0] shown in the diagram is referring to:

    CMPA (32 bits):

    -- CMPA (16 bits - [31-16])

    -- CMPAHR (8 bits - [15-8])

    The register CMPA[31-16] == the diagram CMPA[15:0]

  • How that be correct a physical data bus or address bus does not shift up by 16 bits without a bus arbiter or MUXing, neither one exists according to the TRM and datasheet. I have never seen 16 bit data bus shifting in any TI MCU family for CCS debug register view via JTAG. 

    Yet the real time debug CMPA shadow value is not changing when the match count is updated via SW? We only see CMPA shadow full status bit toggling every so often.

    Our other TI PWM modules CCS debug XDS100v2 debug and we see updates CMPA/B registers, as 10Hz match values. All we can see x49c in CCS real time register view is CMPA bits 31:0 TBCTR count changes. That is no real time silicon confirmation of match counts occurring at the correct TBCTR count value. Whats the point of CCS debug real time silicon view of x49c registers if there is no way to see them change value even at 10Hz?

  • We dont show those internal connections in the TRM...

  • Who is going to believe CMPA matches occur against TBCTR 15:0 when the register exists data bus 31:16 without any support evidence? TI should not expect anyone with microprocessor bus structure knowledge to accept incomplete points not being depicted in technical references.

    Again the shadow value is not changing CMPA drill down often is blank, making it even more plausible the memory address offsets into TBCTR higher integer counts 31:0 somehow delay TBCTR reset. This seems to occur more in EPWM1 Master zero load events and duty cycle CMPA is much wider by +10µs with very different locked shadow values of CMPA in both Synco/Synci slaves loaded every 328µs. Perhaps 328µs interrupt service routine is to fast for x49c EPWM module locks CMPA shadow registers?

    The values of all 3 CMPA are to be nearly the same and cycling for each 10Hz silicon read. The Master/slave shadow values CMPA to compare with TBCTR 31:0 do not move! Perhaps you believe CMPA register bits (31:0) are the match value when it is actually the TBCTR count value.

  • TBCTR is also 16bits wide.

  • Have any idea why shadow values CMPA are not incrementing inside register drill downs EPWM1,2,4? Seems though only the first CMPA match count remains persistent and no updates are being loaded. 

  • Do you have the continuous refresh on in CCS?

  • Yep and still no shadow updates occur after the first load. Yet the duty cycles EPWM-1 >10µs greater over EPWM-2, EPWM-4 being loaded with the same CMPA shadow values.

    Noticing again capture shows CMPA drill down (15:0) yet the memory mapped region (31:16), only cell showing updates. Sometimes expanding the drop down when blank clicking on the memory mapped cell locks GUI, have to kill CCS. Switching between register and Expressions view truncates/blanks the previous CMPA register drill down of any EPMW, CCS 9.3 updated. That blanking of register cells was occurring in earlier CCS versions without real time silicon being enabled.

  • What you see in the register view IS THE SHADOW register.

    The active register is internal and you have no way of viewing it.

    Nima

  • Seemingly CMPA shadow load value is locking or jamming CMPA on EPWM1, EPWM2, EPWM4 according to values printed and being over loaded. Obviously CMPA shadow jammed leaving the last lower values to control duty cycle. When first drilling down CMPA register a few low value shadow matches show up then they stop updating. Unsure the values shown below are exactly what jams CMPA shadow values.  

    Also added ASM delay (10U) after each CMPA load to slow loop down. Oddly EPWM1 is cycling 10µs greater duty cycle than are EPWM2 and EPWM4 though 3 CMPA are loaded with the very same value by SDK FOC software. CCS debug register view shows 3 different locked shadow values. 

  • What is your shadow to active load trigger for CMPA?

  •  ADC trigger via CMPD count 5. 

        // setup the Event Trigger Selection Register (ETSEL)
        // COMPD-DN=5 or SOC_TBCTR=0
        EPWM_disableInterrupt(obj->pwmHandle[0]);
        EPWM_setADCTriggerSource(obj->pwmHandle[0],
                                 EPWM_SOC_A,
    							 EPWM_SOC_TBCTR_D_CMPD); //PWM_SOC_TBCTR_ZERO
    
        EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A);
    
        // setup the Event Trigger Prescale Register (ETPS)
        if(numPWMTicksPerISRTick > 15)
        {
            EPWM_setInterruptEventCount(obj->pwmHandle[0], 15);
            EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_A, 15);
        }
        else if(numPWMTicksPerISRTick < 1)
        {
            EPWM_setInterruptEventCount(obj->pwmHandle[0], 1);
            EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_A, 1);
        }
        else
        {
            EPWM_setInterruptEventCount(obj->pwmHandle[0], numPWMTicksPerISRTick);
            EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0],
                                            EPWM_SOC_A,
                                            numPWMTicksPerISRTick);
        }
    
        // setup the Event Trigger Clear Register (ETCLR)
        EPWM_clearEventTriggerInterruptFlag(obj->pwmHandle[0]);
        EPWM_clearADCTriggerFlag(obj->pwmHandle[0], EPWM_SOC_A);
        
        // setup the Event Trigger Clear Register (ETCLR)
        EPWM_clearEventTriggerInterruptFlag(obj->pwmHandle[0]);
        EPWM_clearADCTriggerFlag(obj->pwmHandle[0], EPWM_SOC_A);
    
        // since the PWM is configured as an up/down counter, the period register is
        // set to one-half of the desired PWM period
        // Note: Shadow of TB period register is configured above.
        EPWM_setTimeBasePeriod(obj->pwmHandle[0], halfPeriod_cycles); //1250
        EPWM_setTimeBasePeriod(obj->pwmHandle[1], halfPeriod_cycles); //1250
        EPWM_setTimeBasePeriod(obj->pwmHandle[2], halfPeriod_cycles); //1250
    
        /* Set the shadow period load mode to occur on counter zero flag */
        EPWM_selectPeriodLoadEvent(obj->pwmHandle[0], EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
        EPWM_selectPeriodLoadEvent(obj->pwmHandle[1], EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
        EPWM_selectPeriodLoadEvent(obj->pwmHandle[2], EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
    
        // write the PWM data value for ADC trigger 10ns SYSCLK 50ns
        EPWM_setCounterCompareValue(obj->pwmHandle[0],
    								EPWM_COUNTER_COMPARE_D, //EPWM_COUNTER_COMPARE_C
                                    5);

    Coincidentally 81,936,384 = (0x04E2.4000) CMPA shadow match value added 15:0 word (0x4000) when it should not. The shifting of CMPA data to bits (31:16) via HWREG (15:0 +1U) somehow adds (0x4000). I've seen it show up in the memory address space 15:0 from time to time but never thought it was persistent. That reveal 32 bit integer reads memory address space, where 16 bit reads masks the lower Word 15:0 and we never see 0x4000 part. It seemingly isn't part of the next serial word being ASCII printed 

  • Also some registers of certain TI silicon family have issues with C++ B2B writes. Datasheet TM4C1294 warns some WR1C registers may require delay between B2B writes or preform a read after write operation to avoid issues.

    The decimation time of the interrupt handler calling CMPA shadow load events was measured 328µs, entry to exit. Seemingly not to fast thought instruction decode and R/W accumulator operations occur much faster, often several microseconds for 100mHz SYSCLK.      

  • Do you have optimization turned on when using driverlib? Thats key for cycle count using driverlib.

  • Description Resource Path Location
    Current optimization/debug settings: --opt_level=2 --opt_for_speed=2 -g is07_speed_control properties

    I also added code check for shadow full flag prior to CMPA writes and got a few buffered writes to scroll by, then it locks again. The oddest part is EPWM1 was configured to count interrupts then used the ADC interrupt source for the handler. This interrupt method for Instaspin was documented to use PWM interrupt timing, not the ADC.

    EPWM1 interrupts were disabled for unknown reasons but partially configured to count interrupts as if EPWM1 had inputs for ADC interrupts. 

  • For your production code, you really want to push even higher on the optimization.

    ALSO, are you linking and using the RELEASE version of the driverlib.lib file or the DEBUG version?

  • For your production code, you really want to push even higher on the optimization

    I tried to push level 2 opts with ARM code compiled via CCS, global opts really cause issues with interrupts and PWM controls etc...

    ALSO, are you linking and using the RELEASE version of the driverlib.lib file or the DEBUG version?

    The COF library is included in the project of Flashlib debug files. I may later try the eabi SDK project, if reducing COF opts level 1 has no effect on debug register drop downs.

  • I tried to push level 2 opts with ARM code compiled via CCS, global opts really cause issues with interrupts and PWM controls etc

    Did you mark your globals variables as "volatile"?

  • No most are interrupt static inter procedural variables. According to the king of IDE  (MSVS)  to preserve variable values during interrupts Static must be assigned. Why the CCS group believes non volatile variables are static is beyond the RFC C++ definition for interrupt vector type variables. 

    Anyway this CMPA match count seems to be several issues combined for the perfect storm with CCS real time silicon register updates refusing to poll 2WD. Perhaps a 4WD JTAG probe would reveal more details?

  • Try the 4WD JTAG.

  • Sadly the launch pad is only 2WD via XDS110 USB on board.

    Seemingly EPWM1 ADC trigger for SOC interrupt events can over run CMPD gate control logic? EPWM1 having more random dead locks CMPA and 10µs wider duty cycle over EPWM2, EPMW3 nor do they have synchronous duty cycle via Synci/Synco timing. 

    The SDK configured EPWM1 for ADC trigger count CMPD(5) or 50ns SOC count events for 100mHz PWMCLK. The SOC INT handler 328µs wide via GPIO test, why CMPD need 50ns trigger counts?

    Perhaps it was thought CMPD was configured for 50µs counts?  Some EPWM modules comparators get latched up via very low match counts when others have much greater match counts configured for active high outputs. Perhaps the entire PWM module struggles to sync Master\Slave due interrupt storm on CMPD?

  • You have EPWM interrupts generated by CMPD every cycle?

  • Looking again EPWM_SOC_TBCTRD_D_CMPD or even TBCTR_PERIOD produce 125µs ADC trigger EOC interrupts. Ideally based on TBCTR consistently being a fixed 25µs period. If CTR=TBCTR is not being reset how would CMPD match counts react, grasping for straws.

    I was wrongly thinking PWMCLK or SYSCLK each being (10Ns), 50ns interrupts is not correct or was it. T

    Still CMPD match count (5) is very low when CMPA match 100 times greater. Also made CMPD shadow load event, noticed no change in CMPA load events. The questionable part again the duty cycles are not evenly distributed between EPWM1, 2, 4 though (for) loop loads CMPA.

    Note rapid B2B reads of TBPRD register are part of the for loop.

        for(pwmCnt=0;pwmCnt<3;pwmCnt++)
        {
        
            // compute the value
            period = (float32_t)(EPWM_getTimeBasePeriod(obj->pwmHandle[pwmCnt]));
            
            // do period calcualtions
        
            int16_t pwmValue  = (int16_t)(V_sat_dc_pu * period);
            
            /* EPMWx CTRL shadow load CMPA empty status */
            if (EPWM_getCounterCompareShadowStatus(obj->pwmHandle[pwmCnt],
    											   EPWM_COUNTER_COMPARE_A) == false)
            {
    
            	        // write the PWM data value
            			EPWM_setCounterCompareValue(obj->pwmHandle[pwmCnt],
                                         EPWM_COUNTER_COMPARE_A,
                                         pwmValue);
    
            }
     

  • Have you considered using the DMA to move the data out of the ADC instead of an interrupt every time?

  • That's way beyond the Instaspin decimation explanations for FOC motor control scheme. Trying to keep inside the scope of FAST estimator requirements.

    However did try linking EPWM2, EPWM4 to EPWM1 master for CMPA shadow loads and remove for loop code load events, Master CMPA load only.  It refused to run for unknown reasons. Though 18.4.5 explains for variable frequency shadows load simultaneously (CTR=0, PRD=0) linked this way. CMPA would not load as it seems after reading the PRD register, it oddly dead locked in the RAW.

    Technically current ramps (Hertz/sec), linking should be very effective for Master/Slave's Synci/Synco events per Fig.18-11?  

  • Linking doesn't work Stuck out tongue winking eye confirms 3 unique values get written to each CMPA. The 3 values are array buffered into for loop count one at a time. Yet it sounds like good idea to link CMPA shadow load events together from the Master but not the actual match data. Seemingly Maser zero count, Slaves Synci/Synco should keep shadow load events together between EPWM's?

    Have you considered using the DMA to move the data out of the ADC

    No FCL code may be a help to separate the ADC trigger and interrupts  into dedicated handlers. 

  • How did you confirm that linking wasnt working?

  • There is very small inductive phase current developed with linking. The text only mentions shadow values, leads to assumption they become like global updates, code below failed too. Perhaps global config should include 3x EPWM shadow global updates? 

           /* Enable global register loads via shadow registers */
            EPWM_enableGlobalLoad(obj->pwmHandle[0]);
            /* Set global shadow register loads trigger on Synci or count zero */
            EPWM_setGlobalLoadTrigger(obj->pwmHandle[0], EPWM_GL_LOAD_PULSE_SYNC_OR_CNTR_ZERO);
            /* enable global loads for these specified register */
            EPWM_enableGlobalLoadRegisters(obj->pwmHandle[0], EPWM_GL_REGISTER_CMPA_CMPAHR);

  • If you have enabled EPWMXLINK registers the values should automatically link once one CMPx is updated.

  • Right the CMPA values only not the shadow load event trigger. Again tested global update triggers for CMPA and it does not work EPWM1,2,4 above code. 

  • So your CMPA is just not updating at all?? I'm starting to think somewhere in your code, it is being overwritten,

  • The linking and global updates do not *seem to work. Perhaps Master/Slave (Cnt0/Synci/Synco) with Global and linking can not be used?

    Otherwise they both *may work but the CMPA update values become less effective to drive phase current. That condition (if true) would indicate some kind of rotation angle calculation error by the surrounding Instaspin code?