📄 dataflash.c
字号:
/* Last change: RM 17 Jan 2001 20:15*///*****************************************************************************//// COPYRIGHT (c) ATMEL Norway, 1996-2001//// The copyright to the document(s) herein is the property of// ATMEL Norway, Norway.//// The document(s) may be used and/or copied only with the written// permission from ATMEL Norway or in accordance with the terms and// conditions stipulated in the agreement/contract under which the// document(s) have been supplied.////*****************************************************************************//// File........: DATAFLASH.C//// Author(s)...: ATMEL Norway//// Target(s)...: All AVRs with built-in HW SPI//// Description.: Functions to access the Atmel AT45Dxxx dataflash series// Supports 512Kbit - 64Mbit//// Revisions...://// YYYYMMDD - VER. - COMMENT - SIGN.//// 20011017 - 1.00 - Beta release - RM// 20011017 - 0.10 - Generated file - RM// 20031009 port to avr-gcc/avr-libc - M.Thomas////*****************************************************************************// Includes//mtA//#include <INA90.H>//#include "iom169.h"#include <avr/io.h>#include <inttypes.h>#include <avr/pgmspace.h>//mtE#include "dataflash.h"// Macro definitions// ( GNU compatability Macros )#ifndef sbi #define _BV(bit) (1 << (bit)) #define sbi(x,bit) (x |= _BV(bit)) // set bit ( GNU compatability ) #define cbi(x,bit) (x &= ~_BV(bit)) // clear bit ( GNU compatability )#endif#ifndef bit_is_set #define bit_is_set(sfr, bit) (sfr & _BV(bit)) #define bit_is_clear(sfr, bit) (!(sfr & _BV(bit)))#endif// Constants//Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M// mt flash unsigned char DF_pagebits[] ={ 9, 9, 9, 9, 9, 10, 10, 11}; //index of internal page address bitsconst uint8_t DF_pagebits[] PROGMEM ={ 9, 9, 9, 9, 9, 10, 10, 11}; //index of internal page address bits//Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M// mt flash unsigned int DF_pagesize[] ={264,264, 264, 264, 264, 528, 528,1056}; //index of pagesizesconst uint16_t DF_pagesize[] PROGMEM ={264,264, 264, 264, 264, 528, 528,1056}; //index of pagesizes// Globalsunsigned char PageBits;unsigned int PageSize;// Functions/******************************************************************************* Function name : DF_SPI_init** Returns : None** Parameters : None** Purpose : Sets up the HW SPI in Master mode, Mode 3* Note -> Uses the SS line to control the DF CS-line.*******************************************************************************/void DF_SPI_init (void){ // mtA // PORTB |= (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0); // DDRB |= (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0); //Set MOSI, SCK AND SS as outputs PORTB |= (1<<PB3) | (1<<PB2) | (1<<PB1) | (1<<PB0); DDRB |= (1<<DDB2) | (1<<DDB1) | (1<<DDB0); //Set MOSI, SCK AND SS as outputs // mtE SPSR = (1<<SPI2X); //SPI double speed settings SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL); //Enable SPI in Master mode, mode 3, Fosc/2// SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL) | (1<<SPR1) | (1<<SPR0); //Enable SPI in Master mode, mode 3, Fosc/2}/******************************************************************************* Function name : DF_SPI_RW** Returns : Byte read from SPI data register (any value)** Parameters : Byte to be written to SPI data register (any value)** Purpose : Read and writes one byte from/to SPI master*******************************************************************************/unsigned char DF_SPI_RW (unsigned char output){ unsigned char input; SPDR = output; //put byte 'output' in SPI data register while(!(SPSR & 0x80)); //wait for transfer complete, poll SPIF-flag input = SPDR; //read value in SPI data reg. return input; //return the byte clocked in from SPI slave} /******************************************************************************* Function name : Read_DF_status** Returns : One status byte. Consult Dataflash datasheet for further* decoding info** Parameters : None** Purpose : Status info concerning the Dataflash is busy or not.* Status info concerning compare between buffer and flash page* Status info concerning size of actual device*******************************************************************************/unsigned char Read_DF_status (void){ unsigned char result,index_copy; DF_CS_inactive; //make sure to toggle CS signal in order DF_CS_active; //to reset dataflash command decoder result = DF_SPI_RW(StatusReg); //send status register read op-code result = DF_SPI_RW(0x00); //dummy write to get result index_copy = ((result & 0x38) >> 3); //get the size info from status register // mtA // PageBits = DF_pagebits[index_copy]; //get number of internal page address bits from look-up table // PageSize = DF_pagesize[index_copy]; //get the size of the page (in bytes) PageBits = pgm_read_byte(&DF_pagebits[index_copy]); //get number of internal page address bits from look-up table PageSize = pgm_read_word(&DF_pagesize[index_copy]); //get the size of the page (in bytes) // mtE return result; //return the read status register value}/******************************************************************************* Function name : Page_To_Buffer** Returns : None** Parameters : BufferNo -> Decides usage of either buffer 1 or 2* PageAdr -> Address of page to be transferred to buffer** Purpose : Transfers a page from flash to dataflash SRAM buffer* ******************************************************************************//*void Page_To_Buffer (unsigned int PageAdr, unsigned char BufferNo){ DF_CS_inactive; //make sure to toggle CS signal in order DF_CS_active; //to reset dataflash command decoder while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high DF_CS_inactive; //make sure to toggle CS signal in order DF_CS_active; //to reset dataflash command decoder if (1 == BufferNo) //transfer flash page to buffer 1 { DF_SPI_RW(FlashToBuf1Transfer); //transfer to buffer 1 op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares }#ifdef USE_BUFFER2 else if (2 == BufferNo) //transfer flash page to buffer 2 { DF_SPI_RW(FlashToBuf2Transfer); //transfer to buffer 2 op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares }#endif DF_CS_inactive; //initiate the transfer}*//******************************************************************************* Function name : Buffer_Read_Byte** Returns : One read byte (any value)** Parameters : BufferNo -> Decides usage of either buffer 1 or 2* IntPageAdr -> Internal page address** Purpose : Reads one byte from one of the dataflash* internal SRAM buffers*******************************************************************************//*unsigned char Buffer_Read_Byte (unsigned char BufferNo, unsigned int IntPageAdr){ unsigned char data; data='0'; // mt DF_CS_inactive; //make sure to toggle CS signal in order DF_CS_active; //to reset dataflash command decoder if (1 == BufferNo) //read byte from buffer 1 { DF_SPI_RW(Buf1Read); //buffer 1 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares data = DF_SPI_RW(0x00); //read byte }#ifdef USE_BUFFER2 else if (2 == BufferNo) //read byte from buffer 2 { DF_SPI_RW(Buf2Read); //buffer 2 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares data = DF_SPI_RW(0x00); //read byte }#endif return data; //return the read data byte}*//******************************************************************************* Function name : Buffer_Read_Str** Returns : None** Parameters : BufferNo -> Decides usage of either buffer 1 or 2* IntPageAdr -> Internal page address* No_of_bytes -> Number of bytes to be read* *BufferPtr -> address of buffer to be used for read bytes** Purpose : Reads one or more bytes from one of the dataflash* internal SRAM buffers, and puts read bytes into* buffer pointed to by *BufferPtr*******************************************************************************//*void Buffer_Read_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr){ unsigned int i; DF_CS_inactive; //make sure to toggle CS signal in order DF_CS_active; //to reset dataflash command decoder while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -