⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at25f1024.c

📁 EP9315的wince下载程序。download.exe
💻 C
字号:
//****************************************************************************
//
// at25f1024.c - Routines for erasing and programing the at25f1024
//               eeprom.
//
// Copyright (c) 2006 Cirrus Logic, Inc.
//
//****************************************************************************

#include "ep93xx.h"
#include "timer.h"
#include "spi.h"
#include "at25f1024.h"

//-----------------------------------------------------------------------------
// at25f1024 write status
//-----------------------------------------------------------------------------
static void at25f1024_write_status(unsigned char value)
{
    int temp,i;
    //
    // Clear out the EEPROM status register in case there are bit left set.
    //
    while(SSP1->SSPSR.Field.TFE == 0);
    SSP1->SSPDR.Value = AT25F1024_WRITE_STATUS_REGISTER;
    SSP1->SSPDR.Value = 0;

    //
    // Get these useless bytes out of the FIFO.
    //
    while (SSP1->SSPSR.Field.RNE == 0);
    temp = SSP1->SSPDR.Value;
    while (SSP1->SSPSR.Field.RNE == 0);
    temp = SSP1->SSPDR.Value;

    //
    // Do some dummy reads to delay long enough for the Frame signal to be
    // deasserted.
    //
    for (i=0;i<100;i++)
    {
        temp = SSP1->SSPDR.Value;
    }
}

static unsigned char at25f1024_clear_receivefifo()
{
    int temp, i;
    unsigned char Status;

    //
    // Wait for the Transmit FIFO to empty
    //
    while(SSP1->SSPSR.Field.TFE == 0);

    while(SSP1->SSPSR.Field.BSY == 1);

     delay_usec(200);
    //
    // Empty the Recieve FIFO
    //
    while(SSP1->SSPSR.Field.RNE == 1)
    {
        temp = SSP1->SSPDR.Value;
    }
    
    return 0;
}
//-----------------------------------------------------------------------------
// at25f1024 get status
//-----------------------------------------------------------------------------
static unsigned char at25f1024_get_status()
{
    int temp, i;
    unsigned char Status;

    //
    // Wait for the Transmit FIFO to empty
    //
    while(SSP1->SSPSR.Field.TFE == 0);

    //
    // Empty the Recieve FIFO
    //
    while(SSP1->SSPSR.Field.RNE == 1)
    {
        temp = SSP1->SSPDR.Value;
    }

    //
    // Issues a Read Status Register command to the at25f1024
    //
    SSP1->SSPDR.Value = AT25F1024_READ_STATUS_REGISTER;

    //
    // Clock back in the status from the
    //
    SSP1->SSPDR.Value = 0x00;

    //
    // Wait for the Transmit FIFO to empty
    //
    while(SSP1->SSPSR.Field.TFE == 0);

    //
    // Throw away of this byte
    //
    while(SSP1->SSPSR.Field.RNE == 0);
    temp = SSP1->SSPDR.Value;

    //
    // Get the status of status register
    //
    while(SSP1->SSPSR.Field.RNE == 0);
    Status = (unsigned char)SSP1->SSPDR.Value;

    //
    // Do some dummy reads to delay long enough for
    // the Frame signal to be deasserted.
    //
    for (i=0;i<100;i++)
    {
        temp = SSP1->SSPDR.Value;
    }

    return(Status);
}

//-----------------------------------------------------------------------------
// at25f1024 enable writing
//-----------------------------------------------------------------------------
static int at25f1024_write_enable()
{
    int temp, i;

    //
    // Send the write enable latch command
    //
    while(SSP1->SSPSR.Field.TFE == 0);
    SSP1->SSPDR.Value = AT25F1024_SET_WRITE_ENABLE;

    while(SSP1->SSPSR.Field.TFE == 0);

    //
    // Empty out the read FIFO entry that was created by the write..
    //
    while (SSP1->SSPSR.Field.RNE == 0);
    temp = SSP1->SSPDR.Value;

    //
    // Do some dummy reads to delay long enough for the Frame signal to be
    // deasserted.
    //
    for (i=0;i<100;i++)
    {
        temp = SSP1->SSPDR.Value;
    }

    //
    // Gives the time to let Frame going high again!
    //
    delay_usec(500);

    //
    // Check that the write enable is indicated in the EEPROM status
    // register.
    do
    {
    //
    // Get the ready status of status register
    //
    temp = at25f1024_get_status();
    if( (temp & (AT25F1024_STATUS_READY | AT25F1024_STATUS_WRITE) ) == AT25F1024_STATUS_WRITE)
    {
        break;
    }
    } while (temp & AT25F1024_STATUS_READY);

    delay_usec(500);

    return 0;
}

