Michail Evstafiev [Evstaf at LUMEX.RU] says:
These routines for Atmel 45Dxx series of data flash and software SPI master. I am using Hi-Tech C. You must define some macro for chip select and others.
//ATMEL SerialDataFlash Commands
#define MAIN_MEMORY_PAGE_READ 0x52
#define BUFFER1_READ 0x54
#define BUFFER2_READ 0x56
#define MAIN_MEMORY_PAGE_TO_BUFFER1_COPY 0x53
#define MAIN_MEMORY_PAGE_TO_BUFFER2_COPY 0x55
#define MAIN_MEMORY_PAGE_TO_BUFFER1_COMPARE 0x60
#define MAIN_MEMORY_PAGE_TO_BUFFER2_COMPARE 0x61
#define BUFFER1_WRITE 0x84
#define BUFFER2_WRITE 0x87
#define BUFFER1_PROGRAM_WITH_ERASE 0x83
#define BUFFER2_PROGRAM_WITH_ERASE 0x86
#define BUFFER1_PROGRAM_NO_ERASE 0x88
#define BUFFER2_PROGRAM_NO_ERASE 0x89
#define PAGE_ERASE 0x81
#define BLOCK_ERASE 0x50
#define MAIN_MEMORY_THROUGH_BUFFER1_PROGRAM 0x82
#define MAIN_MEMORY_THROUGH_BUFFER2_PROGRAM 0x85
#define AUTO_PAGE_THROUGH_BUFFER1_REWRITE 0x58
#define AUTO_PAGE_THROUGH_BUFFER2_REWRITE 0x59
#define DATA_FLASH_STATUS 0x57
#define DATA_FLASH_BUFFER1 0x00
#define DATA_FLASH_BUFFER2 0x01
//polarity of ready/busy signaling
#define IS_DATA_FLASH_BUSY() IS_DATA_FLASH_READY_LO()
//DataFlash status register bits
#define DATA_FLASH_STATUS_READY_MASK 0x80
#define IS_DATA_FLASH_READY(_status_) (_status_ & \
DATA_FLASH_STATUS_READY_MASK)
#define DATA_FLASH_STATUS_COMPARE_MASK 0x40
#define IS_DATA_FLASH_COMPARE_OK(_status_) ((_status_ & \
DATA_FLASH_STATUS_COMPARE_MASK) \
== 0)
#define DATA_FLASH_STATUS_DENSITY_MASK 0x34
#define DATA_FLASH_32MBIT_DESITY_CODE 0x30
//Density related parameters
#define MAX_PAGE_32MBIT_DENSITY 8192
//write byte to SPI (mode 3) as a master
void wrSPI(char Shift)
{
register BYTE BitCnt = 8;
do
{
SPI_SCK_LO();
if(Shift & 0x80)
SPI_SDO_HI();
else
SPI_SDO_LO();
Shift <<= 1;
SPI_SCK_HI();
} while (--BitCnt);
}
//read byte from SPI (mode 3) as a master
BYTE rdSPI(void)
{
register BYTE BitCnt = 8;
register BYTE Shift;
do
{
SPI_SCK_LO();
Shift <<= 1;
if(IS_SPI_SDI_LO())
Shift &= ~1;
else
Shift |= 1;
SPI_SCK_HI();
} while (--BitCnt);
return(Shift);
}
BYTE ReadDataFlashStatus(void)
{
BYTE Data;
DATA_FLASH_CS_LO();
//command
wrSPI(DATA_FLASH_STATUS);
Data = rdSPI();
DATA_FLASH_CS_HI();
return (Data);
}
void WriteByteToDataFlashBuffer1(UINT16 Address, BYTE Data)
{
DATA_FLASH_CS_LO();
//command
wrSPI(BUFFER1_WRITE);
//don't care 8 bits
wrSPI(0);
//2 high address bits
wrSPI(*((BYTE*)&Address +1));
//8 low address bits
wrSPI((BYTE)Address);
//write data byte
wrSPI(Data);
DATA_FLASH_CS_HI();
}
BYTE ReadByteFromDataFlashBuffer1(UINT16 Address)
{
BYTE Data;
DATA_FLASH_CS_LO();
//command
wrSPI(BUFFER1_READ);
//don't care 8 bits
wrSPI(0);
//2 high address bits
wrSPI(*((BYTE*)&Address +1));
//8 low address bits
wrSPI((BYTE)Address);
//don't care 8 bits
wrSPI(0);
Data = rdSPI();
DATA_FLASH_CS_HI();
return (Data);
}
void EraseDataFlashPage(UINT16 PageNum)
{
DATA_FLASH_CS_LO();
PageNum <<= 2;
//command
wrSPI(PAGE_ERASE);
//7 high address bits
wrSPI(*((BYTE*)&PageNum + 1));
//6 low address bits
wrSPI((BYTE)PageNum);
//don't care 8 bits
wrSPI(0);
DATA_FLASH_CS_HI();
}
BYTE ReadByteFromMainMemory(UINT16 PageNum, UINT16 SubAddress)
{
BYTE Data;
PageNum <<= 2;
DATA_FLASH_CS_LO();
//command
wrSPI(MAIN_MEMORY_PAGE_READ);
//7 high page numder bits
wrSPI(*((BYTE*)&PageNum +1));
//6 low page number bits and 2 high address bits
wrSPI(((BYTE)PageNum & 0b11111100) | (*((BYTE*)&SubAddress +1) & 0b11));
//8 low address bits
wrSPI((BYTE)SubAddress);
//don't care 32 bits
wrSPI(0);
wrSPI(0);
wrSPI(0);
wrSPI(0);
Data = rdSPI();
DATA_FLASH_CS_HI();
return (Data);
}
void ProgramBuffer1ToDataFlashMainMemory(UINT16 PageNum)
{
PageNum <<= 2;
DATA_FLASH_CS_LO();
//command
wrSPI(BUFFER1_PROGRAM_NO_ERASE);
//7 high address bits
wrSPI(*((BYTE*)&PageNum + 1));
//6 low address bits
wrSPI((BYTE)PageNum);
//don't care 8 bits
wrSPI(0);
DATA_FLASH_CS_HI();
}
Interested:
Questions: