Run a simulink model on a texas instruments TMS320F28379D with c2000

Hello,
I am currently working on implementing a control strategy for a three-phase matrix converter.
I started from the official MathWorks example: Three-Phase Matrix Converter
My objective at this stage is simple:
I only want to run the SVM modulation part on my Texas Instruments TMS320F28379D LaunchPad (using the C2000 Support Package) and observe the PWM command signals on the GPIO/ePWM outputs.
The MATLAB/Simulink simulation works correctly.
However, when I deploy the controller to the TMS320F28379D, the measured switching signals on the oscilloscope do not match the expected timing. The waveform shape is correct, but the output frequency is systematically slower than the Simulink model (approximately a division by 25). This occurs when using simple GPIO output blocks or epwm.
what i did is i simply added gpiooutputs on the pwm signals (going to the transistors of the matrix) calculated on simulink with space vector modulation. check picture below.
I am trying to understand:
How to correctly map the PWM signals generated by the SVM model to the ePWM modules of the F28379D and whether additional configuration is required.
Any guidance, documentation, or example showing how to correctly deploy a PWM-based modulation (such as SVM) to the F28379D using Simulink would be extremely helpful.
Thank you in advance for your support.
Best regards,
Anais Taiati
engineering student at IMT Atlantique, france

Answers (2)

@Anaïs, after thoroughly researching the MathWorks C2000 documentation including "Detect and Fix Task Overruns on Texas Instruments C2000 Hardware" ( https://www.mathworks.com/help/ti-c2000/ug/detect-and-fix-task-overruns-on-c2000-hardware.html ), "Scheduling and Timing" ( https://www.mathworks.com/help/ti-c2000/ug/scheduling-and-timing.html ), "Submodules of ePWM Type 1-4" ( https://www.mathworks.com/help/ti-c2000/ug/sub-modules-of-epwm-type-1-4.html ), "GPIO Digital Output" block reference ( https://www.mathworks.com/help/ti-c2000/ref/gpiodigitaloutput.html ), and "C28x-ePWM Configuration" ( https://www.mathworks.com/help/ti-c2000/ref/sect-hw-imp-pane-c28x-epwm.html ), I can definitively explain your issue and address your question about mapping PWM signals to ePWM modules. You're experiencing a task overrun where, as the MathWorks overrun documentation states, "A task overrun occurs if the target hardware is still performing one instance of a task when the next instance of that task is scheduled to begin," and your model is taking about 1,250 microseconds to execute but is configured to run every 50 microseconds, causing the scheduler to skip 24 cycles and only execute every 25th interrupt, which explains your exact 25x slowdown with both GPIO and ePWM outputs. The scheduling documentation explains that "each iteration of the model solver is run after an interrupt has been posted and serviced by an interrupt service routine" using CPU_timer0, and when your code exceeds the time budget, the system cannot keep up regardless of whether you use GPIO or ePWM outputs. To confirm this, enable overrun detection as documented where " you can configure a Simulink model running on the target hardware to detect and notify you when a task overrun occurs" by going to Configuration Parameters, Hardware Implementation, Target Hardware Resources, Overrun detection, enabling it with GPIO31 set to toggle mode, and if it toggles continuously on your oscilloscope you have confirmed constant overruns. Your fundamental architectural problem is that your SVM is outputting binary switching patterns to GPIO blocks, which the documentation describes as blocks that " configure general-purpose I/O pins as digital output" where " a value of True at the input drives the GPIO pin high" requiring software execution for each transition, but you should instead restructure your SVM to output duty cycle percentages for each of the nine switches and feed these into properly configured ePWM hardware blocks. Regarding your specific question about how to correctly map PWM signals to ePWM modules, the F28379D has fixed GPIO pin assignments for each ePWM module that cannot be changed, as explained in the MathWorks forum where it states " the GPIO pin mapping to each PWM pin is fixed for TI Delfino" processors, and according to the LaunchPad documentation the default ePWM to GPIO mappings are ePWM1A on GPIO0, ePWM1B on GPIO1, ePWM2A on GPIO2, ePWM2B on GPIO3, ePWM3A on GPIO4, ePWM3B on GPIO5, ePWM4A on GPIO6, ePWM4B on GPIO7, ePWM5A on GPIO8, ePWM5B on GPIO9, ePWM6A on GPIO10, ePWM6B on GPIO11, ePWM7A on GPIO12, ePWM7B on GPIO13, ePWM8A on GPIO14, ePWM8B on GPIO15, and ePWM9A on GPIO16, ePWM9B on GPIO17, which you can verify by navigating to Configuration Parameters, Hardware Implementation, Target Hardware Resources, ePWM where the documentation states you can " visualize the pin assignment" for your processor. The ePWM documentation explains that " several motor control and power electronics applications use the enhanced Pulse Width Modulator peripheral" with hardware submodules including "Time-Base" that "enables configuring the period and mode at which ePWM counter operates," "Counter Compare" that "compares the time-base counter value with the counter compare registers," and "Action Qualifier" that "specifies the action to be taken on the ePWM output when time-base and counter compare events occur," meaning the hardware generates switching at nanosecond precision while your CPU only updates duty cycle values at 20 kHz. Configure each ePWM block with timer period calculated as "Base rate sample time = Timer Period × Prescaler / CPU Clock Speed" set for your switching frequency in up-down counting mode where "the time-base counter value starts from zero and increases until TBPRD is reached, once the counter reaches TBPRD the counter decreases until it reaches zero," with counter compare units set to percentages receiving duty cycle inputs, action qualifiers configured so when counter equals CMPA on up-count it clears and on down-count it sets to create symmetric PWM, synchronization where ePWM1 is master generating sync-out when counter equals zero and ePWM2-9 are slaves receiving this sync signal which is critical for your matrix converter to prevent creating short circuits between input phases, and dead-band delays configured in each ePWM block to prevent shoot-through. As the overrun documentation recommends for fixing overruns, " reduce the processing burden of the model by increasing the sample times, simplifying the model, or using profiling to measure execution time of each task," so as a quick diagnostic test temporarily change your fixed-step size to 1.25e-3 seconds, and if your outputs now match that 800 Hz rate you have confirmed the model executes correctly at slower speeds and needs optimization through lookup tables replacing trigonometric functions, fixed-point arithmetic where possible, pre-calculating constants, and using the profiler to identify bottlenecks before restructuring to the proper ePWM duty-cycle based architecture that power electronics applications require.

Let me know how it goes.

4 Comments

Hello Umar,
Thank you very much for your detailed answer, and sorry for the late reply. I did not see your message earlier because I was not receiving notifications and thought no one had replied. I wil carefully check from now on to see your answer :)
I understand your explanation about the task overrun and the fact that increasing the fixed-step size (for example to ~1.25 ms) is a useful diagnostic to confirm that the model execution time exceeds the available time budget. Indeed, when I increase Ts and test at low frequencies (e.g. 1 Hz fundamental, 1 kHz switching), the signals become correct, which confirms the overrun issue.
However, my target application requires a switching frequency of 50 kHz. With such a large Ts, I no longer have a 50 kHz carrier inside the model, so I cannot perform the sawtooth comparison used in the SVM to generate the switching signals. In that sense, increasing Ts helps to diagnose the problem, but it does not solve how to achieve 50 kHz switching in practice.
The core issue I am facing is how to correctly interface the SVM outputs with the C2000 ePWM hardware. My SVM currently generates pulses to the switches of my converter, not duty-cycle values that can be easily fed into an ePWM block. Because I did not know how to map these SVM-generated pulses to ePWM, I initially used GPIO outputs to reproduce the pulses on the board.
So my main question is: how should I do with my pusles outputsto use the ePWM blocks ? This is the part I am currently struggling with.
Thank you again for your help.
Best regards,
Anaïs

Hello @Anais,

No worries about the late reply. I have read your latest comments and now figure out exactly where the confusion is coming from, and this is actually a very common misunderstanding when moving from simulation to real embedded hardware. The fundamental issue is that you're thinking of SVM as something that outputs switching pulses at 50 kHz, but that's not how it's implemented in actual hardware. Space Vector Modulation is fundamentally a duty cycle calculation algorithm, not a pulse generator. What your SVM should be doing is calculating the duty cycle percentages for each switch based on your voltage reference, and these duty cycles only need to be recalculated at something like 10-20 kHz, not at your switching frequency. The actual 50 kHz switching happens automatically inside the ePWM hardware modules on the F28379D through their time-base counters and compare registers. So your architecture should be: SVM algorithm runs at 20 kHz calculating duty cycle values between 0 and 1, these values get fed into the CMPA/CMPB compare registers of your ePWM blocks, and then the ePWM hardware modules generate the actual 50 kHz switching signals by comparing their internal counters against those compare values. This is exactly how every motor drive, inverter, and matrix converter in industry works because it's impossible to do the carrier comparison in software at high frequencies without overruns. You need to restructure your SVM model to remove the carrier wave and comparison logic entirely and just output three duty cycle percentages, then configure nine ePWM blocks with their TBPRD set for 50 kHz operation in up-down count mode, connect your duty cycle outputs to the compare inputs, set up proper synchronization with ePWM1 as master, and configure dead-band delays to prevent shoot-through. Your model sample time would be 50 microseconds running the SVM calculations, while the ePWM hardware handles the actual 50 kHz switching autonomously. This solves your overrun problem because you're only running calculations at 20 kHz instead of trying to do everything at 50 kHz, and it's the standard approach used in all professional power electronics implementations.Hope this helps!

Hi Umar,
Thank you for your explanation, it makes sense for a standard inverter SVM where the algorithm directly provides duty cycles to the PWM hardware.
In my case I am using the MathWorks three-phase matrix converter example. The difficulty is that I don’t directly have “final duty cycles per switch” at the output of my SVM stage.
In the model, duty cycles are first used to compute the switching times (T1, T2, T0) and the symmetric sequence depends on the sector (selection of adjacent vectors). Then the final gate signals for the 9 bidirectional switches are generated inside the “Matrix Converter Switching” (inside the IGBT matrix converter SVM symmetric switching) block by combining the rectifier SVM and inverter SVM with logical AND/OR operations (virtual rectifier + virtual inverter approach). This is why I was trying to output the pulses directly (GPIO), because I currently don’t know how to convert this structure into duty-cycle commands suitable for ePWM blocks.
in this situation how do i extract the 9 duty cycles for the epwm?
Thanks again for your help,
Anaïs

Hi @Anais,

The key insight you're missing is that in indirect SVM for matrix converters, the duty cycles for your nine bidirectional switches are calculated by multiplying the rectifier stage duty cycles with the inverter stage duty cycles before they go through the AND/OR logic that creates the pulse patterns. What you need to do is tap into the signals before the "Matrix Converter Switching" block performs the logical combinations. Inside the MathWorks example, the rectifier SVM block calculates duty cycles for current vectors like d_gamma, d_delta, and d_zero based on which input current sector you're in, while the inverter SVM block calculates duty cycles for voltage vectors like d_alpha, d_beta, and d_zero based on which output voltage sector you're in. The final duty cycle for each of your nine switches S_ij where i represents the output phase U,V,W and j represents the input phase A,B,C is computed by multiplying the appropriate rectifier duty cycle times the inverter duty cycle for that specific switching period. For example, during a portion of the switching cycle when the rectifier is connecting input phase A to the virtual DC link with duty d_rectA and the inverter is connecting the virtual DC link to output phase U with duty d_invU, then switch S_UA receives the combined duty cycle d_rectA times d_invU. This multiplication needs to account for all active vector combinations being used in that switching period based on your current sectors. You need to modify your Simulink model to extract these intermediate duty cycle values from both SVM stages before the pulse generation logic, calculate the nine final duty cycles through appropriate multiplication based on the switching sequence, and then feed these nine percentage values directly into nine ePWM blocks configured for 50 kHz switching frequency with proper synchronization and dead-band settings. Your SVM calculations would run at 20 kHz calculating these duty cycle multiplications, while the ePWM hardware autonomously generates the actual 50 kHz switching pulses by comparing its internal counters to the duty cycle values you provide. This is exactly how professional matrix converter implementations work in industry, with the DSP calculating duty cycles at lower frequencies while dedicated PWM hardware handles the high-frequency switching. The specific equations for which duty cycles to multiply depend on your current sector combination, but the principle remains constant across all sectors, extract both stage duty cycles as percentages, multiply them according to the active vector sequence, and output the results to ePWM compare registers.

Sign in to comment.

You can refer to some motor control examples that are designed for direct deployment on F28379D controllers (e.g. Field-Oriented Control of PMSM Using SI Units - MATLAB & Simulink Example, Field-Oriented Control of PMSM Using Quadrature Encoder - MATLAB & Simulink Example). These examples also use Space Vector PWM, albeit for motor control applications. Reviewing them might help you correctly configure your ePWM blocks.

Asked:

on 11 Dec 2025

Commented:

on 14 Jan 2026

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!