找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55571|回复: 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
    8 ^; r: O8 c8 B; j" X1 f8 y

  2. 6 r9 ^  `, d$ c, a. ?; L
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    8 G& Z( M' G  P' w) [9 S
  4.   z! i) D! W8 }* f4 x9 R1 b/ I
  5. November 4th, 2005, Rev. 1.0
    ) j% j$ k0 [) m1 ?
  6. 5 K  K% Q+ I) c2 o
  7. ABOUT THE SOFTWARE  ?- Y% o, y! N2 ^& I+ o6 X+ i
  8. This application note provides software driver examples for SST25VF080B,4 G7 ~- E6 I9 h6 b: \
  9. Serial Flash. Extensive comments are included in each routine to describe
    8 K- ]0 ], X6 T. ~1 h
  10. the function of each routine.  The interface coding uses polling method ; Y1 N1 D1 j$ k8 H1 ]" L. D
  11. rather than the SPI protocol to interface with these serial devices.  The
    * Y% b) L; Z& o1 E
  12. functions are differentiated below in terms of the communication protocols
    ' J4 }( K/ }7 u  f
  13. (uses Mode 0) and specific device operation instructions. This code has been 7 \; R! K% ^9 K3 h. h
  14. designed to compile using the Keil compiler.
    " f: n  x* e$ {2 E( c! q0 |

  15. 8 W2 m. \& p* P* L
  16. 8 a( s0 K* x" |2 B
  17. ABOUT THE SST25VF080B
    8 e- \0 B( _* o- X
  18. : q% a- y# U5 @4 X" |1 o9 I8 l
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    $ b$ l$ D' Q! E
  20. conjunction with this application note for a complete understanding
    4 K' F" s) ?& u+ l; E) T
  21. of the device.
    8 M  ]& x! E0 u& V2 c; i! [
  22. - V: W1 r0 {- X5 D: \

  23. 5 O& W$ r' e4 u' ~+ `5 ?
  24. Device Communication Protocol(pinout related) functions:
      s0 V2 n4 N: D& I) Q, \* P$ I/ R3 S' E
  25. - P. U, T4 i# C& i+ n2 H* U! P
  26. Functions                                    Function
    : Y1 V; r- k4 N/ @1 n) o) x
  27. ------------------------------------------------------------------
    # P5 V3 v! ?% Y+ Q$ f1 p' R' U3 X# Q- s
  28. init                                        Initializes clock to set up mode 0.
    0 o$ Y8 r, Z1 s1 u% W7 `: h' K
  29. Send_Byte                                Sends one byte using SI pin to send and ' Z+ h8 j. |  M. ~  {+ K
  30.                                                 shift out 1-bit per clock rising edge
    ) \* ]4 P3 Y( d# R  B0 \
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    ( e" {+ m& y% W" Z" Z8 {
  32.                                                 in 1-bit per clock falling edge8 Y: ~( U: t  c) \! N: d5 B
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    0 c+ h! S9 d! n; r0 a9 h
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high- q- D- _% `& H3 B3 q7 n
  35. CE_Low                                        Clears Chip Enable of the serial flash to low" B# Y% W0 B: p% e: N
  36. Hold_Low                                Clears Hold pin to make serial flash hold* l7 a. d) v4 G4 i7 c; C8 v; \% ?
  37. Unhold                                        Unholds the serial flash
    3 ?0 o3 ]  h5 V# }9 A/ n3 x5 A
  38. WP_Low                                        Clears WP pin to make serial flash write protected0 g5 ]) L+ c( K( h
  39. UnWP                                        Disables write protection pin8 h$ J) l0 t! w: I- X4 }
  40. # V: l7 x% F% z3 v' v
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code) j; D8 @+ b8 o+ ^" Q
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your+ n1 Q# k# \$ [. w
  43. software which should reflect your hardware interfaced.            K, Y8 z# [4 z& L; ~1 \. R

  44. , y9 l* q8 Z% W. |7 K1 W5 S

  45. 6 w% z- V" i% L
  46. Device Operation Instruction functions:
    6 k$ [/ k6 ^0 S3 u

  47. - d. u% y5 A" e, K8 M: O% g* d- N
  48. Functions                                    Function" T7 @& J5 Y/ x! {! n) Z& c5 m; w
  49. ------------------------------------------------------------------
    , F- }) a% v4 k
  50. Read_Status_Register        Reads the status register of the serial flash
    / t- v+ ^. D9 V" e) b
  51. EWSR                                        Enables the Write Status Register5 f: z3 J9 U7 z
  52. WRSR                                        Performs a write to the status register
    . X1 s' G: X  h, S: M, o8 ^! C2 Y4 U' ]
  53. WREN                                        Write enables the serial flash) z! C3 `- o  v" D( ?% D
  54. WRDI                                        Write disables the serial flash- ~/ B8 }8 c( n& j  q4 W
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming& Q% B; Z" J5 J6 ^: |9 D0 ^: Z) G
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming( E5 J" o$ H) w  l$ M( W4 F
  57. Read_ID                                        Reads the manufacturer ID and device ID
    . u+ M  G2 Z  g5 o
  58. Jedec_ID_Read                        Reads the Jedec ID) p, S  F* s' x8 u; M! A3 l
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    - d2 M4 ^. g) u$ m# x5 v1 J
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    / i3 Q6 E4 ?% J2 |3 S" Y0 t
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)* e; T* o3 c* W) v% W! H
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    : T9 n: @+ q1 v  L+ M
  63. Byte_Program                        Program one byte to the serial flash
    ; Z- e  L2 x2 l  l7 R& G
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    6 ^5 V) g: W6 i* Z
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation1 ~( @2 I: l4 G4 w  H6 b- t
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    / e! V9 l1 k% N7 i- F* v
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    8 l9 ]5 j1 L, Z) R$ }8 n8 O7 f
  68. Chip_Erase                                Erases entire serial flash9 c: i! S7 ?0 V' v' w6 g# E
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash+ U3 x) O) w% h9 |9 s
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash( R7 f4 }( h3 N6 H9 \7 k
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash  ?& g8 c4 r" d0 y/ G& D
  72. Wait_Busy                                Polls status register until busy bit is low, @( p& ^5 `( b4 G7 u3 D) h
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    * e. ~, o- g; n. Y3 [) Z. |
  74. WREN_Check                                Checks to see if WEL is set
    ( u1 x+ m" }" m
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set( e. K  N% Z& f# u- p

  76. 5 J/ v0 ^; D/ v4 {5 u0 W

  77. 9 d; X3 ]' f" r2 f# N7 d
  78. 8 f+ k0 @* G! A
  79.                                                                      
    # Q3 I6 d% d4 R, u
  80. "C" LANGUAGE DRIVERS
    + H! {* w( w* ]( D8 M: N% G

  81. . e" M" \( I1 f; z  a9 R! {
  82. /********************************************************************/
      [& |8 T: }7 M  k( R: }
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */4 z0 O) S3 J6 P0 m! F
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */( Q, H6 B7 o1 v
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */, d4 x$ Z% ^/ Y/ U) X  o
  86. /*                                                                  */) g$ [; f6 H" N  J6 n, d
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    0 a7 G. W% K8 v; O9 l, u
  88. /*                                                                  */# R; q8 s; e7 P7 _8 [: T' b5 D
  89. /*                                                                                                                                        */
    3 K3 w7 k. Y! ~
  90. /********************************************************************/6 ^9 }7 E- O3 ^3 t3 n

  91. # n$ x( a# R! j; D4 s# F* {' ^
  92. #include <stdio.h>8 j9 E. T  |: {  K3 V( W5 I
  93. #include <stdlib.h>
    $ y/ H; g2 s( a4 _9 N
  94. 5 q( x! d; P$ Q9 y; {; F4 o
  95. /* Function Prototypes */
    9 K9 @  D4 R. N3 r* O

  96. . K1 O$ f& V  ^
  97. void init();
    / v* o( P# n! {5 `
  98. void Send_Byte(unsigned char out);
    $ G& N: \) K7 w- C1 Q8 H7 L+ v
  99. unsigned char Get_Byte();7 x( B) `- [. D( w) E& r( j
  100. void Poll_SO();
    , C, ~& W- W, c  @1 o2 F
  101. void CE_High();
    $ B. h0 b* h( j( M+ Q3 F7 X& U; U- u$ [
  102. void CE_Low();
    * ]0 w0 Z9 U4 Z! S1 Y
  103. void Hold_Low();, X; z% N1 v4 q2 S# n
  104. void Unhold();
    , ~. c1 f3 C5 q7 j3 b3 {
  105. void WP_Low();
    / ]- r/ ^; ]( J7 K- e8 I! H& B
  106. void UnWP();! o1 R. y5 k# X$ I1 [. X
  107. unsigned char Read_Status_Register();+ d( T) \" l5 b/ Y' |$ h
  108. void EWSR();
    $ n6 g  Q7 z3 `8 m" ]
  109. void WRSR(byte);8 s0 r! d& Y1 E9 b; q0 J
  110. void WREN();
    : Q8 Y& v2 k, c
  111. void WRDI();
    % L: ~" y& r. n+ q* S- W
  112. void EBSY();3 s1 t1 [) c$ }! `  z% K, H
  113. void DBSY();
    7 h! g4 @" ~  q
  114. unsigned char Read_ID(ID_addr);
    ( G) c6 R* b  v  j
  115. unsigned long Jedec_ID_Read();
    1 x( ?# S- ~8 L  p
  116. unsigned char Read(unsigned long Dst);
    ' q; l0 N/ C+ `7 O
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    - Z1 i4 q5 r, H+ ?" W$ q. D9 [. r3 f
  118. unsigned char HighSpeed_Read(unsigned long Dst); % C* v3 V& B* I0 q& p
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);, m; @: U3 V4 A% y" \
  120. void Byte_Program(unsigned long Dst, unsigned char byte);! c7 f( ~$ b/ T3 j6 \' n$ A
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);' G" d6 h+ t" H+ D
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);+ B6 J) P4 t. {1 \0 ?
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    4 Q3 z* h1 V) k; Q3 y- m/ l5 B
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    - ^* j$ K6 }4 ~. Z; y4 z  N
  125. void Chip_Erase();" h% ~8 K6 y6 l) e& `
  126. void Sector_Erase(unsigned long Dst);7 b% ~& {2 c/ V& @! }4 J( J" M* B2 \5 C
  127. void Block_Erase_32K(unsigned long Dst);. }6 ~# p" G5 A+ Q. ~* P& e
  128. void Block_Erase_64K(unsigned long Dst);- x- F8 l$ i- p
  129. void Wait_Busy();. h( j, z( E2 k2 L* _
  130. void Wait_Busy_AAI();
    / y( N. b: x% m3 M8 w/ g# F, I
  131. void WREN_Check();
    3 b! Q  |7 `0 b0 {$ y
  132. void WREN_AAI_Check();
    ; ~6 n7 ?& P4 K
  133. . k; K9 k  x$ i, {' ]7 Q. S
  134. void Verify(unsigned char byte, unsigned char cor_byte);9 Z0 Z8 _* ]* U3 }
  135. 9 H+ k/ }, J7 k  `/ ^# [+ s
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    6 @( L( \, G( L3 G; M9 C% y; j
  137.                                                                                 /* to upper RAM area from 80H - FFH */' }# G) s. j2 j
  138. ' X' ^7 \* |: e
  139. /************************************************************************/
      z2 ?& `1 A  Q3 g) X  h
  140. /* PROCEDURE: init                                                                                                                */* o7 x2 j$ P$ a* U9 k. ?5 W
  141. /*                                                                                                                                                */
    1 k- f, `3 r! X0 Y
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    + s: ^) \. J% E, P6 {' M
  143. /* setting up mode 0.                                                                                                        */
    ) s5 h, t/ ?+ Q9 j2 P- F5 j& w4 X
  144. /*                                                                                                                                                */
    / ~! A" {' q. v  b4 u. q1 W
  145. /* Input:                                                                                                                                */
    2 _, c- W% f4 d5 m- F
  146. /*                None                                                                                                                        */
    ; ~% v& p" z& F& w
  147. /*                                                                                                                                                */4 B; o. {7 {: t0 }% S& c7 g  [
  148. /* Output:                                                                                                                                */
    % w: H. ?+ E" t/ ~: C# w
  149. /*                SCK                                                                                                                                */: _5 ~: Q: F4 }" F1 ~% f: J
  150. /************************************************************************/, p! ^! l( ~9 K  W6 w, f
  151. void init()
    , ?& M0 f8 x/ M6 l8 {
  152. {# H% m5 s+ _: r" K0 m
  153.         SCK = 0;        /* set clock to low initial state */8 W* t# Y: [( s; g
  154. }. f. I4 D/ I$ v9 b1 K7 n7 ]% d
  155. 8 {5 j" A! D! P1 b/ W& m1 M9 F
  156. /************************************************************************/
    + c( I) L- s: S% ?
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    - B/ F. U3 R5 d
  158. /*                                                                                                                                                */
    0 h, V7 J$ P. f
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ! V& ^  j. c+ ^1 ]
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    5 F, J4 n+ c# }# Y$ ^1 V
  161. /*                                                                                                                                                */; V* w# d* Q+ L* x
  162. /* Input:                                                                                                                                */- j4 a4 U! u* a" z/ T7 n$ Q
  163. /*                out                                                                                                                                */. K/ G' f) n. K4 q! J  \
  164. /*                                                                                                                                                */$ P% H6 r' \& x
  165. /* Output:                                                                                                                                */. z, @* \8 @# m3 M0 B$ k4 U8 e
  166. /*                SI                                                                                                                                */
    0 F# S+ a' m7 g# v* x
  167. /************************************************************************/3 B7 k9 W* D( E. V1 t
  168. void Send_Byte(unsigned char out)& p+ O& d' S& Q& h% A
  169. {1 u! r/ H( X# j! u% F  z# {
  170.           X8 S5 k* V6 w; F
  171.         unsigned char i = 0;
    ' X- u2 J% R# n# |3 z/ ^" F
  172.         for (i = 0; i < 8; i++)
    ' o) O) z' g$ R/ K1 f  b- R
  173.         {
    3 N; H5 N7 ?9 U: I7 I& A; q
  174.                
    + a& }9 H8 W# h6 Q  i
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */: J( A7 p8 n. n3 z( H8 ?
  176.                         SI = 1;# A& @# Y% }+ z
  177.                 else7 X& K- T. n2 q; v
  178.                         SI = 0;                                /* if not, set to low */$ r; f1 J1 ~- ~4 |% V$ D0 r$ o
  179.                 SCK = 1;                                /* toggle clock high */
    7 E  n, d  k2 q. \1 z3 _  b
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    % K" W9 j- t3 D. I
  181.                 SCK = 0;                                /* toggle clock low */! {/ E( ^; ]* ^9 U
  182.         }* ?! g& X1 T( Y2 u3 \
  183. }* m+ v$ W5 i$ r' [8 N5 y

  184. : c3 {+ b! B! a7 @8 N% V
  185. /************************************************************************/
    . l# m. F1 @6 m0 D5 Y
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    6 |: b% S8 I  L+ @- Z7 l# X
  187. /*                                                                                                                                                */
    ! ?# p2 l- ~" S, I( F7 b% R, O
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    : I# U' `: Y8 y' @7 }
  189. /* edge on the SO pin(LSB 1st).                                                                                        */3 F5 L. G% s2 U
  190. /*                                                                                                                                                */
    / i& [7 w" p- i4 l  z
  191. /* Input:                                                                                                                                */6 R5 t# I& @' @+ i/ r
  192. /*                SO                                                                                                                                */. ^& p4 c" Q" e1 v6 ?
  193. /*                                                                                                                                                */! z; @/ q! H, w+ G$ v2 P: g
  194. /* Output:                                                                                                                                */
    5 c8 [8 C5 H& q, O% L
  195. /*                None                                                                                                                        */
    5 h' \1 d( \7 T! n2 W
  196. /************************************************************************/% g8 O$ Q7 e) a! A& w( t
  197. unsigned char Get_Byte()5 c3 b7 Y: l7 t  J" F/ Z
  198. {
    ; w4 z4 c1 ^0 K7 g6 f
  199.         unsigned char i = 0, in = 0, temp = 0;
    & i" Y: K& f! k8 F! ?
  200.         for (i = 0; i < 8; i++)7 A+ B2 ?  t& b$ M
  201.         {
    ' H4 Q- x- c) a6 T4 Y
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    9 d& y0 ^( D- L6 i$ M/ A; C/ a
  203.                 temp = SO;                        /* save input */
    . R# n4 S1 y1 H
  204.                 SCK = 1;                        /* toggle clock high */9 Y' F3 d) ?, S8 ^+ s8 T
  205.                 if (temp == 1)                        /* check to see if bit is high */8 A8 F$ D. l* J8 T  \% Q; r
  206.                         in = in | 0x01;                /* if high, make bit high */
      H: N. l" ]9 M0 M' f

  207. + A2 q# ]; T; t; `
  208.                 SCK = 0;                        /* toggle clock low */
    ' z7 b8 Q; l, c8 C4 L. A' v

  209. & {4 E1 `$ c& j+ z# v' q0 [
  210.         }
    . U1 k+ }6 D" x' k5 R+ B" |
  211.         return in;& S* \6 b2 v, _
  212. }
    2 E+ \  Y' F4 E# |& h6 ~) ~

  213. , Y" q- q' K6 T) b/ ?
  214. /************************************************************************/
    2 \8 A/ f( s* g$ {
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    4 f! x6 H' q  D+ |7 s& H  R+ W
  216. /*                                                                                                                                                */) J! B# d! {) t+ C: K! y5 ]3 K
  217. /* This procedure polls for the SO line during AAI programming                  */
    5 i- t3 ]( J0 w5 D- h0 X: X
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ! Y; {9 |2 \5 D+ }' R/ H% v
  219. /* is completed                                                                                                                        */$ j4 ^, q8 B: x* Y6 y
  220. /*                                                                                                                                                */
    ( A6 |$ c3 q; |! ?6 W0 l8 Y& M
  221. /* Input:                                                                                                                                */
    + W5 ~- M$ S9 O
  222. /*                SO                                                                                                                                */
      t7 c+ y* G2 X6 n
  223. /*                                                                                                                                                */
    , x: o# a# B- X# M7 c' ~( g
  224. /* Output:                                                                                                                                */
    % n) ?/ j0 D% O& O- f# k+ B2 l# k
  225. /*                None                                                                                                                        */
    4 n- f! A6 L; A; X- b3 R2 c
  226. /************************************************************************/
    . t: e' |; m3 ^" d5 v
  227. void Poll_SO()
      z6 H5 ?. R* X$ S6 M3 _! h' u
  228. {
    * B& ~0 E: C/ Q7 B: t: w6 M
  229.         unsigned char temp = 0;
    # j4 i) r" W& Z; X/ }
  230.         CE_Low();
    % k" E/ B2 U0 `6 H! R$ f) i
  231.     while (temp == 0x00)        /* waste time until not busy */
    + e" H. q9 ]0 F. K. ~) e. Q! H
  232.                 temp = SO;  j( ~+ \$ ?/ l
  233.         CE_High();
    ! S# C% X0 t; Q+ `7 W; P
  234. }$ H/ h1 l( w/ w7 x/ ~% S

  235.   w0 u" ~! {% D  {
  236. /************************************************************************/
    : A4 @& L9 ?) e4 X, _3 w8 M, r5 n
  237. /* PROCEDURE: CE_High                                                                                                        */1 `$ n4 D+ C: ]
  238. /*                                                                                                                                                */
      m; s/ Z/ v) z2 g
  239. /* This procedure set CE = High.                                                                                */
    6 l' g% j: R, B8 G9 S! {; n. ~) e: g6 o
  240. /*                                                                                                                                                */, G" |9 ]2 C7 K0 S& U
  241. /* Input:                                                                                                                                */
    ) C/ J) g+ @5 |4 ~' v6 z/ n
  242. /*                None                                                                                                                        */
    3 t/ y5 m) v/ N9 r0 D+ x5 }, J
  243. /*                                                                                                                                                */" Q7 D) _- w9 R, L9 s, u: g% J
  244. /* Output:                                                                                                                                */
    : t8 A" ~8 O6 t/ l) N( X1 j# j& ]2 o
  245. /*                CE                                                                                                                                */* S+ [+ a5 e2 b% b& w9 i
  246. /*                                                                                                                                                */
    ( T7 n6 t4 g8 C8 f$ s
  247. /************************************************************************/
    & i% O5 N, d  @) D; K% x4 |  `, j
  248. void CE_High() : d+ d; w5 e) A5 ^  X
  249. {
    7 }/ I5 J' T6 r9 ^+ a
  250.         CE = 1;                                /* set CE high */7 u! @% G- K3 A( h+ c
  251. }
    2 d& H* X, s5 L0 Z
  252. 4 b  _7 X3 {* N. ^& B
  253. /************************************************************************/
    $ I' t, j) y$ X. `5 A
  254. /* PROCEDURE: CE_Low                                                                                                        */# J0 ?* [  [  _! u) |4 D4 p7 f5 \
  255. /*                                                                                                                                                */
    : I) R$ t! U0 H' t; ?( z
  256. /* This procedure drives the CE of the device to low.                                          */4 D) w7 i6 D5 ?( B0 j7 |; e
  257. /*                                                                                                                                                */$ |" W$ d3 @  V8 U& e& c& f' s
  258. /* Input:                                                                                                                                */
    6 f+ I+ ]5 G7 O2 ^6 d( v( [! j
  259. /*                None                                                                                                                        */- a  S1 @9 {+ e. {8 g, z
  260. /*                                                                                                                                                */: V" [$ f" S  K  x) P  c
  261. /* Output:                                                                                                                                */
    + k6 W* m% H6 ]. O9 X9 w1 m
  262. /*                CE                                                                                                                                */
    . K* s  d, t8 |, P% f8 f: Z
  263. /*                                                                                                                                                */. Q. w" T' p' h
  264. /************************************************************************/) Z5 ?0 _0 T) K! b& K
  265. void CE_Low()
    $ C) b# n  h6 i8 R" X/ t* p
  266. {        * k( b- z/ k* e4 I: Q, e
  267.         CE = 0;                                /* clear CE low */
    6 v7 h( C* b4 g; |3 v
  268. }, _5 \( _! U1 N, }

  269. 4 p2 Z1 }1 q" @; |) `0 ]; T% L
  270. /************************************************************************/
    $ Z& n4 J# v0 r6 O& Q
  271. /* PROCEDURE: Hold()                                                                                                        */8 n0 ]8 i3 J' Q; i
  272. /*                                                                                                                                                */
    8 k, q. C! w) }! O! R
  273. /* This procedure clears the Hold pin to low.                                                        */
    2 B$ ^8 x9 s+ d
  274. /*                                                                                                                                                */
    : Q) q4 c/ N! R4 H( Z6 m" d6 y& p! W
  275. /* Input:                                                                                                                                */1 |& H" ^  U5 P' V
  276. /*                None                                                                                                                        *// q% A( [- }  G9 v# Z* @, J
  277. /*                                                                                                                                                */5 ]7 m, g. s+ s! i  S. \* ]& l
  278. /* Output:                                                                                                                                */
    0 R# Y! {7 W) R9 E4 P% P0 m
  279. /*                Hold                                                                                                                        */
    * r8 ?+ ]' U4 M+ g/ Y! J+ _
  280. /************************************************************************// F" V  F) l: S* N3 {+ _2 a) m7 E
  281. void Hold_Low()
    . p, X* a$ \! v& K8 v
  282. {
    " [* N8 Y9 ~/ X
  283.         Hold = 0;                        /* clear Hold pin */, |0 y0 X3 C' Y; E6 f" J$ k
  284. }
    6 p# F! I/ k" Q( t% b
  285. ; W; s$ C9 u8 G- u, R
  286. /************************************************************************/
    - n$ h( }2 V. c' }
  287. /* PROCEDURE: Unhold()                                                                                                        */
    0 B+ M. T" G) X1 ~" {
  288. /*                                                                                                                                                *// \) E3 S0 J& |
  289. /* This procedure sets the Hold pin to high.                                                        */" Y6 m; P- Q3 l* R3 [/ l
  290. /*                                                                                                                                                */* k$ r8 ~" L- ]: @, D# i
  291. /* Input:                                                                                                                                */
    : m- ]+ |8 L7 @. a+ K& t4 H3 D
  292. /*                None                                                                                                                        */! y4 s: Z7 j; d4 F1 o" `2 N! r4 Z
  293. /*                                                                                                                                                */. s( j& s0 ~5 y- v' I& a
  294. /* Output:                                                                                                                                */* t# Q% U$ \' E# {9 K) _
  295. /*                Hold                                                                                                                        */
    5 N1 t. U$ \" o/ b
  296. /************************************************************************/
    6 m7 u( O! _/ e' ?
  297. void Unhold()* O# D! ]1 h8 f/ P0 y
  298. {5 k& ^2 e7 }! g5 Z: u! a5 Q
  299.         Hold = 1;                        /* set Hold pin */
    : B& `# a4 M* x6 e
  300. }
    ! ^" |" r) _+ o0 Q
  301. . ?6 M# J0 W/ y2 X& h7 a
  302. /************************************************************************/9 {/ I. q. p6 w. ]. d% g
  303. /* PROCEDURE: WP()                                                                                                                */
    9 V+ z- V5 w3 m) g2 S# p' ^7 Q
  304. /*                                                                                                                                                */
    ) h1 T' V3 E! |4 @1 J2 V5 o
  305. /* This procedure clears the WP pin to low.                                                                */! v8 j  Y1 U+ Y5 N6 R" T
  306. /*                                                                                                                                                */
    0 i$ l& h, c$ C5 }& {
  307. /* Input:                                                                                                                                */: {" }" V* W2 b1 d% B4 n
  308. /*                None                                                                                                                        */+ H% R5 G+ t7 H# X6 ~
  309. /*                                                                                                                                                */; o! \% Y+ C" K/ X0 g- o7 O
  310. /* Output:                                                                                                                                */
    5 W' z6 K: L" y0 L
  311. /*                WP                                                                                                                                */
    : ~! m6 X, T8 S( m
  312. /************************************************************************/& `# Y3 y6 ^1 P, D6 {
  313. void WP_Low()
    / K. j5 A& l1 ?: \! M7 P+ G7 N& t! e  [/ g
  314. {
    6 K! g& M! R  `+ q+ `
  315.         WP = 0;                                /* clear WP pin */. ?2 C# R5 ^' Y: \" T7 o
  316. }4 J; P& B3 t' @: j! C

  317. 5 w; ], W; C! c: ?' V
  318. /************************************************************************/
    * E, ?  t3 M7 t( Y" _
  319. /* PROCEDURE: UnWP()                                                                                                        */
    : |4 C- b5 A+ Y/ a+ i& f8 \
  320. /*                                                                                                                                                */3 _8 L* x. a/ O1 V  I
  321. /* This procedure sets the WP pin to high.                                                                */
      C# B; b5 Y& h+ v% h
  322. /*                                                                                                                                                */
    5 V: k7 ~" x" P$ i+ a
  323. /* Input:                                                                                                                                */
    6 y4 o, R( T' O; e- d0 K7 L
  324. /*                None                                                                                                                        */
    2 j4 @1 b/ b$ p! a9 G3 s2 q
  325. /*                                                                                                                                                */6 Q  [/ O* `  [4 X0 w- K
  326. /* Output:                                                                                                                                */
    ! H2 _0 s+ R/ T7 j( r, G3 P
  327. /*                WP                                                                                                                                */. n+ x1 [7 T& v2 r$ u/ \( |
  328. /************************************************************************/2 R7 J$ j4 B0 |* p
  329. void UnWP()
    3 [8 W, O8 {4 m8 u7 K
  330. {
    + i) a' {* J$ z" H& }% s
  331.         WP = 1;                                /* set WP pin */
    , W* T/ E0 ~1 t' B6 |
  332. }9 t. K/ V, y: X9 C- M3 b

  333. 9 e) L: _3 o1 H9 ^! u
  334. /************************************************************************/
    : u" U7 I6 h8 E- b3 C
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    $ m7 v0 B# Y* l/ n
  336. /*                                                                                                                                                */
    0 y1 n- U; f  M
  337. /* This procedure read the status register and returns the byte.                */
    ; L: o  ?% n: T- v
  338. /*                                                                                                                                                */
    * i  c: @- k4 C( n; m
  339. /* Input:                                                                                                                                */  Z  c( F( e% m( A8 i/ @2 b
  340. /*                None                                                                                                                        */  P% n6 A3 r4 a$ T& F/ O# G
  341. /*                                                                                                                                                */3 Y  U/ n" r/ a+ O6 u, O
  342. /* Returns:                                                                                                                                */
    : ?( j9 f5 L2 S4 [% u  t2 P( g
  343. /*                byte                                                                                                                        */$ E# P4 @9 I) Y0 Q9 m( R
  344. /************************************************************************/
    0 G7 w0 _9 U+ Q1 O
  345. unsigned char Read_Status_Register()5 {5 k; @3 O  N/ M8 R
  346. {' |* N1 n% ?' x* t+ F3 `# _
  347.         unsigned char byte = 0;7 X% V4 O7 d4 Z6 X6 I# ~
  348.         CE_Low();                                /* enable device */( ]* P" C4 }3 L, X4 ]' E, P# N
  349.         Send_Byte(0x05);                /* send RDSR command */+ S& }9 C+ Z. [2 u: T$ l' d$ g$ o
  350.         byte = Get_Byte();                /* receive byte */6 w7 \- y9 y! s+ y/ D2 A- V# N) q3 u
  351.         CE_High();                                /* disable device */
    2 {* V+ y$ B* O/ N  k
  352.         return byte;, t% f; N  @9 K' u/ O
  353. }1 E' J. Y) K& U4 _

  354. ; `8 g9 N: B  j
  355. /************************************************************************/
    ' k$ A' H$ L. n( d7 z' `
  356. /* PROCEDURE: EWSR                                                                                                                */
    $ r: Y# A' d8 ]7 u. F1 i; v  m
  357. /*                                                                                                                                                */
    ) t- y. [# q7 E5 w
  358. /* This procedure Enables Write Status Register.                                                  */' V( \9 i1 ^" {4 S* i
  359. /*                                                                                                                                                */6 Q' F0 i+ m' s5 [& e
  360. /* Input:                                                                                                                                */
    1 P! O& k  y( {7 q2 ^& _
  361. /*                None                                                                                                                        */0 u  y, {% K0 J+ Z( Z8 ?& a8 l$ }
  362. /*                                                                                                                                                */% m4 ?2 k* S0 R. e: e" I- K! S
  363. /* Returns:                                                                                                                                */
    7 a  `* ^1 {1 j) {; {
  364. /*                Nothing                                                                                                                        */
    . Q+ q; [8 s" M; [: U3 ^7 F! T
  365. /************************************************************************/) `$ f& N. k. H4 F6 s2 \8 A7 e9 Q
  366. void EWSR()
    0 C) \) B$ V5 W4 v: A
  367. {8 _" x8 l4 m% y+ g
  368.         CE_Low();                                /* enable device */% e* S, R5 C; z" I. n, |' a
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    3 p9 a$ }1 I4 s& ~' B  Q
  370.         CE_High();                                /* disable device */
    : @) m. P0 W. C2 @+ D9 s
  371. }
    ' I  n$ @: v5 s; x$ d1 j1 c* S

  372. 2 g+ ~% S" z9 x! }3 G
  373. /************************************************************************/
    8 S& A* @, g- k: \  o, t5 G
  374. /* PROCEDURE: WRSR                                                                                                                */
    9 |  K3 l4 ~2 u+ S( y9 ?* S
  375. /*                                                                                                                                                */
    : L; ?  q6 Y' V3 N, [
  376. /* This procedure writes a byte to the Status Register.                                        */
    5 T& a& R' W/ [1 z# {8 V5 {1 x; T
  377. /*                                                                                                                                                */3 A( {/ L+ V+ N" P4 ?) ^6 s8 X
  378. /* Input:                                                                                                                                */# d; A6 C7 z3 o. Z: g& A2 A
  379. /*                byte                                                                                                                        */' S3 ~! j5 G. y& u) v
  380. /*                                                                                                                                                */1 e+ d: G2 o! x; j& a( a
  381. /* Returns:                                                                                                                                */2 M% y6 C( G( H: J
  382. /*                Nothing                                                                                                                        */
    * Q' y  z( d( B- w* {6 w: n' L
  383. /************************************************************************/
    ( x1 @/ x3 e; i' G9 ?) I
  384. void WRSR(byte)7 z* S7 N/ G9 |7 r2 B$ a
  385. {7 v) c1 ~7 l  G& B$ K5 O
  386.         CE_Low();                                /* enable device */
    , N2 C: D' @8 R' ~# g4 [
  387.         Send_Byte(0x01);                /* select write to status register */
    9 \, {+ ^* K8 G% Q6 v4 ?; T
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    2 A  J5 {, R! H+ J( ^
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */4 g: ]- ]" L, D7 B" e
  390.         CE_High();                                /* disable the device */6 x0 R9 [" @; g( Y; }- X
  391. }
    ' M8 H+ d1 O' f0 r- Y& L0 Q: L( E

  392. ) c% U, m+ R3 Y  m- P
  393. /************************************************************************/% ~" l  o6 J% ^1 T
  394. /* PROCEDURE: WREN                                                                                                                */
    % M- _2 j+ S2 T: Q8 O
  395. /*                                                                                                                                                */! ~. s. U" B4 x, n& r/ j* @# f
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */. q  u  b" E0 A1 Z1 G
  397. /* to Enables Write Status Register.                                                                        */" r/ v+ g. N+ B
  398. /*                                                                                                                                                */
    8 _$ T6 u8 V& a1 {) ?
  399. /* Input:                                                                                                                                */2 D  F5 z' ]) Y) I& ?5 K
  400. /*                None                                                                                                                        */
    3 E: e8 }) U9 r+ M& L! F6 h/ X/ v
  401. /*                                                                                                                                                */  o. B0 j4 [7 r  h, W5 p
  402. /* Returns:                                                                                                                                */( p# l! D6 P9 }& a2 }% c
  403. /*                Nothing                                                                                                                        */
    1 y1 _/ H# a- F: n8 g. p  m
  404. /************************************************************************/
    " j- h* l2 @7 I5 y
  405. void WREN()6 o7 \, d6 q3 }1 w
  406. {
    0 b& ]' i! M& r6 ?. J. y
  407.         CE_Low();                                /* enable device */# u0 i! F3 L' E& j6 X" _
  408.         Send_Byte(0x06);                /* send WREN command */
    % v- k, y6 F/ E! q1 d
  409.         CE_High();                                /* disable device */
    / z+ j, I4 R) }: A/ Z0 `
  410. }6 Z& V+ s! c  y, T
  411. - @- T1 G2 K/ \  k
  412. /************************************************************************/
    3 r1 S) v* t; ]1 C" O3 k
  413. /* PROCEDURE: WRDI                                                                                                                */* @( x8 x+ D* }& {! j9 f% s2 e5 w
  414. /*                                                                                                                                                */
    0 E2 j! e7 T" w! Q8 I
  415. /* This procedure disables the Write Enable Latch.                                                */
    % e* a5 @3 C: C& q6 O" {  b- |  D; B
  416. /*                                                                                                                                                */
    ) L" D, N# \$ P0 V5 \6 Q
  417. /* Input:                                                                                                                                */
    2 \: O- w& S) D3 N
  418. /*                None                                                                                                                        */7 J* G/ O9 z, A- r) W6 M
  419. /*                                                                                                                                                *// b- _$ @# I0 f) Z
  420. /* Returns:                                                                                                                                */1 y& {3 j9 J5 H6 M4 U3 a) ^- g
  421. /*                Nothing                                                                                                                        */
    # D; F1 Q. i. d+ z3 F
  422. /************************************************************************/+ Q, t- ]$ d$ x( N4 M( `3 o6 x  U; ~- c
  423. void WRDI()5 E2 C3 ]# M. |( G
  424. {+ @5 @* R( [, _
  425.         CE_Low();                                /* enable device *// z8 R1 [9 q' K0 P, q4 n
  426.         Send_Byte(0x04);                /* send WRDI command */
    " f7 _/ a% {1 Q, o
  427.         CE_High();                                /* disable device */
    6 J+ `6 x. Z/ W+ A, C0 ?2 J
  428. }$ E  M9 ~6 s, x: s: C7 J" ]6 o
  429. # q0 e; q$ t  B; b  r
  430. /************************************************************************/* C) B" x* Z, n2 j6 K8 _
  431. /* PROCEDURE: EBSY                                                                                                                */1 N9 p0 m4 e+ j. W# [/ y
  432. /*                                                                                                                                                */& H. e- [. A& h1 H7 {* {
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    : c+ A# B9 s7 c3 x
  434. /* programming.                                                                                                                        */
    . v: _$ R5 W! C# E
  435. /*                                                                                                                                                */
    2 o8 @9 ?6 B; p1 |2 }' I
  436. /* Input:                                                                                                                                */
    * B. u$ S4 I0 P2 o" ?+ G
  437. /*                None                                                                                                                        */! @/ V/ x( N9 V* R6 ?
  438. /*                                                                                                                                                */" T' p1 L& }1 D4 d- O8 M
  439. /* Returns:                                                                                                                                */; r* n9 l) D2 [" c9 j* K9 K
  440. /*                Nothing                                                                                                                        */
    : w2 @, R+ E3 f. [0 n) k- x( w+ g
  441. /************************************************************************/
    8 f5 w9 r- b) Z. U7 \* `- m
  442. void EBSY()+ y$ O# y1 u$ u* V
  443. {/ |  R" G6 r; h; H9 a
  444.         CE_Low();                                /* enable device */* z' d3 j5 ~: B* s$ M
  445.         Send_Byte(0x70);                /* send EBSY command */. P9 I3 r3 x8 u5 T
  446.         CE_High();                                /* disable device */" [2 }8 d* ]9 r0 K. j
  447. }/ K( g9 w) {% s2 l; W. L
  448. / ]( b% ]8 G7 i; V- z
  449. /************************************************************************/
    . ~- J  Z! |8 {9 |9 `, X( P
  450. /* PROCEDURE: DBSY                                                                                                                */
    8 V! k6 P, W. T! m3 D. I5 \3 j
  451. /*                                                                                                                                                */
    ; ~3 @$ T! q0 i& a3 f/ T* D
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */+ m, [' q' Q, |* ]
  453. /* programming.                                                                                                                        */7 O" c$ N  w% v4 @
  454. /*                                                                                                                                                */$ ^7 a- W# ?7 h4 X* r. ~
  455. /* Input:                                                                                                                                */3 B6 Q" o6 n  f* S
  456. /*                None                                                                                                                        */
    * Y5 C3 h( X2 h! G
  457. /*                                                                                                                                                */5 C) l; n( M5 @. }* s7 o
  458. /* Returns:                                                                                                                                */
    7 O4 [8 @$ s! U% f8 }- [. K
  459. /*                Nothing                                                                                                                        */( H' X1 I$ @" K' F* k
  460. /************************************************************************/+ V& D, |) @: Z
  461. void DBSY()" j% g8 M7 I9 q) k3 R) ]
  462. {& }8 b( z6 T8 {
  463.         CE_Low();                                /* enable device */
    ( x* v0 T* M  E  C* \
  464.         Send_Byte(0x80);                /* send DBSY command */
    " R7 ~1 B. ^- h3 m* B' w* K
  465.         CE_High();                                /* disable device */
    + z4 v9 A1 [! B- d2 M
  466. }
    8 H/ A- n" Z( G" T, G# u: C4 e

  467. 4 e8 d* ?0 ?6 H/ g$ Y% V9 S
  468. /************************************************************************/
    ) h: Y, @9 L4 s1 }1 |7 ]
  469. /* PROCEDURE: Read_ID                                                                                                        */
    5 e1 g; t5 Y2 ]) Q  f
  470. /*                                                                                                                                                */& F2 C4 S, y8 l  W3 M# W, |
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */6 g% U; {6 \9 F4 A
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */+ a! @: Q6 d+ R
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    . w2 q- v& ]' ]& S3 `
  474. /* whether the device outputs manufacturer's ID first, or device ID         */1 i- s! z( m# a: X  ^" l1 L
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    $ [$ }& v$ u4 b( V
  476. /* variable byte.                                                                                                                */
    & \+ d2 V  U/ n9 q; X+ \
  477. /*                                                                                                                                                */+ U6 G- m) g9 O" Q
  478. /* Input:                                                                                                                                */
    9 K$ z: ?8 O2 G* W6 ?
  479. /*                ID_addr                                                                                                                        */
    5 _# S: {1 O9 J8 V, b
  480. /*                                                                                                                                                */* c4 n) z5 x4 e4 X4 t
  481. /* Returns:                                                                                                                                */
    - w8 w% _0 H% t+ }& `# j
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */% I% @9 _  o' s+ _: [2 O, F9 Z6 ^1 v
  483. /*                                                                                                                                                */
    . x2 U# q3 l  a0 d
  484. /************************************************************************/
    * w5 [7 u' k, J3 t
  485. unsigned char Read_ID(ID_addr)4 T5 R4 C  Y# P, L- S( @& b
  486. {9 \2 }' F5 k( b
  487.         unsigned char byte;' I$ Z: _6 h& k& I+ \8 z
  488.         CE_Low();                                /* enable device */
    / k7 g5 ^" c: F$ F' A+ g
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */- \6 C2 E2 I8 V  \
  490.     Send_Byte(0x00);                /* send address */
    1 B# F! C9 h& n0 J4 \0 F$ s' ~! b
  491.         Send_Byte(0x00);                /* send address */6 o) w6 B4 Z' {& w1 |7 v
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    " s' \! ?( s7 n/ }8 m
  493.         byte = Get_Byte();                /* receive byte */
    8 {7 Y* h3 g) [- u! Z3 z
  494.         CE_High();                                /* disable device */5 g( y; f6 |6 n6 N: {% c
  495.         return byte;
    . M" K7 p/ q) T& m  j+ x) B# g
  496. }$ L- O, J% N5 q+ W) T) s. V, B  T

  497. 5 {( B) d" s% b: g2 l
  498. /************************************************************************/
    " T5 ~6 N5 C# L
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    $ f  c2 v! m$ S9 ?: S! Y5 {8 }
  500. /*                                                                                                                                                */# i( h0 S( t- z+ r# j) |& n3 I
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ! B+ r1 S7 W/ _) b
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    5 \6 {+ R  B5 z  V7 I
  503. /* Please see the product datasheet for details.                                                  */
    " J) s$ c2 W9 |% h( }9 C' U5 _
  504. /*                                                                                                                                                */
    - R) ~+ M- `. E( H6 n# g
  505. /* Input:                                                                                                                                */
    . O* H2 y% X; v, \4 v
  506. /*                None                                                                                                                        */$ Z9 t4 s/ @+ L+ K, x
  507. /*                                                                                                                                                */8 A# n3 J" U: q
  508. /* Returns:                                                                                                                                */
    ; ?$ a& }: z9 c, P  J: r5 Q# W/ }
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    $ k2 K2 y7 i4 Q9 `. c0 n( @: z9 f% L
  510. /*                 and Device ID (8Eh)                                                                                        */& M0 j- D3 z& ~* U% R
  511. /*                                                                                                                                                */
      i7 Z6 F- Z5 m
  512. /************************************************************************/
    % E. J; W+ o! y0 J# ^- t
  513. unsigned long Jedec_ID_Read() ) h2 i( w; S5 d* d/ ~$ ^
  514. {
    ! u0 ^" W( @) ?* d; P
  515.         unsigned long temp;
    - E9 G1 o  E( g4 N2 J, x
  516.        
    ( ?& g9 W' `+ @* h" `9 e" @5 M. v! V
  517.         temp = 0;# `- @5 n. b3 L6 y7 e7 E: }5 [. \8 v2 r

  518.   N4 S) Y0 |# g/ ~9 p& C
  519.         CE_Low();                                        /* enable device */
    ' b) n$ h+ I$ Q' e. L
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */' r7 _7 |  F7 _% k" k
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte *// K1 _5 l8 Y& y8 P4 F, N
  522.         temp = (temp | Get_Byte()) << 8;        : d- W3 {9 _4 p# y' V
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */& x1 y9 o1 ~) M9 G9 X9 W$ m
  524.         CE_High();                                                        /* disable device */
    " D2 F5 G6 h" |% L

  525. 1 p! l+ K; [8 f2 X0 a9 d
  526.         return temp;
    ! I1 |: X. X( R
  527. }' \$ r; d  R0 ?  ~  G: D3 ^/ d
  528. ; t0 @( P! G6 r2 D. Y# I
  529. /************************************************************************/
    & h$ M8 ]* x7 q0 }
  530. /* PROCEDURE:        Read                                                                                                        */+ o# y1 x+ K( h
  531. /*                                                                                                                                                */               
    - L# ?; \( u3 q$ H
  532. /* This procedure reads one address of the device.  It will return the         */3 \- p! r3 O" J2 |$ \. ~& F" \* e
  533. /* byte read in variable byte.                                                                                        */
    ) e5 ]9 {  w* m( F0 l
  534. /*                                                                                                                                                */$ j, z' [! `* H7 v
  535. /*                                                                                                                                                */
    & I5 v6 n7 T6 p# U' F& y
  536. /*                                                                                                                                                */
    + K% d4 H3 h- W; L8 t7 _
  537. /* Input:                                                                                                                                */5 o8 x7 j+ T2 ]; Q/ M( e
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */3 I* w# j: }! F' I- \, N# Q
  539. /*                                                                                                                                      */& r& d7 m6 ?5 `& b% q, b
  540. /*                                                                                                                                                */2 V- N  G, r2 \9 ^) p
  541. /* Returns:                                                                                                                                */
    5 h0 V8 s5 S$ f9 Z5 E4 q
  542. /*                byte                                                                                                                        */. h; W& R" }/ N8 c5 d
  543. /*                                                                                                                                                */9 i4 Q4 z- s4 E+ s: p4 ^
  544. /************************************************************************/% u0 J$ P, W7 h
  545. unsigned char Read(unsigned long Dst)
    8 R$ _# S3 E) G( |6 R9 ?7 v6 F
  546. {! ^3 Z6 z* X( c$ u/ B! ]& f
  547.         unsigned char byte = 0;        1 e. d, K- H9 F, I, K
  548. 0 n, h5 ?' }' k* ]
  549.         CE_Low();                                /* enable device */
    4 r' F1 ]. z6 g9 g) l2 e
  550.         Send_Byte(0x03);                 /* read command */
    , B4 y- E- a. \, h% t0 p
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    % B" s6 n. P, l1 q6 b, P
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) |7 @$ p% U: e9 d1 z* H* M, @* F
  553.         Send_Byte(Dst & 0xFF);4 ~$ Y$ M8 w: w2 ]& l$ {( C
  554.         byte = Get_Byte();5 M" S6 ]' z; _. V& B9 |
  555.         CE_High();                                /* disable device */# ~$ ?' B6 i. ?
  556.         return byte;                        /* return one byte read */1 s4 B2 I' ]" j8 o" j0 r
  557. }" z1 @3 E! d; R* w
  558. 2 l9 [+ M4 i  X0 d  G
  559. /************************************************************************/' K' n1 ~: R0 c/ m# N
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    1 U% E( F7 i& H4 ~* a- q" E( X( M
  561. /*                                                                                                                                                */                2 Z2 K8 W3 n1 ~" W
  562. /* This procedure reads multiple addresses of the device and stores                */
    + p: s9 \9 p9 l* J) H) Y5 |
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ' M: J# ^' ^# p- }3 @& p' H( t) M% E
  564. /*                                                                                                                                                */
    + L- G4 g( z4 j% B* j8 w2 q
  565. /* Input:                                                                                                                                */! @& Q" a3 i8 g; h
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// P9 J5 i9 V) P( V4 h
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # w& l; ?( w' \
  568. /*                                                                                                                                                */
    2 E, ]& l+ }, y; I( t) }" N
  569. /* Returns:                                                                                                                                */) T/ e7 M3 L; |" ~' p
  570. /*                Nothing                                                                                                                        */
    : y, F: V" [& j1 K
  571. /*                                                                                                                                                */0 d* X. A! Y/ S5 `- G
  572. /************************************************************************/! D  w' O/ p; h2 B$ h
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)% P) e  `0 P! Z3 W, `& a
  574. {
    , l9 c( l$ }3 ?5 |8 T' y& j& F7 M
  575.         unsigned long i = 0;
    8 i! Z1 ^5 {$ J0 \; Q( W$ P
  576.         CE_Low();                                        /* enable device */
    ; T4 n- A+ A! o( i5 w8 B
  577.         Send_Byte(0x03);                         /* read command */
    7 L) s$ G, G5 [) e% ^3 N
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! o( z- {0 g4 Y& V1 D
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));: N; m# O- L% t; @5 ~; Z& [  X& v
  580.         Send_Byte(Dst & 0xFF);* T/ K( C% l/ |" \' a
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ! {) p* H2 ~, [) X5 K: E
  582.         {
    9 _3 x/ W" j6 n3 Z  u
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    + v. s1 Y- y  X; U' J0 o
  584.         }# C# }9 _- V3 C+ T
  585.         CE_High();                                        /* disable device */1 s6 }$ A+ Q9 X7 a# [

  586. 1 S* r. j- r  x/ [9 g, f
  587. }
    3 F  R4 H8 C7 f1 @9 w% ?% U. o

  588. 5 ?# i. h/ i; P+ A! h0 p
  589. /************************************************************************/
    0 S* F$ K0 w* f4 C! {
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    : {3 Z, f4 U  D8 m4 [8 M
  591. /*                                                                                                                                                */                4 X3 a6 l$ Q# e) B% E1 q
  592. /* This procedure reads one address of the device.  It will return the         */% W3 u: S6 r& \5 Y
  593. /* byte read in variable byte.                                                                                        */
    - X/ U  N2 I& y5 M9 r: e. i
  594. /*                                                                                                                                                */
    " e$ b% {2 f7 ^  K5 p& h, r
  595. /*                                                                                                                                                */
    ; B8 ?3 h. Y! G4 B' L+ y
  596. /*                                                                                                                                                */
      J/ N& u0 U; a( V5 l! V
  597. /* Input:                                                                                                                                *// R+ K% Q& i6 K3 g# r) A8 J
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    2 u3 Y  E! f1 D& {4 M
  599. /*                                                                                                                                      */5 [8 D7 }) f; M. W+ ^/ y$ s8 i
  600. /*                                                                                                                                                */
    & ~$ a8 [7 M3 f$ F2 W
  601. /* Returns:                                                                                                                                */# H) l' w3 n2 ~8 M: H1 x- g
  602. /*                byte                                                                                                                        */
    - f: t  T( e! k/ W& D! Q
  603. /*                                                                                                                                                */# J2 V1 S% S2 b2 m$ c  p
  604. /************************************************************************/+ g+ Z# p9 Y2 y& g( l' [
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    $ F- d  V0 {: O; d
  606. {1 A( |2 ~  c" K+ w. u7 e) w
  607.         unsigned char byte = 0;       
    ! P7 G8 X3 I7 w: Z! O7 ?4 ?
  608. 5 ]: B/ e. E+ b/ k; Y: r8 b
  609.         CE_Low();                                /* enable device *// Z3 M% h! h( Z1 w7 y. V8 S3 Q
  610.         Send_Byte(0x0B);                 /* read command */( c& d% [" z+ _; G* s/ I, |0 q
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    * H  _" d. `' w' }! a- e
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ P/ M, C9 z& [% O2 u* O
  613.         Send_Byte(Dst & 0xFF);
    + U$ s& P) H7 w6 s
  614.         Send_Byte(0xFF);                /*dummy byte*/
    + O  U- a& N7 F
  615.         byte = Get_Byte();8 q2 D( P1 @0 ?& E6 I6 W
  616.         CE_High();                                /* disable device */$ f4 z  s, z# w& A
  617.         return byte;                        /* return one byte read */
    2 k3 e. |* ]4 `# |  F* p( a9 j
  618. }
    & U$ }' p' j, M8 n7 \1 ~$ n
  619. ( W! t; f5 |# h1 p4 P
  620. /************************************************************************/" P; w+ E  V9 D, I! Z0 p( c
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    7 _0 L* |! b  j2 `' X. F* I
  622. /*                                                                                                                                                */                , l6 L9 n( m8 l) ~. ^, b& E
  623. /* This procedure reads multiple addresses of the device and stores                */1 W' ]4 n) z% d) S
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ) J: c) ]- e! t
  625. /*                                                                                                                                                */7 R6 p/ L% V0 x, y; U
  626. /* Input:                                                                                                                                */3 S& D- U# u6 u2 ?' O' j
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; S/ X1 _9 U2 K9 u) e0 X# F9 j* x+ {
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */. Y& ?5 O4 \0 X5 t4 ]# D
  629. /*                                                                                                                                                */
    ' N, k" U+ W" Y
  630. /* Returns:                                                                                                                                */
    ' g3 i4 h& T- [1 ^5 n* J
  631. /*                Nothing                                                                                                                        *// \8 \$ w3 k+ X  L
  632. /*                                                                                                                                                */, H& l2 o1 G# a; `' V3 m# P! e, X/ C
  633. /************************************************************************/' z3 u% z, a: f( i4 u; p
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    - Y" r4 r4 S5 n
  635. {/ i8 y; C  p6 b$ i
  636.         unsigned long i = 0;: ]) j7 ]# A4 H. ]" y. x
  637.         CE_Low();                                        /* enable device */, B4 \& E, A& G& \5 y& Z9 w
  638.         Send_Byte(0x0B);                         /* read command */  }8 g4 t( t- D0 ?
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 J9 y1 G5 L' G2 k
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));6 |* E8 W6 V0 {9 _- @
  641.         Send_Byte(Dst & 0xFF);
    , c. Z; r4 e# h( ?, v
  642.         Send_Byte(0xFF);                        /*dummy byte*/9 b; ^6 K7 n' B  b' G( S
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */+ ?0 N+ v& U# N7 B
  644.         {2 C2 R8 \8 Y, ?+ ~
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    # P8 P$ H5 e& F. s* p  Q
  646.         }7 Y! K  f) _9 }# g
  647.         CE_High();                                /* disable device */
    , O* I) z8 i7 q) j
  648. }( M) @' P$ i$ a" [- s+ w

  649. , T6 n5 W9 b1 d: z4 [$ ^- ~
  650. /************************************************************************/9 \( _2 \* @  n( S0 e" U& Y
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    1 t9 I( R! K: i7 v
  652. /*                                                                                                                                                */1 n2 s& k( [& i
  653. /* This procedure programs one address of the device.                                        */; w* ~$ O: q( P5 z* i
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 I4 D+ z" F3 r" B* B& a
  655. /* block protected.                                                                                                                */( y3 ~0 u* ?6 i
  656. /*                                                                                                                                                */( A7 l. ]0 N2 U2 R0 z# X
  657. /*                                                                                                                                                */
    8 r2 h9 l3 z7 a3 L
  658. /*                                                                                                                                                */; [, @4 A% g( l
  659. /* Input:                                                                                                                                */
      s1 o. ?: l4 T3 [
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ( _) E: Y4 x% V2 |  Z
  661. /*                byte:                byte to be programmed                                                                */: N! Q; y9 E4 n7 k1 b' `+ g: k
  662. /*                                                                                                                                      */
    ; r6 |" T6 O7 h, v' a3 O1 W
  663. /*                                                                                                                                                */
    $ E- _! ~7 y" Q3 e' v  ^6 y
  664. /* Returns:                                                                                                                                */0 L6 Q6 N! S$ j6 \& w7 Q
  665. /*                Nothing                                                                                                                        */
    0 F& J% C6 u. V
  666. /*                                                                                                                                                */
    3 o& F! X# `& a* A, c5 S$ b
  667. /************************************************************************/
    6 g1 I3 l! S/ G
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    / p+ Q8 A$ ~( g; P4 X7 y
  669. {
    2 \! c, X2 N* L) d' ]4 ^
  670.         CE_Low();                                        /* enable device */
    7 P4 P3 ]6 ?( K8 q! C
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    , s% T* a. ]1 m$ h* n
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    - V1 _% b3 E* `% ?% Q: p
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " D; {1 }7 N5 q! |- K+ v( [
  674.         Send_Byte(Dst & 0xFF);; R0 C/ Q+ T! C6 V6 g0 G
  675.         Send_Byte(byte);                        /* send byte to be programmed */4 q# C( ]: J2 _: N4 t) p1 V
  676.         CE_High();                                        /* disable device */  H+ K5 h% k% {2 P& Q; v$ ^; T0 k: x1 z
  677. }
    ! R" k6 U! S9 c, P# v

  678. 3 }' k9 _$ e5 u5 ?: l' ]* X. Q
  679. /************************************************************************/- x; N- ~$ r- Y+ j  R+ |
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    7 r! e7 T5 L- L  `# q% o2 r
  681. /*                                                                                                                                                */& U5 B1 R5 O* Y+ c- j$ [% V  u
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/3 p1 b6 q( [% t& m6 ^0 N9 x1 g* {
  683. /* the device:  1st data byte will be programmed into the initial                 */$ c* ]* ]/ K2 q' r+ v" z, C9 B4 [
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */, e) r  x& e+ a% t
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
      d  @& _4 f- J
  686. /* is used to to start the AAI process.  It should be followed by                 */$ D- ~! X; _7 {% a- c$ Q
  687. /* Auto_Add_IncB.                                                                                                                */# S1 M5 `" K- [9 J
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 v, V0 ]7 ]$ B. t( ^/ v) k% G
  689. /*                                block protected.                                                                                */
    . c+ t5 |) r2 P5 V$ t0 }
  690. /*                                                                                                                                                */0 ~: k) b/ y# a% {
  691. /*                                                                                                                                                */3 t- o- J# z$ O$ }
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    , C2 Y* i: t, x2 y/ Y
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    8 ~& t0 Q! J$ ^& Q! j1 s! g# Z
  694. /*         unless AAI is programming the last address or last address of                */
    9 I; v# P- r* O% ?8 ]
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    : f* E! d& W' Z) J8 P2 O
  696. /*                                                                                                                                                */! z6 n0 Z/ V2 O0 [' u0 {
  697. /* Input:                                                                                                                                */
    ) E$ s- T7 q( l' W) z2 c
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 A% a  d9 t, E1 H5 b8 ^, ?
  699. /*                byte1:                1st byte to be programmed                                                        */
    ( b+ x; b: F8 a! q+ h" {
  700. /*      byte1:                2nd byte to be programmed                                                        */
    9 j  {: y$ U$ q5 ]4 V0 X6 [, S
  701. /*                                                                                                                                                */
    3 {( [8 y  e6 C9 w5 c: X; T; R
  702. /* Returns:                                                                                                                                */0 L2 X  u" o' v$ T
  703. /*                Nothing                                                                                                                        */
    1 L2 L" g$ ?% x5 c$ ]  ~6 G
  704. /*                                                                                                                                                */: E& C6 z, N/ q2 Y0 }4 j2 p1 _- A
  705. /************************************************************************/* o* ]& x6 {3 g. ]6 F
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)* ?+ L& S& {, ~  E
  707. {
    ' V7 ^$ b( t' g9 t- |
  708.         CE_Low();                                        /* enable device */
    / O, V& p1 h1 [( T7 y% Q8 ~( u
  709.         Send_Byte(0xAD);                        /* send AAI command */
    + T0 j6 N9 I) @. v7 ~+ X
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 n  U: d7 d. @" f$ _- M
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));7 {% J5 W( Z, `" e
  712.         Send_Byte(Dst & 0xFF);3 ]* }2 P, [& O9 E( ~! ~
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        $ D( V* d$ Z0 u1 Y$ }
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */& v" _9 L6 J" \9 Q+ R
  715.         CE_High();                                        /* disable device */
      U, `8 k0 V9 T, A* N; h& V) }0 W
  716. }2 a& N. ~: ]7 ?1 ^

  717. % h$ D* a9 q* V- L4 M6 u# u
  718. /************************************************************************/
    , q# R; s1 R& K$ T
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */2 p2 Q1 _( l! A, v& Q& u
  720. /*                                                                                                                                                */- F' z5 f, n0 s' P: d  G
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    0 [6 z/ I' ]6 c% t0 h1 x3 D
  722. /* the device:  1st data byte will be programmed into the initial                 */6 ^& r  [' {" k3 Z" ]* R6 s
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */) Q9 |5 c6 w) A
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */7 w5 Q) Y  m2 B( h9 q
  725. /* is used after Auto_Address_IncA.                                                                                */
    - ]) u2 c1 n7 P) {
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    " W+ K: L$ M: X7 L
  727. /*                                block protected.                                                                                */
    + b- L* I2 I/ Y: I+ h
  728. /*                                                                                                                                                */5 v# K  C5 k! X) `; Q
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */; O/ m) }' U9 s2 d3 L
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    2 ^6 D2 W; e' m3 ?/ o
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */& C$ \4 a! `2 `# i- x. h
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    5 I/ h% X, [0 ~: c! n% M
  733. /*         last address of unprotected block, which automatically exits                 */
    ! j9 Q) s& X* [4 B
  734. /*         AAI mode.                                                                                                                        */2 r- W! z) B5 z/ s" b+ U" z9 f
  735. /*                                                                                                                                                */
    5 k' J1 w) H( i9 W
  736. /* Input:                                                                                                                                */
    * m) o, c' q. d6 Q& |5 N5 ^7 ^! r
  737. /*                                                                                                                                                */
    2 E4 N% r6 |; n2 t% z
  738. /*                byte1:                1st byte to be programmed                                                        */! O0 f7 Y+ Z! h. _) t9 c
  739. /*                byte2:                2nd byte to be programmed                                                        */
    , _# {. v: E, M+ n5 v
  740. /*                                                                                                                                      */
    & B0 t' T" G0 G8 Q6 K. Z4 @& y
  741. /*                                                                                                                                                */
    0 |% D  C# c, a9 ^& H& D8 f/ B4 b
  742. /* Returns:                                                                                                                                */" X8 Z% q: p# h9 S- R
  743. /*                Nothing                                                                                                                        */
    $ a# E2 Z, O) P$ g# b9 {# |
  744. /*                                                                                                                                                */
    0 h* s& ^  _! y& z, E. t9 Y
  745. /************************************************************************/% K2 k7 o: K8 s' o! ~: w
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    ( {7 K3 Y4 W- F$ _8 q9 B- b+ f7 H. e
  747. {+ t8 o  B, F, p) i+ N/ g6 p3 y, Z
  748.         CE_Low();                                        /* enable device */- v6 J% K; W! @5 F' l! `
  749.         Send_Byte(0xAD);                        /* send AAI command */" C9 D0 E, p7 z* r& N- O) T1 `+ x
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */3 k% r8 a/ m* T7 c: Q6 g
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 X9 ]/ f3 s4 Y/ H% P  f- S% S! I
  752.         CE_High();                                        /* disable device */( A& x8 U4 f8 s) B8 w- Q/ L
  753. }
    ; R/ V  n8 M- y' I, v
  754. * z3 L$ O; F/ K) T: X* I" Y3 p
  755. /************************************************************************/9 f; Y0 g- ]# E$ O* e
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    7 w6 ]; Q7 n: ]# V+ a6 ~! Y
  757. /*                                                                                                                                                */
    5 _. Z6 F4 ?( I1 G
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    & ~  K, Q% b& ~
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */: @5 w, T$ b; [6 \+ y+ y9 k
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    6 U- v+ k" q; V% L2 U& M& {) M: _
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */4 [9 N6 W" [$ E9 F. I) ^' L, B
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */: o7 d, s& M) A7 G7 T5 p+ \9 }
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    # W6 a) Y7 c; X4 Y8 V
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    9 D. J* q$ A2 H- q
  765. /* Assumption:  Address being programmed is already erased and is NOT        */0 x$ R, q. @6 J& y
  766. /*                                block protected.                                                                                */
    ; O6 B7 ~  U) b2 `! Z! N
  767. /*                                                                                                                                                */
    6 ], K: A8 T! t1 ]/ {) c( H# `
  768. /*                                                                                                                                                */8 {! W3 r2 Q# f. g) [$ y) ~
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */' z* l  |' b" y4 N% e8 r, Q; O4 \4 h
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ! W2 c! }! y( a3 D/ Q6 Z  ~! i
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    % r1 x9 ]8 Q6 N0 s& L, B2 N5 \
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    8 L2 E# E- t' Y  I& \0 S
  773. /*         last address of unprotected block, which automatically exits                 */5 b  F. L- Y3 p4 b$ x' d2 e. g9 {
  774. /*         AAI mode.                                                                                                                        */7 z& ?9 g6 l) t! L# b  v% C
  775. /*                                                                                                                                                *// p3 O0 Q/ ?4 Q5 `8 |
  776. /* Input:                                                                                                                                */5 p6 Z  t/ v5 `$ {+ l- K0 h; {. N
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - R* h) H# \2 U; `8 f8 V( \' A
  778. /*                byte1:                1st byte to be programmed                                                        *// A( h3 t: J9 P1 _
  779. /*      byte1:                2nd byte to be programmed                                                        */9 E  G: H0 ?2 {1 Y
  780. /*                                                                                                                                                */9 |, X7 L& x: o0 J( w
  781. /* Returns:                                                                                                                                */
    ) y# N) U+ W# m$ t- r
  782. /*                Nothing                                                                                                                        */
    " r7 {1 D; Y$ K1 A
  783. /*                                                                                                                                                */7 u/ x, P' H7 ~6 x7 @! O
  784. /************************************************************************/, r& ^4 d0 ~. ~* A" j% E
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)5 A- Q; T) }9 R( |5 p
  786. {
    $ s! b( ~  Z" X
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        ) h( c8 A1 v% d1 |

  788. : a0 A4 [% j  S0 [& |
  789.         CE_Low();                                        /* enable device */
    0 q/ w' Y  |  s5 F% e6 C. e2 W
  790.         Send_Byte(0xAD);                        /* send AAI command */
    / c9 @/ P+ ?" `2 f4 q
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */8 @/ W  m) }/ K/ C9 Q4 ?- m
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ( F$ \; T+ N1 h7 T: H: M
  793.         Send_Byte(Dst & 0xFF);
    1 K" t: a- h/ @" n# l1 S# k5 M( \; W
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    3 }  \) J4 {$ G& A, l: N5 a' K, E8 W
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    8 E7 K8 o2 J- z
  796.         CE_High();                                        /* disable device */9 Z7 }1 S* Z. e* {3 `
  797.         / V7 B2 Y3 J  u7 m8 V) c3 y5 N7 w
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    * ]7 B: f. s5 Y) _# W9 N; I' R

  799. % }0 A+ _4 j  e) X" Z4 H
  800. }0 @- E  v8 c; K' b- U. e# R

  801. $ P$ l5 V/ z: \
  802. /************************************************************************/. I- L, b. q. K" B" p7 u# \0 m3 ?  ~. }
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */% l6 {8 o! u: b& q
  804. /*                                                                                                                                                */5 H" i) V2 z7 b: Y$ l
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */  R, g3 ~$ s" w  s7 e) \/ Z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */+ G& A$ M  m- W
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    & W; l1 r5 J, G# [4 y/ E
  808. /* the device.  The 1st data byte will be programmed into the initial   */' \% X$ {: G. A6 F9 F, [' X& ~
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    % Q" @% p3 T. w$ i- Z
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */6 r& s, u( K; F- A$ B
  811. /* used after Auto_Address_IncA.                                                                                */9 q: ?" e: g. q
  812. /* Assumption:  Address being programmed is already erased and is NOT        */, m. }- q& h! W. R, l. R3 S
  813. /*                                block protected.                                                                                */3 p+ i7 v$ A& U% K; P% [, r
  814. /*                                                                                                                                                */
    3 _) i$ s; o. y+ Q0 e6 j3 G; c3 \
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */+ T" z: ?: F7 n/ `
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */" E; n; O- I2 K. {* C3 c6 x5 g5 f
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    3 m$ @. ?0 I; M( m
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    * M# }8 Q) M  h
  819. /*         last address of unprotected block, which automatically exits                 */
    ) ]' [1 P1 Z7 ?$ I
  820. /*         AAI mode.                                                                                                                        */0 O2 p8 g# l; L* d1 |- P* b  `* `' R
  821. /*                                                                                                                                                */
    / c$ N9 X$ ~' ~) _  y- `3 C" |  U
  822. /* Input:                                                                                                                                */6 a# B" E; G! B$ ]. s+ @! l
  823. /*                                                                                                                                                */1 \/ O$ G, {: K4 P
  824. /*                byte1:                1st byte to be programmed                                                        */! x1 ]: i; d  |, J
  825. /*                byte2:                2nd byte to be programmed                                                        */2 c' a2 l" W( q8 _9 a1 F
  826. /*                                                                                                                                      */( l: O8 H( I+ x8 J
  827. /*                                                                                                                                                */5 x$ t5 b: |+ G, p
  828. /* Returns:                                                                                                                                */: `2 u9 ]4 @8 I) `# Q
  829. /*                Nothing                                                                                                                        */
    3 N6 P! R5 b1 l! T
  830. /*                                                                                                                                                */8 Y5 W  c1 Y% \1 s6 m2 A
  831. /************************************************************************/; x9 d! w: |5 o( C+ g9 L* A, g
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ) ?* d3 r0 }7 r7 `; A
  833. {; N0 y, j" o! N8 p. y! M4 h: K
  834.         CE_Low();                                /* enable device */
    8 F8 p$ H3 F  V
  835.         Send_Byte(0xAD);                /* send AAI command */
    - Z5 y; `# o' P+ K8 J5 u
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */, |6 b  D1 T* t4 V1 {- n4 S8 {
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */( W1 h' R/ E1 ]: f
  838.         CE_High();                                /* disable device */6 P7 k5 c6 y3 X/ J2 I
  839. , g8 F. h; [3 J
  840.         Poll_SO();                                /* polls RY/BY# using SO line */( j# ^# d, r# S5 f5 q
  841. ' Y. G! R9 x4 f6 l- A) p
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    " u6 t0 t7 a/ ~/ r4 A7 W
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    3 V$ ?% V6 N6 x) |5 ~
  844. }; b2 W4 a: d7 N5 n5 O
  845. 9 [$ I$ T6 \0 V
  846. /************************************************************************/
    " x1 W- z/ U) w1 s
  847. /* PROCEDURE: Chip_Erase                                                                                                */1 I. N% H/ t  X% T: L! s! \
  848. /*                                                                                                                                                */- q( c4 E  c8 S, v7 R; i$ l" r6 t' T
  849. /* This procedure erases the entire Chip.                                                                */
    7 Y& v6 x% N' B% H* j# I- J7 P
  850. /*                                                                                                                                                */6 @/ o/ T4 {2 r6 Z) |$ z$ S: \6 J
  851. /* Input:                                                                                                                                */9 Q9 t% C0 Z9 L8 C! E' Y% ?# F
  852. /*                None                                                                                                                        */
    ( R9 @4 B( F9 m" P, q
  853. /*                                                                                                                                                */% a3 ], k3 y3 s
  854. /* Returns:                                                                                                                                */3 p) y4 E3 p: G. r" u
  855. /*                Nothing                                                                                                                        */
    9 o6 o) {# K( n2 X9 m. e/ [  v6 \, q
  856. /************************************************************************/
    : `2 F" V6 e, d% A7 r; ~$ w
  857. void Chip_Erase()7 C: N& Q2 Y! Z( A, P$ l. J3 A6 k
  858. {                                               
    6 B: l0 _+ @1 n" U
  859.         CE_Low();                                /* enable device */: b3 r" \" G2 A% P" @2 v  p; u
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    " d& a0 @  r  `( @1 C
  861.         CE_High();                                /* disable device */3 i3 O1 v0 m" f! k0 e% I
  862. }
    0 K, z4 f( O3 f" x2 g' k

  863. 0 |# x7 R' K9 l2 h# v7 d1 M
  864. /************************************************************************// ^/ ?, v4 p! y& o" C
  865. /* PROCEDURE: Sector_Erase                                                                                                */% G& ~5 h6 Q# b5 B6 ^; J9 P8 o
  866. /*                                                                                                                                                */# M3 U; I4 f6 {8 J/ x
  867. /* This procedure Sector Erases the Chip.                                                                */7 U) x/ I! C5 d! }; a
  868. /*                                                                                                                                                */; t/ Z' x1 y9 W
  869. /* Input:                                                                                                                                */
    2 \' a5 Y$ Q& F$ S
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */7 N) S6 g" Q6 |. g+ j. h, J. H! U
  871. /*                                                                                                                                                */: O/ L3 x, m9 o, B  s, S% h
  872. /* Returns:                                                                                                                                */
    0 P2 {. |0 q  s! S% R) Y0 f
  873. /*                Nothing                                                                                                                        */4 l5 S/ ~  m# H: A/ Z
  874. /************************************************************************/$ {0 O5 d2 n+ @! r5 o) U
  875. void Sector_Erase(unsigned long Dst)( K) i2 f" t; I: P
  876. {
    : j# p) f# h( f

  877. 4 F$ u* Y  I; s/ l5 a9 G! b
  878. $ h* q' u2 X0 Y5 I
  879.         CE_Low();                                        /* enable device */" V  N& D$ b" m+ h- S
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    7 G. ~2 k- n# l( Z3 b" v
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' r5 m; N3 V9 [5 {8 X6 E
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ! l6 r! p( Z/ u( J9 }
  883.         Send_Byte(Dst & 0xFF);7 U% e: E% l- \, W' C" h
  884.         CE_High();                                        /* disable device */
    + @- j5 J$ W6 [. x7 j
  885. }       
    + x7 j" s' N, S/ z. Y8 M
  886. 5 r; O- S0 C1 W; w6 J& J/ T
  887. /************************************************************************/5 h- }* e' ?- z; _; i. h; y* m5 |
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    8 e- T: B0 a5 J: r% x) _( Y, T
  889. /*                                                                                                                                                */: u1 K# G# ]1 _
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    2 O/ b" C$ G) _( u8 B
  891. /*                                                                                                                                                */
    ( l0 O! Z0 @; |* \
  892. /* Input:                                                                                                                                */
    2 q7 u# l- t, c4 V. o
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ' X7 l) q9 @# L: w% |  o  I2 _
  894. /*                                                                                                                                                */
    2 \2 C- W( k: g' i7 Q1 j
  895. /* Returns:                                                                                                                                */
    5 m$ ^! F, I, d+ i6 O' h
  896. /*                Nothing                                                                                                                        */) C7 r2 Q( o2 z& V* C
  897. /************************************************************************/4 M! Z! F; Q3 {. U0 v$ q) ?
  898. void Block_Erase_32K(unsigned long Dst)% V  U* Y2 J4 d0 I2 \, e: ~4 g
  899. {. o/ Y( R, r- `4 p, Q0 A+ a6 k
  900.         CE_Low();                                        /* enable device */
    6 d, v9 j1 ?- J/ \; a' {0 y& M
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    6 y! W' X/ H1 U9 P: J
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & I* A$ N" F9 c+ {+ u/ q" U( ~
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));# O# w! L% b0 t) ]. ]
  904.         Send_Byte(Dst & 0xFF);
    2 R% U0 Z& v+ n+ i2 ?: m
  905.         CE_High();                                        /* disable device */; T% u+ X/ l' l2 u8 N- D+ ]: y
  906. }
    / _! q9 i  A" w9 ]% {# ]4 k

  907. + Y: R) M; M8 w7 e% w
  908. /************************************************************************/
    0 q/ p- R$ T0 x) r8 N: `+ x
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    " X; ~$ N2 e( q4 s$ t, V
  910. /*                                                                                                                                                */5 F) v& G' [8 y) d
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    1 }6 \1 ^3 M- j( A# k  _6 f
  912. /*                                                                                                                                                */
    8 t8 I* q. F2 s9 G
  913. /* Input:                                                                                                                                */. p& e( q' _2 n6 p$ K
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) b! N4 l) Z# ]3 C
  915. /*                                                                                                                                                */8 o5 L/ R# |) L1 _% @! b9 P& H  Z2 K
  916. /* Returns:                                                                                                                                */
    # h1 r0 z7 ?' }, ~  l5 Q
  917. /*                Nothing                                                                                                                        */: ~8 @* ?, _! ~0 r
  918. /************************************************************************/
    1 `) \0 S  T6 J  `+ v. o
  919. void Block_Erase_64K(unsigned long Dst)4 V4 @  o* R3 t+ T& U% V5 l
  920. {
    + ~  Y% Q& w1 F$ ]* {4 }
  921.         CE_Low();                                        /* enable device */
    5 |" h% u! w4 g9 @' u
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    8 G! C$ W+ X& X
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 b! l3 g' A5 h" H6 o0 F8 {
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));* s/ R9 h# W7 v2 a7 b6 {
  925.         Send_Byte(Dst & 0xFF);8 e  j( V% Z. ~$ y5 I$ p: i2 p
  926.         CE_High();                                        /* disable device */
    3 y. A4 Q, o8 ^1 q3 Y! U! L
  927. }+ E6 F9 g; R, a" d7 z

  928. * U' W, G* p$ H, K. J1 ~" j0 Q
  929. /************************************************************************// f3 w; J7 z% J! s8 I
  930. /* PROCEDURE: Wait_Busy                                                                                                        */$ }/ J9 l1 E! N
  931. /*                                                                                                                                                */  ^, b4 d/ E; t7 e' g
  932. /* This procedure waits until device is no longer busy (can be used by        */
    * f0 x, g* p5 f9 l) a. q$ h
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    : l- J; a* c3 O& P; M; z3 @4 w, Q
  934. /*                                                                                                                                                */
    ! y! v: h& }3 c/ S
  935. /* Input:                                                                                                                                */0 o& U' d* {2 ]1 g1 O/ k1 w' v; A
  936. /*                None                                                                                                                        */; @& A: V% h* b5 j+ x) E5 h) ?
  937. /*                                                                                                                                                */
    $ Q* ]: A& i& u6 F( a
  938. /* Returns:                                                                                                                                */5 r) G0 Y5 V# T5 I
  939. /*                Nothing                                                                                                                        */
    8 k3 ^: i" d! O6 D; y& H" \% g1 L4 c
  940. /************************************************************************/
      @' `6 @- T; c! s
  941. void Wait_Busy()6 m, i6 y4 j5 t6 L/ Z- q& j
  942. {
    ; n0 q) g$ U3 m9 N
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    9 S$ q' M& r( p! B* w: l
  944.                 Read_Status_Register();
    1 |1 g6 I: h; i! h- f
  945. }
    : p" v4 g/ V' _+ r

  946. . d6 R  F0 p& q) t9 ^
  947. /************************************************************************/& B# x, Y: v6 g( E, c
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */# Q4 |) b- {3 n1 e9 K7 e
  949. /*                                                                                                                                                */
    $ ^4 G- R3 |& Z4 i9 O. B
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    . K$ S/ K" X& H5 Q8 j, a5 v/ f7 K
  951. /*                                                                                                                                                */) v" {+ B0 |( Z- `# j4 `
  952. /* Input:                                                                                                                                */
    - H, @' P, R2 I5 @6 O
  953. /*                None                                                                                                                        */
    1 [# l5 [9 c, ~8 F
  954. /*                                                                                                                                                */
    6 X0 S) y1 L2 H+ H! O5 C* F
  955. /* Returns:                                                                                                                                */* Q$ Q3 H& {2 B) z
  956. /*                Nothing                                                                                                                        *// K3 ]+ C, l2 K# U) N# }7 o
  957. /************************************************************************/4 l! r! S1 x% x3 Q
  958. void Wait_Busy_AAI()4 P- `. K$ p' U# i' v$ ~3 a7 i
  959. {( F; F5 _$ L1 b3 l! |( ]# f
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */6 X8 [: L$ _7 p& J+ q
  961.                 Read_Status_Register();
    / ^$ d' I! p- i
  962. }
    ! R) b, p  G2 R; A1 E
  963. 7 w2 `; `2 ~8 y' I/ N
  964. /************************************************************************/
    . E# G& V; A. a4 k
  965. /* PROCEDURE: WREN_Check                                                                                                */
    7 ~  M% y2 C9 Y7 k  C* G" R
  966. /*                                                                                                                                                */
    * {: Q5 Q* h6 A# \4 c% F: B# J
  967. /* This procedure checks to see if WEL bit set before program/erase.        *// g( i9 S2 p. C7 g2 m
  968. /*                                                                                                                                                */2 i) U. k- _, {3 O
  969. /* Input:                                                                                                                                */& z, Z( n" d+ w8 X4 P. {
  970. /*                None                                                                                                                        */
    9 i9 H" O7 }- h
  971. /*                                                                                                                                                */# v/ o! B; A1 N
  972. /* Returns:                                                                                                                                */7 x3 i- ?# p* u' j" M. l  A
  973. /*                Nothing                                                                                                                        */
    + e* [7 n% a. j' L6 y
  974. /************************************************************************/
    " o; H6 T# P: K
  975. void WREN_Check()0 G4 E5 J: O' ~4 _' R1 E2 s& Y
  976. {  j9 m) P' u& B( a
  977.         unsigned char byte;
    4 Z. H7 A! R. U% H  ]% y+ A
  978.         byte = Read_Status_Register();        /* read the status register */
    " I9 U/ x0 l+ n- s2 ^0 B
  979.         if (byte != 0x02)                /* verify that WEL bit is set *// S& l$ D) [( Q6 E1 d% \
  980.         {
    # G0 Q' U$ B' p, W3 C! @8 W% ]
  981.                 while(1)
    ! I0 |) `: j  I
  982.                         /* add source code or statements for this file */8 H# Q; y) N4 I0 K% r+ {4 r1 ~
  983.                         /* to compile                                  */
    4 c* N! n* y! ?: y: E
  984.                         /* i.e. option: insert a display to view error on LED? */
    . r7 a2 b# R/ t3 N4 X3 ?
  985.                  
    ; j% u  D! q1 e3 T  G' d9 G
  986.         }
    2 h# n* Y) D1 l! {5 a2 U2 z* e2 p
  987. }
      ?! E+ V6 C5 u7 c
  988. 9 e) V; C, o, ]  l  s8 y( q% |# J
  989. /************************************************************************/
      Y+ {4 s' [& o; H
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ' q" {) Y. n7 g
  991. /*                                                                                                                                                */
    ) R# s: r! y( _) z, j3 d6 V
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */9 X6 i1 U8 G6 C( _8 |* y
  993. /*                                                                                                                                                */+ z* b8 e9 J& D( C( B8 R
  994. /* Input:                                                                                                                                *// S) a+ Z$ ?- t6 V7 `
  995. /*                None                                                                                                                        */
    3 g3 G* Z1 V$ ^. s4 U) j5 X+ r
  996. /*                                                                                                                                                */
    1 }- r0 h0 ?  G
  997. /* Returns:                                                                                                                                */- |' T& x; v5 F6 I9 e7 o3 j
  998. /*                Nothing                                                                                                                        */
    0 T* N- \; Z3 F. Y; u, o. ]3 W
  999. /************************************************************************/
    8 r- P9 f* g$ U
  1000. void WREN_AAI_Check()7 ?6 `8 I: f: m  k2 j; ?1 W- V
  1001. {2 _8 y0 m7 j) Y+ Z
  1002.         unsigned char byte;
    . }( a7 L3 R' z/ ]2 j
  1003.         byte = Read_Status_Register();        /* read the status register */+ v+ C% w3 C4 y: a# S
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */5 Z" E; b3 ~. F0 D+ |
  1005.         {5 ?3 l" \5 H6 o8 b3 I- m" k
  1006.                 while(1)                1 b! `( r% u9 N9 A3 }
  1007.                         /* add source code or statements for this file */
    7 \9 v6 `5 v! H: M7 h+ Y3 o
  1008.                         /* to compile                                  */. k1 |! e! s! f, F  h8 h  N
  1009.                         /* i.e. option: insert a display to view error on LED? */
    9 w* m; b% j1 n- ^. |2 x7 L
  1010. / A! f0 G! X: C/ P
  1011.         }' B1 k( A) y1 `3 M; V8 v( I/ z+ `
  1012. }
    % A7 O& I1 b3 A# d( L3 @5 A+ N1 X

  1013. $ K8 o6 s8 C) @3 z
  1014. /************************************************************************/  P7 I. ^+ i6 r9 w# c
  1015. /* PROCEDURE: Verify                                                                                                        */
    4 E8 o4 U! H% \) J
  1016. /*                                                                                                                                                */1 y7 J! F& U# k( `- w
  1017. /* This procedure checks to see if the correct byte has be read.                */' G2 K$ u/ ?; m1 L: p$ A2 m) m3 X2 i
  1018. /*                                                                                                                                                */4 i/ N4 Q; O* `
  1019. /* Input:                                                                                                                                */0 ^& q" {: R* w! d' [# o2 L
  1020. /*                byte:                byte read                                                                                        */: l5 M% h) r3 A6 ~3 c" t
  1021. /*                cor_byte:        correct_byte that should be read                                        */
      N! w6 @0 S3 v7 }2 ?
  1022. /*                                                                                                                                                */
    7 S" U4 F+ {. f8 N/ }7 s
  1023. /* Returns:                                                                                                                                */% L. |8 g7 ~7 B
  1024. /*                Nothing                                                                                                                        */
    0 m! t2 M; t1 \0 w
  1025. /************************************************************************/
    5 V; F6 [4 x' |: ?* P
  1026. void Verify(unsigned char byte, unsigned char cor_byte)7 Y9 {8 t) i  b7 S+ V- v' p
  1027. {
    + M3 f. o+ l+ u) T# ^
  1028.         if (byte != cor_byte)
    # o- Y8 X9 b7 e8 |* [; Z- P
  1029.         {
    3 R$ k$ |- X+ T5 G2 s
  1030.                 while(1)/ s1 [8 X) b2 {% H  Q
  1031.                         /* add source code or statement for this file */5 B9 y1 |3 ~" l8 \* w
  1032.                         /* to compile                                  */) B0 c1 ]* n2 t- h
  1033.                         /* i.e. option: insert a display to view error on LED? */
    ; L$ v7 r6 x1 [' Y2 |0 G/ I
  1034.                
    ) ^8 H2 K  A4 f, ^7 b
  1035.         }
    6 f) a2 m3 M/ c+ p% v9 ?! w
  1036. }
    6 F! C7 i; }; \- H" H& ^
  1037. 7 Q5 P4 g  x4 W" S3 W
  1038. 5 S9 h4 z* Y8 n9 [
  1039. int main()
    1 ~+ U' f/ W5 K9 t/ j
  1040. {3 {/ H) y9 Z# H- _/ i& e
  1041. 9 e9 ?4 }) `/ G- r  }& Y, {
  1042. return 0;
    # _5 D4 O4 x9 Y- ^
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
  Q) G; m, D( Y$ W1 L- S5 w1 ], i   main()
$ g, E) t; V5 {8 y4 Z   里面怎么是空的呢?# p  q. O( j; `
   发一份给我吧
4 ~9 u4 i! g* W# imail:luyijun2005@hotmail.com
/ \: ~1 a9 T: J4 e咯。。。。
回复

使用道具 举报

 楼主| 发表于 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" h0 p: v" }' a, E& v1 y! t0 [/ h9 R( C' a! U8 \- U7 W
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。* {( @* k& c8 k+ W
EC的代码在哪跑,你看DS的说明,每个EC都不同的。. F. f9 y6 A# J5 m5 V
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
; _8 ?* e% |1 K3 Y/ w上面几个问题是你没看任何东西而白问。
+ F  q& Z/ c1 X* S$ m. M
1 P2 ^: |# O2 D, C( J至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
* F% ]. P; S& O9 D+ g& ?3 u
- ?' X: A9 N, F* m5 i关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!. C+ j% j* B6 d- n8 E  d

" s7 J% r. \5 H8 c1 M$ R关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”/ ~4 O' P2 T6 a5 s/ D
) P' T7 h8 z; m3 ^* X1 c  K
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...& i) f5 w" Y" N9 D
3 j6 p! y: X: @! C3 u3 d% V, v. |# a
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样5 g7 Q0 \9 L& m  A! u# q7 Y# @& g
似乎要把SPI能support 到最大,这EC chip应该有好卖点
& H, [+ d5 W  Y$ |! E& V5 @* S) FBIOS功能要不要强大,也就决定了SPI Flach的大小
9 N' W$ L0 w4 J/ A, u. o# g8 ^2 c我是这么想的~让OEM去决定要挂多大!2 ?5 R3 G7 Y* n6 n( U7 r% Y& R
如果我司有BIOS工程师就好了~哈3 ~' [$ x4 @9 Y3 ]
WPCE775应该算很新的东西,来看它支持到多大?
" Y" Y, ^2 E3 b& Y4 s- d" v; `5 G* ]; A8 s; f3 i
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
; Z2 H0 m# y. N2 G6 m# y1 o其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
- t9 T- C1 R, L3 p
$ x' x( i$ [( I6 ~" m2 a这份driver收下~希望以后有用到. M' N# Z( t5 n" }2 e' Q
谢谢bini大大
6 n# ^! j1 [# x# _9 t1 V  Y2 Q: T% h. u* ]- {8 j
很新很新的新手,如有错误请指正 (准备看第二家的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()
. A  d( q7 F8 i, k9 ^9 \- |{% B2 g. |" v- [; Y6 `# A
        unsigned char temp = 0;
7 f/ @" }. k6 H6 q8 L        CE_Low();- ]/ A( v4 C& @7 d9 ?2 Y9 ^' @2 L$ ?
    while (temp == 0x00)        /* waste time until not busy */
' v+ Q5 B+ e$ n& G: T3 S                temp = SO;8 W! _3 w/ U2 w1 v, @! B
        CE_High();
) t, `) `4 I3 c3 ~}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
* y( Q) y1 [. m; r; t{
, {) l9 R- b6 \$ e$ ?3 u# v        
3 s" ~" s' p+ E+ v. ]. P8 h        unsigned char i = 0;
. v' S- A6 U9 c' }9 B+ k/ H        for (i = 0; i < 8; i++), V7 o( b3 X' s: m, E5 G
        {
! T1 q: `( f0 L* b5 p' [               
: v2 j/ G; d; g. @2 o                if ((out & 0x80) == 0x80)        /* check if MSB is high */
8 }8 k4 d; i" g# D. E) |                        SI = 1;
& ~4 Y5 \& e! p! F) A                else" g( Y3 C$ x$ G) J1 Q) {7 M
                        SI = 0;                                /* if not, set to low */8 `" q) i0 G9 j- z5 x7 y2 z
问              SCK = 1;                                /* toggle clock high */
' u8 W1 P( M. h9 R9 H0 A$ b   题            out = (out << 1);                /* shift 1 place for next bit */" h/ [' ~2 G+ m  ?0 x
                SCK = 0;                                /* toggle clock low */2 u5 {( I. O# T
        }
( E  t" ?* `% Q$ k* G}
8 r/ M6 D( C& e. o 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-13 09:05 , Processed in 0.085171 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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