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.

TMS570LC4357-EP: TMS570LC4357

Part Number: TMS570LC4357-EP
Other Parts Discussed in Thread: HALCOGEN, TMS570LC4357

Hello:

    How to set the offset address of the interrupt vector table based on TMS570 platform?

    Thank you!

Jiangbo Hu

  • Hi Jiangbo,

    Do you mean offset address in VIM table? Please refer to interrupt request assignments (table 6-39) in device datasheet (SPNS195C).

    In the HalCoGen generated code, the interrupt table is s_vim_init[..]:

    static const t_isrFuncPTR s_vim_init[128U] =

  • I means:

    As shown in the figure, it is in the cmd file.

    If I want to put the VECTORS to the start address that 0x60000000, I modified the origin = 0x60000000.

    Do I need to make any other settings except that "modified the origin = 0x60000000"?

  • Hi,

    For TMS570 device, the vector is at the 0x00000000 only.

  • Hi,

    Does TMS570 device support second level startup (such as uboot) to start freertos?

    Thanks!

  • No, TMS570 doesn't have ROM bootloader, and supports only bootloader in the flash.

  • No, TMS570 doesn't have ROM bootloader, and supports only bootloader in the flash.

    Thank you!

    Is there any documentation or datasheet explaining this viewpoint?

  • Page 1 of the device datasheet:

    The device doesn't have a boot ROM. After reset (warm-reset or power on reset) is released, the CPU fetches the first instruction from address
    0x00000000

  • Thank you!

    Another question:

    How can I obtain the Flash API Lib for TMS570LC4357? Is it “F021_API_CortexR4_BE.lib”? Is there any example code for how to use library functions?

  • The flash libraries for TMS570LC4357 are: 

    1. F021_API_CortexR4_BE_L2FMC_V3D16_NDS.lib: This is the Flash API object file without debug symbols for Cortex R4/R5 Big Endian devices using the L2FMC memory controller and floating point unit.

    2. F021_API_CortexR4_BE_L2FMC_V3D16.lib: This is the Flash API object file for Cortex R4/R5 Big Endian devices using the L2FMC memory controller and floating point unit.

    3. F021_API_CortexR4_BE_L2FMC_NDS.lib: This is the Flash API object file without debug symbols for Cortex R4 Big Endian devices using the L2FMC memory controller

    4. F021_API_CortexR4_BE_L2FMC.lib: This is the Flash API object file for Cortex R4 Big Endian devices using the L2FMC memory controller.

  • You can use our bootloader (CAN, SPI, Ethernet, UART) as examples. The bootloader use Flash API to erase flash sectors and program data to flash.

    1452.TMS570LC4357_UART_BootLoader.zip

    4670.bl_flash.c
    /*****************************************************************************
     *
     * bl_flash.c     : The file holds the main control loop of the boot loader.
     * Author         : QJ Wang. qjwang@ti.com
     * Date           : 4-19-2019
     */
    /* Copyright (C) 2013-2019 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.
     */
    //*****************************************************************************
    
    #include "bl_config.h"
    #include "bl_flash.h"
    #include "F021.h"
    #include "flash_defines.h"
    
    
    //#define Freq_In_MHz = SYS_CLK_FREQ;
    uint8_t    g_ucStartBank, g_ucEndBank, g_ucStartSector, g_ucEndSector;
    uint32_t   g_ulBankInitialized = 0;
    
    //*****************************************************************************
    //
    // Returns the size of the ist sector size of the flash in bytes.
    //
    //*****************************************************************************
    uint32_t
    BLInternalFlashFirstSectorSizeGet(void)
    {
    	uint32_t firstSectorSize;
    	firstSectorSize = (uint32_t)(flash_sector[0].start) + flash_sector[0].length;
        return (firstSectorSize);
    }
    //*****************************************************************************
    //
    // Returns the size of the internal flash in bytes.
    //
    // This function returns the total number of bytes of internal flash in the
    // current part.  No adjustment is made for any sections reserved via
    // options defined in bl_config.h.
    //
    // \return Returns the total number of bytes of internal flash.
    //
    //*****************************************************************************
    uint32_t
    BLInternalFlashSizeGet(void)
    {
    	uint32_t flashSize;
    	flashSize = (uint32_t)flash_sector[NUMBEROFSECTORS-1].start + flash_sector[NUMBEROFSECTORS-1].length;
        return (flashSize);
    }
    
    //*****************************************************************************
    //
    // Checks whether a given start address is valid for a download.
    //
    // This function checks to determine whether the given address is a valid
    // download image start address given the options defined in bl_config.h.
    //
    // \return Returns non-zero if the address is valid or 0 otherwise.
    //
    //*****************************************************************************
    uint32_t
    BLInternalFlashStartAddrCheck(uint32_t ulAddr, uint32_t ulImgSize)
    {
        uint32_t count=0, i;
    
    	uint32_t ulWholeFlashSize;
    
        //
        // Determine the size of the flash available on the part in use.
        //
        ulWholeFlashSize = (uint32_t)flash_sector[NUMBEROFSECTORS-1].start + flash_sector[NUMBEROFSECTORS-1].length;
    
    	/* The start address must be at the beginning of the sector */
        for (i = 0; i < NUMBEROFSECTORS; i++){
    		if ((ulAddr >= (uint32_t)(flash_sector[i].start)) && (ulAddr < ((uint32_t)flash_sector[i].start + flash_sector[i].length)))
    		{
    			count++;
    		}
    	}
        if (count == 0){
        	return(0);
        }
    
        //
        // Is the address we were passed a valid start address?  We allow:
        //
        // 1. Address 0 if configured to update the boot loader.
        // 2. The start of the reserved block if parameter space is reserved (to
        //    allow a download of the parameter block contents).
        // 3. The application start address specified in bl_config.h.
        //
        // The function fails if the address is not one of these, if the image
        // size is larger than the available space or if the address is not word
        // aligned.
        //
        if((
    #ifdef ENABLE_BL_UPDATE
                           (ulAddr != 0) &&
    #endif
                            (ulAddr != APP_START_ADDRESS)) ||
                           ((ulAddr + ulImgSize) > ulWholeFlashSize) ||
                           ((ulAddr & 3) != 0))
        {
        	return(0);
        }
        else  {
            return(1);
        }
    }
    
    /* Initialize the flash bank and activate the sectors */
    uint32_t Fapi_Init(uint32_t ucStartBank, uint32_t ucEndBank)
    {
        uint32_t i;
    
        /*SYS_CLK_FREQ is defined in bl_config.h */
        if ((Fapi_initializeFlashBanks((uint32_t)SYS_CLK_FREQ)) == Fapi_Status_Success){
            for (i = ucStartBank; i < ( ucEndBank + 1); i++){
                (void)Fapi_setActiveFlashBank((Fapi_FlashBankType)i);
                (void)Fapi_enableMainBankSectors(0xFFFF);                    /* used for API 2.01*/
                while( FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady );
                while( FAPI_GET_FSM_STATUS != Fapi_Status_Success ); /* don't have to include this one*/
            }
            g_ulBankInitialized = 1;
    
        }else {
             return (1);
        }
        return (0); //success
    }
    
    /* ulAddr must be starting address of one flash sector*/
    uint32_t Fapi_BlockErase(uint32_t ulAddr, uint32_t Size)
    {
    	uint8_t  i=0, ucStartSector, ucEndSector;
        uint32_t EndAddr, status;
    
    	EndAddr = ulAddr + Size;
    	for (i = 0; i < NUMBEROFSECTORS; i++){
    		if (ulAddr < (uint32_t)(flash_sector[i].start))
    		{
    			g_ucStartBank     = flash_sector[i-1].bankNumber;
    		    ucStartSector   = i-1;
    		    break;
    		}
    	}
    
    	for (i = ucStartSector; i < NUMBEROFSECTORS; i++){
    		if (EndAddr <= (((uint32_t)flash_sector[i].start) + flash_sector[i].length))
    		{
    			g_ucEndBank   = flash_sector[i].bankNumber;
    			ucEndSector = i;
    		    break;
    		}
    	}
    
        status = Fapi_Init(g_ucStartBank, g_ucEndBank);
    
        for (i=ucStartSector; i<(ucEndSector+1); i++){
    		Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, flash_sector[i].start);
        	while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
        	while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
        }
    
    #if defined (RM57) || defined (TMS570LC43)
        status =  0;
    #else
        status =  Flash_Erase_Check((uint32_t)ulAddr, Size);
    #endif
    
    	return (status);
    }
    
    //Bank here is not used. We calculate the bank in the function based on the Flash-Start-addr
    uint32_t Fapi_BlockProgram(uint32_t Flash_Address, uint32_t Data_Address, uint32_t SizeInBytes)
    {
    	register uint32_t src = Data_Address;
    	register uint32_t dst = Flash_Address;
    	uint32_t bytes;
    
    	if (SizeInBytes < 16)
    		bytes = SizeInBytes;
    	else
    		bytes = 16;
    
        /* The flash bank has been initialized in flash erase function */
        if (g_ulBankInitialized |= 1 ){
            Fapi_Init(g_ucStartBank, g_ucEndBank);
        }
    
        while( SizeInBytes > 0)
    	{
    		Fapi_issueProgrammingCommand((uint32_t *)dst,
    									 (uint8_t *)src,
    									 (uint32_t) bytes,
    									 0,
    									 0,
    									 Fapi_AutoEccGeneration);
    
     		while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
            while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
    
    		src += bytes;
    		dst += bytes;
    		SizeInBytes -= bytes;
            if ( SizeInBytes < 32){
               bytes = SizeInBytes;
            }
        }
    	return (0);
    }
    
    
    uint32_t Fapi_UpdateStatusProgram(uint32_t Flash_Start_Address, uint32_t Data_Start_Address, uint32_t Size_In_Bytes)
    {
    	register uint32_t src = Data_Start_Address;
    	register uint32_t dst = Flash_Start_Address;
    	unsigned int bytes;
    
    	if (Size_In_Bytes < 16)
    		bytes = Size_In_Bytes;
    	else
    		bytes = 16;
    
    	Fapi_issueProgrammingCommand((uint32_t *)dst,
    									 (uint8_t *)src,
    									 (uint32_t) bytes,
    									 0,
    									 0,
    									 Fapi_AutoEccGeneration);
    
     	while( Fapi_checkFsmForReady() == Fapi_Status_FsmBusy );
        while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
    
    	return (0);
    }
    
    
    
    uint32_t Flash_Program_Check(uint32_t Program_Start_Address, uint32_t Source_Start_Address, uint32_t No_Of_Bytes)
    {
    	register uint32_t *src1 = (uint32_t *) Source_Start_Address;
    	register uint32_t *dst1 = (uint32_t *) Program_Start_Address;
    	register uint32_t bytes = No_Of_Bytes;
    
    	while(bytes > 0)
    	{	
    		if(*dst1++ != *src1++)
    			return (1);   //error
    
    		bytes -= 0x4;
    	}
    	return(0);
    }	
    
    
    uint32_t Flash_Erase_Check(uint32_t Start_Address, uint32_t Bytes)
    {
    	uint32_t error=0;
    	register uint32_t *dst1 = (uint32_t *) Start_Address;
    	register uint32_t bytes = Bytes;
    
    	while(bytes > 0)
    	{	
    		if(*dst1++ != 0xFFFFFFFF){
    			error = 2;
    		}
    		bytes -= 0x4;
    	}
    	return(error);
    }
    
    
    
    uint32_t Fapi_BlockRead( uint32_t Flash_Start_Address, uint32_t Data_Start_Address, uint32_t Size_In_Bytes)
    {
    	register uint32_t src = Data_Start_Address;
    	register uint32_t dst = Flash_Start_Address;
    	register uint32_t bytes_remain = Size_In_Bytes;
    	int bytes;
    
    	if (Size_In_Bytes < 16)
    		bytes = Size_In_Bytes;
    	else
    		bytes = 16;
    
     	while( bytes_remain > 0)
    	{
    		Fapi_doMarginReadByByte((uint8_t *)src,
    								(uint8_t *)dst,
    								(uint32_t) bytes,                //16
    								Fapi_NormalRead);
    		src += bytes;
    		dst += bytes;
            bytes_remain -= bytes;
        }
    	return (0);
    }
    
    4670.bl_flash.h2022.flash_defines.h