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