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