📄 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 + -