找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55444|回复: 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( U; X, Z! o$ N& Z8 ^( g  l

  2. 3 {4 s, L" X6 K8 |
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory' e- P+ J/ A( `( @8 [

  4.   {5 e6 l& P; Z9 a- J1 T4 u
  5. November 4th, 2005, Rev. 1.0
    # Y) i3 I  q, h/ ^6 N& n& t) ~
  6. ( I# e+ H: e0 {, J" a' E$ Y
  7. ABOUT THE SOFTWARE7 }: G8 G0 O) ~; d8 [5 K+ L' |
  8. This application note provides software driver examples for SST25VF080B,
    4 u/ @, m; ?, F
  9. Serial Flash. Extensive comments are included in each routine to describe " R/ U; S' W7 T, l3 G9 _
  10. the function of each routine.  The interface coding uses polling method 4 n( _$ [2 K  c  p
  11. rather than the SPI protocol to interface with these serial devices.  The  I6 x/ {7 o2 Z& k; A
  12. functions are differentiated below in terms of the communication protocols
    ( p; q1 I$ z" T; f7 _3 T
  13. (uses Mode 0) and specific device operation instructions. This code has been & X$ K+ ^! y: p6 n2 o$ m
  14. designed to compile using the Keil compiler.0 P$ _) ?. M/ r5 B

  15. 4 e% U. J6 l6 [

  16. ( X" x4 \% _, R# B5 L# X+ {  h
  17. ABOUT THE SST25VF080B
    6 }# G- _, l7 [0 t7 c

  18. 1 ~0 ?5 g- v2 C- p$ C  J* v
  19. Companion product datasheets for the SST25VF080B should be reviewed in - l1 I0 S3 [( B4 f0 ^3 Q& p
  20. conjunction with this application note for a complete understanding
    ; z. a3 a" I9 C1 q, m8 H! S. O
  21. of the device.
    5 N. m" d  z# c: k: U# B

  22. ; z# Y3 B; l) B( ?# Y
  23. & ]2 l+ a, u/ ?, p0 G( ]1 a
  24. Device Communication Protocol(pinout related) functions:
    7 T# t) E; f( g! l& R2 j4 Z

  25. 8 l2 k9 d6 h- m; p- w% f& A
  26. Functions                                    Function
    * l0 d3 |$ b! f
  27. ------------------------------------------------------------------/ A; U6 j7 R. l
  28. init                                        Initializes clock to set up mode 0.* O1 ^# A: {/ V% }8 S* \
  29. Send_Byte                                Sends one byte using SI pin to send and 5 J3 ]; Y: c4 q6 [( t
  30.                                                 shift out 1-bit per clock rising edge
    : c8 m* o  E! r" J! H
  31. Get_Byte                                Receives one byte using SO pin to receive and shift : m' B/ k1 v5 k+ i3 b
  32.                                                 in 1-bit per clock falling edge
    3 g+ ]# H& i9 Z
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    8 S( B. i$ t$ E) f% a" X2 ?/ v
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high" b" ^# N8 p& G5 k
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    ' j1 Z0 X* A9 M0 ]
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    ! p; T( N+ j# d/ t5 a
  37. Unhold                                        Unholds the serial flash
    * Q6 Z) Q. ~# E# t, I( Z5 g6 b
  38. WP_Low                                        Clears WP pin to make serial flash write protected6 ]1 h3 u% A2 _1 ~4 ]3 d$ K
  39. UnWP                                        Disables write protection pin2 I$ z6 L' c8 `3 U  i9 i, v. H; X% O
  40. * ]) ~4 v4 B9 L" J5 B3 {
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code' c# L3 r' S6 g; u+ S% d% w
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    , K+ E/ ?# N& T5 q0 }  Y. k' [
  43. software which should reflect your hardware interfaced.          ) E8 _$ d, v, e

  44. 4 f/ A1 _" J- e

  45. ) v8 r5 K1 ~; \1 V& g. h+ `
  46. Device Operation Instruction functions:
    6 r& b8 T# F* I; I# X2 Z4 I% Y

  47. 8 |: [4 Q$ t; \+ B, o9 D2 b
  48. Functions                                    Function
    2 |; Z% S2 W' ]. |; o4 D
  49. ------------------------------------------------------------------
    . w' j. n/ L+ M: r! p
  50. Read_Status_Register        Reads the status register of the serial flash
    6 o# v* j. [/ ]" V
  51. EWSR                                        Enables the Write Status Register3 C9 n6 |4 ], U" D& [- G6 E3 c1 c
  52. WRSR                                        Performs a write to the status register! u# i4 R& q6 X3 a1 T- e0 r
  53. WREN                                        Write enables the serial flash
    ; L7 S5 Y5 e3 |, |3 a
  54. WRDI                                        Write disables the serial flash3 L1 v, Q; I: Y+ v, H7 c  W" a2 f
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    / t- o4 {# j( L! `8 W) K" Y
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming, P: j; @! t. n$ L9 g2 U9 @
  57. Read_ID                                        Reads the manufacturer ID and device ID8 h' @# e) N; j" `4 b
  58. Jedec_ID_Read                        Reads the Jedec ID" |  _, u  N1 ^+ w
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    / W' Q/ r# O! ^  [  S
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency): }% I4 W; @0 ~& F
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    1 ~4 L) A8 G( J- l+ T* S6 V
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)9 M; c! |8 x2 g1 {& ~  d3 d+ l) e& L
  63. Byte_Program                        Program one byte to the serial flash3 B4 ]/ P, [9 U$ D. _; Z2 U+ e
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    1 q4 t! Q- J- b
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation! e/ l# m2 W$ y( ~. j& {
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY" y" t, S" |" W3 L- P5 _: g5 Q
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    9 f' j' F8 W- X. J" ~
  68. Chip_Erase                                Erases entire serial flash: K5 G7 c! E9 Q: ^- Y9 `0 L
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash4 w8 e, P$ ?* v9 `2 X
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash4 G! l! ^* ?6 }% x- |
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash' R1 m- L$ x& l  k, \4 v, V
  72. Wait_Busy                                Polls status register until busy bit is low
    % L8 c* b: V& Z% _" ?! o) X
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    1 A/ u, w0 a1 @
  74. WREN_Check                                Checks to see if WEL is set; L3 w" Q7 {6 y/ Q- I
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set6 U# P5 F$ d/ p5 ]. a
  76. # K, Q) ?5 r" O+ Q3 J% Y& A

  77. 4 z) X) [; p* u  h! ?
  78. " l9 B( r8 @6 [+ Q" P* R  w
  79.                                                                      + ]& V' L: g5 h
  80. "C" LANGUAGE DRIVERS
    # u- C9 L8 ~$ Y

  81. 3 ^$ \/ B$ e0 p# W+ ^, F
  82. /********************************************************************/+ l6 ?, \$ b2 L
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    $ c. }* p" d; s) X3 G9 A  o( v
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    7 M# t4 a- W& P7 s& |( s5 t5 G5 T
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    ; J6 w4 |) k8 A- G: c. b
  86. /*                                                                  */4 v, E8 T6 X2 s) z
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    0 f' ?* ]0 @2 K% s$ s, ~! c  j
  88. /*                                                                  */: k3 ]( u6 t" i8 m
  89. /*                                                                                                                                        */" ?  w8 m2 Y) _
  90. /********************************************************************/" U7 b( C3 ^- o0 p/ F/ n

  91. : L9 q5 S/ w* Y" C2 q6 P, N
  92. #include <stdio.h>, ~; A- |1 }9 e5 a0 t! N+ W  f
  93. #include <stdlib.h>
    ) `  ~; S* g3 @3 J. ~

  94. 2 J5 Y2 I: g' y6 l: U& S$ Q
  95. /* Function Prototypes */' U$ y1 O; Y; P4 K* z1 F! [

  96.   K. Q# A  r0 S+ U
  97. void init();
    ) q+ q6 V, A; u" K% N  S2 j" c
  98. void Send_Byte(unsigned char out);  n: n3 Y% v5 g, \! K+ Q, O
  99. unsigned char Get_Byte();
    6 F9 D) y: g# `& Q/ q3 o7 i
  100. void Poll_SO();
    ' u3 D, ~! |  Z: ^+ o# Y0 F
  101. void CE_High();
    1 z9 I7 c! v2 L$ a7 k
  102. void CE_Low();3 c& }6 N+ k: t# @% I* `
  103. void Hold_Low();
    # T; s9 O8 M/ c  t+ }: N
  104. void Unhold();
    ! S# o, l  @3 B" P' ?5 I6 D
  105. void WP_Low();
    1 T6 Z- Q! O) o" E" [
  106. void UnWP();
    8 b- K  b/ E( t, U! [0 V; p% z! u
  107. unsigned char Read_Status_Register();
    " Z# E( D$ B% ^/ O7 Y5 a0 F
  108. void EWSR();
    / g% {% h/ |  q
  109. void WRSR(byte);
    - j, u. F& @+ E  q) {" B
  110. void WREN();! ?; ?+ h9 p/ @' X
  111. void WRDI();& ]/ F: [1 H+ h/ Z6 r0 X+ k4 \
  112. void EBSY();9 A( y( {& j8 P* ]& _0 |
  113. void DBSY();
    % l8 p5 t. Z$ f' Z
  114. unsigned char Read_ID(ID_addr);/ r( G! L" Z: r1 \8 m
  115. unsigned long Jedec_ID_Read(); 8 q" ?4 M0 r3 e& P0 [
  116. unsigned char Read(unsigned long Dst);9 H* O& z  D6 V8 \# K% \6 j4 N
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    & A) v5 \( {  L3 B( |! y6 }5 J
  118. unsigned char HighSpeed_Read(unsigned long Dst); : K# ~/ z; n# \8 H7 Q
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ) T0 M, V6 t  H" }' }! u; S
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ) ?% G. N" M3 `4 g) c; H( l
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ( Y3 v. l& V  p9 W3 l
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    + P- b" d6 x% B# t  ?1 L8 W/ ]4 t
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    . I' H8 `3 S2 \9 D5 ]; h. s
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);  A' Z) H9 D! O6 ]0 x' t# d6 T
  125. void Chip_Erase();
    $ O! K4 I& N' V4 s* L/ e, _
  126. void Sector_Erase(unsigned long Dst);
    ' o) _' D8 w! w8 _6 B5 C6 X# s
  127. void Block_Erase_32K(unsigned long Dst);6 o% ^! ~  s# ], W" p
  128. void Block_Erase_64K(unsigned long Dst);
    0 |; ^! P& \4 ^2 d8 ?
  129. void Wait_Busy();9 s: {8 u, P3 o# v: d0 a# a# \- c( G' }
  130. void Wait_Busy_AAI();; B! `& r) ~; E( e* s. ?
  131. void WREN_Check();
    * _' a0 T  o0 H, _
  132. void WREN_AAI_Check();! o8 ~. e4 A7 G! j4 k7 A6 M

  133. , z5 I. _3 R4 q0 |" \  @
  134. void Verify(unsigned char byte, unsigned char cor_byte);0 H! ^, x8 t* X# W% \
  135. 6 K9 q& h+ b, d$ ^) y# G; i
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    1 Y) H/ P1 e5 Y" ~+ K1 z  u
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    % @2 a# R0 W5 m- Z" [% H4 |- Z0 i

  138. 3 _, Z/ @" w9 w7 v+ }' d" B5 @" h
  139. /************************************************************************/
    + X$ a) Y( L3 b/ j2 k
  140. /* PROCEDURE: init                                                                                                                */
    ( ?" V6 R' n& h& m
  141. /*                                                                                                                                                */
    / w6 y3 J9 }2 H, V* F9 g7 d4 }
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    7 d& n5 ]6 z* U" x8 [' o* q
  143. /* setting up mode 0.                                                                                                        */3 l1 R& o" B+ \
  144. /*                                                                                                                                                */
    6 m7 E& E0 j  n0 `3 b- e* W+ l
  145. /* Input:                                                                                                                                */9 x$ D9 A1 g( j0 W& H" C4 `: y+ I
  146. /*                None                                                                                                                        */% y) y  C# G. J5 _& ^
  147. /*                                                                                                                                                */
    / P  b+ K" U/ F/ }( K# g
  148. /* Output:                                                                                                                                */
    / E2 W$ O8 ?$ w4 w: u8 J
  149. /*                SCK                                                                                                                                */
    7 H# m3 b9 Z8 }0 ?9 o2 P" P- D9 _
  150. /************************************************************************/
    4 M. w- e( H9 K2 ]
  151. void init()" L" ^* Y) u9 ^' s' [1 U7 v
  152. {; D8 N, y6 m" g, [
  153.         SCK = 0;        /* set clock to low initial state */
    ! F! k" x$ p/ Y/ O/ i
  154. }' T; G* w% @" n) v4 B

  155. / S3 i% d; y  V' [# l# u& |
  156. /************************************************************************/
    ) t% @  f" U- m3 k$ r0 @
  157. /* PROCEDURE: Send_Byte                                                                                                        */  ~6 l7 \. [& @9 c2 C3 D
  158. /*                                                                                                                                                */
    ; v1 ^, Y/ r8 N9 T# ~
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */0 z% |' ~( y- V( b
  160. /* edge on the the SI pin(LSB 1st).                                                                                */; p* x1 n+ w$ e0 h. b( }: f( S
  161. /*                                                                                                                                                */5 N* K$ e, Z. G0 M
  162. /* Input:                                                                                                                                */
    7 @6 Z! B! U5 R
  163. /*                out                                                                                                                                */  H5 Y! L0 A5 [1 J! \
  164. /*                                                                                                                                                */1 R* Y; e5 |. b# F; L2 l3 _
  165. /* Output:                                                                                                                                */5 T/ Z/ q* C! G$ v5 e
  166. /*                SI                                                                                                                                */
    ! [& q' G' e7 N$ l
  167. /************************************************************************/' J" b/ ^# w& t6 ~$ s% a
  168. void Send_Byte(unsigned char out)
    : y( G3 r' t8 k) Z, Z0 V
  169. {
    0 c) Z' H$ [2 i+ N$ m& f9 Q& t
  170.         ; q8 q" ^# h7 S1 ]9 G
  171.         unsigned char i = 0;
    + g5 V6 \9 ~% e  B: P
  172.         for (i = 0; i < 8; i++). k- E) T' `( u0 X& ^
  173.         {
    . i* Q( `& A* Q6 p* \/ i
  174.                 2 L0 T$ |# H/ \0 z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    2 F' w9 C8 z  W& X
  176.                         SI = 1;( [8 c* C1 s9 u: T$ k* s
  177.                 else
    ) q: o4 }' T# A) W" _7 `
  178.                         SI = 0;                                /* if not, set to low */
    5 l+ Y. z6 R7 b1 l# O
  179.                 SCK = 1;                                /* toggle clock high */
    : n' G5 _3 T, _8 K2 a* ~/ ~
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    % ~! r3 w  u/ V. L0 o
  181.                 SCK = 0;                                /* toggle clock low */
    ! m9 Y# T+ K+ J8 e) S7 B
  182.         }
    4 Y2 J# x/ F2 L" Q' l7 E
  183. }
    ) v7 h: i" W* b0 `
  184. 9 y7 m1 B4 C4 M: |! x/ N3 p
  185. /************************************************************************/
    : W( T" n$ v5 Q' J* o: i* u% u: O
  186. /* PROCEDURE: Get_Byte                                                                                                        */4 [2 [; C; @$ @; J/ w0 X
  187. /*                                                                                                                                                */
    % E5 w, ]5 f& M9 B
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */4 V) u) s* }4 j% w! G) G7 [: Q
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ' C# J5 A+ H- Z/ t! J8 k6 ~
  190. /*                                                                                                                                                */% K& e2 P5 E. W: O
  191. /* Input:                                                                                                                                */
    7 t% t" E% J. r7 Z% u
  192. /*                SO                                                                                                                                */( E, F5 A% v# X: q. b& ^
  193. /*                                                                                                                                                */
    % j" \# t2 X; M1 D4 t/ V
  194. /* Output:                                                                                                                                */
    . U4 Z: z  K9 M* Q$ E- }6 d
  195. /*                None                                                                                                                        */
    4 |; B5 Z5 r$ n3 G
  196. /************************************************************************/
    ; k; y0 k7 W. S6 V; O; X
  197. unsigned char Get_Byte(): `8 C/ q# Q8 v9 b- d4 i+ _- s
  198. {
    - O1 P1 A3 P3 X& Y+ u- ?7 L$ W" H
  199.         unsigned char i = 0, in = 0, temp = 0;! B" T# e; i5 r% A% v8 n: L$ e
  200.         for (i = 0; i < 8; i++)+ C% y+ ^/ x1 L" }5 r
  201.         {
    * S1 t! Q$ }3 Z2 D8 [
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */* \7 f- W) N, R: O; q: }8 V
  203.                 temp = SO;                        /* save input */
    # u% |/ p% ^( D- Z- {+ n
  204.                 SCK = 1;                        /* toggle clock high */' P2 i* y6 e3 I4 O" T
  205.                 if (temp == 1)                        /* check to see if bit is high */
    + F* z# u1 M: g
  206.                         in = in | 0x01;                /* if high, make bit high */
    ' r  ]0 S4 P: D+ ^  w; q
  207. 0 k, \5 L  q! {: G# q- g7 t  l. [
  208.                 SCK = 0;                        /* toggle clock low */5 V  q3 k' |% \8 p7 ^
  209. ) p" f& _8 R% V; N- J  s# G
  210.         }
    ! P9 t3 ~, ~- a) v6 c: T- I
  211.         return in;
    + q; H+ L" R+ p9 U
  212. }
    ! U: B! H0 j" B2 k% d- K

  213. 2 ]; U( ]! G( B% a, R9 }; Y
  214. /************************************************************************/
    0 q/ M" b$ B2 W, q" f
  215. /* PROCEDURE: Poll_SO                                                                                                        */1 a, _# B% ~8 b. ^
  216. /*                                                                                                                                                */
    ! Q  ?* L  ]( X1 K/ X- N3 {: N
  217. /* This procedure polls for the SO line during AAI programming                  */7 V/ o( g9 l" [: f( y
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    3 K9 t- J0 Q5 s. W$ i  w  }& a
  219. /* is completed                                                                                                                        */
    ( L3 E; }! |2 t! J
  220. /*                                                                                                                                                */
    ( J# U; K* \) N4 w! x+ k4 X. ^3 z
  221. /* Input:                                                                                                                                */
    2 j+ y% I2 p' V* F, a, a- X4 J' l  w
  222. /*                SO                                                                                                                                */0 f( H- y0 o+ j1 \5 [
  223. /*                                                                                                                                                */" v  N+ a. D0 a( h5 k5 ?
  224. /* Output:                                                                                                                                */
    1 v3 r; B) ~% b6 `& [
  225. /*                None                                                                                                                        */
    $ F( Q! c) M2 [, K2 P
  226. /************************************************************************/
    + T$ y1 t+ i0 ^
  227. void Poll_SO()! J( {: q5 O) _  i" y3 z3 p( k' w+ `
  228. {5 |, r+ z. |1 L- j0 u; w! d
  229.         unsigned char temp = 0;
    ; J# ~7 M7 ^* }
  230.         CE_Low();4 R2 `5 M6 [) \4 j- K
  231.     while (temp == 0x00)        /* waste time until not busy */
    2 p. G1 G* i$ O9 i4 B! d
  232.                 temp = SO;; [- P9 V6 S4 m: [" F
  233.         CE_High();
    2 x5 z  E3 c( {: ~+ b9 H
  234. }
    # G9 o6 y4 \* Y7 {

  235. 9 a; q* N, L9 @8 i% M
  236. /************************************************************************/8 ?1 G- w1 z$ q$ J2 u7 y
  237. /* PROCEDURE: CE_High                                                                                                        */. ^: T# ]( }  a% W
  238. /*                                                                                                                                                */" F0 [; \0 O" a6 _; ^
  239. /* This procedure set CE = High.                                                                                */, o4 G' [3 Q: ~, X9 v
  240. /*                                                                                                                                                */
    5 [& p3 y2 T* [3 p- _' N
  241. /* Input:                                                                                                                                */
    4 f& U9 H- D/ V- q/ C* m7 R9 A
  242. /*                None                                                                                                                        */. j" i+ f; g4 }4 m
  243. /*                                                                                                                                                */0 B5 [6 l# [: T8 z8 E$ J3 L+ h
  244. /* Output:                                                                                                                                */
    ) m, ?3 [: I: f" R
  245. /*                CE                                                                                                                                */
    6 Z, r- Q2 r, v! G
  246. /*                                                                                                                                                */2 F1 y8 B/ I$ O4 c
  247. /************************************************************************/
    # y$ t8 W5 v3 k9 Z3 O0 {
  248. void CE_High()
      P( F) T. S4 O" M
  249. {0 ]7 p  s/ ?/ a' H0 U8 h
  250.         CE = 1;                                /* set CE high */
      @3 A; m: u- M$ r9 X/ u
  251. }3 ~3 `& Y8 s) V: C* v& @) w: P
  252. , F$ X5 Z/ t+ [+ k
  253. /************************************************************************/' L6 ]7 a9 S8 [' y
  254. /* PROCEDURE: CE_Low                                                                                                        */+ k$ O( `  r3 x8 W- e1 R
  255. /*                                                                                                                                                */; v5 m1 ^: a% N2 r
  256. /* This procedure drives the CE of the device to low.                                          */
    - ~4 E& B7 p0 \
  257. /*                                                                                                                                                */) k  \7 T* ^4 d# p- _& Z
  258. /* Input:                                                                                                                                */9 s! b2 g1 U: G+ v
  259. /*                None                                                                                                                        */; E1 t- M* r' J/ i
  260. /*                                                                                                                                                */
    4 {2 |% u; {. O  b5 o* t& t, k5 n" O$ V
  261. /* Output:                                                                                                                                */5 c3 J  X" J' _6 B
  262. /*                CE                                                                                                                                */
    4 N/ [" ?, I) f) f7 F. j
  263. /*                                                                                                                                                */+ u2 g0 u4 i- b# I
  264. /************************************************************************/
    2 B* C% T3 z/ K7 |, w- _
  265. void CE_Low() ( O+ j9 @+ l% C/ |8 U" n
  266. {       
    9 z7 n9 C2 h2 T0 K8 S
  267.         CE = 0;                                /* clear CE low */
    - z! m7 }# C: d  ~: _
  268. }
    . m& Q( O* L8 E3 B

  269. # d* [2 Q: W) p4 h
  270. /************************************************************************/
    5 o0 W2 \: H- `+ R7 H
  271. /* PROCEDURE: Hold()                                                                                                        */
    3 A8 w; `! m7 m$ F7 U- B! a& @0 [
  272. /*                                                                                                                                                */- S3 Q9 [  O7 O# X
  273. /* This procedure clears the Hold pin to low.                                                        */1 ?0 d# L9 x5 t& ^6 x* U
  274. /*                                                                                                                                                */# x  ]) ?; T% G+ T2 c
  275. /* Input:                                                                                                                                */5 W) K/ r2 q4 ^. W
  276. /*                None                                                                                                                        */
    ) C& B; c' j" O
  277. /*                                                                                                                                                */
    " J  T% e7 y! [$ Q3 i
  278. /* Output:                                                                                                                                */! \& x. ~) c0 u( {; \0 e3 ~
  279. /*                Hold                                                                                                                        */) N+ A- p) |- `/ b6 @
  280. /************************************************************************/
    6 `; g" J, c5 q
  281. void Hold_Low()
    : B9 D! J0 D: g
  282. {
    4 ?& ^# k5 Q# t& x! x
  283.         Hold = 0;                        /* clear Hold pin */! V+ u( R  {% q! d5 l
  284. }% V- R- n3 p9 A! L' C

  285. : ~: a  d; o4 U" ?+ H% _
  286. /************************************************************************/
    ) f& T: I6 b$ w) Y) n
  287. /* PROCEDURE: Unhold()                                                                                                        */
    ' P& g3 ?9 l9 w1 W0 M
  288. /*                                                                                                                                                */
    ; h/ d1 }# O9 s( {) f
  289. /* This procedure sets the Hold pin to high.                                                        */* U1 d4 f/ I+ e0 `- W6 @$ h6 d
  290. /*                                                                                                                                                */
    , f# p8 R  _1 Z! q3 U$ A) _
  291. /* Input:                                                                                                                                */
    3 w3 n" _* R$ l1 f( T9 u" c& k
  292. /*                None                                                                                                                        */' h5 D5 W3 _$ O& b
  293. /*                                                                                                                                                */4 n+ @5 M) M, b: |* I+ l3 l# o6 {
  294. /* Output:                                                                                                                                */4 v+ D. i  O; g9 }* D% _) F4 ?) M
  295. /*                Hold                                                                                                                        */1 ?: z' y* ~0 i# Y. S
  296. /************************************************************************/; R1 d+ X5 i* c: B' _) I
  297. void Unhold()3 y5 X$ u4 n+ r0 v& ~
  298. {1 c9 \7 w" c6 {
  299.         Hold = 1;                        /* set Hold pin */: u& z1 b9 Y3 ?6 @0 I/ r
  300. }
    ( c+ B% ]2 e% a3 b, \

  301. + f( b' b4 \) h& k" I4 Q/ G( K9 S8 s
  302. /************************************************************************/: l. ]( @. T2 L, w
  303. /* PROCEDURE: WP()                                                                                                                */8 m8 f$ P3 ]+ S. B! z
  304. /*                                                                                                                                                */) a! f/ U+ ?2 q
  305. /* This procedure clears the WP pin to low.                                                                */
    4 M* t; R2 i. L3 Z: h1 m
  306. /*                                                                                                                                                */
    1 k6 r6 F" k6 c+ u# y; H8 U& i; m
  307. /* Input:                                                                                                                                */% N( V* K& ~+ ~- Y, f
  308. /*                None                                                                                                                        */4 g0 x5 p" p& S4 L
  309. /*                                                                                                                                                */
    ) w8 d4 X2 j: z; l
  310. /* Output:                                                                                                                                */" _7 i4 i. `, g& @
  311. /*                WP                                                                                                                                */6 J; k1 q5 O# Z# a3 B. z2 l+ \
  312. /************************************************************************/% s& x* a5 A# i: t3 Y
  313. void WP_Low()
    ! `* c' R% O: A9 j+ V: M. Q# n
  314. {
    % q- N. s( v+ B* u" ~( T9 v  y4 s" x
  315.         WP = 0;                                /* clear WP pin */
    2 F2 e" ~6 Z' F  B
  316. }
    ( s5 ]9 L8 Y- U6 D

  317. 8 V6 W% Q* |, b) p
  318. /************************************************************************/
    9 [  C8 G  y. e& d; O9 u- ~
  319. /* PROCEDURE: UnWP()                                                                                                        */
    - Y  T$ O8 o5 |% Z, k
  320. /*                                                                                                                                                */
    ) c& r6 X$ K8 ~3 y; K
  321. /* This procedure sets the WP pin to high.                                                                */  w  ^/ {; r) k( |0 v* @; w9 b
  322. /*                                                                                                                                                */
    1 g& Y' W* g1 _4 s7 S- H
  323. /* Input:                                                                                                                                */
    ( |( }: ~: z  y5 a8 I' K2 ]
  324. /*                None                                                                                                                        */
    ( e; H8 H& Y0 t6 `/ O
  325. /*                                                                                                                                                */, o9 N. }4 c. H% Q8 n
  326. /* Output:                                                                                                                                */% T* {6 H. ?/ ~
  327. /*                WP                                                                                                                                */
    2 y# Q; _# P+ M0 Q& f- W
  328. /************************************************************************/
    * U/ B* i0 A% P6 X# |, r
  329. void UnWP()+ ?( {8 u9 q. D$ V9 g. @
  330. {* r# X- H$ Y/ l5 H7 V! }
  331.         WP = 1;                                /* set WP pin */7 b( i: w/ U5 L6 v5 R
  332. }. c. a" O- ]1 E
  333. 8 }9 ?- m# o& @$ N% b  v5 N+ o( ~
  334. /************************************************************************/
    % E9 y3 @& l9 M$ ?5 ]: _, N
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    - _7 P2 h( \, t( x% x4 `) e
  336. /*                                                                                                                                                */. b" L" B% e, n) H, M  F
  337. /* This procedure read the status register and returns the byte.                */0 @5 J& ]* K3 v+ m. h: y8 q2 k9 h
  338. /*                                                                                                                                                */' O- t, q7 H9 p6 U6 V  ]
  339. /* Input:                                                                                                                                */; k8 V. c' X  ^2 ]$ y! K+ T
  340. /*                None                                                                                                                        */! ]4 u4 y) P# O7 d2 r' T
  341. /*                                                                                                                                                */
    6 v3 M- z+ W- x1 W7 `/ G  q
  342. /* Returns:                                                                                                                                */
    * S( S, O; Y' V' C
  343. /*                byte                                                                                                                        */6 c+ |0 C8 g2 M+ T
  344. /************************************************************************/# a( }9 `1 H8 {4 `
  345. unsigned char Read_Status_Register()' ~2 G8 _( u, f7 }
  346. {# H4 ~# r  ]9 k: {
  347.         unsigned char byte = 0;; D& N8 D3 `5 N) S) M! O) {- ?
  348.         CE_Low();                                /* enable device */1 q  X9 x& N9 B1 M! ]
  349.         Send_Byte(0x05);                /* send RDSR command */
    ( {' t! d" Z7 X  i1 U) ?7 j- w5 g
  350.         byte = Get_Byte();                /* receive byte */- H( m% K: U( I
  351.         CE_High();                                /* disable device */
    , \3 J* L. J. t7 D8 j# g
  352.         return byte;( P( ?. M  m$ w$ S1 k8 c
  353. }
    5 g, i' D3 n& F  h8 x! @( L6 }5 t

  354. 6 ^8 e3 E1 i, F2 N9 c
  355. /************************************************************************/$ G, v1 z/ o- y3 [
  356. /* PROCEDURE: EWSR                                                                                                                */; Z3 A* W, C" t+ e) Q. \
  357. /*                                                                                                                                                */4 ]' y5 d- [* `( q' A/ g! r
  358. /* This procedure Enables Write Status Register.                                                  */0 l( [, y3 z; h1 [' S" C% y5 H
  359. /*                                                                                                                                                */2 s4 T+ U2 c- \) J1 i
  360. /* Input:                                                                                                                                */6 Q& s; Z! Q; J6 I% k& [+ G
  361. /*                None                                                                                                                        */0 D; u$ s# u  p5 s
  362. /*                                                                                                                                                */
    2 h0 F- ~( A, k0 \
  363. /* Returns:                                                                                                                                */! p- M* i; n0 g# L1 i% k) H  k
  364. /*                Nothing                                                                                                                        */
    ) C0 s6 M9 E5 G0 E2 F/ [. G
  365. /************************************************************************/0 t4 E4 e8 f% h$ c4 l  j5 x
  366. void EWSR()
    ) M) c: z+ S% {7 A6 M
  367. {7 M, N' S4 @. i" N# I4 N: _
  368.         CE_Low();                                /* enable device */+ j7 M9 o" o) u/ ^! p9 S7 A5 w
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    , h9 @1 w4 P, i' J1 }
  370.         CE_High();                                /* disable device */5 L7 Z& c) |0 v, u) v" `7 y8 B
  371. }9 |  T5 \* ^: u) g
  372. , A/ m8 u/ f8 [3 O4 l7 ?
  373. /************************************************************************/
    , @5 c) `. a9 w9 {2 D
  374. /* PROCEDURE: WRSR                                                                                                                */8 M7 q7 B3 e. u; y2 n
  375. /*                                                                                                                                                */2 p  h0 M& r# G4 k( z; c! |
  376. /* This procedure writes a byte to the Status Register.                                        */' \% L* m3 S. N. |3 k, Q5 A! R
  377. /*                                                                                                                                                */4 y9 K: a$ e3 w8 g  \
  378. /* Input:                                                                                                                                */  g& d2 T% J" B& a8 I+ p( k9 `
  379. /*                byte                                                                                                                        */" P  d& ]% `0 L' A8 G
  380. /*                                                                                                                                                */$ X  I' j3 u5 |$ i* y
  381. /* Returns:                                                                                                                                */
    ) Z' |" K6 k7 J* b
  382. /*                Nothing                                                                                                                        */4 ^& n# A/ ?3 X9 a% ~& {! r
  383. /************************************************************************/" j1 C; C4 D9 L- g2 v9 w
  384. void WRSR(byte)
    # v6 q& o6 W( V
  385. {9 k0 ?/ d4 |& @; t
  386.         CE_Low();                                /* enable device */  b7 x, E! y* L3 |5 d$ |
  387.         Send_Byte(0x01);                /* select write to status register */2 K. V& a& x6 b" u3 S7 n5 X
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    , J1 r' c7 S' b) ]. o& S
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */. l) ^' ?: J1 s
  390.         CE_High();                                /* disable the device */' e0 B+ C0 `: l1 T
  391. }) k7 P& i$ \# K
  392. # l8 q' R( D" a& y* W
  393. /************************************************************************/- a" x- r7 c( E" T" o
  394. /* PROCEDURE: WREN                                                                                                                */
    : j* y4 J9 E  h
  395. /*                                                                                                                                                */
    $ ^, j4 I+ a  j+ [2 I
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    , _! ~% t/ ~# v9 d
  397. /* to Enables Write Status Register.                                                                        */
    ( a1 L. A0 ?0 }5 O
  398. /*                                                                                                                                                */$ s: |! `4 W7 o4 I8 }1 `% M
  399. /* Input:                                                                                                                                */! v6 X) S; ~: B/ B
  400. /*                None                                                                                                                        */
    7 M+ d" ]; ?6 m* {, x( @& E9 w
  401. /*                                                                                                                                                */  q# |" v. S  x- S. u' d
  402. /* Returns:                                                                                                                                */
    ; r( q7 o- ^; T
  403. /*                Nothing                                                                                                                        */
    9 V1 z# p* p- h5 t& e7 W2 B4 t9 |
  404. /************************************************************************/+ O6 r/ h/ d" A3 A+ t$ T0 r: b2 k; M
  405. void WREN()5 M: ~, q- D9 o2 S! {
  406. {- _/ ]4 j* U3 W+ G% ~4 \
  407.         CE_Low();                                /* enable device */
    ; S/ P2 z. t) W2 ~
  408.         Send_Byte(0x06);                /* send WREN command */
    4 x* ]( A% E9 |, Q6 ?; S) E; Y
  409.         CE_High();                                /* disable device */
    0 l% A) p2 r9 v; a8 U4 B. e  y! g% ]
  410. }
    ( R8 W6 L( z1 O3 Z" m( ~

  411. , b9 O; K8 Q4 ?- y9 k$ h) q7 I
  412. /************************************************************************/" R# h! C# I7 F% H+ p2 r  F8 _4 f  z- m
  413. /* PROCEDURE: WRDI                                                                                                                */
    7 @" h: z# b1 P! m' o& v
  414. /*                                                                                                                                                */# O3 h: p# J) s$ r; p$ t- E) A
  415. /* This procedure disables the Write Enable Latch.                                                */" ^; Y) w+ z( D& W4 _' W
  416. /*                                                                                                                                                */
    1 m# C& h. z( z3 s0 J
  417. /* Input:                                                                                                                                */
    8 [. j# z. }3 }" G
  418. /*                None                                                                                                                        */
    , _; K. h  ]7 o8 T3 Y& x
  419. /*                                                                                                                                                */# ^* d6 b! ^: q! ]6 l6 V5 j
  420. /* Returns:                                                                                                                                */
    + F, z. m, m! E2 Z: [& ~
  421. /*                Nothing                                                                                                                        */
    2 J7 l5 a' n7 {; f
  422. /************************************************************************/# b; t' M! U- a. s: ?' H
  423. void WRDI()3 l. P, k# z8 }# e& T
  424. {. i1 ]" ~+ K, ]9 [9 C
  425.         CE_Low();                                /* enable device */3 h6 b+ ~$ i) N; }, l
  426.         Send_Byte(0x04);                /* send WRDI command */
    + Y, ^: W" p" P* y) Z
  427.         CE_High();                                /* disable device */& A2 p: b' C; K3 Z; b5 p' r
  428. }
    . c0 n7 G4 S4 g) ~- @: b
  429. 5 w& x+ s" G& f% x$ u% N6 p
  430. /************************************************************************/' d$ o" R* X3 R# V
  431. /* PROCEDURE: EBSY                                                                                                                */
    / K- L/ o' f% c) b* {& H3 g
  432. /*                                                                                                                                                */! J, W0 ], {% v1 t4 K
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */) {% j5 u. E0 @: E4 ~3 L  o1 S
  434. /* programming.                                                                                                                        */# n1 L( z' }3 W7 x1 ?% d
  435. /*                                                                                                                                                */+ ^; P0 l6 h8 w6 a- G
  436. /* Input:                                                                                                                                */
    - `0 ?% u, Y7 L4 L! S  e; j) i
  437. /*                None                                                                                                                        */& p5 |7 M) h4 m# [
  438. /*                                                                                                                                                */5 W  [8 _& ^* A/ w2 ]. \6 d
  439. /* Returns:                                                                                                                                */( ]: x  D3 W; I+ `0 ~. N
  440. /*                Nothing                                                                                                                        */+ C( g6 a0 L' p$ J
  441. /************************************************************************/$ Q& x" N# Y( ?* K- h* f
  442. void EBSY()
    8 f1 q8 o6 t- }! |1 x- N
  443. {4 T8 s# K3 h( l$ y6 F
  444.         CE_Low();                                /* enable device */% w- X2 \6 u9 u/ y! q% y
  445.         Send_Byte(0x70);                /* send EBSY command */1 b$ g3 ]( `( E. ~, D
  446.         CE_High();                                /* disable device */6 ?  {0 X; D+ S' K
  447. }, ~/ F7 }# @) C% H& |
  448. ' P9 d4 X6 i' \+ _# I
  449. /************************************************************************/7 I! M8 Y3 k5 S' I, a
  450. /* PROCEDURE: DBSY                                                                                                                */
    : _$ E1 T1 f( k9 y, D
  451. /*                                                                                                                                                *// ]- ]- ]1 T- K6 P! v7 N3 w
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    4 e7 Z# z0 U1 K) Z0 i
  453. /* programming.                                                                                                                        */
    $ [2 ^- N7 ?8 G4 A( Z
  454. /*                                                                                                                                                */. g. V' ^( S. a- Z3 R! x
  455. /* Input:                                                                                                                                */1 p2 X1 g6 \( ?5 A* Q' A7 h" _$ W
  456. /*                None                                                                                                                        */
    $ F! z) U" j( a
  457. /*                                                                                                                                                */
    0 Y# K- t; E/ }& U5 S: T1 c4 W
  458. /* Returns:                                                                                                                                */2 k: [$ I! n3 \% P# q0 T
  459. /*                Nothing                                                                                                                        */
    5 b& a& o' X6 f) s: b
  460. /************************************************************************/; r: b2 U5 n# ]& Z/ ~% a1 T
  461. void DBSY()& W- j7 p- z3 ?& l# @, a
  462. {
    ; I8 ^" x, ?, ~# ^  P; t
  463.         CE_Low();                                /* enable device */
    & [, Q  X+ ?. |6 p( C, B
  464.         Send_Byte(0x80);                /* send DBSY command */
    6 M3 H; g, t2 \* j* p/ r
  465.         CE_High();                                /* disable device */
    ) U* e4 b( u% Q2 S/ u2 ?
  466. }
    7 w$ ^. [) C& J1 P' Q# F
  467. 8 ~" Y- g  x, ^9 J. E# P0 c2 C$ I
  468. /************************************************************************/4 ]8 `, Z, N6 c3 y4 i) i5 l5 ~
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ! E! T* X" ~& \, L* T
  470. /*                                                                                                                                                */
    ' Q+ w/ n! [) Q3 e$ t! Y9 V5 [3 t$ l
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    7 t( ~" a! L0 N; ~+ H5 M( q
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    7 A) o( n, k( p8 O$ z
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    . d- f, d2 M7 o4 M
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    : A1 v* Q9 j3 @3 B
  475. /* first.  Please see the product datasheet for details.  Returns ID in */) @# E2 q) O5 b2 R2 {( o
  476. /* variable byte.                                                                                                                */
    ) t& U2 P8 b$ I8 z& S/ u
  477. /*                                                                                                                                                */
      ?3 h0 z( ?* r% E: W3 y, B# U
  478. /* Input:                                                                                                                                */
    # _6 q4 ?# {2 S- d9 P1 Q
  479. /*                ID_addr                                                                                                                        */
    ) @$ Q4 s! t( R' c; s
  480. /*                                                                                                                                                */
    % w: Q3 v! o1 M6 Z% \/ ~8 y
  481. /* Returns:                                                                                                                                */
    ) `6 H$ i5 {' a
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */' @4 f! v4 Z* V# o
  483. /*                                                                                                                                                */
    7 @( `* W+ x/ P* x: a3 _
  484. /************************************************************************/- R3 X  H$ ]0 V9 t1 L, y. d* [1 r
  485. unsigned char Read_ID(ID_addr)2 H! r0 h/ I7 Z( E1 d
  486. {' x, {; }( v& o4 t8 `* ?6 N
  487.         unsigned char byte;" g6 e% p1 t. z
  488.         CE_Low();                                /* enable device */
    & H+ V/ `7 y4 t- B/ v( V6 x' _
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */' i! y" x9 Z$ {4 x
  490.     Send_Byte(0x00);                /* send address */
    5 F) l3 P* H# `& x3 [; b
  491.         Send_Byte(0x00);                /* send address */
    # U9 Z8 |9 o( S8 J# p& v! d
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
      D% ~+ z' T6 y/ z$ x
  493.         byte = Get_Byte();                /* receive byte */
    $ K& Q  }" H3 z( I& X
  494.         CE_High();                                /* disable device */7 S/ C5 r8 \! g3 X, b
  495.         return byte;
    % m* i0 a  u4 p6 m
  496. }
    0 G$ G% B) I9 i1 }9 m8 E

  497. " R! V7 m, W6 s" G( k2 l9 k* k! R8 i
  498. /************************************************************************/0 e$ H4 B0 }, s6 n7 }: B
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */8 A+ f( O6 }) }2 c* C
  500. /*                                                                                                                                                */
    3 Z1 Z, M7 C, v6 H2 U; u+ k
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */' K9 J, s; [( h' b
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            *// ?8 m" L. @& H- z! d" X: w
  503. /* Please see the product datasheet for details.                                                  */
    . }5 s$ Y  t1 W2 \$ ?& D+ }: V
  504. /*                                                                                                                                                */  R& a* u' o3 p+ m& \$ f7 H1 N$ \
  505. /* Input:                                                                                                                                */& y, q3 s  B: i- A6 Y; h; P/ C3 H
  506. /*                None                                                                                                                        */
    - P: \% U* Y$ g& O3 @7 _3 q8 J
  507. /*                                                                                                                                                */
    : z1 s  a& U8 l: T+ j5 `& v# p8 l
  508. /* Returns:                                                                                                                                */3 F: U" G; g3 ]/ {' j, a8 G
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */+ _' R6 k  Y6 [, N" M
  510. /*                 and Device ID (8Eh)                                                                                        */& ~& Y+ |0 H* i1 I
  511. /*                                                                                                                                                */
    ( J* ~& t- P7 S
  512. /************************************************************************/
    : v/ k# T6 |: @. W
  513. unsigned long Jedec_ID_Read()
    5 |8 P2 {; p' @4 Y! k
  514. {
    * p6 y2 F% r2 t* n$ q3 I
  515.         unsigned long temp;
      i& K8 F" V" S% N+ @
  516.         ( o" [& n& ^+ H. Q' B
  517.         temp = 0;. m" {& |& L2 _! R9 U, N9 G2 t! L

  518. $ u6 H6 d9 d; n8 u& `9 P0 r/ U
  519.         CE_Low();                                        /* enable device */# g) A" ?4 y& L1 H& C" G( s
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    4 ^( ~6 w3 O  b3 w# {5 z$ T
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    3 G& A" c( d* z% Q6 ?$ l  f! \
  522.         temp = (temp | Get_Byte()) << 8;       
    - N0 q  N- F* d1 F6 _+ W+ M
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */- g* _' m, P8 }" S' L$ ^: ]
  524.         CE_High();                                                        /* disable device */
    4 |/ z( ?. T6 K0 M! F5 U7 f
  525. ' z7 P+ i( K( V4 s# n2 a
  526.         return temp;8 ~! [, y" T; F# W. [1 j6 o
  527. }7 ~. S* B. q3 X5 Q( Q, p! p6 A- J

  528. * Z8 h' D9 S* R# j: K2 v9 G  u
  529. /************************************************************************/, n! C7 c) c7 \1 O) P- o& I# W
  530. /* PROCEDURE:        Read                                                                                                        */
    ; H1 v0 w0 O+ K" |1 N* P0 }
  531. /*                                                                                                                                                */                . y, N1 z, a& X6 s! S: F0 l& I4 ~
  532. /* This procedure reads one address of the device.  It will return the         */
    0 Z7 Y( N9 J0 `! I; m& s7 F
  533. /* byte read in variable byte.                                                                                        */( W* o  E) O( T' z' f, _
  534. /*                                                                                                                                                */5 j' ^6 b7 j: _, Y  L
  535. /*                                                                                                                                                */9 h  k* N1 Q% \8 E2 P  n8 V% g& _
  536. /*                                                                                                                                                */
    & g6 `: i4 w( N) m1 Z3 h# \
  537. /* Input:                                                                                                                                */; h. [2 v1 t% F$ R! H$ L
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    $ q# p4 Q- B+ F/ s
  539. /*                                                                                                                                      */
    , t" v0 S* t  w8 }/ u) l. t! U/ i
  540. /*                                                                                                                                                */
    2 u4 f) v9 |7 \! f# C  |; O4 {# t! e
  541. /* Returns:                                                                                                                                */
    7 ]# N3 m. b6 B# g7 r! e, Q; E
  542. /*                byte                                                                                                                        */
    2 F) J) U/ e5 F! j' O* `
  543. /*                                                                                                                                                */* u+ X' f' G3 I6 D
  544. /************************************************************************/
    " n# i# w9 \, G0 \9 J
  545. unsigned char Read(unsigned long Dst) 7 q4 @: m! {: ~3 ?$ G$ p9 Z
  546. {' [! T* H+ m" m/ ]: o2 P+ ~
  547.         unsigned char byte = 0;        9 p: }% p) B/ l' ^5 O& Z6 A
  548. * W5 O+ t  }. k* T
  549.         CE_Low();                                /* enable device */
    : n( H( C! _3 x+ A
  550.         Send_Byte(0x03);                 /* read command */
    ' T8 Q. y4 U* p- ?& Y, P& ^
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */( K: U, B/ x; T
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));) Y6 D; U; p- |6 c; H* r% m
  553.         Send_Byte(Dst & 0xFF);7 X/ j0 \6 d/ x; P9 E; U
  554.         byte = Get_Byte();# b+ q, {& E! B0 }
  555.         CE_High();                                /* disable device */- J8 T( k) W2 X9 V3 F
  556.         return byte;                        /* return one byte read */6 M) l2 ], i; Y8 l3 B0 l0 C8 c
  557. }
    1 t9 [, d" C* v% g4 z! G

  558. 9 C& ^+ `4 E6 X% _1 Y
  559. /************************************************************************/! T, D! R8 ^/ U& l( j# E& I1 D! g7 C
  560. /* PROCEDURE:        Read_Cont                                                                                                */) o* V8 w( F* e1 Z6 e8 Y! `
  561. /*                                                                                                                                                */               
    9 h9 n# g, F. R  S# I5 y) V5 q& q
  562. /* This procedure reads multiple addresses of the device and stores                */
    ' {: B2 K0 z$ f$ a3 Z) j9 Y
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*// r0 w- J% ^- d4 p4 a
  564. /*                                                                                                                                                */# S, J* z) y- Q6 R3 [3 H
  565. /* Input:                                                                                                                                */1 y0 O+ o6 I$ M
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# _7 C5 a2 k. }( @0 u
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    " R# J) b2 v( f4 |  p6 A
  568. /*                                                                                                                                                */8 D0 \; p$ ]& T6 h# e
  569. /* Returns:                                                                                                                                */
    4 Q. B$ D$ k* F9 C
  570. /*                Nothing                                                                                                                        */
    . \  C1 k9 O2 u0 y; o1 S7 n) ~
  571. /*                                                                                                                                                */
    , H& e: S: e( I% S. e
  572. /************************************************************************/& T2 g& |" {. w, m* z' F/ j9 m
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)! [+ ~( f/ M2 x7 X( h% E
  574. {$ `: n1 q/ m8 U; D2 h$ Z; x
  575.         unsigned long i = 0;- r5 D  x4 a, S0 e$ ^
  576.         CE_Low();                                        /* enable device */
    # ?$ p  W( c  f; ~+ [7 Z' s
  577.         Send_Byte(0x03);                         /* read command */9 w* a" ^3 P$ h& R" G$ v9 u& S; @
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  B5 z. R) f5 S- F7 x! i
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + J1 p# }; g% N* Y
  580.         Send_Byte(Dst & 0xFF);
    3 c; u4 ~+ l/ s! e
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    8 h% h: O) G7 H: X0 ^2 @6 `: ^' |
  582.         {
    6 D. h! D9 s( x: q
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    0 b+ f$ r: H$ {" Q
  584.         }- d+ v% I! X) q
  585.         CE_High();                                        /* disable device */
    5 {6 n  c/ K+ n

  586. . S5 K8 ?! s) \1 D" j
  587. }
    * ]. {0 R0 \( F, y/ B( }! |# u
  588. ; _2 W6 s# P. [
  589. /************************************************************************/
    4 x( B7 J+ \" g5 I- u) v+ \  V6 V
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    : P! P5 J# K) E! `
  591. /*                                                                                                                                                */               
    . p' ]3 @% n2 \% l& l
  592. /* This procedure reads one address of the device.  It will return the         */" a* e2 S  P9 `
  593. /* byte read in variable byte.                                                                                        */
    " ]" O6 u7 |* A/ e6 t
  594. /*                                                                                                                                                */
    1 q" m! |" I- ~- d
  595. /*                                                                                                                                                */0 ~4 B. Y$ U! B* K
  596. /*                                                                                                                                                */
    ) e$ F) ?0 y+ y9 M# [' D1 X  @
  597. /* Input:                                                                                                                                */" `( Y. ?9 X9 P- k
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% G4 p$ Q8 R3 u* z6 P1 `& L
  599. /*                                                                                                                                      */
    / y* @1 J1 x" o4 |7 \
  600. /*                                                                                                                                                */
    7 Q7 I* G* {$ E! Q9 M) p8 u' J
  601. /* Returns:                                                                                                                                */
    % w# v7 A6 u5 L( E% b9 B
  602. /*                byte                                                                                                                        */
    6 I7 m3 V0 }& {) ]. t8 R
  603. /*                                                                                                                                                */$ w& ~3 n* w. ?8 o
  604. /************************************************************************/6 `- u. h2 O: _; l
  605. unsigned char HighSpeed_Read(unsigned long Dst) + F6 N) y; Z: |' E5 z5 l; i  }
  606. {
    # ?7 s3 D: U: J- u( _
  607.         unsigned char byte = 0;       
    # q! Z2 g& b0 `8 j$ l- X0 T  t

  608. 8 W, b( g: H& G. f) v4 f
  609.         CE_Low();                                /* enable device */
    3 \0 y+ L3 {: u# A: |, @  ~
  610.         Send_Byte(0x0B);                 /* read command */5 Y) }4 @3 W2 r# c1 Q# ^
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */* B# Y, [' f6 T- }" H% b8 U
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : y1 w) C  K' S7 {7 O$ k
  613.         Send_Byte(Dst & 0xFF);3 J* u# j" G: [$ q! }3 r$ q% [% Z
  614.         Send_Byte(0xFF);                /*dummy byte*/
    4 Y4 l1 J% ~$ D, i
  615.         byte = Get_Byte();# o) n" j; {% @, v* \, {" a7 ~# i
  616.         CE_High();                                /* disable device */( H1 v/ p7 M7 W9 c
  617.         return byte;                        /* return one byte read */% C  Y& T1 M% \8 I
  618. }
    * l1 t4 ]4 I% s0 N0 X# O6 v

  619. , W( P- t! e' t$ L
  620. /************************************************************************/
    2 Q6 l3 Y) r# d' t) A
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    9 c- }9 e( h, B8 _/ O, `6 |1 u' d
  622. /*                                                                                                                                                */                0 {4 s- S* i4 m2 U- Y6 Y
  623. /* This procedure reads multiple addresses of the device and stores                */, O' }3 M/ |+ |. x# C& v" |
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    & S  n( C7 i" b+ K% R. x2 T
  625. /*                                                                                                                                                */5 ]5 q9 ?( v, c- C8 ]* o" Q
  626. /* Input:                                                                                                                                */9 C3 h& |6 O" O
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, I1 y# g/ u2 d# L7 ?5 U3 Z
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */9 B8 a2 x+ I; a/ I# _0 z) v" T
  629. /*                                                                                                                                                */
    5 o9 k. R! `% b& r4 g( j5 X* W
  630. /* Returns:                                                                                                                                */0 k3 Y+ F. x* y
  631. /*                Nothing                                                                                                                        */- S+ V8 M6 Q9 [8 Y
  632. /*                                                                                                                                                */
    ( y* e/ t0 \, q; U: c" z. x  j
  633. /************************************************************************/& {" X. |/ u/ l7 B" r) m% f
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    7 `* S0 v7 V( v- [# f5 B, L0 ~
  635. {/ N) Y" U: F4 c6 v5 `7 Q- s8 [3 S: a
  636.         unsigned long i = 0;* N: N/ l4 N! t& a6 x# U% B
  637.         CE_Low();                                        /* enable device */
    ! W; w' b6 `; V9 y
  638.         Send_Byte(0x0B);                         /* read command */
    4 r! j/ _4 O9 ^9 B- l
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 O7 f' P0 y6 T7 T4 R# S8 A
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , x9 J3 A3 n+ k2 O$ B
  641.         Send_Byte(Dst & 0xFF);* A( ^! f5 f7 ]% V
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ! }: l7 c, `, y' h+ U. ~
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */3 X  x3 q% J0 N4 F
  644.         {( Y3 D$ A: j0 j4 [5 D, C/ m
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */# f( X9 ~0 k% N' T  f/ I, m
  646.         }7 S9 I5 h0 s9 D  k. Y+ k& K5 m8 e. i
  647.         CE_High();                                /* disable device */% y8 n8 u6 p( a
  648. }' R6 l) Z5 f3 W1 R$ A% u
  649. ) _6 s. R1 ]* W' Q& k% U, [$ t
  650. /************************************************************************/
    , N9 f  k$ T- F5 P7 H
  651. /* PROCEDURE:        Byte_Program                                                                                        */( U1 j5 `' e, ]  i; E3 ^
  652. /*                                                                                                                                                */' n, D# T$ v7 P& U( M5 H
  653. /* This procedure programs one address of the device.                                        */
    2 j! \9 ^; l' V; ^$ ]6 s
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    * t* M+ d' L1 R, I/ ~
  655. /* block protected.                                                                                                                */
    3 T: g* C$ g* x, ~2 X; h5 T
  656. /*                                                                                                                                                */+ m0 ?% }9 A1 r3 k
  657. /*                                                                                                                                                */, q. Q$ g+ |  n
  658. /*                                                                                                                                                */
    & t( }" I1 M# e4 ~+ x0 j5 T
  659. /* Input:                                                                                                                                */4 X; r( w3 ^. x
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 p; y8 v( h  o7 z; W. N
  661. /*                byte:                byte to be programmed                                                                */
    ( d; _, f/ d) R
  662. /*                                                                                                                                      */9 v' ?: w- [  N& R; I
  663. /*                                                                                                                                                */3 X" Q, T* e6 A4 j5 m: F8 p. e
  664. /* Returns:                                                                                                                                */
    1 ?# n8 a6 W, [( ?
  665. /*                Nothing                                                                                                                        */
    2 s) T7 m1 K) G" Z
  666. /*                                                                                                                                                */& `) E8 ^" \+ {& [+ s. u3 p
  667. /************************************************************************/
    . P6 [$ @7 n# Y
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    & T* i1 m2 K+ ~& G8 Q7 I. S0 H
  669. {+ ?( P: j- J" y6 F
  670.         CE_Low();                                        /* enable device */# N; N/ o) `6 N4 H! T* T
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    4 B: F" l3 F9 N, c1 b' }, ^
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    7 }2 L" r; t4 c
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 l: d* G4 L; ?
  674.         Send_Byte(Dst & 0xFF);2 A3 v7 `! [7 f3 |, k9 p
  675.         Send_Byte(byte);                        /* send byte to be programmed */3 m6 j1 M  v! v6 ^. E
  676.         CE_High();                                        /* disable device */- C/ s* f1 n' E, a2 X2 ~; G0 M& n
  677. }
    % |0 }1 T4 d5 `, h! I6 }
  678. 0 m, P) I  U) l  T
  679. /************************************************************************/# q- f7 P; J, Q2 @2 Z$ u* p$ h4 b
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ; T. T. ^0 v0 H) D: o3 F# ^
  681. /*                                                                                                                                                */
    & y! B3 V# }* y! n1 t9 P" `
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    " W$ ~5 ]# \4 r& E" h& Y
  683. /* the device:  1st data byte will be programmed into the initial                 */
    & i5 k% `' D- `( C$ p
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */& K# T9 i; s- W+ ^& F, t, s, W; _. S
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          *// x( ~6 \. l% h
  686. /* is used to to start the AAI process.  It should be followed by                 */
    . C/ V# M/ s% Z) z# J% \
  687. /* Auto_Add_IncB.                                                                                                                */% o% ]; w  t$ @( G3 U
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 b5 x4 A+ s* m4 a4 m! G  n6 x
  689. /*                                block protected.                                                                                */8 _, M1 Q1 F4 {$ d
  690. /*                                                                                                                                                */8 }& U2 T+ t: f4 l5 p4 a
  691. /*                                                                                                                                                */
    2 J( v8 C, h% q% U1 D* K
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    * B7 V: m/ d9 a+ k
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    & Q% m5 Q& m. Z" I0 M1 m; ~
  694. /*         unless AAI is programming the last address or last address of                */; n& h; N& R1 F/ @2 Y' b+ d6 {  `
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    3 T5 p- _# E% U4 \. ]* n
  696. /*                                                                                                                                                */
    6 m. e8 @' h' l5 I- V
  697. /* Input:                                                                                                                                */) N$ }$ W9 u0 R2 F
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 T8 X% k3 M: @6 k/ U' z
  699. /*                byte1:                1st byte to be programmed                                                        */
    3 S# C+ c( |  _1 m9 G5 K. B
  700. /*      byte1:                2nd byte to be programmed                                                        */6 @: ^2 W* b* T; t$ A+ d2 o
  701. /*                                                                                                                                                */; g& `* I/ i* F2 w5 y
  702. /* Returns:                                                                                                                                */* e5 d- o, n, [' ^
  703. /*                Nothing                                                                                                                        */
    - r! f6 `' {- k" h1 r9 Z; t
  704. /*                                                                                                                                                */9 M8 e( L7 \; O* M. J. `
  705. /************************************************************************/
    / `$ C) H9 _; Z9 c, ?5 g# `+ X2 a$ [
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)( [' c9 E4 ]( Z  c% |7 Z% l% t
  707. {2 j% c1 j' [& i: Y
  708.         CE_Low();                                        /* enable device */
    / h, p( n7 d: [# _" n
  709.         Send_Byte(0xAD);                        /* send AAI command */
    , i; K9 O. Q5 K  C$ o6 P8 [9 x$ K
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * i/ p! y  V: a
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % O4 {/ f" N5 l3 m
  712.         Send_Byte(Dst & 0xFF);# w; [9 o$ O- ]! p, w# W
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    " }0 s/ ^! G, `
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    3 k. j; |; X( h4 v# I$ V
  715.         CE_High();                                        /* disable device */( Y6 T# X7 C4 G, i
  716. }
    ; C+ \/ ~4 A; `! m- @' s6 K

  717. , E2 g" b# K9 q: D5 C  d
  718. /************************************************************************/" C* j: Z+ Y. @" u/ j/ w
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        *// l% o; p0 R9 H% v
  720. /*                                                                                                                                                */
    " _* w* R2 }& H; ?
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, [1 ]/ R( _! `
  722. /* the device:  1st data byte will be programmed into the initial                 */# _6 ]0 g& D1 s! _
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    9 d2 x  H% S  s7 z! b, i& W
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */. @  G  c2 g6 o
  725. /* is used after Auto_Address_IncA.                                                                                */
    / ?/ F2 ?- e/ E& A0 K3 {
  726. /* Assumption:  Address being programmed is already erased and is NOT        */3 u3 O* G- T) J
  727. /*                                block protected.                                                                                */' |+ }4 M# @* e6 K* x! a- _
  728. /*                                                                                                                                                */
    % @. n; K( f+ X3 q9 h  n$ {3 u4 I8 j
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    1 s0 R4 i/ `# @8 w3 n% j
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    8 y! L" m  ?6 G2 v* a
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    " |. Z/ d8 @1 b+ C+ D
  732. /*          to exit AAI mode unless AAI is programming the last address or                */: w  Z  \6 K% b* {7 \7 }
  733. /*         last address of unprotected block, which automatically exits                 */
    ! r1 u: u1 H8 z* c3 Y, J
  734. /*         AAI mode.                                                                                                                        */7 m7 K0 F  Z; N5 E% G
  735. /*                                                                                                                                                */5 r  o& \7 }  i
  736. /* Input:                                                                                                                                */
      Y) h3 v; J# X* u
  737. /*                                                                                                                                                */
    - o9 ^- k7 ?2 F) ~. T
  738. /*                byte1:                1st byte to be programmed                                                        */) e2 e$ A4 {) ^
  739. /*                byte2:                2nd byte to be programmed                                                        *// _2 e) ]4 f, V! q, N& K6 F
  740. /*                                                                                                                                      */
    8 X  y' _: N+ e( [0 ]: G& S- {
  741. /*                                                                                                                                                */2 J2 b, Y, {5 j# O" ]+ L
  742. /* Returns:                                                                                                                                */
    ( `/ X  E0 `1 A" t2 |
  743. /*                Nothing                                                                                                                        */$ }8 _) P: O/ V# I" T5 b
  744. /*                                                                                                                                                */& G# i8 g# Q9 `- _2 e, m0 ]& K* N/ O
  745. /************************************************************************/7 b: W4 O4 ^  j) Q
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)9 K. L9 A0 v3 [! j
  747. {. I2 E* x0 P# b  u3 B$ R, D4 `
  748.         CE_Low();                                        /* enable device */
    8 a# U- b# N* J" y9 z, U
  749.         Send_Byte(0xAD);                        /* send AAI command */
    : N% {* \1 r7 |. h' k( O
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */3 n  ^$ j0 z* h: N8 j9 n
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( P  a! u/ g6 s  W
  752.         CE_High();                                        /* disable device */
    3 c4 \" x, a7 u7 n$ _" a6 B/ `
  753. }
    4 L; e/ x" `9 k" |

  754. 4 x2 |0 S$ ]3 q% a2 `( r
  755. /************************************************************************/5 V/ S! k( y0 G& c6 J4 ~& ^7 d. d
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */. p0 d: a; O1 D3 e) d( J# j2 s
  757. /*                                                                                                                                                */
    ; ^6 Y% {* E  B# L
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */5 R& `. R$ X! ?3 ?/ N0 K7 n7 R
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */( f# }& R% ?* ^( `( y- J
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */) O1 L% \, j. M0 E( t6 W1 D
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ! X% y3 O0 ]3 k7 ]% _& ^8 I+ K: ]) S
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    . X% d- F: k. O  R8 {& Y' R' ?/ H
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    0 l6 s5 t9 q/ q6 k- U
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */) N, W! F: `; }$ c+ C% v
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    / b9 ~, s0 O# _6 P8 V% r( t
  766. /*                                block protected.                                                                                */
    4 c4 ~3 a" x2 m
  767. /*                                                                                                                                                */- h3 ]) l5 `2 F: m  m
  768. /*                                                                                                                                                */
    3 g' r2 s0 c! j: L" I& N5 z+ P
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    4 Z: e8 v" k! O2 {
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    , Z. ~% ]1 Y: k! y. w$ V" C" x' W
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    2 ~+ ^% C/ k  m/ M1 F
  772. /*          to exit AAI mode unless AAI is programming the last address or                */; `  W3 u7 B0 B5 a) k. t% Z* j
  773. /*         last address of unprotected block, which automatically exits                 */' x( G* v% ^# @5 q/ e9 J; @, L
  774. /*         AAI mode.                                                                                                                        */
    % |$ ?6 p0 j0 E* z, \2 p5 y
  775. /*                                                                                                                                                */8 B: G$ S" U: l" K! x
  776. /* Input:                                                                                                                                */
    + I$ R0 n- c5 o/ \9 Z0 Y- u# |
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ q; C7 a5 Z1 E9 {
  778. /*                byte1:                1st byte to be programmed                                                        */4 g7 k% e: [1 `, ~3 |; d! k/ R( C
  779. /*      byte1:                2nd byte to be programmed                                                        */# y& t( F# K! Y6 \) ~' p
  780. /*                                                                                                                                                */1 j& \6 j2 n, w. B7 b3 y1 Z
  781. /* Returns:                                                                                                                                */
    2 u5 C* w+ i* J: b! J5 M0 n8 [
  782. /*                Nothing                                                                                                                        */* l% Y6 Z: X2 A
  783. /*                                                                                                                                                */
    1 T& s5 v- r( j8 X
  784. /************************************************************************/
    , a. _/ Z- _8 C+ L7 C6 {
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)$ H, j' {3 p' @& @8 u
  786. {, ^/ R, `+ n1 U3 L% T7 D3 ~( i
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    * U# e9 N& N; A3 ?" g

  788. 9 F: E) T7 u2 L6 j5 G  t& J
  789.         CE_Low();                                        /* enable device */
    , m3 U0 n+ R6 n, D4 ^0 q
  790.         Send_Byte(0xAD);                        /* send AAI command */3 X/ E9 d+ B2 h3 d* U  r; |0 H
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 d3 b' x: a# Q" Q/ Y* H9 m: N& K  h& g
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # c' n" d3 F& c) b+ u+ @2 K7 o
  793.         Send_Byte(Dst & 0xFF);
    ) ?( x. N( a2 J7 ?) S& O& x3 i9 Y2 N
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    : D- P1 m3 p: c( t
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */( A; i) b( l) |2 a
  796.         CE_High();                                        /* disable device */
    5 G4 [, K0 |" ?0 N; i  ]. d
  797.        
    0 b% R! `: X$ ]' _4 Z
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */  c: X& {% M$ ?6 n% u
  799. ! X- U2 F6 M% `, `' U! L
  800. }
    9 v2 E' r, f* o2 \+ G7 g1 P
  801. + H) u4 C  R5 v: u; j
  802. /************************************************************************/2 m/ _8 Y' O  B4 P# |! a% D! R
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */! [8 W, H0 a( }0 }
  804. /*                                                                                                                                                */& h3 H1 M# t3 w6 M* i. f
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    1 F9 h2 h7 ?# S
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */" P1 |+ A# [8 }' f& N
  807. /* AAI programmming is completed.  It programs consecutive addresses of */0 y8 W0 L3 V# Y* B$ U
  808. /* the device.  The 1st data byte will be programmed into the initial   */( Q# f& p# m) W9 Q2 j: p7 r
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */! d3 G1 w5 [+ m4 d, I
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */7 P6 b& l" n; Z
  811. /* used after Auto_Address_IncA.                                                                                */8 j: H* |' t7 G- {3 j9 p7 A  u- l
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
      e7 Y$ E2 S$ Y% L$ j, G' L/ J
  813. /*                                block protected.                                                                                *// f" J. L2 j8 {1 E$ E; |
  814. /*                                                                                                                                                */
    6 ?2 g1 m. e( t0 w6 C
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    + }  A. K: ~& Z5 |
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    6 o% b( f6 u4 ^8 q# J, C9 }
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */7 n- P/ d* A0 a$ J( k
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( U& C) _+ @5 x( T( ]
  819. /*         last address of unprotected block, which automatically exits                 */
    0 y6 a6 }3 u! h! d, I+ N% P, Z
  820. /*         AAI mode.                                                                                                                        */
    " M4 i+ E5 [8 A2 E
  821. /*                                                                                                                                                */$ w, a, L) w4 I4 w" U- g! n
  822. /* Input:                                                                                                                                */
    ' K; r0 S4 Z- s' \
  823. /*                                                                                                                                                */
    ) `+ \7 {/ Y2 G' Q
  824. /*                byte1:                1st byte to be programmed                                                        */
    & h8 \, W1 l6 i6 R. \$ t& r3 P
  825. /*                byte2:                2nd byte to be programmed                                                        */
    ! l# c* g$ T& v: I- o1 k4 d
  826. /*                                                                                                                                      */, |" y8 O# m+ `8 H/ T+ l
  827. /*                                                                                                                                                */  g" Y' ?5 ?5 N( G
  828. /* Returns:                                                                                                                                */- w: z+ |- J/ i6 R" S! D- S3 I
  829. /*                Nothing                                                                                                                        */
    / l* G  ]$ p- O$ [7 m  e
  830. /*                                                                                                                                                */! E" n& c" M/ P# d& a/ e' d: s1 c4 l
  831. /************************************************************************/
    . f: S. j  D: f& A  l0 }2 s# ]
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    + g! T0 m( `' T/ Z' }
  833. {9 S1 N8 M1 R) @6 a5 y! T4 j
  834.         CE_Low();                                /* enable device */$ q: N" H0 L5 {- Q+ P9 ]
  835.         Send_Byte(0xAD);                /* send AAI command */# N5 }% ?; f% j. K
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    - b3 q. z3 |, l2 U6 W
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */+ g  W: p) ]/ q) u9 y9 x
  838.         CE_High();                                /* disable device */
    7 m; A) X: i# {  }2 l" k
  839. + b# K! h0 `" P$ L; o& C
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    * d5 H2 o" K9 I9 L! S9 F4 U( G
  841. * k  t+ ^4 M& F5 m! x, [8 ^0 ?
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    & ]2 c( r& h% N+ A& M
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */. g7 A  b( n! F: a) q  Y, v. S
  844. }/ r) j/ k) E5 w0 k  X1 h
  845. $ R. c1 E  x1 _0 D
  846. /************************************************************************/' n" j$ k. \$ e4 \* u
  847. /* PROCEDURE: Chip_Erase                                                                                                */+ }( v& D9 u1 F+ s! b
  848. /*                                                                                                                                                */9 O6 |5 _* s: q; U' q
  849. /* This procedure erases the entire Chip.                                                                */
    3 g7 h8 u  }4 Z" f4 {/ L7 Y1 ~
  850. /*                                                                                                                                                */
    ) D" h- c" r6 f9 r. @( z8 c
  851. /* Input:                                                                                                                                */
    7 u. ^% h3 y" ^, X7 ^. [: O" v
  852. /*                None                                                                                                                        */7 ~6 j2 Q6 f) w8 Z( \6 a/ J
  853. /*                                                                                                                                                */
      o( l5 j) r3 H
  854. /* Returns:                                                                                                                                */
    8 s' [& `9 x1 V' w  u8 {" c
  855. /*                Nothing                                                                                                                        *// Y" S  u3 x2 \7 ~
  856. /************************************************************************/
    # E# X$ N. e& N4 }1 B
  857. void Chip_Erase()  g9 F. I  D% N6 T4 ~
  858. {                                                / C# B) f3 N, K- H- ]/ ]$ s
  859.         CE_Low();                                /* enable device */: j- i- k0 M4 N' c; s1 x! z
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    5 c! j2 d: B( O: U
  861.         CE_High();                                /* disable device */
    # E3 B' Z) O/ x+ k' M
  862. }
    - d$ @! q/ W7 ]4 L$ n5 ]5 Q% I# j

  863. % g# i: C- d) E9 h  @
  864. /************************************************************************/( B9 T, K6 ]% X% h' P
  865. /* PROCEDURE: Sector_Erase                                                                                                */4 v. T! O1 l3 J
  866. /*                                                                                                                                                */$ O5 K' A  {6 P3 T; k0 Y9 h0 L
  867. /* This procedure Sector Erases the Chip.                                                                */0 k8 l& ]5 q. a6 b$ M: |& [
  868. /*                                                                                                                                                */
    $ s$ n) s- }5 }- L: P
  869. /* Input:                                                                                                                                */
    7 j/ i" }# B# t; e! _" @
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */8 @5 |! Y$ E; ]2 g" d
  871. /*                                                                                                                                                */* v( o& J* a, h8 k! c  s; E
  872. /* Returns:                                                                                                                                */+ p  l3 V$ C  ^
  873. /*                Nothing                                                                                                                        */5 @# Y& c) x3 D; H  L
  874. /************************************************************************/
    & h# D- [2 s# B, b
  875. void Sector_Erase(unsigned long Dst)
      P; P0 h& H' I* q
  876. {% W: Y6 c8 }) P( |" r8 v8 K) K' f
  877. + m9 r2 v2 v" ~6 t0 F) K

  878. 6 |$ t2 ?! r/ w# i- j
  879.         CE_Low();                                        /* enable device */9 l7 t! u; n6 B# N7 \2 f0 @
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    + I: s8 k% G5 T% {0 D
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    5 A/ n3 I" G9 u
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 m3 y, L: [+ {( Y  O
  883.         Send_Byte(Dst & 0xFF);
    " C2 _% ~% u" r  V6 k0 Y4 F
  884.         CE_High();                                        /* disable device */
    " P; g0 b# e$ Y3 u6 ]$ |7 @
  885. }       
    ; Z- r" u% y3 F7 H
  886. ; D4 o# b$ @2 U: }
  887. /************************************************************************/
    & ~: V0 ?: C. p; K9 t) o% q
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */5 p) ?0 M* T6 k# K( m. L3 Z. u. e
  889. /*                                                                                                                                                */2 ?8 x+ f. |( M  w) q2 j$ ~
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */$ B, w7 L  D- A! }: b5 C
  891. /*                                                                                                                                                */! C' {# v* H5 ~: \
  892. /* Input:                                                                                                                                */2 d" ]+ A- B- A8 y( V! E+ Y) W
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 {$ g  V* k( z& s
  894. /*                                                                                                                                                */
    6 C' E, V0 M7 q: F" ?- q- ~/ u
  895. /* Returns:                                                                                                                                */
    - @1 S4 h) ?1 ?. f' M
  896. /*                Nothing                                                                                                                        *// G9 v! H: @( K4 ~0 z/ N+ t) i
  897. /************************************************************************/
    - C) z2 E* d: P6 l7 U- p
  898. void Block_Erase_32K(unsigned long Dst)! _, @( \1 H& Z5 e1 C
  899. {
    8 @6 ?' q/ Q3 k% }4 o3 d3 {
  900.         CE_Low();                                        /* enable device */
    4 t4 r# y, N5 @& {# W. {9 M& E) f
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    7 v* N2 A# d5 d
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 v; e- }) I. P- f5 n
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 ?( C9 C3 v! _/ l$ W
  904.         Send_Byte(Dst & 0xFF);$ k( D) x0 f8 d1 _1 v4 t
  905.         CE_High();                                        /* disable device */
    * {, i' h  e3 p: q
  906. }
    ! O3 _. V6 z  E
  907. 7 e7 X& V& w# F7 z7 @; a* r/ a
  908. /************************************************************************/1 N, t6 R( O( `- c0 s4 H9 w/ R
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    7 V) o+ A; Q7 N  Z4 _
  910. /*                                                                                                                                                */0 `5 }+ i; F8 h1 u* b, Y* {3 A
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    : V& G6 p7 ?8 j' b0 M
  912. /*                                                                                                                                                */
    : x% h9 m5 U1 e$ ], _7 D% j) x$ ?3 t
  913. /* Input:                                                                                                                                */
    0 G6 n4 O% B& T7 k
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// Q% `  {1 M3 l3 i+ b6 X
  915. /*                                                                                                                                                */
    4 R4 E, X7 K8 f, D. V: z
  916. /* Returns:                                                                                                                                */& m( y' W* [+ Y. x8 N1 b9 V, Z
  917. /*                Nothing                                                                                                                        */
    7 `, h+ y0 B+ s; F3 c; K; i1 O
  918. /************************************************************************/
    ) a# E" `3 f! w( I/ B0 Q" U1 \: d
  919. void Block_Erase_64K(unsigned long Dst)2 b* }1 p5 t: ^" Y8 O* `) z
  920. {# s- {  U2 y9 g+ w
  921.         CE_Low();                                        /* enable device */$ q$ ?5 m% w, s
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */% M2 j) ~# ^" n! Z) E: z
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , k: V1 G- o8 `
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 H& g8 i3 k8 U: O% T# a
  925.         Send_Byte(Dst & 0xFF);
    9 Q- N. }3 A% Q7 v
  926.         CE_High();                                        /* disable device */
    6 B7 H. L3 Z/ i4 K* u; A+ c
  927. }" z: I% ]: Q, ~5 I! z5 ^# F; e) M

  928. 8 u, U& ~8 A, T2 p1 s
  929. /************************************************************************/
    2 q( B& x( u+ _0 _$ M. _( Q
  930. /* PROCEDURE: Wait_Busy                                                                                                        */% W0 h9 z; r, L6 J
  931. /*                                                                                                                                                */
    : A$ ]+ J8 q9 z8 f' j
  932. /* This procedure waits until device is no longer busy (can be used by        */
    9 V3 y; p9 V* m0 w
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    # l! h. C7 u3 p) m
  934. /*                                                                                                                                                */
    ' {) p4 G8 {' J" W
  935. /* Input:                                                                                                                                */
    0 o$ f8 C: i5 h7 E5 A# H7 g' f
  936. /*                None                                                                                                                        */+ D8 C- ^: \5 E" L( z" P; z
  937. /*                                                                                                                                                */
    ' d8 V; M- l5 m( w
  938. /* Returns:                                                                                                                                */
    / i% E9 e2 l: b
  939. /*                Nothing                                                                                                                        */$ K/ \% `* X( j* r
  940. /************************************************************************/
    ' q( G3 l& B4 U% P
  941. void Wait_Busy()
    ! \3 m2 n( L* i7 p  Q
  942. {
    * f# D0 m# r" r( G, i" l  A% o& z
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    ' s! B6 U0 b8 K. A/ x& e
  944.                 Read_Status_Register();9 r  f( c* n1 m, Y1 e8 K! C
  945. }# P+ o0 `9 z, M, {: P0 M
  946. 1 }$ ?) ?2 _0 s( G' n! X
  947. /************************************************************************/7 X5 s1 j5 p- O8 L, P% [. E( O$ e
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ) R1 L$ a5 z5 p2 |: K
  949. /*                                                                                                                                                */
    $ h2 o7 ^5 P4 v3 z1 @5 Y
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    2 K& J: s9 P) ^6 R
  951. /*                                                                                                                                                */
    9 N% I' Y* A6 p6 q. G* Y
  952. /* Input:                                                                                                                                */
    ; }/ U2 Z( h: V. d4 D3 Y9 T
  953. /*                None                                                                                                                        */1 I0 s8 q$ d% a: m
  954. /*                                                                                                                                                */4 Z2 e9 h; _5 ?6 P3 @
  955. /* Returns:                                                                                                                                */
    4 T) z* x6 o' p. D4 L
  956. /*                Nothing                                                                                                                        */
    3 ?. t( S! A) e0 J( j% F1 }/ y; j
  957. /************************************************************************/
    # `6 t" q5 w/ [8 H
  958. void Wait_Busy_AAI()7 h# s  e2 m! \
  959. {  {8 f# w, k' R
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    1 n5 T6 @) i, H# Z* X2 U' E
  961.                 Read_Status_Register();, J7 R  c  B6 M& U+ r6 C
  962. }
    1 e8 H( v- M1 r4 I7 i0 m  p1 U

  963. , `' `9 z$ T  i' G
  964. /************************************************************************/5 r7 s7 K6 }% G+ y. B; W
  965. /* PROCEDURE: WREN_Check                                                                                                */0 Z- j% x+ U( T: P$ ]- l
  966. /*                                                                                                                                                */
    . S7 T+ c' f. P( y
  967. /* This procedure checks to see if WEL bit set before program/erase.        */8 r" l+ L2 K1 T( ?
  968. /*                                                                                                                                                */3 n. R. b% C4 q
  969. /* Input:                                                                                                                                */
    / f" T- B# m& H* K2 g
  970. /*                None                                                                                                                        */$ @( n! `$ C0 U$ F& T7 [
  971. /*                                                                                                                                                */
    ! o/ q) y/ S6 d/ F9 G2 G
  972. /* Returns:                                                                                                                                */; m9 i; u/ s0 v! A# e
  973. /*                Nothing                                                                                                                        */( O0 y' f) w( b: c( Q9 R
  974. /************************************************************************/8 ^' z% z2 I: q4 Q* t
  975. void WREN_Check()
    . C3 G. f" r4 d, }2 w6 ]- K
  976. {1 l3 W2 O; g2 i. u, e
  977.         unsigned char byte;
    * I0 m- E  h5 N" y: _2 r4 V
  978.         byte = Read_Status_Register();        /* read the status register */
    & t+ C  i/ @# }$ M- s& E
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    3 j# M7 \/ x4 ]! e! a
  980.         {
    2 X& A8 T0 |! ?# D! h
  981.                 while(1)) G5 T, V" Q6 q( q2 g3 f  _0 a
  982.                         /* add source code or statements for this file */
    1 C4 m( a! ~( y/ q. B
  983.                         /* to compile                                  */' o0 P- q2 \/ E0 E6 b! ^
  984.                         /* i.e. option: insert a display to view error on LED? */
    9 t& {% `$ ?& X; H- K1 Z
  985.                  
    7 S5 r: C4 a% P. B! M! D1 G  g
  986.         }" B2 M9 U8 i" |& u& i
  987. }! ^0 _  I5 i' ^4 {2 C6 `8 l
  988. + V2 p* @' j; W* g
  989. /************************************************************************/& T6 k: G; Z. W/ _
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ! c0 b. r7 T! m1 T1 C1 o' g8 k
  991. /*                                                                                                                                                */( k( M, i8 @/ O
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */8 i/ k9 K# {6 k9 ?1 L4 ~5 z4 e' a
  993. /*                                                                                                                                                */
    4 ^& D! d9 s$ T, [& k
  994. /* Input:                                                                                                                                */5 \5 U' l. g: D1 M
  995. /*                None                                                                                                                        */& Z6 b4 w4 J* z1 G7 f* w" i4 q8 {
  996. /*                                                                                                                                                */
    ! |! l( J% ]7 @. v
  997. /* Returns:                                                                                                                                */$ ^% G$ l( u9 p+ w$ y
  998. /*                Nothing                                                                                                                        */
    $ ?# I/ W/ Q( n6 L9 z- U4 [
  999. /************************************************************************/
    7 G+ t. I# k8 ~9 c+ g
  1000. void WREN_AAI_Check()
    : V$ I; ^1 N5 L# V; q4 l/ M. m+ b
  1001. {
    + s9 W4 v, B7 p8 q' V. E) A( ~" K
  1002.         unsigned char byte;& p# t7 L5 I9 Z
  1003.         byte = Read_Status_Register();        /* read the status register */
    + q4 K3 O; {4 f" B- c8 T& t
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */* z" |, j9 \- e# V# w. h* J
  1005.         {: ?$ G* W/ h% K  g( u% B! X
  1006.                 while(1)               
    " X' G9 S2 }: k! y  r# R. o% D2 E* s
  1007.                         /* add source code or statements for this file */
    9 L  F3 ~( V+ Z* @3 I
  1008.                         /* to compile                                  */
    : ]* P6 A; I- Q
  1009.                         /* i.e. option: insert a display to view error on LED? */
    1 l' J. L5 Y  ^# S1 j+ e

  1010. 8 }- |; g7 c) _: w$ M9 Z- A
  1011.         }9 k" k( a( f# R* m" E& e
  1012. }
    8 r# R' [0 s4 f( a
  1013. 3 l- r0 b6 Q1 _4 F8 P- j
  1014. /************************************************************************/5 G) U1 t* Q% ?( Z: @
  1015. /* PROCEDURE: Verify                                                                                                        */
    4 a: O5 G) y4 u
  1016. /*                                                                                                                                                *// m0 ^3 C9 n; N7 t4 I; g$ E& o
  1017. /* This procedure checks to see if the correct byte has be read.                */2 _, F+ j7 a2 D6 Q- Y) |9 g
  1018. /*                                                                                                                                                */) z! V! S; k( g" O" V
  1019. /* Input:                                                                                                                                */
    ; t- e9 G9 M6 r2 T- {! U
  1020. /*                byte:                byte read                                                                                        */2 v+ O* k. j' U6 j" ~; ~+ b
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    : }' [  \2 U% p
  1022. /*                                                                                                                                                */" n- g  B6 F: W% q1 W
  1023. /* Returns:                                                                                                                                */- M# m0 I% L, g/ j7 W: c2 ~
  1024. /*                Nothing                                                                                                                        */
    9 o1 A3 E, l/ [$ c- @& f; b/ f# M
  1025. /************************************************************************/
    * \1 O! m0 Z4 s) D' u
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    4 X! D% m  r: N6 V8 q& A$ \( B/ U
  1027. {
    & W  l7 `8 S3 I8 n$ ~6 f8 \5 R
  1028.         if (byte != cor_byte)1 e2 F# l5 Z/ h1 M9 c$ K
  1029.         {
    3 s/ U# j: p. |2 j" X$ X
  1030.                 while(1)
    , i9 ?8 O: r( q/ K! f0 s
  1031.                         /* add source code or statement for this file */$ m, X4 S7 R% V# g
  1032.                         /* to compile                                  */
    ( P/ }5 I( X  ~# B; b
  1033.                         /* i.e. option: insert a display to view error on LED? */
    " q# F- Q4 j& x5 Y# ]
  1034.                
    6 Y9 Y' r- G' A7 U
  1035.         }0 O5 R4 i1 m! r5 F' e/ G- F6 C
  1036. }& f. }) k$ m, o
  1037. ; D' y! k. u- `0 p9 O5 q: T
  1038. , i/ i8 y( J: Y; Q: y
  1039. int main()
    : Q' d4 }5 @% R0 w
  1040. {5 Y2 o0 F1 H3 A7 r) c! z" ?
  1041. * `% B% e! e5 {, V
  1042. return 0;2 ?2 i: Z) D1 F. O% N) I6 ^
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:& u) V& d3 V5 {- f
   main()
3 Q/ b  ?- N. Y. B% M  P4 M* |   里面怎么是空的呢?
! @+ Y; d8 A, M7 b, y   发一份给我吧
" A6 I' Z0 j5 M* F/ `3 O% bmail:luyijun2005@hotmail.com
/ j" `+ R/ [5 {) Y1 _7 d( g+ v9 m咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。$ K' S' q& ]0 j3 U1 j

% }+ I3 }7 b* f) n% p9 f7 h[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。; a! \. q$ C( e. m5 J
EC的代码在哪跑,你看DS的说明,每个EC都不同的。4 e9 r4 o3 ^4 s
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?# X) f  r2 H2 y/ j
上面几个问题是你没看任何东西而白问。# n$ a% G% C& u3 C
2 G7 n# z, f" O( M) j
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
1 b( W- o0 y. s* U( p
5 t0 B" c4 C+ a关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!# F4 q5 Z1 d- _: s3 B
$ `) X4 p4 |4 `- {
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
/ i6 o" f2 I* X: X/ ~
! m0 y3 M+ Q/ x1 y) C关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
6 X- O4 r, A" S2 h% E  ]% x8 e2 \6 f4 R1 D* m
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样, A) u) q5 H! X8 K% {5 w
似乎要把SPI能support 到最大,这EC chip应该有好卖点
0 [* z6 ^; q$ [. K0 s' ?0 L9 NBIOS功能要不要强大,也就决定了SPI Flach的大小
4 Q( k9 D. p# `7 F" a$ Z我是这么想的~让OEM去决定要挂多大!
" v& v0 `) v1 v5 k如果我司有BIOS工程师就好了~哈3 M" P6 Q0 \! c0 x- r
WPCE775应该算很新的东西,来看它支持到多大?5 u" u$ y" B! {* l9 y3 s

- ]+ S6 U% l5 n2 G* V另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte+ r. a: n. X8 \9 ]4 `% u4 C
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
& F3 S6 L$ s2 d9 A+ E/ ?: c# O% Y( a! s: l0 {# z
这份driver收下~希望以后有用到2 h. l$ o" Q- |( ?* B- \
谢谢bini大大
! r$ }. @# `  _7 s' ^7 m- N" e- b9 N  O, p4 [
很新很新的新手,如有错误请指正 (准备看第二家的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()7 ?. U9 o' ?' i% D& i
{. X7 B" b+ O8 v
        unsigned char temp = 0;
8 ?; v+ |* [3 K8 R' T8 f" K5 _/ z- x        CE_Low();: M5 G9 [3 V! C' c  O! o
    while (temp == 0x00)        /* waste time until not busy */
7 E2 h2 |) F' o7 W$ Y                temp = SO;6 T+ F' }3 m+ h7 k
        CE_High();
3 z: e9 Q# Y0 j! l}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)9 M$ q7 a% D2 l* W8 m; u* o
{
8 I: K; e5 U& Z7 u# V. J        3 ?. {  \+ m. X' A: l* I+ B
        unsigned char i = 0;
# U+ @/ ~( r: b6 D        for (i = 0; i < 8; i++)
2 e# ^* l8 ]: x0 h- g. e        {( o/ T/ u" a8 c, \
               
5 t7 A+ P8 I7 o                if ((out & 0x80) == 0x80)        /* check if MSB is high */1 D1 M6 S! M3 B1 F% H$ m7 D4 a1 O
                        SI = 1;/ y* @* z0 [- f
                else4 f/ z  V: e6 n! j) L+ [: n) y8 g
                        SI = 0;                                /* if not, set to low */2 V% L/ e/ Z4 G* z% B
问              SCK = 1;                                /* toggle clock high */% p6 X  ^& _6 ~' `* y+ [8 W# T( s
   题            out = (out << 1);                /* shift 1 place for next bit */
4 B* O. h) }  T" p* W                SCK = 0;                                /* toggle clock low */8 C$ ]" g: k1 M, I% P* U
        }2 O; i, R- G% j" J+ `; C
}" i2 C1 ?) p6 t7 u/ g
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-8 07:07 , Processed in 0.048779 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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