找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 52457|回复: 13

[Software Driver]SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver
    , b( u- ^- ^) x# @! k' W6 Q; b
  2. - a5 T1 a, U: |6 I
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    , C' |" b, c" x) Z

  4. 3 q8 u& Q3 G$ |/ [4 s- B
  5. November 4th, 2005, Rev. 1.0: q& b; {* q  \' w

  6. 0 G3 J: }' H5 a, u
  7. ABOUT THE SOFTWARE
    9 X: ?' _3 m- `* }
  8. This application note provides software driver examples for SST25VF080B,0 e2 `; a4 p" U2 Q9 Y
  9. Serial Flash. Extensive comments are included in each routine to describe ' Z3 p2 }" `) C$ e
  10. the function of each routine.  The interface coding uses polling method
    3 F" M$ k6 s5 I) r- q
  11. rather than the SPI protocol to interface with these serial devices.  The- L/ _2 F! X" z4 x6 |
  12. functions are differentiated below in terms of the communication protocols
    ( y& O0 ~  p5 F  ~: E! U7 d
  13. (uses Mode 0) and specific device operation instructions. This code has been % j6 {! Y9 k1 g+ @5 |! a4 G
  14. designed to compile using the Keil compiler.5 {- T4 E$ ^; a" c2 d! f
  15. 3 i+ n2 Y; d6 f% k- g% T

  16. 7 d- e* U7 [" c" E+ q/ U) N4 ?& V6 R
  17. ABOUT THE SST25VF080B
    ) X) i  s0 E- ?5 `3 U; c8 q  n
  18. # i% a, E1 w, _/ I1 G9 C  W
  19. Companion product datasheets for the SST25VF080B should be reviewed in * J9 V* i2 ~6 O% Q
  20. conjunction with this application note for a complete understanding
    ) C7 a9 {  y9 A
  21. of the device.( H' M6 Z( [7 J, a6 t9 K4 }1 d$ F5 k

  22. # @+ m6 A0 ?6 @

  23. - O- W. w7 }. R: T+ l, Z' K: g
  24. Device Communication Protocol(pinout related) functions:
    6 s! H; k/ z2 a7 v7 @- ?

  25. 8 v! ^) E8 W5 L" @( M
  26. Functions                                    Function
    6 n! a: `# U  N& l0 F; q% ]6 C
  27. ------------------------------------------------------------------+ s# b# Z0 ]: ~. r% u5 q
  28. init                                        Initializes clock to set up mode 0.( @( t' d$ z: `
  29. Send_Byte                                Sends one byte using SI pin to send and
    1 U* _/ K- n: S! ]7 Z
  30.                                                 shift out 1-bit per clock rising edge% m" x9 G, g1 y0 Y7 Q# `+ p3 p
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 3 {2 K- d$ J7 x: L7 c4 Y" e( Q
  32.                                                 in 1-bit per clock falling edge
    : D7 b: `  H' \( B
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    6 T& V! u% L3 o8 N3 m/ m
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    $ r, G+ i7 z  Y7 }+ i7 g7 p
  35. CE_Low                                        Clears Chip Enable of the serial flash to low% Y! _7 {7 n2 \
  36. Hold_Low                                Clears Hold pin to make serial flash hold
      r. p4 k: Q4 R
  37. Unhold                                        Unholds the serial flash# o- ?, O6 B8 q1 {
  38. WP_Low                                        Clears WP pin to make serial flash write protected4 e  S. s3 L' v, K8 z8 l; q& f5 g
  39. UnWP                                        Disables write protection pin
    * g9 j8 U( s8 @$ s  e
  40. 2 m. v: W/ ~% p* E5 A7 n; R
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    7 H. E, r; r: x( {
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your; X/ g; ?3 e0 I- p& s7 E
  43. software which should reflect your hardware interfaced.          + |/ Z7 w0 g' K" J; d
  44. 2 a' ^5 d$ }8 g' v

  45. . T8 l& B3 m% C
  46. Device Operation Instruction functions:$ z- o, ]& c4 R5 r4 W. `% i2 D
  47. ( g% c8 J" J$ k1 u. i
  48. Functions                                    Function
    , x& k+ K/ W+ X
  49. ------------------------------------------------------------------
    2 e7 G4 z# F, ~8 ?* v
  50. Read_Status_Register        Reads the status register of the serial flash
    5 E, \) _; p9 }7 r" \2 r
  51. EWSR                                        Enables the Write Status Register
    % ]0 Y. ]/ c; T% K/ j
  52. WRSR                                        Performs a write to the status register
    3 x. V( j2 A7 ^4 t6 \! Z  y
  53. WREN                                        Write enables the serial flash
    8 f/ l( p" j& R9 s- x  j
  54. WRDI                                        Write disables the serial flash- ^& n+ {) D9 N0 `4 f# n
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    6 J. q, k. c! |8 Z, I
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    $ z% e/ P2 O) a# n7 P5 e, l  I
  57. Read_ID                                        Reads the manufacturer ID and device ID
      `) N1 L3 _& E
  58. Jedec_ID_Read                        Reads the Jedec ID6 X$ K: v( X  c; }: ^7 K- R# I+ c: l
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    1 q# q, y( g2 @4 V
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)# ^1 ]; ~0 m0 g# p) o0 P8 j$ N9 o
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)7 f4 {1 d- J3 G+ c
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)( O7 Z! w1 ~9 K2 o6 B! G  c
  63. Byte_Program                        Program one byte to the serial flash/ D; ]3 a( n3 f% Z5 t1 }  ~/ _% r
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    9 @" I( R. q  j3 n! g
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    ' [# Z! k& F  T6 J, ~8 h/ P7 P% @1 f
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    $ n* w3 d3 P% A: g# ]% P# E
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    0 g' K0 f0 c& L7 `7 U+ x: D
  68. Chip_Erase                                Erases entire serial flash" J2 s; X; T# E4 m' M; y
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ; r) w8 r+ c1 Z* _5 F6 r& Z
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash" z- r) I& M) b, p% s/ U
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash: E3 B0 I! N* x1 o+ g: X1 T: g
  72. Wait_Busy                                Polls status register until busy bit is low
    " `; ?! k1 R. k& E* j! d
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    " t: z5 e4 Z8 x& J! e( B
  74. WREN_Check                                Checks to see if WEL is set
    2 X# e4 _  e/ t; ]  `6 `; Q& C9 n
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set% L* ?9 M% }# W. u& t

  76. $ j! z* C2 G/ c0 H; z. H+ v

  77. 6 M7 ^7 N' G  F) K8 D9 T7 G$ W

  78. : J6 u& A7 d; M* t) K  G& ?
  79.                                                                      , ^& F& t. D: O  f
  80. "C" LANGUAGE DRIVERS ! F' G: J( X' \. m
  81. 1 Y2 \3 Q1 M6 L% ~4 d1 S
  82. /********************************************************************/
    . d  I# n# v8 o
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    & @% D5 A( S/ j5 f' d
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
      G: A( |! Q9 _$ e+ W
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    3 _. X* M+ G; x$ }- c. Y( {
  86. /*                                                                  */
    , K6 H( t  N; J  c8 ~4 }2 Z
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    2 v+ K6 [: S' Y7 K* s( O
  88. /*                                                                  */; C) p( @8 l. C; `
  89. /*                                                                                                                                        */
    . `/ ?( o) b. X3 f8 ?( O
  90. /********************************************************************/
    ; S/ I/ V+ x1 q4 t0 M, z
  91. ; a. j5 _4 Z% r
  92. #include <stdio.h>3 L" z& a% b( v) j4 L& O9 o, B
  93. #include <stdlib.h>
    / a& d2 S7 T/ [# V- D, w$ G

  94. # |2 {! f, }, `& ]
  95. /* Function Prototypes */
    ! ]5 E  x+ m$ C6 [/ R
  96. 6 S8 U' _6 E7 k! O( a* p
  97. void init();
      k# [0 x7 N. F% k7 d8 G
  98. void Send_Byte(unsigned char out);
    # d# c) ~$ R( Y  B. @
  99. unsigned char Get_Byte();
    6 E2 C: e" F+ j: w
  100. void Poll_SO();* D2 a2 o9 L, H
  101. void CE_High();
    5 D: V! C  j# J: i. i
  102. void CE_Low();
    : G' t9 h! T6 a3 Q
  103. void Hold_Low();$ c* Q7 ?4 z0 z6 H
  104. void Unhold();
    " P4 |! t$ c% j+ B9 D
  105. void WP_Low();
    9 ~) i; G1 F0 p2 ]( o
  106. void UnWP();* N( ^% {; g- C
  107. unsigned char Read_Status_Register();" {  `8 E! c  z- x6 X( K$ u
  108. void EWSR();
    ! @& ]1 D) n! M7 C. \) {6 |& {
  109. void WRSR(byte);4 p9 E6 {& K; t5 p+ D: r, R  o
  110. void WREN();  b1 f2 {) X4 r" x/ h1 D+ g, @
  111. void WRDI();  i" M2 I( n0 B6 s: n
  112. void EBSY();
    ( k6 \/ o$ z3 `# @* L) `) w" b# I; Z
  113. void DBSY();
    8 N7 u/ _1 y; C1 g0 [8 M2 j
  114. unsigned char Read_ID(ID_addr);
    2 Y. r# @, Z! e& [* u4 B
  115. unsigned long Jedec_ID_Read(); 1 D' h  f, h! U. m, f: t8 h  N& t
  116. unsigned char Read(unsigned long Dst);
    ( [* R" |0 i4 X& K, c% U, O
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);) Y3 x( }. @0 O
  118. unsigned char HighSpeed_Read(unsigned long Dst); $ R7 g# P2 m- ?1 F" m% Z
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);* M- L% E* E( z
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    & z, S5 W3 p! k4 x& g1 X9 J; _
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    7 Z4 P' g) p% A; h* u5 h) L' u# t% Q
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);0 [3 X/ T; l7 o. n) [2 q3 p6 G
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    % p* u! a, n4 ?+ H* J* n% O( @
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    + B, A9 \8 n' M5 Y$ ?, o' k
  125. void Chip_Erase();2 e: t) [) `- `8 K( }
  126. void Sector_Erase(unsigned long Dst);
    * B: L3 b' [" x$ h3 L6 ], O! {" q
  127. void Block_Erase_32K(unsigned long Dst);
    + r+ E2 y: B; G( J' q
  128. void Block_Erase_64K(unsigned long Dst);7 m, _  _  Q8 W
  129. void Wait_Busy();
    ' w& _2 S8 P2 J* p% T
  130. void Wait_Busy_AAI();
    - a& |7 q# M4 I5 t
  131. void WREN_Check();0 J% B9 }6 N3 i0 {, z
  132. void WREN_AAI_Check();
    $ U* L  K0 l9 S1 [) W3 p7 L) K9 B

  133. 8 y; {# o. e" z/ b8 f$ p
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ! }' U. ]! e8 O. N6 [
  135. ! ~* ^" a& U2 c" {+ W8 n
  136. unsigned char idata upper_128[128];                /* global array to store read data */
      A6 N& u$ f0 q% e2 K% P( N% |
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    : G8 Q# g4 e: a! `  R  _

  138. ! N- L* o1 \7 a
  139. /************************************************************************/! Q8 p# _8 Z* p7 K- L0 B
  140. /* PROCEDURE: init                                                                                                                */
    0 e; }1 D3 d$ G; v" r
  141. /*                                                                                                                                                */" ], E: A# G, ~9 _  a
  142. /* This procedure initializes the SCK to low. Must be called prior to         */5 l6 u0 C) T# v8 H+ ?
  143. /* setting up mode 0.                                                                                                        */
    $ e. y0 B% I. ^, y, t
  144. /*                                                                                                                                                */
    , E+ m" o2 c% ~/ G* C% n& }3 Y
  145. /* Input:                                                                                                                                */- L! m# M' N4 \4 m5 r& q4 w  J
  146. /*                None                                                                                                                        */; {" D6 ~* w( }" Q/ T! Q
  147. /*                                                                                                                                                */! P  ~' A& J: |
  148. /* Output:                                                                                                                                */1 R7 f+ U; o" X0 i! C
  149. /*                SCK                                                                                                                                */
    3 N! ?5 y. {; t* e
  150. /************************************************************************/# W, D; ~2 k' a/ ^9 g# a# s4 b; g
  151. void init()
    + s3 g$ x  s& c$ z4 Q" }2 H8 K
  152. {. k* n# E7 g9 ~8 q: B4 D& W4 W
  153.         SCK = 0;        /* set clock to low initial state */
    # t# n- ^- Q/ d! r8 m4 `
  154. }
    0 V3 K+ w# j2 G( p1 s  u3 F

  155.   l' @7 P( x0 G
  156. /************************************************************************/5 Q* ^  z- C  g
  157. /* PROCEDURE: Send_Byte                                                                                                        */# S8 ~+ X2 u- n2 a# f1 @% n
  158. /*                                                                                                                                                */
    6 p* G' C( R6 \. k2 ]/ i
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    4 w! c% t0 d1 U, I6 n2 w% b
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    9 H4 z3 K+ q2 ]+ m
  161. /*                                                                                                                                                */# T: `5 j' @( c, Q1 Q+ _, m" h
  162. /* Input:                                                                                                                                */
    # w2 B1 K  e( {9 Z, Y& C
  163. /*                out                                                                                                                                */
      z+ a3 h/ E* D" B! O5 X  D0 Y5 ^# @
  164. /*                                                                                                                                                */) @( x% B8 k* ?0 N& r
  165. /* Output:                                                                                                                                */
    6 f8 }/ i; Y8 U! W* T' u
  166. /*                SI                                                                                                                                */
    . o8 P0 K2 D( c
  167. /************************************************************************/, l- S* m: i1 t5 y! B4 y
  168. void Send_Byte(unsigned char out)7 r8 z% p: e7 ?) `
  169. {
    8 P$ m! L: j: m) y. K2 g
  170.         5 g9 \3 T! u; t. \8 p* w8 X
  171.         unsigned char i = 0;7 B/ b( n. {5 B" }/ [4 r. ~0 C
  172.         for (i = 0; i < 8; i++)
    : M7 [, T* r" _. i8 a8 N8 H
  173.         {( J: c3 I4 M$ V3 U! Z1 V
  174.                 % h6 E% L4 g; I4 O
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    * S' Y; P. D& `) Z. {/ U
  176.                         SI = 1;
    / y8 C( g% ]: F, v! T  Z  ^
  177.                 else
    3 j6 t+ x# R7 P8 w1 r
  178.                         SI = 0;                                /* if not, set to low */- @, A' d8 p& I; W0 t
  179.                 SCK = 1;                                /* toggle clock high */
      c* X3 Z7 K/ H" `
  180.                 out = (out << 1);                /* shift 1 place for next bit */# b, H+ o# N% U, @
  181.                 SCK = 0;                                /* toggle clock low */
    % _# Q7 O6 J8 N$ U$ c
  182.         }+ h, H: ?& \9 M& m: l8 n' D( C
  183. }
    ) a1 z8 g2 M+ \' a3 u

  184. ; _4 L2 R9 R; z1 t2 X6 R4 ?5 e
  185. /************************************************************************/
    % I* q' n! \! H1 f" M' `
  186. /* PROCEDURE: Get_Byte                                                                                                        */' U# ]) q5 Y* \
  187. /*                                                                                                                                                */
    ) S8 C* C9 N1 J3 S6 |/ A
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    # k' M5 e/ T7 M1 ]6 a. S5 n
  189. /* edge on the SO pin(LSB 1st).                                                                                        */, G6 m( k( `0 Q" W
  190. /*                                                                                                                                                */
    ) J+ ^! _+ Q' A* n% ?! U# Y" R9 ~7 k
  191. /* Input:                                                                                                                                */; J1 c  u8 {, o  I' H
  192. /*                SO                                                                                                                                */0 w, ]& ~- w2 V) T" J; z$ s
  193. /*                                                                                                                                                */
    ; k! }( p" Z4 K
  194. /* Output:                                                                                                                                */# C; B4 q" _1 Z+ X( R" p% Z% v
  195. /*                None                                                                                                                        */
    2 n6 K: J( W& `" s
  196. /************************************************************************/
    3 A! p" Y0 _& M- P
  197. unsigned char Get_Byte()& d% o8 a* r+ J0 i7 W
  198. {
    & F' p" N/ t8 J: `
  199.         unsigned char i = 0, in = 0, temp = 0;
    3 Y8 Q# R# ~1 s5 i( A! c1 w7 l+ n# y
  200.         for (i = 0; i < 8; i++)
    6 _' s; }; n/ W0 L
  201.         {
    1 S+ e" [2 ~; G: v( Y* J. _
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    8 R" c$ |: F* V+ y. q* a" @
  203.                 temp = SO;                        /* save input */: R! R. {/ L6 J5 y  V9 b
  204.                 SCK = 1;                        /* toggle clock high */1 V# G  x5 p. \% a" L7 o- }' }/ I/ S
  205.                 if (temp == 1)                        /* check to see if bit is high */
    : b6 |& Y7 O, [+ o1 g
  206.                         in = in | 0x01;                /* if high, make bit high */, @! t. A) B& A
  207. 2 g* T1 U7 T5 T, I
  208.                 SCK = 0;                        /* toggle clock low */
    8 n2 |( m9 b; Q

  209. : f& z/ r, \7 |! R+ r  z$ z8 I
  210.         }8 V- ]2 C7 X& v$ P. T( k
  211.         return in;
    & ~; o' ~/ e7 B/ ]. V: e& [
  212. }
    / x, A- e: [# c- g: R3 w
  213. + k% a- w$ {- H( n, _+ @$ L$ X; I
  214. /************************************************************************/  G$ A8 C7 B- {+ K0 }
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    9 k% \" \" g1 a  o( i
  216. /*                                                                                                                                                */
    2 C: x- ]- x8 E
  217. /* This procedure polls for the SO line during AAI programming                  */
    , m' E. l/ _& N2 Z  F# {6 L! t& P
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/2 `4 H' j7 u2 O& Z4 u3 @
  219. /* is completed                                                                                                                        */( }# h$ l, w* q- [6 @# V# l8 r
  220. /*                                                                                                                                                */
    - u  d; n( p' b! |5 o4 m$ z# M
  221. /* Input:                                                                                                                                */
    & A+ o; G$ U' v* q
  222. /*                SO                                                                                                                                */8 V, O5 E2 `% k5 M3 p
  223. /*                                                                                                                                                */
    2 C. E, X; {+ L- R7 Q3 _  o
  224. /* Output:                                                                                                                                */! Q, j" T( r' r% @3 B
  225. /*                None                                                                                                                        */
    ) N! n% z: [& N# c3 w
  226. /************************************************************************/6 J0 R' X" K) ~2 d7 \2 a
  227. void Poll_SO()
    2 v; J2 _- B( t4 C
  228. {
    ! E" Y9 ^4 j; X6 |$ K8 w# G
  229.         unsigned char temp = 0;
    / x$ I# L+ O" S& G+ m( a/ z" Q
  230.         CE_Low();
    , o: Q5 ^) M5 W# w
  231.     while (temp == 0x00)        /* waste time until not busy */8 v7 o; y$ a) k5 o6 Q4 }/ [5 P4 G
  232.                 temp = SO;' |2 t7 q" ~# P+ x
  233.         CE_High();1 r2 b4 V' G( ^5 V" H8 I  Y
  234. }
    8 ]8 H4 g" |9 e( R2 a
  235. ( M& Q' e/ ~) ^# Y
  236. /************************************************************************/
    / H- _9 [9 X' O% g1 ^7 r- B
  237. /* PROCEDURE: CE_High                                                                                                        */
    / l7 `! T2 X' _8 S! J
  238. /*                                                                                                                                                */
    % U3 K9 p8 E8 m: E, ~
  239. /* This procedure set CE = High.                                                                                */; V2 f# v, K8 s4 V$ R' g6 u' X
  240. /*                                                                                                                                                */& ?- U) I9 E' p) Y/ I# y
  241. /* Input:                                                                                                                                */2 |/ \' ?5 Q5 N# B3 p% v6 S
  242. /*                None                                                                                                                        */
    # x4 c6 S4 L  f+ \$ h7 E4 S9 c
  243. /*                                                                                                                                                */- N4 |6 _, M3 Q8 I0 G# }
  244. /* Output:                                                                                                                                */
    . A* {; l, ^" |# x4 d& y! F
  245. /*                CE                                                                                                                                */
    - X3 L4 t6 H/ K$ L: |, d  a$ z
  246. /*                                                                                                                                                */; V* f% G3 u+ W+ |& p. F
  247. /************************************************************************/' H$ U8 x4 ]5 O3 N" k  u7 h
  248. void CE_High()
    ; w2 V1 C! Z; ~) A. d8 |
  249. {. i+ f5 K% \- @
  250.         CE = 1;                                /* set CE high */- q+ K4 B4 f& P; u) @) g7 a7 v
  251. }0 z$ L9 U$ N7 s4 F
  252. + C  u- H+ Y7 Q9 e/ B% D
  253. /************************************************************************/
    + H2 O6 l8 Y2 C- R
  254. /* PROCEDURE: CE_Low                                                                                                        */
    5 D& G8 e1 {" j9 ^
  255. /*                                                                                                                                                */
    ) c1 A2 e# j% f9 v
  256. /* This procedure drives the CE of the device to low.                                          */4 d; B% n* K6 H: q# ^+ ~2 j
  257. /*                                                                                                                                                */, j4 ?- v- O( }( `' L
  258. /* Input:                                                                                                                                */6 f0 i" _! F* ]" O( N
  259. /*                None                                                                                                                        */2 m( B8 ~/ G+ W. ?4 c4 ?6 x
  260. /*                                                                                                                                                */
    ! R5 D* J  D. I% e/ V
  261. /* Output:                                                                                                                                */
    & U" y& `$ H4 E1 k
  262. /*                CE                                                                                                                                */
      S7 G7 @+ `9 ^$ d* L, I, g
  263. /*                                                                                                                                                */6 J1 O! \+ g: C" h* Z# Z, J6 h
  264. /************************************************************************/! k5 _' M! ^1 F1 d3 @
  265. void CE_Low()
    * @3 j/ D' V3 o; A+ L/ }8 R. a' ?% A
  266. {       
    # e; C, T* w) M3 ?9 `, K
  267.         CE = 0;                                /* clear CE low */
    & Y6 _3 |2 \! d& W  @3 y* v
  268. }
    & _( T7 C; ?: f

  269. , i) q4 S# r9 P4 u: U6 Y
  270. /************************************************************************/
    * O6 w; {* n2 R. b, {9 g
  271. /* PROCEDURE: Hold()                                                                                                        */) f: r, ~! `' j, R/ H; v
  272. /*                                                                                                                                                */" x+ k/ \  A) @* @4 u( Q/ M
  273. /* This procedure clears the Hold pin to low.                                                        */
    9 }, o# z3 }* ~, s" h
  274. /*                                                                                                                                                */$ P$ j+ C1 Y" ]& Z4 r8 [
  275. /* Input:                                                                                                                                */  o; I; \) m$ i5 }- j
  276. /*                None                                                                                                                        */
    & `% ^  s1 {' ?
  277. /*                                                                                                                                                */9 Z4 l7 }. ~. D: F5 \7 G& }
  278. /* Output:                                                                                                                                */
    5 B/ d5 l; S; b/ x2 P; \* o4 T
  279. /*                Hold                                                                                                                        */
    1 n/ h  I5 L1 Y) B0 p
  280. /************************************************************************/0 ^" _3 e5 Q0 s4 `! [
  281. void Hold_Low()
    6 f  n  r" D) d) g4 \7 V2 L3 p
  282. {
    ( V1 S' X* U% D( f/ R8 T& b
  283.         Hold = 0;                        /* clear Hold pin */; t- i5 P+ ]# ^& c
  284. }: D$ @- u  I. `. v/ W# X+ N9 Z

  285. 6 u/ L, P1 i7 ?- @
  286. /************************************************************************/
    9 v7 {) F: U  a$ D+ C
  287. /* PROCEDURE: Unhold()                                                                                                        */6 @+ I6 I6 }9 |6 p/ O8 \
  288. /*                                                                                                                                                */) Y0 h. x0 K- j! R
  289. /* This procedure sets the Hold pin to high.                                                        */
    % U6 F6 o& l8 p4 X
  290. /*                                                                                                                                                */2 p' N- A2 p2 l. ]
  291. /* Input:                                                                                                                                */
    / y" c9 E2 N% M% ]+ ~
  292. /*                None                                                                                                                        */
      z  \; q3 H9 D  }* [" {0 A5 f
  293. /*                                                                                                                                                */
    * X! e  p6 o% l( L' q
  294. /* Output:                                                                                                                                */  ?! U8 d/ F# C2 t0 h
  295. /*                Hold                                                                                                                        */
    4 k; b+ f4 c5 X% ?! ~* @+ P
  296. /************************************************************************/& v6 \# S- h+ v9 q' W* ~: E9 i* Z
  297. void Unhold()
    ; |9 ]3 T9 G8 |( F9 Z  K8 {, k7 H
  298. {
    8 N2 R: q' F# [! K: d
  299.         Hold = 1;                        /* set Hold pin */3 R3 ^- p) P) M. A1 ^9 e- o* m
  300. }6 h. ?2 B  L+ O
  301. 6 j; N# e# Q) W
  302. /************************************************************************/
    & y, ^/ p! o1 I/ ?
  303. /* PROCEDURE: WP()                                                                                                                */
    ! l9 D3 d& R" J( y+ s% `* Q! p
  304. /*                                                                                                                                                */$ J4 S2 k* P5 c$ V& }+ q8 z
  305. /* This procedure clears the WP pin to low.                                                                */
    % M  n4 W- Q" V7 H! A
  306. /*                                                                                                                                                */
    $ C5 n* ]9 A* t, V  z7 ?% L7 {
  307. /* Input:                                                                                                                                */
    . f9 o6 U% [8 J: t. U
  308. /*                None                                                                                                                        */
    ; Y7 N# Q; T1 P9 j! o; I
  309. /*                                                                                                                                                */
    & A5 g: C4 [- O9 @1 a* ^
  310. /* Output:                                                                                                                                */3 V! Q7 N+ w+ l; A* a7 Y
  311. /*                WP                                                                                                                                */
    , f6 U* b* `9 I8 I+ P
  312. /************************************************************************/& ~6 w7 i8 L/ H. {+ S/ ]* N
  313. void WP_Low()
    ! P/ s4 H& m# Z" U, g! g2 t! ^8 m
  314. {  A+ D3 ?* P3 }5 I) x+ ], I2 b
  315.         WP = 0;                                /* clear WP pin */6 Y, l$ y* J% [! o2 ?8 I, w
  316. }* Q/ [4 U) e( V5 Z6 q
  317. & h, i9 p8 D3 U
  318. /************************************************************************/4 p8 d0 n3 `7 C0 U& O1 Q
  319. /* PROCEDURE: UnWP()                                                                                                        */' d$ P9 c3 T, ~; F0 P& v
  320. /*                                                                                                                                                */$ I# f/ o. X3 @8 c* E& d9 A, x
  321. /* This procedure sets the WP pin to high.                                                                */
    ! x+ M! Y/ u- g8 J. W- \
  322. /*                                                                                                                                                */
    ' E. F7 \& q& ^$ p
  323. /* Input:                                                                                                                                */
    4 O# j0 b9 [7 X6 g. L. L' L! c$ I
  324. /*                None                                                                                                                        */
    ' y$ e$ S) h7 k" [
  325. /*                                                                                                                                                */
    9 q, ^+ L& O5 x3 P1 J% k' c
  326. /* Output:                                                                                                                                */3 q4 Y5 P: v# d/ i
  327. /*                WP                                                                                                                                */0 i5 @8 G" Q( y( F+ ~6 v" \
  328. /************************************************************************/
    & Z8 n- M6 G/ ^& s9 ]9 X3 h. h- ~
  329. void UnWP()
    . M( a  z* E  {, }
  330. {
    % f6 Z: e1 u6 ]
  331.         WP = 1;                                /* set WP pin */' W1 z$ w4 V( B) m# Y
  332. }1 F" k2 p% s' b, k
  333. 9 k# g! @1 U; P- i, y
  334. /************************************************************************/0 G: o" Z9 p, G' y8 |# E" R
  335. /* PROCEDURE: Read_Status_Register                                                                                */& s/ k; l% `6 r" U. p2 c+ S
  336. /*                                                                                                                                                */  g1 x- W5 Q; T# J) Y( }! z
  337. /* This procedure read the status register and returns the byte.                */
    ' Q$ ~- t7 a5 p: T% a/ }
  338. /*                                                                                                                                                */
    9 I) v: ~! f1 e) J* O5 e2 Y
  339. /* Input:                                                                                                                                */
    " j3 {9 Q: R/ |/ L0 ~, @
  340. /*                None                                                                                                                        */
    7 x( g; a7 X* @. n& h7 T  Q& \( o8 _0 r
  341. /*                                                                                                                                                */2 |2 U& J! f2 _, |3 d1 t
  342. /* Returns:                                                                                                                                */
    * a/ Q5 E9 a2 b# Q; P% d/ |5 e
  343. /*                byte                                                                                                                        */
    ' ]) k( I2 P( y, t8 b1 I1 P
  344. /************************************************************************/
    4 m# X2 r0 ^7 V; _& C, Z# |2 e
  345. unsigned char Read_Status_Register()
    % C9 x" D( a$ y* y* }
  346. {1 i" K" A6 `+ R' }: O4 L7 S
  347.         unsigned char byte = 0;9 g$ d2 g  U- n/ p
  348.         CE_Low();                                /* enable device */
    $ ]  I# e. `6 B9 a0 L8 l/ k/ k
  349.         Send_Byte(0x05);                /* send RDSR command */$ J$ Q0 \% J* _* l4 i6 Q
  350.         byte = Get_Byte();                /* receive byte */5 `0 M) P6 y" b/ _. _8 O2 C. x
  351.         CE_High();                                /* disable device */
    + ^, i6 K; q# P7 W7 n+ e8 _
  352.         return byte;3 O+ X( f6 x7 W/ C# Y. \% i+ M& z
  353. }
    9 r  x, c6 A& ~+ P/ g

  354. 2 x" H: S6 ?' q" z. e6 x
  355. /************************************************************************/
    4 p& b- D4 ~* U; ~/ ?* o( x8 C
  356. /* PROCEDURE: EWSR                                                                                                                */& r# d; [' F$ l
  357. /*                                                                                                                                                */
    9 t; d  ^  B- s. h4 a
  358. /* This procedure Enables Write Status Register.                                                  */
    $ g% v6 r( L: B+ |* o
  359. /*                                                                                                                                                */
    5 k. u  E, H5 E) B# K9 u+ [
  360. /* Input:                                                                                                                                */
    - @% R3 r4 J1 k$ A. O* c7 [$ w" F$ v
  361. /*                None                                                                                                                        */2 v, c. v$ v1 ^  V$ V/ a
  362. /*                                                                                                                                                */
    ; ?. M5 L5 z/ M1 ?9 p; F% }3 q
  363. /* Returns:                                                                                                                                */! ]$ T" B$ h5 A, [) r6 _% r
  364. /*                Nothing                                                                                                                        */
    % _8 b" V) X* C& R# T& g1 J) R
  365. /************************************************************************/
    & b" ^  N8 X" B% s6 p
  366. void EWSR()& q1 g4 c- K* |% l1 `0 ^
  367. {
    9 @1 G) d6 @# I: a
  368.         CE_Low();                                /* enable device */7 r- N! B% Y$ s5 t3 a/ H. A; e
  369.         Send_Byte(0x50);                /* enable writing to the status register */' k5 z, W9 r" [7 Q
  370.         CE_High();                                /* disable device */3 [, e4 |: p+ Y9 l: k
  371. }
    1 m9 C+ r7 g  H( J5 m

  372. 3 J  e* {+ j: v4 M  `
  373. /************************************************************************/7 e1 k* Y4 E8 h2 [# {% @; ]
  374. /* PROCEDURE: WRSR                                                                                                                */+ `3 h- ?8 Z$ i  n% H
  375. /*                                                                                                                                                */
    6 u( T8 U. W( S, @. j; M
  376. /* This procedure writes a byte to the Status Register.                                        */( n+ N+ G+ [* J2 x/ k
  377. /*                                                                                                                                                */
    $ `7 [+ p! ]/ Y- g1 \
  378. /* Input:                                                                                                                                */
    + B* k: }/ p$ d
  379. /*                byte                                                                                                                        */5 `& l% E# a4 d0 _) @, Q
  380. /*                                                                                                                                                */) `9 \$ ?- F3 [" U6 h) P8 d
  381. /* Returns:                                                                                                                                */
    * u/ m0 B  C, f
  382. /*                Nothing                                                                                                                        */
    % e' U* d6 _- M
  383. /************************************************************************/
    8 x4 B/ j% H, L* R8 h8 d  t
  384. void WRSR(byte)  `$ h" \$ a" D0 ^0 t, `3 d. k
  385. {
    # O/ F8 l; w9 L7 b
  386.         CE_Low();                                /* enable device */
    9 \1 S  m, H- A0 }1 P  q3 @
  387.         Send_Byte(0x01);                /* select write to status register */
    1 `$ W, r: i" a1 a/ O/ d
  388.         Send_Byte(byte);                /* data that will change the status of BPx & T/ }( a1 B+ L+ ?
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    * n5 O% l  }2 t7 [7 i
  390.         CE_High();                                /* disable the device */
    : d2 p9 m7 t& N# D, ^' v5 g
  391. }; Y) i$ I6 i+ V* O3 S1 U4 v
  392. 6 x5 N- o  G' U' R% b7 [; Q& ^4 X8 \4 V2 U7 }
  393. /************************************************************************/
    ( c! s# R& t8 f# o5 A
  394. /* PROCEDURE: WREN                                                                                                                */
    8 Q4 O0 T1 Q: b6 M& i+ p6 b
  395. /*                                                                                                                                                */( F1 x" D5 m2 L7 W. u3 E
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ; A' a$ x8 g/ O9 D: u8 ]
  397. /* to Enables Write Status Register.                                                                        */  a; q- d7 O1 [' ~
  398. /*                                                                                                                                                */; t! P( ^1 u) @6 R' h% X
  399. /* Input:                                                                                                                                */
    . v) U0 k  V0 W4 A; d9 _# J$ k
  400. /*                None                                                                                                                        *// [7 E" N2 @9 }$ N9 [* E
  401. /*                                                                                                                                                */( H4 O5 C, n& M
  402. /* Returns:                                                                                                                                */
    * X: e9 i1 h9 y; }6 L
  403. /*                Nothing                                                                                                                        */- p0 e* c+ f- c$ y* v
  404. /************************************************************************/
    8 n' \& F3 R  H& s! Z% ]( A
  405. void WREN()
    & b* ?' F) p7 }9 S
  406. {: B5 V$ Z% Z% X1 P% \2 C9 H
  407.         CE_Low();                                /* enable device */3 ~& u8 f- t- \4 V* K8 I
  408.         Send_Byte(0x06);                /* send WREN command */# M2 x1 X. Z& f" }2 h3 q
  409.         CE_High();                                /* disable device */
    % X1 P" u6 O& W1 n: v% u
  410. }
    9 C) [1 V5 n& y5 R; o0 k) F

  411. , T5 k7 \" q. ?. O% U1 \
  412. /************************************************************************/
    ' y& Y" b5 t: V" ^
  413. /* PROCEDURE: WRDI                                                                                                                */
    0 I& C& Z! X; G
  414. /*                                                                                                                                                */
    $ a, f% o( c% s
  415. /* This procedure disables the Write Enable Latch.                                                */
    6 y/ r. E/ j& d
  416. /*                                                                                                                                                */
    + ?, R" w7 t& m
  417. /* Input:                                                                                                                                */
    % p' r* l0 c0 x6 I/ }
  418. /*                None                                                                                                                        */
    3 D( Y* ]; e) o- G2 b/ W4 M5 b
  419. /*                                                                                                                                                */
    2 c+ }6 m. d" X: m
  420. /* Returns:                                                                                                                                */% @0 p- k  j. @- W
  421. /*                Nothing                                                                                                                        */
    ; P! A3 @6 U. N4 h) @
  422. /************************************************************************/
    2 ]3 x6 F/ T1 o& j- V' f( T
  423. void WRDI()
    7 Z$ U' V- }3 r) z' H! i
  424. {6 J/ i3 p2 J' J' t1 }
  425.         CE_Low();                                /* enable device */
    , d" n3 }, ^2 \# j
  426.         Send_Byte(0x04);                /* send WRDI command */4 G4 V7 A2 r# j: e. o1 o
  427.         CE_High();                                /* disable device */
    6 {9 s: |: {* m; B
  428. }9 T' t0 p- @" U0 D( h

  429. 8 ]9 O) W' ?3 z: w! ~
  430. /************************************************************************/+ M. [8 ]3 K+ k% f. t( t# d
  431. /* PROCEDURE: EBSY                                                                                                                */4 f: U, M1 r" L2 F# |
  432. /*                                                                                                                                                */) w7 ~$ Y0 V" e6 ?% U7 Q6 o% n7 f4 U. _
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */* D0 S* `; s! T8 n6 x4 ?
  434. /* programming.                                                                                                                        */
    0 W# M5 U' P0 q. _7 M
  435. /*                                                                                                                                                */% M4 `& Q' `; t9 A$ F
  436. /* Input:                                                                                                                                */. {  a' W! ~' g- S: l& P
  437. /*                None                                                                                                                        */: ?: g$ }1 L2 {( @( |6 h
  438. /*                                                                                                                                                */' b6 u7 m+ K9 Y6 {/ W3 v( D9 ^8 ~8 y
  439. /* Returns:                                                                                                                                */
    ) x' p( X0 W; K, L, D- |3 {
  440. /*                Nothing                                                                                                                        */2 W  m6 ?# k3 H# Y& ?3 S' N
  441. /************************************************************************/
    " }% g) ^* [) y5 c. K6 \5 ~/ f" {
  442. void EBSY()2 |1 J; `, c7 M8 T
  443. {
    : B8 A7 f$ I7 z0 j! M3 ]
  444.         CE_Low();                                /* enable device */( a5 t6 P8 @8 s$ J. Q
  445.         Send_Byte(0x70);                /* send EBSY command */: T! {0 N0 v8 Y! M+ S# W
  446.         CE_High();                                /* disable device */
    # X  ?: x5 p& l5 r# S
  447. }3 u4 O# Y" \1 U
  448. - w1 Z: a" d# k, T/ p
  449. /************************************************************************/
    2 M+ m7 O: j! `8 |' _1 y# C
  450. /* PROCEDURE: DBSY                                                                                                                */! |+ \+ h% P* e
  451. /*                                                                                                                                                */
    $ m/ N9 P2 I/ V. h
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */9 ^1 U0 Q) Z& R
  453. /* programming.                                                                                                                        */
    " k% H, P3 r2 |4 p2 h3 }" a' [
  454. /*                                                                                                                                                */
    : E4 q6 d! s% i+ d; w* f. }+ |' e1 `
  455. /* Input:                                                                                                                                */4 C6 m! a. z' k4 h7 e3 j
  456. /*                None                                                                                                                        */
    + a5 n* C- d- o
  457. /*                                                                                                                                                */: ^* M) u( ^9 G( `1 g) f2 A5 H
  458. /* Returns:                                                                                                                                */' i6 u3 C+ g* \2 Y& Y
  459. /*                Nothing                                                                                                                        */
    5 d! A" O5 e, M/ o  ]# B
  460. /************************************************************************/* |% ~5 }7 {: W1 l
  461. void DBSY(); u. ^- L) y0 d
  462. {: z, o) f0 H* N3 p: q6 v: l( J, B
  463.         CE_Low();                                /* enable device */
    9 {% E. T% o  c; y  ~) J' D
  464.         Send_Byte(0x80);                /* send DBSY command *// [# w2 D* a2 u- n, V: N: L2 V0 m
  465.         CE_High();                                /* disable device */5 g% E$ F5 m: o1 _) `6 K+ {2 y
  466. }
    5 m6 d" P8 J  c3 c% m
  467. 0 ?& ~, x) h( v! B3 Q
  468. /************************************************************************/
    0 Z" t, I2 O2 ?
  469. /* PROCEDURE: Read_ID                                                                                                        */
    8 |$ P! _1 Z/ B& F/ E; ], L0 B
  470. /*                                                                                                                                                */, A4 o# b3 w1 N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ' I4 z# j4 E& J
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */- e: u) \& P3 Z1 P2 P
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ( y" p" a" J, f5 h8 s  ?* y3 w# j
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
      l4 r2 s! n  w. ^2 f
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    * E  O  e9 t- q1 u7 ]
  476. /* variable byte.                                                                                                                */
    . ^6 Q- P1 Q* ~6 G: p* M
  477. /*                                                                                                                                                */( ?5 s5 H5 }% S9 Y
  478. /* Input:                                                                                                                                */
    ( _/ ^9 a; L& h' U4 x2 d
  479. /*                ID_addr                                                                                                                        */
    * n, `! S1 Z* `3 C9 ^
  480. /*                                                                                                                                                */
    " {+ L3 I7 q7 Y7 ^
  481. /* Returns:                                                                                                                                */
    * ?8 p* Q+ n7 G1 V
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        *// U7 H/ Q3 T1 X* K! N2 y% L
  483. /*                                                                                                                                                */, M7 c) A6 l" Y
  484. /************************************************************************/
    $ Z% g7 M/ n  U; ^3 q6 e
  485. unsigned char Read_ID(ID_addr)& w2 ]7 w. v  X3 Z# @$ t
  486. {4 l' e! ]) L7 e( t) u
  487.         unsigned char byte;# F9 N: o2 n: _  k1 {' S
  488.         CE_Low();                                /* enable device */
    8 d; Y8 f. q; h7 S$ e- j7 O
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */# W$ v, ?4 H1 c) [2 T- R
  490.     Send_Byte(0x00);                /* send address */
    3 d: M+ P  H' _  z6 y# P: d: ^2 l& U
  491.         Send_Byte(0x00);                /* send address */
    , J) ]3 V# Y) g' H
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    / x0 [9 a! e0 O) O
  493.         byte = Get_Byte();                /* receive byte */% X/ `/ t; _2 @, M
  494.         CE_High();                                /* disable device */6 K2 A0 X* V; H& t: X4 T4 ~/ K! P' [
  495.         return byte;
    + |% Y1 L+ K( M1 ^  t6 M
  496. }" r" f# s" I+ m' }5 S6 y$ R, u% ^

  497. 0 v; [6 \0 u1 ~0 a& V, B1 S
  498. /************************************************************************/
    " C% z+ R/ R" z( I
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    0 Q& m, v1 ^. f& s2 S6 X
  500. /*                                                                                                                                                */% A& D0 \2 b1 Q( x, I8 S
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */) i, I9 b: e# B
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */) X) x% C# Z0 _1 l$ M* |  @
  503. /* Please see the product datasheet for details.                                                  */
    2 f3 U& X4 ?, Z# D2 b1 E9 _
  504. /*                                                                                                                                                */
    # l. j% |& A2 x
  505. /* Input:                                                                                                                                */
    $ D, U2 {: o& l: P
  506. /*                None                                                                                                                        */
    9 s1 }! |  Y& P, W# O
  507. /*                                                                                                                                                */
    ) Q1 k* D5 D$ J) K+ {; w! s& C
  508. /* Returns:                                                                                                                                */; H) r3 b0 E& @$ Z3 J
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    6 P! y/ `. }7 Q, @* x" c
  510. /*                 and Device ID (8Eh)                                                                                        */
    . D7 e$ l- f5 p: c) ~* i3 e
  511. /*                                                                                                                                                */- J0 @. g; b0 h6 ^* s4 i6 ^! d
  512. /************************************************************************/
    * W! b- [$ T7 h* z
  513. unsigned long Jedec_ID_Read() . t5 X# r! v& \7 w
  514. {0 n0 \; C6 u8 F9 M6 _: s( d
  515.         unsigned long temp;
    8 ^% e9 s3 Y6 p. b1 J9 [( m
  516.        
    9 k. D0 `% S& M5 i3 u  f
  517.         temp = 0;
    2 ~, m) E* B' P  @' X) q. _0 q
  518. $ R& S6 j& F% k2 ^" m/ x
  519.         CE_Low();                                        /* enable device */4 `' i5 E! C) C) H
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */; L5 t9 l  u& z$ O0 U! A) W2 n
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    . u  |2 E. g( X
  522.         temp = (temp | Get_Byte()) << 8;        : d, i) W$ q$ b( ~% T# z
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    3 H% O4 _. V, h) f$ C4 {
  524.         CE_High();                                                        /* disable device */  e) E3 p" t: `5 i, C* B

  525. + @: {! M4 E- V$ m
  526.         return temp;
    # {, |$ i- M3 G  Y5 K5 z
  527. }
    ( f9 A6 x5 J1 ~* M1 I+ p

  528. & b. A9 k% j" B9 @# y; Y
  529. /************************************************************************/: a1 ^7 M7 l/ K0 N# C
  530. /* PROCEDURE:        Read                                                                                                        */
    ' `. r4 W0 h  O5 k# F+ j5 _
  531. /*                                                                                                                                                */                2 K& Y) G5 F& ~7 {" A' o
  532. /* This procedure reads one address of the device.  It will return the         */
    , Y! L! J, X  i  O" @
  533. /* byte read in variable byte.                                                                                        */- F. c3 R5 P; C5 m  h
  534. /*                                                                                                                                                */: F% h, Q' U& {8 U; k' h3 I
  535. /*                                                                                                                                                */5 D, Q- P: p$ i6 V6 O& w
  536. /*                                                                                                                                                */
    , f/ g4 x" U, u+ j
  537. /* Input:                                                                                                                                */
    & K3 D+ N, [, I* m/ z( I
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% R. D6 K* ^) [6 l
  539. /*                                                                                                                                      */
    1 d  v/ R' D, l! X0 H" v' e; }
  540. /*                                                                                                                                                */
    1 E  Y5 ^, W0 S* t. o) ^* X$ Y7 k3 N
  541. /* Returns:                                                                                                                                */, c; k% O6 b- j% y
  542. /*                byte                                                                                                                        */) p- o  x. J  V2 |; }. N6 A" |& V' c
  543. /*                                                                                                                                                */+ g& R" X. x% L4 Z3 p7 p
  544. /************************************************************************/
    & B" a9 \* j" \* r2 i
  545. unsigned char Read(unsigned long Dst)
    3 x. w. b7 F; i( v7 o9 `
  546. {
    , n1 j3 `" K! J3 ~6 f# G  C
  547.         unsigned char byte = 0;       
    . ~+ D0 Z, r9 X; S0 N! [

  548. + Z* @* ~- w4 k& A! y
  549.         CE_Low();                                /* enable device */
      ~* x; @4 }# T1 g: t; e7 N6 J
  550.         Send_Byte(0x03);                 /* read command */
    - a# n6 w/ _$ ~+ j7 a/ q
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */% G7 l( D9 R* F8 W  X
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 _' S- s% x9 D4 T
  553.         Send_Byte(Dst & 0xFF);) W3 `# U: j7 j/ {$ O
  554.         byte = Get_Byte();/ S0 Q& m0 ~& I  T2 P+ b
  555.         CE_High();                                /* disable device */* u8 ]7 ^$ t* c6 v5 t3 Q  u5 r
  556.         return byte;                        /* return one byte read */- J: S4 a$ S/ v, o2 t
  557. }
    ; }6 t& J( c7 E8 k
  558. % b7 l( M0 g) S# G/ j' `
  559. /************************************************************************/
    2 Q' _: M  t: U8 m. s) T' [) K  p
  560. /* PROCEDURE:        Read_Cont                                                                                                */% I; e  \0 T* J8 e* ?4 d7 Q
  561. /*                                                                                                                                                */               
    * i4 P8 Y& R* P4 R# P3 ]
  562. /* This procedure reads multiple addresses of the device and stores                */+ Z% u2 y& e; ~& s
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    - e- u* p5 h) D! l/ C+ ?3 j
  564. /*                                                                                                                                                */2 R8 Q1 E0 E# {2 g
  565. /* Input:                                                                                                                                */4 R, A& J& Z: Z6 }* z6 k
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 n, ]8 v# l* o1 D1 K
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    5 m9 X! \, M, I- b: e* g' S) W* S
  568. /*                                                                                                                                                */* V" N6 Q' k; J. n) K; Y+ U
  569. /* Returns:                                                                                                                                */
    , _. m8 q- P; k; L2 m* o
  570. /*                Nothing                                                                                                                        */
    2 o. T0 M! Z  n
  571. /*                                                                                                                                                */
    ! {2 N% k$ F0 G, p  p/ `0 Z
  572. /************************************************************************/
    4 c, D6 a& Q2 |
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)9 b) ]' a! z* `
  574. {
    % `* J" R: k+ F+ W% @7 q, r  S
  575.         unsigned long i = 0;
    4 I, A: h4 J( }5 _* A. n
  576.         CE_Low();                                        /* enable device */
    + c4 n$ E! v7 ~9 e$ c
  577.         Send_Byte(0x03);                         /* read command */  O1 A/ G8 p" x7 Y9 ?* ]7 a; F0 |" B
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 f' L9 @' D  J  q+ r
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % ]+ K* c3 V: ~6 z
  580.         Send_Byte(Dst & 0xFF);# E" [( D2 v2 C) e9 e. ^9 ]
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */7 h5 {; D# u3 O1 s6 n0 `6 v% K* Y
  582.         {0 N3 y% P' m9 x. N# J. c2 }! e
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ) Y' K3 [$ E8 P: s% i
  584.         }2 n# [& N0 W7 M- _
  585.         CE_High();                                        /* disable device */
    1 D# {* n: @  \9 A! D& L; E1 a
  586. % P! M/ o' q5 c2 ]- Y/ h9 c/ k
  587. }
    , R3 p. a6 D; \! N- X+ k. C! N3 y
  588. % }9 ^" i8 F6 t6 g9 w% s/ ~6 ~
  589. /************************************************************************/" P/ j& i/ J( E0 M: W
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    9 A4 h$ C! V% m; ?0 _; u
  591. /*                                                                                                                                                */                1 O! H  N3 ~5 @8 n2 S0 x6 B; f
  592. /* This procedure reads one address of the device.  It will return the         */, t, f, o  M4 l; m% w
  593. /* byte read in variable byte.                                                                                        */* |, m% x9 p7 v7 t. a
  594. /*                                                                                                                                                */1 B/ y% x6 x  p& _4 E  m4 D  R
  595. /*                                                                                                                                                */
    % b  g& s: Y* h+ v
  596. /*                                                                                                                                                */
    . |, ?8 W/ H# G5 U5 p$ x
  597. /* Input:                                                                                                                                */
    3 w+ V1 X% x+ D6 p" J- O; P$ v/ ~
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    % f5 O* a) p  [' k$ d; B
  599. /*                                                                                                                                      */
    ' t) K8 Q6 a+ @4 J7 V; ^. x
  600. /*                                                                                                                                                */
    % E7 Q) s# a0 y2 K" X
  601. /* Returns:                                                                                                                                */0 H. Y8 x- e1 x& l  }
  602. /*                byte                                                                                                                        */
    & n: Y# T$ _& g! O" V
  603. /*                                                                                                                                                */
    : r8 ~" h; d' C2 q4 I& z% q
  604. /************************************************************************/# Y0 r( M3 p. d6 v/ C! _
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    ( A: d/ w' S, N
  606. {, I$ V, M+ J! P9 n1 k4 x3 t
  607.         unsigned char byte = 0;        9 N) u, t, x! x# M. _. N
  608. ( j7 B; G; f/ T
  609.         CE_Low();                                /* enable device */; a# x1 r, x5 U9 F# [, E' @
  610.         Send_Byte(0x0B);                 /* read command */5 d/ L3 Z- k. B- |
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */% t& X  h& D1 m- n' U$ D& d0 h* n
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + ~, w* N, s- M7 V. J6 H
  613.         Send_Byte(Dst & 0xFF);5 d6 j" P1 C7 X6 M3 I! A
  614.         Send_Byte(0xFF);                /*dummy byte*/& N7 W& G7 _. d/ x7 A* O3 j) u
  615.         byte = Get_Byte();# a+ a' X( q9 a
  616.         CE_High();                                /* disable device */1 a5 n$ e5 \( J" ?' u  ~
  617.         return byte;                        /* return one byte read */6 D4 D  B* D& n8 c6 m' O
  618. }
    7 R; h0 a2 `/ m4 Y. x% I
  619. . d5 Y/ l, ]& g
  620. /************************************************************************/3 @9 }$ @, v& M
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */' G! A" I1 F# v  Z: [/ ?# Z
  622. /*                                                                                                                                                */                3 [& [9 |5 }: X7 n+ X8 r8 o0 N
  623. /* This procedure reads multiple addresses of the device and stores                */
    4 |& R2 D) d6 ?5 {* i' x) p) ]
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    + ]) Z& X6 l( W, m5 w  y
  625. /*                                                                                                                                                */  \1 k: e" |& w' v+ @* ~
  626. /* Input:                                                                                                                                *// y% m, I, F  S% K7 f2 ]0 v6 x% V
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ y9 P2 i, x, H4 ~5 j3 ?* b
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    , D; n2 _( k: j% u
  629. /*                                                                                                                                                */% U5 P% E1 d3 ^0 e$ j8 i: g: Z! p
  630. /* Returns:                                                                                                                                */
    8 }& L4 a$ e+ ?1 K& c
  631. /*                Nothing                                                                                                                        */, Y/ b) v. k& n
  632. /*                                                                                                                                                */
    ; q7 J% \5 \: ]9 ?# \
  633. /************************************************************************/3 J( `' n1 E& W( i
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)& X. {2 v0 L7 a; c$ [( Y# ~& i
  635. {% I1 ~7 `/ @! L$ ?, s
  636.         unsigned long i = 0;
    ; J( r& A' k$ J" K  W/ r
  637.         CE_Low();                                        /* enable device */
    # o0 i/ b; F1 E; Y' Y) q. z
  638.         Send_Byte(0x0B);                         /* read command */# g9 J$ h) j+ f  ^* S6 I2 r
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 a% {: Z; `. O  q; A1 k/ w
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 |4 k+ F' _1 k
  641.         Send_Byte(Dst & 0xFF);
    9 x1 Y1 o' B$ t/ n. C
  642.         Send_Byte(0xFF);                        /*dummy byte*/8 B( ?  D  l, \( S- d# j1 ^/ X
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    & l; ~+ y4 ]( D7 n& [9 n& l+ [2 ?
  644.         {
    ) |  F" `* _. l# B% v8 c, t, v
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */8 `' m- m$ z) }; a' z
  646.         }
    7 E3 Y3 o# B- j; q3 @3 b
  647.         CE_High();                                /* disable device */
    ) P) \4 `1 I( d
  648. }
    6 `' i) s# S9 q% q! F- Y1 y; q" W
  649. , I9 L, n7 k+ _1 {4 I# U1 F! S  l
  650. /************************************************************************/$ Z9 _; ?$ R2 [+ G' e5 {
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    ) s# c  j; B' e( i- J
  652. /*                                                                                                                                                */
    ) S. @  f! `6 B
  653. /* This procedure programs one address of the device.                                        */% T8 d2 I* S, `6 _
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    & L% Y& `9 [1 s8 k, ]. M" m
  655. /* block protected.                                                                                                                */. O9 A' X! ], }  H- R
  656. /*                                                                                                                                                */
    " I+ d4 O8 {$ X7 [/ M
  657. /*                                                                                                                                                */
    $ T/ \/ |$ {- t) o
  658. /*                                                                                                                                                */
    0 q$ P0 H; {% v6 L6 _; |& ~
  659. /* Input:                                                                                                                                */  S0 @8 B; \* C7 N) Z# [
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) G( [+ a% g3 \, h2 R+ K4 I
  661. /*                byte:                byte to be programmed                                                                */8 W- @* w1 |6 Z' ^3 L" [, {8 T
  662. /*                                                                                                                                      */, }% x1 p8 P( [6 _% }; d
  663. /*                                                                                                                                                */' P9 E3 K2 ?. G
  664. /* Returns:                                                                                                                                */. F+ y1 k6 e5 k: K0 {! k' {
  665. /*                Nothing                                                                                                                        */
    ! y+ j9 G8 d1 g, n3 n
  666. /*                                                                                                                                                */- z2 I0 }& h  y# v% d
  667. /************************************************************************/; Y* f5 r( g. a+ `! z3 o
  668. void Byte_Program(unsigned long Dst, unsigned char byte)6 |0 m1 n& H0 S7 [5 @* F
  669. {
    1 K5 N' X5 h  w/ o
  670.         CE_Low();                                        /* enable device */
    # z! N1 W+ d6 n
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    % `! n9 t! h) ~
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ) ?; y* F0 P, i& K; l8 M
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));" i8 Y6 `1 U9 T; G0 K. v
  674.         Send_Byte(Dst & 0xFF);
    7 `4 |- |! C( T5 v% X1 ]. p# g
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    2 N8 ?1 }' s: F: m& S1 Y
  676.         CE_High();                                        /* disable device */
    # Y! E. l( @; X* d3 n9 }3 {* C
  677. }
    6 \( c, i  {* q4 J& s: a+ S% R
  678. 0 G8 `1 M4 g5 J
  679. /************************************************************************/' U' m; ?, N% T( s% f+ M5 Y, j
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */" e% A$ ^4 y: [& T5 D) \
  681. /*                                                                                                                                                */. x7 c' W, w: O0 u" G7 j1 v
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/0 K1 M0 w  \8 y  l2 p
  683. /* the device:  1st data byte will be programmed into the initial                 */; p4 [6 f3 c5 I' E5 |# Z4 W" l; {
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    5 ]# G6 Z2 h( ?0 c' `: j
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ' \" j" L- b& W' G% b9 o
  686. /* is used to to start the AAI process.  It should be followed by                 */! _% Q8 O7 V3 a
  687. /* Auto_Add_IncB.                                                                                                                */) W0 \% T6 ?; t2 Y, Z
  688. /* Assumption:  Address being programmed is already erased and is NOT        */! P  {- T9 o* P$ y  W6 Y% s
  689. /*                                block protected.                                                                                */
    9 D* `6 p  X& g* T  j5 @4 A3 A
  690. /*                                                                                                                                                */
    * l1 ?4 Q4 t8 T3 f( S9 |
  691. /*                                                                                                                                                */
    ) r* M' F( v4 O) D, t- Y
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    ) r' C8 J- a3 v1 ?: h. G
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */  m3 t3 P) g/ M% U5 s: M
  694. /*         unless AAI is programming the last address or last address of                */4 o0 A' b3 A2 ]! M
  695. /*          unprotected block, which automatically exits AAI mode.                                */; |0 u# E* {" D. E. j
  696. /*                                                                                                                                                */" ~! _7 P/ f& Q: ?) E& t
  697. /* Input:                                                                                                                                */
    % z/ r* K8 u9 p( p, a' J, a
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 _( n5 d0 o( E0 w9 @
  699. /*                byte1:                1st byte to be programmed                                                        */
    1 n4 b$ l# M3 E/ F+ W; I2 l
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ' ^* O# o0 H* P' C+ n2 V
  701. /*                                                                                                                                                */
    : s9 {& U+ Q) m; i" |
  702. /* Returns:                                                                                                                                */2 y% l3 y8 n, `
  703. /*                Nothing                                                                                                                        */
    + y( ?1 U2 q) @2 ^3 V
  704. /*                                                                                                                                                */
    4 v& l. N# t' j8 b  ]
  705. /************************************************************************/
    - Z% B/ z7 |) s# k
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)7 q4 r4 l  P% F7 D: Q/ M
  707. {
    % b+ l4 e7 H! h- G& G( s
  708.         CE_Low();                                        /* enable device */
    2 R* c/ W6 C1 A  t7 W5 n; O' }) M! ^$ c
  709.         Send_Byte(0xAD);                        /* send AAI command */6 n5 Y0 v7 n/ E6 b
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! X% \% _5 G* x/ C; M
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ! m+ U! n) ]3 `
  712.         Send_Byte(Dst & 0xFF);9 r7 g' s4 u' y8 _0 [# |
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        . K8 ~+ J7 r( Q" O0 g( M$ w2 m
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 q, m) H' _4 e/ w
  715.         CE_High();                                        /* disable device */
    % k4 N! P' @3 B6 V$ s
  716. }
    1 Z5 H1 ~) Y2 Q

  717. 8 c) ~' R) X, W2 r0 F) b8 |4 ~* `
  718. /************************************************************************/
    % j& n' w; d0 s: D# C, k- M: R$ x+ h
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
      V/ W3 Y# t1 r. j4 f
  720. /*                                                                                                                                                */2 J# u. w9 q5 }* F- C+ S
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    3 o% W& d5 M. f& b9 r( N9 I
  722. /* the device:  1st data byte will be programmed into the initial                 */
    % M9 t; H! d. M4 ?
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */7 b! t- b. C3 H9 @
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */3 ?1 i: a& K4 t8 S6 a( a) ^$ e
  725. /* is used after Auto_Address_IncA.                                                                                */
    3 _* Q0 b6 _  X+ @$ G, D" v
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) }/ ^5 ]: q7 W; I( Z
  727. /*                                block protected.                                                                                */9 ~2 m' ?+ a( h" K9 \! f: N% e
  728. /*                                                                                                                                                */
    ! q$ I- P6 P. k( e/ i9 o: h
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */3 L# c$ _$ `) Z1 n
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    7 a: A" T+ o/ W" V4 L
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: \1 S2 x9 G& H. n( i& l
  732. /*          to exit AAI mode unless AAI is programming the last address or                */7 Z& m  @( c; v1 e8 \
  733. /*         last address of unprotected block, which automatically exits                 */
    3 e* T2 e, V. F: Z) g' G6 l
  734. /*         AAI mode.                                                                                                                        */
    9 h' ~% f& y8 _  g$ C$ d
  735. /*                                                                                                                                                */
    & h# j3 y% V8 _: v  H2 R' \
  736. /* Input:                                                                                                                                */' T' Y. x! ~: l2 x& U7 E+ R  r
  737. /*                                                                                                                                                */
    4 P/ H* J4 D* A1 H$ p+ i
  738. /*                byte1:                1st byte to be programmed                                                        */! Q) G- x; B) B9 c3 k, c# x
  739. /*                byte2:                2nd byte to be programmed                                                        */
    $ X- _6 q, o. P
  740. /*                                                                                                                                      */
    2 M2 y# r: C. J, H" `& g2 {
  741. /*                                                                                                                                                */
    $ n2 ]- n  _  z: L1 I3 H& N
  742. /* Returns:                                                                                                                                */
    . V: M$ R3 C5 |0 s
  743. /*                Nothing                                                                                                                        */% X% A6 Q% H9 w' m' c
  744. /*                                                                                                                                                */
    8 g2 O  |" h9 [- F# j
  745. /************************************************************************/7 }/ P4 N: z& @
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    4 @5 m: ^2 x2 ]# N  B5 u
  747. {, R" L/ z# }% k
  748.         CE_Low();                                        /* enable device */5 U# _. `/ I( o( b1 g, f, a( C0 E, {
  749.         Send_Byte(0xAD);                        /* send AAI command */9 d5 Z3 V* @( J
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    % O2 Q8 R+ {/ ?  M6 _4 @
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ' r+ _& c' T0 O% U6 W& z
  752.         CE_High();                                        /* disable device */
    * e' n, J2 H* X  F. P
  753. }( s2 w6 a* J) o8 F' V1 C
  754. 9 Q' Q$ ]! L7 a* j6 R2 _
  755. /************************************************************************/! X  c5 X' @. p" ]
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */0 F; v: p6 n9 N& S
  757. /*                                                                                                                                                */
    ) G7 t! a9 O* U+ t
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */! u- b) O$ U" D4 W2 Q$ u
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */! R8 h5 U3 d4 {
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */  B- M# r; ?5 x  M- d) Z
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */" u. j7 M, C& k; T4 c: f7 g
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */: c8 V8 ?, Q2 x/ S& s, F
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    & ~9 {* ]" }- f% t
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ! W) `1 L3 i- ?3 H
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    % K3 M4 A4 c- J) F7 p* h
  766. /*                                block protected.                                                                                */
    6 z$ q- |& U6 i3 c" v
  767. /*                                                                                                                                                */
    3 t% F8 Q! b8 p6 l% Y9 {/ P: Y
  768. /*                                                                                                                                                */
    , ?# v2 B% I2 N* R
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ( R1 N: a( K; G# j9 ?& v  [5 b
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */5 j; b) ]) K/ `# H4 L& c3 S
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    : W7 p, K& x9 ]* v
  772. /*          to exit AAI mode unless AAI is programming the last address or                */. L. |2 h. V. b. i# T
  773. /*         last address of unprotected block, which automatically exits                 */3 g3 e& R" V( M+ G- v3 L0 Y
  774. /*         AAI mode.                                                                                                                        */9 Z" ~1 P3 N- S7 B1 N( M4 V9 v/ T
  775. /*                                                                                                                                                */& l9 {, h' N% Q4 T  T
  776. /* Input:                                                                                                                                */
    ) Y& N1 o4 p+ k# |
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) v$ A* u8 J% X, d1 t3 s; {" u
  778. /*                byte1:                1st byte to be programmed                                                        */
    % N! m/ |# |/ h" _
  779. /*      byte1:                2nd byte to be programmed                                                        */
    5 o( `9 E$ b* I6 D+ y( [
  780. /*                                                                                                                                                */: Z  x) z  w/ ~, ]
  781. /* Returns:                                                                                                                                */
    5 u! w0 _/ a8 z5 _3 o! N4 w. e1 B
  782. /*                Nothing                                                                                                                        */8 L1 E* f5 g) D9 P* m- a
  783. /*                                                                                                                                                */
    & S% A; t6 w9 i9 A" N7 Q) Y2 o
  784. /************************************************************************/3 q# ^9 a* k8 a1 W
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ( n7 h: W5 W$ j1 n3 `
  786. {
    % z1 _+ Q2 i3 V& Q) T. |
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    - F: T: F9 g7 v& x0 J
  788. 5 g  n; D; R: S+ B( [6 _; P
  789.         CE_Low();                                        /* enable device */
      e& m$ ]% l1 F4 f+ j' B  L6 L) F
  790.         Send_Byte(0xAD);                        /* send AAI command */# c* y3 t: j' K
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* A5 z! j' @6 b: C* o" H; u
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));; r" O! F& ^0 E; ]* Z
  793.         Send_Byte(Dst & 0xFF);* ~  Z4 S) Z# G- ~' K; [3 X. ]
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ! o+ ]. ]% ?: X, L( P
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    # U7 |8 u3 j( {& {! x3 A" ]& v
  796.         CE_High();                                        /* disable device */, c& I4 }; Q8 E- g2 b3 d+ k
  797.         0 ?3 n4 t+ T* o2 @$ M
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */9 ?! _( Z" B8 R5 B4 V0 D
  799. & N- H' H1 h' r- Q# e' {4 U2 q
  800. }
    2 ^1 m) _* n6 z2 ^& `! L6 b8 K# s
  801. + `0 i# D9 a: I8 q
  802. /************************************************************************/
    # d  c, d  e) B' N3 K3 S
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */5 u7 r& D+ D! H7 g9 V  h5 P" ~
  804. /*                                                                                                                                                */
    $ H) P; |7 e. o: G8 i
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */+ V- N3 I# Y+ W- ~; e6 }- B, F) x9 a% Q
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
      |9 z; b9 f: ?
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    4 \5 d9 y6 Z% b/ r. p& A! C
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    8 Q; M( Y* Z& n4 m
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    # G8 W* K3 O: m/ Z# r
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */: ~, Z* {5 v9 F' N
  811. /* used after Auto_Address_IncA.                                                                                */" x' p1 @4 _0 X
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! R' K. C( P7 m8 m9 k0 P
  813. /*                                block protected.                                                                                */4 U: L6 A" R: U4 L
  814. /*                                                                                                                                                */
    : b% T0 ^- Q# h3 E; K
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / X8 s0 n$ k+ Z$ K7 p- n7 {
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    ! O. ]6 ]( T/ O  f9 V3 q8 P
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    # y6 ]: C7 h0 D% M4 f
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    4 ^% R9 y, F- S% E; q3 Q* G$ c" u
  819. /*         last address of unprotected block, which automatically exits                 */
    3 @7 M# B' V# ]2 D
  820. /*         AAI mode.                                                                                                                        */
    / ?/ ?3 n& ]& {9 j$ Z8 G. Q3 m+ p
  821. /*                                                                                                                                                */
    & ]  f  h) v0 u2 u/ C( n' K& B
  822. /* Input:                                                                                                                                */2 @9 S" w5 r7 q* Q6 D5 d+ e
  823. /*                                                                                                                                                */
    8 ]; F8 Z( F5 `* @: g/ Y3 D
  824. /*                byte1:                1st byte to be programmed                                                        */
    3 w2 E: c* X5 {2 a9 Q0 L
  825. /*                byte2:                2nd byte to be programmed                                                        */
    * [' k5 _, L# l: Q+ ?
  826. /*                                                                                                                                      */5 E3 u3 j  M( P1 V+ q3 n
  827. /*                                                                                                                                                */
    - `( Z/ R; n8 {9 l0 G
  828. /* Returns:                                                                                                                                */6 C. u1 S2 Z# t8 l2 I' _' T+ ]- Q
  829. /*                Nothing                                                                                                                        */
    7 ]0 S; w8 A  k7 V5 Q
  830. /*                                                                                                                                                */7 Z, o+ q- m. f4 n$ G
  831. /************************************************************************/( Y7 q/ U- n, K5 I+ E1 I7 F/ D
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2), J( [, i4 Y) |
  833. {
    ; A) f1 |" V- f: Z% H
  834.         CE_Low();                                /* enable device */
    " r. \9 X6 E( Z; V& h6 j( g
  835.         Send_Byte(0xAD);                /* send AAI command */$ C' F0 C" W, B/ e9 |/ X3 \
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    " H' i% e. C* F0 F- R2 w
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ) r1 n% W* {1 C
  838.         CE_High();                                /* disable device */
    & \  u1 P, q: m  }( f
  839. + z" p2 v% L6 K9 |+ z2 E
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    # e" F. G- u  {5 _" y
  841. , N( d7 u& K2 ?  K: k6 n! W3 O2 }
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    4 ]/ K. U5 t- J
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */) ?" c: W* {1 r. `: e+ X" |. F* @
  844. }, \) I4 O4 Q5 B% B
  845. 8 Z; u5 N- z3 J
  846. /************************************************************************/0 p- ^0 {/ o/ U
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    9 V9 h9 b/ U+ C, K4 k& P# P6 o
  848. /*                                                                                                                                                */) I. I( F, M* R) b5 v
  849. /* This procedure erases the entire Chip.                                                                */
    ! d0 p/ B7 g0 H  O  t
  850. /*                                                                                                                                                */! E6 g; u( N: x0 r8 ?: Q1 r
  851. /* Input:                                                                                                                                */$ c1 B! e! Q/ W& w) Y: m
  852. /*                None                                                                                                                        */8 j+ W, H- \% q2 [% X: f% k* J2 i  _
  853. /*                                                                                                                                                */' m. D7 @1 r' w8 E1 ~8 ]! Z
  854. /* Returns:                                                                                                                                */
    & j0 j6 F' C( J5 |% |2 C
  855. /*                Nothing                                                                                                                        */
    2 t$ V6 ^0 ]/ U6 X& I
  856. /************************************************************************/
    ) C9 w0 e9 v% Y$ P) P& \
  857. void Chip_Erase()
    . ?8 z  J3 G3 {$ ?/ c' x% L
  858. {                                                6 C; m! Y, C# x+ {
  859.         CE_Low();                                /* enable device */
    5 d$ [/ i6 G; _4 i! p( m
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    3 Z  b7 X. o1 I5 _
  861.         CE_High();                                /* disable device */
    6 u' f( ?, j2 W. H8 U4 m% `
  862. }
    : [3 \  ~% X$ M* Q2 j

  863. ( Y9 J$ Y$ E+ S3 n8 R
  864. /************************************************************************/) \2 [* }( i: E
  865. /* PROCEDURE: Sector_Erase                                                                                                */# c; ?, Z/ S* Y
  866. /*                                                                                                                                                */$ u' }; Q8 u. E5 Q; m! ^
  867. /* This procedure Sector Erases the Chip.                                                                */
      u- q' d: L  B  T1 c; x: ?! S" k7 O
  868. /*                                                                                                                                                */2 V  i! \- [3 `8 f
  869. /* Input:                                                                                                                                */
    6 N' C; O  D1 P* m0 I
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% u* `8 n! Y! d% |. s2 {; h5 F, t
  871. /*                                                                                                                                                */2 F6 S7 z+ G  q* r9 R2 }2 d, ^
  872. /* Returns:                                                                                                                                */  j7 W# a: }) X9 I6 }# b
  873. /*                Nothing                                                                                                                        */
    ! _5 f* K/ ~1 t. p/ Z: v" W: S
  874. /************************************************************************/0 x& ^+ \/ Q! }0 i$ [1 x
  875. void Sector_Erase(unsigned long Dst)
    ( t" s- _( @) Q) L
  876. {
    & o/ N& B- x5 M
  877. : d3 K4 B% l- m- v* }# A" I7 o
  878. $ S8 l+ W& X: ^% G+ e, V6 a5 i7 ]
  879.         CE_Low();                                        /* enable device */0 A- P# `" w6 W+ R
  880.         Send_Byte(0x20);                        /* send Sector Erase command */. O: z' E- X2 t+ `0 l# G, E
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */. Z( z" L7 \0 F3 r& h, ~
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 N5 u. ~9 F( e# |" ^5 c( y7 C3 A( s
  883.         Send_Byte(Dst & 0xFF);* Q; y& r" b; I% H6 X
  884.         CE_High();                                        /* disable device */2 Y/ ^! Z. V1 c' ]: q3 e; m: o) G
  885. }       
    4 N7 n: I: r# k) D- w9 [7 T

  886. : z: }" m$ N! l( ]8 H. L
  887. /************************************************************************/
    7 _% f7 v: q9 S& ^6 H. T$ P6 ?
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    & f. A. c4 k2 h: T
  889. /*                                                                                                                                                */: [6 ]% L$ K- }7 D8 O. d, {5 [
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */5 }' X# l9 ]. ^  [& F7 M
  891. /*                                                                                                                                                */
    6 r" d& \& j' A  I9 E% C/ K) v8 l
  892. /* Input:                                                                                                                                */. V  N7 I, A& O. H
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - X: e5 Y$ _# _
  894. /*                                                                                                                                                */8 b/ r5 n4 O* u) t# t  s4 N2 \
  895. /* Returns:                                                                                                                                */
    ! g* l  G& q, J. W: F) v
  896. /*                Nothing                                                                                                                        */# H1 N8 Z% j4 P6 M0 Q( a
  897. /************************************************************************/8 L) O( n* }6 I2 q
  898. void Block_Erase_32K(unsigned long Dst): X/ `, Z2 m" B+ Z# W
  899. {6 Y- q. Q1 t3 {, E7 p' v6 l
  900.         CE_Low();                                        /* enable device */3 F- |( |2 u& k  {$ x! f0 i: m/ o
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    3 u! m3 x8 p; t' L2 u
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ y+ P, c! G: U, G3 Q2 q
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));- u8 a( \9 F( y  \
  904.         Send_Byte(Dst & 0xFF);. A2 H0 s& y) u* q
  905.         CE_High();                                        /* disable device */! B9 m" G6 @* O
  906. }
    : ~) O" {% d3 f) T2 z
  907. ' D& k" m8 i) t- b
  908. /************************************************************************/. w2 K- |5 C  w
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */9 @/ u' Y1 U8 W- Z8 g
  910. /*                                                                                                                                                */* \! o! d1 l: r# i; I6 a
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */' U+ y/ x' l0 B( F  o( u9 a
  912. /*                                                                                                                                                */
    ' r" y# h7 M" G
  913. /* Input:                                                                                                                                */
    " f$ e: I8 [) h
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 v4 J% ?& I* P# X* V4 e# ^
  915. /*                                                                                                                                                */, N$ D, G1 j4 e  ]5 ^
  916. /* Returns:                                                                                                                                */5 c5 t; j+ C2 b' i
  917. /*                Nothing                                                                                                                        */3 E! B& i8 [8 l- E0 o! k. b
  918. /************************************************************************/
    0 N" d2 b7 [  K
  919. void Block_Erase_64K(unsigned long Dst)
    5 g! ^) D- q' U* l& A" H
  920. {6 ?# u( f5 q  X6 l* L
  921.         CE_Low();                                        /* enable device */; R9 q4 {1 I5 N+ ~1 K$ n5 m8 h
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */* G0 M  [' [* @' L: A
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * b. o0 k8 z, ~/ ^9 `
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));. \! W9 V8 y4 j/ ^- C
  925.         Send_Byte(Dst & 0xFF);
    1 `" a. F) p! Y- Z
  926.         CE_High();                                        /* disable device */* V5 E+ X9 O; ~  }9 \- h* u; d" a& X
  927. }1 c, D3 e5 M8 [8 j

  928. ! L; v9 `+ d/ ?/ u8 t
  929. /************************************************************************/
    5 ]9 }! \' ^1 C, ]' @+ g
  930. /* PROCEDURE: Wait_Busy                                                                                                        */" T' A* _% s# o. S8 I4 F
  931. /*                                                                                                                                                */
    & I2 G9 z$ E! ]( O
  932. /* This procedure waits until device is no longer busy (can be used by        */8 B, p0 ^0 z7 x! k5 }* `/ f6 Q- n
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */$ K" G) V5 m* N  f; j/ X
  934. /*                                                                                                                                                */
    5 k8 S0 }3 X  ?$ L
  935. /* Input:                                                                                                                                */6 z; c: T. U1 v9 a
  936. /*                None                                                                                                                        *// a8 C4 J/ U( o+ m. \5 f
  937. /*                                                                                                                                                */0 ^' H( n; K& U8 P0 {0 ?( I, G
  938. /* Returns:                                                                                                                                */" Y1 b: h, y2 S4 ~
  939. /*                Nothing                                                                                                                        */
      j; `) G5 g* [* T' o
  940. /************************************************************************/+ z9 {( u3 S! J$ |: c! \
  941. void Wait_Busy()& l! s) S& N2 l
  942. {0 @8 ^* D0 g9 b* v' N" W  L% b  p
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */# S4 v! j5 |* H& v- Q/ M
  944.                 Read_Status_Register();; h* O+ O& T8 l3 V* u, `0 S: g
  945. }
    ; X! n; U& U: X+ Y* k* M+ ?9 w$ `* j4 D

  946. ; V6 r) {3 O; `- M7 N8 }( x
  947. /************************************************************************/0 g* z% i, S+ b9 N" w
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    + m: K' A" O* j% F) J  h
  949. /*                                                                                                                                                */. M5 o( T5 O- _* \' H
  950. /* This procedure waits until device is no longer busy for AAI mode.        */# E% m0 ?4 Q: m8 D# ~
  951. /*                                                                                                                                                */: A' j+ x! H; e& r+ D# \
  952. /* Input:                                                                                                                                */! ~4 ]/ C- P! i: w% i  I
  953. /*                None                                                                                                                        */
    9 @3 Z1 g8 ?& A5 L: _4 {6 a' ~
  954. /*                                                                                                                                                */
      B5 m( B$ |. N! o( r
  955. /* Returns:                                                                                                                                */
    3 `( w3 m2 u& ^0 P3 ~6 V
  956. /*                Nothing                                                                                                                        */9 j* k/ d: o) S4 I
  957. /************************************************************************/
    ! E  s5 |( X! z+ K4 C
  958. void Wait_Busy_AAI()2 T, f- o' h1 Y# B* q
  959. {
    & B0 R, D/ ?! u9 a+ w7 ^
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    / p8 i; I6 E+ K
  961.                 Read_Status_Register();
      \+ l' `' r8 n7 Y
  962. }/ k. D$ P7 L  J9 z# D1 m' v
  963. * \5 s. w) Y3 y% |! d4 ]
  964. /************************************************************************/: }4 ], W9 f$ _6 g& h
  965. /* PROCEDURE: WREN_Check                                                                                                */
    6 u2 C( Q8 n' S6 Q7 H
  966. /*                                                                                                                                                */
      w/ I. b- K+ b- L* E3 {) X' Y
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    - _2 C' g2 w4 u9 z: S5 ~) A
  968. /*                                                                                                                                                */9 p" O6 l, H9 U7 M8 h
  969. /* Input:                                                                                                                                */
    1 }8 a" f4 z: H  G' G. G4 `
  970. /*                None                                                                                                                        */
    % [; ~; I7 G- ^0 B. u9 v
  971. /*                                                                                                                                                */( O+ j- {% Y0 j
  972. /* Returns:                                                                                                                                */
    . s- h3 k6 S6 \! p
  973. /*                Nothing                                                                                                                        */
    ) w) e) n0 ?. o: J- E; z  K8 d* Y
  974. /************************************************************************/
    + m: u; H7 ], X9 ]
  975. void WREN_Check()9 L+ l+ r- U9 L1 a
  976. {
    & Q1 }, C& o' W! V1 p, O0 k
  977.         unsigned char byte;5 G; d$ b# X$ X/ Y; @; W
  978.         byte = Read_Status_Register();        /* read the status register */1 J" e2 Y9 C/ U0 f* w
  979.         if (byte != 0x02)                /* verify that WEL bit is set */# i, [. M7 Z3 K4 X) ~
  980.         {$ n8 s( V8 S$ z5 O
  981.                 while(1)% C8 Y& A7 W" _6 C( P
  982.                         /* add source code or statements for this file */
    , C# V1 W) `; ]" y% Y' R
  983.                         /* to compile                                  */
    . a5 a1 i: ?$ ~$ b
  984.                         /* i.e. option: insert a display to view error on LED? */) N' ~1 p. L3 ?: |( C8 A
  985.                  / e2 P9 Y$ ^% N  J' @" i
  986.         }
    8 _$ H  q6 b1 n! z( [# c/ }
  987. }' D) M2 a& N6 }' a

  988. ( ]/ D; n/ D3 p9 x4 B! K4 r
  989. /************************************************************************/
    0 @: F* K3 r6 z+ J7 k, i
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    8 N$ x* Q, e" T& Z0 E
  991. /*                                                                                                                                                */
      ~* l. z; ]: D  Q$ Y! V! g5 s
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */5 [% Z! D" L& O; R; b
  993. /*                                                                                                                                                */1 e( u: B1 {) I7 p7 q; D
  994. /* Input:                                                                                                                                */
      l% ]5 @- C& F, [6 f0 `$ p
  995. /*                None                                                                                                                        */
    $ p6 t; R3 `  x& s, k0 }' a
  996. /*                                                                                                                                                */
    % S4 g* G: }( E
  997. /* Returns:                                                                                                                                */6 ~- T( O$ V  ?8 g7 z
  998. /*                Nothing                                                                                                                        */
    " C8 z1 ^) y! b% v1 I( u3 z3 V
  999. /************************************************************************/; T- [( n; B  \3 O& z
  1000. void WREN_AAI_Check()
    + q1 V+ e1 ?: e7 u) u
  1001. {" ?. ~: |% v0 C# N, X. q( A' o, m' i
  1002.         unsigned char byte;" t& \: v/ Q8 B( z4 v' {, G
  1003.         byte = Read_Status_Register();        /* read the status register */
    ' c- w$ ~. O% j6 X0 Q1 g. E
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    1 m# x3 M7 O: Y. m* h
  1005.         {
    ) f0 ?1 j! o* @; l- |6 ?; q
  1006.                 while(1)               
    1 r. b  z& L+ t8 A# G
  1007.                         /* add source code or statements for this file */: P* J! p$ m( p5 {) K
  1008.                         /* to compile                                  */# H; d& K! n# y" i% y0 K
  1009.                         /* i.e. option: insert a display to view error on LED? */3 `7 o7 n7 x% W5 o4 W! H7 C
  1010. - p9 {" \5 P' ~4 m0 [9 m& v
  1011.         }$ C  E* U2 B9 I7 h; j6 Q! U2 O
  1012. }2 K* G" B- J7 M$ @$ \$ Z
  1013. 5 h9 Q$ b( @1 D% I* C3 k
  1014. /************************************************************************/
    2 L2 j/ v! S9 @, }3 ]5 u
  1015. /* PROCEDURE: Verify                                                                                                        */
    4 V2 {8 c7 v2 g
  1016. /*                                                                                                                                                */7 D/ [7 r) ]: ]5 X( K8 t) U
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ! ~9 b4 N, T" e0 Q7 ]
  1018. /*                                                                                                                                                */' s2 t- D+ D; E6 U
  1019. /* Input:                                                                                                                                */! `* T! X" e% J! ?9 W. Z
  1020. /*                byte:                byte read                                                                                        */
    1 g. E' O1 V4 S5 [+ p
  1021. /*                cor_byte:        correct_byte that should be read                                        */- Z( e+ A9 B% S+ m: K. p
  1022. /*                                                                                                                                                */
    ; v0 x; n2 X$ K: V
  1023. /* Returns:                                                                                                                                */
    : S: |$ y2 b9 m) S, Q' j
  1024. /*                Nothing                                                                                                                        */0 o" X: `, a" m
  1025. /************************************************************************/
    , ~- K  h5 ~; z1 I' S. ~
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    / r. K  u, u6 |+ d" w* [: g+ A
  1027. {
    3 @1 k! ^" q9 g
  1028.         if (byte != cor_byte)
    " }1 B' }! E& j
  1029.         {
    4 G% h' y# U! C5 J
  1030.                 while(1): s$ i0 t) t# O4 {9 C# O9 c
  1031.                         /* add source code or statement for this file */# e! X' v6 o! i( H8 i6 h
  1032.                         /* to compile                                  */4 t" D- I$ P3 [' o& B7 `
  1033.                         /* i.e. option: insert a display to view error on LED? */
    $ u( ~4 m6 Y/ L7 k- ?, m
  1034.                 3 A- \) }5 V/ {; y  ~
  1035.         }+ D1 |; c/ q! f% g" s
  1036. }
    & N! h. D. U! ~  E" L/ {: r/ k. _

  1037. 4 T) d9 o1 H- F7 a, j/ q

  1038. ' C- Z. d* p4 _$ _, ]
  1039. int main()
    , }" N5 n! U9 d& G% s; P
  1040. {
    0 ]$ \! y: P0 y2 L8 [4 m2 [
  1041. ! Y) Y$ C$ V! ?4 d
  1042. return 0;2 h1 V( f% K* ^# C
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:- o$ u+ X$ K4 R- {( k% v8 ^
   main()( F* \5 |, m0 e  ?, I8 c
   里面怎么是空的呢?
3 Q0 W- Q; p( A8 A9 E   发一份给我吧& @: `& \) I  @( R) \4 _
mail:luyijun2005@hotmail.com4 Y8 B2 V, [, @8 I7 M& k" ~
咯。。。。
回复

使用道具 举报

 楼主| 发表于 2007-12-11 19:37:35 | 显示全部楼层
本部分就是如此,它提供的是方法,并不是给你拿来编译的.你要main函数能用来干什么? 为什么不看看 Byte_Program...等函数?
回复

使用道具 举报

发表于 2008-1-8 17:42:00 | 显示全部楼层
如获至宝!请问哪里能找到SPI的官方spec(我不是指flash的datasheet)?网上只能找到些片断...管理员是否可以上传spi spec至本站?
回复

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
! j8 {6 X. f+ q( n* z& E, X. b
6 C  v. }5 K- I[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

发表于 2008-1-10 09:20:46 | 显示全部楼层
感觉有些冷清啊。不知道现在OEM一般使用多大的flash?
回复

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。) @% f4 ^9 G# K2 I
EC的代码在哪跑,你看DS的说明,每个EC都不同的。% t& I. w. |# C; e5 a) z/ \
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?4 f5 |; T( ]4 ^: v
上面几个问题是你没看任何东西而白问。
6 s/ F7 z; q! p( E1 T2 ^! {
$ F, ~2 a, ~$ U$ ^+ c至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。4 L& d: H' z8 S2 p5 T$ T

% |+ S4 j" n/ Y( h) ^关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
! d- Z$ X, |+ l" t4 ?+ T5 ~- H  l% s7 \3 ~7 |
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
# G" N  p( f  d' z0 S$ T( `- m+ ?+ v% o  S, z
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
" x( l" z5 l. u2 s- G: X, N. F+ q, y5 s8 B7 E2 e5 W; K8 E5 l
不管怎么说,多谢。
回复

使用道具 举报

发表于 2008-1-11 18:55:40 | 显示全部楼层
我是很希望能在这里跟懂EC的人多交流的...国内弄EC的似乎不是太多
回复

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
' O/ U$ V0 G4 b. |' N9 _似乎要把SPI能support 到最大,这EC chip应该有好卖点
; B1 u: M0 e8 Q5 G: }; @BIOS功能要不要强大,也就决定了SPI Flach的大小
7 b# H0 p+ k8 S8 J$ Q( I我是这么想的~让OEM去决定要挂多大!: l: q  P# s) [" M
如果我司有BIOS工程师就好了~哈9 s/ g/ M: _! U1 M* b
WPCE775应该算很新的东西,来看它支持到多大?
' O0 u7 ]. q- A1 y; l! S. p7 v
/ P* m' L) h& g另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte$ E1 N: B( K# c
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
. _2 Z' F# q0 P' o. Z0 y8 W0 h! ~  G, \
这份driver收下~希望以后有用到2 p7 H# D8 f' D4 T/ W' r
谢谢bini大大7 u. T( o" Z7 N) B

4 P4 W9 F- E8 P& p: _很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

发表于 2009-7-18 15:16:34 | 显示全部楼层
我也有份汇编的DOS下的烧写代码,SST 1MB的 flash可以用。我不知道为什么AFUDOS为什么不能工作,AMI好象没有发送94 CMD下来,AFUDOS直接就说不支持。搞的下BIOS非要自己写个程序,烦的很啊。
回复

使用道具 举报

发表于 2009-8-13 10:59:30 | 显示全部楼层
前端时间小弟也在windows系统下写了一个并口到SST25VF080B的烧写程序......
回复

使用道具 举报

发表于 2009-8-17 16:47:36 | 显示全部楼层

这个函数看不懂Poll_SO()

void Poll_SO()  @9 @2 t. p; f+ F" ~
{2 n, B% O  \1 }0 V2 @% j1 u1 a
        unsigned char temp = 0;
; m9 m9 B- N5 G0 w. f        CE_Low();
( R& m4 t' g4 ?  r$ r3 {    while (temp == 0x00)        /* waste time until not busy */
' o% d$ f0 |# e% R  q+ g" y2 ]                temp = SO;. e. Z' ]3 s& P" ~
        CE_High();
7 R! V/ L4 X( U7 p}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)$ k+ K, C  _( `0 R# M* z6 o
{! L$ V3 _9 _# H7 D: Z+ y, r: W
        ; J" m3 D# K: ~9 w" ~, \
        unsigned char i = 0;9 w8 d) S2 m  I0 J* C" w0 v) X
        for (i = 0; i < 8; i++)
$ ^1 ?( J6 {1 v- |9 i3 M/ l/ x* E        {
5 o0 M8 a) ?/ J9 C6 L7 c+ j               
0 L; o; a- j4 {. c3 K                if ((out & 0x80) == 0x80)        /* check if MSB is high */
' u8 @5 t0 A: S  L- V                        SI = 1;- t5 g- t" C" ~! _- @
                else# `9 x% x5 V( I
                        SI = 0;                                /* if not, set to low */) l6 t+ [( j# t* N
问              SCK = 1;                                /* toggle clock high */
4 O  D2 F; d& R3 [5 }   题            out = (out << 1);                /* shift 1 place for next bit */
* @9 D; n! R$ W1 p                SCK = 0;                                /* toggle clock low */, i$ L" v$ z. t% s# P1 R; M, @
        }
: d; c0 M4 @/ o}
, ?8 a* G1 Q6 Z+ Z1 c 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2024-5-20 13:40 , Processed in 0.028058 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表