📄 megaspiwriteandreadatmeldataflah.txt
字号:
C代码
//来自 atmel 已经移植gcc了
//CPU Mega16L @7.3728MHz
//*****************************************************************************
//
// 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
// 20050403 port to avr-gcc/avr-libc - zlei
//
//*****************************************************************************
// Includes
#include <avr/io.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include "dataflash.h"
// Constants
//Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M
const 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
const uint16_t DF_pagesize[] PROGMEM ={264,264, 264, 264, 264, 528, 528,1056}; //index of pagesizes
// Globals
unsigned char PageBits = 0;
unsigned int PageSize = 0;
// 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)
{
PORTB |= (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7);
DDRB |= (1<<DDB5) | (1<<DDB7) | (1<<DDB4); //Set MOSI, SCK AND SS as outputs
SPSR = (1<<SPI2X); //SPI double speed settings
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL); //Enable SPI in Master mode, mode 3, Fosc/4
}
/*****************************************************************************
*
* 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_DISABLE; //make sure to toggle CS signal in order
DF_CS_ENABLE; //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
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)
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_DISABLE; //make sure to toggle CS signal in order
DF_CS_ENABLE; //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_DISABLE; //initiate the transfer
DF_CS_ENABLE;
while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high
}
/*****************************************************************************
*
* 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';
DF_CS_DISABLE; //make sure to toggle CS signal in order
DF_CS_ENABLE; //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_DISABLE; //make sure to toggle CS signal in order
DF_CS_ENABLE; //to reset dataflash command decoder
if (1 == BufferNo) //read byte(s) 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
for( i=0; i<No_of_bytes; i++)
{
*(BufferPtr) = DF_SPI_RW(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr
BufferPtr++; //point to next element in AVR buffer
}
}
#ifdef USE_BUFFER2
else
if (2 == BufferNo) //read byte(s) 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
for( i=0; i<No_of_bytes; i++)
{
*(BufferPtr) = DF_SPI_RW(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr
BufferPtr++; //point to next element in AVR buffer
}
}
#endif
}
/*****************************************************************************
*
* Function name : Buffer_Write_Enable
*
* Returns : None
*
* Parameters : IntPageAdr -> Internal page address to start writing from
* BufferAdr -> Decides usage of either buffer 1 or 2
*
* Purpose : Enables continous write functionality to one of the dataflash buffers
* buffers. NOTE : User must ensure that CS goes high to terminate
* this mode before accessing other dataflash functionalities
*
******************************************************************************/
void Buffer_Write_Enable (unsigned char BufferNo, unsigned int IntPageAdr)
{
DF_CS_DISABLE; //make sure to toggle CS signal in order
DF_CS_ENABLE; //to reset dataflash command decoder
if (1 == BufferNo) //write enable to buffer 1
{
DF_SPI_RW(Buf1Write); //buffer 1 write 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
}
#ifdef USE_BUFFER2
else
if (2 == BufferNo) //write enable to buffer 2
{
DF_SPI_RW(Buf2Write); //buffer 2 write 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
}
#endif
}
/*****************************************************************************
*
* Function name : Buffer_Write_Byte
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -