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.

TMS320F28388D: Structure not update in Debug expression window

Part Number: TMS320F28388D


Hello,

we have some Code running on an interrupt of CPU1 (interrupt is triggered by CPU2). Within the interrupt we toggle a GPIO and we can see it toggling in the expression-window. So we know that the intrrupt is running.

We also see changes in the "AdccResultRegs.ADCRESULT0" register, when changing the analog input value.

// *************************************************************************************************
// *
// * Function name : Cpu1Task3Calc()
// * Creation date : 2022-06-13
// * Programmer    : Ralf Rink
// *
// * Description   : Task 3 der CPU1, sampling period = 128 x system sampling period
// *                 mit einer CONTROL_LOOP_CYCLE_TIME_NS von 31,25µs = 4 ms
// *                 Poti-Handling zum Sollpositionen-Generator
// *
// *************************************************************************************************
inline void Cpu1Task3Calc(IPC_CPU1Task3DataIn* input, IPC_CPU1Task3DataOut* output)
{
    static uint16_t  alive = 1;       // Umschaltung zwischen Still-Alive-LED und Laufzeit-Messung
    static uint16_t  ledCounter = 0;  // Variable für Still-Alive-LED


    if(alive == 0)
    {
        // Laufzeit-Messung
        GpioDataRegs.GPASET.bit.GPIO3 = 1;
    } else
    {
        // CPU1-Alive-LED (0,5 Hz / 2000 ms)
        if(ledCounter >= STILL_ALIVE_LED_UPDATE_LOOPS_CPU1_TASK3)
        {
            GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1;
            ledCounter = 0;
        }
        ledCounter++;
    }

    SOLLPOSGENERATOR::callADC(&SOLLPOSGENERATOR::sollPosGen.poti);

    if(SOLLPOSGENERATOR::sollPosGen.poti.valueChanged)
    {
        SOLLPOSGENERATOR::potiNewCalcInit(&paramsUser.kinematics[0],
                                          &SOLLPOSGENERATOR::sollPosGen.poti,
                                          &SOLLPOSGENERATOR::sollPosGen.kinematics.calc[0],
                                          &SOLLPOSGENERATOR::sollPosGen.kinematics,
                                          &SOLLPOSGENERATOR::sollPosGen.time[0],
                                          &SOLLPOSGENERATOR::sollPosGen.time[1],
                                          &SOLLPOSGENERATOR::sollPosGen.timeBuffer);
    }

    // output->data = input->data + 1;

    if(alive == 0)
    {
        // Laufzeit-Messung
        GpioDataRegs.GPACLEAR.bit.GPIO3 = 1;
    }
}

In the function "SOLLPOSGENERATOR::callADC(&SOLLPOSGENERATOR::sollPosGen.poti)" we copy the "AdccResultRegs.ADCRESULT0" into a global variable "AdccResult0". This variable always shows zero instead of the same value like in "AdccResultRegs.ADCRESULT0". Further on no value of our structure "SOLLPOSGENERATOR::sollPosGen" gets updated.

int32_t SOLLPOSGENERATOR::callADC(Potentiometer* pPoti)
{
    int32_t     errorCode = 0;
    static bool Stillstand = true;
    static bool Test = true;


    // start conversions immediately via software, ADCA
    AdccRegs.ADCSOCFRC1.all = 0x0003; //SOC0 and SOC1
    // Store results
    AdccResult0 = AdccResultRegs.ADCRESULT0;

    if (((AdccResult0 - pPoti->value) > 90) || ((pPoti->value - AdccResult0) > 90 ))
    {
        pPoti->value = AdccResult0; //int32 wert mit uint16 wert
        Stillstand = false;
        //pPoti->PotiValueChanged = true;
    } else if((!Stillstand) ) //&& (pPoti->PotiValue == AdccResult0)
    {
        //pPoti->PotiValueChanged = true;
        if((!Stillstand) && (!Test))
        {
            pPoti->valueChanged = true;
            Stillstand = true;
            Test = true;
        }
        Test = false;
    }

    return errorCode;
}

Can somebody help us to solve this (debug-)problem?

