📄 dataflash.c
字号:
//*----------------------------------------------------------------------------
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
{
unsigned int i,j;
INT32U status;
pDataFlashDesc->DataFlash_state = IDLE;
do
{
AT91F_DataFlashGetStatus(pDataFlashDesc);
timeout--;
// dummy waiting time
for(j=0;j<5;j++)
{
for(i=0;i<20;i++)
;
status = AT91C_BASE_SPI->SPI_SR;// & AT91C_BASE_SPI->SPI_IMR );
if(status & AT91C_SPI_RXBUFF)
{
AT91F_DataFlashHandler(DataFlash.pDataFlashDesc, status);
if(pDataFlashDesc->DataFlash_state != ERROR)
break;
}
}
}
while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout>0) );
if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
return DATAFLASH_ERROR;
return DATAFLASH_OK;
}
void AT91F_AT45D(void)
{
//* 2. On DeviceAT45DB for AT91S_DataflashFeatures structure
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,AT91C_SPI_PCS1_SERIAL_DATAFLASH);
DataFlash.pDevice = &DeviceAT45DB;
//* Wait DataFlash Ready
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Test_AT45DB
//* \brief Configure SPI for Serial DataFlash init, then jump to Test Functions
//*----------------------------------------------------------------------------
void AT91F_Test_AT45DB(void)
{
//* Switch on DataFlash Card AT45DB:
//* 1. On CS0 for AT91F_SPI_CfgPCS
//* 2. On DeviceAT45DB for AT91S_DataflashFeatures structure
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,AT91C_SPI_PCS0_SERIAL_DATAFLASH);
DataFlash.pDevice = &DeviceAT45DB;
//* Wait DataFlash Ready
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Test_AT45DCB
//* \brief Configure SPI for DataFlash Card init, then jump to Test Functions
//*----------------------------------------------------------------------------
void AT91F_Test_AT45DCB(void)
{
//* Switch on DataFlash Card AT45DCB:
//* 1. On CS3 for AT91F_SPI_CfgPCS
//* 2. On DeviceAT45DCB for AT91S_DataflashFeatures structure
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,AT91C_SPI_PCS3_DATAFLASH_CARD);
DataFlash.pDevice = &DeviceAT45DCB;
//* Wait DataFlash Ready
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
}
//*----------------------------------------------------------------------------
//* Function Name : AT91F_SPIflash_WR_BUffer
//* Object : 用buffer写入数据
//* Input Parameters : 源数据指针
//* 扇区的物理地址
//* Output Parameters : none
//*----------------------------------------------------------------------------
INT16U AT91F_SPIflash_WR_BUffer(INT8U *P,INT32U Addr)
{
static INT8U Last_op;
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
// Last_op =1;
if(Last_op == 1)
{
AT91F_DataFlashBufWR( &DataFlash,
P,
0,
DB_BUF1_WRITE);
}
else
{
AT91F_DataFlashBufWR( &DataFlash,
P,
0,
DB_BUF2_WRITE);
}
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
if(Last_op ==1)
{
AT91F_DataFlashSendCom (
&DataFlash,
DB_BUF1_PAGE_ERASE_PGM,
Addr);
Last_op = 0;
}
else
{
AT91F_DataFlashSendCom (
&DataFlash,
DB_BUF2_PAGE_ERASE_PGM,
Addr);
Last_op = 1;
}
return 0;
}
//*----------------------------------------------------------------------------
//* Function Name : ReadSPIflash
//* Object : 读出一个扇区
//* Input Parameters : 目的地指针
//* 扇区的物理地址
//* Output Parameters : 空
//*----------------------------------------------------------------------------
INT16U ReadSPIflash(INT8U *P,INT32U Addr)
{
//AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
AT91F_DataFlashPageRead(&DataFlash,
Addr,
P,
DeviceAT45DB.pages_size);
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
return 0;
}
//*----------------------------------------------------------------------------
//* Function Name : WriteSPIflash
//* Object : 写入一个扇区
//* Input Parameters : 源数据指针
//* 扇区的物理地址
//* Output Parameters : 空
//*----------------------------------------------------------------------------
INT16U WriteSPIflash(INT8U *P,INT32U Addr)
{
//* Wait end of Read
// AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
AT91F_DataFlashPagePgmBuf(&DataFlash,
P,
Addr,
DeviceAT45DB.pages_size);
AT91F_DataFlashWaitReady(DataFlash.pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);
return 0;
}
//*----------------------------------------------------------------------------
//* Function Name : AT91F_SPI_CfgSPI
//* Object : 配置SPI工作模式
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
void AT91F_SPI_CfgSPI(void)
{
//* Reset the SPI
AT91F_SPI_Reset(AT91C_BASE_SPI);
//* Configure SPI in Master Mode with No CS selected !!!
AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS);
//* Configure SPI CS0 for Serial DataFlash AT45DBxx 时钟设置
AT91F_SPI_CfgCs(AT91C_BASE_SPI,1, AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((MCK / (2*DATAFLASH_CLK)) << 8));
//* Configure SPI CS3 for DataFlash Card AT45DCBxx
AT91F_SPI_CfgCs(AT91C_BASE_SPI,3, AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((MCK / (2*DATAFLASH_CLK)) << 8));
//* Enable the SPI
AT91F_SPI_Enable(AT91C_BASE_SPI);
}
//*----------------------------------------------------------------------------
//* Function Name : AT91F_CfgDataFlash
//* Object : 配置所使用的 SPI FLASH 物理结构
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
void AT91F_CfgDataFlash (void)
{
// Init AT91S_DataflashFeatures Structure for AT45DB161
DeviceAT45DB.pages_number = 4096;
DeviceAT45DB.pages_size = 528;
DeviceAT45DB.page_offset = 10;
DeviceAT45DB.byte_mask = 0x700;
// Init AT91S_DataflashFeatures Structure for AT45DCB004 <=> AT45DB321B
DeviceAT45DCB.pages_number = 8192;
DeviceAT45DCB.pages_size = 528;
DeviceAT45DCB.page_offset = 10;
DeviceAT45DCB.byte_mask = 0x300;
// Init AT91S_DataflashFeatures Structure for AT45DCB002 <=> AT45DB161B
/* DeviceAT45DCB.pages_number = 4096;
DeviceAT45DCB.pages_size = 528;
DeviceAT45DCB.page_offset = 10;
DeviceAT45DCB.byte_mask = 0x300; */
// Init AT91S_DataflashDesc Structure
DataflashDesc.state = IDLE;
DataflashDesc.DataFlash_state = IDLE;
// Init AT91S_DataFlash Global Structure, by default AT45DB choosen !!!
DataFlash.pDataFlashDesc = &DataflashDesc;
DataFlash.pDevice = &DeviceAT45DB;
}
//*----------------------------------------------------------------------------
//* Function Name : AT91F_CfgSPIForDataFlash
//* Object : 配置SPI端口 ,配置SPI中断
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
void AT91F_CfgSPIForDataFlash(void)
{
// ============================= Init SPI Interface =============================
//AT91F_DBGU_Printk("\n\rInit SPI Interface\n\r");
// Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard
// AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7);
// AT91F_PIO_ClearOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7);
// Init SPI for DataFlash interface
AT91F_SPI_CfgPIO();
AT91F_SPI_CfgPMC();
AT91F_SPI_CfgSPI();
AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
AT91F_CfgDataFlash();
// Configure SPI interrupt
/* AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
AT91C_ID_SPI,
AT91C_AIC_PRIOR_HIGHEST,
AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
AT91F_ASM_SPI_Handler);
// Enable SPI interrupt
AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_SPI);
*/
AT91F_AT45D();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -