找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54757|回复: 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# M$ ~9 s- r  a: D  o- r7 v5 q
  2.   \$ P9 u5 U. ^- a- P% w3 |
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    0 I5 p: `% Y" d- p2 b2 B
  4.   t" r7 [* e5 E  e2 r
  5. November 4th, 2005, Rev. 1.0# L3 x+ Z$ p+ F* u
  6. : [- ^1 U1 s' J! U0 R( m2 _
  7. ABOUT THE SOFTWARE5 l  @0 p8 V, r4 z
  8. This application note provides software driver examples for SST25VF080B,7 l; X# P% J* {  x6 ]( E
  9. Serial Flash. Extensive comments are included in each routine to describe 2 c8 u: t" r7 Y8 T
  10. the function of each routine.  The interface coding uses polling method , g2 e/ ]3 a- G8 w& n
  11. rather than the SPI protocol to interface with these serial devices.  The
    $ j! @! }: c$ Q/ r* Z) ~5 s; Z' Q
  12. functions are differentiated below in terms of the communication protocols  y' L3 m# s5 E& s3 N8 ]! H
  13. (uses Mode 0) and specific device operation instructions. This code has been - w/ j2 f; t% r/ h, E" K+ y
  14. designed to compile using the Keil compiler.
    * @$ _( `% F5 D7 ]  O) ]6 H3 h  [

  15. 4 f8 B/ q8 B0 M( k. H
  16. * a) Z9 Z3 s& [* I* W
  17. ABOUT THE SST25VF080B
    9 G$ M- \/ m  F( y' H

  18. 8 Y$ v- k, _& S! R6 T. A* \
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    - H+ B. B% a$ q  ~8 H4 j7 v
  20. conjunction with this application note for a complete understanding / ?  @2 L5 a5 Y3 Z+ k* p
  21. of the device.
    + X5 }7 H( a! o

  22. $ U7 V4 X! f: p; c* U8 p3 ]  }

  23. : `6 n9 }% g. P$ `" b. z
  24. Device Communication Protocol(pinout related) functions:$ [( O# A4 M7 p5 ~& ~& P

  25. % H% C/ k! O1 z1 P$ ^
  26. Functions                                    Function
    ) }$ X% h1 A! }  T
  27. ------------------------------------------------------------------) P# K6 Z1 Z0 N. H( v1 H5 s  r, K  x
  28. init                                        Initializes clock to set up mode 0.3 ]+ Y1 _1 o; X# t7 {  |
  29. Send_Byte                                Sends one byte using SI pin to send and $ ]' Y& u% I! h# V- q2 H7 @
  30.                                                 shift out 1-bit per clock rising edge
    ' M0 }! y4 [  H4 J5 k0 ]
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    ) s0 E. [- |- R8 e) a% W
  32.                                                 in 1-bit per clock falling edge! b8 G2 J' h6 u9 W8 |4 O
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    5 D( C$ U4 m( Q  i/ O1 y  C- W
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high: V5 U* P* a/ m1 P' J0 [
  35. CE_Low                                        Clears Chip Enable of the serial flash to low( `- S( B* i; U2 |/ {
  36. Hold_Low                                Clears Hold pin to make serial flash hold+ I+ O/ Q: s, v  s$ Z. z( B
  37. Unhold                                        Unholds the serial flash
    7 ^8 I0 W! I4 ?6 i2 |' m
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    " Q9 R4 O$ Y: g5 M2 F" K5 L3 L
  39. UnWP                                        Disables write protection pin0 N5 ?. f( W0 @0 U
  40. 5 p% O6 {8 @3 H" P3 W! q0 S
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code' P; a$ ?0 [) ~) q2 s- g+ B
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your2 f$ k+ n4 p. C1 ~$ z. G& d
  43. software which should reflect your hardware interfaced.          9 T6 M2 M. o  C, ^# f2 R% ~2 R# P
  44. & v. w8 x, B* g( O

  45. 3 l+ F: K8 X3 z
  46. Device Operation Instruction functions:
    ' K/ I- I* v5 t* d9 K- U

  47. ' W/ \. D' T, ?. d0 ?
  48. Functions                                    Function
    ) I2 B, m, b8 A9 a9 N
  49. ------------------------------------------------------------------; w; k" p4 H- x' `8 U( o
  50. Read_Status_Register        Reads the status register of the serial flash
    ) A4 r5 D9 T% U/ e# D# d# H
  51. EWSR                                        Enables the Write Status Register
    . A( E! ?6 t1 X$ Q
  52. WRSR                                        Performs a write to the status register
    % F  W; d2 W1 V( E; w0 `4 X* a  a
  53. WREN                                        Write enables the serial flash
    4 H# l- @, _; M6 d
  54. WRDI                                        Write disables the serial flash
    / y4 x4 t3 k$ s1 F  Y, B/ H
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming  B8 l8 \- a, b8 l- T4 t* Q$ M
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    + q, x0 U4 @2 @! Z
  57. Read_ID                                        Reads the manufacturer ID and device ID, \" T7 E/ \1 P6 W' x! S" U; n
  58. Jedec_ID_Read                        Reads the Jedec ID- p1 }# K/ E, C. G
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)8 P4 y* s/ w. L
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    * F, w, u3 G3 r; q
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    3 t) ^) H! e& O* W0 g
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)2 P: b/ o' A4 W2 @
  63. Byte_Program                        Program one byte to the serial flash
    8 I& n% U3 m1 p5 v
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    9 l( C) ^& x% V' T! O! `3 O$ B
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation3 F2 E+ X  ]) i9 e7 k
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    3 d$ Z+ O. f8 o! n# Y$ i
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    % g2 }9 E, _$ {+ z* \* q7 Z
  68. Chip_Erase                                Erases entire serial flash
    + T+ d2 m" g3 w: Z, E% s8 \  f
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ! {# U4 G7 U8 x2 D. i
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    1 l7 A5 z" j. h" W/ a. q- K3 ?
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash3 @. B) A2 H/ [0 k, R
  72. Wait_Busy                                Polls status register until busy bit is low
    6 h9 ]. D/ R' [( m5 O" \
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming6 _& _6 ?; P8 X* `* E* [7 q$ v
  74. WREN_Check                                Checks to see if WEL is set8 F' [7 b) n1 o
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    7 \! S) h# ?. ~  U/ |
  76. ) J1 \* j- N) k; ]" Z

  77. ; r  h5 P) Q+ }2 q4 A
  78. : a$ A4 l! |8 Q3 |
  79.                                                                      / Q1 s4 m1 h% k2 S% i' {
  80. "C" LANGUAGE DRIVERS
    5 W; w& D  B1 s9 c' _+ B; e. C

  81. 0 c4 l( J. ]& q# d7 H5 f  Q
  82. /********************************************************************/
    9 a& i* g/ u! }$ w
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */. `& u+ }& `' {$ m! K
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
      f4 o. l$ i% \3 i& i* o2 ]
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */, i8 i7 D) u) K) C: b7 ?
  86. /*                                                                  */
    ' @9 _$ `/ H9 A% _- V1 r6 L  x8 I
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    5 X( |5 n% W+ M2 q" v6 l* h
  88. /*                                                                  */  w" A- e$ `! O- u
  89. /*                                                                                                                                        */
    . t: G  [9 u! g! W/ T1 s0 A# u6 G0 ?/ Q
  90. /********************************************************************/: o* m8 }3 k9 u

  91. , q: I4 _4 P7 q! M7 O3 k
  92. #include <stdio.h>
      b! J* z* W1 N0 m) F2 ^/ b
  93. #include <stdlib.h>
    . Q% Z5 @! @, {' f) z' ^) {+ m
  94. : ?, D9 |! _! ?7 Y" p3 ]  C
  95. /* Function Prototypes */& C! F$ p( i+ ?! Z8 G
  96. $ y8 ~1 d$ ^' t# M; D( p  r: k( `
  97. void init();6 Y. h2 ~4 x# y9 B
  98. void Send_Byte(unsigned char out);
    & l) O9 @2 F( o) P" |
  99. unsigned char Get_Byte();
    . E2 J6 X( }0 ?: V4 r
  100. void Poll_SO();9 W, Q( z3 Q5 d5 |
  101. void CE_High();+ u8 K. O: {) g
  102. void CE_Low();
    4 U; @* \; ]' b2 D+ O
  103. void Hold_Low();
    ) D$ \6 c5 W7 F
  104. void Unhold();
    $ T8 C; z0 r8 U9 \# V
  105. void WP_Low();
    0 ?. f1 t$ N7 Q! c
  106. void UnWP();$ a7 h( C0 |! j
  107. unsigned char Read_Status_Register();
    ) e0 N7 f" q' m0 v1 m+ i
  108. void EWSR();/ A( H* A2 g2 W3 g4 d2 M
  109. void WRSR(byte);
    3 F4 O0 s" V( Z; V+ y
  110. void WREN();
    9 X: f6 s9 b* ?5 K) |8 l1 g
  111. void WRDI();
    $ E4 ?7 Z. m) {! [* z! _
  112. void EBSY();5 X! z; o' i, o& i5 h
  113. void DBSY();
    : @8 v. S% U4 i+ K5 \6 ^% h
  114. unsigned char Read_ID(ID_addr);
    & S6 ]8 [! v* Q' H
  115. unsigned long Jedec_ID_Read(); - `7 V( E! s5 m$ V" ~" H/ P+ L5 f
  116. unsigned char Read(unsigned long Dst);
    ! V7 P/ s. ]0 X! d; n
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);4 i( z$ K. |  t0 s: p+ a* i. Z4 c6 g4 ^
  118. unsigned char HighSpeed_Read(unsigned long Dst); # ]8 a( @% _: A+ j* J
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);/ U) i' n. N: n# d
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    , ]1 U  H6 D+ ]" Q" }
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);' ~# E5 z; F9 f7 {0 K, I: a
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    7 \# X; s5 @2 |5 ]# |
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);2 i9 _% K; ]: o1 m# }! |
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    8 D. {- {+ u7 n9 i3 a; H
  125. void Chip_Erase();
    * H$ U# s7 E; K' |6 E4 [. `
  126. void Sector_Erase(unsigned long Dst);
    6 ?; e9 z) Z* I0 `. y5 k: k
  127. void Block_Erase_32K(unsigned long Dst);
    8 e9 \% ?3 p6 I* h: S# M/ p  X. Y9 n, g
  128. void Block_Erase_64K(unsigned long Dst);2 g( p0 H' F( H' x4 m. m6 p
  129. void Wait_Busy();
    . X. D* z  C8 t+ V# h' C* g$ L
  130. void Wait_Busy_AAI();+ o$ I1 v5 Y% c
  131. void WREN_Check();5 k( H. ^  E2 l9 n! w
  132. void WREN_AAI_Check();
    1 j! [7 [. }7 U* i

  133. 3 C) {; f- L" X3 A
  134. void Verify(unsigned char byte, unsigned char cor_byte);! d; a9 M0 ]' o4 @
  135.   g# b- R0 u/ ?2 s" ~$ f& ?6 p' V
  136. unsigned char idata upper_128[128];                /* global array to store read data */& O4 }0 n. q: K
  137.                                                                                 /* to upper RAM area from 80H - FFH *// i0 m, n0 v! A7 k
  138. ( q. K6 Y: p3 t- [: D0 c) `
  139. /************************************************************************/
    2 k" P$ g/ D  s& W- t5 `# v
  140. /* PROCEDURE: init                                                                                                                */
    1 H" S1 Y: v2 e5 V' t4 v
  141. /*                                                                                                                                                */9 J9 N+ ^- _# c. R
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    : b- ^# o1 W0 [) Z+ s+ k4 h) Z
  143. /* setting up mode 0.                                                                                                        */
    - W. h2 j/ q  O' z
  144. /*                                                                                                                                                */, [3 B, c- ]% j& [* g! m
  145. /* Input:                                                                                                                                */
    % s# D" N+ P, @# s
  146. /*                None                                                                                                                        */
    " W) D9 f, E8 f. O9 Y
  147. /*                                                                                                                                                */
    2 \) i/ h2 j' k
  148. /* Output:                                                                                                                                */
    & a3 t5 e6 @6 E$ \4 t( w- _- g
  149. /*                SCK                                                                                                                                */
      j7 a, m! p% n- w
  150. /************************************************************************/
    ) s4 d( h$ H% h) k
  151. void init()
    ) r: u6 S! m! f
  152. {
    / Q/ y. _* K- H. ]3 [
  153.         SCK = 0;        /* set clock to low initial state */" H7 ]" z3 `" L. }' d
  154. }
    " T6 d9 Q$ i; {1 y9 ~5 U7 j5 U

  155. / w, {: G' V! o
  156. /************************************************************************/4 i0 e8 m5 ?: Y* ]: X8 s
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    1 I# H- u+ v  J: ]+ ~! z
  158. /*                                                                                                                                                */
    6 w& T: K9 x; H2 A9 g- z( V; Y
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */5 w5 F& Q- [) T5 ^( H* K' }
  160. /* edge on the the SI pin(LSB 1st).                                                                                */; ]' S4 }8 r. f, \2 z+ w
  161. /*                                                                                                                                                */
    7 c* f$ R0 I7 G, Y/ {
  162. /* Input:                                                                                                                                */6 A2 k- r2 C3 `6 p9 N1 C, c
  163. /*                out                                                                                                                                */
    5 k& {6 F5 w4 n' t: V
  164. /*                                                                                                                                                */% a% {3 C8 g+ K3 O+ t5 F" E+ x8 J
  165. /* Output:                                                                                                                                */
    , N* R' ~' L8 m# }  S
  166. /*                SI                                                                                                                                */3 D9 }( t, k: E1 B0 [8 S
  167. /************************************************************************/
    3 x% n% j! u# {4 V5 ]' o
  168. void Send_Byte(unsigned char out)
    " N3 t* y  D4 z9 g
  169. {. n0 [0 E& ~5 h! H) w
  170.        
    , c) x! O) i% A# A6 y# y; p
  171.         unsigned char i = 0;
    $ R- ^1 M" ~& W+ f+ _
  172.         for (i = 0; i < 8; i++)7 J2 w8 G; n/ {( x* u" V  U8 y
  173.         {
    3 p3 U9 O) r% u! N4 P( \& G. {4 ]
  174.                 + b( C, ]4 ]- B9 Y5 S
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    0 [+ v1 c4 m( y% Y$ B
  176.                         SI = 1;
      e* j  M( @; ~4 M9 N8 k  o
  177.                 else
    ' r% Y* L9 B& w
  178.                         SI = 0;                                /* if not, set to low */6 t6 O, j7 d9 D$ ?1 j# U$ b* F
  179.                 SCK = 1;                                /* toggle clock high */! _; H; d$ ~3 I* p+ Q
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    + u& C4 B, f1 r  j
  181.                 SCK = 0;                                /* toggle clock low */
    & n6 G* ]7 z8 c5 q0 S
  182.         }; p6 Z' ]. c  X) A5 M
  183. }
    & ~. w! B. W+ _; r

  184. , V, o* W. E" G: L4 I; X! t
  185. /************************************************************************/' U$ C5 R% d& b  g+ g, x2 e3 j
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    2 a) ~3 q& v" P( j5 ?
  187. /*                                                                                                                                                */1 {' D+ ~; @# z4 v, Z& H+ ^0 g
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */7 D* B% j" L) Z( ]7 H( T
  189. /* edge on the SO pin(LSB 1st).                                                                                        */3 ~5 i) z1 w+ Z9 B6 R$ {: p
  190. /*                                                                                                                                                */
    $ _" E2 ~: S) t
  191. /* Input:                                                                                                                                */
    2 j* K6 ?& O& ]; j5 E. Q# u$ L
  192. /*                SO                                                                                                                                */
    7 H5 ]/ I5 j9 ~! o. K& A
  193. /*                                                                                                                                                */
    , T) Y6 Z1 Z' D, |- m
  194. /* Output:                                                                                                                                */# {5 c" R8 ~. p2 x
  195. /*                None                                                                                                                        */- N, L. d* f2 I$ n. u# W" |
  196. /************************************************************************/
    1 I5 p) Y/ ~3 ~7 J9 v8 E/ h3 W
  197. unsigned char Get_Byte()
      f- h0 Y" L- Q/ M0 T( Y
  198. {5 l* J/ [5 u9 F
  199.         unsigned char i = 0, in = 0, temp = 0;
    9 W7 A' F5 I% O* g$ D0 N
  200.         for (i = 0; i < 8; i++)( X, g# [+ y7 o; \% a/ g
  201.         {
    4 k+ G3 }4 j% j
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    1 V4 d9 \# ?4 ~
  203.                 temp = SO;                        /* save input */# e6 l8 M/ ]+ A4 b
  204.                 SCK = 1;                        /* toggle clock high */, a$ p1 {# x7 }- e- \0 e4 h
  205.                 if (temp == 1)                        /* check to see if bit is high */9 A. E; z. `  k/ G: N" u
  206.                         in = in | 0x01;                /* if high, make bit high */7 b- T/ W0 R4 z/ F: v4 U
  207. 5 W1 Z6 Z" h; v1 \; B8 K$ M
  208.                 SCK = 0;                        /* toggle clock low */
    / {  [4 X( [- i) u0 A
  209. # }# @7 q9 j2 }; J6 e
  210.         }
    + a+ i5 o/ h$ d( g+ z  {
  211.         return in;
    3 c8 Y1 }9 L, F$ G
  212. }1 |# V5 p  Q/ P9 |( ^! ^2 F* R
  213. ; C# `7 q  l2 r% \& {
  214. /************************************************************************/
    0 [% ?) X% p, v0 q
  215. /* PROCEDURE: Poll_SO                                                                                                        */" G, {; ]* G* ~3 I" s( J( Y
  216. /*                                                                                                                                                */3 ^! {9 f# J6 x
  217. /* This procedure polls for the SO line during AAI programming                  */- F+ ~4 Y  @9 u  P6 |$ A, i4 Z
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    . K) ^' Q3 {' u
  219. /* is completed                                                                                                                        */
    5 j+ V) ?& G) _' T/ s$ f
  220. /*                                                                                                                                                */
    5 Y0 ]) L( s# K7 E
  221. /* Input:                                                                                                                                */
    9 x) t5 q8 k# K# i6 y
  222. /*                SO                                                                                                                                */
      A; U$ ]$ I& C# S
  223. /*                                                                                                                                                */2 [1 X7 |- _* U% j  K$ h1 C1 Z( G
  224. /* Output:                                                                                                                                */
    ; g7 Y$ G* L6 W0 i. U
  225. /*                None                                                                                                                        */; f! }; M; s6 ^
  226. /************************************************************************/
    ' T3 E1 w+ K9 a
  227. void Poll_SO()
    * j( \/ Z2 q1 d* _
  228. {
    ' X6 K" a) R  Z
  229.         unsigned char temp = 0;
    0 V. E' [; X! H% u" Y
  230.         CE_Low();
    5 \5 v0 f6 P6 Z$ b8 b6 |; r
  231.     while (temp == 0x00)        /* waste time until not busy */
    ) i4 A* ]5 }: x% r. y+ c: X
  232.                 temp = SO;
    1 y- K, ^! K: @* G: O
  233.         CE_High();7 x! v) V2 [; ?( y- J' t# ?
  234. }3 b3 K$ R# O; h7 n3 V- ?% h

  235. " H  u, W: D, F: ^
  236. /************************************************************************/
    6 i( q/ Z8 v$ Q9 `. W' H
  237. /* PROCEDURE: CE_High                                                                                                        */
    6 s9 b/ Z/ k3 r/ q0 M1 U
  238. /*                                                                                                                                                */
    / Z* Y! q% Y% @9 G& n; L7 y
  239. /* This procedure set CE = High.                                                                                */, q6 @6 X! C0 [& @
  240. /*                                                                                                                                                */6 }8 H+ {) o9 d1 b0 B- k
  241. /* Input:                                                                                                                                */! E- `( q  S3 Q
  242. /*                None                                                                                                                        */0 x6 Q) N' s7 m
  243. /*                                                                                                                                                */
    ) M6 f$ S& j9 |6 ^0 ^' {5 f) J
  244. /* Output:                                                                                                                                */
    * o8 W" y& l1 ~2 M/ q, C; r( ]
  245. /*                CE                                                                                                                                */( |1 [1 O* s- S# h+ g# q8 h
  246. /*                                                                                                                                                */2 `6 T3 a$ z2 r9 j
  247. /************************************************************************/
    % g  B1 y2 G, B" F: _$ Q
  248. void CE_High() : X! ~1 F5 Q6 D, a! E
  249. {
    ; f/ X$ T) K0 }/ e) k; @" w! ?
  250.         CE = 1;                                /* set CE high */
      U9 i6 x! s. [. Z) k
  251. }
    - R- f. H) L( o! I
  252. - i$ i2 E& J. Y* @% j
  253. /************************************************************************/
    $ x- r8 i. b0 m% W& W. a/ Q
  254. /* PROCEDURE: CE_Low                                                                                                        */4 r% _* Y( h9 r" m) J+ f( f. Y
  255. /*                                                                                                                                                */) Y4 q5 k- U3 F. q" t
  256. /* This procedure drives the CE of the device to low.                                          */$ Y+ t( v+ q# ~1 h! H& c* X
  257. /*                                                                                                                                                */5 X. |+ I) u3 _7 Q8 j
  258. /* Input:                                                                                                                                */
    + s0 M/ K0 {6 J( C/ E9 T' G- p$ h3 L
  259. /*                None                                                                                                                        */8 K. A1 Q# C3 I! Z
  260. /*                                                                                                                                                */+ e- j7 P+ d5 b6 c
  261. /* Output:                                                                                                                                */: p5 c$ q+ o! [  g) E1 t
  262. /*                CE                                                                                                                                */
    5 g& X8 L5 R( y3 h8 p7 K3 s2 j
  263. /*                                                                                                                                                */) H, D$ o1 g6 X1 X3 f; g9 M$ `
  264. /************************************************************************/9 b  ~2 I; w+ U' [* ?" F, B" c5 R
  265. void CE_Low()
    ( ~' E4 |6 E) ?' y' Z& f8 y
  266. {       
    & e( [* b, L6 a% |5 Y9 z6 x9 N1 d
  267.         CE = 0;                                /* clear CE low */6 k* E2 [4 h0 L3 f8 [* q0 ]. h9 O
  268. }6 _+ g' Q& u6 H) u# Z  E( T/ r
  269. 6 x& K, }) }+ Q) B* ~/ ?
  270. /************************************************************************/
    5 ^) Q$ O, m6 O( {2 c
  271. /* PROCEDURE: Hold()                                                                                                        */8 o, z+ J9 k5 ^' r
  272. /*                                                                                                                                                */
    : q1 i( l, D; ]6 C. D. q  {2 O
  273. /* This procedure clears the Hold pin to low.                                                        */+ E' [* ~% l0 x' c4 X7 a4 C. j
  274. /*                                                                                                                                                */
    8 o( l( a9 Q  B1 _
  275. /* Input:                                                                                                                                */) D! j$ }, R$ R" ]
  276. /*                None                                                                                                                        */) o' Q2 B3 h  Y) v
  277. /*                                                                                                                                                */% `, b2 _& S3 u+ |% W
  278. /* Output:                                                                                                                                */$ v  f$ w2 r) M7 H
  279. /*                Hold                                                                                                                        */
    / ^! g+ c& x0 \  H0 u+ P, S
  280. /************************************************************************/) `3 _+ f" q% X% ^5 g& M8 m
  281. void Hold_Low()/ B4 b" S4 [* `
  282. {& k4 ]0 J9 i& \8 ]6 I5 ~- I
  283.         Hold = 0;                        /* clear Hold pin */  C6 Z% H5 v  I% I
  284. }
    4 K! z+ @8 w; J6 |5 |  o

  285. , I9 m; l4 E4 j/ H5 Y3 f3 O8 j
  286. /************************************************************************/% b/ `0 H2 Z1 D& z
  287. /* PROCEDURE: Unhold()                                                                                                        */. o! A7 M" V1 x9 @
  288. /*                                                                                                                                                */
    % k5 b! C; ?3 U* v
  289. /* This procedure sets the Hold pin to high.                                                        */
    7 j# P# s% `) _) ]
  290. /*                                                                                                                                                */# M  m- H$ F6 x! b6 d
  291. /* Input:                                                                                                                                */  C( \/ [$ ]' A3 ?
  292. /*                None                                                                                                                        */( W1 L. A* B- r! d9 \0 Q
  293. /*                                                                                                                                                */6 X2 I# T. C" q
  294. /* Output:                                                                                                                                */
    # Z0 d( y1 R8 ?' w! |# z5 @; C
  295. /*                Hold                                                                                                                        */4 T0 S; ^& r+ M8 P) k0 W1 J
  296. /************************************************************************/
    4 y8 f9 a% T8 T
  297. void Unhold()' b, J9 t( V6 |: m" N7 B/ Q0 q3 n
  298. {
    % l6 ?' e+ |5 Q3 n, ]" C
  299.         Hold = 1;                        /* set Hold pin *// X( X8 [- Z) g" {; l8 b- f5 Q4 _
  300. }* W  p. P! k% B% X2 K. u
  301. 9 S* l* o6 ~' q1 N0 z# r
  302. /************************************************************************/
    2 \: S1 s) k) a* W- |/ ^
  303. /* PROCEDURE: WP()                                                                                                                */
    " l1 l5 C! O1 I# U; D
  304. /*                                                                                                                                                */; J- z' o- A: ~6 i" v) E/ ?
  305. /* This procedure clears the WP pin to low.                                                                */) f7 P# ?/ g# E; m1 W& x
  306. /*                                                                                                                                                */
    - l. \+ p" ]4 \3 E4 w9 o
  307. /* Input:                                                                                                                                */
    4 Y) V$ q5 a" s+ t) s
  308. /*                None                                                                                                                        */
    6 k7 ~4 H  s) G) @
  309. /*                                                                                                                                                */% |3 L  T' j& {7 q$ Y6 Q' b2 t
  310. /* Output:                                                                                                                                */
    + _9 @: Y# I* ~! ^' L# F$ f) q9 a
  311. /*                WP                                                                                                                                */
    " N/ p; I7 V  Q. F
  312. /************************************************************************// n* Q0 i' ^+ W$ z( W" I
  313. void WP_Low()* C  o0 ^  L5 |: r/ r  |8 m1 u7 T* T
  314. {
    # E  M' i: I: m
  315.         WP = 0;                                /* clear WP pin */
    8 O8 o, P3 k/ m1 v% {
  316. }
    9 P" o4 U* k' p: Y! l9 t# k# T/ N
  317. 3 H, m* {4 x9 @
  318. /************************************************************************/
    9 @  Q- H) B. G& y; M
  319. /* PROCEDURE: UnWP()                                                                                                        */
    $ J, r2 i3 k% G6 p
  320. /*                                                                                                                                                */
    ; |. A: H' S) J5 z2 c
  321. /* This procedure sets the WP pin to high.                                                                */# N' a7 b/ R& ?$ e  X  h3 _/ X0 N
  322. /*                                                                                                                                                */
    - o  N/ I2 R0 _( K$ S! Y8 n8 V
  323. /* Input:                                                                                                                                */( L+ F) ?& s( j7 u- R. k+ w9 q+ @
  324. /*                None                                                                                                                        */
    2 P, P) V% q% I1 n. U' w
  325. /*                                                                                                                                                */+ o& ^+ G/ I8 T) R" D
  326. /* Output:                                                                                                                                */
    6 v# a& Y9 a. g
  327. /*                WP                                                                                                                                */
    8 `$ P# i2 z+ L( X2 Y& u
  328. /************************************************************************/  j, }* ]7 a4 _; P6 B
  329. void UnWP()) K* v7 X# i$ E. s" ~
  330. {
    3 u; f5 H# h8 Q" |" k' S/ n
  331.         WP = 1;                                /* set WP pin */
    7 P2 _1 z+ ?. ]; O" r
  332. }
    , Y( Z* ^/ d6 O  t

  333. + x. o7 n5 r, b+ i0 L7 H" G2 z* Z
  334. /************************************************************************/3 L2 y- y8 o2 V( g
  335. /* PROCEDURE: Read_Status_Register                                                                                */4 m, T0 V/ V% r7 T: J, y9 m4 }
  336. /*                                                                                                                                                */( D0 ]2 F2 h- y/ @. j2 F
  337. /* This procedure read the status register and returns the byte.                */: a1 l$ h7 W; w( c" x' `
  338. /*                                                                                                                                                */7 V' A  i% l* J. `# k" s! J
  339. /* Input:                                                                                                                                *// }3 k: S! O3 H' n, R
  340. /*                None                                                                                                                        */+ O# ^7 }# C" R. \8 ~
  341. /*                                                                                                                                                */7 z2 I) `1 a, o, B- m& E' H0 b
  342. /* Returns:                                                                                                                                */7 q! ^7 }6 I& I: L$ O+ _" L9 k; X
  343. /*                byte                                                                                                                        */
    4 j( N; U( m' H, f4 ?! f
  344. /************************************************************************/# _; i2 T# D3 I# l8 o
  345. unsigned char Read_Status_Register()
    ( P: [& {9 s# k4 O
  346. {* m5 D/ b, `, m& K
  347.         unsigned char byte = 0;
      j1 P; H; N3 j7 e0 B: c4 v  ~; d
  348.         CE_Low();                                /* enable device */" ?& E& Z: ~- }* x  D4 R
  349.         Send_Byte(0x05);                /* send RDSR command */7 a" A& F  O+ I  x8 F7 H) E4 r
  350.         byte = Get_Byte();                /* receive byte */
    0 g" A; n4 |3 w4 J; ~, d, J
  351.         CE_High();                                /* disable device */) z% y+ r$ N8 e! [+ x
  352.         return byte;
    7 h" f# t9 F8 m8 N& g" ^
  353. }
    ! H5 r( |$ _: Z3 b( M

  354. ) D# L6 a7 I$ Z  Q; H$ R$ A
  355. /************************************************************************/
      q- X+ ?9 C" ]9 `  c" M; ?
  356. /* PROCEDURE: EWSR                                                                                                                */9 t& b6 J% E$ V  I% C* w
  357. /*                                                                                                                                                */6 X: D1 v' r0 r% v9 \# y+ d
  358. /* This procedure Enables Write Status Register.                                                  */
    % C3 d5 ^: c/ A; A3 p  r# I
  359. /*                                                                                                                                                */
    8 n$ m& _9 q5 k; r1 l
  360. /* Input:                                                                                                                                */
    % C% U- G# a; B" J% |! U1 [
  361. /*                None                                                                                                                        */0 Q; O" H5 s; v/ C5 L5 @" x" _
  362. /*                                                                                                                                                */& a/ C6 y4 Y4 h4 [
  363. /* Returns:                                                                                                                                */  H5 e8 G/ I  H9 w8 g
  364. /*                Nothing                                                                                                                        */6 S$ n+ |9 L7 O8 w
  365. /************************************************************************/, B. a7 e# i0 a! y7 @' i  E- l, i# K
  366. void EWSR()
    / ~6 J  V, M+ ]( o' \9 Y4 |
  367. {9 \3 X! S/ h1 |! Z: v& }2 j6 q
  368.         CE_Low();                                /* enable device */
    ; Q1 l( ], F! f8 ^+ P& m
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    : j. h0 _! i& p9 M1 }
  370.         CE_High();                                /* disable device */' q: t$ b0 T+ _1 \0 \6 I
  371. }  q; m5 P+ d( H9 E3 e" T* L  t

  372. 5 q) e' v8 u# [- Z8 f8 O
  373. /************************************************************************/
    # ]; ]; s7 D# b* H8 h* s% S
  374. /* PROCEDURE: WRSR                                                                                                                */
    / _( r8 g) d, S5 u
  375. /*                                                                                                                                                */
    " k" T: J  m/ C+ _* R! ~
  376. /* This procedure writes a byte to the Status Register.                                        */
    : |# {5 e4 `2 I
  377. /*                                                                                                                                                */( ]/ a" U- C7 d/ `
  378. /* Input:                                                                                                                                */  ?4 k, x7 u7 i" Q, k
  379. /*                byte                                                                                                                        */
    3 I3 R& m1 z) d4 b  T, Q$ {7 M8 @
  380. /*                                                                                                                                                */
    , m9 a/ m0 Q2 F0 a
  381. /* Returns:                                                                                                                                */- t0 h+ N9 ^( P8 G8 b- j, O
  382. /*                Nothing                                                                                                                        */
      p2 g8 n" @# `1 q0 M: ?" c$ I) B
  383. /************************************************************************/
    5 Q2 \# E- z& [, ]- e
  384. void WRSR(byte)0 X: h: J; ^8 m) D* w
  385. {3 N. p% g: ?3 F! z$ |5 f0 ]
  386.         CE_Low();                                /* enable device */- C; V# J8 `/ n2 k' B! {
  387.         Send_Byte(0x01);                /* select write to status register */; x7 [, Q: O9 m- C
  388.         Send_Byte(byte);                /* data that will change the status of BPx : G8 v7 y6 f* N9 ?
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */$ r2 z& l$ ~# i: p  N
  390.         CE_High();                                /* disable the device */5 v& r: Z. ]0 w" [7 c" E
  391. }5 M5 q- r2 h0 h+ F
  392. : {. p2 w% R; q3 ]! H$ u
  393. /************************************************************************/* R5 |8 N1 C1 L( z0 M, V
  394. /* PROCEDURE: WREN                                                                                                                */" X1 Y6 ^$ [; H& f* V" N$ u) |# g
  395. /*                                                                                                                                                */
    ! h# d: r* C+ f
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    " Q  d7 E& t% I: T: h$ l
  397. /* to Enables Write Status Register.                                                                        */
    2 m, v" K1 V* E* p4 t
  398. /*                                                                                                                                                */
    6 @& e! _  n# X) V# q& q$ g* `
  399. /* Input:                                                                                                                                */+ M% D# G" N3 x9 {8 w
  400. /*                None                                                                                                                        */" A, S) a4 h$ S
  401. /*                                                                                                                                                */8 k* ]& X# s  p2 H) C& W; l( G
  402. /* Returns:                                                                                                                                */- @0 d5 \% m! D9 u
  403. /*                Nothing                                                                                                                        */7 K& \8 i) W# S4 G7 X/ ?
  404. /************************************************************************/: T( W# p" u. `/ j
  405. void WREN()) P2 F+ N4 F% V, D7 F* y- r
  406. {2 O( d) s, V4 x, s5 _
  407.         CE_Low();                                /* enable device */
    + ?) k: v; \/ _# s3 {
  408.         Send_Byte(0x06);                /* send WREN command */
    9 \* s, q: I( B9 v5 {
  409.         CE_High();                                /* disable device */* _% \+ T6 T* c- }
  410. }
    1 _' M3 ?* |% {
  411. 7 c5 Z: ?% l$ l# j* _) [
  412. /************************************************************************/
    4 h  l/ q" N/ Y* l8 `
  413. /* PROCEDURE: WRDI                                                                                                                */$ i1 K: S8 `7 M- W; R' i
  414. /*                                                                                                                                                */! }3 M# \& y/ K* {
  415. /* This procedure disables the Write Enable Latch.                                                */
    $ M6 S! b- x! Y( n
  416. /*                                                                                                                                                */
    - g4 Y+ Y# w% z$ m% V
  417. /* Input:                                                                                                                                */
    7 w9 j# V$ j: W' P
  418. /*                None                                                                                                                        */
    & M2 A- v, Z3 ]9 D, [* t4 Z* m
  419. /*                                                                                                                                                */
    8 t7 k6 ?9 Y: P  R* V
  420. /* Returns:                                                                                                                                */
    ( F9 E' k' U  j% @% s
  421. /*                Nothing                                                                                                                        */7 g+ i! |6 U, W9 i
  422. /************************************************************************/5 \, l7 J; _* ^& W  N
  423. void WRDI()
      v# K: Q$ q. r: a  D; M8 t* {. W  r
  424. {
    6 j1 q% _  y1 x5 x  |5 \. m
  425.         CE_Low();                                /* enable device */" r" h9 K& ?6 l5 [, W2 l4 R
  426.         Send_Byte(0x04);                /* send WRDI command */$ y! O& q( A8 ~+ Y* |
  427.         CE_High();                                /* disable device */
    6 D7 D/ q4 ?% D" q
  428. }4 h2 U" S# g: c& e& _  n
  429. ' m3 {  R& U; D
  430. /************************************************************************/
    + U9 T8 a+ B0 k! B  O: R
  431. /* PROCEDURE: EBSY                                                                                                                */' q& q) k5 s( M2 i+ O5 J, Q
  432. /*                                                                                                                                                */5 `8 f- B+ J' {  ?; b1 F- a# n
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    $ ^1 `: b4 s2 M: E" J3 B" @( F- I. D
  434. /* programming.                                                                                                                        */1 N4 a" m% H+ s
  435. /*                                                                                                                                                */
    * m3 {# l% f( x4 g; y: [/ P
  436. /* Input:                                                                                                                                */
    / _# F  ]' R+ }
  437. /*                None                                                                                                                        */9 M6 P  L0 B- p
  438. /*                                                                                                                                                */
    : c0 k# K5 m% i% N4 Y% M' G
  439. /* Returns:                                                                                                                                */
    " P2 P1 K9 X+ @3 M
  440. /*                Nothing                                                                                                                        */7 o2 o& v, }- ~3 r% _. n
  441. /************************************************************************/
    : h' h  v4 a. b/ }9 n
  442. void EBSY()
    + C& i; N. U; o9 M# F! ?3 R) W
  443. {; {  W3 ]5 g1 y0 `2 p5 v+ a2 j' C" l
  444.         CE_Low();                                /* enable device */+ N5 u% m, z& U. S
  445.         Send_Byte(0x70);                /* send EBSY command */# _  ?5 B% i6 M  `$ W% q: w$ E
  446.         CE_High();                                /* disable device */
    8 H: p7 z# J% L$ L3 z/ J- \
  447. }
    7 S( x% @* m* b# O: j

  448. + }: e  a: {, U( n
  449. /************************************************************************/- `' G% \, C9 m5 s- M
  450. /* PROCEDURE: DBSY                                                                                                                */- A: U+ f2 ^% G: p  ^% F
  451. /*                                                                                                                                                */
    8 q8 s# _0 n5 C
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    . ]( c- _4 s2 L+ E, w
  453. /* programming.                                                                                                                        *// Q7 d: {: S8 W+ ~9 [/ S; B! k
  454. /*                                                                                                                                                */
    . m9 S7 l4 O" N. j
  455. /* Input:                                                                                                                                */
    : d- M) Z/ ]9 O2 e- V
  456. /*                None                                                                                                                        */9 \  ^2 A% a6 [+ Q* l, B3 \! v
  457. /*                                                                                                                                                */
    5 M+ {; c: k/ c# ]7 Q
  458. /* Returns:                                                                                                                                */
    ! D- z. i! A$ E1 G1 `
  459. /*                Nothing                                                                                                                        */
    3 l* |- J  T9 W( c
  460. /************************************************************************/# r# L! J( _5 G3 ^
  461. void DBSY()/ ]4 y) J& v# i; H  o7 q
  462. {8 n$ P- }) c1 T  k' g
  463.         CE_Low();                                /* enable device */; ?# c' C+ {' c
  464.         Send_Byte(0x80);                /* send DBSY command */% D' l: T5 d# L: x" r) B3 U: u$ X
  465.         CE_High();                                /* disable device */& f+ z& t$ L5 a7 r' Y0 `
  466. }
    2 p/ r% @3 h% c2 v/ Z3 B) m

  467. 1 W( K, g3 U6 X/ M
  468. /************************************************************************/& d; ^# s# y. h6 p
  469. /* PROCEDURE: Read_ID                                                                                                        */( D0 P% w" o2 q; X2 {
  470. /*                                                                                                                                                */
    : |9 C2 M3 _, y2 _
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */) f( d+ A" |9 P4 c; G/ N7 u& @: S
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */1 A8 W6 s4 B. W( x+ I, O
  473. /* It is up to the user to give the last byte ID_addr to determine      */6 d( I8 }. k4 i  Q
  474. /* whether the device outputs manufacturer's ID first, or device ID         */4 E' a0 D4 X1 }* f3 W2 A
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    7 ^9 p) ~0 F( j' K9 H% o
  476. /* variable byte.                                                                                                                */: ^9 g! s; X1 d' @% H$ T2 S
  477. /*                                                                                                                                                */
    . O# Q0 c% U% ]$ j: Y+ V( z
  478. /* Input:                                                                                                                                */; j* S: D1 K9 t) h( n
  479. /*                ID_addr                                                                                                                        */! O/ H5 C; G# D! P! {7 ~/ K
  480. /*                                                                                                                                                */3 t& `; @# t& \1 G8 D
  481. /* Returns:                                                                                                                                */
    5 p, S' A' g5 f2 [$ |. _3 O4 G" L
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */9 {8 o2 _1 @/ ?" w$ Y
  483. /*                                                                                                                                                */* {( ]: \4 |9 t6 a
  484. /************************************************************************/
    : t3 K1 A+ A- M2 [" H( ~' v$ x
  485. unsigned char Read_ID(ID_addr)9 d6 L# P  e# l: ^& e* `
  486. {
    8 u" l! `, L0 Z4 k6 p
  487.         unsigned char byte;
    2 G5 O5 U, z' n) e2 |
  488.         CE_Low();                                /* enable device */
    4 X; c3 |# g2 k
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */5 I: R  E2 a0 }1 `; X
  490.     Send_Byte(0x00);                /* send address */( q% e# q% ?: Q
  491.         Send_Byte(0x00);                /* send address */
    0 m' V8 e& \" o+ k* U
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    & _0 T" X( z/ k/ p
  493.         byte = Get_Byte();                /* receive byte */) m* K( N2 T$ u- A( @7 c. {
  494.         CE_High();                                /* disable device */4 p/ b' j1 b9 ~* ^$ A% Q4 b, ~
  495.         return byte;
    ( ]  K' R6 r" q; Z
  496. }
    1 V. f3 ~, B9 w7 e$ P3 K; g7 P- C
  497. + X5 x: H! f  B7 J
  498. /************************************************************************/9 @. f; j0 Y& o: m# U6 f) X
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    9 K. ?7 k; k$ h8 q' d
  500. /*                                                                                                                                                */2 Z( I0 i( _4 Y3 f1 F/ `  c
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */4 x0 s  S4 {0 r' ?4 u# s
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    . Q+ X& K( Y, D; Y
  503. /* Please see the product datasheet for details.                                                  */
    ' e! z5 R: Q. w+ @5 b
  504. /*                                                                                                                                                */+ A, @1 J3 T- W$ J8 a* m. I/ Y) H9 ^
  505. /* Input:                                                                                                                                */
    9 g* Z$ h3 C6 d$ E3 g; I0 W/ O1 w
  506. /*                None                                                                                                                        */
    0 _5 \5 n  B7 @$ \: t
  507. /*                                                                                                                                                */& H8 V+ j# F1 @  g
  508. /* Returns:                                                                                                                                */" ]# k# ?3 {2 S' D
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    8 _) S$ S# u" ?* ?0 P0 R0 h7 J
  510. /*                 and Device ID (8Eh)                                                                                        */
    - r& M/ W, J2 s4 ?; `  Z% ]& M
  511. /*                                                                                                                                                */
    . y# W3 t5 D# U& c
  512. /************************************************************************/+ f0 {7 i1 A7 x: G, e* X% x8 ?
  513. unsigned long Jedec_ID_Read()
    & x! c6 Z! i9 L6 ?' N2 p8 F* T
  514. {
    8 C% n! ~% r6 u. _3 w7 X. v% y
  515.         unsigned long temp;
    : G4 ]9 U. c& M! _2 `! ]* [
  516.         % i/ i$ ~; h$ s- l
  517.         temp = 0;8 ^7 u8 w2 A# v+ n* E$ S. D: c9 E( E! ~
  518. 9 |7 I7 U& E1 x0 v
  519.         CE_Low();                                        /* enable device */
    , k0 _& \# m  I2 A# `% Y
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */. T- B) t1 s2 \
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    ! M; ^! {, b" u/ l3 @, e
  522.         temp = (temp | Get_Byte()) << 8;       
    ; j/ T& X) J0 r) v
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E *// H! {) Z5 K( h4 y( A( j
  524.         CE_High();                                                        /* disable device */
    1 h3 ]7 V: P! }1 v
  525. / m0 K- c+ D; z1 n
  526.         return temp;
    6 @) T5 c1 [$ M' }! B( n
  527. }
    . Y/ s/ y# \" i; a$ U: T" l9 s* K) l

  528. ) O  ]8 c; b0 u) U
  529. /************************************************************************/
    6 S+ g) g& L7 D1 Z, V# Y/ n5 p& F0 A1 U
  530. /* PROCEDURE:        Read                                                                                                        */$ {9 ]" p. ~1 C. N( a- s
  531. /*                                                                                                                                                */                1 I. o7 M8 L6 }1 y$ P3 T  H
  532. /* This procedure reads one address of the device.  It will return the         */
    * t& t! w" P4 I3 u* {9 h
  533. /* byte read in variable byte.                                                                                        */6 i+ Z4 s9 \. m* f. T/ {. w- w
  534. /*                                                                                                                                                */
    # i) K& Q0 ~4 D( o8 U# \# U' q/ G
  535. /*                                                                                                                                                */6 i1 A% E- j! ?5 S+ d2 u% ?# }
  536. /*                                                                                                                                                */
    2 O( Z8 F. h9 @! T( V
  537. /* Input:                                                                                                                                */; T% z5 ^* x) j$ ^! z
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */, y3 B6 o6 L9 |' n9 |9 g/ H; g9 {4 k
  539. /*                                                                                                                                      */
    5 X/ W4 G& a5 p% y" k% F* r
  540. /*                                                                                                                                                */
    ! e6 i7 W6 e5 v8 q8 u+ u' W
  541. /* Returns:                                                                                                                                */
    9 Q5 l" `! g. p
  542. /*                byte                                                                                                                        */2 l/ K1 D% C4 m! w% q/ u# n+ D
  543. /*                                                                                                                                                */9 V! ^* ^6 u$ T  s! [: d8 j! X+ C
  544. /************************************************************************/2 N" ?6 K! L, v. J* i
  545. unsigned char Read(unsigned long Dst) # X/ d+ y: f8 [3 m% P
  546. {& W# u. k% c' m
  547.         unsigned char byte = 0;        2 J2 V6 x  u% n1 @
  548. & T5 l4 V, b. e) J  Y* G" i
  549.         CE_Low();                                /* enable device */
    # `7 L( S4 K9 \5 l
  550.         Send_Byte(0x03);                 /* read command */" V% f9 {5 v3 g& d$ p
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    7 P" B- |# R$ Z# D- Z
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));: f$ ]# `, L! J. t8 ^* k1 t2 b
  553.         Send_Byte(Dst & 0xFF);
    6 B& m" C, P9 B5 N3 S9 E
  554.         byte = Get_Byte();
    3 Q5 x9 V* y' u/ W3 W- I+ \6 F
  555.         CE_High();                                /* disable device */
    5 S# R; u2 t! f! \* C/ z% K, A
  556.         return byte;                        /* return one byte read */  @7 j# p- f$ X" v. G/ K. m
  557. }- A6 c6 q: A5 F3 {9 B1 y+ t

  558. 7 T5 K2 _7 n! R" Q9 T' m% u
  559. /************************************************************************/) m& J$ P* \( `$ a" t8 G+ }
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    # {7 ^, _2 O6 J
  561. /*                                                                                                                                                */                5 u1 B5 H8 _7 O* @
  562. /* This procedure reads multiple addresses of the device and stores                */
    / Y/ u$ G" Q+ H9 q
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/3 M) g5 b7 t9 Q
  564. /*                                                                                                                                                */( h) Q+ e' I$ E% }0 D, D+ \* h
  565. /* Input:                                                                                                                                */
    4 X8 Q2 v; K* s/ |  _, Y+ b
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 X7 c/ D% t+ G( W
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */' T( c* r7 T8 t, d  }# X/ w
  568. /*                                                                                                                                                */
    ! R; K8 Q& J) z$ s- Y$ _
  569. /* Returns:                                                                                                                                */
    1 E/ n. j# n; S
  570. /*                Nothing                                                                                                                        */
    7 O( ^/ @& I5 {0 I7 G% t; i2 k
  571. /*                                                                                                                                                */
    % D3 M; {3 V# C+ f1 p2 U
  572. /************************************************************************/) R! Z! v1 r; h
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ; x4 h3 P# |  k0 X4 j, [
  574. {
    1 Z+ R# w9 D5 h; ^$ w
  575.         unsigned long i = 0;# C& ?; W0 g/ n6 y( o) R% C: U
  576.         CE_Low();                                        /* enable device */
    ' C' L/ o- v5 h
  577.         Send_Byte(0x03);                         /* read command */
    ; x: [" [; O  i4 r
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      \7 u" v6 z# r  h
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " L1 c& K$ x" T+ w: t2 G
  580.         Send_Byte(Dst & 0xFF);
    - P- h) C- g, k  h3 b+ W4 l3 A# V8 |3 L
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    8 p5 `, q# c5 ^
  582.         {: M/ ]8 w+ c* f* Z1 @
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    : ~8 O. k/ ?2 s8 `0 D
  584.         }8 Q+ t: ^0 u* l: H) E) q
  585.         CE_High();                                        /* disable device */" e$ T3 `- s. a0 n* t
  586. 8 C! l, @2 u( |7 {2 C, u
  587. }* ?" G# n$ \" l3 H3 e6 b

  588. ) j# Q6 [( ]) [3 J
  589. /************************************************************************/" m9 `$ G% B  `! R5 U! p: o/ o; w
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */; m9 P* d+ C9 q) ]
  591. /*                                                                                                                                                */                  h3 N8 i/ c/ {  B, v2 l: b
  592. /* This procedure reads one address of the device.  It will return the         */7 G5 ?" k- N+ v6 m( _
  593. /* byte read in variable byte.                                                                                        */; F" {% [* p$ |
  594. /*                                                                                                                                                */
    + j% T' \' V5 F# `
  595. /*                                                                                                                                                */
    9 s, j7 p' A3 O5 I1 m* C6 ^: v4 i
  596. /*                                                                                                                                                */
    / Z' B" p2 Q# p, s% v
  597. /* Input:                                                                                                                                */
    ! F: y7 K7 M$ q# T5 D$ s- V( ]
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */: Z5 k" [1 C& x" K
  599. /*                                                                                                                                      */2 [+ `( ^1 h% U9 M
  600. /*                                                                                                                                                */+ u  V$ F7 i4 w
  601. /* Returns:                                                                                                                                */
    3 l/ j8 M" _1 ?5 U" k% O
  602. /*                byte                                                                                                                        */! P: k$ ]* \) Y2 j  u7 s
  603. /*                                                                                                                                                */7 D0 d; p: h5 N  v
  604. /************************************************************************/8 x* o; D& I( {
  605. unsigned char HighSpeed_Read(unsigned long Dst) 6 q/ n$ o7 D2 Z3 F3 \% d
  606. {" t2 f+ U" g9 g6 i, F2 A! v& b1 r
  607.         unsigned char byte = 0;       
    + U5 z( m' u+ c/ F5 g) L

  608. " B  S0 A. V5 M. H9 x+ _1 ]
  609.         CE_Low();                                /* enable device */' N) B% i: U+ b2 ~* P
  610.         Send_Byte(0x0B);                 /* read command */
    4 V- A. q3 P/ o' P1 ~8 S
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */) k  W$ W3 E& y" k% I& V! W
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));2 K, G  w8 D; D7 ?1 y
  613.         Send_Byte(Dst & 0xFF);0 }' h6 N; |+ t9 J2 E# |" u1 U7 N
  614.         Send_Byte(0xFF);                /*dummy byte*/1 s2 e6 k7 B5 i3 X
  615.         byte = Get_Byte();9 L6 g# b( w9 m' I- v: R
  616.         CE_High();                                /* disable device */& a* b- }. H3 [
  617.         return byte;                        /* return one byte read */1 \% A' ]9 E% o
  618. }- p. c, E4 z6 O

  619. * H2 X* o/ ?5 @" x  j
  620. /************************************************************************/" A8 q$ E" ]+ h* q& Q; L
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    7 k4 v# Z  A0 i& ^9 s9 P
  622. /*                                                                                                                                                */               
    2 f# V3 o6 m! I* T& y, O
  623. /* This procedure reads multiple addresses of the device and stores                */5 ]" j; G# {- K8 I2 P: L
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/  t9 `' x; c3 x/ D" u/ l' r( k4 a! k
  625. /*                                                                                                                                                */* X7 ~7 N0 s. T, U" p
  626. /* Input:                                                                                                                                */  r, f: t/ W  h8 _9 A
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: @. X6 D+ Q( ^* {+ G5 }  y; D3 H
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    4 B0 v! b4 C( h
  629. /*                                                                                                                                                */
    ' I0 a2 g; z2 n! }* j) K
  630. /* Returns:                                                                                                                                */1 r$ ^4 V# L& g; z' v( R/ f
  631. /*                Nothing                                                                                                                        */
    7 j/ y7 ~3 U% u# h( f
  632. /*                                                                                                                                                */) ]7 J) _0 a+ k
  633. /************************************************************************/( u: Q% b- @& e% }; U
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    " H0 h, w* L9 I1 U* O
  635. {2 {7 n& G) n2 ]( z
  636.         unsigned long i = 0;
    ; Q1 }( G& I6 u, A* I- P
  637.         CE_Low();                                        /* enable device */: H) j6 n5 s8 q" b5 F. T
  638.         Send_Byte(0x0B);                         /* read command */
    / J" C7 [! o; g2 X8 `, W4 }
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' E) `. ^$ p+ o6 b! \: V# d
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));' G0 i, E0 F) [8 j
  641.         Send_Byte(Dst & 0xFF);
    ( v7 P: G' p: y. }
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    / B7 \0 g& S6 j' b+ I
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 R9 I5 t" u1 ]3 h" D8 p
  644.         {
    & c7 u' t' \8 d" k: [
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    1 A" J# M( W$ w% y0 J
  646.         }" R# w: N7 J) K& }$ u: r
  647.         CE_High();                                /* disable device */
    9 ~  [2 m$ y8 b9 y
  648. }
    8 l8 |: s5 p  U

  649. + P4 q# u" P3 @/ c
  650. /************************************************************************/. n  `1 ]4 ]; e4 \$ n7 ?4 p
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    5 F$ f$ ^4 F6 b- r
  652. /*                                                                                                                                                */! h0 s/ Y; _* p  s- G; ~$ x
  653. /* This procedure programs one address of the device.                                        */
    & P% f4 S2 _" u4 p; T+ y
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    " H  R9 d+ j8 S/ F; j: O! a
  655. /* block protected.                                                                                                                */; p, t' S; e) o  f
  656. /*                                                                                                                                                */$ D. v' A) |8 i5 g7 |
  657. /*                                                                                                                                                */
    ) U- G7 l! }4 y* @5 m1 {
  658. /*                                                                                                                                                */
    $ ~+ Q" A6 D* E  |$ n0 B
  659. /* Input:                                                                                                                                */1 ~/ T/ W$ S" I2 R
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - ?( \+ a5 M. A, h, E, w9 i
  661. /*                byte:                byte to be programmed                                                                */, o, L1 x; G$ n3 l
  662. /*                                                                                                                                      */
    % n; d* g* Q5 P$ Z' i% F
  663. /*                                                                                                                                                */
    5 W- p8 Q5 d  Z$ s; Q& ?
  664. /* Returns:                                                                                                                                */
    . ~; T, o0 ~1 J% M4 J
  665. /*                Nothing                                                                                                                        */
    ! P5 H6 |5 C' g* E# q% ~
  666. /*                                                                                                                                                */
      l  D( @0 N/ k/ o
  667. /************************************************************************/
    * u) F+ d+ V$ E" b; S
  668. void Byte_Program(unsigned long Dst, unsigned char byte)1 z, K0 g# F. q: h
  669. {
    ! Q5 N: x1 e2 j& Q
  670.         CE_Low();                                        /* enable device */. H. @: {: i* M) z0 I, {- \% l
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    8 k+ D2 _$ r8 q( f
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    & O! l/ `, u. M& _: e
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));1 ?' r) i* R* k$ Y9 z
  674.         Send_Byte(Dst & 0xFF);! L/ D, G2 x6 X# j
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    $ s: i6 R2 g& h
  676.         CE_High();                                        /* disable device */
    " _! a- \- u: G3 C! n5 ^
  677. }
    ( q: v% L% ?( n7 N

  678.   I3 j- F2 e5 D
  679. /************************************************************************/
    ! t+ q2 i# `+ c5 z% ^
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    2 X3 r$ N5 Y9 m/ ^9 k# h4 \) H
  681. /*                                                                                                                                                */
    $ `7 r: \: P' v' J9 \) ~
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    / \$ I4 Z5 _. ]
  683. /* the device:  1st data byte will be programmed into the initial                 */+ U5 _0 K1 n& ~$ f0 m
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */5 O8 J4 ]$ Y- k2 W
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ) K8 a6 f" p( F3 A
  686. /* is used to to start the AAI process.  It should be followed by                 *// `0 G, [8 D: J: Y+ m- G/ G2 G
  687. /* Auto_Add_IncB.                                                                                                                */* q: b: T% k* z' A8 {
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    " K$ i* h; [$ m
  689. /*                                block protected.                                                                                */1 m$ n' l+ ?- t: a. W- j5 p
  690. /*                                                                                                                                                */: z; Q4 W' h9 A' k
  691. /*                                                                                                                                                */
    * r9 V3 r7 h* K- M/ n
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */- Y, I) b% c& d; A9 s
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */+ P' o* C" x9 a. ]3 ]8 h
  694. /*         unless AAI is programming the last address or last address of                */6 P8 X: p2 g. Z9 \" d% T
  695. /*          unprotected block, which automatically exits AAI mode.                                */# t+ @  \% |+ H
  696. /*                                                                                                                                                */
    9 P' `% t* f, Z3 m( C$ l: e; c% e
  697. /* Input:                                                                                                                                */
    ' d) u: Y" ^5 f- g) Z) Y9 F
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 c" r" G3 X: I3 q+ @
  699. /*                byte1:                1st byte to be programmed                                                        */5 F1 z: F5 O  }( r1 z4 e1 e& W0 M+ `
  700. /*      byte1:                2nd byte to be programmed                                                        */9 G! f$ G: u* B' z
  701. /*                                                                                                                                                */7 `# l! V& U, @: ~
  702. /* Returns:                                                                                                                                */
    3 o1 f' U/ N/ ]( o  H( S  ]2 U
  703. /*                Nothing                                                                                                                        */
    7 R. u& R8 o6 y( M( O1 Y
  704. /*                                                                                                                                                */5 ?# x  C; I/ `& h- D' i
  705. /************************************************************************/
    7 L" T; {3 V6 r' Y4 q7 U# R
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ) R7 H. o! ^# Z5 z5 T
  707. {
    ; I9 p, f1 R( Y+ Q
  708.         CE_Low();                                        /* enable device */1 D1 o! }" p* \" g4 n7 m) K& t
  709.         Send_Byte(0xAD);                        /* send AAI command */$ C- t& C# l5 x! |" C
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * g5 r$ w! w5 I! H+ b7 P4 d* K
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % |: s. P  Q) p$ J. y" @  G2 [
  712.         Send_Byte(Dst & 0xFF);
    5 F% P, c" b1 v, ~$ A
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ( M6 z+ D# h" y) e: s7 T/ K
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */* N9 j7 N! p2 y
  715.         CE_High();                                        /* disable device */
    3 q' R7 D- d9 }5 Y# c& o
  716. }$ s4 C1 x! h, B6 k' {! g# T7 N

  717.   W7 \2 P0 R  X
  718. /************************************************************************/
    3 Z4 e$ n+ H5 s* L
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */* v* m& _1 o% T1 Z6 K
  720. /*                                                                                                                                                */7 C# v6 ^& o8 Y7 B
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/0 y) C, @1 \) n+ v: u$ b* v1 W- s3 Q5 a
  722. /* the device:  1st data byte will be programmed into the initial                 */
    , ]9 ?) _9 F8 G, _# l7 V5 {/ c
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    * b% Z4 K1 O: \9 x
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */+ w# D1 z: Q7 B" l/ s
  725. /* is used after Auto_Address_IncA.                                                                                */. G1 T- O% W* V8 Z3 U& n
  726. /* Assumption:  Address being programmed is already erased and is NOT        */& g1 i7 r' `/ N, l4 r+ ~* I
  727. /*                                block protected.                                                                                */) S) R4 I5 j. b9 u6 [. X+ a: c1 T
  728. /*                                                                                                                                                */! u: _; v$ M8 P4 i# e0 w% {
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    0 `. F5 a" p& \! _
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ) ]& d( J: \! q  `; o  A6 s$ u
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    0 c* Q$ [) J0 P  B: Y* u3 Y
  732. /*          to exit AAI mode unless AAI is programming the last address or                */6 m. a' t6 N' v0 `$ b, j# n, z
  733. /*         last address of unprotected block, which automatically exits                 */" ], b) n- }1 p, @. d+ {; x
  734. /*         AAI mode.                                                                                                                        */" \/ b  q; l- G- S* X
  735. /*                                                                                                                                                */) f+ t& B2 a7 o: y1 I, E
  736. /* Input:                                                                                                                                */
    ' o: E1 d$ S& k+ X
  737. /*                                                                                                                                                */% {/ B% N$ l& K9 Q/ r
  738. /*                byte1:                1st byte to be programmed                                                        */
    0 g* Q! S" T$ ~: h6 K$ X
  739. /*                byte2:                2nd byte to be programmed                                                        */
    % r$ T0 J- I/ x& b+ W; h: b: o
  740. /*                                                                                                                                      */' i8 i; _+ g  g& c& C# Y6 a7 ^3 |
  741. /*                                                                                                                                                */
    " U7 ]3 q7 y& [* Z! N4 P4 u& `8 r# T
  742. /* Returns:                                                                                                                                */
    ( \9 F. _  N+ A5 U* u
  743. /*                Nothing                                                                                                                        */, x; P9 y1 I* ?
  744. /*                                                                                                                                                */8 O; h! ^" j; s  _* H2 O/ ^# L" L
  745. /************************************************************************/
    . |5 Y7 D8 w, ?% |. z  r
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)* Y' [1 g. @/ _3 U
  747. {  f7 j! J3 k  ?, D0 @7 I5 F9 \
  748.         CE_Low();                                        /* enable device */9 S; \# M- I7 R8 T: N
  749.         Send_Byte(0xAD);                        /* send AAI command */$ E  W) V- O8 U* Y: |# M$ _+ ^
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */1 E8 R1 d4 l2 W4 O
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ; f4 E" P' L0 @* o# K% M" Q8 Q% L4 \
  752.         CE_High();                                        /* disable device */
    - y* u/ A# Y" ~4 i  _, w# J- I. `
  753. }
    4 O  D8 b% m$ q# s) p

  754. + m$ H+ e) |: l2 H. }% |$ c
  755. /************************************************************************/
    6 ~, u  h- z& i! |
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */! V% h& ]4 M5 U
  757. /*                                                                                                                                                */2 \; u$ |, k/ X. s6 w1 ~
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */  I/ _$ o. j7 S" n5 z" Y) q
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    4 Y, n# l, [2 T. D
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ) O; ~- }# p8 B
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    * m: C3 T. M6 L# i5 o+ q
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    0 r4 V/ w; d3 q3 u8 r
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */& p. m7 y' X' @  H) `  N/ H
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    $ ?7 k. D8 O% f1 b8 r: R* }1 o
  765. /* Assumption:  Address being programmed is already erased and is NOT        */* ]& o0 E" u' B9 S+ X" q( m0 c
  766. /*                                block protected.                                                                                */4 o* Y: F) H5 W
  767. /*                                                                                                                                                */
    # f7 d/ H1 F' g/ g+ P! e: l
  768. /*                                                                                                                                                */
    0 N+ X' M# j) q+ X
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 X. [3 |" L4 c7 j+ E
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */! h4 _' w: G. A3 g8 u9 c! H  U
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    , S5 k4 ?4 w0 r
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    ' O$ k1 r8 W2 l, a
  773. /*         last address of unprotected block, which automatically exits                 */
    $ s$ M6 l1 V  b: p  o: c: _
  774. /*         AAI mode.                                                                                                                        */
    $ l9 \3 |- R! W4 Y. W) M
  775. /*                                                                                                                                                */
    + D+ |5 K  q* p8 p
  776. /* Input:                                                                                                                                */* }/ ]9 R7 Z5 H$ _* X
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ k/ x& C2 s+ u. B) Y9 i7 @
  778. /*                byte1:                1st byte to be programmed                                                        */$ M4 o' U* a& v( q" D6 x4 ]
  779. /*      byte1:                2nd byte to be programmed                                                        */
    5 s/ Y) T: c3 j
  780. /*                                                                                                                                                */
    8 b( |5 ^" B+ \. C+ Z
  781. /* Returns:                                                                                                                                */
    4 m9 c$ g: l$ @# @4 q
  782. /*                Nothing                                                                                                                        */
    - u7 X5 e2 ]0 i* K, U
  783. /*                                                                                                                                                */
    % j, {2 b" Y+ q7 w2 t8 y  X  r8 ~
  784. /************************************************************************/
    3 q7 Z% k  {8 w0 q  A
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)9 j: u/ ?3 I" a/ E3 h: |
  786. {
    9 d- k# l; O& J
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        6 z% q" j# |  l: q) h( q

  788. : i" F, d. C4 y9 F
  789.         CE_Low();                                        /* enable device */$ E! t0 N0 r! q) `
  790.         Send_Byte(0xAD);                        /* send AAI command */
    8 `/ E0 K3 |9 C
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes *// D7 Q1 O4 y7 e
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));# ~8 q( g8 D+ K/ @+ t
  793.         Send_Byte(Dst & 0xFF);# g# A1 o7 }& n' l$ ?3 M
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    " n( C2 [5 O9 V9 ?9 }9 X
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */! a* S3 U  {! L& _3 ]- I
  796.         CE_High();                                        /* disable device */+ d) Z" Y, B7 ]' F4 a
  797.        
      M5 E: b, k: K& B
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    1 s0 _& ~# g6 s; e! b

  799. , n' ~6 p' H8 g6 Z) v, e
  800. }* s8 r5 L+ o! o7 _7 v4 l
  801. 6 q7 H, s' q; j- X" I+ [
  802. /************************************************************************/
    # I! Y1 P  z0 K, Z& I# S5 u, Q
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    " O! c* ?) z' K% ]
  804. /*                                                                                                                                                */9 o/ b# J5 i. G. O) s! ~! o
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    5 S( z/ p- P$ M& X+ ]$ t, C( A/ M
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    ) R# {' \) p* Y4 U! Q& E$ k
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    3 N9 C4 d3 h7 _" F6 W& A
  808. /* the device.  The 1st data byte will be programmed into the initial   */; {! ^6 y$ N: g6 D4 _# T
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    4 z% V' K# \5 Z% i& N7 o! Q
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */% b3 A0 D: Z( ^% l, W9 e5 D
  811. /* used after Auto_Address_IncA.                                                                                */: R* G, ^3 C# S5 V
  812. /* Assumption:  Address being programmed is already erased and is NOT        */. m+ C; m- e" j& x  _7 Q8 L
  813. /*                                block protected.                                                                                */3 D. k; f# V5 _: I0 x
  814. /*                                                                                                                                                */  N5 k- r" t! v# q
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 m9 L! B) P3 L  H% L7 J4 }/ w* z
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
      P8 b: {2 l# ?1 n, p
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */3 D5 a9 i- O, i2 d8 a- q
  818. /*          to exit AAI mode unless AAI is programming the last address or                */1 M/ e9 D/ F2 Q9 o: c* b
  819. /*         last address of unprotected block, which automatically exits                 */7 l# u4 }* b$ [/ z# L
  820. /*         AAI mode.                                                                                                                        */
    , A/ x0 H+ ~: ]/ v0 H
  821. /*                                                                                                                                                */
    / a4 L5 M! _' ?" q' O
  822. /* Input:                                                                                                                                */" `  Y9 ?, d, J* W. w
  823. /*                                                                                                                                                */
    . u! b* V5 }4 G% r  U
  824. /*                byte1:                1st byte to be programmed                                                        */! i# l3 E1 z, `4 E# s
  825. /*                byte2:                2nd byte to be programmed                                                        */
    5 f! t7 O9 Z' U* v% K7 c. P2 l
  826. /*                                                                                                                                      */
    9 P  i6 G9 R$ h/ i, X3 A
  827. /*                                                                                                                                                */3 b4 `1 K# J2 O5 g+ k7 [+ U0 k2 X# f
  828. /* Returns:                                                                                                                                */, E* j1 m; C% n9 T8 i4 Z/ g# @
  829. /*                Nothing                                                                                                                        */
    / h* c- r9 U  x; p3 D& y) W- s
  830. /*                                                                                                                                                */
    4 X% \2 |4 ^. z1 _
  831. /************************************************************************/2 {' u1 }. p9 m5 N- K; B- w( {
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    5 ^: G4 H( ?) g( Q
  833. {
    - v# d* H* _, {2 c# o8 i$ V& ]
  834.         CE_Low();                                /* enable device */1 h0 O$ O2 H9 ^: r5 X3 o, E! L/ _4 r
  835.         Send_Byte(0xAD);                /* send AAI command */9 N/ J% ?9 y+ E5 k
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */: r( R: O! N& k# H
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */. d, m: k, o1 I6 o) R
  838.         CE_High();                                /* disable device */; m/ S. ?0 F  \3 p- [. E8 e; v
  839. + q4 K) q8 @5 R; }, s+ [) u
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    3 B( D& n& ^- I2 a" g

  841. : t  R2 ]! k4 f+ M4 c4 ?
  842.         WRDI();                                 /* Exit AAI before executing DBSY */( x; k, z. f; x$ N% i3 C3 K& I1 S& U
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    7 g# p  s- f  [; i
  844. }) I" L# u! @, O6 H( B+ `/ |
  845. + p' n! U1 r( {* G
  846. /************************************************************************/
    8 f" U% G- l/ X( M  ]
  847. /* PROCEDURE: Chip_Erase                                                                                                */: K) U2 V  m( g4 l9 @
  848. /*                                                                                                                                                */
    6 |" _# {7 b3 _* ?) m1 k
  849. /* This procedure erases the entire Chip.                                                                */
    + c- B1 s8 U: b6 u
  850. /*                                                                                                                                                */. X3 R9 d8 P9 u/ Y' ^
  851. /* Input:                                                                                                                                */
    6 t: h( D* ^8 C. N/ J- X: n
  852. /*                None                                                                                                                        */
    ; }' G6 h% A% ^8 ~4 v
  853. /*                                                                                                                                                */
    . H: g& q) W6 s2 }5 M) a, ?2 E
  854. /* Returns:                                                                                                                                */
    & F9 O* M( p) i3 o
  855. /*                Nothing                                                                                                                        */# r3 U) |+ W& M( i% z6 }: Q$ @
  856. /************************************************************************/0 R, R- T: W5 R) ]0 O, P! }  M
  857. void Chip_Erase()" C; h% M, ?0 }; p/ M" B/ t
  858. {                                                " N7 Z; X; q- c- T; P" H, V+ M
  859.         CE_Low();                                /* enable device */+ j9 X/ z6 X- Q% A6 c! U
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */4 k$ {2 P; m" ~% @$ d- e  m5 H
  861.         CE_High();                                /* disable device */
    6 K: i; }: S5 B! {
  862. }/ V, I3 T6 X" k

  863. 7 b; [* P/ t7 e# i; c; n; `
  864. /************************************************************************/
    " R. ?" ?. O. O( s! ?' ^
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    3 P. Z# e, j7 H$ c9 _% m
  866. /*                                                                                                                                                */
      Q3 S9 X8 o! h
  867. /* This procedure Sector Erases the Chip.                                                                */
    / [/ ?) N4 p$ }  n8 ^" c+ E
  868. /*                                                                                                                                                */: b- C4 A6 M5 Z3 K
  869. /* Input:                                                                                                                                */9 c" R% w* V( ]- [8 ~  D4 a! G
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % n; c. |& u, u3 k! k2 ^
  871. /*                                                                                                                                                */  C+ n2 K/ Q: m! ?3 {
  872. /* Returns:                                                                                                                                */
    & U' `/ [% S# q9 f
  873. /*                Nothing                                                                                                                        */
    $ b% j7 t& d  v8 D# b
  874. /************************************************************************/* f5 C6 X/ `0 C0 B. `
  875. void Sector_Erase(unsigned long Dst)
    - Z% ]0 A' \+ X0 ^, h% K7 ^
  876. {
    3 |3 q" n* @" y5 D9 U2 q: [
  877. 7 l8 \* o, k8 f$ D9 y0 [
  878. & `% A. V1 i1 G! H- t- S
  879.         CE_Low();                                        /* enable device */% M/ Z* E3 o7 G( g. t7 |, w
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    : w6 G+ E8 \8 Y( X: z8 c$ \
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 o' L' ^; K3 k. a, V8 c4 G
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * p, M5 S# }" L! R
  883.         Send_Byte(Dst & 0xFF);; f9 s$ J0 C9 p9 I* n
  884.         CE_High();                                        /* disable device */
    ; w, s; [( J3 h
  885. }       
    2 y, C4 J8 Y9 [; j% {7 W2 {/ B

  886. 9 M; [' L8 h; V; i1 e+ Z
  887. /************************************************************************/( I$ r- V& o0 Q
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    4 j1 A3 B, q# K$ y5 D
  889. /*                                                                                                                                                */
    ; O. T+ c( ?) Q( A/ i
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    : i8 m- d! _; S( M: h
  891. /*                                                                                                                                                */
    2 W6 a- Y. P! U1 G5 d
  892. /* Input:                                                                                                                                */
    + k6 g/ @+ X, r$ i' B
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# p/ I2 w/ B+ ]  S8 t
  894. /*                                                                                                                                                */7 J1 z% P0 \) H7 x1 g7 F
  895. /* Returns:                                                                                                                                */- [2 S" g, z( n  Q; T8 R) T
  896. /*                Nothing                                                                                                                        */* [+ ?& K2 D% E" o0 a  s
  897. /************************************************************************/3 d) N; J& v# F9 s
  898. void Block_Erase_32K(unsigned long Dst)1 q/ [! l1 j. G- O' J
  899. {
    . f' S% v/ y: Z: Q
  900.         CE_Low();                                        /* enable device */( i) r$ [0 V1 X9 s8 Y0 s
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ' P. y( ]" f9 I  V
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 U3 b  E  Y. |$ Q/ d
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 l# B5 j8 z0 o5 l
  904.         Send_Byte(Dst & 0xFF);# o( M; P' f2 I6 D
  905.         CE_High();                                        /* disable device */$ H- O. F" p: t/ z$ k8 f0 q
  906. }
    7 x, j0 w: C' m/ Y  H
  907. 9 j/ v# O$ x& P9 }" s4 \9 X$ D* G4 Y
  908. /************************************************************************/( {  ]: v- s7 m
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */' o. n- Y% |) m0 |4 s2 H
  910. /*                                                                                                                                                */, w; m5 q( G% w+ `, D7 H/ W7 X+ F* |
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    6 x! e  z# N5 @& E3 ]2 H/ Z
  912. /*                                                                                                                                                */
    0 a/ p; {8 ^/ ~  z7 Y
  913. /* Input:                                                                                                                                */! F# Y. T5 y' ~' j
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) y/ T+ D- ^+ J' H
  915. /*                                                                                                                                                */
    ; F: n. ]! o9 e1 Q. _! r
  916. /* Returns:                                                                                                                                */( j0 ^: g3 c( T5 B
  917. /*                Nothing                                                                                                                        */- O4 d$ }$ g1 N: n- r; J  `
  918. /************************************************************************/
    % B/ P: u" `6 V8 L4 f; G0 M$ T4 R) l
  919. void Block_Erase_64K(unsigned long Dst)
    ( X5 {: j) z2 b& o2 ?
  920. {
      {. F8 O: [+ Q* ^4 l
  921.         CE_Low();                                        /* enable device */  s6 u7 {1 `6 k+ k$ V
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */; y# t% k3 U2 @# U9 [
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 U: e5 @( ?; M6 @- L3 D% [
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));# E5 |& l- y- f5 S
  925.         Send_Byte(Dst & 0xFF);3 Z; e/ {- y2 ]; m! g+ c
  926.         CE_High();                                        /* disable device */
    6 D) K" C6 V# A+ {9 B- I
  927. }4 W8 j' V% }' W2 U/ O1 ^# j3 U. I6 w

  928. 0 W  F) y" f% }  U# w) m* J! E
  929. /************************************************************************/6 K& G+ x6 K: ?& E
  930. /* PROCEDURE: Wait_Busy                                                                                                        */8 T& n- i3 `& `6 t: s- z5 @5 q
  931. /*                                                                                                                                                */; f) y+ B) A# r: K- q* Z6 P
  932. /* This procedure waits until device is no longer busy (can be used by        */0 ?9 ]8 }; n5 L
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */: O% Z- `6 k1 L% P1 e0 l+ ?
  934. /*                                                                                                                                                */' Z- @5 y0 M' r7 A, d
  935. /* Input:                                                                                                                                */
    1 J8 |0 h! _. `7 b2 _# D2 K' U! n/ C
  936. /*                None                                                                                                                        */
    ) o5 w" L/ Y5 `& K$ h8 G
  937. /*                                                                                                                                                */
    0 ^8 n: p) g! ^$ A
  938. /* Returns:                                                                                                                                */
    ' ]$ V9 {) K8 v, p8 N% O6 Q
  939. /*                Nothing                                                                                                                        */
    ! N, _! |* I7 K# k
  940. /************************************************************************/1 j$ q1 i! f: t8 J) }; T
  941. void Wait_Busy()
    ( ~* R9 h% C0 M% z- L$ C( ^
  942. {5 [9 i- Q9 [' e1 [; _
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    & o5 l: v# C0 {
  944.                 Read_Status_Register();
    7 F; j0 @! q5 l+ q+ ~  @
  945. }. k8 D1 ]. p  [% A
  946. % D, n, L9 c1 _; x% ]' v
  947. /************************************************************************/7 i# j- \$ V$ D5 ^, l' G; @
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    4 H# u' C3 ]7 f2 Q
  949. /*                                                                                                                                                */
      w- l$ E; @: Y8 q
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    - x% E, {/ s$ m+ z
  951. /*                                                                                                                                                */+ g! M2 d+ r$ J+ b
  952. /* Input:                                                                                                                                */; @7 x! ~/ I! O; |9 a& ^
  953. /*                None                                                                                                                        */5 B  r( u( c, b" b8 l; d
  954. /*                                                                                                                                                */
    8 `6 ^% F8 F. ?3 z( _/ C+ J
  955. /* Returns:                                                                                                                                */
    ) r' Y& m) x- l" o! {
  956. /*                Nothing                                                                                                                        */
    $ b  G: r* D, F* l
  957. /************************************************************************/
    : E. v* p; ]$ A, g) T$ ]9 [9 z! a2 |
  958. void Wait_Busy_AAI()
    " K2 Q5 S! y) a
  959. {
    1 \& X, U/ X* F; _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */# H2 j( ?) C3 k# [5 Q3 W7 G
  961.                 Read_Status_Register();
    2 a0 \/ K! ^4 J/ O$ n6 u6 V
  962. }
    * G3 Z0 \) G, h0 O$ b# R& Y  j
  963. * J5 `; B  O/ Q$ m& o
  964. /************************************************************************/
    . |% H6 g8 ]! A6 m. d( L( Q) p
  965. /* PROCEDURE: WREN_Check                                                                                                */
    2 I! P' a$ N, ~+ V1 Q  u& R  m
  966. /*                                                                                                                                                */; U* U/ C6 X' h
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    $ J+ g3 X" Y& S9 Z7 ~4 c: F
  968. /*                                                                                                                                                */1 A4 s  S6 w/ Q' m2 A" Z5 O+ b% Z
  969. /* Input:                                                                                                                                */
    2 |4 ^3 j" {  W6 G
  970. /*                None                                                                                                                        */% w6 n3 z" B% K2 V% s& d
  971. /*                                                                                                                                                */* X% a0 K7 D- }2 F9 A  n% Y
  972. /* Returns:                                                                                                                                */
    8 _9 R/ U: ?& B
  973. /*                Nothing                                                                                                                        *// y$ f" k& T3 k% @$ I7 B
  974. /************************************************************************/
    ! O4 N3 K% l/ E+ ^. ^
  975. void WREN_Check()" a) N+ y  v% D) e6 N4 ]
  976. {9 D" }) G: I6 P; E8 |- V4 Q
  977.         unsigned char byte;  M0 Q& D6 y7 n( }8 I
  978.         byte = Read_Status_Register();        /* read the status register */
    9 A$ c, D# r# D- }6 l8 j1 m
  979.         if (byte != 0x02)                /* verify that WEL bit is set */% f6 o( c: L$ a
  980.         {
    + f! H4 h/ p! Y4 k" Y
  981.                 while(1)( @2 Q4 W# Q, R) b& U2 O- C2 R: Q
  982.                         /* add source code or statements for this file */
    . T/ S7 K$ W; e8 E5 {4 O
  983.                         /* to compile                                  */$ ?. b, i- r8 d9 r
  984.                         /* i.e. option: insert a display to view error on LED? */# Z% M! U2 B9 e. a. l: d; Y1 `
  985.                  
    ; F3 T- u5 r+ j; Q6 D
  986.         }% Z) t" P8 _$ P$ E8 I1 e: T
  987. }9 b( R1 |" g6 ?1 g6 K$ V
  988. ) Y$ f( s/ ?0 P5 ^
  989. /************************************************************************/
    ) |. w$ h4 [; z# g6 W
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */$ {: w7 v- F+ N
  991. /*                                                                                                                                                */( R5 T$ J/ Y. Y
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    9 u( H$ O/ x, U) c7 }0 i
  993. /*                                                                                                                                                */
    5 M! {/ V, ^( L; x
  994. /* Input:                                                                                                                                */. r# J3 A0 Q1 W4 ~
  995. /*                None                                                                                                                        */8 Z8 W: V# @2 t; O6 T8 b- q
  996. /*                                                                                                                                                */8 E7 o( G& o2 m" W- |
  997. /* Returns:                                                                                                                                */) M% F5 e# _+ g4 W
  998. /*                Nothing                                                                                                                        */6 G  z1 e* T" @* Z' g+ E
  999. /************************************************************************/
    6 c  k5 y; g3 N- a( a2 [0 e8 Q, n
  1000. void WREN_AAI_Check()% [& D# t# ^6 F* s, |
  1001. {
    - j; D8 v* [+ |" z' u& @
  1002.         unsigned char byte;
    . q8 `4 u6 l$ K4 C7 P8 I1 Q8 y
  1003.         byte = Read_Status_Register();        /* read the status register */: [  D/ C/ S/ \4 j1 \3 L
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    # f5 Z+ r* ~8 u6 u4 w* W
  1005.         {
    ) ^  U, [0 L% W8 @* x
  1006.                 while(1)               
    8 M2 S/ u& b9 e) K+ S
  1007.                         /* add source code or statements for this file */
    7 e) y4 D/ J# o/ d1 N
  1008.                         /* to compile                                  */
    . s, l9 `0 ~4 ?8 g7 J
  1009.                         /* i.e. option: insert a display to view error on LED? */
    3 i  ~+ ~; T: m' D0 |1 Z
  1010. : i6 Y; z, H3 U7 L' B$ i
  1011.         }
    . B' v* E, C1 D3 D& ]
  1012. }$ x3 S" e) b1 z+ |$ u& L" R5 D
  1013. , c2 x: ]6 M* M- P( Q  K( q
  1014. /************************************************************************/8 Q9 p9 J6 M/ w! J# j  ~# F; _6 o0 E4 s
  1015. /* PROCEDURE: Verify                                                                                                        *// t0 [6 ]5 {; F4 |5 U
  1016. /*                                                                                                                                                */
    - D) E* ^0 W3 b8 U( M( V, P) d- k2 ~
  1017. /* This procedure checks to see if the correct byte has be read.                */
    # b5 r( \! s7 ^& d# R* s
  1018. /*                                                                                                                                                */
    . R0 z. Y6 a- N+ g" `- v- M: X
  1019. /* Input:                                                                                                                                */
    7 U" ~  H. N( l5 C
  1020. /*                byte:                byte read                                                                                        */
    7 Z1 o3 J) H: n; i
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ! @4 y5 P3 t0 E; n: l; C' O* A& v
  1022. /*                                                                                                                                                */& E" l9 q+ c0 Q, x+ u
  1023. /* Returns:                                                                                                                                */% U3 _4 C1 V5 ?; j" C; M# g
  1024. /*                Nothing                                                                                                                        */
    # T3 O" j# U# q# E
  1025. /************************************************************************/
    , e7 e; \# @4 @5 s% {
  1026. void Verify(unsigned char byte, unsigned char cor_byte)0 Y/ [( |0 L# T# @0 z$ D7 O$ @4 W
  1027. {
    4 N# O1 ^# V& V0 ^
  1028.         if (byte != cor_byte)( {( l( _8 @8 n* _
  1029.         {
    6 r3 R# l/ N) p0 E4 h  [  x) t
  1030.                 while(1)/ N* x  U% i4 W# F& F' B
  1031.                         /* add source code or statement for this file */
    4 ?8 W5 E7 f* J2 X" ?/ Z
  1032.                         /* to compile                                  */6 W& A! q6 q- ?( z
  1033.                         /* i.e. option: insert a display to view error on LED? */9 K4 s7 s  t4 K; t0 ~- l$ @& P
  1034.                 + w, X, j' M, P
  1035.         }1 d4 g! o- q8 f- ?: o
  1036. }" e" e- M& L& |, s7 L8 U

  1037. 1 ?1 g0 C: J9 |5 Q( Z
  1038. $ [$ }" R% v! [4 E7 }; M
  1039. int main()7 [1 \1 h4 y% l' B' P
  1040. {
    6 s- x( R8 y; y

  1041. $ N  v0 k% U% A( D4 j
  1042. return 0;; t: r4 |; T0 a  e3 Q- m4 U
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:( i* C9 [$ @0 f* V2 f2 Z
   main()2 m+ x% V1 `9 @# e; A9 M& G
   里面怎么是空的呢?
( h9 ~2 v0 w2 r2 }- \   发一份给我吧) F! H0 t( {- H/ B
mail:luyijun2005@hotmail.com
$ K4 e! d2 z3 J/ a& Q6 }咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。+ O! y( f; b9 A+ r3 e* `3 T4 p

; \- x: J7 d3 i! j9 Y: G; m: b[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。' {; i+ f4 i+ ~) @( p* t
EC的代码在哪跑,你看DS的说明,每个EC都不同的。" }5 P* }- M* w& f
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
  X, y: M) `& R' E- m上面几个问题是你没看任何东西而白问。
- x1 T3 d. Z, q+ A8 j8 V5 Q, F( [) ^& Q! Q
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
; _  c/ P% v) W( F. [; A
' `- w& z6 r) b5 n  P关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!* P* b; p: x( {5 p
# b9 a' x2 @1 c( a7 S
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
  V+ ~; X9 A3 s: t0 W$ q; M( U, G
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
6 n2 k) Z8 l: U# C9 K' J7 W8 I/ `( l/ o, W& A* a; s$ m: N5 i4 c
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
4 M; w% G4 B# c* g似乎要把SPI能support 到最大,这EC chip应该有好卖点
# p6 `% j4 `' ^4 w! TBIOS功能要不要强大,也就决定了SPI Flach的大小5 J% \$ j. D. |8 N# d
我是这么想的~让OEM去决定要挂多大!
8 i& N3 |! F. Y) Q0 j3 \* V如果我司有BIOS工程师就好了~哈2 R: e0 d3 Z) B' {) R
WPCE775应该算很新的东西,来看它支持到多大?9 G9 C' b% P& v) y

7 B( k+ a+ B  |5 D另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte2 i% ]' `* `  e; x7 d( Z7 ?
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
5 p' @/ |1 _9 _; {5 G7 d; K& @
$ C9 `1 V( P. P* |这份driver收下~希望以后有用到
+ X/ J3 b* n$ y  `( w谢谢bini大大
* K7 w& A; {7 \( b1 X/ P2 Q
1 g6 i6 D# j* b6 G很新很新的新手,如有错误请指正 (准备看第二家的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()/ _3 z) i2 x0 g% f2 @
{
( Y! W' L& E1 D! `: f3 I6 x2 f        unsigned char temp = 0;
9 g! o- @4 d. A+ e        CE_Low();9 L) ]2 D' ?1 `4 I4 y! F! d
    while (temp == 0x00)        /* waste time until not busy */
  Z# w* j- H# G" Y. w; r                temp = SO;+ I: E7 O; ^: Z' Y" F$ v
        CE_High();% {8 _+ r1 i8 j- N
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)9 W* s. ~' p. _% m- P8 Z, d
{$ Z( z3 N  I  y) c( F' F% G
        6 p( D( c0 h# ~( L% C8 d5 \
        unsigned char i = 0;
4 L3 d/ K: k2 Q7 k        for (i = 0; i < 8; i++)$ L- x$ {3 o- M" A5 M
        {& N( E! y6 B. j3 j) h
               
7 y# M) ~" M; Z1 O& s. y0 N                if ((out & 0x80) == 0x80)        /* check if MSB is high */& K0 v" G# L3 i( a% r9 h
                        SI = 1;3 A- y2 n, k! Y( ?, f
                else
) l3 `: ?; o3 X+ I% A5 t8 Z* _                        SI = 0;                                /* if not, set to low */4 q  y# X' K' n1 f
问              SCK = 1;                                /* toggle clock high */- s* R% Q9 p* r
   题            out = (out << 1);                /* shift 1 place for next bit */
0 J3 g, s7 S4 m5 }                SCK = 0;                                /* toggle clock low */+ ]3 h, U1 n" M6 }: m0 b$ _
        }2 J+ C2 r- B3 \# [2 s2 ?9 I
}
4 g% \) V7 ^* X/ J  I1 J7 O 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-1 00:20 , Processed in 0.095961 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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