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