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.

TMS320F28377D: How to force all controller PWM signals to a LOW state when debugger is stopped?

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

Hi,

I am almost done working on my C2000Ware code for a high voltage DC/DC converter but had a few questions about making the code more safe when I want to stop the code execution.

At the moment, when I halt the debugger, the DSP seems to continue outputting signals to the GPIO's, meaning that my PWM is still being outputted. I would like the code such that when the debugger is stopped, every PWM signal on the DSP goes to a LOW state and instantly turns off all the PWM signals. This allows a true emergency stop that halts all outputs as soon as I click the stop button.

Furthermore, I have placed a counter in one of my ISR's that, after a certain number of seconds, forces an emergency stop on my converter. It may be that I need to halt the code before this, but this will be good for say, a 60 second run of the code for initial tests at high voltage to ensure nothing gets too hot or bothered. Unfortunately, when the emergency stop comes into place after 60 seconds, some of my PWM is forced high and some forced low. I would like all the PWMs again to be forced LOW. 

What else can be placed in this short loop just before the ESTOP button, to force the PWM's low? Would the TZFRC signal work well from within the trip zone in this scenario? I tried this:

   // Run the code for 1,000,000 Cycles = 33.33 Seconds (1,000,000 * (1/30kHz))
    if(codeNumberOfCycles > 1000000) {

        // Force PWMxA and PWMxB of EPwm1 and EPwm4 LOW using OST DCA/BEVT1 force signals
        EPwm1Regs.TZFRC.bit.DCAEVT1 = 1;
        EPwm1Regs.TZFRC.bit.DCBEVT1 = 1;
        EPwm4Regs.TZFRC.bit.DCAEVT1 = 1;
        EPwm4Regs.TZFRC.bit.DCBEVT1 = 1;

        // Force emergency stop and exit code
        asm(" ESTOP0");
    }

But again, some of the outputs latch HIGH when I have them set up to latch to LOW. For example in my PWM setup:

         // Trip Zone Submodule - Trip Logic block
         EPwm4Regs.TZCTL.bit.DCAEVT1 = 0x10;      // On trip, force EPWM4A to a LOW state
         EPwm4Regs.TZCTL.bit.DCBEVT1 = 0x10;      // On trip, force EPWM4B to a LOW state
         EPwm4Regs.TZCTL.bit.DCAEVT2 = 0x10;      // On trip, force EPWM4A to a LOW state
         EPwm4Regs.TZCTL.bit.DCBEVT2 = 0x10;      // On trip, force EPWM4B to a LOW state

Yet one output latches LOW and one outputs latches HIGH when using the code in the codeNumberOfCyclesLoop. Furthermore, this only occurs during the ESTOP routine, because the trip zones when operating normally will trip both EPWMxA and EPWMxB as expected. It is something to do with the ESTOP routine that causes one of the GPIO's to be latched high and not low.

Any suggestions as to why this may be occuring?

Best regards,

Joel

  • Hi Joel,

    What else can be placed in this short loop just before the ESTOP button, to force the PWM's low? Would the TZFRC signal work well from within the trip zone in this scenario?

    Yes, using a trip zone force is the best way to completely make all your EPWM outputs low. I suggest you force a OST event not a DCAEVT/DCBEVT and then configure the TZA/TZB bits of the TZCTL register to go low. This should make all of your EPWM outputs go low. 

    I would like the code such that when the debugger is stopped, every PWM signal on the DSP goes to a LOW state and instantly turns off all the PWM signals. This allows a true emergency stop that halts all outputs as soon as I click the stop button.

    I don't know of a way to stop the EPWM outputs when you stop the debugger. I would recommend implementing a "disable" function with the trip zone force implementation suggested above and then have a variable that checks for a certain value, upon the desired value it will call the disable function. This will allow you to stop the EPWM outputs by changing the value of the variable through the expression's window in CCS, then you can stop the debugger. 

    Best Regards,

    Marlyn

  • Hi Marlyn,

    First of all thanks for your reply, this is a good idea. I am trying to implement it now. I set GPIO12 to be default 1 and routed to the input XBar as follows:

    // For External Trigger, GPIO12 as the trigger for TripZone
        GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;    // Enable pull-up on GPIO12 (TZ1)
        GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3;  // Asynch input GPIO12 (TZ1)
    
        EALLOW;
    
        // Input XBar input for Trip Zone
        InputXbarRegs.INPUT1SELECT = 12;
    

    I then enabled TZ1 as OST source for EPWM1 and EPWM4 (my PWM outputs), leaving the INT out for now:

          
          EALLOW;
          // Enable TZ1 as one shot trip sources
          EPwm1Regs.TZSEL.bit.OSHT1 = 1;
    
          // Set TZA
          EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
          EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    
          // Enable TZ interrupt
          //EPwm1Regs.TZEINT.bit.OST = 1;
          EDIS;

    Such that when the GPIO12 goes LOW, indicating a trip event, my PWM will be low. I have done the exact same code above for EPWM4 too.

    I then finally, within the ISR, trigger GPIO12 to go low when the count is matched:

     // Run the code for 300,000 cycles of ISR
        if(codeNumberOfCycles > 300000) {
            
            check = 1;
            
            // Force PWMxA and PWMxB of EPwm1 and EPwm4 LOW using OST DCA/BEVT1 force signals
            GpioDataRegs.GPATOGGLE.bit.GPIO12 = 1;
    
            codeNumberOfCycles = 0;
    
            // Force emergency stop and exit code
            //asm(" ESTOP0");
        }

    But the trip doesn't ever occur, and the TZFLG[OST] bit is not set either. 

    Am I missing something here?


    Best regards,

    Joel

  • Hi Joel,

    The setup you have looks correct.

    But the trip doesn't ever occur, and the TZFLG[OST] bit is not set either. 

    Would it be possible for you to insert a breakpoint in your ISR to see if the condition in the if statement is happening. Do you see your variable "codeNumberOfCycles" ever get reset to zero? 

    Alternatively, you could scope GPIO12 to see if it is changing states.

    Best Regards,

    Marlyn

  • Hi Marlyn,

    It does enter the ISR and reset the variable to zero. I have looked in the registers and probed GPIO12 and it stays at 1 and never changes. The GPATOGGLE register for GPIO12 remains at 0 and never becomes 1, meaning that the GPIO is never told to change state. I have also tried using a different GPIO, in a different ISR, and again the GPATOGGLE bits aren't set, and the GPIO doesn't change state.

    Is there any other thing that may be causing this issue? 

    EDIT: Think I may be getting somewhere. In the example code, the pin is specified as an input pin, because it uses an external trigger on GPIO12. I am setting GPIO12 manually and not using an external trigger - I set it to an output pin instead, and seem to be tripping the two EPWMs - but it trips at start up straight away before I pull the GPIO12 to zero. 

    Best,
    Joel

  • Joel,

         Marlyn is out of the office and will be back on Monday, at which time she will respond to your questions. Thank you for your patience.

  • Hi,

    I think I have fixed the issue. Changing the GPIO to output mode, and as I mentioned this caused one shot trips in all PWM modules. 
    That's because the GPIO12 for some reason was default 0 value, meaning the trips occurred straight away. I solved this by writing a 1 to the GPIO pin during initialization, and then writing a 0 to the GPIO during the ISR, the trips now happen correctly.

    It seems like the issue is with the configuration of the GPIOs - I don't know whether what I have done should need to be done, and GPIO12 should automatically be set to a 1 when set to pull-up mode. Maybe Marlyn can clarify what might have happened here. I think there is a function in some newer codes called board_init(); which uses "Board.h" but I do not seem to have that file, so it may be that the way I have set my GPIO up at the moment is incorrect.

    Best regards and have a good weekend Hareesh and Marlyn. Thanks!

    EDIT: When I now insert ESTOP after writing a 0 to GPIO12 to trip TZA/TZB in OST mode, the compiler exits to the following state:

    The PWM signals do indeed set to LOW, so the trip action works and the code exits successfully - not sure if the way it exits is an issue? Look forward to your reply next week.


    Joel

  • Joel,

        Good to know. Let us await Marlyn's inputs..A great weekend to you too.

  • Hi Joel,

    It seems like the issue is with the configuration of the GPIOs - I don't know whether what I have done should need to be done, and GPIO12 should automatically be set to a 1 when set to pull-up mode. Maybe Marlyn can clarify what might have happened here. I think there is a function in some newer codes called board_init(); which uses "Board.h" but I do not seem to have that file, so it may be that the way I have set my GPIO up at the moment is incorrect.

    Were you referencing the trip zone example in C2000Ware for this? If so, there should be a .syscfg file within the project, this is what is generating the "board_init()" function you are referring to. SysConfig is a graphical tool to allow you to initialize/setup IP. It will automatically generate the required driverlib code for you. The example has a GPIO added and by default, GPIOs are setup as inputs. Furthermore, the example is setup so that you physically tie the GPIO high initially (through jumper wire) and then connect to ground for the trip. 

    Since you were toggling your GPIO it does make sense that it needs to be an output for this to occur.

    If you want to gain some insight into SysConfig we recently released a training series: https://training.ti.com/sysconfig-development-tool-c2000-real-time-mcus?context=1137766-1149557 

    EDIT: When I now insert ESTOP after writing a 0 to GPIO12 to trip TZA/TZB in OST mode, the compiler exits to the following state:

    I only see a breakpoint in your code, not an ESTOP. Did you mean to include a different figure? In general, it is okay to have an ESTOP0 condition and then manually stop the debugger in CCS.

    Best Regards,

    Marlyn

  • Hi Joel,

    I think the FREE_SOFT bit in the TBCTL register will be useful in solving your problem.
    Have you considered using this bit?

    TBCTL Register

    Best Regards,

    Sangil