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