SPRACZ6 December   2021 TDA4VH-Q1 , TDA4VH-Q1 , TDA4VM , TDA4VM , TDA4VM-Q1 , TDA4VM-Q1

 

  1.   1
  2.   2
  3.   3
    1.     4
    2.     5
  4.   6
  5.   7
    1.     8
    2.     9
  6.   10
  7.   11

JTAG Flashing Application on MCU1_0

After converting silicon to HS-SE and unlocking the JTAG, there is still need to design a JTAG flashing application on MCU1_0, which can load the binary from customer HSM and program to OSPI. In normal boot process, the system firmware should be loaded in DMSC first, then boot the MCU and other cores. But the DMSC ROM sets up a 3-minutes watchdog timer, the MCU boot needs to complete within this period, otherwise the WDT reset will occur and reboot the whole system. In the third bullet in this section, the keywriter1 and kerywriter2 can successfully be flashed because the binary size is small. Flashing can be finished in 3-minutes, but due to a bigger image size, you cannot flash all firmware binaries in 3-minutes. So, in order to avoid 3-minute watchdog timeout, you need to port the flashing application to MCU domain MCU1_0, such that it does not load TIFS to DMSC and also does not have dependency on SciClient services. The flashing flow shown in Figure 4-2 and all of the following source code can be downloaded from the following URL: https://www.ti.com/lit/zip/spracz6.

Figure 4-2 JTAG Flashing Application Process

The flash tools based on Windows system and including three parts:

  • The first part, you need to use emulation tools to connect the TDA4 via JTAG, then using CCS .js and .gel file to connect/reset/halt the MCU1_0, initialize the DDR and configure everything from MCU1_0, you can design the part1 process by reference from the file in default SDK, which located in ${PSDKRA_PATH}/pdk/packages/ti/drv/sciclient/tools/ccsLoadDmsc/j721e/launch.js Also, you can refer to the below code to achieve the function:

    This part is a little difference for HS-FS and HS-SE device, in case of HS-FS, the DDR is initialized by .js file in no boot mode, but for HS-SE device, the system is working in the OSPI boot mode, and the DDR is initialized by system image.

    function connectTargets()
    {
        script.setScriptTimeout(200000);
        updateScriptVars();
        print("Connecting to MCU Cortex_R5_0!");
        // Connect the MCU R5F
        dsMCU1_0.target.connect();
         // Reset the R5F to be in clean state.
        dsMCU1_0.target.reset();
        dsMCU1_0.target.halt();
        dsMCU1_0.expression.evaluate("J7ES_LPDDR4_4266MTs_Config()");
    }
    function flashOspi()
    {
        var configFileObj = new File("Configuration.txt");
        print("Starting Flashing !");
        if (configFileObj.exists())
    {
    var scanner = new Scanner(configFileObj);
    var ospiOffset;
    var ospiFile;
    while (scanner.hasNextLine())
    {
             var data = scanner.nextLine();
             var parts = data.split(" ");
             ospiOffset = parseInt(parts[0], 16)
             ospiFile = parts[1];
             var file = new File(ospiFile);
             fileSize = file.length();
            dsMCU1_0.memory.writeWord(0x0, 0x80000000, ospiOffset);
            dsMCU1_0.memory.writeWord(0x0, 0x80000004, fileSize);
            dsMCU1_0.memory.loadRaw(0, 0x90000000, ospiFile, 32, false);
            print("Flashing "+ospiFile+" of size " + fileSize + " at offset " + ospiOffset);
            // Connect the MCU R5F
            dsMCU1_0.target.connect();
            print("Running the OSPI load program from R5!");
            // Load the board configuration init file.
            dsMCU1_0.memory.loadProgram("bin/uart_j721e_evm_flash_programmer_release.xer5f");
           // Halt the R5F and re-run.
           dsMCU1_0.target.halt();
          dsMCU1_0.target.reset();
          dsMCU1_0.target.restart();
          dsMCU1_0.target.run();
          // Reset the R5F to be in clean state.
          dsMCU1_0.target.reset();
     }
        }
            scanner.close();
        }
        else
        {
            print("File Does not exist!");
        }
    }
    function disconnectTargets()
    {
        updateScriptVars();
        // Reset the R5F to be in clean state.
    dsMCU1_0.target.reset();
    }
    function doEverything()
    {
        printVars();
        connectTargets();
        disconnectTargets();
        flashOspi();
        print("Burning is complete, happy to go !!!");
    }
  • The second part is mainly used to specify the file path and flashing address. The flashing tools in the third bullet in this section will read this configuration file and scan line by line, used to flash binary to the specified address, using the file format shown below:
    0 image/se/tiboot3.bin
    80000 image/se/tifs.bin
    E1000 image/se/app
    1E1000 image/se/app3_0
    F5E000 image/se/lateapp1
    175E000 image/se/lateapp2
  • The third part is actual flashing application running in MCU1_0, this application will be running in OCMC, initialize the OSPI interface load the binary from PC to TDA4 DDR and flashing it to OSPI. You can find the complete patch as attached and use the following steps to compile.
    $ cp ccs_main.c ${PSDKRA_PATH}/pdk_jacinto_07_00_00/packages/ti/board/utils/uniflash/target/src
    $ cp uart_make.mk ${PSDKRA_PATH}/pdk_jacinto_07_00_00/packages/ti/board/utils/uniflash/target/build
    $ cd  ${PSDKRA_PATH}/pdk_jacinto_07_00_00/packages/ti/build
    $ make -s   PLATFORM=j721e_evm BUILD_PROFILE=release board_utils_uart_flash_programmer

Based on the current backup-read keywriter mechanism and MCU1_0 flashing application, see the steps in Figure 4-3 to complete the flashing process.

Figure 4-3 Whole Flashing Process