//-----------------------------------------------------------------------------
// init_at25f1024 chip init
//-----------------------------------------------------------------------------
void init_at25f1024(void)
{
    unsigned long ulChipID=0;
    //
    // Disable the ssp, disable interrupts
    //
    SSP1->SSPCR1.Value = 0;

    //
    // Set GPIO pins 12 and 14 as outputs.
    //
    *((volatile unsigned int *)(PBDDR)) = (0x50);

    //
    // Set GPIO pins 12 and 14 high to disable the keyboard.
    //
    *((volatile unsigned int *)(PBDR)) = (0x50);

    //
    // Set GPIO pin 6 and 7 as an outputs.
    //
    *((volatile unsigned int *)(PADDR)) = (0xc0);

    //
    // Clear GPIO pin 7 to enable the frame line.
    // Set GPIO pin 6 to disable the CS4271.
    //
    *((volatile unsigned int *)(PADR)) = (0x00);
    *((volatile unsigned int *)(PADR)) = (0x40);

    //
    // Set FGPIO pin 0 as an output.
    //
    *((volatile unsigned int *)(PFDDR)) = (0x01);

    //
    // Set FGPIO pin 0 to disable the TLV2542.
    //
    *((volatile unsigned int *)(PFDR)) = (0x01);

    //
    // Set the enable bit(SSE) in SSP1CR1
    //
      SSP1->SSPCR1.Value = 0x10;

    //
    //program the SSP1CRO register
    //
    ulChipID = *((volatile unsigned int *)(SDRAMDEVCFG0));
    if((ulChipID&0x4)==4)
    {
    	SSP1->SSPCR0.Value = 0x000002c7;
    }
    else
    {
    	SSP1->SSPCR0.Value = 0x000001c7;
    }

    //
    //Read the chip id
    //
    ulChipID = *((volatile unsigned int *)(CHIPID));
    
    //
    // Program the predivisor register.
    //
    //if(((ulChipID&0xf0000000)>>28)>=0x0111)
    if(((ulChipID&0xf0000000)>>28)>=0x07)
    {   
    	//
    	//if Chip REV >=E2,the diver =4;
    	//
    	SSP1->SSPCPSR.Value = 4;
    }
    else
    {
    	//
    	//if Chip REV <=E1,(E0)the diver =2;
    	//
    	SSP1->SSPCPSR.Value = 2;
    }
    //
    // Clear the enable bit(SSE) in SSP1CR1
    //
    SSP1->SSPCR1.Value = 0;

    //
    // Set the enable bit(SSE) in SSP1CR1
    //
    SSP1->SSPCR1.Value = 0x10;
}

//-----------------------------------------------------------------------------
// query_at25f1024 chip query
//-----------------------------------------------------------------------------
int query_at25f1024(unsigned int manu_id,unsigned int device_id)
{
    int delay;
    int atmelcode;
    int devicecode;
    int temp, temp2;

    //
    // Make sure fifo is empty.
    //
    while(SSP1->SSPSR.Field.TFE == 0 || SSP1->SSPSR.Field.BSY == 1);

    //
    // Wait for any data to get out of the transmit fifo.
    //
    for(delay=64;delay >0; delay--);

    while(SSP1->SSPSR.Field.RNE == 1)
    {
        temp = SSP1->SSPDR.Value;
    }

    //
    // Clock in four bytes of data.
    //
    SSP1->SSPDR.Value = AT25F1024_READ_MANUFACTURER_PRODUCT_ID;
    SSP1->SSPDR.Value = 0x00;
    SSP1->SSPDR.Value = 0x00;

    while(!SSP1->SSPSR.Field.TFE || SSP1->SSPSR.Field.BSY || !SSP1->SSPSR.Field.RNE);

    //
    // throw away the 2 first data
    //
    temp2 = (unsigned char)SSP1->SSPDR.Value;

    //
    // Get the bytes of data that are actually read back from the device.
    //
    while(!SSP1->SSPSR.Field.RNE);
    atmelcode = (unsigned char)SSP1->SSPDR.Value;

    while(!SSP1->SSPSR.Field.RNE);
    devicecode = (unsigned char)SSP1->SSPDR.Value;

    //
    // Compare the ID got from eeprom with at25f1024's ID
    //
    if ((manu_id ==(unsigned int)atmelcode)&(device_id==(unsigned int)devicecode))
        return 1;
    else
        return 0;
}



//-----------------------------------------------------------------------------
// erase_at25f1024 chip erase
//-----------------------------------------------------------------------------
int erase_at25f1024(unsigned int addrOffset, int length)
{
    int temp;
    unsigned int addrBase=0,addr;

    if(addrOffset>1*1024*1024/8)
    	return 2;
    else if(addrOffset+length>1*1024*1024/8)
    	return 0;	
   
   //each sector 32k bytes
   for(addrBase=0; addrBase<length; addrBase+=0x8000)
    {
    addr =  addrBase+addrOffset; 	    	
    //
    // Send the write command to status register
    //
    at25f1024_write_status(0);

    delay_usec(50);

    //
    // Send the enable_write command to status register
    //
    at25f1024_write_enable();

    delay_usec(50);

    //
    // Send the chip erase command to eeprom
    //
    SSP1->SSPDR.Value = AT25F1024_SECTOR_ERASE;//AT25F1024_CHIP_ERASE;
    
    SSP1->SSPDR.Value = (addr>>16) & 0xFF;//0;
    SSP1->SSPDR.Value = (addr>>8)  & 0xFF;
    SSP1->SSPDR.Value = (addr)	   & 0xFF;

    delay_usec(50);

    //
    // Check that the write enable is indicated in the EEPROM status
    // register.
    //
    do
    {
        delay_usec(100/2);
        temp = at25f1024_get_status();
    } while (temp & AT25F1024_STATUS_READY);


    }
    
    delay_usec(500);
    return(1);
}

