?? at25f1024.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 + -