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