找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55442|回复: 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
    ( Z0 y2 z) d  @$ l
  2. % g( ]5 K" t, ]2 p) E
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    % ~( b6 k. l) S5 N3 x. ?3 H
  4. # c8 d* `6 U& u% f6 p" W
  5. November 4th, 2005, Rev. 1.0: o9 q# j8 O+ A: M! X4 w! D
  6. 8 x0 b- J1 U; Y8 `% l
  7. ABOUT THE SOFTWARE1 P$ Y& d2 v' u- \9 U) Y
  8. This application note provides software driver examples for SST25VF080B,
    7 R* ~& N1 c3 D- D, N5 k
  9. Serial Flash. Extensive comments are included in each routine to describe 8 K5 l! R9 ?$ ]. z& _
  10. the function of each routine.  The interface coding uses polling method + A* J# S: N7 j6 f0 F
  11. rather than the SPI protocol to interface with these serial devices.  The
    6 h7 R1 e1 d" A, X
  12. functions are differentiated below in terms of the communication protocols- K0 r# s1 M2 s/ S! G' p
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ( g8 G6 R7 p# C" R( {$ i& s/ V
  14. designed to compile using the Keil compiler.
    * C$ g' c% c% b4 n" z
  15. / R0 S, e% w6 x& e4 G8 s' T& l

  16. ; P6 ]4 l6 T! g7 @0 Q  c/ }
  17. ABOUT THE SST25VF080B
    0 d) W" ^1 [* t( O$ n
  18. / Y! t. w3 N. U4 {; _
  19. Companion product datasheets for the SST25VF080B should be reviewed in 9 s1 m8 L; I+ w3 K( w$ K8 I
  20. conjunction with this application note for a complete understanding 5 f+ @, w2 w/ {5 Q7 ^+ G. W& H
  21. of the device.
    + W( v& K! N% j- ^  f* o5 m1 t

  22. ' o8 U9 H( @8 _  H! u' x! i
  23. 0 J. e/ u. m  Z: V9 R6 O* w
  24. Device Communication Protocol(pinout related) functions:
    . @8 `4 A; F, [, |

  25. " e) r& w3 h. v% F, u% U
  26. Functions                                    Function1 J* {( w1 `( M# W: T* s0 n  T
  27. ------------------------------------------------------------------; _; p- h$ P+ Z$ q' j2 c
  28. init                                        Initializes clock to set up mode 0.
      d+ D9 [" S' P% z' Q5 }+ {: B5 j
  29. Send_Byte                                Sends one byte using SI pin to send and ( N; Q5 X# L# ]2 x3 X
  30.                                                 shift out 1-bit per clock rising edge
    / `2 p" c+ O9 B9 v; t: r6 u( r
  31. Get_Byte                                Receives one byte using SO pin to receive and shift + `0 ~# v7 b% G9 n- Y) T6 U
  32.                                                 in 1-bit per clock falling edge
    9 m* M9 ~0 ]. K! Z' q. P6 h
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    & ]$ }( W6 E9 `0 S- g7 ^# I! w7 i
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high4 b2 s0 o& v* C- ~8 ~
  35. CE_Low                                        Clears Chip Enable of the serial flash to low0 {4 M! W" |; |% L- N
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    - z- \# s9 X( {* H; x9 Y6 U: a
  37. Unhold                                        Unholds the serial flash
    " S; ]( G8 h  r9 M
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ! b4 K- g4 a7 }! v" N
  39. UnWP                                        Disables write protection pin
    / y5 j3 h2 ?3 U( x) m1 e. s( Q
  40. . ]6 P# e4 J/ ^+ _% D' A- W
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    - I2 U8 ~$ ^5 E7 c$ n
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your0 ?: n6 ^% n) K* ]# P  {
  43. software which should reflect your hardware interfaced.          : C( A4 Z2 K; Z0 o+ n5 A3 z  P

  44. ( \8 D' o0 z+ Z  t% r$ u+ b

  45. . \* ^: l8 H4 R4 S  `6 D6 {+ B
  46. Device Operation Instruction functions:: s6 p, Q) f, N

  47. ' O/ P- a& R: n+ Y" z: R" z
  48. Functions                                    Function, W& {1 ~$ F' ?, W/ g" B
  49. ------------------------------------------------------------------, V5 c4 ^+ F2 Y7 Q& U- h' h/ J
  50. Read_Status_Register        Reads the status register of the serial flash
    $ C8 A, g: f  b: y" c0 p! \# E
  51. EWSR                                        Enables the Write Status Register+ P  R1 y8 ]; N# y/ N
  52. WRSR                                        Performs a write to the status register5 ^" N, m6 ^) b6 N# \' @* x2 }6 q
  53. WREN                                        Write enables the serial flash
    ) g1 R# Y1 H( N! T. X# _
  54. WRDI                                        Write disables the serial flash
    ' F" v. }1 n. p( D& N* C" a
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming0 x. ]" V/ N2 b3 O# i/ E0 O& w
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    + N: w- w& W+ L- i9 l
  57. Read_ID                                        Reads the manufacturer ID and device ID
    ) r; R& z% H/ i( B. P# f
  58. Jedec_ID_Read                        Reads the Jedec ID
    $ p: e3 ^# y/ B
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)5 M" R7 \7 Q0 n" {9 j) @
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)- P/ x8 F; [+ Z# N6 e+ V
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    4 l% k+ z. v3 q' c0 T
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    8 l) L0 B8 o& [7 P0 w1 ^8 a
  63. Byte_Program                        Program one byte to the serial flash$ I# V; D% }# L! p) Z/ n9 N
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    / B  {2 S- y9 e  y, w! F
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation- }1 i% M1 v7 ]3 W
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY4 f3 q6 P( D) z2 a% B5 p
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY( Z( U8 C) s1 n% c) ^8 u+ X& M
  68. Chip_Erase                                Erases entire serial flash/ c' e! Z6 l! }  x: v% d) O
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash3 M: }$ X; m# c5 l$ N
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash$ p( X9 M' ^; c: L" x- v
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash1 w# D* X( M+ R7 _
  72. Wait_Busy                                Polls status register until busy bit is low% g6 a/ U$ j& T
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming7 J& M) u( J- G: ]* ^8 \4 j
  74. WREN_Check                                Checks to see if WEL is set
    & {4 X5 M' ]4 ?9 u% `! d% F! E
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set4 N8 F8 L" L; u* w

  76. : G) J# A4 P; }7 K& S
  77. . M4 {' ]: i, m3 Q
  78. ' I) Q3 C; F# C& H: F) T# `
  79.                                                                      
    7 y( p" G4 @( J( X- \) ]$ t* ]
  80. "C" LANGUAGE DRIVERS
    # Z4 ]* \, L* x  \; F7 g: z

  81. * L  c" q. \2 J: n
  82. /********************************************************************/
    ( |/ [1 T' F5 j8 y5 @
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    , Z+ M  R7 m& ?( y" g+ \
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */" L7 j2 K% Q. W; Q. b
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    2 s6 c2 g, N) v6 E
  86. /*                                                                  */
    2 m6 ?0 G8 y  r0 x" S! {2 X0 x
  87. /* Revision 1.0, November 4th, 2005                                                                          */   , t$ u/ Z  \2 U  q' t" Z) g$ F
  88. /*                                                                  */* Y& O8 l: C. L; U0 j) L8 \  y3 ?  U
  89. /*                                                                                                                                        *// Q5 ^  S: Q: j: C8 \
  90. /********************************************************************/
    5 d  y1 t. M9 E: R2 x8 Z) U9 V
  91. & J+ |* A) Z! r7 a/ V$ t$ D# Q
  92. #include <stdio.h>7 R8 X2 @$ L1 {  k4 E
  93. #include <stdlib.h>
    0 e5 S) v. D( J7 F
  94. ! i9 ]9 M0 `$ L& ?; ~0 x( X8 m
  95. /* Function Prototypes */
    6 I% |% W0 M; t6 q# I. e( @. G! p7 c

  96. 2 B4 F( j  A- }7 \& ^) b& B& j. b
  97. void init();( e& L% g$ m+ X+ v, e6 L  E0 c# v
  98. void Send_Byte(unsigned char out);
    4 ?* G7 g/ g/ E  q! m  H! V
  99. unsigned char Get_Byte();3 c: ~7 _1 C5 _: \1 t; q; H3 k
  100. void Poll_SO();. H! U: c: W( T  Y/ w; M8 S4 a
  101. void CE_High();+ V! y9 t# D( x. ^: M
  102. void CE_Low();  c* _6 y& {: i' `- g1 F3 W
  103. void Hold_Low();8 j7 r2 ]& C$ i1 O( |% y
  104. void Unhold();
    ( c. U$ v" ~5 w2 R7 R' o
  105. void WP_Low();
    ) q  D4 i2 n  h1 V! [; H; l5 A
  106. void UnWP();8 z0 G" O- E0 o  |
  107. unsigned char Read_Status_Register();
    7 B- N) \$ [! g  O/ X
  108. void EWSR();
    : F+ w$ C* D- v% Y/ y7 J
  109. void WRSR(byte);- e' i0 L' ~' s' W, D  T
  110. void WREN();
    7 U. ^) L$ \" D
  111. void WRDI();
    ; M& @; s3 X7 Y: Z
  112. void EBSY();; K+ T: }: \' \& I  x4 Y- D$ J, u
  113. void DBSY();- W2 `' G/ w) C8 ^
  114. unsigned char Read_ID(ID_addr);
    / t) x9 Q9 Y6 i; @0 `7 g) y
  115. unsigned long Jedec_ID_Read();
    6 o2 c  y% l$ L8 q4 O: h4 E
  116. unsigned char Read(unsigned long Dst);0 m( d* C! `( U
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    6 w! l# d* W1 ]7 i, O
  118. unsigned char HighSpeed_Read(unsigned long Dst);
      C, h$ w$ m7 S. {- d' N' @. d0 N
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);: _1 G7 W2 f- S- k/ G% ]+ f
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    $ U+ F' Q& j2 r0 R* f
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);( i! ?7 X) Z- H* V4 E3 |6 k
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    - w1 O3 E1 D# v& d& p! _
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ; |2 K3 [$ R. L! B- k
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    # }2 m8 f  q1 n% W5 {* p% n
  125. void Chip_Erase();4 @! r$ c6 F6 w
  126. void Sector_Erase(unsigned long Dst);
    5 d" B# P$ J) W# j5 p( E
  127. void Block_Erase_32K(unsigned long Dst);% y* u9 P3 _2 W7 @1 I3 j9 |
  128. void Block_Erase_64K(unsigned long Dst);
      {6 G8 p. f% ~, D+ a- R
  129. void Wait_Busy();
    ; Q; L; x) A# f4 C7 Q
  130. void Wait_Busy_AAI();- K& _! ]+ ~) c' N* A; {3 |- `1 [3 P
  131. void WREN_Check();
    4 E8 o% `# W: W/ l& V
  132. void WREN_AAI_Check();
    * U7 H- j! C7 K) ?/ Q. E

  133. % K9 T1 b1 q, q7 I2 h+ F" ?1 Q5 j
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    6 b/ ?0 u/ B. l6 }$ ^6 m% X- _9 N
  135. 3 E% r4 r: v/ `1 \# r9 _
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    ; V- n. t# `9 z+ K
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    0 k3 t7 N0 e0 O9 g" E4 M8 `

  138. , W- q( f9 O  c, _! M+ }( m! }# g
  139. /************************************************************************/) x% ?% }: s0 w6 P1 u7 j
  140. /* PROCEDURE: init                                                                                                                */
    - v8 M! ]9 B9 y' I
  141. /*                                                                                                                                                */
    9 p) e8 }- o: q. e( Z
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    % F2 R$ b+ O& n4 `
  143. /* setting up mode 0.                                                                                                        */. Y3 V+ g! o- @, z+ b% [% ^, c
  144. /*                                                                                                                                                */
    " {+ r/ x9 }, c+ G" W3 ?
  145. /* Input:                                                                                                                                */
    0 Y( v$ X, K1 b: O  s: V2 V5 C
  146. /*                None                                                                                                                        */2 g2 E/ @: ?3 [4 [1 y
  147. /*                                                                                                                                                */
    1 Y) m2 x: I/ }& c1 O
  148. /* Output:                                                                                                                                */
    5 O0 E% \$ E8 a* |7 |
  149. /*                SCK                                                                                                                                */
    , H6 m; o/ ]% V6 g: [6 K
  150. /************************************************************************/
    ' @) x: I- Y) T* m  H. M$ k
  151. void init()
    0 a  I% a- Q7 V6 }6 E
  152. {
    * J7 X! ^* [$ x" ?
  153.         SCK = 0;        /* set clock to low initial state */+ E5 `7 Y' ^* }3 L  C
  154. }
    2 t" |0 E, J; n( U" G! O

  155. 0 {% c# m' L7 W- A- \4 l6 o8 N1 g
  156. /************************************************************************/0 M, }8 r0 g$ Y! R" M2 I4 v
  157. /* PROCEDURE: Send_Byte                                                                                                        *// N) H% d* s. p) u( i
  158. /*                                                                                                                                                */
    ( O; [6 Y6 ~  q; W2 b
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ) A  ^. w( l9 N/ T( ]6 |8 ~5 @
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    6 T: q/ f  b5 M/ F  ]& a
  161. /*                                                                                                                                                */" [# v# F% b  U# E. v+ G
  162. /* Input:                                                                                                                                */- w. l8 g1 ]5 B1 D1 V  P( g% e
  163. /*                out                                                                                                                                */
    $ N; F1 Y4 d& ?# l) \
  164. /*                                                                                                                                                */
    ! E; D2 z5 ~+ y
  165. /* Output:                                                                                                                                */
    * t/ f. x' B3 w$ ~
  166. /*                SI                                                                                                                                */
    8 Q6 Z6 n* L  z7 ]
  167. /************************************************************************/
    8 i) ^9 U# K5 u4 K" x9 `
  168. void Send_Byte(unsigned char out)+ b4 X6 c. r8 @
  169. {2 k* u- V- A. a0 D& s' v( x
  170.        
    4 q; O* Q' |) v  I( t2 `
  171.         unsigned char i = 0;
    , m! \1 R- z  Q1 T2 V
  172.         for (i = 0; i < 8; i++)1 Z" `  q  T, \
  173.         {
    % d; g9 V3 Q9 f
  174.                 ! S9 @9 Z5 y' w8 d5 n
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */. L6 `$ V( F* z) A3 f3 j+ ~
  176.                         SI = 1;
    . w6 {! b# P4 n1 z1 L/ f, m$ p1 G
  177.                 else
    ( ?" r; Z" Z5 b( m% y0 e6 Q  y
  178.                         SI = 0;                                /* if not, set to low */9 [! Z6 r) x, A5 }7 y2 c3 A6 H% x4 k
  179.                 SCK = 1;                                /* toggle clock high */
    ' Q8 S$ i3 q6 s7 g( X
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    & D. O& Z1 e$ h, I# Y. R1 h: a
  181.                 SCK = 0;                                /* toggle clock low */
    ( a# O/ c: E0 c
  182.         }7 e- K0 ~6 T* _6 a% |( ]/ i
  183. }3 o1 m* N, `, A7 I7 [
  184. ' z7 p7 x  K# H1 a0 d8 _
  185. /************************************************************************/) _3 H9 p8 D/ v/ `
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    # K8 p4 b7 g( F* b& F
  187. /*                                                                                                                                                */
    0 k3 H' J; @4 e0 K7 `$ F( a2 E
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */6 v/ x4 p/ ?, M% b
  189. /* edge on the SO pin(LSB 1st).                                                                                        */9 H9 d  Q' R' I! i* t$ a& p6 ?, ]# J1 c
  190. /*                                                                                                                                                */
    5 w8 O8 M, h1 `! t3 N% I# j
  191. /* Input:                                                                                                                                */
    * Q3 v- O& k, [( B+ y5 n: ?# ], |
  192. /*                SO                                                                                                                                */
    . c  z1 Q9 W1 H' R! X' ?- G
  193. /*                                                                                                                                                */1 s, Q  z, m8 l! n8 s9 r
  194. /* Output:                                                                                                                                */
    # q: f, Y' p: n$ c2 H6 u
  195. /*                None                                                                                                                        */
    5 Y& }; c# ~* Y" g9 `( z' S
  196. /************************************************************************/
    / p& d" u: D2 G; c% x, f4 ~* n$ G
  197. unsigned char Get_Byte()6 \$ x, O% U5 s1 t- X) y
  198. {& I; s) f! B; e( D" h$ d1 O# {
  199.         unsigned char i = 0, in = 0, temp = 0;
    ' b2 D+ e+ I" v! c, C9 G
  200.         for (i = 0; i < 8; i++)
    1 o# [2 v1 d: ^, e0 h
  201.         {
    0 ?0 K& }$ ~9 T  b
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    " v4 V. Q. @7 w% S, f5 P
  203.                 temp = SO;                        /* save input */
    8 j$ }3 v$ M" A" R
  204.                 SCK = 1;                        /* toggle clock high */1 u( S- x  [4 }1 r4 C
  205.                 if (temp == 1)                        /* check to see if bit is high */) q- I6 A: ^2 D, r0 h" `' h
  206.                         in = in | 0x01;                /* if high, make bit high */' L4 L, U6 }- d
  207. * G' W$ n/ [, I, |
  208.                 SCK = 0;                        /* toggle clock low */! K+ A5 Q9 b. d8 Z6 x# |, i$ o& y

  209. 7 E/ n  B1 v5 z
  210.         }
    8 g2 M* c/ h$ r4 M& H5 M
  211.         return in;$ a8 o5 T: G4 a4 C  A
  212. }
    0 k6 q! ]( ~+ [

  213. 4 Z1 t) T% W- b: f8 v& d
  214. /************************************************************************/
    / Z* j! e3 C* ?9 q* a) o
  215. /* PROCEDURE: Poll_SO                                                                                                        */" _3 G$ s3 K1 O3 \$ E
  216. /*                                                                                                                                                */
    0 N6 }- }: u! H$ X" l  }* ]' }
  217. /* This procedure polls for the SO line during AAI programming                  */; y& p1 S* ]) V# h6 N- `/ Q$ f
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    1 x2 ?- R0 \. P/ p* Y& W& m( q
  219. /* is completed                                                                                                                        */
    - R( Z" i& z2 y
  220. /*                                                                                                                                                */
    , `0 V% @5 }& X( x( G* ?7 `
  221. /* Input:                                                                                                                                */
    ) Q+ K4 x9 W9 C+ }! |5 c/ D# \
  222. /*                SO                                                                                                                                */2 _# Q/ d  f7 b% H6 a7 s
  223. /*                                                                                                                                                */
    3 G+ W3 Z) K9 {2 r- H
  224. /* Output:                                                                                                                                */
    . `2 t) S1 t$ L6 h) g) F
  225. /*                None                                                                                                                        */
    7 A; ~; d$ D* d4 |. z
  226. /************************************************************************/
    9 r7 h7 @: j' `- C2 k
  227. void Poll_SO()3 i" a% G. W* c  {6 }* j: ^) q
  228. {6 C  y) m+ Z" r- l% A
  229.         unsigned char temp = 0;6 ^/ M8 ?# ]" u9 z
  230.         CE_Low();, ?! Z0 ^# v& f! @0 ?' y: Z
  231.     while (temp == 0x00)        /* waste time until not busy */
    + J2 V, u; [6 k% ~( K
  232.                 temp = SO;# W. t$ O8 K9 p0 J' f! ~& m( Q5 h# I
  233.         CE_High();
    6 t! q" y; Z: X5 x
  234. }
      p1 B$ a' O$ j- \

  235. 2 p  c, W# m4 t+ S8 E  u. A
  236. /************************************************************************/
    . {$ s- J. A/ W# E9 S+ K7 p) `/ E
  237. /* PROCEDURE: CE_High                                                                                                        */6 z) i1 I3 L3 P* U  p
  238. /*                                                                                                                                                */- y9 b5 X) v: {( e/ S+ `& j; ^
  239. /* This procedure set CE = High.                                                                                */
    2 i" [; {4 H/ p
  240. /*                                                                                                                                                */
    7 u  I: J0 b9 W7 T$ U1 O% O
  241. /* Input:                                                                                                                                */+ d; U5 v" }+ d: z% M, a9 y
  242. /*                None                                                                                                                        */
    ' _$ n5 p" o% C* s2 {, I
  243. /*                                                                                                                                                */  g" j) I/ O# E
  244. /* Output:                                                                                                                                */7 {# D7 g! I1 B' N! K8 \
  245. /*                CE                                                                                                                                */5 k: `7 Q6 x1 u3 u- y6 \7 a3 }
  246. /*                                                                                                                                                */
    ; ?; D, d. _6 b, W5 h! W4 b
  247. /************************************************************************/
    ( L' g5 V. ?8 T2 i
  248. void CE_High()
    ) \8 T) s" k( }: `/ v
  249. {
    0 e: a/ D9 K/ u  l, [6 \0 C
  250.         CE = 1;                                /* set CE high */) N& x, P5 p8 W1 W
  251. }
    * [6 N  V+ O( }

  252. % Q4 p( K. h! ~
  253. /************************************************************************/8 U( t6 x) ?$ M& ~  ]+ k  _. f
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ! p8 \- T# F" O7 c" }1 G% _
  255. /*                                                                                                                                                */3 V" p+ t7 O( Z$ m
  256. /* This procedure drives the CE of the device to low.                                          */
    4 u/ x  {5 z0 I0 |8 G2 |" i/ n
  257. /*                                                                                                                                                */! |( @  Q& ^" p0 {! `0 {
  258. /* Input:                                                                                                                                */
    " w5 M1 o2 C5 _0 S
  259. /*                None                                                                                                                        */" z, g/ v$ f9 M; Z
  260. /*                                                                                                                                                */; R  x0 r3 E2 @" X' O1 f
  261. /* Output:                                                                                                                                */
    3 G7 F5 `- _$ h9 b' g, p5 u
  262. /*                CE                                                                                                                                */
    " M: S3 Z0 P: \5 [# }& _  h
  263. /*                                                                                                                                                */
    - a- r* }) l* ?- o7 J
  264. /************************************************************************/% }, u% F4 {4 M/ E( @" s
  265. void CE_Low() 0 [' O& E! A- B; r- {7 I0 V  e7 n
  266. {       
    ( o) L- F! `' N8 e
  267.         CE = 0;                                /* clear CE low */
    . H0 m6 T) }, S  g1 F) z# N' b
  268. }7 [! J5 H# O6 C5 t. J

  269. 6 Q/ f  J, E6 G% x( o' g
  270. /************************************************************************/
    1 p2 U7 @7 ?/ w* ]( I
  271. /* PROCEDURE: Hold()                                                                                                        */
    9 w6 k/ C" e0 _9 ^4 c" ?
  272. /*                                                                                                                                                */
    ; q" W6 b, g& }3 G' C& j
  273. /* This procedure clears the Hold pin to low.                                                        */% g' U1 O; e5 w( O3 ~/ M
  274. /*                                                                                                                                                */. F4 I9 g9 \1 P+ E- K9 M
  275. /* Input:                                                                                                                                */
    % M$ p/ e# N0 [1 E
  276. /*                None                                                                                                                        */- _/ W$ g6 S" ]# Z5 o) K" T5 M6 N
  277. /*                                                                                                                                                */
    2 W& i1 J; u6 O  W
  278. /* Output:                                                                                                                                */
    - J( g& z4 S. ?$ q; ~
  279. /*                Hold                                                                                                                        */
    ! j4 r& c! w; h7 z- z5 M
  280. /************************************************************************/+ I* t9 ?* Y' \: e2 y% s
  281. void Hold_Low()
    ! A/ I/ N! q$ {  r3 w/ }
  282. {0 B. v8 z6 u5 S6 l! f6 w
  283.         Hold = 0;                        /* clear Hold pin */
    ; G5 X4 f/ z5 r/ k8 c3 W9 M/ R
  284. }0 r+ Y7 e1 K% F" G' p3 D
  285. + p- J7 Z3 S9 o! V, {8 J' r
  286. /************************************************************************/  X7 y& a2 C* ]( u8 ~
  287. /* PROCEDURE: Unhold()                                                                                                        */
    * _9 X( O+ }! r! f
  288. /*                                                                                                                                                */. @% K  |2 X7 u: ^
  289. /* This procedure sets the Hold pin to high.                                                        */
    ( G$ R( I# w1 r$ u! T' n" u& f
  290. /*                                                                                                                                                */8 F# a  N1 v2 O$ F0 m  I
  291. /* Input:                                                                                                                                */
    1 L5 q# R: r, U& G0 t
  292. /*                None                                                                                                                        */
    " k+ `- D3 p$ C
  293. /*                                                                                                                                                */, {4 @$ q6 [. v; W+ t0 T; x: X
  294. /* Output:                                                                                                                                */- o3 L; h* [8 f* ?3 d- o& U" a
  295. /*                Hold                                                                                                                        */
    ( ~$ K  w; e1 k9 T( ?0 `
  296. /************************************************************************/3 ?. p9 v0 q6 q& M1 F/ ~  F
  297. void Unhold()7 l4 ?+ U3 g2 ^
  298. {* Z4 k; G' R3 ?3 V
  299.         Hold = 1;                        /* set Hold pin */  F7 M8 ~# u! y4 U1 U* e/ B
  300. }
    / [, V& e- |4 M- A
  301. . s8 O! C% T- S
  302. /************************************************************************/+ ~" _5 M  H( P
  303. /* PROCEDURE: WP()                                                                                                                */* o) Q- K/ u! G! y5 i! Z7 ]
  304. /*                                                                                                                                                */
    . Z! p+ H5 v/ r- X- X2 W) K
  305. /* This procedure clears the WP pin to low.                                                                */
    8 @- q1 l" q8 v
  306. /*                                                                                                                                                */
    * P5 L" }- I9 j! ^2 h' R
  307. /* Input:                                                                                                                                */! N0 B7 `1 q2 I1 k, D
  308. /*                None                                                                                                                        */
    * I3 b) g$ z3 `' E  o' \" X1 V! a6 J2 n8 j
  309. /*                                                                                                                                                */
    $ j1 m9 ~4 i# Q% K8 M% q- F' l
  310. /* Output:                                                                                                                                */
    % \/ t6 S- D+ A7 S
  311. /*                WP                                                                                                                                */0 Q( u' t# h6 l# R/ N7 S2 O
  312. /************************************************************************/
    " {( d5 k$ j" W" F
  313. void WP_Low()4 T9 C8 p: i# n& u8 L; ~! t, j
  314. {
    , C! H$ e8 V& C. k- u% m' t
  315.         WP = 0;                                /* clear WP pin */* h  T: t7 v! W  G* X8 N6 ]" z2 x8 u
  316. }  U" e/ e- X$ {' G5 ^! h  X
  317. * f0 _" Q7 |( Q$ t% [
  318. /************************************************************************/# d, Y: m$ ^( n! u& S" C
  319. /* PROCEDURE: UnWP()                                                                                                        */
    % ?: ~' W" q2 D" p3 ^' h
  320. /*                                                                                                                                                */
    , \+ X4 ?) |  P" f
  321. /* This procedure sets the WP pin to high.                                                                */3 L  C4 j6 s- Q0 k
  322. /*                                                                                                                                                */
    ' U, C* a8 `. o; W
  323. /* Input:                                                                                                                                */$ p6 C, t# E: o! s# K/ \
  324. /*                None                                                                                                                        */
    # b2 J( c0 |" h5 K2 c" n
  325. /*                                                                                                                                                */- q( \5 A; \' ?! L: r( v: \
  326. /* Output:                                                                                                                                */
    5 x( a7 {/ f1 G1 v9 U. j
  327. /*                WP                                                                                                                                */( j( l! k* i) p# w$ j5 m7 ?/ P1 I/ [. S
  328. /************************************************************************/% `" O4 M6 ^( N& c
  329. void UnWP()
    ! P8 Z, P, {4 I6 ?) J
  330. {
      P5 ^# F, S8 ~; z; X% b& T
  331.         WP = 1;                                /* set WP pin */
    2 h! }+ R: ?' B# {# W- m# _
  332. }
    * }: m# o: p2 P# @# }. Q) w- D+ _
  333. $ F6 n1 L5 T% `+ {8 `3 O- C% w
  334. /************************************************************************/7 l% ]+ f$ P* \( q- S
  335. /* PROCEDURE: Read_Status_Register                                                                                */* L9 y- ]9 x0 Y+ I: n
  336. /*                                                                                                                                                */1 l! q' i+ T) f! X9 Y/ @
  337. /* This procedure read the status register and returns the byte.                */3 N: }, p9 k/ {& |5 J5 b
  338. /*                                                                                                                                                */3 V3 r* e0 l5 \) b
  339. /* Input:                                                                                                                                */" {& l* o! Y! Q  G' j3 ^
  340. /*                None                                                                                                                        */
    . n/ M0 k& [. a' @% E& q: X
  341. /*                                                                                                                                                */
    4 ?5 Y' @, d! f5 j2 G( R
  342. /* Returns:                                                                                                                                */
    2 `7 ]' p9 I+ J5 d; W3 }- q2 m
  343. /*                byte                                                                                                                        */! P# l$ t6 U) c) j3 |' m
  344. /************************************************************************/
    $ k3 t7 J/ r" ^* r9 I% \1 [
  345. unsigned char Read_Status_Register()2 O/ o: o% A" E7 K5 {: U6 {! e+ ~
  346. {) X. I/ l1 J5 X, `2 G2 B! ^8 Q2 W
  347.         unsigned char byte = 0;' R( @2 A' t  {* ]& P( m& |, v
  348.         CE_Low();                                /* enable device */
    4 `& |. [7 @3 E! s6 |
  349.         Send_Byte(0x05);                /* send RDSR command */
    7 T, e/ _8 J, x$ v
  350.         byte = Get_Byte();                /* receive byte */
    7 C+ `% P; Q+ D) A
  351.         CE_High();                                /* disable device */
    + b  Q) v# H  z. I
  352.         return byte;
    ) L3 F' h! q+ P, p+ m6 q
  353. }: d7 v) A9 A+ @$ J. _3 n$ e

  354. ( t# U, C& s6 f. e- l
  355. /************************************************************************/
    ; v. @! M. b& `" [  Q
  356. /* PROCEDURE: EWSR                                                                                                                */
    - {/ j: t4 }3 |
  357. /*                                                                                                                                                */
    $ a* B6 B8 w% Q- R5 }) z
  358. /* This procedure Enables Write Status Register.                                                  */
    , P( |) n0 ~$ f' R
  359. /*                                                                                                                                                */
    / Q, l4 N& h  S7 L# _
  360. /* Input:                                                                                                                                */
    ! N0 v3 P. @, j- E4 ?: J
  361. /*                None                                                                                                                        */
    + |2 x! \9 h$ e! s; V- e1 H! U9 @
  362. /*                                                                                                                                                */: j7 f7 F% d6 A. i( k
  363. /* Returns:                                                                                                                                */5 b8 I  U9 v6 J' H0 ?! A- [
  364. /*                Nothing                                                                                                                        */. c0 T9 P0 }9 _% ?. V
  365. /************************************************************************/
    $ L0 h7 ]2 ~& H5 H8 p  L: g2 S
  366. void EWSR()5 V7 G( S/ W$ u3 q8 m
  367. {
    0 Z5 V( y" P) A
  368.         CE_Low();                                /* enable device */
    6 p7 K* R5 W3 A) Z  T# M" g; I+ `
  369.         Send_Byte(0x50);                /* enable writing to the status register */
      ~4 |: x2 v9 W( P$ f! N& q
  370.         CE_High();                                /* disable device */+ Z5 x, u9 V3 A/ L# G, t- s
  371. }+ c; Q8 {5 i" R' Z8 ~$ R4 P

  372. # P2 U" ?: ?7 X- p# C. F' c, Q
  373. /************************************************************************/
    ; Q4 t* [1 d6 H4 @8 n5 N5 E0 b" `
  374. /* PROCEDURE: WRSR                                                                                                                */
    % \. [3 l5 _( Z1 P6 `8 a) G" _/ n
  375. /*                                                                                                                                                */3 v! w& h) d" t) U
  376. /* This procedure writes a byte to the Status Register.                                        *// c2 y$ {6 c+ E" F- |$ N  ^
  377. /*                                                                                                                                                */
    " d4 r& c- _2 a% R
  378. /* Input:                                                                                                                                */
    - x) X0 t# Y% {" v/ D
  379. /*                byte                                                                                                                        */
    ; h& Q8 Y6 V: b
  380. /*                                                                                                                                                */
    2 }/ n/ Z# ?9 Q% L
  381. /* Returns:                                                                                                                                */( c3 `  f6 G+ g) j4 C* P
  382. /*                Nothing                                                                                                                        */
    4 x6 b; I& n4 S0 X* g6 P9 S" e3 [
  383. /************************************************************************/, G! y4 u  g4 c' p  [
  384. void WRSR(byte)
    * {0 |7 K) N) l
  385. {
    + E6 j3 l+ X5 [" n3 w
  386.         CE_Low();                                /* enable device */! [* ?: Y) x3 S' C" D/ I6 {1 I' m
  387.         Send_Byte(0x01);                /* select write to status register */
    ( @. b8 n/ Z4 s& ^9 R. N
  388.         Send_Byte(byte);                /* data that will change the status of BPx - V/ I4 p( L4 s2 U: T1 ^  Z
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */3 D! D: d* A. O7 l
  390.         CE_High();                                /* disable the device */
    , k$ p. T: X- G3 R2 A$ Y2 M
  391. }. c- @9 k1 g0 A2 H, z1 L
  392. & H) R8 l5 q. L. U) W- B' |, g
  393. /************************************************************************/
    4 ^( p2 Q+ |1 D$ [2 R  ~
  394. /* PROCEDURE: WREN                                                                                                                */8 n) o1 \( o# Z% j7 |
  395. /*                                                                                                                                                */& y4 T3 Q; \' d+ A8 t$ p4 Q
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    5 M: }" i( k5 J- `, H" E
  397. /* to Enables Write Status Register.                                                                        */
    # Q& M* I6 e! `$ p  z7 I
  398. /*                                                                                                                                                */, d" y" ]. A+ t9 [4 X
  399. /* Input:                                                                                                                                */
    9 U* D$ e9 P1 o$ M! Y2 F. h" C
  400. /*                None                                                                                                                        */, }5 g1 J: \% Y# W# D' F6 o
  401. /*                                                                                                                                                */
    ' a5 M8 J5 p+ v7 |4 S% B
  402. /* Returns:                                                                                                                                */+ y( W: f! L8 L5 V
  403. /*                Nothing                                                                                                                        */
    ' ~1 y# Q- N9 S1 G
  404. /************************************************************************/
      g1 C8 L* z7 G5 \4 G
  405. void WREN()% L6 @% `: {7 X
  406. {
    ) a  C% @; }# o- S$ F# _
  407.         CE_Low();                                /* enable device */
    8 x# _7 O( f$ ~, \; S
  408.         Send_Byte(0x06);                /* send WREN command */
    % H% T* o- a* t3 G) h4 I, ]
  409.         CE_High();                                /* disable device */
      B* Z0 t; N/ E
  410. }' l2 ~8 Y' E0 F, \: _, f
  411. ) |- H! D# S$ z5 n% ]
  412. /************************************************************************/
    1 Q, g2 i) X' b: _9 D1 z& C  L+ b
  413. /* PROCEDURE: WRDI                                                                                                                */
    * i* M1 r$ L- ?6 ^
  414. /*                                                                                                                                                */7 {+ C& {+ ?% x* f% D& ?9 T: W6 N
  415. /* This procedure disables the Write Enable Latch.                                                */4 X1 o$ w* m) Z8 j& @0 {' y" ^
  416. /*                                                                                                                                                */5 B7 L5 _  y4 H
  417. /* Input:                                                                                                                                */
    ) Z% z1 _% n* `& N# J' e
  418. /*                None                                                                                                                        */
    ! B/ S" I- Q: I5 _' ^4 K6 }# J
  419. /*                                                                                                                                                */2 G8 y& \* l( ~; |2 g- e1 J
  420. /* Returns:                                                                                                                                */  W* [+ H. p" Q( A7 n! E
  421. /*                Nothing                                                                                                                        */
    / Z; B8 d" v' p+ \
  422. /************************************************************************/
    5 j5 `4 U0 g/ T' `1 @7 ^
  423. void WRDI()
    / o. J0 z4 i) F! ^' L5 q
  424. {
    ( A! `. l! b4 \+ @, b
  425.         CE_Low();                                /* enable device */- v4 Z6 @( Q. X3 e0 n& U
  426.         Send_Byte(0x04);                /* send WRDI command */0 B1 ~& u) N# [7 x; O. g  d& z
  427.         CE_High();                                /* disable device */. n. }% x$ N' d" D) h
  428. }4 f  h" x; y2 ?3 h# o7 w8 g) G
  429. $ A: P6 b& j% u& u/ n$ F8 }. }
  430. /************************************************************************/3 `+ h- s2 q$ X1 B) X
  431. /* PROCEDURE: EBSY                                                                                                                */8 \; \- ?  y- c8 U$ ]
  432. /*                                                                                                                                                */
    " Z4 P9 s$ B; }' k& g) F
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    . A1 \2 q  W" O
  434. /* programming.                                                                                                                        */' M6 e# C+ B2 b
  435. /*                                                                                                                                                */
    * ]4 Z; N8 U; q1 ?7 z5 X' H
  436. /* Input:                                                                                                                                */
    9 g! X& i! ?$ ^7 V# [
  437. /*                None                                                                                                                        */
    0 f8 ?" e; [9 D! W' S# t
  438. /*                                                                                                                                                */
    - \# [4 O. A8 B
  439. /* Returns:                                                                                                                                */
    " _1 J! i" r: h4 L
  440. /*                Nothing                                                                                                                        */
    ! r+ h" r. U3 \: J* ^5 q* G
  441. /************************************************************************/: j9 ^/ V/ ~$ Z9 r  S
  442. void EBSY()
    ( S' ]8 P) l( Y5 W5 |8 v! n! t
  443. {5 p8 D, k( a0 N5 h2 E
  444.         CE_Low();                                /* enable device */, s* _5 g) `0 B' _1 u8 g
  445.         Send_Byte(0x70);                /* send EBSY command */
    ; n7 B2 E- {3 I: V* h+ J0 B
  446.         CE_High();                                /* disable device */
    ( H( K1 _/ z3 Y& L2 j
  447. }+ U+ a- @* o+ m: U
  448. * l6 G8 S9 x5 K- q- W2 U* S
  449. /************************************************************************/5 M% H% p8 N6 n& R
  450. /* PROCEDURE: DBSY                                                                                                                */
    * J* \( D4 [, i: [1 ?6 x) }
  451. /*                                                                                                                                                */; O  n! Y5 V+ H
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ) v# x' x& X8 j1 w' \
  453. /* programming.                                                                                                                        */
    1 e) J" R7 [5 Z( N
  454. /*                                                                                                                                                */6 O8 }: ]5 l9 u" Y8 w' `) m: {
  455. /* Input:                                                                                                                                */6 _( @# H6 }" i6 B( m  i+ p
  456. /*                None                                                                                                                        */0 Q8 ^$ a( P# p
  457. /*                                                                                                                                                */$ c& R6 h9 m9 L. d: _) e
  458. /* Returns:                                                                                                                                */
    / B6 d# h, A& T2 i
  459. /*                Nothing                                                                                                                        */9 m, O& V, p7 L; t
  460. /************************************************************************/. Y" k- H6 v8 Z" r7 [
  461. void DBSY()! M/ m  x) F" N/ n8 j
  462. {% l* p: ?" c9 u7 b4 u3 e7 Z9 H& ~8 O+ C
  463.         CE_Low();                                /* enable device */
    # J$ Q9 U" N3 H8 [6 `6 w$ f/ I
  464.         Send_Byte(0x80);                /* send DBSY command */
    * V9 ^1 f0 t+ T6 f9 f6 }
  465.         CE_High();                                /* disable device */
    " ~& c- M' i' I8 D
  466. }
    ) n5 E1 `. x. a) _' N. l
  467. 5 y( D6 t6 s$ c- \0 p: _# K
  468. /************************************************************************/8 d, |$ d" m. Y- ^
  469. /* PROCEDURE: Read_ID                                                                                                        */
    7 F9 d7 [( N3 W6 @
  470. /*                                                                                                                                                */
    + M7 q$ W+ ^( T) I: f! O: U
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    5 @: x8 \9 R3 h  @
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   *// G( O, p  n# S
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    3 i* N: ^% a9 x. L4 F3 h
  474. /* whether the device outputs manufacturer's ID first, or device ID         */' |: T# L  ?; x& r
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    2 R. p0 T9 w8 \# }: F1 h% G; `
  476. /* variable byte.                                                                                                                */) M* |2 I: b$ p) [6 b3 G1 E
  477. /*                                                                                                                                                */
    ) H. ?9 h" Y4 T
  478. /* Input:                                                                                                                                */- ]8 Z. r' k1 I& h% @5 R
  479. /*                ID_addr                                                                                                                        */$ e( L- d# o/ z3 p# ]8 P/ ~" @( d
  480. /*                                                                                                                                                */
    & E; l8 N" a* r0 x/ d9 x# U' D
  481. /* Returns:                                                                                                                                */' E0 a- a  z' a* m
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    ! K" N( m8 \# v4 f
  483. /*                                                                                                                                                */4 E' V5 a9 `. Z0 q. l
  484. /************************************************************************/
    ; B6 N( }3 S/ x; L
  485. unsigned char Read_ID(ID_addr)' U! H4 z: z3 P6 O6 f- l! i* R3 D( ?
  486. {( I# q* {) y: I  J7 V. g  {
  487.         unsigned char byte;( H3 S- _/ ]  I" H/ s
  488.         CE_Low();                                /* enable device */
    + ~7 P7 X$ ~, C$ [
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */* _* H$ V# V) z5 ~# f
  490.     Send_Byte(0x00);                /* send address */1 s5 A0 ~$ v% s7 D" m
  491.         Send_Byte(0x00);                /* send address */
    0 E4 n6 u, W) m
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ! q+ F7 B/ ~7 r- a, }) q
  493.         byte = Get_Byte();                /* receive byte */" q( P" S* q  p0 O( c0 q* n. N+ z+ ]
  494.         CE_High();                                /* disable device */; V" h. c3 W3 t0 `
  495.         return byte;
    + ~  b2 y3 C6 P- d% M# O5 A
  496. }! L' u' X- m0 X) C  F
  497. " J/ |* k8 D! I
  498. /************************************************************************/
    ! r0 z$ w) E' S+ r! ~( i3 ]; j
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    0 K. e* X3 C; k  ]
  500. /*                                                                                                                                                */
    ! d; M2 c9 D! h- \! o
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    . F  X) H" T  }% Q$ n* ~
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */+ o3 U  ?! Y% Q$ f9 a0 F( B
  503. /* Please see the product datasheet for details.                                                  */5 U9 ~* ~) Q' i
  504. /*                                                                                                                                                */
    + K  ~2 V( p9 C4 J
  505. /* Input:                                                                                                                                */3 m3 I) \- T  k* g
  506. /*                None                                                                                                                        */
    + Y1 N+ l0 ]; b0 k9 T
  507. /*                                                                                                                                                */
    ) s/ v+ m; P" ]" S2 r0 ~
  508. /* Returns:                                                                                                                                */
    * |3 W1 B0 f" g2 H. g" S/ b. P1 X3 n
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */3 P% b4 M: }: V6 Y7 d
  510. /*                 and Device ID (8Eh)                                                                                        */' @- W$ X/ y9 J; J) F( F4 d& n
  511. /*                                                                                                                                                */
    . j) C( R; T" ], A
  512. /************************************************************************/% |" g) L. I% r0 C8 X9 J# O; i8 l) B
  513. unsigned long Jedec_ID_Read()
    7 G9 I0 {4 d# ~4 G5 {* O! m4 u
  514. {
    / I5 W# ~3 T& {1 s' S( W% g9 b0 j
  515.         unsigned long temp;
    % F; H6 ?- {0 F; D; Q, n
  516.        
    7 V/ n( h% i8 p! q' K
  517.         temp = 0;
    5 h- b/ G' c# o& l9 t" j* T
  518. $ u8 i" }  X+ f3 [+ K2 o) o
  519.         CE_Low();                                        /* enable device */0 e6 P. z! r! P; B4 G3 x4 O+ C$ v
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    * r1 u1 J, Y( y1 E9 m
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    & b  Y+ L  W* K: }
  522.         temp = (temp | Get_Byte()) << 8;       
    ! N- \. g* t. X0 p& N* [, e
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    # @, N; e0 X, `: V) P
  524.         CE_High();                                                        /* disable device */1 T6 ^* [4 L- E; n4 q# h

  525. 5 G% f" W6 f% v$ s, E
  526.         return temp;
    & @2 {! m) V$ g- x' ~
  527. }
    9 m* {( u5 _9 O# X  m  a: `8 G
  528. 4 \! m/ `, K7 u% q
  529. /************************************************************************/, A6 r* w( @- g. k) R8 p
  530. /* PROCEDURE:        Read                                                                                                        */
    1 Q* Z+ u/ U# B4 {) d9 V. j
  531. /*                                                                                                                                                */                2 e+ g$ C3 S% G: j
  532. /* This procedure reads one address of the device.  It will return the         */( h  T' P& N) W4 m" ~  E
  533. /* byte read in variable byte.                                                                                        */- C* v$ U; \% H2 R$ ?, q4 s
  534. /*                                                                                                                                                */
      O  {# y0 E+ a7 g2 ^
  535. /*                                                                                                                                                */7 ?- `& w7 F- J- @2 Y+ L
  536. /*                                                                                                                                                */2 y7 L9 \/ t" \" c  {
  537. /* Input:                                                                                                                                */* b9 m4 W' K  _$ g# U, \
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */( Y, \3 J! p7 k( p2 R1 @7 b; Z
  539. /*                                                                                                                                      */
    9 O) W6 _+ v( v6 {% Q
  540. /*                                                                                                                                                */
    1 z/ C& @6 ^+ @) G- f
  541. /* Returns:                                                                                                                                */
    " ^: ^  O; ^# ]6 g  r0 ?. E
  542. /*                byte                                                                                                                        */4 Z" z1 h( ^3 F. ]- Y) D4 a
  543. /*                                                                                                                                                */& }4 L1 m* T* I& e& L" @4 x2 O
  544. /************************************************************************/
    ' F* [9 A$ P6 M/ m! \: E) i
  545. unsigned char Read(unsigned long Dst)   H9 O" c, [9 [  o* s. l& R% ~
  546. {
    ' _/ o" T5 D3 h  Y: }  y( N
  547.         unsigned char byte = 0;       
    % `5 g% o" T; u! m0 f

  548. $ _: h! |2 W5 e
  549.         CE_Low();                                /* enable device */' H+ J% T3 V- F
  550.         Send_Byte(0x03);                 /* read command */- j* p, r' y. t. ~4 H2 L( A
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    3 V# J: |, g2 ]) [3 L# D# U$ @3 s: F
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - P$ U4 P; _* I2 Z! Y
  553.         Send_Byte(Dst & 0xFF);
    8 a, S+ r: X! q: L6 k
  554.         byte = Get_Byte();3 h3 r9 b. \' R0 V
  555.         CE_High();                                /* disable device */& ^& S: T8 H, X3 y, k# A3 \! ]
  556.         return byte;                        /* return one byte read */
    : J8 z8 j8 d5 }
  557. }
    9 G4 W0 f$ X3 L. u
  558. : v# g# F% z+ A0 ~- ?$ v0 R! M$ q
  559. /************************************************************************/' _4 T6 o; H3 s+ k% `1 Z
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    4 X/ i2 H% Q) K; \- e
  561. /*                                                                                                                                                */               
    / X" b- R! e5 D$ |' W$ f  J
  562. /* This procedure reads multiple addresses of the device and stores                */+ O: a) V4 T; a4 K" w
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/6 M/ i/ h" J+ |' z5 O0 \
  564. /*                                                                                                                                                */% W9 z. I+ G1 r: ]. R
  565. /* Input:                                                                                                                                */* z$ `5 \) u# Y+ |- O; T
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : P' @# O8 p( T2 ]' Y$ B5 e
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    2 K) x3 I/ @" D3 G
  568. /*                                                                                                                                                */
    4 H0 @& @; ?  ^0 r% H' e3 e, F- H
  569. /* Returns:                                                                                                                                */5 w" U5 t. g" [7 I( |. T8 C( q" B
  570. /*                Nothing                                                                                                                        */& v# P+ A( f+ R3 r
  571. /*                                                                                                                                                */; [* h  T0 Q+ r* l- g# ?# x
  572. /************************************************************************/( f6 h9 ]0 X1 O0 d1 m  l. ?( D+ t
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    3 ?+ L2 L1 k8 M9 J: q/ g/ x/ R; b6 W
  574. {
    2 q, w  T9 p  |) X
  575.         unsigned long i = 0;
    & X( M6 d) C- k2 R* ]8 R/ h
  576.         CE_Low();                                        /* enable device */: B% @  V& p$ O/ v( h7 l
  577.         Send_Byte(0x03);                         /* read command */
    1 `& F* Z% O. R
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */) g6 w. f. _: ]' O, ~
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));$ j- z6 k9 u  G* x
  580.         Send_Byte(Dst & 0xFF);
    0 A+ [7 G1 I4 \# _7 t
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */- ^6 ^3 F! M: n) w+ W
  582.         {
    , o9 q9 Q' Z6 c- E6 m* G
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    % `5 E8 U  J0 x) c) i. [5 F
  584.         }9 O8 A; C6 i7 s0 ^* a
  585.         CE_High();                                        /* disable device */' i4 \1 _0 k( \/ `( e6 v1 l& z0 Q

  586. * ]  d$ z* ]/ B% f5 x
  587. }
    # S; k; c# l' g* V$ A; Q, q3 n+ T

  588. " }9 Q3 ]! J4 p
  589. /************************************************************************/2 ?. ^' r& \! ?. u3 Y" V
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    $ {. n( o% _# H
  591. /*                                                                                                                                                */                - ^9 i) I7 @) @% F$ g, O7 k
  592. /* This procedure reads one address of the device.  It will return the         */
    5 Y+ B+ D- w" C( I! v. e
  593. /* byte read in variable byte.                                                                                        */
    + G1 ?: I* K' e6 e  [9 l$ I
  594. /*                                                                                                                                                */
    ! l6 J: ~# h' b, [$ |/ M6 Y- t& X
  595. /*                                                                                                                                                */
    4 G, G$ w/ }. N) L! y' N9 G/ D
  596. /*                                                                                                                                                */! P% \( _- }1 F/ J  W0 a
  597. /* Input:                                                                                                                                */
    2 D" f! V% \( t/ f9 m8 B# o
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    7 t6 u# p; X* W3 j. x
  599. /*                                                                                                                                      */. C$ a" F% m9 n) l1 X: v
  600. /*                                                                                                                                                */
    ' f2 @3 f3 U7 {3 v
  601. /* Returns:                                                                                                                                *// F( v) C3 ~# F2 d1 @, D
  602. /*                byte                                                                                                                        */: Q' _: Q5 k8 u
  603. /*                                                                                                                                                */; ^+ Z" V7 D' L0 `3 Y% ?
  604. /************************************************************************/
    ! L0 _1 c* y( J) d% R* s5 V
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    ) G9 P" s3 h2 {  c+ |
  606. {
    * R% W' C) f" B% D
  607.         unsigned char byte = 0;       
    0 L4 j% S8 E7 i0 Q% i
  608. 0 [4 t" r3 c$ f8 e& ?6 A
  609.         CE_Low();                                /* enable device */- p% y+ C: C/ y5 Q% ~: p
  610.         Send_Byte(0x0B);                 /* read command */
    ( L) O- Q8 K( N3 W# `  x
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    # q, j( |3 W, a6 V2 y# S
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & Z1 r, q' ^9 i% N: H1 {& R
  613.         Send_Byte(Dst & 0xFF);( K/ z1 j" ^. o  v  f9 z/ p
  614.         Send_Byte(0xFF);                /*dummy byte*/+ Y% J# l. A! `( Z
  615.         byte = Get_Byte();, m1 ]0 O+ a3 x* U5 |
  616.         CE_High();                                /* disable device */
    6 }  R& B2 ~' X5 r* i: I4 F
  617.         return byte;                        /* return one byte read */& M+ b  \- W- ]0 h& P& N3 D
  618. }
    1 h) F, A/ q8 ]5 E

  619. 8 j! T4 {" {+ q6 i
  620. /************************************************************************/
    2 `7 j" z1 _) r4 p
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */0 B3 j) w& ]6 q% V' y! Y
  622. /*                                                                                                                                                */                7 z3 `! _  l1 K+ U) q! G: L) R
  623. /* This procedure reads multiple addresses of the device and stores                */& s5 k0 o  b; ?% _  ]
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ; N- c) d0 r$ m: d
  625. /*                                                                                                                                                */4 g6 b& ?% D- Y% S/ \6 i& }7 p4 U$ Y
  626. /* Input:                                                                                                                                */
    2 I" `$ E1 N: u0 g- v
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */' n  m3 C# t& v6 m2 w: }6 t/ b6 B
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */# J! u4 R& k. ^' t. K
  629. /*                                                                                                                                                */
    ) F' q! b! Y* K0 {0 J8 F# d+ [, E8 T
  630. /* Returns:                                                                                                                                */% P+ G+ O' `: B$ s/ g) W% Z
  631. /*                Nothing                                                                                                                        */
    : b. |2 K  E& h; @  A8 q$ y; J
  632. /*                                                                                                                                                */
    + V4 u) ?. z* ?0 H$ n
  633. /************************************************************************/0 A5 b3 u5 |1 T+ m. a. |( b* T
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)/ l" F1 Q3 l7 L) d1 L" u
  635. {  B9 e  {( {# [8 p% f3 D
  636.         unsigned long i = 0;$ e! L* {0 K( p) ?' I
  637.         CE_Low();                                        /* enable device *// S' C. x* Q/ S
  638.         Send_Byte(0x0B);                         /* read command */
    $ c. O  M6 b* B7 i+ E
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 u, `# S$ h1 ^; ]
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));6 x5 i/ H0 a9 {) }  [, ~9 u
  641.         Send_Byte(Dst & 0xFF);+ H& _, L# ~+ g( o
  642.         Send_Byte(0xFF);                        /*dummy byte*/* p: R! g: G7 u; _/ Y# R' g
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */& f5 z. i* \  U: X# B
  644.         {
    1 k3 D5 u" D9 E9 t7 q, @
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ) B6 ?0 c. ~/ R
  646.         }
    4 D' t+ D/ i8 P% S7 S
  647.         CE_High();                                /* disable device */
    6 E$ f# ~* b2 Q! Q
  648. }
    " S3 t1 w3 }; i6 w& C5 ?0 i
  649. 9 S# Y9 n2 [; G: X
  650. /************************************************************************/
    2 I# I, a/ Y; t
  651. /* PROCEDURE:        Byte_Program                                                                                        */4 E* `1 y% i5 n. O; }! O. R
  652. /*                                                                                                                                                */
    5 S+ ~  s3 O8 b3 Y+ `
  653. /* This procedure programs one address of the device.                                        */
    & Q  g$ @, H  |) O$ M
  654. /* Assumption:  Address being programmed is already erased and is NOT        */* S6 r& ?8 \2 g: p2 U8 b6 Y) z
  655. /* block protected.                                                                                                                */0 W: K% o. j. ~. T4 k% Z/ c8 O
  656. /*                                                                                                                                                */5 n6 q: j& ^* a  W$ O' v! ]  i
  657. /*                                                                                                                                                */+ B( F* A  c% x8 j2 h4 R" M
  658. /*                                                                                                                                                */
    3 p3 M( t- D* T! Y
  659. /* Input:                                                                                                                                */
    1 Q5 O: g) r2 Z3 m
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, I* t1 a& L2 S4 ?4 U
  661. /*                byte:                byte to be programmed                                                                */' z6 M* H" s' L
  662. /*                                                                                                                                      */' b( C7 q% o) J. t
  663. /*                                                                                                                                                */6 s  U; ?7 C* ?; _: R7 S3 G, A# b5 A
  664. /* Returns:                                                                                                                                */
    * M* v# {0 \2 Y1 T* k, ~
  665. /*                Nothing                                                                                                                        */
    , m, F2 z. e5 B  ?# O
  666. /*                                                                                                                                                */  c; T* `: z1 U9 D
  667. /************************************************************************/" l8 f* g% _) V. |$ n* T
  668. void Byte_Program(unsigned long Dst, unsigned char byte)" j, a6 \' L" `3 C6 @5 t# i  t
  669. {* n4 h6 B+ ?* W
  670.         CE_Low();                                        /* enable device */
    - z9 Z. w- o% |: m; A! J
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ' }7 \  x* R0 L8 ~' C  _
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ( C  @4 F7 y9 P' t
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));0 L; c; ~; H/ A( k* v2 a
  674.         Send_Byte(Dst & 0xFF);
    # V) H) X/ y1 I: L
  675.         Send_Byte(byte);                        /* send byte to be programmed */# o. Q; ?+ d4 s5 t7 W
  676.         CE_High();                                        /* disable device */
      K  P# d, o- l' f
  677. }
    " K# [: O8 D- X0 o, f
  678. 6 \6 a8 n9 i3 m' O
  679. /************************************************************************/+ L, v+ v& p+ z" Y% H
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ; Q- N) z) \' w  p+ A
  681. /*                                                                                                                                                */) b( _2 c  C0 d+ E
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ( y( V% A# ]( A' o
  683. /* the device:  1st data byte will be programmed into the initial                 */) @4 x2 p* B/ J2 W: |7 Z2 e& b; Z
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    : V9 j% G* v+ @5 G% [* M: A
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    / F. j, e/ y' i% ~! V  g- g+ K
  686. /* is used to to start the AAI process.  It should be followed by                 */
    , j" D/ }$ W9 ~7 U
  687. /* Auto_Add_IncB.                                                                                                                */
    . W. {( U/ P# _% t. I% o: K& i" o
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    & [4 ?5 [; o4 j' O
  689. /*                                block protected.                                                                                */2 F1 h2 H; j1 v: z( I4 \6 ~8 i
  690. /*                                                                                                                                                */
    4 c, c1 o+ p6 _$ O( s: `
  691. /*                                                                                                                                                */
    ( ^7 v- g: E) k9 ~
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */% e% y, ~1 t" ^/ _8 f7 i
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */0 N7 \7 f: |# D; ~- }* Q8 I+ [
  694. /*         unless AAI is programming the last address or last address of                */
    2 f" f; R7 ^3 i, ?0 L
  695. /*          unprotected block, which automatically exits AAI mode.                                */- ^; p, x) D' H! B4 ?- Y
  696. /*                                                                                                                                                */$ a5 U  Z( S! N( T& Y7 i! t  ~4 F
  697. /* Input:                                                                                                                                */; m3 U; K# a6 d4 V5 R
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 O2 C- U( ^& k2 w2 u2 m7 @" H5 T
  699. /*                byte1:                1st byte to be programmed                                                        */
    9 M% D. _% E2 m: X- ?' \2 C9 U4 ^
  700. /*      byte1:                2nd byte to be programmed                                                        */& t" q" a1 c4 _. Y, X3 E  a) z( i
  701. /*                                                                                                                                                */
      g5 y9 W9 X& T+ w# j
  702. /* Returns:                                                                                                                                */$ N* F8 Y: d( \2 s
  703. /*                Nothing                                                                                                                        */6 B: _; C1 v* Y1 K6 P$ ~# J
  704. /*                                                                                                                                                */, M- O4 F, Q; a  ~; p
  705. /************************************************************************/* P$ P+ x# p% t) T9 u
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)9 J8 x: u/ \/ I
  707. {
    9 E* R  G7 }4 u8 Q
  708.         CE_Low();                                        /* enable device */
    4 z5 `& \1 ]. C- o, l* W
  709.         Send_Byte(0xAD);                        /* send AAI command */
    0 y, P" H8 o* l: m7 Q
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 {* C- z. |  ~
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));" ^  k9 |: R4 y5 b6 o
  712.         Send_Byte(Dst & 0xFF);4 A7 i5 D! t/ t7 e- ^
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + \& m# R3 u  m4 ^( h
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , Z4 H3 W8 X0 [0 ~' n3 C1 P" Y
  715.         CE_High();                                        /* disable device */
      K& C* Z0 r  u6 }+ C
  716. }
    2 O/ n' ]& ^1 X8 n8 H" {0 Y+ o

  717. : K2 _5 D2 g3 B( T/ |/ `6 b# _
  718. /************************************************************************/
      m# P) U" Y; G! v" [/ K! X
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ' M; b, _/ ]; `; k
  720. /*                                                                                                                                                */7 @, ?+ O' e  S
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    4 K" _5 i9 H7 p- `! e4 E
  722. /* the device:  1st data byte will be programmed into the initial                 */
    9 L0 u  E# R5 x1 O, z
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    2 I  p% K2 `1 q+ [) j1 {
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */" }0 t  D: r  V* \9 t
  725. /* is used after Auto_Address_IncA.                                                                                */
      g) f% |: u' O& R& {- Z
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    3 @5 n0 |1 R. B! X9 w
  727. /*                                block protected.                                                                                */
    6 @5 w2 m8 W1 h
  728. /*                                                                                                                                                */6 Q. y" p2 `# Y: p" }+ |  Q& N
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' H) d. A- N9 ?$ m! |6 h
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ) a+ z" o, i3 k5 ^. P, V* t
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */% z& f! ]" g, W! ~7 {' S% T: s
  732. /*          to exit AAI mode unless AAI is programming the last address or                */" B5 u0 S1 J6 v; j2 t: r8 x
  733. /*         last address of unprotected block, which automatically exits                 */
    & E: o8 h2 I' Y. S9 c
  734. /*         AAI mode.                                                                                                                        */
    ( T: ]8 J4 z5 |/ G* \; Q
  735. /*                                                                                                                                                */
    2 r- y* }. I  N6 B2 X
  736. /* Input:                                                                                                                                */' Z1 B* b: S- ~% o+ c
  737. /*                                                                                                                                                */2 N) |- i0 O4 l  {3 I
  738. /*                byte1:                1st byte to be programmed                                                        */
    7 @8 o4 N$ E% X) R
  739. /*                byte2:                2nd byte to be programmed                                                        */4 F7 w" Q! U: _6 {" w- S& ]( }' b
  740. /*                                                                                                                                      */
    ! e: C2 @9 Z8 k) x' v1 D
  741. /*                                                                                                                                                */
    & z" R, m+ |$ F2 u+ \2 X
  742. /* Returns:                                                                                                                                */$ `* ^; a" A, i
  743. /*                Nothing                                                                                                                        */5 J$ h1 f& g* n
  744. /*                                                                                                                                                */' u& l9 ^+ T6 S( s
  745. /************************************************************************/' S7 ?7 c! @# A$ D2 `% ~% P
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)) P4 Q; N1 e, D* q% n, F* ]! O
  747. {
    7 g% k$ Q7 x. ]9 A. M/ j7 b
  748.         CE_Low();                                        /* enable device */
      G" D: \$ b0 M4 S9 c
  749.         Send_Byte(0xAD);                        /* send AAI command */3 k9 F) V) l! U+ A
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ! K& M% g  J( c; M0 T$ ^0 X
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( A! ~3 y2 N) F' I" q3 q1 ]
  752.         CE_High();                                        /* disable device */3 S. Q/ y8 u' g1 M1 D  n
  753. }# y& M' Q* T: ]& l5 P9 N

  754. - H) ]( O4 v4 t( p7 U  s. x& v
  755. /************************************************************************/0 E* U( I& ]/ G( j) N$ f
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                *// q' b, I. j( g- N8 }( I
  757. /*                                                                                                                                                */5 U1 f  ^& {, ?4 G
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */6 a3 Q& t# u9 e9 t
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */" J% S% G( y! v6 m# J
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    * I. |3 i( i8 g( i
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    7 H3 ]1 z5 d& z2 g7 K$ u
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    & C8 W( y" o2 [; K- `) c
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ( K1 @2 `4 B# `4 [
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */, T- V$ p/ Y; [, t2 a  u0 J2 Z
  765. /* Assumption:  Address being programmed is already erased and is NOT        */: M1 B( K( A  h/ E- j; J( Z
  766. /*                                block protected.                                                                                */. E" }# ^* p( f/ U+ k$ V
  767. /*                                                                                                                                                */
      _/ m- n3 e1 ]! F9 Y( j
  768. /*                                                                                                                                                */) x/ D6 t/ ]  ]6 n6 b+ U) Q
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */, X% l6 f# j% r3 y7 E' j
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    1 [3 D3 ^# B2 t- E: A) |
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. O( Q. I8 r! d
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    ; A- e0 d7 V2 c1 ~
  773. /*         last address of unprotected block, which automatically exits                 */
    4 ?4 \( }5 e7 r5 B8 \4 B
  774. /*         AAI mode.                                                                                                                        */
    0 ?9 d! q' M  s- _3 U, g  Z
  775. /*                                                                                                                                                */6 `$ A" e1 k$ F+ E9 T8 U
  776. /* Input:                                                                                                                                */# q, L/ e' l7 W
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */$ H4 x# z) v7 [% F/ K/ T# W
  778. /*                byte1:                1st byte to be programmed                                                        */$ P# k6 R+ H  e4 @2 n& |5 [! D
  779. /*      byte1:                2nd byte to be programmed                                                        */, F1 v+ q' [& @  d7 g$ `$ a0 q/ N- X
  780. /*                                                                                                                                                */1 l' M5 X% G: T6 D0 c. |! g
  781. /* Returns:                                                                                                                                */
    / g% J9 x8 I, [# y' e5 W+ f
  782. /*                Nothing                                                                                                                        */+ Q0 V2 e. v! H
  783. /*                                                                                                                                                */
    * ^. m, U$ s7 N$ _
  784. /************************************************************************/
    " X  M. |7 M( Y0 @0 b4 L
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ; l# M7 ^# m3 |8 A) Y; {8 i
  786. {8 _, S6 {# f# ~. [2 D( R7 Q
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        ; b% T0 `, X1 R3 U" ^1 S

  788. ) [0 W" {8 `3 j9 r
  789.         CE_Low();                                        /* enable device */; ]$ X, A; }3 B6 j9 ~% Q: G
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ) u; e0 S2 e: }8 Z; x% ?
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * O' Y! P- ]6 U/ _
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));- K* ?' k5 E6 b3 F# r: \! m
  793.         Send_Byte(Dst & 0xFF);
    * G) c. x7 E, D+ {  s
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ; |  q' I- j, X  e- y
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */0 p, \2 w3 b0 o$ G# C; t- M  u$ F7 D
  796.         CE_High();                                        /* disable device */' W/ c' R# j+ G9 ?0 E
  797.         & p# k- `; N8 g6 {! s  r* ?
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    0 T$ j7 j7 t1 l( n" d- z

  799. # j7 S) a1 _. Q/ ]$ B
  800. }
      j6 [& u0 W/ f! k, f& x
  801. ; |. e1 w; g* A' V7 D
  802. /************************************************************************/) c) @2 `+ R- o' q+ @% w# o
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */. v% N; K5 a& z6 Y3 m8 ^( q
  804. /*                                                                                                                                                */! R2 G0 A+ v( Q$ Y$ Z5 f  v
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
      b8 o+ Q# Z) |# Y8 g" `" N! G
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    8 ?/ x) n3 j# L" L
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ! z% |; ~& v8 e" W# S2 @7 i  j7 g
  808. /* the device.  The 1st data byte will be programmed into the initial   */5 r/ J* ?4 k6 p4 D/ [8 a
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        *// _. A+ _& c. L' u/ B% d9 h
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */3 p* i, I8 P6 j/ `( R+ N
  811. /* used after Auto_Address_IncA.                                                                                */8 C! Y4 U4 ~* G$ r# e4 G4 w
  812. /* Assumption:  Address being programmed is already erased and is NOT        */& a2 `( k" o, C1 d/ `
  813. /*                                block protected.                                                                                */2 q) O7 I+ D3 n% d; x5 A, L
  814. /*                                                                                                                                                */
    4 s. n  i6 W$ `$ [
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */: L: Z& }0 O2 V( i# c: m4 N
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    ) A% H- U' d; N+ h
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    $ ]) P0 Y: M4 G( K
  818. /*          to exit AAI mode unless AAI is programming the last address or                */4 b# o$ N! Y$ x' c$ n
  819. /*         last address of unprotected block, which automatically exits                 */
    ; N4 w) A+ q9 x$ I. }" m0 r
  820. /*         AAI mode.                                                                                                                        */
    , m" J4 b$ j: j1 r; k0 ?; B
  821. /*                                                                                                                                                */
    + v7 w; x# D8 Z5 K( n
  822. /* Input:                                                                                                                                */
    " U' M6 s( X/ q8 c' n0 Q; u
  823. /*                                                                                                                                                */
    5 C& ^4 V: t) e
  824. /*                byte1:                1st byte to be programmed                                                        */) u2 A5 t( R, }: W
  825. /*                byte2:                2nd byte to be programmed                                                        */
    7 m& C$ _+ G. J6 m# ^9 i
  826. /*                                                                                                                                      */
    3 R( C0 o7 i0 A/ Z% C4 I( A
  827. /*                                                                                                                                                */
    / B+ H# z- J# X7 E
  828. /* Returns:                                                                                                                                */2 f, D/ Y6 q4 ^2 F  j, x, m
  829. /*                Nothing                                                                                                                        */
    . b1 c( K4 R% ~7 o8 q. e$ r+ t) X
  830. /*                                                                                                                                                */1 A* D  a# r6 z7 w. Y$ l# b: `. Q
  831. /************************************************************************/& E& f/ c; U7 \+ @7 F
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    9 o! |) U( y% T- a, `2 M
  833. {0 c6 S2 O% o6 Z( i$ t+ U: z
  834.         CE_Low();                                /* enable device */
    8 h% Z8 ^/ F0 n* Q& E4 h
  835.         Send_Byte(0xAD);                /* send AAI command */
    9 n4 ]$ O7 f$ F0 j! Z. v% T+ ^
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    0 |3 y9 Y: ^8 j/ s( I6 N
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */* P, F. F9 u4 r% X3 P3 t  X
  838.         CE_High();                                /* disable device */. `& s/ C; \: y7 W7 w
  839. 9 J8 Q1 o$ `6 q  c% q: `
  840.         Poll_SO();                                /* polls RY/BY# using SO line */+ w1 M0 l# Z' ?% Y0 K: o
  841. : V1 C' z% v# f, B
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    - Y7 z6 g- X1 e3 \0 u* z
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    1 i! a, A) [4 M: ], Z" J- m
  844. }
      t% d2 H0 E" E& q( A2 G6 ~

  845. # b+ _( I( w; o- E: k
  846. /************************************************************************/( D9 j0 m1 ?2 a& h9 R
  847. /* PROCEDURE: Chip_Erase                                                                                                */; v; i# P: ]: }0 M, z1 Q' j
  848. /*                                                                                                                                                */
    & Q# f  u, Q2 r/ _1 z$ h6 ?
  849. /* This procedure erases the entire Chip.                                                                */  P$ O8 S) ~- H: W, v
  850. /*                                                                                                                                                */. \; i/ I3 i3 Y6 b! x% Q
  851. /* Input:                                                                                                                                */3 M( Z) g9 U+ n) _* q
  852. /*                None                                                                                                                        */
    , D9 l+ O# V( `2 g
  853. /*                                                                                                                                                */2 q) Z& [2 O0 |  l! L& ^6 {
  854. /* Returns:                                                                                                                                */) K0 K( C9 {/ t% y+ {6 \6 }& y6 L
  855. /*                Nothing                                                                                                                        */
    5 L* K7 v$ J" j
  856. /************************************************************************/9 h6 i1 E6 q! r' G
  857. void Chip_Erase()
    9 I1 @) v" C: S
  858. {                                                5 H' ]( ]6 @! q, e: N
  859.         CE_Low();                                /* enable device */! F$ i: f! S: `" I  R0 h0 x, w
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    + U8 N9 m7 i* W. W
  861.         CE_High();                                /* disable device */
    ; R+ V( n& ?1 {- ^# H) ~
  862. }) u' e, f/ A9 D! ~
  863. - j# M: y: N3 ~; q
  864. /************************************************************************/, o1 C8 S6 W! O9 L5 W* ?1 @/ O
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    7 @8 ^$ I* P& O0 D! z
  866. /*                                                                                                                                                */
    2 d9 N+ F% \, i+ D
  867. /* This procedure Sector Erases the Chip.                                                                */
    4 T& O5 r5 }9 [6 d& {7 P: L
  868. /*                                                                                                                                                */+ m& a% s; x5 B* P! f. H+ q$ P+ O
  869. /* Input:                                                                                                                                */
    ; w6 H( q8 s1 U; C/ T( v
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & w/ X4 H0 V- Y( a
  871. /*                                                                                                                                                */
    : ], J+ z- }1 i( q0 |7 ~5 ~& N
  872. /* Returns:                                                                                                                                */1 {5 c" i$ u: D6 j% ]. H
  873. /*                Nothing                                                                                                                        */( M# k& _' b0 C+ ^* K
  874. /************************************************************************/
      E0 q9 ?" |0 F6 I* J
  875. void Sector_Erase(unsigned long Dst)
    % c' `3 e$ F% ^( g' n. |
  876. {" u; l( [; @- n. s) R: Y+ f/ A

  877. ; H9 X0 {2 x6 [1 o" W8 @
  878. 4 I% c" {2 |8 K; u# @: e
  879.         CE_Low();                                        /* enable device */
    - _, v# q1 I  k% c5 h% r
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    ' z" `/ J- K% _; k: V
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 ^0 h6 T2 B( p; k4 f1 q( }
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));. |2 g  n8 S- T
  883.         Send_Byte(Dst & 0xFF);$ w/ g5 x  q! S$ i  j% f
  884.         CE_High();                                        /* disable device */
    ) D; }9 s1 g- f8 U( ?5 m1 h
  885. }          Q6 G' d3 F& S) X8 U
  886. ( @4 m* \! d9 i9 a  D% v' |
  887. /************************************************************************/8 b% q, D7 X- j* _# N* X
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    : D1 u- T# \4 U& r5 n
  889. /*                                                                                                                                                */9 o; x1 O3 ]. T, j* V
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    ) o( r3 Z: m7 n, X/ l; P
  891. /*                                                                                                                                                */
    ( _; Q) m2 P7 P; Z. d. ]
  892. /* Input:                                                                                                                                */
    0 Y0 F; _) I2 R6 n% ]
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % `+ u2 U5 H# D9 B: `7 D1 ?; B
  894. /*                                                                                                                                                */
    - K2 h) A5 q4 @' V2 v8 q6 L( {) I
  895. /* Returns:                                                                                                                                */0 k( K) i- p5 ]" Z! S4 G4 Z% c
  896. /*                Nothing                                                                                                                        */
    , c1 h" L) [* o; }, t7 ~( F' ]  R
  897. /************************************************************************/! ?; w" q& S) O! i' k
  898. void Block_Erase_32K(unsigned long Dst)+ v$ E. e4 I$ N& c
  899. {6 D( G& |6 Z7 d2 _3 U2 p
  900.         CE_Low();                                        /* enable device */
    9 B  Z# @7 M9 a9 i. c* ]9 D- Z' m
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    / C" j$ i; F  H+ [7 w
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */: b( C. F: r: R
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));  A1 @: O0 s8 Z# v1 E
  904.         Send_Byte(Dst & 0xFF);) J; n' t! p  x" [) i- j& D7 ^  j% S
  905.         CE_High();                                        /* disable device */
    # O  }% q" H- q9 j$ k
  906. }
    * ?5 u0 a, F6 h& b+ X9 g# G2 t

  907. ! b1 R0 F0 V$ c; n: ?. q5 l5 q
  908. /************************************************************************/
    - A1 [1 \# Q+ ^
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    " ]$ N  B: [2 z5 }+ v/ v
  910. /*                                                                                                                                                */) U4 A4 C7 o) r# c% `- C" T6 k; e
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    8 k' u$ c! k0 u) S. W% E
  912. /*                                                                                                                                                */
    4 A4 e+ T' Q! ?
  913. /* Input:                                                                                                                                */
    # \) i6 _5 v8 M$ C1 j  Y
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * o2 ?9 c8 I; f* @/ O
  915. /*                                                                                                                                                */' H2 j6 V' c& C. W, a
  916. /* Returns:                                                                                                                                */
    9 K% \, B" ?, ?& t9 \* d
  917. /*                Nothing                                                                                                                        */
    9 w' C! d  h% j5 J* h$ D7 B3 s' p
  918. /************************************************************************/
    8 @& X' S9 ]0 p. v4 o; {( O( r" r
  919. void Block_Erase_64K(unsigned long Dst)4 e$ q7 n2 {0 F4 {0 _/ J
  920. {% u" T! x( x+ T4 [1 Z# F  ^# f
  921.         CE_Low();                                        /* enable device */. O  K% H/ N/ X. M# x' n$ {* K
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */8 M& J. t0 \. z% `7 x- N
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 D8 r0 N& c  X7 {  g
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));8 J% P2 s: I8 {& _2 y1 _  A
  925.         Send_Byte(Dst & 0xFF);
    6 p. S' h0 ?# {
  926.         CE_High();                                        /* disable device */4 D# x0 O2 N, I1 b% p
  927. }
    1 N( ^6 o+ U1 E3 Y

  928. $ e0 o2 k7 G. o1 r- @  G- i
  929. /************************************************************************/
    0 m* {$ T2 ]9 Y+ a
  930. /* PROCEDURE: Wait_Busy                                                                                                        */1 t- t1 P$ \* x# C, D5 M
  931. /*                                                                                                                                                */
    5 `. o0 V& z$ Z/ `
  932. /* This procedure waits until device is no longer busy (can be used by        */
    + d" F) m8 M# K
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */5 i, B6 B$ S: \+ G
  934. /*                                                                                                                                                */7 }; Z, P+ c; j& _8 f
  935. /* Input:                                                                                                                                */
    3 U# q' u, H# V. n5 R% \, Y4 _
  936. /*                None                                                                                                                        */
    2 {( J2 g+ g) n; L% V
  937. /*                                                                                                                                                */
    # W5 V0 o4 o) l5 A7 `: m. r6 F
  938. /* Returns:                                                                                                                                */& `- m) N; R6 ?% j/ Y; u/ S9 A
  939. /*                Nothing                                                                                                                        */
    3 T9 C; l# g" ]  N0 R% K
  940. /************************************************************************/
    $ f3 K2 j$ W3 L+ U* N
  941. void Wait_Busy()
    , W& a% S4 [+ z1 B: V
  942. {
    # F! L( ]" K& c' M
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */4 a: L8 s: _/ {6 u5 e# c
  944.                 Read_Status_Register();; q; P$ p, c" D( V: v. r0 U
  945. }
    ) S" H, h6 k* h- i# y* c0 z& u0 B

  946. : ]7 f+ j. }: ]
  947. /************************************************************************/
    % n& M; C% h  X  D' Y+ ~
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */3 ?( F! T( _# M0 [
  949. /*                                                                                                                                                */+ i: J7 H0 N& }2 Y4 n
  950. /* This procedure waits until device is no longer busy for AAI mode.        */. y: D/ }4 q' m# l5 |' [$ c! N
  951. /*                                                                                                                                                */' L+ o+ I" s" c8 B- A5 l
  952. /* Input:                                                                                                                                */
    / E8 `5 K5 ~) a4 \* Z
  953. /*                None                                                                                                                        */
    * H7 B) H) @# A2 L
  954. /*                                                                                                                                                */
    ! o$ L3 F) |. Y3 N8 V. k2 q; d' T
  955. /* Returns:                                                                                                                                */
    & u. E9 j) @. ]& v+ I
  956. /*                Nothing                                                                                                                        */, N! V/ Q) I" l1 ^; ~
  957. /************************************************************************/1 w3 M0 J' V+ o* A, e3 Z
  958. void Wait_Busy_AAI()! [8 L6 ~1 i, S% T2 R- N
  959. {
    ; t2 _! {3 ]8 y1 P  ^
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */6 G$ I9 Y9 l( h2 `6 I/ T& W) q+ n
  961.                 Read_Status_Register();6 l" A3 W8 w& I+ I( [
  962. }
    5 g5 [6 Q1 k2 F6 H
  963. " x7 r  C0 t2 h$ j" [0 Z  V# R9 b9 r
  964. /************************************************************************/' n, |4 h; M2 h& ~, D% i7 P1 A% g) H* n
  965. /* PROCEDURE: WREN_Check                                                                                                */1 G5 i. ?) B# j
  966. /*                                                                                                                                                */
    3 B) y7 z- `7 V$ k- x9 y" m, m
  967. /* This procedure checks to see if WEL bit set before program/erase.        */6 X. W( p" k# g0 a) i7 O# L
  968. /*                                                                                                                                                */
    ' ^0 u& _3 u. D' P0 w/ t: D
  969. /* Input:                                                                                                                                */7 D( q" r. T7 [
  970. /*                None                                                                                                                        */
    6 o) x' e' L# N+ l+ T
  971. /*                                                                                                                                                */
    ' D3 _4 z1 ~0 _1 ?$ h2 @, P: D: T: B
  972. /* Returns:                                                                                                                                */5 s4 h, ^& N& u  o$ I: c" l$ d2 I
  973. /*                Nothing                                                                                                                        */5 W& l+ u) U4 W( S/ ~& u9 p2 t
  974. /************************************************************************/0 t6 u8 ]! j7 O* ^; V/ W" L
  975. void WREN_Check()  H+ f7 j9 \5 G
  976. {  [$ l8 g" e/ r% I+ X3 ]
  977.         unsigned char byte;
    ' x) ~7 W: u$ E% i
  978.         byte = Read_Status_Register();        /* read the status register */+ b9 P# I  j$ Z3 {+ v7 s
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ; D( {( M3 j' v3 N& ^4 z6 I8 L3 w
  980.         {
    + M, Z4 |$ ?4 b1 y0 t
  981.                 while(1)5 _( W1 a3 y# z. u# k. s0 ~& i# \
  982.                         /* add source code or statements for this file */
    ( m0 W  j% l$ c( U: m
  983.                         /* to compile                                  */
    ( Q2 D2 k* r% z0 T9 O$ `
  984.                         /* i.e. option: insert a display to view error on LED? */
    8 [9 _3 A& I+ a3 h5 R7 K% N, b
  985.                  9 z$ |: b+ o. o6 W
  986.         }
    * W4 c/ ?# T- z6 b: Y& S: b3 N
  987. }# p( U6 o7 [. s% L

  988. ) I  X8 _' O, D6 ^% h3 F$ `, L, S
  989. /************************************************************************/
    ( c7 W7 Y3 P) Z5 M6 \& `
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */. k. j, O- g" g) I5 D
  991. /*                                                                                                                                                */
    * Q1 `$ ?. V3 R6 L8 v8 d1 W
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    & v, c, ^# w  b4 R* \
  993. /*                                                                                                                                                */
    3 }& k4 e  ?0 I- w' C
  994. /* Input:                                                                                                                                */' T. w; k3 O$ |# W3 C
  995. /*                None                                                                                                                        */, h7 b" W! t# a, p, y7 J" V
  996. /*                                                                                                                                                */
    ( U2 O* r/ T+ @: Y
  997. /* Returns:                                                                                                                                */
    * D) ^  q* q# y. a
  998. /*                Nothing                                                                                                                        */
    9 q9 _9 S- u* _, r/ n0 `! W: Y
  999. /************************************************************************/
    ' M: _9 ?  |# a( K7 d
  1000. void WREN_AAI_Check()
    # o2 d) P' k+ N9 y% ?% }
  1001. {6 F! D% H) z2 V. ?4 |
  1002.         unsigned char byte;
    $ q4 ^9 a+ `9 k, `( r7 Y) ]" o2 q
  1003.         byte = Read_Status_Register();        /* read the status register */2 b6 G  v! l8 ?2 s# o" f: K  g3 z
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */6 U' T5 O% M' }. {) N9 W& s
  1005.         {$ O, X, ]7 V, l, X# C
  1006.                 while(1)                7 Y8 I: e& e4 B7 A$ g# p
  1007.                         /* add source code or statements for this file */
    ' p* y* Y0 t. ^( G
  1008.                         /* to compile                                  */8 n4 Z( ?- I# G2 [6 _2 ~
  1009.                         /* i.e. option: insert a display to view error on LED? */& C+ j) S( V7 v5 q9 y1 A

  1010. ' [4 R2 J' |% N  f
  1011.         }7 S; C: e/ i2 u/ H8 _
  1012. }, M, p# g* U: r+ e- E) @9 X! T
  1013. . j3 l! N" F$ k0 b7 [
  1014. /************************************************************************/
    & [! k+ V5 N6 \% R
  1015. /* PROCEDURE: Verify                                                                                                        */* b* \6 r$ K& E& g3 l4 R" u
  1016. /*                                                                                                                                                */: o9 j- k; I0 @. z( F2 I
  1017. /* This procedure checks to see if the correct byte has be read.                */+ _( I$ G1 S6 A; [! K5 C5 z) }
  1018. /*                                                                                                                                                */
    , ~; \( o) g! I
  1019. /* Input:                                                                                                                                */
    ! e8 e7 ?! M" l! T' q9 e
  1020. /*                byte:                byte read                                                                                        */
    0 u, L. O- k$ V& P+ Z
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ; z* U* q  L% o5 i0 ^7 z
  1022. /*                                                                                                                                                */
    $ U4 F3 J5 v1 }' S
  1023. /* Returns:                                                                                                                                */* C. J* z) h0 p' F+ ~' p
  1024. /*                Nothing                                                                                                                        */( Q# c1 c( n8 @/ U) K' K0 u
  1025. /************************************************************************// C6 [! M2 c6 I- O
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    ' b! \9 E* J  q; }
  1027. {
      {0 @& Y: k7 t9 P' z
  1028.         if (byte != cor_byte)# s- u) N( ]* |) I
  1029.         {4 o# b1 d' w0 U  ^$ {: \
  1030.                 while(1)
    6 X/ O0 Y; [4 x1 D: H
  1031.                         /* add source code or statement for this file */
    2 @- r- v( q& @# a
  1032.                         /* to compile                                  */
    0 \9 s# k9 l1 U
  1033.                         /* i.e. option: insert a display to view error on LED? */
    : L8 j3 e" o; h9 K! y' M) J
  1034.                 5 `6 j6 I" w/ @+ Q* o; a6 h
  1035.         }2 g* [8 x% ?7 b2 @7 p8 E
  1036. }4 |3 d- T9 N) H

  1037. 3 _+ @$ h. F* E7 e0 l1 S4 s
  1038. / c) L8 |7 ~  k( L9 A/ X! l  L
  1039. int main()3 E7 y; e. W2 V0 i5 S# _, G4 u
  1040. {
    ; k3 I9 x- Z5 H% ?4 A' G% X

  1041. : E  w0 [  |. L
  1042. return 0;
    0 @# X# A" v5 t6 R) x0 Z
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
. ]5 O# ]! Z& ~7 M( D   main()
4 C1 S' \% {5 Q4 F   里面怎么是空的呢?
- E5 \* t' M, y8 u& Q4 V, V   发一份给我吧+ ]4 ]+ f* s$ U) i9 T
mail:luyijun2005@hotmail.com% L- @& Z% p. L+ s- k
咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
: g4 @8 i# O! ^; E# t
/ t. m/ V. z' x% ~; H" x: 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)里有。3 O; ]5 d# M8 `* ]5 r# n) i
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
6 _1 t  `) _+ d' [4 s* n, `4 EOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
4 L4 v9 }6 {; l$ @上面几个问题是你没看任何东西而白问。8 ~$ n" J1 v0 I  D. U! Q

3 S  g: k' _! B* @9 m7 c至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。2 W; S( k/ r- D$ \* e0 r  b0 U5 W$ U- D- T
5 [0 ^7 J0 I9 p" _7 o
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!- P& V0 ^" F$ R# S* `: p3 H
. _& I+ _1 p0 d& p9 }. I
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”6 [7 r) Y; i4 ~9 p

1 I, j+ {  g9 k2 D! w' }关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
- k' x, h, ~  {1 h& p
. t1 e  s( b: {) D3 `: ?不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样7 @: |7 L  w7 b: }) }
似乎要把SPI能support 到最大,这EC chip应该有好卖点
% N" m. ^, V4 }BIOS功能要不要强大,也就决定了SPI Flach的大小* J7 o8 N& O8 v! C) _/ u( J
我是这么想的~让OEM去决定要挂多大!# B% d" [; J, W1 h) O
如果我司有BIOS工程师就好了~哈
+ r" v1 B, }# C4 G6 b* zWPCE775应该算很新的东西,来看它支持到多大?
8 a% M' m9 H) W- Q* k
; s7 f" x7 x$ }+ ]. A另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
. {7 W* W9 K7 K: X# t其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.# U: k; [4 T& ?& F

1 |! B: j* u2 _3 g& x7 i7 w这份driver收下~希望以后有用到
8 j( ]" A% s- ~5 C% `谢谢bini大大
6 g, _( N8 p) D9 v( T$ r
1 M2 ]: r+ ]. b' w4 T* B, v很新很新的新手,如有错误请指正 (准备看第二家的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()5 |4 {8 e# T8 {$ Q+ r6 H$ e
{
( T% F% O6 L: Z        unsigned char temp = 0;& \  {9 s' R% Y" b: C6 L
        CE_Low();2 j; i# C2 `4 p, m. O! g
    while (temp == 0x00)        /* waste time until not busy */
6 x) x# `5 a* N8 l: x+ g                temp = SO;
- E# \' a  [$ g8 F        CE_High();. c* u! e2 B7 B) v
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)' h7 D' V% R, z/ k4 R
{- f% F9 h* @6 [8 @$ `  t
        4 N2 k2 B8 W2 y7 k
        unsigned char i = 0;
8 v& \, l* j  z# I        for (i = 0; i < 8; i++)% t+ z6 O5 X" Q& z+ S7 K8 N! _+ u  ^
        {
! s( P" v6 r# e: K                1 ~3 X0 P1 @4 n( M% n: ]
                if ((out & 0x80) == 0x80)        /* check if MSB is high */  m: p! E4 B. D! \2 _: |* k
                        SI = 1;- u5 }, W+ h* z3 s: q( N% B
                else
3 o& q; b6 ^; e' a0 a7 o                        SI = 0;                                /* if not, set to low */; U% t' N: D6 p
问              SCK = 1;                                /* toggle clock high */! x- `" V$ r* P8 C; {4 Y0 p
   题            out = (out << 1);                /* shift 1 place for next bit */
1 m) a  `# c  M' b7 G                SCK = 0;                                /* toggle clock low */9 W& k; T# T/ i! d. B
        }  s7 ^4 a% V: b! i# E) x
}7 M; r% j6 A2 O' Z/ `9 o
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-4 14:41 , Processed in 1.836013 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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