Hi @Gianluca,
I’ve gone through your detailed comments and will address each of your doubts step by step, focusing on how the ePWM, SOC triggers, ADC sampling, and CMPA register updates line up in time. I’ve also added references so you can follow up with MathWorks and TI documentation.
1. When CMPA gets updated after TBCTL=0 event
You are right that if you use shadow mode, the value you write in the ISR is not immediately applied. The actual transfer from the shadow register to the active CMPA register occurs at the event configured in the `CMPCTL.LOADAMODE` setting (TI Technical Reference Manual [SPRUFN4], section on Compare Unit).
- If set to Zero, the transfer occurs only when `CTR=0`.
- If set to PRD, the transfer occurs when `CTR=PRD`.
- If set to Both, it transfers at both events.
So, if you write CMPA at `CTR=0` but the load mode is Zero, it won’t become active until the next `CTR=0`, i.e. one PWM period later. With PRD, it will become active half a period later.
2. Updating CMPA only once per period
With shadow mode, yes, a single ADC sample tied to `CTR=0` will update CMPA once per full PWM period. To achieve two updates per period in up/down mode, you can use both `CTR=0` and `CTR=PRD` events (see TI TRM, ePWM – Compare and Action Qualifier sections; also MathWorks “ADC-PWM Synchronization Using ADC Interrupt” example).
- At `CTR=0`: trigger ADC, compute new CMPA, and configure the load mode to apply the update at `CTR=PRD`.
- At `CTR=PRD`: trigger ADC again, compute a second CMPA, and configure the load mode so it updates at `CTR=0`.
This way you get one duty update for each half of the PWM cycle.
3. Timing in up/down mode with two ADC triggers In up/down mode, a full PWM period is `2 × TBPRD`. The two critical points are `CTR=0` and `CTR=PRD`. By using both, you can have:
- First ADC sample and CMPA update taking effect in the second half of the current cycle.
- Second ADC sample and CMPA update taking effect in the first half of the next cycle.
References: MathWorks C2000 Blockset documentation on ePWM types and SOC triggering, TI F28388D TRM (time-base counter and compare unit).
4. Concern about getting only “half duty” (e.g., 25% instead of 50%)
That happens if your CMPA update only affects half of the PWM cycle. For example, setting 50% duty but only for one half results in an average of 25% across the full cycle. By staggering the load events as described above, you ensure the intended duty applies to each half-cycle consistently.
Reference: TI TRM, ePWM chapter (examples of up/down counting and duty cycle calculation).
5. Practical approach
- Configure two SOC triggers: one at `CTR=0` and one at `CTR=PRD` (MathWorks C2000 ADC block supports this).
- Use their ISRs (or tasks in Simulink) to compute the CMPA shadow values.
- Set the load mode carefully: ISR at `CTR=0` → load at `PRD`; ISR at `CTR=PRD` → load at `ZERO`.
- This way, every ADC measurement directly influences the following half-cycle duty.
References: MathWorks “C2000 Peripheral Blocks: ePWM and ADC” documentation; TI SPRUFN4 (ePWM Compare Unit, ADC SOC Trigger section).
In summary:
- Shadow updates always wait for the configured load event.
- With careful use of both `ZERO` and `PRD` load events, you can achieve two ADC-based CMPA updates per PWM period in up/down mode.
- This prevents the “half-duty” averaging issue you were worried about.
For detailed guidance, I recommend:
MathWorks C2000 Blockset Example: “ADC-PWM Synchronization Using ADC Interrupt” (shows ADC trigger from ePWM and updating duty).
TI TMS320F28388D Technical Reference Manual: ePWM section, especially Time-Base, Compare, and Shadow Register subsections.
I hope this clears up the timing relationship and gives you a working strategy for your PI controller with the H-bridge.