?? w25x32_wr.c
字號:
/**------------------------------------------------------------------------------------------------------
** Created by:
** Created date:
** Version:
** Descriptions: 使用LPC2300系列ARM的SSP DMA,操作W25X32。
**
********************************************************************************************************/
#include "config.h"
/* 全局變量定義 */
//uint8 InitDatas[8] = {0x35, 0x45, 0x55, 0x36, 0x37, 0x38, 0x39, 0x30};
//uint8 RdCmdBuf[5] = {0x0B, 0x0, 0x20, 0x07, 0xFF}; // 該數(shù)組用于存放對FLASH的讀操作初始化信息,僅由SSPDMA_Snd函數(shù)訪問,發(fā)送完這組數(shù)據(jù)后,Flash進(jìn)入讀數(shù)據(jù)狀態(tài)
//uint8 WaitCmdbuf[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 每發(fā)送一個0xff到Flash,Flash會返回一個數(shù)據(jù)
//max add for extend flash r/w area
uint8 setup_sec=SETUP_PARAMS_SEC; //設(shè)定參數(shù)存放的起始扇區(qū)號
uint8 work_sec= WORK_PARAMS_SEC; //工作參數(shù)存放的起始扇區(qū)號
uint8 custom_sec=CUSTOM_PARAMS_SEC; //終端自用,無須上傳,自定義參數(shù)存放的起始扇區(qū)號
uint8 mileage_sec=MILEAGE_ACC_SEC; //存儲里程數(shù)及ACC開關(guān)狀態(tài)的起始扇區(qū)號
uint8 Ini_Sec_counter(uint8* , uint8 , uint8);
uint8 Reset_All_Sec(void);
uint8 Test_Count_Sec(uint8, uint16, uint8);
uint8 Dump_Sec(uint8);
uint8 UART3_output_digit(uint16, uint8);
void DelayS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<5000; i++);
}
uint8 W25X32_READ(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff)
{
/* 中斷方式下DMA發(fā)送和接收 */
// OS_ENTER_CRITICAL();
DelayS(20);
W25X32_RD(Oid_Addr,Oid_Len,Buff);
// OS_EXIT_CRITICAL();
return TRUE;
}
uint8 W25X32_READ_2(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff)
{
// OS_ENTER_CRITICAL();
DelayS(20);
W25X32_RD_2(Oid_Addr,Oid_Len,Buff);
// OS_EXIT_CRITICAL();
return TRUE;
}
/********************************************************************************************************
** 函數(shù)名稱:W25X32_INIT
** 函數(shù)功能:調(diào)用軟件包,演示使用SSP DMA操作W25X32
** 入口參數(shù):無
** 出口參數(shù):返回0則表明出錯
** 調(diào)試說明:在Flash中運(yùn)行
********************************************************************************************************/
uint8 W25X32_INIT(void)
{
/* 完成SSP初始化 */
SSP_Init(); // 初始化SSP管腳以及SSP的工作參數(shù)
#if 1
//Reset_All_Sec(); //erase flash all sector
Ini_Sec_counter( &setup_sec, 'S', SETUP_PARAMS_SEC );
Ini_Sec_counter( &work_sec, 'W', WORK_PARAMS_SEC );
Ini_Sec_counter( &custom_sec, 'C', CUSTOM_PARAMS_SEC );
Ini_Sec_counter( &mileage_sec, 'M', MILEAGE_ACC_SEC );
#endif
return (TRUE);
}
// 將buff寫入從地址Oid_Addr開始的Flash存儲單元里
uint8 W25X32_WRITE(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff, uint32 Data_Size)
{
const uint8 pageLen=0xff;
uint8 i=0;
//uint8 temp[SEC_SIZE];
uint8 * temp;
#if defined(SYSTEM_SEMCONTROL)
INT8U SysFlashErr;
OSSemPend(gw_pSysFlashSem, 0, &SysFlashErr);
#else
OSSchedLock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
OSMemQuery(IntBuffer_Big,&MemInfo);
if(MemInfo.OSNFree > (uint8)(Data_Size/BlockSize_Big))
{
temp=(INT8U *)OSMemGet(IntBuffer_Big,&err);
//使用獲得的內(nèi)存塊
if( (Oid_Addr+Oid_Len)/SEC_SIZE > Oid_Addr/SEC_SIZE )
{
W25X32_READ(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
W25X32_READ(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase((Oid_Addr+Oid_Len)/SEC_SIZE, (Oid_Addr+Oid_Len)/SEC_SIZE);
memmove(temp,Buff+Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE,(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
else
{
W25X32_READ(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
//memset(temp,0,sizeof(temp));
//W25X32_READ(GetAddr(FIRSTSEC,Oid_Addr),Oid_Len,temp);
//釋放獲得的內(nèi)存塊
OSMemPut(IntBuffer_Big,temp);
}
else
{
#if defined(UART_SEMCONTROL)
OSSemPost(gw_pSysFlashSem);
#else
OSSchedUnlock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
return FALSE;
}
#if defined(UART_SEMCONTROL)
OSSemPost(gw_pSysFlashSem);
#else
OSSchedUnlock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
return TRUE;
}
uint8 W25X32_WRITE_2(uint32 Oid_Addr,uint32 Oid_Len,uint8 * Buff,uint32 Data_Size)
{
const uint8 pageLen=0xff;
uint8 i=0;
//uint8 temp[SEC_SIZE];
uint8 * temp;
#if defined(SYSTEM_SEMCONTROL)
INT8U SysFlashErr;
OSSemPend(gw_pSysFlashSem, 0, &SysFlashErr);
#else
OSSchedLock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
OSMemQuery(IntBuffer_Big,&MemInfo);
if(MemInfo.OSNFree > (uint8)(Data_Size/BlockSize_Big))
{
temp=(INT8U *)OSMemGet(IntBuffer_Big,&err);
//使用獲得的內(nèi)存塊
if( ((Oid_Addr+Oid_Len)/SEC_SIZE) > (Oid_Addr/SEC_SIZE) )
{
W25X32_READ_2(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
W25X32_READ_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2((Oid_Addr+Oid_Len)/SEC_SIZE, (Oid_Addr+Oid_Len)/SEC_SIZE);
memmove(temp,Buff+Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE,(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
else
{
W25X32_READ_2(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
//memset(temp,0,sizeof(temp));
//W25X32_READ(GetAddr(FIRSTSEC,Oid_Addr),Oid_Len,temp);
//釋放獲得的內(nèi)存塊
OSMemPut(IntBuffer_Big,temp);
}
else
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -