Part Number: TMS320F28069F
Other Parts Discussed in Thread: C2000WARE
Hello,
I am having an issue with software forced adc conversions. I have two adc interrupts. One is a fast interrupt that is EOC triggered on a simultaneous adc conversion on soc0 and soc1. The slower interrupt is EOC triggered on a simultaneous adc conversion on soc2 and soc3. the slower interrupt SOC is triggered from a down sample count in the fast interrupt. I have noticed that there are spurious interrupts in my code that appear to be the cause of the software forced interrupt call; the spurious fast interrupts dont occur with the software forced interrupt call commented out. Another factor in this problem is the fact that im using two interrupts in the PIE. My code works correctly when I change the slower interrupt to use PIEIER10. Please see the code below. I would post all my code but unfortunately it is large. An important thing to not is Im directly using whole register access and not the bit wise examples in the c2000ware code. Also a screenshot of what I am observing is below
with software forced interrupt commented out

with the software forced interrupt the interrupts keep triggering

Here is the relevant excerpt of code. I believe the issue resides in `AdcRegs.ADCSOCFRC1 |= ADCSOC_SOC2;` inside of the fast isr. My debugger shows that the interrupt flags for PIEIFR1 and ADCINTFLG look correct aka only the ADCINT1 is pending. however right after the call to the software forced soc the ADCINTFLG goes to 0x0103, PIEIFR1 = 0x0022, and ADCINTOVF = 0x0003. I have checked the memory address of AdcRegs.ADCSOCFRC1 and it is correct.
Questions:
- Is it not possible to call a software force soc from an isr context?
- is a rmw operation and the ADCSOCFRC1 not correct?
- Is it not possible to use more than one interrupt from a PIE group at a time?
static const PwmConfig resolver_pwm_config =
{
.enable_center_aligned=true,
.counts=937,//94,
.adc_trigger={.enable=true, .event_scaler=ePwmSocPulseOnThirdEvent},
.compliment={.enable=false, .edge_delay=0},
.sync={.enable=false, .phase_counts=0, .sync_out=ePwmSyncOutSyncIn}
};
static const SampleConfig resolver_adc_config =
{
.soc_index=0,
.channel=eAdcInA0,
.trigger_source=eAdcTriggerPwm1SocA,
.sample_time=7,
.enable_simultaneous_sample=true,
.adc_interrupt={.enable=true, .interrupt_index=1}
};
static const SampleConfig current_adc_config =
{
.soc_index=2,
.channel=eAdcInA1,
.trigger_source=eAdcTriggerSoftware,
.sample_time=7,
.enable_simultaneous_sample=true,
.adc_interrupt={.enable=true, .interrupt_index=2}
};
__interrupt void adc_resolver_isr(void)
{
static const unsigned down_count = 4;
static unsigned isr_count = 0;
hal_resolver_isr_pin_toggle();
hal_resolver_sin = AdcResult.ADCRESULT0;
hal_resolver_cos = AdcResult.ADCRESULT1;
// start phase current adc sampling
if (++isr_count >= down_count)
{
isr_count = 0;
AdcRegs.ADCSOCFRC1 |= ADCSOC_SOC2;
}
AdcRegs.ADCINTFLGCLR |= ADCINT_BIT1;
AdcRegs.ADCINTOVFCLR |= ADCINT_BIT1;
PieCtrlRegs.PIEACK = PIEACK_GROUP1;
}
__interrupt void adc_current_isr(void)
{
static unsigned down_count = 20;
static unsigned isr_count = 0;
hal_current_isr_pin_toggle();
hal_current_a = AdcResult.ADCRESULT2;
hal_current_b = AdcResult.ADCRESULT3;
AdcRegs.ADCINTFLGCLR |= ADCINT_BIT2;
AdcRegs.ADCINTOVFCLR |= ADCINT_BIT2;
PieCtrlRegs.PIEACK = PIEACK_GROUP1;
}
void hal_boot_init(void)
{
f28_setup_system_control(&system_config);
DINT; // Disable CPU interrupts
f28_setup_peripheral_interrupt_control();
// Disable CPU interrupts and clear all CPU interrupt flags
IER = 0x0000;
IFR = 0x0000;
f28_setup_peripheral_interrupt_table();
// map isrs
EALLOW;
PieVectTable.ADCINT1 = &adc_resolver_isr;
PieVectTable.ADCINT2 = &adc_current_isr;
PieVectTable.ADCINT9 = &adc_1kHz_isr;
PieVectTable.TINT2 = &cpu_timer2_isr;
PieVectTable.SPIRXINTA = &sci_rxa_isr;
EDIS;
hal_gpio_init();
f28_adc_init();
f28_adc_soc_setup(&adc_1khz_config);
f28_adc_soc_setup(¤t_adc_config);
f28_adc_soc_setup(&resolver_adc_config);
f28_timer_init(&CpuTimer2Regs, &msec_timer_config);
f28_sci_init(&SciaRegs, &sci_a_config, LSPCLK_SPEED);
f28_can_init(&can_node, &can_bitrate, &can_mask_filter);
f28_pwm_init(&EPwm1Regs, &resolver_pwm_config);
// Enable ADCINT1,2,9
PieCtrlRegs.PIEIER1 = (PIEIxR_INTx1 | PIEIxR_INTx2 | PIEIxR_INTx6);
// Enable SCIRXA
PieCtrlRegs.PIEIER9 = (PIEIxR_INTx1);
// Enable Int1=Adc; Int9=sci; Int14=timer2 interrupt
IER = (IxR_INT1 | IxR_INT9 | IxR_INT14);
// Enable global Interrupts and higher priority real-time debug events
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
Lastly here is a trace with using ADCINT3 and PIEIER10. This is what I expect to occur. Code changes are below; this code does not produce the odd ADCINTFLG = 0x0103 after the software soc start. However it produces the ADCINTFLG = 0x0005, PIEIF1 = 0x0002, PIEIF10 = 0x0007, and ADCINTOVF = 0x0000. The odd thing here is why is ADCINTFLG = 0x0005 and not 0x0001?

static const SampleConfig current_adc_config =
{
.soc_index=2,
.channel=eAdcInA1,
.trigger_source=eAdcTriggerSoftware,
.sample_time=7,
.enable_simultaneous_sample=true,
.adc_interrupt={.enable=true, .interrupt_index=3}
};
__interrupt void adc_current_isr(void)
{
static unsigned down_count = 20;
static unsigned isr_count = 0;
hal_current_isr_pin_toggle();
hal_current_a = AdcResult.ADCRESULT2;
hal_current_b = AdcResult.ADCRESULT3;
AdcRegs.ADCINTFLGCLR |= ADCINT_BIT3;
AdcRegs.ADCINTOVFCLR |= ADCINT_BIT3;
PieCtrlRegs.PIEACK = PIEACK_GROUP10;
}
void hal_boot_init(void)
{
f28_setup_system_control(&system_config);
DINT; // Disable CPU interrupts
f28_setup_peripheral_interrupt_control();
// Disable CPU interrupts and clear all CPU interrupt flags
IER = 0x0000;
IFR = 0x0000;
f28_setup_peripheral_interrupt_table();
// map isrs
EALLOW;
PieVectTable.ADCINT1 = &adc_resolver_isr;
PieVectTable.ADCINT3 = &adc_current_isr;
PieVectTable.ADCINT9 = &adc_1kHz_isr;
PieVectTable.TINT2 = &cpu_timer2_isr;
PieVectTable.SPIRXINTA = &sci_rxa_isr;
EDIS;
hal_gpio_init();
f28_adc_init();
f28_adc_soc_setup(&adc_1khz_config);
f28_adc_soc_setup(¤t_adc_config);
f28_adc_soc_setup(&resolver_adc_config);
f28_timer_init(&CpuTimer2Regs, &msec_timer_config);
f28_sci_init(&SciaRegs, &sci_a_config, LSPCLK_SPEED);
f28_can_init(&can_node, &can_bitrate, &can_mask_filter);
f28_pwm_init(&EPwm1Regs, &resolver_pwm_config);
// Enable ADCINT1,2,9
PieCtrlRegs.PIEIER1 = (PIEIxR_INTx1 | PIEIxR_INTx6);
PieCtrlRegs.PIEIER10 = PIEIxR_INTx3;
// Enable SCIRXA
PieCtrlRegs.PIEIER9 = (PIEIxR_INTx1);
// Enable Int1=Adc; Int9=sci; Int14=timer2 interrupt
IER = (IxR_INT1 | IxR_INT9 | IxR_INT10 | IxR_INT14);
// Enable global Interrupts and higher priority real-time debug events
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}