//-----------------------------------------------------------------------------
// program_at25f1024 chip write
//-----------------------------------------------------------------------------
int program_at25f1024(unsigned int addr, unsigned char *pBuffer, int length)
{
    unsigned int  count = 0;
    volatile unsigned char * pData;
    unsigned long * pLongData,pulTest[4];
    addr &= 0x1ffff;
    pData = pBuffer;
    pLongData = (unsigned long *)pBuffer;
    
    do
    {
    //
    // Send the enable_write command to status register
    //
    at25f1024_write_enable();

    //
    // Send byte_program command and the address to eeprom
    //
    SSP1->SSPDR.Value = AT25F1024_PROGRAM_DATA;
    SSP1->SSPDR.Value = (addr>>16) & 0xFF;//0;
    SSP1->SSPDR.Value = (addr>>8)  & 0xFF;
    SSP1->SSPDR.Value = (addr)	   & 0xFF;

    //
    // Write the word to eeprom and add the length of the buffer
    //
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];

    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];
    SSP1->SSPDR.Value = pData[count++];            
    
    //while(SSP1->SSPSR.Field.TFE == 0);

    //
    // Increase the address of the eeprom
    //
    addr +=16;//4
    delay_usec(100);

    //
    // Get the ready status of status register
    //
    while(at25f1024_get_status() & (AT25F1024_STATUS_READY | AT25F1024_STATUS_WRITE));

    delay_usec(50);
    
    //
    //Read-back verification
    // 
    pulTest[0] = read_at25f1024(addr-16,(unsigned char *)(pulTest),4);
    pulTest[1] = read_at25f1024(addr-12,(unsigned char *)(pulTest),4);
    pulTest[2] = read_at25f1024(addr-8,(unsigned char *)(pulTest),4);
    pulTest[3] = read_at25f1024(addr-4,(unsigned char *)(pulTest),4);
    
    if( 
      (((pulTest[0])&0xff)!=pData[count-16])||(((pulTest[0]>>8)&0xff)!=pData[count-15])||
      (((pulTest[0]>>16)&0xff)!=pData[count-14])||(((pulTest[0]>>24)&0xff)!=pData[count-13])||
      (((pulTest[1])&0xff)!=pData[count-12])||(((pulTest[1]>>8)&0xff)!=pData[count-11])||
      (((pulTest[1]>>16)&0xff)!=pData[count-10])||(((pulTest[1]>>24)&0xff)!=pData[count-9])||
      (((pulTest[2])&0xff)!=pData[count-8])||(((pulTest[2]>>8)&0xff)!=pData[count-7])||
      (((pulTest[2]>>16)&0xff)!=pData[count-6])||(((pulTest[2]>>24)&0xff)!=pData[count-5])||
      (((pulTest[3])&0xff)!=pData[count-4])||(((pulTest[3]>>8)&0xff)!=pData[count-3])||
      (((pulTest[3]>>16)&0xff)!=pData[count-2])||(((pulTest[3]>>24)&0xff)!=pData[count-1])            
      )
    {
    	return 0;//-1;	
    }

    }while (count < length);
    
    return length;
}



unsigned long read_at25f1024(unsigned int start, unsigned char *pBuffer, int numBytes)
{
	
    unsigned long ulRet, ulTemp;
    //unsigned long count=0;
  
    unsigned long ulOffset = start;
  
    at25f1024_clear_receivefifo();
  
    //
    //
    //
    out(SSP1DR,0x03);
    out(SSP1DR, (ulOffset >>16) & 255);
    out(SSP1DR, (ulOffset >>8) & 255);
    out(SSP1DR,  ulOffset & 255);
    
    do{
      ulTemp = in(SSP1SR);
    } while(!(ulTemp & 0x04));
     ulTemp = in(SSP1DR);
     
     out(SSP1DR,0x00);
     out(SSP1DR,0x00);
     out(SSP1DR,0x00);
     out(SSP1DR,0x00);
     
     do{ 
     	 ulTemp = in(SSP1SR);
     } while(!(ulTemp & 0x04));
       ulTemp = in(SSP1DR);
     //out(SSP1DR,0x00);
     
     do{ 
     	ulTemp = in(SSP1SR);
     } while(!(ulTemp & 0x04));
       ulTemp = in(SSP1DR);
     //out(SSP1DR,0x00);
     
     do{ 
     	 ulTemp =in(SSP1SR);
     }while (!(ulTemp & 0x04));
      ulTemp = in(SSP1DR);
     //out(SSP1DR,0x00);
     
      do{
     	ulTemp =in(SSP1SR);
     } while(!(ulTemp & 0x04));
       ulRet = in(SSP1DR);
     
     do{
        ulTemp = in(SSP1SR);
      } while(!(ulTemp & 0x04));
       ulTemp = in(SSP1DR);
       ulRet |= ulTemp<<8;
       
      do{
         ulTemp = in(SSP1SR);
        } while(!(ulTemp & 0x04));
          ulTemp = in(SSP1DR);
          ulRet |= ulTemp<<16;
      
      do{
         ulTemp = in(SSP1SR);
        } while(!(ulTemp & 0x04));
          ulTemp = in(SSP1DR);
          ulRet |= ulTemp <<24;
          
       do{ 
          ulTemp = in(SSP1SR);
        } while(!(ulTemp & 0x01));
        
        
        do{ 
           ulTemp = in(SSP1SR);
           if(ulTemp & 0x04)
             ulTemp = in(SSP1DR);
        } while (ulTemp & 0x04);
        
        return ulRet;
 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -