
寫Code的過程中發現原來巨集後面不能加"空白"字元!
見下圖中紅色框框的地方,如果有空白字元會Compiler error.
將自己踏入BIOS領域中所學習到的知識做一些心得整理,像是Legacy BIOS、EFI BIOS、Windows Driver...etc. ※版權與智慧財產權聲明:保留所有法律權利。我在寫文章時如果有引用到其他人的地方我會盡量說明參考出處,如果有遺漏的地方請告訴我,我會馬上註明! 而轉貼我的文章時也請您註明出處!
| 選項 | 用途 |
|---|---|
| 指定回應檔。 | |
| 列出編譯器選項。 | |
| 指定一個要搜尋的目錄,以解析傳遞給 #using 指示詞的檔案參考。 | |
| 啟用程式碼分析 | |
| 在程式碼產生時使用 SSE 或 SSE2 指令 (僅適用於 x86)。 | |
| 增加 .obj 檔中可定址區段的數目 | |
| 在前置處理過程中保留註解。 | |
| 編譯而不連結。 | |
| 產生輸出檔案,以便在 Common Language Runtime 上執行。 | |
| 定義常數和巨集。 | |
| 將文件註解處理成 XML 檔案 | |
| 複製前置處理器輸出至標準輸出。 | |
| 指定例外處理模型。 | |
| 複製前置處理器輸出至標準輸出。 | |
| 讓您直接提供內部編譯器錯誤 (ICE) 資訊給 Visual C++ 團隊 | |
| 設定堆疊大小。 | |
| 產生已為特定 x64 架構最佳化的程式碼,或為 AMD64 和 延伸記憶體 64 技術 (Extended Memory 64 Technology, EM64T) 架構中微架構特性最佳化的程式碼 | |
| 建立清單檔。 | |
| 設定清單檔名稱。 | |
| 顯示在診斷測試中傳遞給 cl.exe 的原始程式檔完整路徑 | |
| 重新命名程式資料庫檔案。 | |
| 重新命名可執行檔。 | |
| 前置處理指定的包含檔。 | |
| 建立對應檔 (Mapfile)。 | |
| 建立目的檔。 | |
| 指定浮點行為 | |
| 指定先行編譯標頭檔的名稱。 | |
| 產生瀏覽器檔案。 | |
| 強制使用某一檔名,就如同它已傳遞給 #using 指示詞一樣。 | |
| 將插入的程式碼與原始程式檔合併。 | |
| 為 Itanium 處理器執行最佳化。只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。 | |
| 為 Itanium2 處理器最佳化 (預設值為 /G1 與 /G2 之間),只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。 | |
| 對 Windows 應用程式進行程式碼最佳化。 | |
| 使用 __cdecl 呼叫慣例 (僅適用於 x86)。 | |
| 啟動堆疊探查。 | |
| 啟用字串共用。 | |
| 呼叫攔截 (Hook) 函式 _pexit。 | |
| 呼叫攔截 (Hook) 函式 _penter。 | |
| 啟用整個程式最佳化。 | |
| 啟用最少重建。 | |
| 啟用執行階段型別資訊 (RTTI)。 | |
| 使用 __fastcall 呼叫慣例 (僅適用於 x86)。 | |
| 緩衝處理安全性檢查。 | |
| 控制堆疊探查。 | |
| 對使用靜態執行緒區域儲存區配置的資料支援 Fiber 安全性。 | |
| 啟用同步例外處理。 | |
| 啟用函式階層連結。 | |
| 與 /RTC1 相同。/RTC (執行階段錯誤檢查) | |
| 使用 __stdcall 呼叫慣例 (僅適用於 x86)。 | |
| 限制外部 (公用) 名稱的長度。 | |
| 列出編譯器選項。 | |
| 在函式進入時,強制暫存器中所傳遞的參數寫入至堆疊上的位置。這個編譯器選項只適用於 x64 編譯器 (原生和跨平台編譯) | |
| 建立可線上修補的影像 | |
| 搜尋包含檔的目錄。 | |
| 變更預設 char 型別。 | |
| 建立動態連結程式庫。 | |
| 建立偵錯動態連結程式庫。 | |
| 傳遞指定的選項給 LINK。 | |
| 建立 MSIL 模組 | |
| 使用 MSVCRT.lib 建立多執行緒 DLL。 | |
| 使用 MSVCRTD.lib 建立偵錯多執行緒 DLL。 | |
| 使用 LIBCMT.lib 建立多執行緒可執行檔。 | |
| 使用 LIBCMTD.lib 建立偵錯多執行緒可執行檔。 | |
| 隱藏登入程式的啟始資訊。 | |
| 建立小型程式碼。 | |
| 建立快速程式碼。 | |
| 控制內嵌展開。 | |
| 停用最佳化。 | |
| 使用全域最佳化。 | |
| 產生內建函式。 | |
| 在原始程式碼中啟用 #pragma omp | |
| 偏好小的程式碼。 | |
| 偏好快的程式碼。 | |
| 使用最大最佳化 (/Ob2gity /Gs)。 | |
| 省略框架指標 (僅適用於 x86)。 | |
| 在必須從浮點型別轉換為整數型別時,抑制 _ftol (僅適用於 x86)。 | |
| 根據 B CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。 | |
| 根據 C CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。 | |
| 不要使用上層 96 浮點暫存器(僅適用於 IPF)。 | |
| 產生影像加上與位置有關的程式碼 (僅適用於 IPF) | |
| 為不在執行階段建立函式的程式增強效能(僅適用於 IPF)。 | |
| 將前置處理器輸出寫入檔案。 | |
| 啟用執行階段錯誤檢查。 | |
| 在編譯時顯示包含檔清單。 | |
| 指定 C 原始程式檔。 | |
| 指定 C++ 原始程式檔。 | |
| 移除某個預先定義巨集。 | |
| 移除所有預先定義巨集。 | |
| 設定版本字串。 | |
| 抑制或啟用隱藏的 vtordisp 類別成員。 | |
| 對指向成員的指標使用最佳基底。 | |
| 對指向成員的指標使用完整一般性。 | |
| 宣告多重繼承。 | |
| 宣告單一繼承。 | |
| 宣告虛擬繼承。 | |
| 設定警告層級。 | |
| 停用所有警告。 | |
| 啟用所有警告,包括預設停用的警告。 | |
| 從命令列編譯 C++ 原始程式碼時啟用一行錯誤和警告訊息診斷。 | |
| 偵測 64 位元可移植性問題。 | |
| 忽略標準 Include 目錄。 | |
| 忽略目前組建中所有其他先行編譯標頭編譯器選項。 | |
| 建立先行編譯標頭檔。 | |
| 將完整的偵錯資訊置於所有目的檔中。 | |
| 在建立偵錯程式庫時插入一個 PCH 參考 | |
| 在建置時使用先行編譯標頭檔。 | |
| 產生 C 7.0 相容的偵錯資訊。 | |
| 停用語言擴充功能。 | |
| 指定 /Ze 下的標準行為。/Za、/Ze (停用語言擴充功能) | |
| 啟用語言擴充功能。 | |
| 產生函式原型。 | |
| 將偵錯資訊包括在與「編輯後繼續」相容的程式資料庫中。 | |
| 產生完整偵錯資訊。 | |
| 從 .obj 檔案移除預設程式庫名稱 (僅適用於 x86)。 | |
| 指定先行編譯標頭的記憶體配置上限。 | |
| 封裝結構成員。 | |
| 僅檢查語法。 | |
| 產生可偵錯最佳化程式碼,只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供 |
ftp://download.intel.com/technology/framework/docsReference
今天在網路瀏覽的時候看到SST 有提供 Software Driver 的範例程式,從範例程式中可以很容易的知道如何
去控制Flash part的存取 , 如果想學R/W Flash Part的朋友可以參考看看,而底下是一個範例程式:
SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
November 4th, 2005, Rev. 1.0
ABOUT THE SOFTWARE
This application note provides software driver examples for SST25VF080B,
Serial Flash. Extensive comments are included in each routine to describe
the function of each routine. The interface coding uses polling method
rather than the SPI protocol to interface with these serial devices. The
functions are differentiated below in terms of the communication protocols
(uses Mode 0) and specific device operation instructions. This code has been
designed to compile using the Keil compiler.
ABOUT THE SST25VF080B
Companion product datasheets for the SST25VF080B should be reviewed in
conjunction with this application note for a complete understanding
of the device.
Device Communication Protocol(pinout related) functions:
Functions Function
------------------------------------------------------------------
init Initializes clock to set up mode 0.
Send_Byte Sends one byte using SI pin to send and
shift out 1-bit per clock rising edge
Get_Byte Receives one byte using SO pin to receive and shift
in 1-bit per clock falling edge
Poll_SO Used in the polling for RY/BY# of SO during AAI programming
CE_High Sets Chip Enable pin of the serial flash to high
CE_Low Clears Chip Enable of the serial flash to low
Hold_Low Clears Hold pin to make serial flash hold
Unhold Unholds the serial flash
WP_Low Clears WP pin to make serial flash write protected
UnWP Disables write protection pin
Note: The pin names of the SST25VF080B are used in this application note. The associated test code
will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
software which should reflect your hardware interfaced.
Device Operation Instruction functions:
Functions Function
------------------------------------------------------------------
Read_Status_Register Reads the status register of the serial flash
EWSR Enables the Write Status Register
WRSR Performs a write to the status register
WREN Write enables the serial flash
WRDI Write disables the serial flash
EBSY Enable SO to output RY/BY# status during AAI programming
DBSY Disable SO to output RY/BY# status during AAI programming
Read_ID Reads the manufacturer ID and device ID
Jedec_ID_Read Reads the Jedec ID
Read Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
Read_Cont Reads multiple bytes(max of 25 MHz CLK frequency)
HighSpeed_Read Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
HighSpeed_Read_Cont Reads multiple bytes(max of 50 MHz CLK frequency)
Byte_Program Program one byte to the serial flash
Auto_Add_IncA Initial Auto Address Increment process
Auto_Add_IncB Successive Auto_Address_Increment process after AAI initiation
Auto_Add_IncA_EBSY Initial Auto Address Increment process with EBSY
Auto_Add_IncB_EBSY Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
Chip_Erase Erases entire serial flash
Sector_Erase Erases one sector (4 KB) of the serial flash
Block_Erase_32K Erases 32 KByte block memory of the serial flash
Block_Erase_64K Erases 64 KByte block memory of the serial flash
Wait_Busy Polls status register until busy bit is low
Wait_Busy_AAI Polls status register until busy bit is low for AAI programming
WREN_Check Checks to see if WEL is set
WREN_AAI_Check Checks to see if WEL and AAI mode is set
"C" LANGUAGE DRIVERS
/********************************************************************/
/* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005 */
/* Example "C" language Driver of SST25VF080B Serial Flash */
/* Conrado Canio, Silicon Storage Technology, Inc. */
/* */
/* Revision 1.0, November 4th, 2005 */
/* */
/* */
/********************************************************************/
#include
#include
/* Function Prototypes */
void init();
void Send_Byte(unsigned char out);
unsigned char Get_Byte();
void Poll_SO();
void CE_High();
void CE_Low();
void Hold_Low();
void Unhold();
void WP_Low();
void UnWP();
unsigned char Read_Status_Register();
void EWSR();
void WRSR(byte);
void WREN();
void WRDI();
void EBSY();
void DBSY();
unsigned char Read_ID(ID_addr);
unsigned long Jedec_ID_Read();
unsigned char Read(unsigned long Dst);
void Read_Cont(unsigned long Dst, unsigned long no_bytes);
unsigned char HighSpeed_Read(unsigned long Dst);
void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
void Byte_Program(unsigned long Dst, unsigned char byte);
void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
void Chip_Erase();
void Sector_Erase(unsigned long Dst);
void Block_Erase_32K(unsigned long Dst);
void Block_Erase_64K(unsigned long Dst);
void Wait_Busy();
void Wait_Busy_AAI();
void WREN_Check();
void WREN_AAI_Check();
void Verify(unsigned char byte, unsigned char cor_byte);
unsigned char idata upper_128[128]; /* global array to store read data */
/* to upper RAM area from 80H - FFH */
/************************************************************************/
/* PROCEDURE: init */
/* */
/* This procedure initializes the SCK to low. Must be called prior to */
/* setting up mode 0. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* SCK */
/************************************************************************/
void init()
{
SCK = 0; /* set clock to low initial state */
}
/************************************************************************/
/* PROCEDURE: Send_Byte */
/* */
/* This procedure outputs a byte shifting out 1-bit per clock rising */
/* edge on the the SI pin(LSB 1st). */
/* */
/* Input: */
/* out */
/* */
/* Output: */
/* SI */
/************************************************************************/
void Send_Byte(unsigned char out)
{
unsigned char i = 0;
for (i = 0; i < 8; i++)
{
if ((out & 0x80) == 0x80) /* check if MSB is high */
SI = 1;
else
SI = 0; /* if not, set to low */
SCK = 1; /* toggle clock high */
out = (out << 1); /* shift 1 place for next bit */
SCK = 0; /* toggle clock low */
}
}
/************************************************************************/
/* PROCEDURE: Get_Byte */
/* */
/* This procedure inputs a byte shifting in 1-bit per clock falling */
/* edge on the SO pin(LSB 1st). */
/* */
/* Input: */
/* SO */
/* */
/* Output: */
/* None */
/************************************************************************/
unsigned char Get_Byte()
{
unsigned char i = 0, in = 0, temp = 0;
for (i = 0; i < 8; i++)
{
in = (in << 1); /* shift 1 place to the left or shift in 0 */
temp = SO; /* save input */
SCK = 1; /* toggle clock high */
if (temp == 1) /* check to see if bit is high */
in = in | 0x01; /* if high, make bit high */
SCK = 0; /* toggle clock low */
}
return in;
}
/************************************************************************/
/* PROCEDURE: Poll_SO */
/* */
/* This procedure polls for the SO line during AAI programming */
/* waiting for SO to transition to 1 which will indicate AAI programming*/
/* is completed */
/* */
/* Input: */
/* SO */
/* */
/* Output: */
/* None */
/************************************************************************/
void Poll_SO()
{
unsigned char temp = 0;
CE_Low();
while (temp == 0x00) /* waste time until not busy */
temp = SO;
CE_High();
}
/************************************************************************/
/* PROCEDURE: CE_High */
/* */
/* This procedure set CE = High. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* CE */
/* */
/************************************************************************/
void CE_High()
{
CE = 1; /* set CE high */
}
/************************************************************************/
/* PROCEDURE: CE_Low */
/* */
/* This procedure drives the CE of the device to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* CE */
/* */
/************************************************************************/
void CE_Low()
{
CE = 0; /* clear CE low */
}
/************************************************************************/
/* PROCEDURE: Hold() */
/* */
/* This procedure clears the Hold pin to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* Hold */
/************************************************************************/
void Hold_Low()
{
Hold = 0; /* clear Hold pin */
}
/************************************************************************/
/* PROCEDURE: Unhold() */
/* */
/* This procedure sets the Hold pin to high. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* Hold */
/************************************************************************/
void Unhold()
{
Hold = 1; /* set Hold pin */
}
/************************************************************************/
/* PROCEDURE: WP() */
/* */
/* This procedure clears the WP pin to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* WP */
/************************************************************************/
void WP_Low()
{
WP = 0; /* clear WP pin */
}
/************************************************************************/
/* PROCEDURE: UnWP() */
/* */
/* This procedure sets the WP pin to high. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* WP */
/************************************************************************/
void UnWP()
{
WP = 1; /* set WP pin */
}
/************************************************************************/
/* PROCEDURE: Read_Status_Register */
/* */
/* This procedure read the status register and returns the byte. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* byte */
/************************************************************************/
unsigned char Read_Status_Register()
{
unsigned char byte = 0;
CE_Low(); /* enable device */
Send_Byte(0x05); /* send RDSR command */
byte = Get_Byte(); /* receive byte */
CE_High(); /* disable device */
return byte;
}
/************************************************************************/
/* PROCEDURE: EWSR */
/* */
/* This procedure Enables Write Status Register. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void EWSR()
{
CE_Low(); /* enable device */
Send_Byte(0x50); /* enable writing to the status register */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: WRSR */
/* */
/* This procedure writes a byte to the Status Register. */
/* */
/* Input: */
/* byte */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WRSR(byte)
{
CE_Low(); /* enable device */
Send_Byte(0x01); /* select write to status register */
Send_Byte(byte); /* data that will change the status of BPx
or BPL (only bits 2,3,4,5,7 can be written) */
CE_High(); /* disable the device */
}
/************************************************************************/
/* PROCEDURE: WREN */
/* */
/* This procedure enables the Write Enable Latch. It can also be used */
/* to Enables Write Status Register. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN()
{
CE_Low(); /* enable device */
Send_Byte(0x06); /* send WREN command */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: WRDI */
/* */
/* This procedure disables the Write Enable Latch. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WRDI()
{
CE_Low(); /* enable device */
Send_Byte(0x04); /* send WRDI command */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: EBSY */
/* */
/* This procedure enable SO to output RY/BY# status during AAI */
/* programming. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void EBSY()
{
CE_Low(); /* enable device */
Send_Byte(0x70); /* send EBSY command */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: DBSY */
/* */
/* This procedure disable SO as output RY/BY# status signal during AAI */
/* programming. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void DBSY()
{
CE_Low(); /* enable device */
Send_Byte(0x80); /* send DBSY command */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Read_ID */
/* */
/* This procedure Reads the manufacturer's ID and device ID. It will */
/* use 90h or ABh as the command to read the ID (90h in this sample). */
/* It is up to the user to give the last byte ID_addr to determine */
/* whether the device outputs manufacturer's ID first, or device ID */
/* first. Please see the product datasheet for details. Returns ID in */
/* variable byte. */
/* */
/* Input: */
/* ID_addr */
/* */
/* Returns: */
/* byte: ID1(Manufacture's ID = BFh or Device ID = 8Eh) */
/* */
/************************************************************************/
unsigned char Read_ID(ID_addr)
{
unsigned char byte;
CE_Low(); /* enable device */
Send_Byte(0x90); /* send read ID command (90h or ABh) */
Send_Byte(0x00); /* send address */
Send_Byte(0x00); /* send address */
Send_Byte(ID_addr); /* send address - either 00H or 01H */
byte = Get_Byte(); /* receive byte */
CE_High(); /* disable device */
return byte;
}
/************************************************************************/
/* PROCEDURE: Jedec_ID_Read */
/* */
/* This procedure Reads the manufacturer's ID (BFh), memory type (25h) */
/* and device ID (8Eh). It will use 9Fh as the JEDEC ID command. */
/* Please see the product datasheet for details. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h), */
/* and Device ID (8Eh) */
/* */
/************************************************************************/
unsigned long Jedec_ID_Read()
{
unsigned long temp;
temp = 0;
CE_Low(); /* enable device */
Send_Byte(0x9F); /* send JEDEC ID command (9Fh) */
temp = (temp | Get_Byte()) << 8; /* receive byte */
temp = (temp | Get_Byte()) << 8;
temp = (temp | Get_Byte()); /* temp value = 0xBF258E */
CE_High(); /* disable device */
return temp;
}
/************************************************************************/
/* PROCEDURE: Read */
/* */
/* This procedure reads one address of the device. It will return the */
/* byte read in variable byte. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* */
/* Returns: */
/* byte */
/* */
/************************************************************************/
unsigned char Read(unsigned long Dst)
{
unsigned char byte = 0;
CE_Low(); /* enable device */
Send_Byte(0x03); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
byte = Get_Byte();
CE_High(); /* disable device */
return byte; /* return one byte read */
}
/************************************************************************/
/* PROCEDURE: Read_Cont */
/* */
/* This procedure reads multiple addresses of the device and stores */
/* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* no_bytes Number of bytes to read (max = 128) */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Read_Cont(unsigned long Dst, unsigned long no_bytes)
{
unsigned long i = 0;
CE_Low(); /* enable device */
Send_Byte(0x03); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
{
upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */
}
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: HighSpeed_Read */
/* */
/* This procedure reads one address of the device. It will return the */
/* byte read in variable byte. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* */
/* Returns: */
/* byte */
/* */
/************************************************************************/
unsigned char HighSpeed_Read(unsigned long Dst)
{
unsigned char byte = 0;
CE_Low(); /* enable device */
Send_Byte(0x0B); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(0xFF); /*dummy byte*/
byte = Get_Byte();
CE_High(); /* disable device */
return byte; /* return one byte read */
}
/************************************************************************/
/* PROCEDURE: HighSpeed_Read_Cont */
/* */
/* This procedure reads multiple addresses of the device and stores */
/* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* no_bytes Number of bytes to read (max = 128) */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
{
unsigned long i = 0;
CE_Low(); /* enable device */
Send_Byte(0x0B); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(0xFF); /*dummy byte*/
for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
{
upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */
}
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Byte_Program */
/* */
/* This procedure programs one address of the device. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte: byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Byte_Program(unsigned long Dst, unsigned char byte)
{
CE_Low(); /* enable device */
Send_Byte(0x02); /* send Byte Program command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte); /* send byte to be programmed */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Auto_Add_IncA */
/* */
/* This procedure programs consecutive addresses of 2 bytes of data into*/
/* the device: 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be be */
/* programmed into initial address [A23-A1] and with A0 = 1. This */
/* is used to to start the AAI process. It should be followed by */
/* Auto_Add_IncB. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* Note: Only RDSR command can be executed once in AAI mode with SO */
/* disable to output RY/BY# status. Use WRDI to exit AAI mode */
/* unless AAI is programming the last address or last address of */
/* unprotected block, which automatically exits AAI mode. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte1: 1st byte to be programmed */
/* byte1: 2nd byte to be programmed */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Auto_Add_IncB */
/* */
/* This procedure programs consecutive addresses of 2 bytes of data into*/
/* the device: 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be be */
/* programmed into initial address [A23-A1] and with A0 = 1. This */
/* is used after Auto_Address_IncA. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* */
/* byte1: 1st byte to be programmed */
/* byte2: 2nd byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Auto_Add_IncA_EBSY */
/* */
/* This procedure is the same as procedure Auto_Add_IncA except that it */
/* uses EBSY and Poll_SO functions to check for RY/BY. It programs */
/* consecutive addresses of the device. The 1st data byte will be */
/* programmed into the initial address [A23-A1] and with A0 = 0. The */
/* 2nd data byte will be programmed into initial address [A23-A1] and */
/* with A0 = 1. This is used to to start the AAI process. It should */
/* be followed by Auto_Add_IncB_EBSY. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte1: 1st byte to be programmed */
/* byte1: 2nd byte to be programmed */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
{
EBSY(); /* enable RY/BY# status for SO in AAI */
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
Poll_SO(); /* polls RY/BY# using SO line */
}
/************************************************************************/
/* PROCEDURE: Auto_Add_IncB_EBSY */
/* */
/* This procedure is the same as Auto_Add_IncB except that it uses */
/* Poll_SO to poll for RY/BY#. It demonstrate on how to use DBSY after */
/* AAI programmming is completed. It programs consecutive addresses of */
/* the device. The 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be */
/* programmed into initial address [A23-A1] and with A0 = 1. This is */
/* used after Auto_Address_IncA. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy, */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* */
/* byte1: 1st byte to be programmed */
/* byte2: 2nd byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
Poll_SO(); /* polls RY/BY# using SO line */
WRDI(); /* Exit AAI before executing DBSY */
DBSY(); /* disable SO as RY/BY# output if in AAI */
}
/************************************************************************/
/* PROCEDURE: Chip_Erase */
/* */
/* This procedure erases the entire Chip. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Chip_Erase()
{
CE_Low(); /* enable device */
Send_Byte(0x60); /* send Chip Erase command (60h or C7h) */
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Sector_Erase */
/* */
/* This procedure Sector Erases the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Sector_Erase(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0x20); /* send Sector Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Block_Erase_32K */
/* */
/* This procedure Block Erases 32 KByte of the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Block_Erase_32K(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0x52); /* send 32 KByte Block Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Block_Erase_64K */
/* */
/* This procedure Block Erases 64 KByte of the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Block_Erase_64K(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0xD8); /* send 64KByte Block Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}
/************************************************************************/
/* PROCEDURE: Wait_Busy */
/* */
/* This procedure waits until device is no longer busy (can be used by */
/* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase). */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Wait_Busy()
{
while (Read_Status_Register() == 0x03) /* waste time until not busy */
Read_Status_Register();
}
/************************************************************************/
/* PROCEDURE: Wait_Busy_AAI */
/* */
/* This procedure waits until device is no longer busy for AAI mode. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Wait_Busy_AAI()
{
while (Read_Status_Register() == 0x43) /* waste time until not busy */
Read_Status_Register();
}
/************************************************************************/
/* PROCEDURE: WREN_Check */
/* */
/* This procedure checks to see if WEL bit set before program/erase. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN_Check()
{
unsigned char byte;
byte = Read_Status_Register(); /* read the status register */
if (byte != 0x02) /* verify that WEL bit is set */
{
while(1)
/* add source code or statements for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */
}
}
/************************************************************************/
/* PROCEDURE: WREN_AAI_Check */
/* */
/* This procedure checks for AAI and WEL bit once in AAI mode. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN_AAI_Check()
{
unsigned char byte;
byte = Read_Status_Register(); /* read the status register */
if (byte != 0x42) /* verify that AAI and WEL bit is set */
{
while(1)
/* add source code or statements for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */
}
}
/************************************************************************/
/* PROCEDURE: Verify */
/* */
/* This procedure checks to see if the correct byte has be read. */
/* */
/* Input: */
/* byte: byte read */
/* cor_byte: correct_byte that should be read */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Verify(unsigned char byte, unsigned char cor_byte)
{
if (byte != cor_byte)
{
while(1)
/* add source code or statement for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */
}
}
int main()
{
return 0;
}
而範例程式中已經把主要的控制方式的"概念"都已經列出來了!
所以只要讀一下Datasheet應該就可以了解他的意義!
至於main()裡面要做甚麼就因人而異,因此千萬不要問我 main()要怎麼寫!
Reference
http://www.sst.com
點Software Driver 旁邊的TXT就可以看到範例程式