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: Requesting information regarding code dump into flash through CAN.

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi,

To dump code into flash of a 379D controller, we are currently use debugger via JTAG. Now the requirement is such that a common point of code dump should be done and there are multiple DSPs, so each of this DSP would receive the required code. All the DSPs are connected to a common CAN A bus. Given the document from TI "sprad51a" about CAN Flash Programming of c2000 microcontrollers, we are following the steps. However, I stumbled across a few doubts which needs to be clarified:

1. My understanding is after setting the GPIO 72 and 84 to Get Boot Mode (both GPIOS pulled high through SW1), we need to set the Z1 BOOTCTRL register BMODE and KEY to 0x07 and 0x5A in order to receive code into flash of DSP through CANA. Now, question regarding this is, how do I program the Boot Mode in Launch pad? Like my understanding is we need to set up the boot mode before the application code begins. Now the BOOTCTRL register is Read only, so how do I write to it and if so, when to write (in which file). I saw that there are some OTP based concepts, I am not clear about it. 

2. After I am done with this, from the documentation, I am trying to use the dcan flash programmer. However, the examples specified in the document as:  dcan_flash_programmer.exe -d f28003x -k flash_kernel_ex5_dcan_flash_kernel.txt -a led_ex1_blinky.txt -v . I have found the flash kernel and i have generated the led_ex1_blinky.txt from the application code. MY question is whether I have selected the correct settings while generating the application.txt? I am attaching the screenshots of what options I have selected.


3. If the above steps are correct, then I have the proper application txt. Now I open command line and write the command under the folder where dcan flash programmer.exe is present. Now, when I do that I only change the device name from f28003x to f2837xd as per my DSP. However, it does not recognize the device name and the following message pops up:

-d <device> - The name of the device to load to.
f28003x, f28p65x, f280015x
Kindly tell me what should be the device name for the TMS320F28379D Dsp. Also, let me know whether we need to modify the flash kernel anyways for this particular dsp as I am not sure whether the current flash kernel can be used or not with F28379D dsp? And if so, what should be modified in particular? Same query about the dcan flash programmer.exe also.

4. With respect to point 1, I have tried to edit BOOTCTRL register from the Tools -- > ON chip flash settings after debugging through debugger. In that I came across Z1 OTPBOOTCTRL. It was originally 0x FFFFFFFF. I re wrote that as 0x 0000 075A to enable it to work through CAN dump mode. However, even after doing that, when I debug through a debugger, the code goes to RAM and code runs. Shouldn't it be only working if dump code through CAN A only as I reprogrammed the Z1 BOOT CTRL get boot mode. Or does dumping code through debugger over writes all these? But when I comment RAM linker cmd file and use Flash linker cmd file, the code goes to it but it doesnt run. It says 

  • Now the BOOTCTRL register is Read only, so how do I write to it and if so, when to write (in which file).

    The device has one register called EMU_BOOTCTRL for debugging purpose. When debugging, EMU_BOOTCTRL is the emulation equivalent of the BOOTCTRL register and allows users to experiment with different boot modes without writing to OTP memory.

    The EMU_BOOTCTRL is located at 0x0000_0D00

    You can write 0xFFFF to 0x0D00, and 0x5AFF to 0x0D01

  • . MY question is whether I have selected the correct settings while generating the application.txt? I am attaching the screenshots of what options I have selected.

    1. You are correct, The easiest way to generate txt file is to use the post-build of CCS:

    "${CG_TOOL_HEX}" "${BuildArtifactFileName}" -boot -sci8 -a -o "${BuildArtifactFileBaseName}.txt"

    2. To generate txt file using C2000 HEX utility, please check "boot mode" and "SCI8"

  • MY question is whether I have selected the correct settings while generating the application.txt?

    1. Correct. The easiest way to generate txt file is to use the post-build property:

    "${CG_TOOL_HEX}" "${BuildArtifactFileName}" -boot -sci8 -a -o "${BuildArtifactFileBaseName}.txt"

    2.Another way is to use the C2000 Hex Utility

    Please check the "boot mode" and "SCI8"

  • ell me what should be the device name for the TMS320F28379D Dsp

    Please try "-d f2837xD". You can the same flash kernel

  • 4. With respect to point 1, I have tried to edit BOOTCTRL registe

    Please refer to my previous message. 

  • Hello QJ,

    I tried this in the command prompt, however its still not working. Attached Screenshot.


    Also do let me know, at which stage do I have to use PEAK PCAN, and where can I download it from install it?

  • Also, I want to dump my code through CAN, so as per the given table, I see I have to enter:
    0x0000 to 0x0D00 (Boot mode pins to be selected default as 72 and 84)
    0x075A to 0x0D01(Boot Mode as CAN 0 and Key 5A)

    Shouldnt this be the correct configuration? Or am I misunderstanding, could you please clarify?

  • Hi,

    I read the source code of dcan_flash_programmer.cpp in C2000Ware folder. The programmer supports F28003x, and P65x, but doesn't support F2837x device. 

  • You can add F2837x device to dcan_flash_programmer.cpp, then recompile the project using VC++

    1.  if (g_bf28003x || g_bf28p65x || g_bf280015x || g_bf28379x) {
    VERBOSEPRINT(_T("\nInitializing CAN USB-C1 with Bit rate set to 1 MBit/s\n"));
    if (g_bf28003x) {
    sleep_time = 10; // in msec
    }
    else if (g_bf28p65x) {
    sleep_time = 1; // in msec
    }
    else if (g_bf280015x) {
    sleep_time = 1; // in msec
    }

    else if (g_bf28379x) {
    sleep_time = 1; // in msec
    }

    2.  if (wcsncmp(g_pszDeviceName, (wchar_t*)L"f28p65x", 7) && wcsncmp(g_pszDeviceName, (wchar_t*)L"f28003x", 7) && wcsncmp(g_pszDeviceName, (wchar_t*)L"f280015x", 8)  && wcsncmp(g_pszDeviceName, (wchar_t*)L"f28379x", 7))
    {
    _tprintf(_T("\nUnrecognized device name: X%sX\n\n"), g_pszDeviceName);
    ShowHelp();
    ExitApp(2);
    }

    3. else if (!wcsncmp(g_pszDeviceName, (wchar_t*)L"f28379x", 7))
    {
    g_bf021 = true;
    g_bf28379x = true;
    }

  • The C2000Ware doesn't have DCAN Flash Kernel example for F28479x, you need to develop one for your application.

    Please refer to the DCAN flash kernel for other devices:

    C:\ti\c2000\C2000Ware_5_05_00_00\driverlib\f28p65x\examples\c28x_dual\flash_kernel

  • Hello QJ,

    Thanks for reverting back. I will update the CPP source file for dcan_flash_programmer. However regarding the DCAN flash kernel, can you suggest the modifications that needs to be done in the flash kernel. I have seen the flash kernel for 28p65 device as you mentioned in the examples. However, I see there are quite a lot of files. Out of those, as per my understanding, I have modified the DCAN_Boot.c, code_start_branch.asm and Linker command file. The files are attached for your reference. These have been modified for my target Device of 379D Dsp. I am getting some build errors which I am solving one by one. Could you please go through the files and let me know if any further modifications need to be done in terms of functioning of the flash kernel. Also, kindly suggest if any more files are required for the purpose. Thanks.


    //###########################################################################
    //
    // FILE:    DCAN_Boot.c
    //
    // TITLE:   DCAN (CAN) Bootloader
    //
    // Functions involved in running CAN bootloader
    //
    //
    //###########################################################################
    // $TI Release: $
    // 
    // 
    // C2000Ware v5.05.00.00
    //
    // Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    
    //###########################################################################
    // Modified DCAN_Boot.c for F28379D DSP with Multibank Flash Erase and Alt GPIOs
    //###########################################################################
    
    #include "driverlib.h"
    #include "device.h"
    #include "F021_F2837xD_C28x.h"
    
    
    #define CAN_RX_MSG_ID          0x1U
    #define CAN_TX_MSG_ID          0x2U
    #define CAN_MSG_OBJ_1          1U
    #define CAN_MSG_OBJ_2          2U
    #define DCAN_MAX_PAYLOAD_BYTES 8U
    
    #define DCAN_BYTE_MASK         0xFFU
    #define DCAN_DWORD_SHIFT       16U
    #define DCAN_2ND_WORD_INDEX    2U
    
    #define MAX_FLASH_BANKS        2U
    #define Sector8KB_u32length    0x1000U
    
    uint16_t flashEraseError = 0;
    
    typedef enum
    {
        DCAN_DATA_SIZE_16BITS = 2U,
        DCAN_DATA_SIZE_32BITS = 4U
    } DCAN_dataTypeSize;
    
    typedef struct {
        uint16_t data[DCAN_MAX_PAYLOAD_BYTES];
    } DCAN_RxBufElement;
    
    static DCAN_RxBufElement rxMsg;
    uint16_t msgBufferIndex = 0;
    
    uint16_t (*GetWordData)(void);
    
    int _args_main(void)
    {
        return 0;
    }
    
    static void DCAN_Boot_GPIO(uint32_t altMode)
    {
        uint32_t rxPin, txPin;
        if (altMode == 1) {
           /* rxPin = 70; txPin = 71;  // example alternate GPIOs
            GPIO_setPinConfig(GPIO_70_CANA_RX);
            GPIO_setPinConfig(GPIO_71_CANA_TX);*/
        } else {
            rxPin = 30; txPin = 31;
            GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
            GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
        }
        GPIO_setPadConfig(rxPin, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(txPin, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(rxPin, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(txPin, GPIO_QUAL_ASYNC);
    }
    
    static void DCAN_Boot_Init(uint32_t btrReg)
    {
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
        CAN_initModule(CANA_BASE);
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);
        if (btrReg != 0) {
            HWREG(CANA_BASE + CAN_O_BTR) = btrReg;
        }
        CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);  //  or use CAN_TEST_SILENT, etc.
        CAN_startModule(CANA_BASE);
        CAN_setupMessageObject(CANA_BASE, CAN_MSG_OBJ_1, CAN_RX_MSG_ID,
                               CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0,
                               CAN_MSG_OBJ_RX_INT_ENABLE, DCAN_MAX_PAYLOAD_BYTES);
        CAN_setupMessageObject(CANA_BASE, CAN_MSG_OBJ_2, CAN_TX_MSG_ID,
                               CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0,
                               CAN_MSG_OBJ_NO_FLAGS, DCAN_MAX_PAYLOAD_BYTES);
    }
    
    void DCAN_readMessage()
    {
        while (!CAN_readMessage(CANA_BASE, CAN_MSG_OBJ_1, rxMsg.data)) {}
        msgBufferIndex = 0;
    }
    
    uint32_t DCAN_getDataFromBuffer(DCAN_dataTypeSize dataTypeSize)
    {
        uint32_t data = 0;
        uint16_t shift = 0;
        uint16_t i = 0;
        for (i = 0; i < dataTypeSize; ++i)
        {
            if ((msgBufferIndex + i) >= DCAN_MAX_PAYLOAD_BYTES)
            {
                DCAN_readMessage();
                i = 0;
                data = 0;
                shift = 0;
            }
            data |= ((uint32_t)rxMsg.data[msgBufferIndex++] & DCAN_BYTE_MASK) << shift;
            shift += 8;
            if (i == DCAN_2ND_WORD_INDEX - 1) data <<= DCAN_DWORD_SHIFT;
        }
        return data;
    }
    
    static uint16_t DCAN_GetWordData(void)
    {
        DCAN_readMessage();
        return rxMsg.data[0];
    }
    
    static void DCAN_SendWordData(uint16_t data)
    {
        uint16_t txData[8] = {data, 0};
        CAN_sendMessage(CANA_BASE, CAN_MSG_OBJ_2, 1, txData);
    }
    
    void EraseFlashBanks(uint16_t numBanks, uint16_t *banks)
    {
        Fapi_StatusType oReturnCheck;
        Fapi_FlashStatusWordType oFlashStatusWord;
        EALLOW;
        Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, 3);
        EDIS;
        Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
        uint16_t i=0;
        for (i = 0; i < numBanks; i++) {
            uint32_t baseAddr = 0x080000 + (banks[i] * 0x10000);
            oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseBank, (uint32_t *)baseAddr);
            while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady) {}
            oReturnCheck = Fapi_doBlankCheck((uint32_t *)baseAddr, 0x10000 / 4, &oFlashStatusWord);
            if (oReturnCheck != Fapi_Status_Success) {
                flashEraseError++;
            }
        }
    }
    
    void CopyData(void)
    {
        struct {
            uint32_t DestAddr;
            uint16_t BlockSize;
        } BlockHeader;
    
        BlockHeader.BlockSize = (*GetWordData)();
        while (BlockHeader.BlockSize != 0x0000U)
        {
            BlockHeader.DestAddr = DCAN_getDataFromBuffer(DCAN_DATA_SIZE_32BITS);
            uint16_t i = 0;
            for (i = 0; i < BlockHeader.BlockSize; ++i)
            {
                uint16_t word = (*GetWordData)();
                *(uint16_t *)BlockHeader.DestAddr = word;
                BlockHeader.DestAddr += 1;
            }
            BlockHeader.BlockSize = (*GetWordData)();
        }
    }
    
    uint32_t DCAN_Boot(uint32_t btrReg)
    {
        uint16_t flashBanksToErase[MAX_FLASH_BANKS] = {0, 1};
        DCAN_Boot_GPIO(0);
        DCAN_Boot_Init(btrReg);
        GetWordData = DCAN_GetWordData;
    
        DCAN_readMessage();
        if ((rxMsg.data[0] | (rxMsg.data[1] << 8)) != 0x08AA)
            return 0xFFFFFFFF;
    
        DCAN_readMessage();
        DCAN_readMessage();
        uint32_t entryAddr = DCAN_getDataFromBuffer(DCAN_DATA_SIZE_32BITS);
    
        EraseFlashBanks(2, flashBanksToErase);
        if (flashEraseError > 0)
            return 0xFFFFFFFE;
    
        CopyData();
        return entryAddr;
    }


    //###########################################################################
    ;// FILE:   f2837xD_codestartbranch.asm
    ;// TITLE:  Branch for redirecting code execution after boot
    ;//         Modified from f28p65x for F28379D Flash Kernel
    ;//###########################################################################
    
    WD_DISABLE  .set  1    ; set to 1 to disable watchdog, else set to 0
    
        .ref    _c_int00
        .global code_start
        .ref    DCAN_Boot
        .global ExitBoot
    
        .sect   "codestart"
        .retain
    
    code_start:
        .if WD_DISABLE == 1
            LB wd_disable
        .else
            LB DCAN_Boot
        .endif
    
    ;-----------------------------------------------
    ; wd_disable section
    ;-----------------------------------------------
        .if WD_DISABLE == 1
    
        .text
    wd_disable:
        SETC OBJMODE
        EALLOW
        MOVZ DP, #0x7029 >> 6
        MOV  @0x7029, #0x0068     ; Disable watchdog
        EDIS
        LB   DCAN_Boot
    
        .endif
    
    ;-----------------------------------------------
    ; ExitBoot - Clean up and jump to loaded app
    ;-----------------------------------------------
    ExitBoot:
    
    __stack:    .usect ".stack",0
    
        MOV SP,#__stack
        MOV  *SP++,#0
        MOV  *SP++,#0
    
        PUSH ACC
        POP  RPC
    
        ZAPA
        MOVL XT, ACC
    
        MOVZ AR0, AL
        MOVZ AR1, AL
        MOVZ AR2, AL
        MOVZ AR3, AL
        MOVZ AR4, AL
        MOVZ AR5, AL
        MOVZ AR6, AL
        MOVZ AR7, AL
        MOVW DP, #0
    
        MOV  *SP++,#0
        MOV  *SP++,#0x0A0B
        POP  ST1
        POP  ST0
    
        LRETR
    
        .end
    

    /*===========================================================================
     FILE:    2837xD_flash_kernel.cmd
     TITLE:   Linker Command File for F28379D Flash Kernel (Safe with App)
    ===========================================================================*/
    
    MEMORY
    {
       BOOT_RSVD     : origin = 0x000000, length = 0x000080   /* Boot ROM reserved */
       RAMM0_SAFE    : origin = 0x000080, length = 0x0000A3   /* Only safe range before 0x123 */
       RAMM1         : origin = 0x000400, length = 0x0003F8   /* For .stack */
       
       RAMLS6        : origin = 0x00B000, length = 0x000800   /* Not used in app */
       RAMLS7        : origin = 0x00B800, length = 0x000800
       RAMLS8        : origin = 0x00C000, length = 0x000800
       RAMLS9        : origin = 0x00C800, length = 0x000800
       RAMLS10       : origin = 0x00D000, length = 0x000800
    
       RAMGS12       : origin = 0x018000, length = 0x001000   /* Fully unused by app */
       RAMGS13       : origin = 0x019000, length = 0x001000   /* Fully unused by app */
    
       KERNEL_ENTRY  : origin = 0x00008000, length = 0x000002 /* Bootloader jump address */
    }
    
    SECTIONS
    {
       codestart       : > KERNEL_ENTRY, ALIGN(8)
       .text           : >> RAMLS6 | RAMLS7
       .cinit          : > RAMGS12
       .const          : > RAMGS12
       .bss            : > RAMM0_SAFE
       .stack          : > RAMM1
       .init_array     : > RAMGS12
       .data           : > RAMGS12
       .sysmem         : > RAMGS12
    
       /* Flash API - place in same RAM region as .text or alternate if needed */
       Flash28_API:
           LOAD = RAMLS6,
           RUN  = RAMLS6,
           LOAD_START(_Flash28_API_LoadStart),
           LOAD_END(_Flash28_API_LoadEnd),
           RUN_START(_Flash28_API_RunStart)
    
    #ifdef __TI_COMPILER_VERSION__
       #if __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} > RAMLS8,      PAGE = 0
       #else
        ramfuncs    : > RAMLS8      PAGE = 0
       #endif
    #endif
    }
    

  • Hi,

    I will check if SW team can help

  • Hello QJ,

    Thanks. Kindly do let me know.

  • Hi Parambhik,

    I have made a request for creating a flash kernel example for F28379x, and will keep you updated whenever I get any feedback.   

  • Hi Parambhik,

    I am closing this thread. Whenever the example is ready, I will ping you again. Thanks