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