Kind regards Ralf

  • Hello Ralf,

    In your callADC function, you are reading the ADC result register immediately after forcing the conversion. The ADC conversion takes some time to happen, depending on your configured acquisition window size (ACQPS) + the actual conversion time as specified in the datasheet. You should add the following lines before reading the result register:

    // Wait for ADC conversion to complete
    while ((AdccRegs.ADCINTFLG.all & 0x0003) != 0x0003);
    // Clear interrupt flag
    AdccRegs.ADCINTFLGCLR.all = 0x0003;

    This should resolve the issue.

    Best regards,
    Ibukun

  • Hello Ibukun,

    we are calling the conversion every 4 ms. So should see the "old" adc-result in the variable, bu we don't. In addition to that other variables (with no adc-values) don't get updated, too.

    Maybe som settings are wrong for debugging in periodic called interrupts?

    Kind regards Ralf

  • Hello Ralf,

    Thanks for the clarification. A couple of questions:

    • Can you confirm that when you set a debug breakpoint at line 11 in your ISR, you are able to observe the previous conversion result in the ADCRESULT0 register for ADCC?
    • Where and how is the variable AdccResult0 defined?
    • What other variables are not getting updated?

    Thanks,
    Ibukun

  • Hello Ibukun,

    - when  i set a breakpoint, i can see the ADCRESULT0 register for ADCC changing between two following function calls. With "continuous refresh" the ADCRESULT0 register gets also refreshed without using a breakpoint

    - the variable AdccResult0 is globally declared within the same cpp-file.

    /**
     * @file ADC_SPG.cpp
     * @author Wilko.Moritz
     * @date 16.04.2021
     * @brief Implementation.
     *
     * For a detailed description see the belonging header file.
     */
     
    
    #include "f28x_project.h"
    #include "f2838x_globalprototypes.h"
    #include "f2838x_adc.h"
    #include "adc.h"
    
    #include "SollPosGenerator/SollPosGenerator.h"
    
    
    using namespace SOLLPOSGENERATOR;
    
    Uint16 AdccResult0;
    
    
    int32_t SOLLPOSGENERATOR::callADC(Potentiometer* pPoti)
    {
        int32_t     errorCode = 0;
        static bool Stillstand = true;
        static bool Test = true;
    
    
        // Wait for ADC conversion to complete
        //while ((AdccRegs.ADCINTFLG.all & 0x0003) != 0x0003);
        // Clear interrupt flag
        //AdccRegs.ADCINTFLGCLR.all = 0x0003;
        // Store results
        AdccResult0 = AdccResultRegs.ADCRESULT0;
    
        if (((AdccResult0 - pPoti->value) > 90) || ((pPoti->value - AdccResult0) > 90 ))
        {
            pPoti->value = AdccResult0; //int32 wert mit uint16 wert
            Stillstand = false;
            //pPoti->PotiValueChanged = true;
        } else if((!Stillstand) ) //&& (pPoti->PotiValue == AdccResult0)
        {
            //pPoti->PotiValueChanged = true;
            if((!Stillstand) && (!Test))
            {
                pPoti->valueChanged = true;
                Stillstand = true;
                Test = true;
            }
            Test = false;
        }
    
        // start conversions immediately via software, ADCA
        AdccRegs.ADCSOCFRC1.all = 0x0003; //SOC0 and SOC1
    
        return errorCode;
    }

    The other variable is a within a namepace decalred variable (=> SollPosGenerator sollPosGen;). "SollPosGenerator" is a own #typedef-structure.

    Kind regards Ralf

  • Hello Ralf,

    I'm looking further into this for you. I have attempted to replicate your scenario with the namespace setup but I have no issue seeing the global variable get updated. I will also try to consult with some of our other experts here.

    Best regards,
    Ibukun

  • Hello Ibukun,

    i have found out, that an .bss section in the linker command file was initialized in the source code as CLA program code. After changing it to CLA data memory the updating of the variables does work. So this solved my problem.

    A autogenerated source code based of the settings in the linker command file would be helpful.

    Thanks and kind regards Ralf Rink

  • Hello Ralf,

    Glad to hear you were able to resolve this issue. My suspicion was that there was some sort of compiler/linker issue as well.

    Best regards,
    Ibukun