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.

Can I get EMIF16 sample code as NOR I/F on C6657?

Hi Champs,

I'm planning to use c6657 EMIF16 as NOR flash I/F.  I could not the reference code in a c6657 PDK.
So, does anyone have the EMIF16 sample code or GEL?

Thanks in advance for your cooperation.

Best regards,
j-breeze

  • Hi j-breeze,

    Please refer the gel file available in MCSDK 2.01.02.06. Attached for your reference. 

    PATH: ..\ti\mcsdk_2_01_02_06\tools\program_evm\gel

    MCSDK:  http://software-dl.ti.com/sdoemb/sdoemb_public_sw/bios_mcsdk/latest/index_FDS.html

    GEL : 8117.evmc6657l.gel

    Thanks.

  • Hi Rajasekaran,

    I refered the gel in the MCSDK, but I think that it dose not include EMIF16 Settings for parallel NOR flash interface.
    I'd appreciate if you could check it out again?

    Best regards,
    j-breeze

  • Hi j-breeze,

    I have simple example of NOR writer that is connected to the EMIF16. I have attached the main source file for the nor writer. This was tested using Spansion NOR devices so will need low level driver for that NOR flash device to build this but you can look at the EMIF initialization and the sequence used to create the writer.

    /* A very simple NOR 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 NOR */
    
    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               0x20c00000
    
    #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;   
    
      FLASHDATA * writeDataWord;
    
      // Calculate the base address of the device in EMIF
      memBase  = 0x70000000 + (csRegion * 0x04000000);
      base_addr = (FLASHDATA *)memBase;
      writeDataWord = (FLASHDATA *)writeData;
      
      printf ("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);
    
      // Reset the NOR device
      lld_ResetCmd(base_addr);
    
      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);   
    
      if (doWrite != 0)  
      {
        printf ("Erase NOR device\n");
        if (FlashEraseIfNotBlank())
        {
          printf("\n Problem erasing NOR, stall...\n");
          for (;;)
          {
          }
        };
    
        printf ("Program device, writing %d (0x%04X) 32-bit words.\n", dataSizeUint32, dataSizeUint32);
        
        for (word_16_count = errorCount = 0; word_16_count < dataSizeUint16; word_16_count++)
        {
          status = lld_ProgramOp(base_addr, (ADDRESS)word_16_count, writeDataWord[word_16_count]);
        }
        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 (change to 16-bit word address)
    /***************/
    unsigned int FlashAddress (unsigned int sector)   
    {   
      if (sector < 4)
      {   
        return ((sector<<(14+1))>>1);
      }
      else if (sector > 257)
      {
        return (((((sector-258)<<14) | 0xFF0000)<<1)>>1);
      }
      else    
      {
        return (((((sector-3)<<16))<<1)>>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)>>1);  // return number of 16-bit words
      }
      else    
      {
        // All other sectors are 128 Kbytes
        return ((128*1024)>>1);  // return number of 16-bit words
      }
    }   
    
    
    /***************/
    // Erase any non-blank sectors in bank 0 of NOR
    /***************/
    unsigned int FlashEraseIfNotBlank (void)   
    { 
      unsigned int            sectorNum;
      DEVSTATUS               status;
      volatile unsigned long  delay;
         
      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)));
          status = lld_SectorEraseOp (base_addr, FlashAddress(sectorNum));
          for (delay = 0; delay < 500000; delay++)
          {
          }
          printf("  Sector erase status = %d\n", status);
          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)   
    { 
      FLASHDATA * startAddr;
      FLASHDATA * endAddr;
      FLASHDATA * dataAddr;
      volatile unsigned int data;
    
      //unsigned int flashAddr = 0;
      //unsigned int sectorSize = 0;
    
      //flashAddr = FlashAddress(sector);
      //sectorSize = SectorSize(sector);
      //printf ("  flashAddr: 0x%08X, sectorSize: 0x%08X\n", flashAddr, sectorSize);
    
      startAddr = base_addr + FlashAddress(sector);
      endAddr = startAddr + SectorSize(sector);
      printf ("  SectorBlankCheck, Sector: %02d, startAddr: 0x%08X, endAddr: 0x%08X, base_addr: 0x%08X\n", sector, startAddr, endAddr, base_addr);
    
      while(startAddr < endAddr)   
      {   
        dataAddr = startAddr;
    	data = *dataAddr;
        if (*dataAddr != 0xffff)
        {  
            printf ("  Non-blank value, Sector: %02d, Addr: 0x%08X, startAddr: 0x%08X, endAddr: 0x%08X, base_addr: 0x%08X, Value: 0x%0x\n", sector, dataAddr, startAddr, endAddr, base_addr, data);
        	return(1);  // return 1 to indicate sector is NOT blank
        }  
        
        startAddr += 1;
      }   
       
      return(0);  // return 0 to indiact sector is blank   
    }   
    

    Hope this helps.

    Regards,


    Rahul

  • Hi Rahul,

    Thank you for answering my question.

    Best regards,
    j-breeze