📄 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 "parts\m63200\lib_m63200.h"
#include "drivers\serial_periph_1\serial_periph_1.h"
#include "dataflash.h"
#define NB_SUPPORTED_DATAFLASH 7
/* AT45DBXXX Dataflash d閒inition*/
S_DataflashDef S_Dataflash[NB_SUPPORTED_DATAFLASH+1]=
{
{
1<<3, // AT45DB011
512 ,
264
},
{
2<<3, // AT45DB021A, AT45DB021B
1024,
264
},
{
3<<3, // AT45DB041A, AT45DB041B
2048,
264
},
{
4<<3, // AT45DB081, AT45DB081A
4096,
264
},
{
5<<3, // AT45DB0161
4096,
528
},
{
6<<3, // AT45DB0321
8192,
528
},
{
7<<3, // AT45DB0642
8192,
1056
},
{
0,
0,
0
},
};
/* Global Variables */
SerialPeriph1DataDesc spi_data ;
S_DataflashDef *S_Dataflash_detect;
/* Data Flash Assembler Interrupt Handler */
extern void data_flash_asm_handler (void) ;
/* Static functions */
static int db_get_status (void );
static int db_page_read ( u_int src, u_char *dest, int size );
static int db_page_pgm_buf1 (u_char *src, u_int dest, int size);
#if 1
/* Mount a Serial Peripheral 1 Desc as the Data Flash */
SerialPeriph1Desc data_flash_desc =
{
&SPI_DESC, /* SPI Mode Register */
&spi_data,
0x11, /* SPI pin mode */
SP_CPOL |(255<<16)|(50<<8), /* Peripheral Chip Select Register */
SPI_NPCS0_USED, /* Data Flash connected on NPCS1 */
data_flash_asm_handler, /* Assembler Handler */
0
} ;
#else
/*
typedef struct
{
const SpiDesc *spi_desc ;
SerialPeriph1DataDesc *serial_periph_1_data ;
u_int mode_spi ;
u_int mode_spi_periph ;
u_int mode_pin_spi ;
TypeAICHandler *asm_handler ;
u_char spi_periph_id ;
} SerialPeriph1Desc ;
*/
SerialPeriph1Desc data_flash_desc =
{
&SPI_DESC, /* SPI desc */
&spi_data,
SP_MSTR | SP_PCSDEC, /* spi mode */
SP_CPOL | (255 << 16) | (50 << 8), /* Peripheral Chip Select Register */
SPI_NPCS0_USED, /* mode_pin_spi */
data_flash_asm_handler, /* Assembler Handler */
0 /* spi_periph_id */
};
#endif
//*-----------------------------------------------------------------------------
//* Function Name : db_get_status
//* Object : get memory status
//* Input Parameters :
//* Return value : memory status register if ok else FALSE
//*-----------------------------------------------------------------------------
static int db_get_status (void )
//* Begin
{
u_char cmd[2] = {DB_STATUS,0} ;
u_int time_out = 1000 ;
u_int i = 0 ;
spi_data.tx_cmd_pt = cmd ;
spi_data.tx_cmd_size = 2 ;
spi_data.rx_cmd_pt = cmd ;
spi_data.rx_cmd_size = 2 ;
spi_data.tx_data_size = 0 ;
serial_periph_1_write ( &data_flash_desc ) ;
while ( (serial_periph_1_get_status( &data_flash_desc ) != SERIAL_PERIPH_1_IDLE) && (i++ < time_out) );
//* If timeout
if ( i < time_out )
{
return ( cmd[1] ) ;
}
else
{
return ( FALSE ) ;
}
}
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_wait_ready
//* Object : wait for memory ready
//* Input Parameters :
//* Return value : dataflash status
//*-----------------------------------------------------------------------------
int dataflash_wait_ready(int time_out )
//* Begin
{
while( (!(db_get_status() & DB_STATUS_MASK_READY)) && (time_out--));
/* If timeout */
if (time_out > 0)
return DATAFLASH_READY;
return DATAFLASH_BUSY ;
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : db_page_pgm_buf1
//* 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 db_page_pgm_buf1 ( u_char *src, u_int dest, int size)
//* Begin
{
static u_int adr = 0;
u_char cmd[4] = { DB_PAGE_PGM_BUF1, 0, 0, 0 } ;
adr = ((dest / (S_Dataflash_detect->pages_size)) << 10) + (dest % (S_Dataflash_detect->pages_size));
cmd[1] = (u_char)((adr & 0x00FF0000) >> 16);
cmd[2] = (u_char)((adr & 0x0000FF00) >> 8);
cmd[3] = (u_char)(adr & 0x000000FF) ;
spi_data.tx_cmd_pt = cmd ;
spi_data.tx_cmd_size = 4 ;
spi_data.rx_cmd_pt = cmd ;
spi_data.rx_cmd_size = 4 ;
spi_data.tx_data_pt = src ;
spi_data.tx_data_size = size ;
spi_data.rx_data_pt = src;
spi_data.rx_data_size = size;
serial_periph_1_write ( &data_flash_desc ) ;
//* Wait for the end of transmission
while ( (serial_periph_1_get_status (&data_flash_desc) != SERIAL_PERIPH_1_IDLE)) ;
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 db_page_read ( u_int src, u_char *dest, int size )
//* Begin
{
u_char cmd[8] = { DB_PAGE_READ, 0, 0, 0, 0, 0, 0, 0} ;
u_int adr = 0;
adr = ((src / (S_Dataflash_detect->pages_size)) << 10) + (src % (S_Dataflash_detect->pages_size));
cmd[1] = (u_char)((adr & 0x00FF0000) >> 16);
cmd[2] = (u_char)((adr & 0x0000FF00) >> 8);
cmd[3] = (u_char)(adr & 0x000000FF) ;
spi_data.tx_cmd_pt = cmd ;
spi_data.tx_cmd_size = 8 ;
spi_data.rx_cmd_pt = cmd ;
spi_data.rx_cmd_size = 8 ;
spi_data.rx_data_pt = dest ;
spi_data.rx_data_size = size;
spi_data.tx_data_pt = dest ;
spi_data.tx_data_size = size;
serial_periph_1_write ( &data_flash_desc ) ;
//* Wait for the end of transmission
while ( (serial_periph_1_get_status ( &data_flash_desc ) != SERIAL_PERIPH_1_IDLE)) ;
return (TRUE);
}
//* End
//*-----------------------------------------------------------------------------
//* 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 ( void )
//* Begin
{
int i = 0;
int ret_value;
serial_periph_1_open ( &data_flash_desc ) ;
ret_value = db_get_status();
if (ret_value!= FALSE)
{
i = 0;
while((i < NB_SUPPORTED_DATAFLASH) && (S_Dataflash[i].Dataflash_mask != (ret_value & 0x38)))
i++;
if (i < NB_SUPPORTED_DATAFLASH)
{
S_Dataflash_detect = &S_Dataflash[i];
return DATAFLASH_OPEN_OK;
}
}
S_Dataflash_detect = &S_Dataflash[NB_SUPPORTED_DATAFLASH+1];
return DATAFLASH_OPEN_ERROR;
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : dataflash_close
//* Object : Close the connection to a DataFlash
//* Input Parameters : None
//* Output Parameters : None
//* Functions called :
//*-----------------------------------------------------------------------------
void dataflash_close ( void )
//* Begin
{
S_Dataflash_detect = &S_Dataflash[NB_SUPPORTED_DATAFLASH+1];
//* Close the SPI connection
serial_periph_1_close ( &data_flash_desc ) ;
}
//* End
//*-----------------------------------------------------------------------------
//* 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_write_buffer ( u_char *src, u_char *dest, int size )
//* Begin
{
u_char cmd[4] = { DB_BUF1_WRITE, 0, 0, 0 } ;
spi_data.tx_cmd_pt = cmd ;
spi_data.tx_cmd_size = 4 ;
spi_data.rx_cmd_pt = cmd ;
spi_data.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) ;
spi_data.rx_data_pt = src ;
spi_data.tx_data_pt = src ;
spi_data.rx_data_size = size ;
spi_data.tx_data_size = size ;
serial_periph_1_write ( &data_flash_desc ) ;
//* Wait for the end of transmission
while ( serial_periph_1_get_status ( &data_flash_desc ) != SERIAL_PERIPH_1_IDLE ) ;
}
//*-----------------------------------------------------------------------------
//* 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_read_buffer ( u_char *src, u_char *dest, int size )
//* Begin
{
u_char cmd[5] = { DB_BUF1_READ, 0, 0, 0, 0 } ;
spi_data.tx_cmd_pt = cmd ;
spi_data.tx_cmd_size = 5 ;
spi_data.rx_cmd_pt = cmd ;
spi_data.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) ;
spi_data.rx_data_pt = dest ;
spi_data.tx_data_pt = dest ;
spi_data.rx_data_size = size ;
spi_data.tx_data_size = size ;
serial_periph_1_write ( &data_flash_desc ) ;
//* Wait for the end of transmission
while ( serial_periph_1_get_status ( &data_flash_desc ) != SERIAL_PERIPH_1_IDLE ) ;
}
//*-----------------------------------------------------------------------------
//* 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 )
//* Begin
{
u_int length;
int db_page_size;
if (S_Dataflash_detect->Dataflash_mask == 0)
return DATAFLASH_INVALIDE;
db_page_size = S_Dataflash_detect->pages_size;
if ( (src + size) > (db_page_size*(S_Dataflash_detect->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
//* If source does not fit a page start address
if ((src % db_page_size) != 0 )
{
dataflash_wait_ready(20000);
length = db_page_size - (src % db_page_size);
//* Send first Read Command
if (size < length)
length = size;
if (!db_page_read (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_wait_ready(20000);
//* Send a Read Command with Source Base Address
if(!db_page_read (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_wait_ready(20000);
if(!db_page_read (src, dest, size ))
return DATAFLASH_READ_ERROR;
}
return DATAFLASH_READ_OK;
}
//* End
//*-----------------------------------------------------------------------------
//* 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 (S_Dataflash_detect->Dataflash_mask == 0)
return DATAFLASH_INVALIDE;
db_page_size = S_Dataflash_detect->pages_size;
if ( (dest + size) > (db_page_size*(S_Dataflash_detect->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
//* If destination does not fit a page start address
if ((dest % db_page_size) != 0 )
{
dataflash_wait_ready(20000);
length = db_page_size - (dest % db_page_size);
//* Send first Read Command
if (size < length)
length = size;
if(!db_page_pgm_buf1(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_wait_ready(20000);
// program dataflash page
if(!db_page_pgm_buf1(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_wait_ready(20000);
// program dataflash page
if(!db_page_pgm_buf1(src, dest, size))
return DATAFLASH_WRITE_ERROR;
}
return DATAFLASH_WRITE_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -