?? flash.c
字號(hào):
//*------------------------------------------------------------------------------------------------
//* 文件名 : flash.c
//* 功能描述 : FLASH讀寫驅(qū)動(dòng)
//* 作者 : 焦海波
//* 版本 : 0.1
//* 建立日期、時(shí)間 : 2008/05/04 16:04
//* 最近修改日期、時(shí)間 :
//* 修改原因 :
//*------------------------------------------------------------------------------------------------
//*------------------------------------------ 頭文件 ----------------------------------------------
#include "/at91sam7x256/include/AT91SAM7X256.h"
#include "/uCOS-II/ucos_ii.h"
#include "spi.h"
#define OS_GLOBALS
#include "flash.h"
//*---------------------------------------- 變量定義區(qū) --------------------------------------------
static ST_SPI_DEV_RW stFlash;
//*================================================================================================
//* 函 數(shù) 區(qū)
//*================================================================================================
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : FlashInitCfg
//* 功能描述 : 外部FLASH初始設(shè)置,實(shí)際完成與FLASH相連的SPI接口的初始設(shè)置工作
//* 入口參數(shù) : 無
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
void FlashInitCfg(void)
{
//* 復(fù)位FLASH
AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x09 << 8);
AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
//* 等待NRST引腳恢復(fù)為高電平
while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL));
//* 使能FLASH設(shè)備的片選線
AT91C_BASE_PIOA->PIO_IDR = FLASH_NPCS;
AT91C_BASE_PIOA->PIO_PPUDR = FLASH_NPCS;
AT91C_BASE_PIOA->PIO_ASR = FLASH_NPCS;
AT91C_BASE_PIOA->PIO_PDR = FLASH_NPCS;
//* 設(shè)定為SPI模式0(CPOL:0,NCPHA:1),波特率為1MHz,片選有效之后延時(shí)12/MCK時(shí)間之后輸出SPCK,
//* 兩個(gè)連續(xù)傳輸之間等待(32*1)/MCK時(shí)間
FLASH_BASE->SPI_CSR[FLASH_NPCS_IDX] = AT91C_SPI_NCPHA | ((MCK/FLASH_RW_BAUD_RATE) << 8)| ((unsigned int)12 << 16) | ((unsigned int)1 << 24);
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __SendOptFlashCode
//* 功能描述 : 向FLASH發(fā)送操作碼
//* 入口參數(shù) : <pbCmd>[in] 指向操作指令的指針
//* : <u8CmdLen>[in] 操作指令的長(zhǎng)度
//* : <pbData>[in] 指向具體的操作數(shù)據(jù)的指針
//* : <u32DataLen>[in] 具體的操作數(shù)據(jù)的長(zhǎng)度
//* : <pfunCallBack>[in] 回調(diào)函數(shù)指針
//* : <pvArg>[in] 傳遞給回調(diào)函數(shù)的參數(shù)
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
static void __SendOptFlashCode(INT8U *pbCmd, INT8U u8CmdLen, INT8U *pbData,
INT32U u32DataLen, PFUN_CALLBACK pfunCallBack, void *pvArg)
{
memset(&stFlash, 0, sizeof(ST_SPI_DEV_RW));
stFlash.u8SPIPort = SPI0;
stFlash.u8NPCSPin = FLASH_NPCS_IDX;
stFlash.pbCmd = pbCmd;
stFlash.u8CmdLen = u8CmdLen;
stFlash.pbData = pbData;
stFlash.u32DataLen = u32DataLen;
stFlash.pfunCallBack = pfunCallBack;
stFlash.pvArg = pvArg;
ReadAndWriteSPIDev(&stFlash);
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __GetFlashStatus
//* 功能描述 : 獲得外部Flash狀態(tài)
//* 入口參數(shù) : 無
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
static INT8U __GetFlashStatus(void)
{
INT8U __bCmd = FLASH_CMD_READ_STATUS;
INT8U __bStatus = 0x00;
__SendOptFlashCode(&__bCmd, 1, &__bStatus, 1, NULL, NULL);
macWaitSPIRecvEnd();
return __bStatus;
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : CheckFlashID
//* 功能描述 : 外部FLASH初始設(shè)置,實(shí)際完成與FLASH相連的SPI接口的初始設(shè)置工作
//* 入口參數(shù) : 無
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
void CheckFlashID(void)
{
while(FLASH_ID != (__GetFlashStatus() & FLASH_ID_MASK));
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : FlashRead
//* 功能描述 : 從指定頁面的指定位置讀取數(shù)據(jù)
//* 入口參數(shù) : <u16PageIdx>[in] 指定要讀取的頁面
//* : <u16ByteAddr>[in] 指定數(shù)據(jù)在頁面中的讀取地址
//* : <pbData>[in] 指向接收緩沖區(qū)的指針
//* : <u32DataLen>[in] 要讀取數(shù)據(jù)的長(zhǎng)度
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
void FlashRead(INT16U u16PageIdx, INT16U u16ByteAddr, INT8U *pbData, INT32U u32DataLen)
{
__align(4) INT8U __bCmd[8];
U_FLASH_OPT_CODE __uFOptCode;
INT8U __u8Err;
memset(__bCmd, 0, sizeof(__bCmd));
//* 按照嚴(yán)格的格式組裝操作指令
__uFOptCode.bstOptCode.bitByteAddr = u16ByteAddr;
__uFOptCode.bstOptCode.bitPageAddr = u16PageIdx;
__uFOptCode.bstOptCode.bitReserved = 0;
__uFOptCode.bstOptCode.bitCmd = FLASH_CMD_CONTINUOUS_READ;
*((unsigned int*)&__bCmd[0]) = macHighToLowSwitch(__uFOptCode.u32OptCode);
OSMutexPend(hSPI0, 0, &__u8Err);
{
__SendOptFlashCode(__bCmd, 8, pbData, u32DataLen, NULL, NULL);
macWaitSPIRecvEnd();
}
OSMutexPost(hSPI0);
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __IsErased
//* 功能描述 : 判斷指定頁面是否已經(jīng)被擦除
//* 入口參數(shù) : <u16PageIdx>[in] 指定要檢查的頁面號(hào)
//* 出口參數(shù) : OS_TRUE - 已擦除
//* : OS_FALSE - 未擦除或未擦除干凈
//*------------------------------------------------------------------------------------------------
static BOOLEAN __IsErased(INT16U u16PageIdx)
{
INT32U i;
__align(4) INT8U __bFBuf[FLASH_BUF_SIZE];
memset(__bFBuf, 0, sizeof(__bFBuf));
FlashRead(u16PageIdx, 0, __bFBuf, sizeof(__bFBuf));
for(i=0; i<FLASH_PAGE_SIZE/4; i++)
{
if(((unsigned int*)__bFBuf)[i] != 0xFFFFFFFF)
return OS_FALSE;
}
return OS_TRUE;
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __FlashErase
//* 功能描述 : 擦除指定頁面
//* 入口參數(shù) : <u16PageIdx>[in] 指定要擦除的頁面
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
static BOOLEAN __FlashErase(INT16U u16PageIdx)
{
INT8U i = 0;
__align(4) INT8U __bCmd[4];
U_FLASH_OPT_CODE __uFOptCode;
while(i++ < 3)
{
if(__IsErased(u16PageIdx))
return OS_TRUE;
else
{
memset(__bCmd, 0, sizeof(__bCmd));
//* 按照嚴(yán)格的格式組裝操作指令
__uFOptCode.bstOptCode.bitByteAddr = 0;
__uFOptCode.bstOptCode.bitPageAddr = u16PageIdx;
__uFOptCode.bstOptCode.bitReserved = 0;
__uFOptCode.bstOptCode.bitCmd = FLASH_CMD_PAGE_ERASE;
*((unsigned int*)&__bCmd[0]) = macHighToLowSwitch(__uFOptCode.u32OptCode);
__SendOptFlashCode(__bCmd, 4, NULL, 0, NULL, NULL);
macWaitSPIRecvEnd();
while(!(__GetFlashStatus() & FLASH_IS_RDY));
}
}
return OS_FALSE;
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : FlashWrite
//* 功能描述 : 向指定頁面的指定位置寫入數(shù)據(jù)
//* 入口參數(shù) : <u16PageIdx>[in] 指定要擦除的頁面
//* : <u16ByteAddr>[in] 指定數(shù)據(jù)在頁面中的寫入地址
//* : <pbData>[in] 指向?qū)懭霐?shù)據(jù)的指針
//* : <u16DataLen>[in] 寫入數(shù)據(jù)的長(zhǎng)度
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
BOOLEAN FlashWrite(INT16U u16PageIdx, INT16U u16ByteAddr, INT8U *pbData, INT16U u16DataLen)
{
__align(4) INT8U __bCmd[4];
INT8U __bFBuf[FLASH_BUF_SIZE];
U_FLASH_OPT_CODE __uFOptCode;
INT16U i;
INT8U __u8Err;
if(u16DataLen > FLASH_BUF_SIZE)
return OS_FALSE;
memcpy(__bFBuf, pbData, u16DataLen);
//* 首先進(jìn)行頁面擦除
if(!__FlashErase(u16PageIdx))
return OS_FALSE;
//* 向FLASH寫入數(shù)據(jù)
memset(__bCmd, 0, sizeof(__bCmd));
//* 按照嚴(yán)格的格式組裝操作指令
__uFOptCode.bstOptCode.bitByteAddr = u16ByteAddr;
__uFOptCode.bstOptCode.bitPageAddr = u16PageIdx;
__uFOptCode.bstOptCode.bitReserved = 0;
__uFOptCode.bstOptCode.bitCmd = FLASH_CMD_PAGE_WRITE;
*((unsigned int*)&__bCmd[0]) = macHighToLowSwitch(__uFOptCode.u32OptCode);
OSMutexPend(hSPI0, 0, &__u8Err);
{
__SendOptFlashCode(__bCmd, 4, __bFBuf, u16DataLen, NULL, NULL);
macWaitSPIRecvEnd();
while(!(__GetFlashStatus() & FLASH_IS_RDY));
}
OSMutexPost(hSPI0);
FlashRead(u16PageIdx, u16ByteAddr, __bFBuf, sizeof(__bFBuf));
for(i=0; i<u16DataLen; i++)
{
if(__bFBuf[i] != pbData[i])
return OS_FALSE;
}
return OS_TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -