📄 old_dataflash.c
字号:
//*---------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*---------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*-----------------------------------------------------------------------------
//* File Name : dataflash.c
//* Object : Data Flash Atmel AT45DBxxx Driver.
//*
//* 1.0 18/01/01 HI : Creation
//*---------------------------------------------------------------------------
#include "appli\includes\spi1.h"
#include "appli\includes\dataflash.h"
#include "services\obj_romboot.h"
#include "appli\includes\main.h"
#define NB_SUPPORTED_DATAFLASH 7
#define TIMEOUT_STATUS 2 // timeout dataflash in ms
#define TIMEOUT_DATAFLASH 10 // timeout dataflash in ms
#ifdef POD
#define DATAFLASH_CLK 500000
#else
#define DATAFLASH_CLK 2000000
#endif
#define SPI_CLK MASTER_CLOCK / (2*DATAFLASH_CLK)
/* AT45DBXXX Dataflash d閒inition*/
AT91S_Dataflash AT91S_DataflashList[NB_SUPPORTED_DATAFLASH+1]=
{
{
1 << 3, // AT45DB011B ok
512 , // pages_number
264 // pages_size
},
{
2 << 3, // AT45DB021A, AT45DB021B ok
1024,
264
},
{
3 << 3, // AT45DB041A, AT45DB041B ok
2048,
264
},
{
4 << 3, // AT45DB081B, AT45DB081A ok
4096,
264
},
{
5 << 3, // AT45DB161B ok
4096,
528
},
{
6 << 3, // AT45DB321B ok
8192,
528
},
{
7 << 3, // AT45DB642 ok
8192,
1056
},
{
0,
0,
0
},
};
/* Global Variables */
AT91S_SpiDataDesc Spidata;
AT91PS_Dataflash pDataflashConnect;
/* Data Flash Assembler Interrupt Handler */
extern void asm_dataflash_handler (void) ;
/* Static functions */
static int dataflash_getStatus (void );
static int dataflash_pageRead ( u_int src, u_char *dest, int size );
static int dataflash_pagePgmBuf1 (u_char *src, u_int dest, int size);
AT91S_DataflashDesc dataflash_desc =
{
0,
(AT91PS_SpiDataDesc)&Spidata,
SP_MSTR | SP_MODEFAULT_DIS, //* spi mode
SP_CPOL | (SPI_CLK << 8) | (16 << 16),
SPI_NPCS0_USED, //* mode_pin_spi
asm_dataflash_handler, //* Assembler Handler ==> not used in SP_PCSDEC
0 //* spi_periph_id ==> CS in SP_PCSDEC
};
//*-----------------------------------------------------------------------------
//* Function Name : db_get_status
//* Object : get memory status
//* Input Parameters :
//* Return value : memory status register if ok else FALSE
//*-----------------------------------------------------------------------------
static int dataflash_getStatus (void )
{
u_char cmd[2] = {DB_STATUS,0};
u_int tick;
volatile int status;
Spidata.tx_cmd_pt = cmd ;
Spidata.tx_cmd_size = 2 ;
Spidata.rx_cmd_pt = cmd ;
Spidata.rx_cmd_size = 2 ;
Spidata.tx_data_size = 0 ;
spi1_write ( &dataflash_desc );
tick = GetTickCount() + TIMEOUT_STATUS;
status = spi1_getStatus( &dataflash_desc );
while ( (status != SERIAL_PERIPH_1_IDLE) && (GetTickCount() < tick) )
status = spi1_getStatus( &dataflash_desc );
if(status != SERIAL_PERIPH_1_IDLE)
return (FALSE);
return(cmd[1]);
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_wait_ready
//* Object : wait for memory ready
//* Input Parameters :
//* Return value : dataflash status
//*-----------------------------------------------------------------------------
int dataflash_waitReady(void)
{
if( dataflash_getStatus() & DB_STATUS_MASK_READY)
return(DATAFLASH_READY);
return(DATAFLASH_BUSY);
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_pagePgmBuf1
//* Object : Main memory page program through buffer 1
//* Input Parameters : <*src> = Source buffer
//* : <data> = data buffer pointer
//* : <size> = data buffer size
//* Return Value :
//*-----------------------------------------------------------------------------
static int dataflash_pagePgmBuf1 ( u_char *src, u_int dest, int size)
{
static u_int adr = 0;
u_char cmd[4] = { DB_PAGE_PGM_BUF1, 0, 0, 0 } ;
volatile int status;
u_int tick;
adr = ((dest / (pDataflashConnect->pages_size)) << 10) + (dest % (pDataflashConnect->pages_size));
cmd[1] = (u_char)((adr & 0x00FF0000) >> 16);
cmd[2] = (u_char)((adr & 0x0000FF00) >> 8);
cmd[3] = (u_char)(adr & 0x000000FF) ;
Spidata.tx_cmd_pt = cmd ;
Spidata.tx_cmd_size = 4 ;
Spidata.rx_cmd_pt = cmd ;
Spidata.rx_cmd_size = 4 ;
Spidata.tx_data_pt = src ;
Spidata.tx_data_size = size ;
Spidata.rx_data_pt = src;
Spidata.rx_data_size = size;
spi1_write( &dataflash_desc ) ;
tick = GetTickCount() + TIMEOUT_DATAFLASH;
//* Wait for the end of transmission
status = spi1_getStatus( &dataflash_desc );
while ( (status != SERIAL_PERIPH_1_IDLE) && (GetTickCount() < tick) )
status = spi1_getStatus( &dataflash_desc );
if(status != SERIAL_PERIPH_1_IDLE)
return (FALSE);
return(TRUE);
}
//*-----------------------------------------------------------------------------
//* Function Name : db321_page_read
//* Object : Main memory page read
//* Input Parameters : <*src> = Source buffer
//* : <data> = data buffer pointer
//* : <size> = data buffer size
//*-----------------------------------------------------------------------------
static int dataflash_pageRead ( u_int src, u_char *dest, int size )
{
u_char cmd[8] = { DB_PAGE_READ, 0, 0, 0, 0, 0, 0, 0} ;
u_int adr = 0;
volatile int status;
u_int tick;
adr = ((src / (pDataflashConnect->pages_size)) << 10) + (src % (pDataflashConnect->pages_size));
cmd[1] = (u_char)((adr & 0x00FF0000) >> 16);
cmd[2] = (u_char)((adr & 0x0000FF00) >> 8);
cmd[3] = (u_char)(adr & 0x000000FF) ;
Spidata.tx_cmd_pt = cmd ;
Spidata.tx_cmd_size = 8 ;
Spidata.rx_cmd_pt = cmd ;
Spidata.rx_cmd_size = 8 ;
Spidata.rx_data_pt = dest ;
Spidata.rx_data_size = size;
Spidata.tx_data_pt = dest ;
Spidata.tx_data_size = size;
spi1_write ( &dataflash_desc ) ;
tick = GetTickCount() + TIMEOUT_DATAFLASH;
status = spi1_getStatus( &dataflash_desc );
while ( (status != SERIAL_PERIPH_1_IDLE) && (GetTickCount() < tick) )
status = spi1_getStatus( &dataflash_desc );
if(status != SERIAL_PERIPH_1_IDLE)
return (FALSE);
return(TRUE);
}
//*-----------------------------------------------------------------------------
//* Function Name : db321_open
//* Object : Open the Data Flash connection
//* Input Parameters :
//* Output Parameters : The Data Flash status register
//* Functions called :
//*-----------------------------------------------------------------------------
u_int dataflash_open (const AT91PS_SPIDesc pDesc )
{
int i = 0;
int ret_value;
dataflash_desc.spi_desc = pDesc;
spi1_open ( &dataflash_desc );
ret_value = dataflash_getStatus();
if ( (ret_value & 0xC0) == 0x80)
{
i = 0;
while((i < NB_SUPPORTED_DATAFLASH) && (AT91S_DataflashList[i].Dataflash_mask != (ret_value & 0x38)))
i++;
if (i < NB_SUPPORTED_DATAFLASH)
{
pDataflashConnect = &AT91S_DataflashList[i];
return DATAFLASH_OPEN_OK;
}
}
pDataflashConnect = &AT91S_DataflashList[NB_SUPPORTED_DATAFLASH];
return DATAFLASH_OPEN_ERROR;
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_close
//* Object : Close the connection to a DataFlash
//* Input Parameters : None
//* Output Parameters : None
//* Functions called :
//*-----------------------------------------------------------------------------
void dataflash_close ( void )
{
pDataflashConnect = &AT91S_DataflashList[NB_SUPPORTED_DATAFLASH];
//* Close the SPI connection
spi1_close( &dataflash_desc ) ;
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_write_buffer
//* Object : Write data to the memory
//* Input Parameters : <*src> = Data buffer
//* : <*dest> = Buffer 1 or buffer 2 of the memory
//* : <size> = data buffer size
//*-----------------------------------------------------------------------------
void dataflash_writeBuffer ( u_char *src, u_char *dest, int size )
{
u_char cmd[4] = { DB_BUF1_WRITE, 0, 0, 0 } ;
u_int i = 0;
Spidata.tx_cmd_pt = cmd ;
Spidata.tx_cmd_size = 4 ;
Spidata.rx_cmd_pt = cmd ;
Spidata.rx_cmd_size = 4 ;
//* Send first Read Command
cmd[1] = (u_char)(((u_int)dest & 0xFF0000)>>16) ;
cmd[2] = (u_char)(((u_int)dest & 0xFF00)>>8) ;
cmd[3] = (u_char)((u_int)dest & 0xFF) ;
Spidata.rx_data_pt = src ;
Spidata.tx_data_pt = src ;
Spidata.rx_data_size = size ;
Spidata.tx_data_size = size ;
spi1_write( &dataflash_desc ) ;
//* Wait for the end of transmission
i = 0;
while ( (spi1_getStatus( &dataflash_desc ) != SERIAL_PERIPH_1_IDLE) && (i++ < 1000) );
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_read_buffer
//* Object : Read data from the SPI memory
//* Input Parameters : <*src> = source buffer
//* : <*dest> = destination buffer
//* : <size> = data buffer size
//*-----------------------------------------------------------------------------
void dataflash_readBuffer ( u_char *src, u_char *dest, int size )
{
u_char cmd[5] = { DB_BUF1_READ, 0, 0, 0, 0 } ;
u_int i = 0;
Spidata.tx_cmd_pt = cmd ;
Spidata.tx_cmd_size = 5 ;
Spidata.rx_cmd_pt = cmd ;
Spidata.rx_cmd_size = 5 ;
cmd[1] = (u_char)(((u_int)src & 0xFF0000)>>16) ;
cmd[2] = (u_char)(((u_int)src & 0xFF00)>>8) ;
cmd[3] = (u_char)((u_int)src & 0xFF) ;
Spidata.rx_data_pt = dest ;
Spidata.tx_data_pt = dest ;
Spidata.rx_data_size = size ;
Spidata.tx_data_size = size ;
spi1_write( &dataflash_desc ) ;
//* Wait for the end of transmission
i = 0;
while ( (spi1_getStatus( &dataflash_desc ) != SERIAL_PERIPH_1_IDLE) && (i++ < 1000) );
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_read
//* Object : Read data from the DB321 memory
//* Input Parameters : <*src> = Pointer to Main memory page
//* : <*dest> = data buffer pointer
//* : <size> = data buffer size
//*-----------------------------------------------------------------------------
int dataflash_read ( int src, u_char *dest, int size )
{
u_int length;
int db_page_size;
if (pDataflashConnect->Dataflash_mask == 0)
return DATAFLASH_INVALIDE;
db_page_size = pDataflashConnect->pages_size;
if ( (src + size) > (db_page_size * (pDataflashConnect->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
//* If source does not fit a page start address
if ((src % db_page_size) != 0 )
{
dataflash_waitReady();
length = db_page_size - (src % db_page_size);
//* Send first Read Command
if (size < length)
length = size;
if (!dataflash_pageRead (src, dest, length))
return DATAFLASH_READ_ERROR;
//* Update size, source and destination pointers
size -= length;
dest += length;
src += length;
}
while (( size - db_page_size ) >= 0 )
{
dataflash_waitReady();
//* Send a Read Command with Source Base Address
if(!dataflash_pageRead (src, dest, db_page_size))
return DATAFLASH_READ_ERROR;
//* Update size, source and destination pointers
size -= db_page_size;
dest += db_page_size;
src += db_page_size;
}
//* If still some bytes to read
if ( size > 0 )
{
dataflash_waitReady();
if(!dataflash_pageRead (src, dest, size ))
return DATAFLASH_READ_ERROR;
}
return DATAFLASH_READ_OK;
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_write
//* Object : Write data from the SPI
//* Input Parameters : <*src> = Source buffer
//* : <dest> = dataflash adress
//* : <size> = data buffer size
//*-----------------------------------------------------------------------------
int dataflash_write ( u_char *src, int dest, int size )
{
u_int length;
int db_page_size;
if (pDataflashConnect->Dataflash_mask == 0)
return DATAFLASH_INVALIDE;
db_page_size = pDataflashConnect->pages_size;
if ( (dest + size) > (db_page_size * (pDataflashConnect->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
//* If destination does not fit a page start address
if ((dest % db_page_size) != 0 )
{
dataflash_waitReady();
length = db_page_size - (dest % db_page_size);
//* Send first Read Command
if (size < length)
length = size;
if(!dataflash_pagePgmBuf1(src, dest, length))
return DATAFLASH_WRITE_ERROR;
//* Update size, source and destination pointers
size -= length;
dest += length;
src += length;
}
while (( size - db_page_size ) >= 0 )
{
// wait dataflash ready
dataflash_waitReady();
// program dataflash page
if(!dataflash_pagePgmBuf1(src, dest, db_page_size ))
return DATAFLASH_WRITE_ERROR;
//* Update size, source and destination pointers
size -= db_page_size ;
dest += db_page_size ;
src += db_page_size ;
}
//* If still some bytes to read
if ( size > 0 )
{
// wait dataflash ready
dataflash_waitReady();
// program dataflash page
if(!dataflash_pagePgmBuf1(src, dest, size))
return DATAFLASH_WRITE_ERROR;
}
return DATAFLASH_WRITE_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -