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.

TMS320F28379D: Using DSS for automatic programming the chip

Part Number: TMS320F28379D
Other Parts Discussed in Thread: UNIFLASH

Tool/software:

Hi,

I am developing programming of two core chip TMS320F28379D for mass production purpose.
I had some unpleasent experience with DSLite and the command line environment generated from UniFlash.
The most painfull was when programming broke in the middle of programming flash or OTP memory leaving the device in strange state.
Generally it was possible to correct the state in CSS but it is time consuming. The percentage of incorrect programmed devices is significant.

That is why I decided to switch to DSS (Debug Server Scripting).

I already modified provided example called loadti (written in JavaScript) and succesfully programmed flash in both cores (so far without OTP).

I have some questions to DSS:

  1. How can I check and print progress of programming when I call debugSession.memory.loadProgram()?
    I found that there is no way to do that: https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/725300/ccs-how-to-access-the-debug-server-scripting-loadprogram-progress
    but DSLite and CCS are doing that.
  2. Why I get exception when I am trying to get checksums of memories? I tried debugSession.flash.getFlashChecksum() as well calculateChecksum().
    Log is below:
    +++Calculate checksum...
    getFlashChecksum: ENTRY
    waitUntil: ENTRY timeout: infinite
    C28xx_CPU1: Calculating Checksum...
    
    C28xx_CPU1: Main Flash Checksum: 0x8774
    
    C28xx_CPU1: Main ECC Checksum: 0x2121
    
    C28xx_CPU1: OTP Checksum: 0xFC00
    
    C28xx_CPU1: OTP ECC Checksum: 0xFF80
    
    waitUntil: RETURN
    waitUntil: ENTRY timeout: infinite
    waitUntil: RETURN
    SEVERE: Error getting data associated with "FLASHCHECKSUM": Unknown key
    Error code #4020, could reset target!
  3. Is there any specific sequence or requirements for working with OTP in DSS?

Kind regards,

Piotr Romaniuk

  • Hello,

    The most painfull was when programming broke in the middle of programming flash or OTP memory leaving the device in strange state.

    dslite should be pretty reliable. At least that is the goal. Can you provide more details of this failure such as any error messages and the techniques required to remedy the issue?

    How can I check and print progress of programming when I call debugSession.memory.loadProgram()?

    There still is not an easy way to do this. I suppose you can enable full verbosity to the console and you should get more diagnostic messages during the program load but there will also be a lot of noise in the messages.

    Why I get exception when I am trying to get checksums of memories? I tried debugSession.flash.getFlashChecksum() as well calculateChecksum().
    Log is below:
    SEVERE: Error getting data associated with "FLASHCHECKSUM": Unknown key
    Error code #4020, could reset target!

    This issue does not occur with dslite, correct? Which CCS version is being used.

    Is there any specific sequence or requirements for working with OTP in DSS?

    This is a question for the device experts. I would create a separate thread for this.

    Thanks

    ki

  • Hi Ki,

    dslite should be pretty reliable

    I observe about 5% of programming failures when I use DSLite. I used XDS100v3 and bash scripts in Linux.
    I run following programing sequence:
    1st call of DSLite - OTP & FLASH of cpu02,
    2nd call of DSLite - as above but for cpu01.

    Unfortunatelly DSLite is programming OTP before FLASH - it probably sorts data from one file in the order of ascending addresses [?]

    I just improved logging in my environment, so I will collect some statistics of issues and I will share with you exact messages.

    Now I only remember following, occuring separately errors:

    • ftdi driver returned bad status,
    • dslite complains about incorrect OTP ECC (2 cases: (1) OTP was completely unprogrammed, (2) LINKPOINTERS were moved to unprogrammed block) - it should be ok,
    • more often happens that programming sequence has been broken, so the chip has: 
      • partially programmed OTP,
      • programmed  OTP but not programmed FLASH
      • cpu02 programmed but cpu01 not
    Can you provide more details of this failure such as any error messages and the techniques required to remedy the issue?

    I fixed the chips in CCS, by starting debug session and performing manual unlock, erase and program operations for incorrectly programmed cores. This is time consuming and not an acceptable solution for mass production. As I wrote detailed error messages I will provide later.

    Further description is concerning DSS.

    There still is not an easy way to do this. I suppose you can enable full verbosity to the console and you should get more diagnostic messages during the program load but there will also be a lot of noise in the messages.

    I already use setting 'ALL' for printed messages but there is no progress displayed. LoadProgram() just blockes until it finishes, I was surprised because CCS as well as DSLite provide some progress information. It looks weird, because there are some large chunks but at least there is something. How the progress is implemented in these two programs, are they rely on DSS API? 

    This issue does not occur with dslite, correct? Which CCS version is being used.

    Yes, it was with DSS. I use DDS from CCS 12.1.0, so far windows version, later I switch to linux.

    Is there any specific sequence or requirements for working with OTP in DSS?

    This is a question for the device experts. I would create a separate thread for this.

    I just wanted to be sure if I can program OTP and FLASH from one file (.hex or .out) by executing LoadProgram() function. I know the chip site, my question was rather about programming API (i.e. DSS). 

    Kind regards,

    Piotr Romaniuk

    PS
    When I use DSS from Java, logs looks like below:

    C28xx_CPU2: Calculating Checksum...
    
    C28xx_CPU2: Main Flash Checksum: 0x4E91
    
    C28xx_CPU2: Main ECC Checksum: 0xE052
    
    C28xx_CPU2: OTP Checksum: 0xFC00
    
    C28xx_CPU2: OTP ECC Checksum: 0xFF80
    
    waitUntil: RETURN
    waitUntil: ENTRY timeout: infinite
    waitUntil: RETURN
    SEVERE: Error getting data associated with "FLASHCHECKSUM": Unknown key
    ERROR
    com.ti.ccstudio.scripting.environment.ScriptingException: Error getting data associated with "FLASHCHECKSUM": Unknown key
            at com.ti.debug.engine.scripting.Flash.getData(Flash.java:225)
            at com.ti.debug.engine.scripting.Flash.calculateChecksum(Flash.java:248)
            at test1.main(test1.java:34)

  • I observe about 5% of programming failures when I use DSLite.

    Ok, it is a sporadic error. Perhaps some obscure timing issue.

    As I wrote detailed error messages I will provide later.

    Thank you

    I already use setting 'ALL' for printed messages but there is no progress displayed. LoadProgram() just blockes until it finishes, I was surprised because CCS as well as DSLite provide some progress information. It looks weird, because there are some large chunks but at least there is something. How the progress is implemented in these two programs, are they rely on DSS API? 

    DSLite is separate from DSS. The CCS IDE can rely on several APIs including DSS and also calling GEL directly under the hood. 

    Can I see your DSS script? Can you rename to *.txt and attach it?

  • Hi Ki,

    Ok, it is a sporadic error.

    I have an update on programming error ratio, previous was estimated and approximate. The exact value is about 9%, it is still unacceptable for mass production.
    As one can calculate that it is 45 faulty devices from 500 series. Fixing them manually creates extra cost for out bussiness. The cost is significant.
    All TI tools, althrough they are much better and reliable then competition, they do not work without any issues. Sometimes strange behaviour or unexpected errors appear. The best is CCS, after that is DSLite and UniFlash is the worse. 

    Perhaps some obscure timing issue

    What do you mean? In what part?

    Error messages while using DSLite and XDS100v3 under Linux

    1. Break while OTP was programmed, OTP was unprogrammed - this is the most critical error that cause core lock without flash programing 
    Loading Program: /here-path-to-HEX-file
    Preparing...
    0 of 24 at 0x78000
    error: C28xx_CPU2: Error during Flash programming (Flash algoritm returned error code). OTP checksum mismatch detected. Operation Cancelled (4)
    error: C28xx_CPU2: File Loader: Memory write failed: Unknown error

    2. everything was properly connected
     fatal: IcePick_C_0: Error connecting to the target: (Error -151 @ 0x0) One of the FTDI driver functions used during the connect returned bad status or an error. The cause may be one or more of: no XDS100 is plugged in, invalid XDS100 serial number, blank XDS100 EEPROM, missing FTDI drivers, faulty USB cable. Use the xds100serial command-line utility in the 'common/uscif' folder to verify the XDS100 can be located. (Emulation package 12.7.0.00059)
    Failed: Operation was aborted

    DDS issues
    I slightly modified loadti DDS example. I added two instances for supporting two cores of the chip.
    Here is the script.

    /**
     * @main.js - This script mimics Texas Instruments' load6x stand-alone simulator
     *          base functionality but will work with any TI target (HW or
     *          Simulator) that is supported by Debug Server Scripting.
     */
    
    // Run loadti.
    testEnv = {};
    run();
    
    /**
     * Send message to the console and log (if logging is enabled)
     * 
     * @param {String}
     *            The string to output to the console/log.
     */
    function printTrace(string) {
        if (!testEnv.quietMode) {
            dssScriptEnv.traceWrite(string);
        }
    }
    
    /**
     * Get error code from the given exception.
     * 
     * @param {exception}
     *            The exception from which to get the error code.
     */
    function getErrorCode(exception) {
        var ex2 = exception.javaException;
        if (ex2 instanceof Packages.com.ti.ccstudio.scripting.environment.ScriptingException) {
            return ex2.getErrorID();
        }
        return 0;
    }
    
    /**
     * This function is called to perform some clean up before exiting (or aborting)
     * the script. It assumes that the the scripting environment and debug and
     * profile servers have been created.
     */
    function quit(retVal) {
    
        if (isDebugSession1) {
            // Close debug session.
            debugSession1.terminate();
        }
        if (isDebugSession2) {
            // Close debug session.
            debugSession2.terminate();
        }
        if (isDebugServer) {
            debugServer.stop();
        }
    
        date = new Date();
        printTrace("\nEND: " + date.toTimeString());
    
        if (testEnv.logFile != null) {
            // Close log.
            dssScriptEnv.traceEnd();
        }
    
        delete testEnv;
    
        // Terminate JVM and return main return value.
        java.lang.System.exit(retVal);
    }
    
    /*
     * Main function.
     */
    function run() {
        var inst;
    
        var errCode = 0;
        var retVal = 0;
        var date = 0;
        var defaultTimeout = -1;
    
        isDebugServer = false;
        isDebugSession1 = false;
        isDebugSession2 = false;
    
        load(java.lang.System.getenv("LOADTI_PATH") + "/getArgs.js");
        print("\nTESTING+++++\n");
        print(java.lang.System.getenv("LOADTI_PATH"));
    
        getArgs();
    
        // Create base scripting environment.
        dssScriptEnv = Packages.com.ti.ccstudio.scripting.environment.ScriptingEnvironment.instance();
    
        // Set overall script timeout value.
        dssScriptEnv.setScriptTimeout(defaultTimeout);
    
        // Enable logging to a file if specified.
        if (testEnv.logFile != null) {
            // NOTE: Log output folder must already exist.
            try {
                dssScriptEnv.traceBegin(testEnv.logFile, java.lang.System.getenv(
                        "LOADTI_PATH").replace("\\", "/")
                        + "/DefaultStylesheet.xsl");
                dssScriptEnv.traceSetFileLevel(Packages.com.ti.ccstudio.scripting.environment.TraceLevel.ALL);
            } catch (ex) {
                errCode = getErrorCode(ex);
                dssScriptEnv.traceWrite("Error code #" + errCode
                        + ", failed to enable logging for " + testEnv.logFile
                        + "\nLogging disabled!");
                testEnv.logFile = null;
            }
        }
    
        // Set console verbosity.
        if (testEnv.verboseMode) {
            dssScriptEnv.traceSetConsoleLevel(Packages.com.ti.ccstudio.scripting.environment.TraceLevel.ALL);
        }
    
        printTrace("\n***** DSS Generic Loader *****\n");
    
        date = new Date();
        printTrace("START: " + date.toTimeString() + "\n");
    
        // Configure the Debug Server.
        if (testEnv.setupCfgFile != null) {
            printTrace("Configuring Debug Server for specified target...");
    
            load(java.lang.System.getenv("LOADTI_PATH") + "/dsSetup.js");
    
            errCode = configureDebugServer(testEnv.setupCfgFile, dssScriptEnv);
            if (errCode != 0) {
                quit(errCode);
            }
    
            printTrace("Done");
    
            if (testEnv.file1 == null || testEnv.file2 == null) {
                dssScriptEnv.traceWrite("No target outfiles specified. Aborting!");
                quit(0);
            }
        } else {
            dssScriptEnv.traceWrite("No target setup configuration file specified. Aborting!");
            quit(1);
        }
    
        // Open Debug Server session.
        if (!isDebugServer) {
            debugServer = dssScriptEnv.getServer("DebugServer.1");
            isDebugServer = true;
        }
    
        // if specific cpu is specified
        if (testEnv.cpu1 != null) {
            try {
                printTrace("Specifying CPU1: " + testEnv.cpu1);
                debugSession1 = debugServer.openSession("*", testEnv.cpu1);
            } catch (error) {
                printTrace("Invalid CPU1 Name: " + testEnv.cpu1);
                quit(1);
            }
            isDebugSession1 = true;
        }
    
        if (testEnv.cpu2 != null) {
            try {
                printTrace("Specifying CPU2: " + testEnv.cpu2);
                debugSession2 = debugServer.openSession("*", testEnv.cpu2);
            } catch (error) {
                printTrace("Invalid CPU2 Name: " + testEnv.cpu2);
                quit(1);
                // printTrace("Switching to the default CPU1");
                // debugSession = debugServer.openSession("*", "*");
            }
            isDebugSession2 = true;
        }
    
        // Set the default File IO folder
        debugSession1.options.setString("FileIODefaultDirectory", testEnv.fileIOFolder);
        debugSession2.options.setString("FileIODefaultDirectory", testEnv.fileIOFolder);
    
        printTrace("TARGET1: " + debugSession1.getBoardName());
        printTrace("TARGET2: " + debugSession2.getBoardName());
        printTrace("Connecting to target...");
    
        // Connect to target. If target is simulator or already connected, a warning
        // will be reported.
        try {
            debugSession1.target.connect();
            debugSession2.target.connect();
        } catch (ex) {
            errCode = getErrorCode(ex);
            dssScriptEnv.traceWrite("Error code #" + errCode + ", could not connect to target!\nAborting!");
            quit(errCode != 0 ? errCode : 1);
        }
    
        if (testEnv.resetTarget) {
            printTrace("Resetting target...");
    
            // Reset target.
            try {
                debugSession1.target.reset();
                debugSession2.target.reset();
            } catch (ex) {
                errCode = getErrorCode(ex);
                dssScriptEnv.traceWrite("Error code #" + errCode + ", could reset target!\nAborting!");
                quit(errCode != 0 ? errCode : 1);
            }
        }
    //the part for programming flash ++++++++++++++++++++
        try {
            print("\n***** programming CPU02 **************************");
            printTrace("Loading " + testEnv.file2);
            debugSession2.memory.loadProgram(testEnv.file2);// , testEnv.argvArgs);
            print("\n***** programming CPU01 **************************");
            printTrace("Loading " + testEnv.file1);
            debugSession1.memory.loadProgram(testEnv.file1);// , testEnv.argvArgs);
        } catch (ex) {
            errCode = getErrorCode(ex);
            printTrace("Error code #" + errCode + ", " + file1 + "/" + file2 + " load failed!\nAborting!");
            quit(errCode != 0 ? errCode : 1);
        }
    //the part for calculating checksums ++++++++++++++++
        print("+++Calculate checksum...");
        try{
            //debugSession1.flash.calculateChecksum();
            print( debugSession1.flash.getFlashChecksum());
        }catch(ex){
            errCode = getErrorCode(ex);
            dssScriptEnv.traceWrite("Error code #" + errCode + ", could reset target!\nAborting!");
            quit(errCode != 0 ? errCode : 1);
        }
        printTrace("Done");
    
        // End automation.
        quit(retVal);
    }
    

    In the code there are two parts:
    1. one for programming flash,
    2. one for calculating checksums

    I commented out one of them to generate corresponding issues, i.e. checksum exception or programming without any progress.

    The behavior is the same if I use only one core.

    The exception is also generated when I call DSS from Java:

    // Import all DSS packages for the Debug Server
    import com.ti.ccstudio.scripting.environment.*;
    import com.ti.debug.engine.scripting.*;
    
    
    
    public class test1 {
    
        public static void main(String[] args)
        {
            // Create our scripting environment object - which is the main entry point into any script and
            // the factory for creating other Scriptable servers and Sessions
            ScriptingEnvironment dssScriptEnv = ScriptingEnvironment.instance();
    
            
                DebugServer debugServer = null;
                DebugSession debugSession = null;
    
                try {
                    dssScriptEnv.traceSetConsoleLevel(com.ti.ccstudio.scripting.environment.TraceLevel.ALL);
                    System.out.println("\nGetting access to debug server...");
                    // Get the Debug Server and start a Debug Session
                    debugServer =  (DebugServer)dssScriptEnv.getServer("DebugServer.1");
                    //debugServer.setConfig("./TMS320F28379D__PR-xds100v3.ccxml");
                    //debugServer.setConfig("./TMS320F28379D__PR-xds110.ccxml");
                    debugServer.setConfig("./TMS320F28379D__PR-xds110-opto.ccxml");
                    System.out.println("\nOpening session...");
                    debugSession = debugServer.openSession("*","C28xx_CPU2");
                    System.out.println("\nOpening connecting to core1...");
                    debugSession.target.connect();
                    System.out.println("\ncore reset");
                    debugSession.target.reset();
                  //  System.out.println("\nLoading program...");
                  //  debugSession.memory.loadProgram("./secured-no-cpulock/Bootloader_cpu02.out");
                    debugSession.flash.calculateChecksum();
                    
                } catch (ScriptingException e) {
                    dssScriptEnv.traceWrite("ERROR");
                    e.printStackTrace();
                }
                
                System.out.println("\nFinilizing...");
                try{
                        if( !( debugSession == null )){
                            debugSession.terminate();
                        }
                        if( !(debugServer == null)){
                            debugServer.stop();
                        }
                }catch(ScriptingException e) {
                    dssScriptEnv.traceWrite("ERROR");
                    e.printStackTrace();
                }
                System.out.println("\nFinished\n");
            }    
            
    }
    

    Regards,
    Piotr Romaniuk

  • Thank you for the added details. I will be following up with some experts. I will keep you updated as I receive more information.

  • Ki,

    the matter is urgent.
    This week 13 boards were incorrectly programmed. FLASH or OTP programming was interrupted.

    Regards,
    Piotr Romaniuk

  • Sorry for the delayed response. I have some answers.

    For the below:

    SEVERE: Error getting data associated with "FLASHCHECKSUM": Unknown key

    This is due to the flash.calculateChecksum() call. This API is to support old legacy C2000 device. While this call will also get the checksum on more modern C2000 devices, the API relies on a FLASHCHECKSUM property that does not exist for these more modern devices. Hence the exception. The exception can be caught and ignored. A better option is to use flash.performOperation(“CalculateChecksum”) instead, which will not cause an exception.

    2. everything was properly connected
     fatal: IcePick_C_0: Error connecting to the target: (Error -151 @ 0x0) One of the FTDI driver functions used during the connect returned bad status or an error. The cause may be one or more of: no XDS100 is plugged in, invalid XDS100 serial number, blank XDS100 EEPROM, missing FTDI drivers, faulty USB cable. Use the xds100serial command-line utility in the 'common/uscif' folder to verify the XDS100 can be located. (Emulation package 12.7.0.00059)
    Failed: Operation was aborted

    dslite was unable to detect the XDS100 debug probe. This can happen if the XDS100 is not properly enumerated by the host OS or for some reason the connection was dropped. I don't have a good explanation on why this could all of a sudden occur if things were already working fine. I assume when this happens that xds100serial utility does not detect anything.

    Is there any specific sequence or requirements for working with OTP in DSS?

    I am still working on this. I'll likely need to reassign this thread to the device flashing experts.

  • Hi Ki,

    This is due to the flash.calculateChecksum() call. This API is to support old legacy C2000 device. While this call will also get the checksum on more modern C2000 devices, the API relies on a FLASHCHECKSUM property that does not exist for these more modern devices. Hence the exception. The exception can be caught and ignored. A better option is to use flash.performOperation(“CalculateChecksum”) instead, which will not cause an exception.

    How can I read checksums? I see in the API documentation getFlashChecksum() and getOTPChecksum() but how can I get ECCs checksums?

    I assume when this happens that xds100serial utility does not detect anything.

    FDTI drivers always was stable and reliable for me. Maybe there is some issue on XDS100v3?

    I have some statictics from boards that were incorrectly programmed. I have no logs yet but I following cases:

    1. Flash and OTP unprogrammed at all,
    2. Only LINKPOINTERS in OTP programmed (correct values), FLASH was empty
    3. OTP correctly programmed, but FLASH empty
    4. OTP correct but FLASH partially programmed (I compared checksum) 

    All these cases except [1] look like programming sequence was interrupted. The case [1] looks like connection to xds was not performed.

    Regards,
    Piotr Romaniuk

  • How can I read checksums? I see in the API documentation getFlashChecksum() and getOTPChecksum() but how can I get ECCs checksums?

    flash.calculateChecksum() will output all the checksum values to the console. However, I assume your want to get the checksum value in your script so that you can assign it to a variable. There is a way to do this with the accessing the debugger properties. I will look into getting this info for you.

    I have some statictics from boards that were incorrectly programmed. I have no logs yet but I following cases:

    1. Flash and OTP unprogrammed at all,
    2. Only LINKPOINTERS in OTP programmed (correct values), FLASH was empty
    3. OTP correctly programmed, but FLASH empty
    4. OTP correct but FLASH partially programmed (I compared checksum) 

    All these cases except [1] look like programming sequence was interrupted. The case [1] looks like connection to xds was not performed.

    I see you created a related thread.

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1397762/tms320f28379d-dslite-programs-flash-and-otp-in-wrong-order

    Thanks for this and I will have a C2000 flash expert take a look.

  • There is a way to do this with the accessing the debugger properties. I will look into getting this info for you.

    Try something like:

    var checksum = debugSession.flash.performOperation("CalculateChecksum");
            
    // Checksum values
    var main = debugSession.options.getString("FlashCRCMainValue");
    var ecc = debugSession.options.getString("FlashCRCECCValue");
    var otp = debugSession.options.getString("FlashCRCOTPValue");
    var otp_ecc = debugSession.options.getString("FlashCRCOTPECCValue");

  • Hi Ki

    thank you for the solution for the checksums.
    I am not marking it as "This resolved my issues" because there are still open other questions and I don't want this thread to be closed yet.

    Regards,

    Piotr Romaniuk

  • I am not marking it as "This resolved my issues" because there are still open other questions and I don't want this thread to be closed yet.

    Let's use your other thread for the other flash OTP issues. I have brought it to the attention of the C2000 experts.