|
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。- Software Driver/ [9 u0 W4 H! p4 G4 |: F8 ^+ Q- F9 t
- 4 S% e1 v3 [- x" z
- SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory0 g4 {# N- R. K+ W4 G
- ! O: b+ Z8 |& U& X8 f' X
- November 4th, 2005, Rev. 1.0
6 G w; Y" n' z; } j' @$ E/ _/ k( P
0 T6 U' \9 p8 [9 Z) P- ABOUT THE SOFTWARE
; i+ s$ D6 M0 @; q0 c( P2 u - This application note provides software driver examples for SST25VF080B,
# H& t1 ]2 r) {2 v* a# F - Serial Flash. Extensive comments are included in each routine to describe
; H" [. a* Y" V+ m - the function of each routine. The interface coding uses polling method
9 |- J$ S" _4 ?! P& m - rather than the SPI protocol to interface with these serial devices. The
5 A( p7 W5 P# W% F - functions are differentiated below in terms of the communication protocols
# j3 @4 ^8 e+ K+ F - (uses Mode 0) and specific device operation instructions. This code has been
2 I& |7 t9 j U0 r+ Q1 d! ]) x - designed to compile using the Keil compiler.
! w# E- X& C: l2 d1 _: u - 2 g" m; o/ o4 m
1 z) b2 K3 R' e, i) N0 N+ o( x# N- ABOUT THE SST25VF080B
' C1 N' D" x, ~8 `, k ] - ) i1 A, `3 ~8 _
- Companion product datasheets for the SST25VF080B should be reviewed in
: p8 p. V) a9 k! i- m# { - conjunction with this application note for a complete understanding
' a6 N$ B5 T6 @; R# n# v3 l- W - of the device.4 N) W( R* i& s9 J
- 6 w& P8 f$ P1 ^7 ]3 w
1 d6 U, u; U1 j& }* L& [* p- Device Communication Protocol(pinout related) functions:
# U0 F/ [( l6 H3 {5 Y" r' { - . r4 V& [; k0 {% U* Z5 u
- Functions Function. f) f+ J/ w! i
- ------------------------------------------------------------------0 h0 n4 |0 B/ S' T5 M+ M Q
- init Initializes clock to set up mode 0.2 d7 J# j! m9 l2 ~/ ~7 H
- Send_Byte Sends one byte using SI pin to send and + C$ f" Z- [. `9 ^6 s
- shift out 1-bit per clock rising edge% E( P" `( i* [3 ~9 A7 P
- Get_Byte Receives one byte using SO pin to receive and shift ' H6 s( z s3 ~$ g5 v' a. K& }6 K; g
- in 1-bit per clock falling edge
8 B; V/ W1 `- X% X5 u - Poll_SO Used in the polling for RY/BY# of SO during AAI programming
. O9 a6 m V# r7 |$ H) w" v - CE_High Sets Chip Enable pin of the serial flash to high
+ c1 J; A) s* P t( o( { - CE_Low Clears Chip Enable of the serial flash to low2 Q$ s+ f* ^* k+ f/ K3 I0 h7 z; P
- Hold_Low Clears Hold pin to make serial flash hold" z5 I2 p9 V: [( Z
- Unhold Unholds the serial flash+ C$ E- ~$ V5 H' t# B9 {
- WP_Low Clears WP pin to make serial flash write protected6 [' `' X# S/ L5 o
- UnWP Disables write protection pin
! L* @2 Y+ A2 [1 j: b/ G7 x' G h
9 G- _, l' _ ?0 Y0 e- Note: The pin names of the SST25VF080B are used in this application note. The associated test code
) Z; D4 h7 n7 J! `) E - will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your, D9 ~, q* Z9 j$ g9 G# |
- software which should reflect your hardware interfaced. / N) w3 n9 V) p* @4 |& |% Z' x! O* K
* G3 e& V, m1 [! \
6 w' j0 \" Z, S, f6 ~- Device Operation Instruction functions:
7 z. }" p7 Y* ?$ Q$ ~7 \ s, p - & w, U) G) I# l& Y* m4 H
- Functions Function
( `# M, |, S* m' m& T! Z - ------------------------------------------------------------------ J0 q6 `, H4 [* ?0 S6 V: T
- Read_Status_Register Reads the status register of the serial flash
! m, d8 N! x+ A" s; E- `& i - EWSR Enables the Write Status Register, f+ w/ I. w" F v; V$ m6 {
- WRSR Performs a write to the status register
2 y6 z P/ Y) Q1 A7 r( e - WREN Write enables the serial flash
9 i" E$ ?$ D$ e7 {# V ^1 e - WRDI Write disables the serial flash8 O+ k3 ]/ @; P# l5 x2 \1 h$ p
- EBSY Enable SO to output RY/BY# status during AAI programming" y" I; f6 t8 P2 b
- DBSY Disable SO to output RY/BY# status during AAI programming
' @% q9 u( @7 y6 W! I4 L a - Read_ID Reads the manufacturer ID and device ID3 q/ J, L" ^. E6 g/ i
- Jedec_ID_Read Reads the Jedec ID
( e q5 {* x5 J. z: ~ - Read Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
! b0 F+ [' O6 t - Read_Cont Reads multiple bytes(max of 25 MHz CLK frequency)
! o; c: c' o4 N* Y - HighSpeed_Read Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)" }- U& o* K) x9 o% z0 s/ F- W
- HighSpeed_Read_Cont Reads multiple bytes(max of 50 MHz CLK frequency)7 {- `$ H' O9 u0 c5 m
- Byte_Program Program one byte to the serial flash8 ~: P% g5 Y% ~, k! @
- Auto_Add_IncA Initial Auto Address Increment process
4 v9 `/ {/ B1 F+ _) @' G - Auto_Add_IncB Successive Auto_Address_Increment process after AAI initiation* Q- a9 Y/ u' y# \- y/ A
- Auto_Add_IncA_EBSY Initial Auto Address Increment process with EBSY
! v2 k' Y9 M3 h1 I% m( J - Auto_Add_IncB_EBSY Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY1 \4 \+ B5 J, v0 K: U
- Chip_Erase Erases entire serial flash
8 V3 v0 t8 [' M$ ^ - Sector_Erase Erases one sector (4 KB) of the serial flash. c1 c9 m9 n+ N' @1 }
- Block_Erase_32K Erases 32 KByte block memory of the serial flash
# b8 P, a( S: }1 g3 D+ {$ Q - Block_Erase_64K Erases 64 KByte block memory of the serial flash
3 L/ v1 r! u- L# Q$ l' y - Wait_Busy Polls status register until busy bit is low
" W1 T& c5 P' { z% Q; y - Wait_Busy_AAI Polls status register until busy bit is low for AAI programming6 o* L# k( a- J0 f+ D7 K" ]$ }
- WREN_Check Checks to see if WEL is set6 N' g! D. K/ H6 x& z; {0 t' t
- WREN_AAI_Check Checks to see if WEL and AAI mode is set3 G) k+ L7 j2 `/ m- ^& G- F
& e$ w7 ]& Z6 [/ G: R- ^8 D G3 } ^/ C
) l# W3 M" `' E4 I- 8 b" P0 a p! f9 d
- "C" LANGUAGE DRIVERS 1 v+ U, X: `! s6 ^/ Z
$ V$ M/ W9 g, Y$ F5 N9 h+ `5 p- /********************************************************************/
5 N5 \2 Q& x7 @: S - /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005 */
" h& V! [$ Y( I- h9 H - /* Example "C" language Driver of SST25VF080B Serial Flash */$ Z2 U3 V2 ~/ N3 |3 F7 d
- /* Conrado Canio, Silicon Storage Technology, Inc. */( {% w3 W, Y. L5 r% Y( F
- /* */
7 B' B1 K# n- J0 T - /* Revision 1.0, November 4th, 2005 */ 2 |: j T1 y2 I7 I8 \
- /* */5 J& O. r" _- H& |" L6 j6 i
- /* */
/ C; c" A- F9 M } - /********************************************************************/
' ]. j! C* Z: ~8 _
0 f( W) N6 p* o+ v3 m7 S+ ]& c7 [- #include <stdio.h>
! h% l; Q) U g: w - #include <stdlib.h>
' @6 w6 u" Y0 Z% |
2 E0 _" D" g+ a* w u- /* Function Prototypes *// p( g, F5 b6 G% X' j2 h7 t- W, h. z
- 5 K z& Z% X# |5 ~- x
- void init();
: W" o4 R- o8 ~ }6 H6 Q - void Send_Byte(unsigned char out);: l& h, \5 C" R" m0 o( _2 V
- unsigned char Get_Byte();* t! F, {, b$ O) B K4 K% d
- void Poll_SO();
0 u' C4 a: J/ R6 F - void CE_High();- t: s4 N" a( f% C7 w, y
- void CE_Low();
N/ f3 l! W0 h- i# d/ |4 |. I - void Hold_Low();
3 O5 h- n( ~, a - void Unhold();
e: N3 g4 `6 X - void WP_Low();8 k. [9 |, B0 f3 S
- void UnWP();
9 e& I! F, b+ q" q+ O - unsigned char Read_Status_Register();% n# J% o5 q; c3 K7 u
- void EWSR();
6 Y# Q6 L6 c' b: j - void WRSR(byte);# \( z2 C6 l, O: g
- void WREN();
2 c: e) |% `7 w( ~' B5 z - void WRDI();
4 g: m) p8 L0 K+ @, p - void EBSY();
2 t9 A6 R; u+ o5 A - void DBSY();7 ~6 U/ Z( q- S8 z5 U2 f0 J
- unsigned char Read_ID(ID_addr);
# G+ z& W& |; P: L) E - unsigned long Jedec_ID_Read(); Z8 }) P3 w: Z5 D& T3 R6 m
- unsigned char Read(unsigned long Dst);% g) b" V9 {8 F2 l9 O. ^, N
- void Read_Cont(unsigned long Dst, unsigned long no_bytes);
. C/ {0 {; b% b! u7 ? - unsigned char HighSpeed_Read(unsigned long Dst);
w6 b2 r: a, G5 @ - void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
8 A" F: x$ B$ v5 e# X3 Y' D - void Byte_Program(unsigned long Dst, unsigned char byte);4 I3 J3 W) x# R" Y& h2 ]
- void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);( ~- D- B5 ] s4 O
- void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
+ U! l' e# t! h1 [2 s- o - void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);: W& \7 M$ n% r# D6 f5 y
- void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
. s, n7 C* V9 K - void Chip_Erase();
* W- x" w, O2 _2 @# Y+ x5 g* A& f8 p - void Sector_Erase(unsigned long Dst);
' H/ ~) |2 A2 o) N3 K - void Block_Erase_32K(unsigned long Dst);
5 S3 Z: y5 b1 R! j3 N - void Block_Erase_64K(unsigned long Dst);/ q: _( r5 t5 d5 y$ }: P
- void Wait_Busy();3 [& Q6 E, H) O- r
- void Wait_Busy_AAI();
6 @- l# {' O' U - void WREN_Check();$ A' C t6 W; C) y* O2 r8 k
- void WREN_AAI_Check();
% v+ T- V# w' W- A# @2 E3 H/ Y - 0 d# s6 h5 L: r G
- void Verify(unsigned char byte, unsigned char cor_byte);
$ y8 [ r8 q: w, K
0 N0 J; x5 C' A1 L0 `- unsigned char idata upper_128[128]; /* global array to store read data */$ K: r( p$ P7 x
- /* to upper RAM area from 80H - FFH */" y: f8 u# B: G6 B! o' }0 `- b1 z8 m
- 3 Y: N0 u! I- H" Z0 t
- /************************************************************************// f4 V) d! x' ~1 L1 L
- /* PROCEDURE: init */
, v/ B# l. A' k) M, G, o3 Z - /* */' Y1 i3 b, b& ~$ P1 Y/ F$ G9 A
- /* This procedure initializes the SCK to low. Must be called prior to */
7 R) P0 X, {& R* M - /* setting up mode 0. */
4 N* v# |3 C3 ?3 a4 K6 |/ ] - /* */
7 Z0 L2 h9 N6 U8 {7 T r5 t2 x - /* Input: */
- ]+ Y$ {+ t3 h0 X$ c! ^6 o1 K$ Q - /* None */
& m5 \ e1 T( Z* r7 B8 X: F - /* */
* v' Z' T1 g( |3 B+ Y - /* Output: */
; j2 S) V9 }% B - /* SCK */& f4 g6 L; Y5 R6 d' ?7 I, H" F
- /************************************************************************/
5 G o' a+ L) @% z - void init(), r& w, q+ E7 G! D
- {% R& i+ _2 e1 ?
- SCK = 0; /* set clock to low initial state */0 L) k8 E. L3 L9 P2 [5 A' l
- }! s" w* Q4 c7 X8 x
9 C2 A8 P2 {2 k& a: d- /************************************************************************/
& J9 n" B& j* _. B) G6 Q - /* PROCEDURE: Send_Byte */
" P r" c. g7 Y3 A* @/ b9 d3 N" x% m - /* */
4 o8 G: j" B" t; z1 ] - /* This procedure outputs a byte shifting out 1-bit per clock rising */
( [" E7 M: n" W# E; P - /* edge on the the SI pin(LSB 1st). */
( l. O: K; P$ F& A - /* */
& z: [; w" O0 }+ a) q7 i - /* Input: */& B, M/ S$ z! E `
- /* out */1 s$ p# g7 w0 z
- /* */
/ M7 r9 D4 B) s" |+ l& N4 `( n - /* Output: */
F$ a% o" F# j0 S' g7 S8 [1 D& Y6 c - /* SI */
' ^6 ]" V5 n; z" @! W1 u- D" m- R; S# y& v - /************************************************************************/
) t: O0 g* A6 `$ |( K( u7 p - void Send_Byte(unsigned char out)
0 Y* G d$ M! r R* a+ Q4 W - {. h y7 Q/ d/ o1 P
-
' h E7 G. \3 g/ M9 a2 a b" T - unsigned char i = 0;- b. [. ]- y$ P) U! |: I
- for (i = 0; i < 8; i++)6 w( e( }+ H3 A
- {
3 ^$ S9 r& ^$ e! x+ G - 0 b1 ^! N: t" r6 P: B5 F* d3 U3 r
- if ((out & 0x80) == 0x80) /* check if MSB is high */- g7 p; a! @% @2 F
- SI = 1;
' ] J$ X5 E T* e: i. S5 D - else% G) a2 `0 h5 q( Z) c) A" r
- SI = 0; /* if not, set to low */5 X3 n4 |; s" a" f4 W
- SCK = 1; /* toggle clock high */
! p& S9 w4 c3 i" { - out = (out << 1); /* shift 1 place for next bit */
8 y1 X( u# ~7 ?; ~3 w/ g4 u - SCK = 0; /* toggle clock low */ W. f! C5 Z7 F+ v) h! |+ k
- }
! o$ z% v$ L1 v' }1 m! }2 Z - }& h% ?7 H$ g+ t5 c0 i' m: }6 ?
- ( A) e5 H# j/ l# m0 v* e6 d; S5 a
- /************************************************************************/" ~# x5 i! A9 q$ |, Z; @
- /* PROCEDURE: Get_Byte */
$ w5 W, E6 \% B! R - /* */. ?" r# t. _. \/ ^8 i. `, O
- /* This procedure inputs a byte shifting in 1-bit per clock falling *// I+ L( h8 U f( t' t2 e
- /* edge on the SO pin(LSB 1st). */
/ q. ]8 ^" E1 P | - /* */
* n/ v% [$ r+ F4 W- d; _ - /* Input: */. k1 ^( h$ ~6 [6 s, f6 x! o; m0 f
- /* SO */
2 X- @+ R3 Q$ e5 F( l - /* */" D/ |3 Z4 V4 x$ h& R
- /* Output: */6 g! k2 Z3 Z* _: T% T
- /* None */
- r1 R; M" Z7 p i - /************************************************************************/
' Z$ {$ F% s8 d0 H* c - unsigned char Get_Byte()& j1 u" B' k8 n$ M% {$ {% e8 x
- {+ r' M' {2 Z( _6 Q/ i# F, E2 q
- unsigned char i = 0, in = 0, temp = 0;
* U# @& k1 n1 Y/ Q5 f. [$ e - for (i = 0; i < 8; i++)
! j5 L3 I- Q; `! j2 @ _ - {
* x) N# i& [" z - in = (in << 1); /* shift 1 place to the left or shift in 0 */& Q: K* V' d/ J: q# o5 i' k& W8 F
- temp = SO; /* save input */
: c& ?' X+ J, u - SCK = 1; /* toggle clock high */" i& D- p5 ^5 O! R% H: W1 y
- if (temp == 1) /* check to see if bit is high */% [ T# E6 v. P0 ~3 r; q. \
- in = in | 0x01; /* if high, make bit high */! p4 b6 ~$ ~( i; x8 [
?+ S u8 U' K( i" l- SCK = 0; /* toggle clock low */
! ]2 j. w. y- c. Z9 k/ X - 9 {5 J4 P: X( W: F4 x$ Z
- }
$ R4 j) |& w5 y8 | - return in;2 Q3 q8 g, z+ B) z2 X5 f8 m
- }9 @5 A5 d B* x) f) |$ t. i4 l9 ^
- 7 N6 k8 P' v( ~$ q+ C
- /************************************************************************/7 ^7 a( m+ h9 I( W g
- /* PROCEDURE: Poll_SO */
s; Q) y" }$ @3 Q- ` - /* */" _8 L9 u- I1 D# X6 [1 @3 g
- /* This procedure polls for the SO line during AAI programming */" p- Y- J+ k1 R/ c, [
- /* waiting for SO to transition to 1 which will indicate AAI programming*/
6 ^# B; I+ G, I1 D+ _ - /* is completed */3 J5 I9 J2 F7 [ j2 F
- /* */
/ Y9 ]* S& v! r' b) q - /* Input: */: ^+ D% M4 x/ R
- /* SO */: z7 s) Z$ G$ H* e
- /* */
6 s, v) c | [1 X: _( t# e - /* Output: *// f, {( ~+ Z8 x6 @8 S& o
- /* None */" ^: _( E( S0 L9 H/ }; H
- /************************************************************************/
) r' Z8 w# [7 k* h - void Poll_SO()
5 S% W' h4 v4 c+ g+ ~2 I - {- j7 o( u2 \8 C( i8 w
- unsigned char temp = 0;
, j: ]; K8 J% E. K$ u* H - CE_Low();
1 \' z& a- `8 N0 n0 G6 U0 j - while (temp == 0x00) /* waste time until not busy */! i( q2 b9 ]+ t% ~- Y8 t3 N/ j E
- temp = SO;+ z+ F& g% {% X! w, ?
- CE_High();& g& Q5 n. e) S/ Z+ ~
- }
5 J( w* O/ r( s% i8 U0 n
( `3 L; w0 T$ z3 b) d- /************************************************************************/# `9 B: N/ s" D- T0 \
- /* PROCEDURE: CE_High */
# q8 _/ b1 I" P1 A+ U - /* */1 [. _7 z3 c) b/ {) ]
- /* This procedure set CE = High. */
' R+ B8 s, t& r9 s$ C: f4 z; L - /* */
/ w% t# N2 C2 j" L - /* Input: */
* Z+ }' H8 e' f7 t- C6 S - /* None */9 Y ^9 y6 b5 ^2 J5 H j9 X
- /* */; }5 r! J( F9 P7 T$ R. P( d% _0 G
- /* Output: */
& r: ]; w, P5 M0 m - /* CE */& u( U! |: ^9 J# I1 g
- /* */
6 {+ t, C v' |) E3 ?6 } - /************************************************************************/' |/ Y c. x' i& [# ], @1 A
- void CE_High()
- @, T8 d" J+ n) n# q% j - {1 D! C4 G, @% F6 S
- CE = 1; /* set CE high */0 U; D" i* g% o. n
- }
2 c1 p- f" H" j8 _, x8 @ - ! Z" B) o1 Y) f% \ `& t
- /************************************************************************/
0 p7 B% _: u- }5 V: W - /* PROCEDURE: CE_Low */( t. `: D9 ?& y+ L. T/ Q# O
- /* *// k$ x( ^$ ]7 m! q5 W" O
- /* This procedure drives the CE of the device to low. */
4 b4 Y9 t) H& J - /* */, ^; M7 b9 G( I/ w( y+ c! `' v0 y
- /* Input: */! ^) V+ |$ z1 h3 V) I
- /* None */+ I3 }8 [7 A, y. z
- /* */
4 n/ G9 B1 H$ J' T5 |0 j$ c% e- z, t - /* Output: */- U* C7 @6 h9 R I
- /* CE */) x7 n# {* C! d8 `: s4 G' ]
- /* */7 Y) k$ M& I! f8 x' [# L8 _) ]+ V
- /************************************************************************/( e9 q$ D1 ?7 F9 _6 Z; `8 D
- void CE_Low() * E8 `# T s' O* @$ t, x) L
- {
: u3 ]/ L j4 k - CE = 0; /* clear CE low */
6 f' Z( H: y: H6 t# ]" H - }3 }% N+ c* u; y# F; o
- * f1 @/ n2 |) [; D, ?* \3 C' ?
- /************************************************************************/
X( W- y8 m9 v0 ~! w3 c - /* PROCEDURE: Hold() */! y' Y! B) z9 s$ [; F( @& W
- /* */
) Y, s% [ r$ d9 W- @! U - /* This procedure clears the Hold pin to low. */
$ }8 Y9 e5 }: X' S: Z* ~: _8 ~* ` - /* */
& H+ h( V1 N" c3 H$ e3 C - /* Input: */
, c1 {6 b5 l/ ^- y - /* None */
! z) N0 M0 p# a- ? ~ - /* */" H. ~! y) ]1 R2 N* v
- /* Output: */
/ L+ L1 s3 H/ G, g) b - /* Hold */
/ N, v4 F; X* {8 a' x3 e# K - /************************************************************************/9 U$ d9 g" ^* k4 @- v$ F2 C
- void Hold_Low()% @/ f2 E. f8 S& [( j
- {
$ V% @$ w$ Z6 Z - Hold = 0; /* clear Hold pin */
3 n! n) R% K; j! i; X$ w - }$ y. E. x6 q2 @0 Q
- ! _" y7 B9 n( _5 h! F% w/ H
- /************************************************************************/
: a* |9 G7 o4 u. A R5 O - /* PROCEDURE: Unhold() */3 u- T. n6 g$ b* H$ Y# B
- /* */
: d3 d3 Z+ d% G2 N - /* This procedure sets the Hold pin to high. */
; ?; S& F: d8 D: e* k( b - /* */: Q5 l4 J' d, L+ y: Z( g
- /* Input: */
! l$ o, k* [& r3 S- i - /* None */
5 D- S; u+ M3 G6 J( ~0 T+ [/ T) q - /* */1 q' r4 C+ {3 i4 I' @4 B( c
- /* Output: */
4 \$ H% h1 U) X - /* Hold */
' q+ ^2 Z( _3 G3 m$ E/ B - /************************************************************************/
. J% i" z- E' D6 { - void Unhold()
5 E2 a" p/ d4 S9 E! |$ ?% P, [ - {
\1 `: ], h2 A6 c) _/ K7 R - Hold = 1; /* set Hold pin */
* n. H' u d b8 ?- e) e( |* j1 i - }
/ I$ }/ h! f; |+ Y: p( g7 U
, V. d% C3 S0 z- /************************************************************************/: v; H% @$ [; u# b
- /* PROCEDURE: WP() */" |/ w, m8 p) K2 `4 J F
- /* */
# h% t1 Z. s' a H( Y$ A - /* This procedure clears the WP pin to low. */
, k c! O9 Z# b) y( N - /* */6 F* |9 j8 [6 a \4 H9 X
- /* Input: */2 \" j/ @- C& G/ m: ]
- /* None */
9 G3 L6 V+ D; @2 I2 } ] F$ B - /* */1 @, e r9 i, \% m8 H
- /* Output: */
8 p! M+ D! J" B- _& b N1 w - /* WP */" p a1 ]$ J, {( J7 J9 y# G
- /************************************************************************/
# N8 h9 B$ L5 Z5 e2 K$ `( l: H( A( a - void WP_Low(); ^( l: v8 R0 k# i2 Y
- {& m7 L! Q' C) b2 ?' `
- WP = 0; /* clear WP pin */1 z5 H$ E# O$ |, U5 u
- }/ K. R2 h# c8 f& b2 J
; G* J0 d9 a; Z% v+ F4 k- /************************************************************************/) Y, g7 k N9 n$ n) U9 }* c' I
- /* PROCEDURE: UnWP() */- d. k7 I: l7 O( l# a- Y7 _ S
- /* */
+ `5 C8 A3 d$ @- D% [ - /* This procedure sets the WP pin to high. */
$ [4 _ e- e0 M7 E& F - /* */
9 K4 E+ G3 [ T+ [ - /* Input: */$ v. C# i3 f, a9 b1 B& D7 h) q0 N
- /* None */% B8 j6 e% A% o, W R5 I8 j2 n4 K
- /* */$ x1 P3 i! P# W. G Y% i
- /* Output: */0 T- Y4 c3 Z G& b5 A4 _7 o* V
- /* WP *// c$ _. ]: d1 J" s: i1 U, K: M' x
- /************************************************************************/9 u5 i' G" o. |& }8 ?" U
- void UnWP()
) p) f* |/ U( t4 u6 M# ? - {7 k- u" |+ H1 j
- WP = 1; /* set WP pin *// A; Z$ a6 M/ k. v, ^2 f
- }
, w! B8 g% y! o7 `4 h' S* j
/ Q. ^( l% E/ ^5 I- /************************************************************************/# W+ T8 K& m A9 q
- /* PROCEDURE: Read_Status_Register */
- H+ b( `0 z6 Z. z& b7 `8 q* r - /* */
! Z% z/ x8 h& t* b u% Y b - /* This procedure read the status register and returns the byte. */8 `! C# b3 Q7 @8 z. I' q9 `
- /* */
* p: Y; V1 t! a - /* Input: */
" S: L! m8 U5 y& A9 k/ l! j" q - /* None */& i6 O" x' C* R; E
- /* */2 v! w4 s/ W$ H3 H
- /* Returns: */' j4 ]: W% }/ V% ~6 s
- /* byte */
2 J s g' O7 t+ i. Z1 W2 ~7 M - /************************************************************************/
# @# U+ J$ `3 u1 y1 ] - unsigned char Read_Status_Register()* B& N' E2 r, o. J8 L1 F% B
- {
: ~6 J& y% I5 `3 h2 p- F9 c - unsigned char byte = 0;
: w2 Q& {* c7 _ - CE_Low(); /* enable device */( z9 O1 x/ D3 W1 o
- Send_Byte(0x05); /* send RDSR command */
" X3 w% u* ?- q6 x, C - byte = Get_Byte(); /* receive byte */7 I8 ~. R0 U: t- T' K; q
- CE_High(); /* disable device */) @# u! y/ `* N/ x6 F! L
- return byte;
; y+ m6 a1 l+ i - }
: _( `3 z+ b1 Q) I: f6 ~7 W& _; f - 7 b7 U8 w+ ^) c) h; a; A2 K
- /************************************************************************/
8 O7 h2 X# F9 ` i - /* PROCEDURE: EWSR */8 M2 b! I2 F# n! x' D9 l4 R' n
- /* */* V& B4 Q7 q. _4 U# P8 G
- /* This procedure Enables Write Status Register. */
/ a( s. ]5 A3 b7 q* m/ f - /* */
) D3 r4 C3 M3 P9 G+ T4 ? - /* Input: */! I9 L0 X# f: ^% A/ P* \. G
- /* None */
. {; H+ V7 L; D b% d - /* */
9 G m! C) I$ I6 e; d2 B( U" } - /* Returns: */8 w2 p" h4 _5 |: U- A3 S
- /* Nothing */
, h1 y; D: H; M6 p: } - /************************************************************************/
9 Z( {, t) w+ ~, R/ u - void EWSR() }4 v6 a; }/ x0 @0 Y/ ~
- {4 {3 J: ]% M1 U" p+ {7 f6 Q/ A, i
- CE_Low(); /* enable device */- S0 a3 x* M" L$ g: x
- Send_Byte(0x50); /* enable writing to the status register */ Y8 D# G1 R3 P8 Q
- CE_High(); /* disable device */
* [7 M+ Q9 y/ ]" K" E2 v - }
) U5 _4 C$ O! J7 L/ f - + k- `, N# f) A; g. B# g
- /************************************************************************/7 m5 W' Q: R( e! B# T0 B
- /* PROCEDURE: WRSR */) N+ P c% b" ~3 V
- /* */) r4 |' L2 D' ^3 D
- /* This procedure writes a byte to the Status Register. */
5 i& r3 f% Q$ ?- i - /* */% D! x3 W+ h: a5 X+ z6 ~
- /* Input: */1 {- f0 n8 A8 O* P2 D* k1 c
- /* byte */
( T; }- z0 J5 m& c4 j - /* */
a; C! b/ r0 X - /* Returns: */6 Q6 U. ^. ]4 Y! [/ Q
- /* Nothing */* w+ \4 w% A% j6 X
- /************************************************************************/4 `# ?8 W5 H1 |6 ?) U; R
- void WRSR(byte)
6 d& ^% G+ g+ W- m - {: U2 k: z* B' P) y! l/ x* k3 [! i
- CE_Low(); /* enable device *// J' ~( ^, n3 @& |. M3 M- W; a
- Send_Byte(0x01); /* select write to status register */
# E4 r& n/ y9 T1 i! C/ y; @# B& t6 s - Send_Byte(byte); /* data that will change the status of BPx
( M# i1 t5 q( {% X - or BPL (only bits 2,3,4,5,7 can be written) */
: Y3 |3 y" q8 }' ^! s - CE_High(); /* disable the device */! E& C6 q' l& F. l* s0 U" {
- }/ s7 N) o; Q o6 o9 G" b
- * A! ^0 t9 l, |% E
- /************************************************************************/
3 A3 u- t/ F1 Y5 \! @* h4 @' L - /* PROCEDURE: WREN */
) E, y0 O4 P- ^' V$ _ - /* */+ o$ v2 E$ A! N# m% G+ h* o
- /* This procedure enables the Write Enable Latch. It can also be used */, P4 A ]% T/ ~% G" t
- /* to Enables Write Status Register. */) j N( q+ r5 H4 K+ v
- /* */
! }) i$ N' O7 N7 E3 ~3 e) ?3 [% e" y - /* Input: */
. A+ r+ @/ d0 b# B2 w - /* None */4 R( v8 H/ C" T& S: {0 w5 f, i) [
- /* */
0 a6 l3 {" n/ C- c$ p - /* Returns: */
1 Q1 R2 L* K9 i+ P - /* Nothing */; [ d( P* i& Q$ q4 O8 `
- /************************************************************************/
9 b. M5 ?" j% I/ J9 X9 q - void WREN()
3 l% o7 ^; `1 c/ ]5 T. C# u1 Q - {
- E' O% S* y$ N' j) H, D( j - CE_Low(); /* enable device *// X+ b' k+ K: C0 d. ~& k
- Send_Byte(0x06); /* send WREN command */1 @( ~) u% N$ L
- CE_High(); /* disable device */- f* I' q& B1 O8 f _6 i: @6 _
- }
/ `5 f, T+ H& s7 h; [; m" _ F! `
, r3 X' ^1 [ E1 w* [ x# y9 M2 i- /************************************************************************/$ U! ~% f% ^2 g/ O9 t
- /* PROCEDURE: WRDI */* |8 @! ?8 Y3 u0 J# H* P' X8 v
- /* */
b* P3 r7 d' f' K - /* This procedure disables the Write Enable Latch. */
4 W- ], K5 Q6 Y# D0 ?5 Z - /* */, F- V3 }8 W! L7 p" |0 E
- /* Input: */
: J/ U' b2 n u: n( c* h - /* None */
6 X: _! i1 L, n9 a) L7 v - /* */, k8 s! R$ q6 n# @5 @
- /* Returns: */
3 \" y" {( } @/ A - /* Nothing */
$ y* W/ a* z2 [' x' j4 L: a& p- i( T V - /************************************************************************/
5 [) a' F! d2 k1 b6 z - void WRDI()
& u" s& b N# y7 f# J/ u# Y9 b - {: d, y- G( `! N( F4 {
- CE_Low(); /* enable device */# M( X: Y6 W- U: c5 ~
- Send_Byte(0x04); /* send WRDI command */
3 z# n( ~" N; V+ R* Q - CE_High(); /* disable device */
3 B7 Y/ l4 @5 ?/ y3 ~3 d, l) Q6 e - }
3 j4 w2 z2 Q2 X1 X( e* B7 B" }
) B& ]' l* \/ m, G3 {" _4 a& r- /************************************************************************/. w4 ~5 A" G1 O! Z" m% M" i9 {
- /* PROCEDURE: EBSY */7 r4 q" ]* U: Z6 b" Z/ M" J1 ~
- /* */
0 k1 ~/ H* M# y3 l1 v7 h9 Z - /* This procedure enable SO to output RY/BY# status during AAI */( ^9 o7 J6 y, W5 Q( p( m- w( N
- /* programming. */4 x1 |0 m8 n" I/ [5 F
- /* */0 T' U( t; v: S; r
- /* Input: */" p# X$ X) K2 b4 B
- /* None */
* i6 E/ E( N/ k+ B% j- E - /* */& {# p4 ~5 z2 \2 |
- /* Returns: */7 G: l% R/ F% f' v0 V5 ?* |; P5 c/ S
- /* Nothing */
: Y/ l/ F/ t. g5 a - /************************************************************************/' \/ l/ J. w2 A, w* Q1 O
- void EBSY()" \+ W& j/ i3 X
- {
# Y1 g* Q, h3 U, { - CE_Low(); /* enable device */0 }5 c3 L- d2 k2 O
- Send_Byte(0x70); /* send EBSY command */
/ N9 E8 N6 E$ R9 V, y1 |1 D/ f+ J - CE_High(); /* disable device */
2 ] d0 x) J6 l! @ - }
& N0 H6 j8 w p* G
1 L/ f- l& g" e; Q& i- /************************************************************************/
5 e2 k7 Y. v& m) K* \. X! T n) T( j - /* PROCEDURE: DBSY */6 f. R: {1 u* M( d4 N3 Q+ C4 w; e
- /* */( F9 o; y$ q2 g; N' h
- /* This procedure disable SO as output RY/BY# status signal during AAI */; u% \3 q; ^# g! Y; L$ ~8 T! v
- /* programming. */
- b& { n$ ^) h) e, n7 D - /* */; H( U# ]4 H7 A4 Z: ]% [# x
- /* Input: */! H5 T7 s1 ?1 S; v0 b0 j) T/ X
- /* None */
# g) t0 ~* a2 O. i1 I( ?$ T3 p5 U - /* */
( }! B7 ~7 w* J - /* Returns: */7 ^2 l7 X6 e* J6 j; S. \. A
- /* Nothing */
3 M% R4 X2 C$ J1 D& K' [0 ^+ t - /************************************************************************/
+ J- }3 p% @; h. x! X - void DBSY()
, ]! y v( @8 G - {9 k! H9 G/ \; C0 X+ m: l
- CE_Low(); /* enable device */
& ^# n4 x# E0 `5 o- e7 C* z0 U3 @ - Send_Byte(0x80); /* send DBSY command */
8 X9 a2 \' K, x3 j6 S - CE_High(); /* disable device */
" n& Q, D1 `) o% g - }. [! _1 S# w, Q; g
- 0 I) f/ |4 T2 b* J
- /************************************************************************/
. H, ]& u) [$ z! l& `: k8 ]0 x4 | - /* PROCEDURE: Read_ID */$ P) v* H' F: ]& h' r$ T8 H2 [
- /* */
/ f, D1 v& M+ B% Y: S1 q - /* This procedure Reads the manufacturer's ID and device ID. It will */
7 B9 l# @, Q6 u9 ~. J' M: w - /* use 90h or ABh as the command to read the ID (90h in this sample). */" n& ~& x- ?" d N: Y: _& U
- /* It is up to the user to give the last byte ID_addr to determine */
4 G X5 I. a9 M4 Z - /* whether the device outputs manufacturer's ID first, or device ID */
0 F9 O) A: @' D1 {2 v* X - /* first. Please see the product datasheet for details. Returns ID in */4 f- C) { F, T, R- i
- /* variable byte. */
' p0 o$ j1 |9 D0 T- `7 D/ @- Z - /* */
1 _2 {. R, ~6 {; }$ { - /* Input: */9 E4 H2 Z4 f& Q# L7 i4 v
- /* ID_addr */8 Z. H8 |5 I% `+ A9 X5 v
- /* */
8 V- } Z: ]2 o/ T7 Q1 q; D - /* Returns: */' v- Y L% y+ Q3 d; c5 |! W0 L" E
- /* byte: ID1(Manufacture's ID = BFh or Device ID = 8Eh) */: F1 H3 ~7 R; @3 p8 M
- /* */6 ]( D% P" C! J9 b# a1 c
- /************************************************************************/& v+ e; x( K" P6 \' K! X2 n
- unsigned char Read_ID(ID_addr)
' f' b3 t* f) H% y+ `2 O - {, u! @+ Q5 p5 L8 P
- unsigned char byte;" F2 {6 @ B5 [, ^
- CE_Low(); /* enable device */5 z- b) l# m: a/ g
- Send_Byte(0x90); /* send read ID command (90h or ABh) */
3 d) s$ b6 r/ ]: o/ @# u% R% S! V - Send_Byte(0x00); /* send address */. S1 s6 M: U, U8 a9 B4 Z( }7 @
- Send_Byte(0x00); /* send address */
& t) d9 Z/ E7 Y3 \+ `6 f- E - Send_Byte(ID_addr); /* send address - either 00H or 01H */9 W8 D* O' h9 s' }) Z% d
- byte = Get_Byte(); /* receive byte */
6 o; T3 U( s9 J8 @3 e5 |. l) S7 c - CE_High(); /* disable device */
1 M7 i( C* | _. P7 [. V - return byte;5 Z- P1 u) F* M C" c9 l
- }
0 u; i) N4 Z/ j& f" @" z
8 o r* |# y% M: _' F+ T/ }- /************************************************************************/$ x* X1 h* ~5 [4 ?2 w
- /* PROCEDURE: Jedec_ID_Read */
! B2 R. N3 K( K4 r# x6 J8 s; U) M - /* */
% a& U) m. Q0 }& H - /* This procedure Reads the manufacturer's ID (BFh), memory type (25h) */
- K. l! b1 } W( G( Q6 n - /* and device ID (8Eh). It will use 9Fh as the JEDEC ID command. */
' L9 ~9 `: y8 L - /* Please see the product datasheet for details. */' D$ i' X+ N& X5 v+ c3 x9 Z; Q- |
- /* */ X& l" O7 N' b8 H
- /* Input: */
8 L* T5 p: j9 A5 U1 ~1 n! V - /* None */" L1 @; \- X( g, l8 S
- /* */8 M9 l' a7 A$ R9 I2 |& Q5 `4 _
- /* Returns: */# j* w5 e6 l# ?' X: M2 [
- /* IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h), */
# J' Q3 P: i4 J8 a/ L, {- ?* Y% P - /* and Device ID (8Eh) */
4 w7 c/ v( q, W" | - /* */
# }: K# t6 x5 b/ e) [ - /************************************************************************/6 ` e0 G7 ?- F) x: r) p$ z! j
- unsigned long Jedec_ID_Read() 7 A. D) h- D+ k& `
- {! k7 u* x* u C K$ |! Z6 d
- unsigned long temp;
0 S! e, U" ^) r& e -
0 e" T2 X8 V& h, A8 B$ S ]; o - temp = 0;
2 W1 t3 F J7 a/ r
+ ~, E; F4 P+ o6 g" e1 F! O" @& w- CE_Low(); /* enable device */
. ?6 s! \! H3 U# u# h1 O2 V - Send_Byte(0x9F); /* send JEDEC ID command (9Fh) */& |( d- w: C4 |+ y$ U$ Q g
- temp = (temp | Get_Byte()) << 8; /* receive byte */6 s9 h7 C( ^ `; ^: ~. J" U' p
- temp = (temp | Get_Byte()) << 8; 5 G7 ^! j1 u* C6 z) b- ~! D/ u: P
- temp = (temp | Get_Byte()); /* temp value = 0xBF258E */) E% L( P1 e7 _ E0 k8 C2 c1 O
- CE_High(); /* disable device *// Q" c" w, ]5 w. z/ ^
) W8 q" S6 ?: N$ n- return temp;
; u" a( E# S# k2 L) ~9 q - }$ \. G8 W; A' k9 q9 t" _5 e
$ k! u: S* P6 `4 ^- /************************************************************************/
8 v a! ?2 w9 V, _; C* K; Y9 w7 _ - /* PROCEDURE: Read */
7 |; c- w4 j/ w: i' M8 _$ t: f: C - /* */
; F5 i# @7 Z) G( n+ O - /* This procedure reads one address of the device. It will return the */- X' N% X( I6 G
- /* byte read in variable byte. */$ Y; _3 W! R0 \% i7 ^, G
- /* */* u0 N1 y) w* J4 n$ q* B5 B' l( g
- /* */0 X# G: w5 m, b a5 ?
- /* */; A& }8 Z: Y" S+ Y. I5 |
- /* Input: */
/ y, K) N5 D0 H- @# _/ z, D* Z - /* Dst: Destination Address 000000H - 0FFFFFH */* v; S4 [: Q* n9 k
- /* */
$ L' l8 e% U7 ~# a8 h4 k - /* */0 _' z' }( q* e3 v
- /* Returns: */- p4 g! I) I7 ?- c
- /* byte */9 \' _4 }1 _' r( S/ p! A9 e' X' u
- /* */# N3 ?9 f" ]* r9 M. _
- /************************************************************************/
T$ v8 K, s- _* ^! { - unsigned char Read(unsigned long Dst)
9 R2 ?. t4 M* q, N5 ? - {7 C: |7 [5 Z3 S9 n& n- w9 k; T3 c
- unsigned char byte = 0;
- l* q; E% j! e/ E& Y - : ]& f' X. ?- n6 S% n
- CE_Low(); /* enable device */
8 {" p9 v+ Z8 z+ _" h3 \ - Send_Byte(0x03); /* read command */
+ P0 U4 h l; X2 l u# w' x( | - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
8 f7 l! s1 t# l6 _) U6 {3 A - Send_Byte(((Dst & 0xFFFF) >> 8));- M* ?8 N* y2 B- A, x; L8 |: x# G
- Send_Byte(Dst & 0xFF);
/ r5 S# p* n% E) i: [ - byte = Get_Byte();$ j& p2 [: h6 q: E$ {
- CE_High(); /* disable device */
; \# ?- R; ~9 p0 [5 ?. x( ]+ B - return byte; /* return one byte read */& z. [9 V& D. y' Z' F+ M' b
- }; v3 g3 [& K' e
5 s" Q; `' Z: c- /************************************************************************/ r( M8 R& Q8 c; h5 Z
- /* PROCEDURE: Read_Cont */# j+ J! B6 G5 f/ _! ]) S
- /* */
* X4 S& R' @& Z W9 Z' F: w - /* This procedure reads multiple addresses of the device and stores */
7 J; M: J0 d/ G# {1 Z - /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/7 {( Z) }; E' q: {: e
- /* */
. I. q: X; Q, y- ?1 z - /* Input: *// Q' r4 [* h% ^7 N
- /* Dst: Destination Address 000000H - 0FFFFFH */
: u( n4 a+ k% K - /* no_bytes Number of bytes to read (max = 128) */
; J }5 k8 u" k8 d' ?# M& Z% V/ u( H - /* */- ~7 M9 H1 F) s9 ?! ?6 a
- /* Returns: */
. j9 }* F. N( H+ v+ d4 w7 F - /* Nothing */6 [& y( b+ ~, k
- /* */" [2 o$ J/ r' Q
- /************************************************************************/) g* j5 j |: m3 R/ }* E
- void Read_Cont(unsigned long Dst, unsigned long no_bytes): m% P% n; Q6 s: b& @
- {" O1 M* y+ h4 f7 a2 p1 O
- unsigned long i = 0;
1 O8 B6 D. L! x7 W+ {1 V& P9 n( w - CE_Low(); /* enable device */
1 P$ {( N/ {1 z! C! ]9 n - Send_Byte(0x03); /* read command */
- G2 D+ i! Z" m- N( | - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
, T F: V. l. t: L9 d - Send_Byte(((Dst & 0xFFFF) >> 8));2 w" V% G* ]) _; \
- Send_Byte(Dst & 0xFF);
2 j5 b$ F/ J" J9 L/ A1 q: n - for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
& A! ~5 e2 g+ h7 J$ M8 m3 p - {
4 J3 M9 @8 H* c) s" u - upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */9 v/ U5 D1 j4 e5 ^# Y R0 d
- }
9 k* U5 K( I7 E! J - CE_High(); /* disable device */9 K& n, q; u; I
( h/ S( k' M2 ^/ V- }
' m$ R/ q. z) A! f4 F4 B9 X+ R
! [ M& p# k i! e- /************************************************************************/& X# c2 _, @0 @* \1 C4 R6 [
- /* PROCEDURE: HighSpeed_Read */3 G! l, n) ]9 s' N/ E, F% Q
- /* */
2 [1 N# q! K" k0 m, n( o, N - /* This procedure reads one address of the device. It will return the */
% k2 w. R2 z8 _3 c - /* byte read in variable byte. */5 M6 p# q6 m$ O2 y& q! q9 E
- /* */
, t7 i. h. q, b3 {" E. C6 v2 t - /* */
- n3 B* T/ f5 ^/ \: q7 v - /* */
4 ^# \' I9 m" N& ^9 j) U( J0 V - /* Input: */
* X7 `: N" C1 X( M3 ` Y - /* Dst: Destination Address 000000H - 0FFFFFH */- e3 }+ H3 I, u( k( F- p" v. o
- /* */7 A& I) z$ {& T
- /* */
6 \+ q' c1 E, j - /* Returns: */
2 K% b# i$ H1 C0 x/ b: O - /* byte */" E' |. V8 N% r. O) r9 `$ \9 \) d
- /* */
4 W9 G- A8 U( i3 G - /************************************************************************/7 ~3 \0 n$ a+ \
- unsigned char HighSpeed_Read(unsigned long Dst)
. o3 {0 e4 ?( H x0 X - {
* H- u/ h3 `; x# Q% l - unsigned char byte = 0;
6 x8 [# n& Y9 g
) L7 ?6 _; q- J$ B- CE_Low(); /* enable device */
' T' _! A, ]* ?7 p' \# d) y" E. [ - Send_Byte(0x0B); /* read command */' p, {# A* T" @, w( t" g
- Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
$ V# d1 G( |$ z8 q9 P* d% n6 h5 ] - Send_Byte(((Dst & 0xFFFF) >> 8));
0 C9 {3 J8 G! t6 Z9 U7 ~- v - Send_Byte(Dst & 0xFF);4 r+ O2 o4 N8 J- p- p
- Send_Byte(0xFF); /*dummy byte*/7 a+ [, J2 s; W$ n0 m1 V7 X
- byte = Get_Byte();
) [5 z7 N* e+ Q2 _/ [. ^ - CE_High(); /* disable device */
; E6 A8 H! p* m, C" w2 t @# [ - return byte; /* return one byte read */: x" F) l) _0 D. m! G; h' t
- }
4 S5 X, p' E$ l _8 t& T - ) J p3 K2 g6 p! a V4 H- F
- /************************************************************************/
* b' Z0 ?8 b' ]+ a8 k - /* PROCEDURE: HighSpeed_Read_Cont */) R' s2 _% s% w5 L, f, q
- /* */ 9 v8 u% y0 E+ n0 M8 L4 G4 V
- /* This procedure reads multiple addresses of the device and stores */
8 C2 a* E$ p4 l' V - /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
' f( W$ w- v8 Q+ O - /* */
( T9 x0 D7 \; x+ G2 g: M9 { - /* Input: */% g6 U/ ` \4 @8 u. F% G
- /* Dst: Destination Address 000000H - 0FFFFFH */% M( F, x% J* T0 r+ H% y
- /* no_bytes Number of bytes to read (max = 128) */) ?7 E$ ]5 c) P t' |* M/ [
- /* */
* L! h5 C# ?4 X, w- x B - /* Returns: */8 n7 ~" L# k6 w( M; B" r$ ^
- /* Nothing */. Z _' M4 l$ n: P! a8 Y
- /* */+ \7 p$ T1 o$ O; e' P' n
- /************************************************************************/
2 n+ V" u* `; R. S% N - void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
- c4 ] n g4 {6 a( C& { - {4 ]) X: w# t0 E0 ^! Q0 s* u5 ]
- unsigned long i = 0;
; ]1 z7 [0 m( z! \( l. d; R - CE_Low(); /* enable device */$ B7 v8 ^* r# ^' P% I; _
- Send_Byte(0x0B); /* read command */
; }! q! v! i6 u/ J9 }* ~ - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */& [" _3 q0 J! s
- Send_Byte(((Dst & 0xFFFF) >> 8));
% I+ c: o( c* t' S - Send_Byte(Dst & 0xFF);
$ ]% y& x _+ |" @ - Send_Byte(0xFF); /*dummy byte*/
8 c2 R( y1 V' Q - for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
* V1 U: m) P/ B! y1 x3 W. y5 @ - {
* B K+ h4 Z) b, G; d - upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */$ q9 {5 X" l! c/ t
- }% l8 C; d- f4 O- H7 i7 O, M
- CE_High(); /* disable device */
3 Z7 _7 H+ \$ [ i# O2 X - }% x0 y0 U6 \1 z8 G9 e
- |. f3 C! \$ e- ` d1 f" ], G
- /************************************************************************/* p: T( N4 }; T2 S* R* m0 D
- /* PROCEDURE: Byte_Program */" K2 p+ O( y% B9 I* B7 S y; b
- /* */
6 d1 A4 j/ ]1 z9 } - /* This procedure programs one address of the device. */0 U( K9 Y3 ?8 j- D
- /* Assumption: Address being programmed is already erased and is NOT */
8 g5 o9 Z3 M8 k - /* block protected. */
, t/ z( V& l3 f' l1 t" J/ @ - /* */# j8 Y c! P: U$ k4 f) u) J* {4 }
- /* */$ ^: Q# u1 U8 t% Q5 S5 m
- /* */& t- h9 [5 a8 l$ v! ~0 F' P
- /* Input: */7 q2 V2 E- Z1 k
- /* Dst: Destination Address 000000H - 0FFFFFH */; _! C$ A& k: C, K6 h4 ^7 X
- /* byte: byte to be programmed */! x; }; v2 ~! h! E; P
- /* */7 D, j7 l3 T- n' J
- /* */1 j3 Q) I A4 m$ t! |
- /* Returns: */: d- w7 p: X% B+ s
- /* Nothing */
) |% i% M7 W- P# ?( i! D - /* */, C9 q- {1 R% Q5 `; V
- /************************************************************************/
% G/ }" ^/ N' {7 d2 n - void Byte_Program(unsigned long Dst, unsigned char byte). G! \$ O& r4 \7 A9 D: E/ N
- {" ~9 B, H0 ^% I3 L Q+ J. P
- CE_Low(); /* enable device */
8 o7 l# \+ ]0 Q7 @0 l1 K3 L - Send_Byte(0x02); /* send Byte Program command */: N3 E4 T2 @# h1 ~7 ]
- Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */) `7 a/ i1 F% O0 n( H3 G8 p c$ y
- Send_Byte(((Dst & 0xFFFF) >> 8));1 N3 Q* ]' k# {, {5 P
- Send_Byte(Dst & 0xFF);
0 S/ |7 w& U: I# C% | - Send_Byte(byte); /* send byte to be programmed */+ i5 k8 a2 `1 {/ g( u1 Z4 l
- CE_High(); /* disable device */; N+ Z. P {" R+ E" y: G7 T7 @
- }/ j/ q2 e2 n* [, W
5 @% Y" C. G5 y- /************************************************************************/
M" `4 t2 O$ x% T6 E Q# M( u+ u - /* PROCEDURE: Auto_Add_IncA */
1 ?) t3 F% L1 @# @3 M+ `/ j - /* */
3 Q& W- D! s6 o - /* This procedure programs consecutive addresses of 2 bytes of data into*/4 H; V4 e/ q# [& z$ @
- /* the device: 1st data byte will be programmed into the initial */
- S' M: S9 Z X8 l - /* address [A23-A1] and with A0 = 0. The 2nd data byte will be be *// y' }4 Z1 l' H+ E9 V
- /* programmed into initial address [A23-A1] and with A0 = 1. This */
7 B0 ~# E7 [$ O& o* e - /* is used to to start the AAI process. It should be followed by */
: ]7 V* \# }, f3 F F - /* Auto_Add_IncB. */2 V7 k" D ?' ^# g1 T
- /* Assumption: Address being programmed is already erased and is NOT */3 m8 S' |7 X6 t F* o+ \0 q
- /* block protected. */# I* p( D& ~& N7 G4 x4 `0 s
- /* */
. d }: M# m( D1 `- O - /* */
* L+ ?# H9 X8 x8 t% P: h0 I - /* Note: Only RDSR command can be executed once in AAI mode with SO */
. F/ P/ ?1 o' o9 E% Q: X - /* disable to output RY/BY# status. Use WRDI to exit AAI mode */
; |1 A) J0 g' \( Q( E t - /* unless AAI is programming the last address or last address of */
6 [5 J% R2 M( {6 W5 c0 c - /* unprotected block, which automatically exits AAI mode. */1 r8 k; J' u9 K; y7 r2 u
- /* */! f: |3 D4 R2 R, w- w O- K6 @
- /* Input: */! k0 Q3 B4 ?2 m2 D& d
- /* Dst: Destination Address 000000H - 0FFFFFH */& y- X7 w. i5 t( u3 \' ^
- /* byte1: 1st byte to be programmed */
) f% R+ c( s8 c% ]! M - /* byte1: 2nd byte to be programmed */- W. K" q. J& _% h' } ]' s
- /* */" U- ^, K0 Q) I" ~2 w9 N
- /* Returns: */
9 j6 G" y& w. u- k9 c. u o - /* Nothing */
( k% s1 k( ^. ]- h - /* */ y2 Y7 ~( y) a, E
- /************************************************************************/: I; r% y6 s6 Z7 I( i
- void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
5 I4 u. K* v7 y% `% ]. N+ ` - {
! ?9 Z" N5 \3 T/ F0 \! n) S9 x+ P0 N - CE_Low(); /* enable device */* `! a6 K2 R) w8 s2 z
- Send_Byte(0xAD); /* send AAI command */
@5 Q* U8 O5 C5 R. R" X - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
8 s2 O/ K+ z! W" \/ B) M; @6 p - Send_Byte(((Dst & 0xFFFF) >> 8));( R3 |/ e6 p( [
- Send_Byte(Dst & 0xFF);* r( R0 i* n/ z: |+ M
- Send_Byte(byte1); /* send 1st byte to be programmed */ 2 u) ?. C5 V5 h- g2 d
- Send_Byte(byte2); /* send 2nd byte to be programmed */7 }7 F6 r% q$ c: V9 R! n
- CE_High(); /* disable device */" `5 O. d# r# U( b+ [
- }
# H% P, w6 A% N" r6 J: r- S
) W y: g7 d) K0 B9 b% ]- /************************************************************************/
. g6 c- {( x' `. p+ T - /* PROCEDURE: Auto_Add_IncB */& J9 C3 e8 k6 J2 a# l( V+ p- H5 H
- /* */
# N$ v" l( ]4 c( n( [5 U - /* This procedure programs consecutive addresses of 2 bytes of data into*/3 s2 \+ L) z/ W) f" X& A0 ~
- /* the device: 1st data byte will be programmed into the initial */& m8 V0 E) K: @+ t, J+ y
- /* address [A23-A1] and with A0 = 0. The 2nd data byte will be be */4 P. m* ]' L" Q! r/ A
- /* programmed into initial address [A23-A1] and with A0 = 1. This */
) l) [, P ^8 b4 `, h2 _, y7 e: q - /* is used after Auto_Address_IncA. */
! m* y7 v* J! w9 } - /* Assumption: Address being programmed is already erased and is NOT */
5 b( o! k0 r8 J- b% K0 q7 b - /* block protected. */- |0 k0 a* p# g4 f
- /* */* j* f. @, x1 U0 q9 g
- /* Note: Only WRDI and AAI command can be executed once in AAI mode */2 s) D& l9 }9 t
- /* with SO enabled as RY/BY# status. When the device is busy */: I! ?/ x9 ~: F9 l) {$ Q$ ]. X
- /* asserting CE# will output the status of RY/BY# on SO. Use WRDI */8 L$ ~4 T$ H$ ]: A) G
- /* to exit AAI mode unless AAI is programming the last address or */
( N2 p2 U3 N4 d - /* last address of unprotected block, which automatically exits */, i+ ]7 o* w$ _! d) g% Q$ U- x
- /* AAI mode. */' ]$ d$ u3 \! J( k' m. W
- /* */- n2 K: N8 w. m, N7 C
- /* Input: */8 M# F# l8 {, D2 O: R" i3 F5 b
- /* */
" D9 f3 Z8 l3 @7 F' Z$ l' r0 W - /* byte1: 1st byte to be programmed */" Y* m% W" f5 U: e
- /* byte2: 2nd byte to be programmed */
% W o* ^) h2 I! B. i - /* */
. ]! J7 {# O+ G# V: ` - /* */
- h8 }8 b4 |/ C0 |0 p# {* E - /* Returns: */
3 M& M9 L/ H0 S: l/ H' ]. [# D+ x - /* Nothing */
U, @" ^0 n& i% f2 n0 D2 Y# t - /* */
5 \0 S% ^9 F( o$ \ - /************************************************************************/, @% f' Q; c: {0 t& S& ]2 ~, r
- void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
5 P/ ~1 S7 `2 O" c - {
* ~ g, b. L8 p+ L7 D: W! O1 f+ K - CE_Low(); /* enable device */% s, m" l) T1 ~: E6 f. N7 A
- Send_Byte(0xAD); /* send AAI command */
# m6 _4 a( u- Q' t# V - Send_Byte(byte1); /* send 1st byte to be programmed */* K! L4 Q- Y' X) d
- Send_Byte(byte2); /* send 2nd byte to be programmed */
) e) x. G( C9 s - CE_High(); /* disable device */+ ^& a9 z; K* | M5 d9 N
- }: c% k( ?6 A! T3 m3 o: ^6 m
- ! _1 ?: ~5 m/ M: ^/ f* Q# j
- /************************************************************************/& ]5 c: S) } g; H8 u' G( J
- /* PROCEDURE: Auto_Add_IncA_EBSY */3 ]$ E; ~1 H. ?: @; }
- /* *// E4 x4 Y5 U( Q5 B+ E
- /* This procedure is the same as procedure Auto_Add_IncA except that it */- z+ T# E H' u& L# G
- /* uses EBSY and Poll_SO functions to check for RY/BY. It programs */
7 M1 H9 j0 ` s! @% n - /* consecutive addresses of the device. The 1st data byte will be */
5 i. b# @- M) b4 }( }" U t. A" s - /* programmed into the initial address [A23-A1] and with A0 = 0. The */
$ d' ?) [6 v: w7 L - /* 2nd data byte will be programmed into initial address [A23-A1] and */
) z1 ~) L% F& N, |4 c - /* with A0 = 1. This is used to to start the AAI process. It should */
4 y3 @, T% u- v1 X1 r - /* be followed by Auto_Add_IncB_EBSY. */# G0 u+ q# I' J( R' c# `" D1 O
- /* Assumption: Address being programmed is already erased and is NOT */
) @1 t( A- C$ Q - /* block protected. */7 k% H' b/ r. W5 O& x7 g' l
- /* */3 L7 Y; h C/ g( e5 k s3 M
- /* */: R; s+ ~$ p# M
- /* Note: Only WRDI and AAI command can be executed once in AAI mode */
! g3 H* [6 G# e+ y2 a. U( C - /* with SO enabled as RY/BY# status. When the device is busy */
& e6 m7 l! r6 ?+ O: C0 ^* e4 E9 M - /* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
* B! v& q! R7 V) j. Q - /* to exit AAI mode unless AAI is programming the last address or */
: s; g/ v J0 e' ^ - /* last address of unprotected block, which automatically exits */
# _- m- i% W, a - /* AAI mode. */; u3 o |$ }7 Y* M. L% c* Z0 M! P
- /* */
/ h1 p% g j* O+ K# V - /* Input: */
s6 z9 R. H+ J8 s - /* Dst: Destination Address 000000H - 0FFFFFH */) K# E7 v, z& }( m
- /* byte1: 1st byte to be programmed */
6 g6 l( u& R4 i8 ~ - /* byte1: 2nd byte to be programmed *// T; |' p" f. f; O- G7 i# w) D: Z
- /* */& S+ c1 y% d, h, Z0 y# H6 J
- /* Returns: */" F5 U1 j2 ]" h" D! h
- /* Nothing */
6 N/ b) X: S/ K) @7 u( l3 t - /* */
|6 Q- b) T, t& n - /************************************************************************/) q1 `! I( Y5 l5 q
- void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
7 ?& v" E3 l0 G/ k8 o: Y - {& b, ]7 m; W& L2 l1 y. o1 T6 G& N* d5 s
- EBSY(); /* enable RY/BY# status for SO in AAI */ # r# [8 H1 R, M5 l
m( e: @; ?/ G3 p5 ?- CE_Low(); /* enable device */' z. C( o- `) p6 w
- Send_Byte(0xAD); /* send AAI command */
& X/ b. ]6 L; H I0 [9 A/ ? - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
- f) X& P, u' ?$ d - Send_Byte(((Dst & 0xFFFF) >> 8));$ @( X5 v8 I8 p2 C3 w! u A4 }
- Send_Byte(Dst & 0xFF);; m% l' z- G" e( v
- Send_Byte(byte1); /* send 1st byte to be programmed */
3 `. y. P- O. ?( a) m - Send_Byte(byte2); /* send 2nd byte to be programmed */
, D( j5 u$ A2 W- l4 d, | - CE_High(); /* disable device */
8 F+ t M V& N5 w9 G6 ? - $ }" |' b, r- e p1 M5 D& Q
- Poll_SO(); /* polls RY/BY# using SO line */
9 u0 J1 [5 H: E# Z* X/ M0 E/ ~
: O3 J4 y. @2 g @* Z- }
8 H! \. ^- h- }% I - ' U) W3 y7 j) B, N; T/ @# `+ W( f
- /************************************************************************/
4 q r. J9 Q/ `) n9 Y - /* PROCEDURE: Auto_Add_IncB_EBSY */! X* A1 O6 z$ R, T$ m
- /* */
& h7 d; k8 d; @ - /* This procedure is the same as Auto_Add_IncB except that it uses */
' F6 z; p/ t2 M0 w/ R" l( ?. z - /* Poll_SO to poll for RY/BY#. It demonstrate on how to use DBSY after */# o9 v& Q5 G0 E3 f3 |
- /* AAI programmming is completed. It programs consecutive addresses of */) }9 d: |) \4 C* W9 Y7 ?# W$ h
- /* the device. The 1st data byte will be programmed into the initial */6 s9 @( H9 x% ^- z2 ]; m9 u
- /* address [A23-A1] and with A0 = 0. The 2nd data byte will be */5 u+ H) k9 s/ L
- /* programmed into initial address [A23-A1] and with A0 = 1. This is */6 Q3 K9 J X6 W: x H
- /* used after Auto_Address_IncA. */3 _ c. P1 e# U. s0 c9 R E* t
- /* Assumption: Address being programmed is already erased and is NOT */3 b6 Q( q8 y8 ?4 q$ H. V2 D2 b4 b
- /* block protected. */; H9 q+ d" G* _" v- b% g
- /* */
* A' x' l# l& I. F) D6 U0 e - /* Note: Only WRDI and AAI command can be executed once in AAI mode */
3 O3 [+ Q: @ z' P - /* with SO enabled as RY/BY# status. When the device is busy, */
8 X4 n( f' J- A+ k) M - /* asserting CE# will output the status of RY/BY# on SO. Use WRDI */: V# E$ x8 { e* j' L0 d) Z
- /* to exit AAI mode unless AAI is programming the last address or */
) }* q* z# c8 g4 ^; o. [/ E - /* last address of unprotected block, which automatically exits */
7 @8 f* V6 B: R5 Q - /* AAI mode. */
: `; ~. D6 ?1 Y, W! T# _ - /* */3 z* w8 Y+ P5 |% _8 V
- /* Input: */" {9 T* v! \+ r* k) x+ _
- /* */8 r7 |, H7 O3 q1 y" s
- /* byte1: 1st byte to be programmed */
* s2 l9 L5 H) `5 Y1 h y- }; k - /* byte2: 2nd byte to be programmed */
! {7 ]7 ?6 i8 L# J, f - /* */
- _1 ^1 [& z |2 n% M7 @ - /* */
' \6 d9 V1 p3 A9 |7 ` - /* Returns: */
$ ?+ s: g( r/ H8 ]2 P - /* Nothing */
! r( Q" }- l0 Y! `6 H5 U9 c) r - /* */
9 ]- O+ V; Q5 ]! O, R+ } - /************************************************************************/
1 \$ P* K4 E$ M: r* o% K, S - void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)& y; S) R8 J" l* b7 h- b7 m2 B
- {: r( `$ ? k8 r6 U
- CE_Low(); /* enable device */, s- L: @) H9 A0 Q* a- g% J* T
- Send_Byte(0xAD); /* send AAI command */- x7 L3 d( p, j3 L1 \
- Send_Byte(byte1); /* send 1st byte to be programmed */, r' a% \. o. ]# q% F# L7 Y
- Send_Byte(byte2); /* send 2nd byte to be programmed */
8 ?" ^2 x8 s- W) v" W W" B! Q - CE_High(); /* disable device */4 @% f; c8 b. M- Q# d( s$ ^
J) v2 I2 O2 R) k6 j- Poll_SO(); /* polls RY/BY# using SO line */
V; d0 P( M( `5 X: ]: O - ' e6 ^1 e( b4 w3 v
- WRDI(); /* Exit AAI before executing DBSY */4 W8 I# h0 m+ [' Z
- DBSY(); /* disable SO as RY/BY# output if in AAI */
% `$ G8 `% R6 c6 ~. z) D$ b, J - }* \, t' y6 E) _2 O, B6 x" s
- " V2 {7 |; H v$ v+ n* r
- /************************************************************************/
6 B4 y# R+ C1 Y+ y1 V6 i - /* PROCEDURE: Chip_Erase */
, o8 q6 ]: N7 W" a& i* |. Y9 r- o2 w/ c - /* */
7 W' \* h) d* N1 N - /* This procedure erases the entire Chip. */
* X9 E1 }" N& u7 a9 F - /* */3 ]& J8 w' D1 u: W& G; f7 D
- /* Input: */
7 k k7 H! u5 u' y: r3 f - /* None */
t8 J& K5 p2 @4 g - /* *// M; x( H2 Y; ^! r4 X% K
- /* Returns: */) Y7 { t1 {( {. j7 s( T
- /* Nothing */# \& R8 ? a/ ?$ U8 B
- /************************************************************************/
# s5 y+ F) z0 Y8 V; x# A# h. ? - void Chip_Erase()
8 Z, f, @4 s Z" z0 W& F8 ?% k; ^ - {
& b' I$ @) `' u - CE_Low(); /* enable device */5 T2 b+ y: u9 h9 S6 ^( _0 }
- Send_Byte(0x60); /* send Chip Erase command (60h or C7h) */
5 S3 }: n* V8 n' i3 r% ` - CE_High(); /* disable device */
- ]( |. p, j5 b$ Y" E; L - }# j, w( R+ b3 y
- 6 p2 h( j* F+ W# p1 b" @8 c1 @9 `8 j
- /************************************************************************/6 v, O' p) g" {) q+ N+ @
- /* PROCEDURE: Sector_Erase */+ N6 |$ A6 _0 r# K* p; f& S
- /* */
. {% S u0 \# h. L - /* This procedure Sector Erases the Chip. *// ]1 n# H, p t/ F/ |
- /* */2 L k& b. [+ I/ a( P
- /* Input: */
" l* x# n" {2 z6 r! Y% X2 K$ x - /* Dst: Destination Address 000000H - 0FFFFFH */9 Z3 ~- S. S# Z9 j# P
- /* */- N- o3 ^: k9 u7 k
- /* Returns: */9 ]5 \" v& F$ l2 G9 d/ p
- /* Nothing */: ]& R; m3 E7 X. Z& {' D1 ]
- /************************************************************************/6 L& |# F' w6 P% v& a
- void Sector_Erase(unsigned long Dst)
h( w0 m$ p: }4 h# V - {
4 s7 [% K8 E8 d/ k - / a, D) _# o6 ?+ X7 G$ c
- $ J. L' p, o2 `% R! P
- CE_Low(); /* enable device */
* o5 F% F% z1 m4 J6 C - Send_Byte(0x20); /* send Sector Erase command */
" ]0 E! F, V0 \. {, x - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */8 H; B# N e7 D! K+ s9 ^
- Send_Byte(((Dst & 0xFFFF) >> 8));- j9 S6 c) Q% {
- Send_Byte(Dst & 0xFF);
1 b2 T5 S% w, A- Z2 i* ] - CE_High(); /* disable device */
; G( M! H0 I* i, _ - }
0 Y4 W7 ^+ O% d" o T; Z
: E- j8 r" {5 L# I- /************************************************************************/: X7 m' Z0 n! v
- /* PROCEDURE: Block_Erase_32K */
! S8 l6 D* o. @ - /* */* A, a$ n* G1 `
- /* This procedure Block Erases 32 KByte of the Chip. */7 T: y0 u \4 ^3 K/ B6 _
- /* */; e( a9 J& Z5 s1 X( A" z7 _
- /* Input: */
0 z L# t' y- a+ R. x. h - /* Dst: Destination Address 000000H - 0FFFFFH */
+ b, a6 q4 n U" {5 [7 @ - /* */
* ]0 j/ V& S3 b/ L - /* Returns: */
h1 z/ _% g$ r - /* Nothing */, P4 h& t4 S" |; J% V( O. A* [
- /************************************************************************/% ^& r; r. M/ @* o: z3 A- J8 Z
- void Block_Erase_32K(unsigned long Dst) d u# d; K4 u/ [& r& i7 Y
- { A, A7 s8 t0 O& g- V* A
- CE_Low(); /* enable device */6 J |9 v: x6 W% ]6 M) T3 [
- Send_Byte(0x52); /* send 32 KByte Block Erase command */
% q6 X: I/ F2 h n! P - Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
# _; X5 q) G9 v4 E) C+ `2 |3 F5 Q - Send_Byte(((Dst & 0xFFFF) >> 8));
, h. o$ ]: U# |/ c" L4 W0 M - Send_Byte(Dst & 0xFF);/ F" Z6 s. |' Q0 Z+ t) S) r
- CE_High(); /* disable device */
! c) e0 _, D9 q, Z: \! t - }6 t# N6 m8 ] ~& Q7 o8 d
- + B6 @: B4 e2 h7 D
- /************************************************************************/
: m# j! z( _# f/ F0 l4 N- r - /* PROCEDURE: Block_Erase_64K */
* X. H. _% T8 c+ q) w. C; P - /* */
7 F {" Q [( ~8 F& Y9 I - /* This procedure Block Erases 64 KByte of the Chip. */
& A% ^3 F# v; J( P - /* */
5 ^# R8 D' ^3 h - /* Input: */
: }. @; U' ^; K8 A - /* Dst: Destination Address 000000H - 0FFFFFH */
! ?4 Y0 ]1 O: [. j* G - /* */
1 w( r& G; T( G V# C. C9 l - /* Returns: */+ Z- c% }$ Z, e/ F, o0 b) M8 @
- /* Nothing */
- ?) d3 g2 R+ \, |" F& ?. ]7 n& J7 w5 S - /************************************************************************/- u. l2 ]6 P4 { m
- void Block_Erase_64K(unsigned long Dst)
) r: S- {8 O1 H& d6 N - {
( j- I4 I$ v! | ]8 t - CE_Low(); /* enable device */
$ l" V! G7 y1 _; T- L - Send_Byte(0xD8); /* send 64KByte Block Erase command */. E& j1 c' W0 Z8 ~
- Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
4 t+ P7 C1 Y7 ^4 ]* h - Send_Byte(((Dst & 0xFFFF) >> 8));. x* `/ V( t1 ]; _
- Send_Byte(Dst & 0xFF);
. R+ j; `. n: t; I+ z5 _$ k( ~9 o - CE_High(); /* disable device */: ?, g0 Z4 Y: s5 r( ?1 j# [4 ^
- }
, q, y2 t" T, c: Y/ O' Y1 r. J
6 b7 ^9 a1 B+ e" l5 P- /************************************************************************/' u9 [. s5 c" N0 r0 F0 p
- /* PROCEDURE: Wait_Busy */+ b9 E+ @( ]" V3 s" D0 S2 O
- /* */0 L3 d; k7 ~( S2 R( H; t
- /* This procedure waits until device is no longer busy (can be used by */! ~& U* }0 P- D& n
- /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase). */
5 V$ y# j3 U3 L - /* */3 A) q6 `* s W* y+ S" x+ b
- /* Input: */- O3 I( D% H6 u
- /* None */2 o* o! F" Y8 [' K. y
- /* */2 O2 {5 |- U* ?+ R! v
- /* Returns: */2 @' e4 t) p9 w% p* r( R9 t
- /* Nothing */5 c( v" v/ [* p) W( r( e
- /************************************************************************/
x' ^3 i" ?& u! p# H$ [ - void Wait_Busy(). F! |7 `, k2 T) y, B a
- {
3 Y! V# w8 ^5 Q, [& G& o - while (Read_Status_Register() == 0x03) /* waste time until not busy */9 O9 Y1 J* w! b9 Y
- Read_Status_Register();6 I/ h9 x7 G% V; B; K7 y1 i& ^
- }
2 I0 J0 n \9 ~7 Z - . c) y, k5 }. t8 C1 f
- /************************************************************************/
[( ~- J9 d; O$ X5 H - /* PROCEDURE: Wait_Busy_AAI */
2 M! f) x1 m X" |; k) ^ - /* */, ^& w* e h- [$ N1 ^3 {( j: Y7 y9 u
- /* This procedure waits until device is no longer busy for AAI mode. */
0 M, G6 J3 |! ?7 c6 x4 m3 A% ^ - /* */* ~) t j ~ A h
- /* Input: */% s2 W- ?+ w* H# P, D) {
- /* None */* y5 X( n5 D2 ^7 c3 }+ F4 F
- /* */4 d/ R7 B* S; g! E" I5 U9 ~. c% F
- /* Returns: */) c/ R$ h# p/ q, U% z7 {
- /* Nothing */
( ?, S1 f1 D% g# ]6 E( F9 C! T* t - /************************************************************************/
o3 U0 W* E& |. t/ @ i - void Wait_Busy_AAI(), t+ }. `9 ?5 R
- {" A2 ?6 p* V, ?3 }% y( j
- while (Read_Status_Register() == 0x43) /* waste time until not busy */
% c: a; Z# f7 h( L - Read_Status_Register();
: @5 D% D( c1 R5 D) H - }
! H7 P, x5 D* G( a; |& G% J - % }$ F# ~' H! J0 b+ q& I
- /************************************************************************/- }# i c& r* Z4 z
- /* PROCEDURE: WREN_Check */
3 N# x1 r" W6 A( R) m - /* */
9 k6 V0 n, g9 s9 m5 x - /* This procedure checks to see if WEL bit set before program/erase. */" }$ s; Y+ E( M9 m% y4 i/ \
- /* */: b' R# B. ?5 R1 L
- /* Input: */
, m9 p7 P+ R7 l) M5 ]. D6 j) k! b# ? - /* None */
0 p+ i* q, f* v! e% g) \3 \ - /* */! |2 X7 E" |8 H; s' y: t! U% Z& {$ P
- /* Returns: */
( |! B7 R0 W u( ~. n. H* J4 Q - /* Nothing */
% b1 [. {8 q3 v$ Y, |1 I: J+ G2 b - /************************************************************************/
. e& `1 `& v; C# i - void WREN_Check()
" V0 I& c$ X/ b. L3 z - {
7 a% n# @ p0 n" v: b - unsigned char byte; y2 k& n# c- V2 S
- byte = Read_Status_Register(); /* read the status register */
$ x6 Y2 P$ U% Q( i# W/ G" O/ j - if (byte != 0x02) /* verify that WEL bit is set */! [* e+ n( C+ E+ N; I
- {
9 s# o3 c: [3 o2 g8 }2 N# i - while(1)
2 S. p8 }6 J& Q# c9 i - /* add source code or statements for this file */8 f4 q( j( l+ \, Z/ S( o
- /* to compile */
: p" {1 Y5 j0 Q/ q0 \ - /* i.e. option: insert a display to view error on LED? */
J3 p. P- C, Q( C. X8 k5 T" J% d - 7 V: V& z3 G- [* P3 m- h. c
- }
8 J5 r0 D/ t' B; d" ] - }
0 C! v/ ]* p" c, k O$ \7 |% j
+ U. W6 F! W5 ?4 J- @% I- /************************************************************************/
" [' R8 G( h+ {6 f P- f - /* PROCEDURE: WREN_AAI_Check */
( k, b, T! ]1 d# x( s - /* */
7 O( `3 Y; P F9 S6 }/ ~$ Q - /* This procedure checks for AAI and WEL bit once in AAI mode. */
/ B6 b! l) d# R, `7 O8 L" c0 @ - /* */% a: k4 |) K5 D1 T- s0 ^! k# f9 e- x
- /* Input: *// _* Y1 S" C' m" Y( D* b, i
- /* None */
$ n* `/ C T3 Z' r6 C - /* */
! u) Y" I9 r1 C0 _/ i2 z - /* Returns: */. T! i6 j# {, X
- /* Nothing */
- ]: w4 Q/ k& F$ \4 K: }" M$ I - /************************************************************************/! s8 _+ a* G9 v1 g+ B. ^8 P
- void WREN_AAI_Check()2 S/ _7 S: Z* [; f" t5 _
- {% F0 a1 L$ p' P" _4 ^# X3 d
- unsigned char byte;. u9 }! I/ ?* o% z; n( O/ I! {
- byte = Read_Status_Register(); /* read the status register */
8 u, }6 \0 L8 P - if (byte != 0x42) /* verify that AAI and WEL bit is set */
( [" m% m. m# u0 U- \4 T - {1 B0 k* \. [3 t! d+ U
- while(1)
" U( c5 n2 x) O* e - /* add source code or statements for this file */0 K c3 z1 }) P: G) T
- /* to compile */! N; p. a) {) y0 P
- /* i.e. option: insert a display to view error on LED? */. P, ]: `' X1 ^. E& m+ C1 D
- . D' M% Q4 g/ [& I! Y6 t) [$ R+ O+ p
- }
4 Y/ L+ L! E& ~! K, j* R$ q6 ~ - }3 w& x/ D4 v% T2 C/ J/ P0 x
/ s+ o4 M3 Q$ y$ z) k- /************************************************************************/$ P/ B% P5 B& I. j6 ^$ p
- /* PROCEDURE: Verify */
8 f: \7 D9 |: Y2 [2 ^4 G. g - /* */
$ t% f: J& U8 ]% }( {7 H- R - /* This procedure checks to see if the correct byte has be read. */
, }7 u- U+ o1 _' `# o7 H - /* */
8 X3 i, k9 U; B; r5 [5 R - /* Input: */# j, G) |9 f* @/ `% i
- /* byte: byte read */" _% V) S; V" p* R3 c
- /* cor_byte: correct_byte that should be read */
6 N& u) s$ i. c! ^: c& L. \2 E7 h - /* */
; a6 k9 h P" c" m - /* Returns: */
1 m2 M) ~% G& D0 z - /* Nothing */
: `: t0 k/ m2 n) l - /************************************************************************/
! \% g; A0 ~2 C. p; ` ? - void Verify(unsigned char byte, unsigned char cor_byte)
5 r4 v ]! ]# d/ q' a. \ T - {
& g3 Z+ L, [" h% V3 t% l6 J - if (byte != cor_byte)) c( D" P p8 t" E( v; e7 I
- {
" s: i/ x$ [1 O+ A# ~' o - while(1)
1 F) q" k$ _& N n - /* add source code or statement for this file */8 F- f3 Q5 Q: Z* K
- /* to compile */% U$ [) s6 ]2 G \8 [: e6 c$ K
- /* i.e. option: insert a display to view error on LED? */# Z D4 G- d3 G8 J: {# s" Z
- . t- y5 { l' L1 S3 S' W
- }
7 |7 i) y, n2 G( o - }* L9 C* G! @/ C1 E
0 }- B$ K$ ?" [2 W
3 \6 Z2 N8 {! |- int main()8 }. Z7 L; A) d) @% M8 M
- {
7 o8 Q0 ?4 q& t - : x& Q4 @& s* v
- return 0;
$ j% _7 C/ k' J - }
复制代码 |
|