⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataflash.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 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 + -