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: