网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  移植测试好的C代码         ★★★ 【字体:
移植测试好的C代码
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    
//来自 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
*
*    Returns :        None
*
*    Parameters :    IntPageAdr    ->    Internal page address to write byte to
*                    BufferAdr    ->    Decides usage of either buffer 1 or 2
*                    Data        ->    Data byte to be written
*
*    Purpose :        Writes one byte to one of the dataflash
*                    internal SRAM buffers
*
******************************************************************************/
void Buffer_Write_Byte (unsigned char BufferNo, unsigned int IntPageAdr, unsigned char Data)
{
    
    DF_CS_DISABLE;                                //make sure to toggle CS signal in order
    DF_CS_ENABLE;                                //to reset dataflash command decoder
    
    if (1 == BufferNo)                            //write byte 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
        DF_SPI_RW(Data);                        //write data byte
    }

#ifdef USE_BUFFER2
    else
    if (2 == BufferNo)                            //write byte 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
        DF_SPI_RW(Data);                        //write data byte
    }        
#endif
}


/*****************************************************************************
*
*    Function name : Buffer_Write_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 written
*                    *BufferPtr    ->    address of buffer to be used for copy of bytes
*                                    from AVR buffer to dataflash buffer 1 (or 2)
*
*    Purpose :        Copies one or more bytes to one of the dataflash
*                    internal SRAM buffers from AVR SRAM buffer
*                    pointed to by *BufferPtr
*
******************************************************************************/
void Buffer_Write_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)                            //write byte(s) 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
        for( i=0; i<No_of_bytes; i++)
        {
            DF_SPI_RW(*(BufferPtr));            //write byte pointed at by *BufferPtr to dataflash buffer 1 location
            BufferPtr++;                        //point to next element in AVR buffer
        }
    }

#ifdef USE_BUFFER2
    else
    if (2 == BufferNo)                            //write byte(s) 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
        for( i=0; i<No_of_bytes; i++)
        {
            DF_SPI_RW(*(BufferPtr));            //write byte pointed at by *BufferPtr to dataflash buffer 2 location
            BufferPtr++;                        //point to next element in AVR buffer
        }
    }
#endif
}

/*****************************************************************************
*
*    Function name : Buffer_To_Page
*
*    Returns :        None
*
*    Parameters :    BufferAdr    ->    Decides usage of either buffer 1 or 2
*                    PageAdr        ->    Address of flash page to be programmed
*
*    Purpose :        Transfers a page from dataflash SRAM buffer to flash
*                    
******************************************************************************/
void Buffer_To_Page (unsigned char BufferNo, unsigned int PageAdr)
{
    DF_CS_DISABLE;                                                //make sure to toggle CS signal in order
    DF_CS_ENABLE;                                                //to reset dataflash command decoder
        
    if (1 == BufferNo)                                            //program flash page from buffer 1
    {
        DF_SPI_RW(Buf1ToFlashWE);                                //buffer 1 to flash with erase 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)                                            //program flash page from buffer 2
    {
        DF_SPI_RW(Buf2ToFlashWE);                                //buffer 2 to flash with erase 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 flash page programming
    DF_CS_ENABLE;                                                
    
    while(!(Read_DF_status() & 0x80));                            //monitor the status register, wait until busy-flag is high
}


/*****************************************************************************
*
*    Function name : Cont_Flash_Read_Enable
*
*    Returns :        None
*
*    Parameters :    PageAdr        ->    Address of flash page where cont.read starts from
*                    IntPageAdr    ->    Internal page address where cont.read starts from
*
*    Purpose :        Initiates a continuous read from a location in the DataFlash
*
******************************************************************************/
void Cont_Flash_Read_Enable (unsigned int PageAdr, unsigned int IntPageAdr)
{
    DF_CS_DISABLE;                                                                //make sure to toggle CS signal in order
    DF_CS_ENABLE;                                                                //to reset dataflash command decoder
    
    DF_SPI_RW(ContArrayRead);                                                    //Continuous Array Read op-code
    DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits)));                        //upper part of page address
    DF_SPI_RW((unsigned char)((PageAdr << (PageBits - 8))+ (IntPageAdr>>8)));    //lower part of page address and MSB of int.page adr.
    DF_SPI_RW((unsigned char)(IntPageAdr));                                        //LSB byte of internal page address
    DF_SPI_RW(0x00);                                                            //perform 4 dummy writes
    DF_SPI_RW(0x00);                                                            //in order to intiate DataFlash
    DF_SPI_RW(0x00);                                                            //address pointers
    DF_SPI_RW(0x00);
}
               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号