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.

CCS/TMS320C6713B: c6000-Hex conversion Utility (hex6x)

Part Number: TMS320C6713B

Tool/software: Code Composer Studio

Hi,

I am working on an application built around tms320c6713 DSP Processor. My application scenario as as follow:

Boot mode: 8-bit ROM boot.

ROM attached: AT29C010A on CE-1 memory space.

Working Procedure:

On boot the primary bootlaoder (built-in in c6713) will copy 1k Byte from Memory space (CE-1-->above mentioned attached ROM) into IRAM (0x00000000). This copied memory will contain custom secondary bootloader. after the 1k memory copy operation, the remaining code/data will be copied into internal RAM (IRAM) by secondary bootloader. After this the transfer will be given to __c_init00 i.e. application starting point.

How Application is built:

Sections like .text, .cinit, .const, etc. have Load address in ROM (CE-1) and Run address in IRAM. Application is built with run-time autoinitialization in ccsv3.3. from .map file, the sections address start from CE-1 memory space as defined by linker script.

Whats the Problem:

In order to burn the code in AT29C010A, i have to convert .out file to .hex file format. Now the problem is, for ROM burner software, the address 0x90000000 (load addresses) doesn't exist in AT29C010A. It means I have to map load address to 0h (ROM start) which after attaching to C6713 processor CE-1 space, will look like address 0x90000000 to C6713. This scenario is shown bellow.

Now how can I map addresses from CE-1 (0x90000000) to 0x00000000 in hex conversion utility so that ROM burner can burn it to AT29C010A? I have already tried flag -zero in cmd file.

Kind Regards,

  • I've forwarded your query to the software experts. Their feedback should be posted here.

    BR
    Tsvetolin Shulev
  • Thanks Cvetolin Shulev-XID, waiting for their feedback...
  • Kowalski,

    Can you indicate what ROM flash software are you referring to ?  Is this TI provided software or a third party software. Is the flash programmer run from the DSP or are you programming the flash before assembling it on your board?  

    If you are programming the NOR from the DSP, you don`t need to change those addresses. Please check the flassh writer code for a DSP with the same EMIF16 interface, where the base address is 0x30000000 instead of 0x90000000 that is used on your device.

    norwrite.c
    /* A very simple NAND writer */
    #include <stdio.h>
    
    #include "lld.h"
    
    // This code will work ONLY for Spansion S29WS256P devices!
    
    
    volatile unsigned int statusReg;
    
    
    /* data, address, command latch addresses assuming the EMIF16 is configured with emif11a as
     * the address latch, and emif12a as the command latch */
    unsigned int dataOffset = 0x0000;
    unsigned int addrOffset = 0x2000;
    unsigned int cmdOffset  = 0x4000;
    
    int smallPage = 0;  //1;
    
    /* The following values are defined in the linker command file */
    //extern unsigned int writeBlock;
    //extern unsigned int readBlock;
    //extern unsigned int spareBlock;
    //extern unsigned int scratchBlock;
    extern unsigned char writeBlock;
    extern unsigned char readBlock;
    extern unsigned char spareBlock;
    extern unsigned char scratchBlock;
    
    unsigned char *writeData        = &writeBlock;        /* Defined in the linker command file */
    unsigned char *readData         = &readBlock;
    unsigned char *spareData        = &spareBlock;        /* the spare data area is placed here after writes */
    unsigned char *scratch          = &scratchBlock;      /* used for temporary storage */
    
    volatile unsigned int dataSizeUint32 = 0;  // THIS MUST BE SET TO THE NUMBER OF WORDS TO PROGRAM!
    FLASHDATA *           base_addr;
    
    unsigned int firstBlock = 0;    /* The first block to program */
    
    int doWrite   = 1;   /* Set to 1 to program the nand */
    
    void norEnableRegion(int region);
    unsigned int FlashAddress(unsigned int sector);
    unsigned int SectorSize(unsigned int sector);
    unsigned int FlashEraseIfNotBlank(void);   
    unsigned int SectorBlankCheck(unsigned int sector);
    
    
    
    #define EMIF_CTL_BASE               0x21000a00
    
    #define EMIF_CTL_RCSR               0x0000
    
    #define EMIF_CTL_A1CR               0x0010
    
    #define EMIF_CTL_NANDFCR            0x0060
    
    //#define EMIF_CTL_NANDFSR            0x0064
    //#define EMIF_CTL_NANDF4BECCLR       0x00bc
    //#define EMIF_CTL_NANDFEA1R          0x00d0
    //#define EMIF_CTL_NANDFEA2R          0x00d4
    //#define EMIF_CTL_NANDFEV1R          0x00d8
    //#define EMIF_CTL_NANDFEV2R          0x00dc
    
    
    /***************/
    /* main  */
    /***************/
    int main ()
    {
      unsigned int      csRegion = 0;
      unsigned int      memBase  = 0;
      
      unsigned int      dataSizeUint16;
      unsigned short *  norPointer;
      unsigned short *  ramPointer;
      int               word_16_count;
      int               errorCount;
    
      unsigned short    deviceId;
      LLD_CHAR          versionStr[9];
      DEVSTATUS         status;
    
      unsigned short    Manufacturing_ID;   
      unsigned short    Flash_ID1;   
      unsigned short    Flash_ID2;   
      unsigned short    Flash_ID3;   
    
    
      // Calculate the base address of the device in EMIF
      memBase  = 0x30000000 + (csRegion * 0x04000000);
      base_addr = (FLASHDATA *)memBase;
      
      printf ("Appleton VDB NOR writer for Spansion S29WS256P device.\n\n");
    
      if (dataSizeUint32 == 0x00)
      {
        printf ("Variable \'dataSizeUint32\' is zero.\n");
        printf ("It must be set the the number of words in image!\n");
        printf ("Execution will stall until the variable is updated.\n");
        
        while (dataSizeUint32 == 0x00)
        {
          // Wait until user tells us how much data to program
        }
      }
      dataSizeUint16 = dataSizeUint32 * 2;
    
      // Configure the EMIF for NOR flash 
      norEnableRegion(csRegion);
    
      lld_GetVersion(versionStr);
      printf("LLD Release Version: %s\n", versionStr);
      
      deviceId = lld_GetDeviceId(base_addr);
      printf("Device ID: %8.8X\n\n", deviceId);
      
      printf ("Flash ID\n");       
      lld_AutoselectEntryCmd(base_addr);   
      Manufacturing_ID = lld_ReadOp(base_addr, 0x0000);   
      Flash_ID1 = lld_ReadOp(base_addr, 0x0001);   
      Flash_ID2 = lld_ReadOp(base_addr, 0x000E);   
      Flash_ID3 = lld_ReadOp(base_addr, 0x000F);   
      printf("Manufacturing ID : %04X\n", Manufacturing_ID);   
      printf("Device ID, Word1 : %04X\n", Flash_ID1);   
      printf("Device ID, Word2 : %04X\n", Flash_ID2);   
      printf("Device ID, Word3 : %04X\n\n", Flash_ID3);   
      lld_AutoselectExitCmd(base_addr);   
      lld_ResetCmd(base_addr);   
    
    //jbh
    {
      volatile unsigned int trap;
      
      trap = 0;
      while (trap == 1)
      {
      }
    }
    //jbh  
    
      if (doWrite != 0)  
      {
        printf ("Erase NOR device\n");
        if (FlashEraseIfNotBlank())
        {
          printf("\n Problem erasing NOR, stall...");
          for (;;)
          {
          }
        };
    
        printf ("Program device, writing %d (0x%04X) 32-bit words.\n", dataSizeUint32, dataSizeUint32);
        status = lld_memcpy(base_addr, 0x00, dataSizeUint16, (FLASHDATA *)writeData);
        //printf("status = %s\n", get_status_str(status));
        printf("Write status = %d\n", status);
      }
    
      /* Compare the read and write data. */
      printf ("Compare data on device to what was written.\n");
      ramPointer = (unsigned short *)writeData;
      norPointer = (unsigned short *)base_addr;
      for (word_16_count = errorCount = 0; word_16_count < dataSizeUint16; word_16_count++)  
      {
        if (ramPointer[word_16_count] != norPointer[word_16_count])  
        {
          printf ("Data comparison failure at offset %d (0x%08x). Wrote 0x%08x, read 0x%08x\n", 
                   word_16_count, word_16_count, ramPointer[word_16_count], norPointer[word_16_count]);
    
          if (++errorCount >= 10)  
          {
            printf ("Too many comparison errors, quiting\n");
            break;
          }
        }
      }
    
      if (errorCount == 0)
      {
        printf ("Data compare complete, no errors\n");
      }
    }
    
    
    /***************/
    /* Enable EMIF access for NOR at this chip select  */
    /***************/
    void norEnableRegion(int region)
    {
      unsigned int a1cr;
      
      a1cr = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_A1CR));
      a1cr = a1cr & ~0x03;
      a1cr = a1cr | 0x01;  // NOR is 16-bit
      *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_A1CR)) = a1cr;
      
      *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFCR)) = 0;  // Set all "use NAND" bits to 0 (not NAND)
    }
    
    
    /***************/
    // Convert sector number to byte address
    /***************/
    unsigned int FlashAddress (unsigned int sector)   
    {   
      if (sector < 4)
      {   
        return (sector<<(14+1));   
      }
      else if (sector > 257)
      {
        return ((((sector-258)<<14) | 0xFF0000)<<1);   
      }
      else    
      {
        return ((((sector-3)<<16))<<1);   
      }
    } 
    
    
    /***************/
    // Calculate size of a sector
    /***************/
    unsigned int SectorSize (unsigned int sector)   
    {   
      if ((sector < 4) || (sector > 257))
      { 
        // Sectors 0 - 3 and 258 - 261 are 32 Kbytes 
        return (32*1024);   
      }
      else    
      {
        // All other sectors are 128 Kbytes
        return (128*1024);   
      }
    }   
    
    
    /***************/
    // Erase any non-blank sectors in bank 0 of NOR
    /***************/
    unsigned int FlashEraseIfNotBlank (void)   
    { 
      unsigned int sectorNum;
         
      printf ("\nErase all sectors (0 - 18) in NOR bank 0\n");   
    
      for (sectorNum = 0; sectorNum <= 18; sectorNum++)   
      {   
        if (SectorBlankCheck(sectorNum))
        {  
          printf ("Erasing sector %02d, (byte address = 0x%08X)\n", sectorNum, (base_addr + FlashAddress(sectorNum)));   
          lld_SectorEraseOp (base_addr, (FlashAddress(sectorNum) >> 1));   
          if (SectorBlankCheck(sectorNum))
          {
            printf ("  ERROR: sector %02d, (byte address = 0x%08X) could not be erased!\n", sectorNum, (base_addr + FlashAddress(sectorNum)));   
            return(1);
          }
          else
          {
            printf ("  Sector %02d successfully erased\n", sectorNum);   
          }
        }
        else
        {
          printf ("  Sector %02d already erased\n", sectorNum);   
        }
      }   
    
      printf ("\nAll Sectors erased.\n");
      return(0);   
    }   
    
       
    /***************/
    // Check to see if a sector is blank
    /***************/
    unsigned int SectorBlankCheck (unsigned int sector)   
    { 
      unsigned int startAddr;
      unsigned int endAddr;   
    
    
      startAddr = FlashAddress(sector);
      endAddr = startAddr + SectorSize(sector);
           
      while(startAddr < endAddr)   
      {   
        if (*(unsigned short *)(base_addr + startAddr) != 0xffff)
        {  
          return(1);  // return 1 to indicate sector is NOT blank
        }  
        
        startAddr += 2;      
      }   
       
      return(0);  // return 0 to indiact sector is blank   
    }   
    

    Regards,

    Rahul

  • If additonal guidance on hex6x is required, please post specific questions in the TI Compiler forums as the utility is supported by the TI compiler team.

    Example:
    e2e.ti.com/.../93502
  • Dear Rahul, thanks for your kind reply.
    I am using Dataman programmer and the mention ROM is programmed before it is assembled in the ROM.
    Link: http://www.dataman.com

    In this case, i have to remap the addresses otherwise address may go beyound the range.!! Now how can i do that??

    Another thing, can we program AT29C010A directly onboard from DSP without a programmer!!?
  • Have you checked with the dataman support, if their tool can handle this scenario. The Hex file is just a binary which is formated in a way that the DSP can understand. I don`t understand why the dataman tool is looking for the programming address inside the binary.

    Have you tried to see if the image programmed on the NOR flash boots after programming it using dataman. A good way to check would be to let the ROM run and setup direct addressing and then checking what the DSP sees in the parallel access memory.

    Program flash from DSP is described here:
    processors.wiki.ti.com/.../Flashing_the_C6713_EVM


    Regards,
    Rahul
  • Dear Rahul, I believe flash programmer should extract the address information from .hex files as how would it then place data/code at appropriate locations?? There is a proper address encoding in .hex files. its some how explained in bellow link:

    www.elproducts.com/understanding-hex-files.html

    I am totally confused here like how exactly should i handle the scenario of programming flash off-board... !!! :-(
  • Kowalski,

    If dataman is the third party then how would they be using TI compiler .hex format to extract the address. I believe that the utility must be programming the binary image as is starting from the base address on the memory. You can get this clarification from the dataman support team or their technical documents. Is this utility supposed to only work with TI C67x DSPs as our other DSPs map this to 0x3000_0000 or some different base address available in its memory map.

    When you connect the flash the the DSP the the ROM bootloader setup the EMIF peripheral and makes the flash memory location such that it can directly access it from address 0x90000000.

    Regards,
    Rahul