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.

TMS320C6455: flash .hex file

Part Number: TMS320C6455

hi,

before touching my TMS320C6455 flash memory, it had  POST program on it and was working correctly

but since I erased the flash and flashed post.hex (was given to me by board support package)  it no longer works, no led blinks

my flash base address is 0xB0000000 and I wrote this program to write into flash memory since the flash burn program no longer available

I don't know what am I doing wrong on this, please help me I'm so confused

/*
 * main.c
 */
#include "stdio.h"
// Define the Flash paramters for DSK645x with AMD29lV033C
#define FLASH_SIZE		0x400000
#define FLASH_START		0xB0000000
#define FLASH_END		(FLASH_START + FLASH_SIZE)
#define FLASH_SECTORS   0x40

#define FLASH_KEY1		0xAA
#define FLASH_KEY2		0x55
#define FLASH_KEY3		0xA0
#define FLASH_KEY4		0x80
#define FLASH_KEY5		0x10
#define FLASH_KEY6      0x30

//simplfing integer types
typedef float f32;

typedef long s32;
typedef unsigned long u32;

typedef short s16;
typedef unsigned short u16;

typedef unsigned char u8;
typedef signed char s8;

/* Local prototype
	 */
static GetFlashBuf(u8 *dest, u8 *flashsrc, u16 nBytes);

	/* Used by the checksum calc functions
	 */
static volatile unsigned long cksum = 0;

    /* flashstart/next are used to track
     * where we are in a "flat" Flash memory.
     * Paging, etc. are handled by helper
     * funcs.
     */
static volatile u8 *flashstart = (volatile u8 *)FLASH_START;
static volatile u8 *flashnext  = (volatile u8 *)FLASH_START;



/* Constant table containing end address of each sector */
unsigned long sector_end[FLASH_SECTORS] = {
    FLASH_START + 0x00ffff, /* Sector 0  */
    FLASH_START + 0x01ffff, /* Sector 1  */
    FLASH_START + 0x02ffff, /* Sector 2  */
    FLASH_START + 0x03ffff, /* Sector 3  */
    FLASH_START + 0x04ffff, /* Sector 4  */
    FLASH_START + 0x05ffff, /* Sector 5  */
    FLASH_START + 0x06ffff, /* Sector 6  */
    FLASH_START + 0x07ffff, /* Sector 7  */
    FLASH_START + 0x08ffff, /* Sector 8  */
    FLASH_START + 0x09ffff, /* Sector 9  */
    FLASH_START + 0x0affff, /* Sector 10 */
    FLASH_START + 0x0bffff, /* Sector 11 */
    FLASH_START + 0x0cffff, /* Sector 12 */
    FLASH_START + 0x0dffff, /* Sector 13 */
    FLASH_START + 0x0effff, /* Sector 14 */
    FLASH_START + 0x0fffff, /* Sector 15 */
    FLASH_START + 0x10ffff, /* Sector 16 */
    FLASH_START + 0x11ffff, /* Sector 17 */
    FLASH_START + 0x12ffff, /* Sector 18 */
    FLASH_START + 0x13ffff, /* Sector 19 */
    FLASH_START + 0x14ffff, /* Sector 20 */
    FLASH_START + 0x15ffff, /* Sector 21 */
    FLASH_START + 0x16ffff, /* Sector 22 */
    FLASH_START + 0x17ffff, /* Sector 23 */
    FLASH_START + 0x18ffff, /* Sector 24 */
    FLASH_START + 0x19ffff, /* Sector 25 */
    FLASH_START + 0x1affff, /* Sector 26 */
    FLASH_START + 0x1bffff, /* Sector 27 */
    FLASH_START + 0x1cffff, /* Sector 28 */
    FLASH_START + 0x1dffff, /* Sector 29 */
    FLASH_START + 0x1effff, /* Sector 30 */
    FLASH_START + 0x1fffff, /* Sector 31 */
    FLASH_START + 0x20ffff, /* Sector 32 */
    FLASH_START + 0x21ffff, /* Sector 33 */
    FLASH_START + 0x22ffff, /* Sector 34 */
    FLASH_START + 0x23ffff, /* Sector 35 */
    FLASH_START + 0x24ffff, /* Sector 36 */
    FLASH_START + 0x25ffff, /* Sector 37 */
    FLASH_START + 0x26ffff, /* Sector 38 */
    FLASH_START + 0x27ffff, /* Sector 39 */
    FLASH_START + 0x28ffff, /* Sector 40 */
    FLASH_START + 0x29ffff, /* Sector 41 */
    FLASH_START + 0x2affff, /* Sector 42 */
    FLASH_START + 0x2bffff, /* Sector 43 */
    FLASH_START + 0x2cffff, /* Sector 44 */
    FLASH_START + 0x2dffff, /* Sector 45 */
    FLASH_START + 0x2effff, /* Sector 46 */
    FLASH_START + 0x2fffff, /* Sector 47 */
    FLASH_START + 0x30ffff, /* Sector 48 */
    FLASH_START + 0x31ffff, /* Sector 49 */
    FLASH_START + 0x32ffff, /* Sector 50 */
    FLASH_START + 0x33ffff, /* Sector 51 */
    FLASH_START + 0x34ffff, /* Sector 52 */
    FLASH_START + 0x35ffff, /* Sector 53 */
    FLASH_START + 0x36ffff, /* Sector 54 */
    FLASH_START + 0x37ffff, /* Sector 55 */
    FLASH_START + 0x38ffff, /* Sector 56 */
    FLASH_START + 0x39ffff, /* Sector 57 */
    FLASH_START + 0x3affff, /* Sector 58 */
    FLASH_START + 0x3bffff, /* Sector 59 */
    FLASH_START + 0x3cffff, /* Sector 60 */
    FLASH_START + 0x3dffff, /* Sector 61 */
    FLASH_START + 0x3effff, /* Sector 62 */
    FLASH_START + 0x3fffff, /* Sector 63 */
};
char erasetable[FLASH_SECTORS];

u8 GetFlashVal(unsigned long addr)
{
	return *(volatile u8 *)(addr);
}


/* Erase a segment of Flash memory */
void flash_erase(u32 start, u32 length)
{

	int im = 0;
    /* Mark all sectors as unerased */
    for (im = 0; im < FLASH_SECTORS; im++)
        erasetable[im] = 0;

    int i;
    unsigned long sector_base, phys_base, end;

    /* Calculate extents of range to erase */
    end = start + length - 1;

    /* Walk through each sector, erase any sectors within range */
    sector_base = FLASH_START;
    for (i = 0; i < FLASH_SECTORS; i++)
    {
        if (!erasetable[i] && (start <= sector_end[i]) && (end >= sector_base))
        {
            /* Start sector erase sequence */
            phys_base = (sector_base & 0x00070000) + FLASH_START;
            *(volatile char *)FLASH_START = (char)FLASH_KEY1;
            *(volatile char *)FLASH_START = (char)FLASH_KEY2;
            *(volatile char *)FLASH_START = (char)FLASH_KEY4;

            *(volatile char *)FLASH_START = (char)FLASH_KEY1;
            *(volatile char *)FLASH_START = (char)FLASH_KEY2;
            *(volatile char *)(phys_base) = (char)FLASH_KEY6;

            /* Wait until erase is done */
	        while(GetFlashVal(sector_base) != 0xff);

            /* Put the Flash in normal mode */
            *(volatile char *)phys_base = (char)0xf0;

            /* Mark sector as erased */
            erasetable[i] = 1;
        }

        /* Advance to next sector */
        sector_base = sector_end[i] + 1;
    }
}
/* The Flash Erase function uses
 * the AMD algorithm to erase the
 * entire chip.
 */

void EraseFlash(void)
{
    int i;

	/* Code to erase AMD29LV033C
	 * 32MBit (4MK X 8) Flash Memory
	 */
	//*FLASH_PAGE = 0;
	*(volatile char *)FLASH_START = (char)FLASH_KEY1;
	*(volatile char *)FLASH_START = (char)FLASH_KEY2;
	*(volatile char *)FLASH_START = (char)FLASH_KEY4;

	*(volatile char *)FLASH_START = (char)FLASH_KEY1;
	*(volatile char *)FLASH_START = (char)FLASH_KEY2;
	*(volatile char *)FLASH_START = (char)FLASH_KEY5;

    /* Wait until erase is done */
	while(GetFlashVal(FLASH_START) != 0xff);

    /* Put the Flash in normal mode */
    *(volatile char *)FLASH_START = (char)0xf0;

    /* Mark all sectors as erased */
    for (i = 0; i < FLASH_SECTORS; i++)
        erasetable[i] = 1;

	return;
}


int main(void) {
	EraseFlash();
	 FILE *fl = fopen("post.hex", "rb");
	    fseek(fl, 0, SEEK_END);
	    long len = ftell(fl);
	    char *data = (u8*)malloc(len+1);
	    rewind (fl);
	    fread(data, 1, len+1, fl);
	    fclose(fl);
	    int filelen;
	    int i;


		    	volatile unsigned int nBytes = len;
		    	//data = (char*) (data+filelen);
		   	    u16 timeout;
		   	    u8 cn;
		   	    //pointer to data
		   	    	volatile u8 *pdata;

		   	        /* Put the Flash in normal mode */
		   	        *(volatile char *)FLASH_START = (char)0xf0;

		   	        flash_erase((u32)flashnext, (u32)nBytes);




		   	    	while(nBytes--)
		   	    	{
		   	    		/* Prep AMD
		   	    		 * 32MBit (4M x 8) Flash Memory
		   	    		 * for writing a byte.
		   	    		 */

		   	    		*(volatile char *)FLASH_START = (char)FLASH_KEY1;
		   	    		*(volatile char *)FLASH_START = (char)FLASH_KEY2;
		   	    		*(volatile char *)FLASH_START = (char)FLASH_KEY3;

		   	    		//direct write to address wich is pointing to a flash region(segment)/*
		   	            pdata = (volatile u8 *)((u32)flashnext);
		   	    		*(pdata) = *data;


		   	    		/* Spin here 'til programming completes
		   	    		 */

		   	    		cn = *data++;
		   	    		timeout = 0;
		   	    		do timeout += 1;
		   	    		while(*(pdata) != cn && timeout < (u16)0xffff);
		   	    		flashnext++;
		   	    	}

		   	        /* Put the Flash in normal mode */
		   	        *(volatile char *)FLASH_START = (char)0xf0;




	return 0;
}

  • Hi,

    This is an old device. You may look at https://e2e.ti.com/support/tools/ccs/f/81/t/69909 if it helps. I thought you need a flash writer. Also a tool can convert an application (like LED blinking) into hex file for booting from flash.

    Regards, Eric

  • yes I know about hex file, I already using a pre hexed file that was provided to me by the TI, according to the documentation, the flash burn is the tool that used to write hex file to flash but it's deprecated and no longer available for usage and so I found the program that flash burn loads it into the device and communicates with it to burn the data on flash, it is called FBTC, in its source code I found the code that performs writing to the flash, I used it to make the following code, the code works fine and it writes to flash correctly but the program does not start after reset, I guess I should not write a program at the base address of flash ...  I don't know...

  • oh maybe I described something incorrectly 

    my device works fine but its only problem is it doesn't start the flashed program when I turn it on or after reset

  • Hi,

    You mentioned address 0xB000_0000, I looked at the datasheet https://www.ti.com/lit/ds/symlink/tms320c6455.pdf, this is the EMIF A interface with CS 3. You have the flash connect here, correct?

    Then I looked at the bootloader user guide: https://www.ti.com/lit/ug/spruec6g/spruec6g.pdf

    2.3.3 EMIFA Boot Mode In EMIFA boot mode, the bootloader simply branches to the base address of EMIFA CE3 (0xB000 0000). Interrupts are disabled.

    It looks to me you don't need to have any offset when flashing your program. 

    Are you able to see from CCS memory window what instructions at that address when you set EMIF A boot mode? And if you can set a hardware break point at the starting address 0xB000_0000 and do a reset if you can hit it. Then you can step through a few instructions. This is way how we typically debug issues running from a flash.

    Regards, Eric 

  • exactly as you mentioned I did the exact same thing; instructions were there at 0xB000_0000 I step through  the instructions but nothing was happening(no led blink)

    and yes I compared each hex value in flash against .hex file, they were the same; one thing that I have read about is the boot loader(may?) copy 1kb at the start of flash to address 0x000_0000 it called boot table  ... it's used to copy other instructions to l2 ram and call c_init function

  • the only thing that I haven't done yet is to generate .hex from my led_blink.c and flash it ... maybe the problem is with the .hex file

    but I can load post.out and it works fine

    I have a question, can I load .hex file in debug mode and run it? like what we always do with .out file?

  • Hi,

    when boot from a flash, two kinds of execution can happen: 1. execute in place (directly on the flash), I doubt the C6455 has this supported. 2. the bootloader read the flash memory and copy it into local memory, the boot loader will also be able to determine the entry point of the program and jump to there. I am not sure how the .hex in the flash is formatted, is it a simple flat binary or some ELF/COFF format with header, offset, length info? But this should be the bootloader's job to understand it. 

    You already know what written to flash, do you have access to the bootloader code to see how it parse the binary on flash? I also added a colleague who may be familiar with flash boot.

    Regards, Eric

  • Hi,

    thanks for your advice

    I will try to check the bootloaders instructions and understand how it works

  • after 2 weeks of  fulltime research, I finally flashed my DSP correctly

    everything that I was expecting was right, but the big problem was my way to read the .hex file and write to flash 

    I disassembled the .hex file and saw some addresses and data in ASCII format; I was reading the file in binary format

    and I was right about that 1kb at the start of the flash, it is called boot loader and it copies the whole program to l2 ram then initialize c environment (_c_int00) 

    then the main function gets called

    thanks for supports  ♥️