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