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.

TMS320F280025C: Issue CMPSS / ADC (configuration mistake I suppose ?)

Part Number: TMS320F280025C


Hi expert,

I have a problem with the cmpss. I set up different adc entries on the microcontroller to override their readings via an isr as well as other entries that are connected to the cmpss in order to cut my epwm. However I notice by testing that all my entries even those I use in adc reading cut my epwm what I do not want.

Am I setting up the cmpss module incorrectly ? I join my code :

void cmpss_init()
{
    // Enable CMPSS and configure the negative input signal to come from the DAC
    CMPSS_enableModule(CMPSS1_BASE);
    CMPSS_enableModule(CMPSS2_BASE);
    CMPSS_enableModule(CMPSS3_BASE);
    CMPSS_enableModule(CMPSS4_BASE);

    // Use VDDA as the reference for the DAC and set DAC value to midpoint for arbitrary reference.
    CMPSS_configDAC(CMPSS1_BASE, CMPSS_DACREF_VDDA);
    CMPSS_configDAC(CMPSS2_BASE, CMPSS_DACREF_VDDA);
    CMPSS_configDAC(CMPSS3_BASE, CMPSS_DACREF_VDDA);
    CMPSS_configDAC(CMPSS4_BASE, CMPSS_DACREF_VDDA);

    // To use CMP1_HP2 pin A6 for MU_TRAC_BATT_PCH
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_1, 2);
    // To use CMP1_LP3 pin A15/C7 for MU_FUEL_CELL_PCH
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 3);
    // To use CMP3_HP1 pin A5/C2 for MI_L_W
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_3, 1);
    // To use CMP2_HP1 pin A12/C1 for MI_L_U
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_2, 1);
    // To use CMP2_LP4 pin A8/C11 for MI_L_V
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_2, 4);
    // To use CMP4_HP1 pin A7/C3 for MI_TRAC_BATT
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_4, 1);

    // Configure the output signals. Both CTRIPH will be fed by the asynchronous comparator output.
    //1
    CMPSS_configHighComparator(CMPSS1_BASE, CMPSS_INSRC_DAC);              // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueHigh(CMPSS1_BASE, max_dac_cmpss);                     // Define threshold
    CMPSS_configOutputsHigh(CMPSS1_BASE, CMPSS_TRIP_SYNC_COMP);            // Set output comparator (synchronous or asynchronous)
    //2
    CMPSS_configLowComparator(CMPSS1_BASE, CMPSS_INSRC_DAC);               // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueLow(CMPSS1_BASE, max_dac_cmpss);                      // Define threshold
    CMPSS_configOutputsLow(CMPSS1_BASE, CMPSS_TRIP_SYNC_COMP);             // Set output comparator (synchronous or asynchronous)

    // Configure the output signals. Both CTRIPH will be fed by the asynchronous comparator output.
    //1
    CMPSS_configHighComparator(CMPSS2_BASE, CMPSS_INSRC_DAC);              // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueHigh(CMPSS2_BASE, max_dac_cmpss);                     // Define threshold
    CMPSS_configOutputsHigh(CMPSS2_BASE, CMPSS_TRIP_SYNC_COMP);            // Set output comparator (synchronous or asynchronous)
    //2
    CMPSS_configLowComparator(CMPSS2_BASE, CMPSS_INSRC_DAC);               // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueLow(CMPSS2_BASE, max_dac_cmpss);                      // Define threshold
    CMPSS_configOutputsLow(CMPSS2_BASE, CMPSS_TRIP_SYNC_COMP);             // Set output comparator (synchronous or asynchronous)

    // Configure the output signals. Both CTRIPH will be fed by the asynchronous comparator output.
    //1
    CMPSS_configHighComparator(CMPSS3_BASE, CMPSS_INSRC_DAC);              // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueHigh(CMPSS3_BASE, max_dac_cmpss);                     // Define threshold
    CMPSS_configOutputsHigh(CMPSS3_BASE, CMPSS_TRIP_SYNC_COMP);            // Set output comparator (synchronous or asynchronous)

    // Configure the output signals. Both CTRIPH will be fed by the asynchronous comparator output.
    //1
    CMPSS_configHighComparator(CMPSS4_BASE, CMPSS_INSRC_DAC);              // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueHigh(CMPSS4_BASE, max_dac_cmpss);                     // Define threshold
    CMPSS_configOutputsHigh(CMPSS4_BASE, CMPSS_TRIP_SYNC_COMP);            // Set output comparator (synchronous or asynchronous)

    // Configure TRIP4 to be CTRIP1H using the ePWM X-BAR. Attach CMPSS output to TRIPINx via EPWMXBAR module
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX00_CMPSS1_CTRIPH);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX01_CMPSS1_CTRIPL);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX04_CMPSS3_CTRIPH);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX02_CMPSS2_CTRIPH);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX03_CMPSS2_CTRIPL);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX06_CMPSS4_CTRIPH);

    // See the ePWM X-BAR Mux configuration table, see Crossbar(X-BAR) doc for more informations
    XBAR_enableEPWMMux(XBAR_TRIP4, XBAR_MUX00 | XBAR_MUX01 | XBAR_MUX04 | XBAR_MUX02 | XBAR_MUX03 | XBAR_MUX06);
}

void cmpss_actions(base)
{
    // Configure ePWMx to output low on TZx TRIP
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);

    // Trigger event when DCBH is high
    EPWM_setTripZoneDigitalCompareEventCondition(base, EPWM_TZ_DC_OUTPUT_B1, EPWM_TZ_EVENT_DCXH_HIGH);

    // Configure DCBH to use TRIP4 as an input
    EPWM_enableDigitalCompareTripCombinationInput(base, EPWM_DC_COMBINATIONAL_TRIPIN4, EPWM_DC_TYPE_DCBH);

    // Enable DCB as OST
    EPWM_enableTripZoneSignals(base, EPWM_TZ_SIGNAL_DCBEVT1);

    // Clear trip flags
    EPWM_clearTripZoneFlag(base, EPWM_TZ_FLAG_DCBEVT1);
}
void adc_config(uint32_t adc_base)
{
    // Enable ADC
    ADC_setVREF(adc_base, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    ADC_setPrescaler(adc_base, ADC_CLK_DIV_1_0);

    // Set pulse ADCINTx at the end of conversion
    ADC_setInterruptPulseMode(adc_base, ADC_PULSE_END_OF_CONV);

    if(adc_base == ADCA_BASE)
    {
        // Configure the SOC to occur on the first up-count event
        EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
        // To set ADCCLK
        EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, ADC_PRESCALE);

        EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
    }

    ADC_enableConverter(adc_base);

    //Delay to allow ADC time to power up
    DEVICE_DELAY_US(adc_powerup_us);
}

void adc_init_soc(void)
{
    // Corresponding module ADCx -> SOC -> pin. Enchainement des SOC une fois la conversion terminée sur un SOC.SOC0 will start at 1 / PWM_FREQ and an another SOC0 at 1 / PWM_FREQ after.

    // MU_TRAC_BATT_FLT with pin ADCINA3
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN3, ADC_ACQPS_WINDOW);

    // MU_FUEL_CELL_FLT with pin ADCINA2
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN2, ADC_ACQPS_WINDOW);

    // MI_TRAC_BATT_FLT with pin ADCINA14
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN14, ADC_ACQPS_WINDOW);

    // MU_FUEL_CELL_PCH_FLT with pin ADCINA0
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, ADC_ACQPS_WINDOW);

    // MU_TRAC_BATT_PCH_FLT with pin ADCINC6
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN6, ADC_ACQPS_WINDOW);

    // MT_COLD_PLATE_FLT with pin ADCINC0
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, ADC_ACQPS_WINDOW);

    // MI_L_U_FLT with pin ADCINC14
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN14, ADC_ACQPS_WINDOW);

    // MI_L_V_FLT with pin ADCINC8
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN8, ADC_ACQPS_WINDOW);

    // MI_L_W_FLT with pin ADCINC10
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER4, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN10, ADC_ACQPS_WINDOW);

    // Corresponding EOC to ADCINTX pulse to enter on interrupt for read ADCRESULTx registers. Refer to ADCINTSEL1N2 and ADCRESULTx registers.
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER4);

    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}

__interrupt void isr_adc(void) // Enter on interrupt when SOC3 on ADCC will end.
{
    MU_TRAC_BATT_PCH_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0);
    MT_COLD_PLATE_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER1);
    MI_L_U_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER2);
    MI_L_V_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER3);
    MI_L_W_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER4);

    MU_TRAC_BATT_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
    MU_FUEL_CELL_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
    MI_TRAC_BATT_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2);
    MU_FUEL_CELL_PCH_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3);

    adc_convert_samples_digit_to_analog();

    // Clear the interrupt flag
    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);

    // Check if overflow has occurred
    if(ADC_getInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1) == true)
    {
        ADC_clearInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
    }

    // Acknowledge the interrupt, see PIE Interrupt Vectors  table
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

Thanks

Damien

  • Hi Damien,

    I see you have the EPWM configured to trigger the ADC to sample some channels and the CMPSS configured to trip the EPWM. I'm however not clear on the issue you are facing. Can you explain what is not working?

  • Hi Frank,

    I sample 9 ADC channels and I also have 6 entries that are connected to the cmpss. I want to shut down the pwm when the cmpss is triggered, the comparison is made via a DAC threshold ("max_dac_cmpss" in my code). When I only test the cmpss the trigger is done correctly, but when I apply a voltage on the ADC inputs the reading is done correctly on the ADC but if I pass above the threshold of the DAC the PWM shut down through the cmpss I think. However, that should'nt be because it is a simple reading of ADC. However, I have review my code and I see no error. Is this a mapping problem ? Or ... ?

    Thanks

    Damien

  • Hi,

    I solved my problem, when I tested all my inputs were not related to a potential. So I had some pins at floating potentials which must disturb the microcontroller (ADC was reading a value above the threshold from which the shut down). Now by applying potential on my cmpss inputs as well as inputs for reading the ADC everything works fine.

    Thanks for your reply

    Damien

  • Hi Damien,

    Glad to hear you resolved the issue. Let us know if more issues come up.