找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55990|回复: 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% X9 z, Q! V) s1 L" C

  2. ' z0 P  E! x$ e1 U6 s
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    4 p) A( {( W, H5 K9 A- F1 f
  4. . P3 `* T# s! @; Z. L7 G1 g
  5. November 4th, 2005, Rev. 1.0) v$ i0 z# ^- O8 I3 H8 T, @. P
  6. ; e& ]0 E- H  _
  7. ABOUT THE SOFTWARE7 n2 N8 e5 p. _: ?) N# g  ?
  8. This application note provides software driver examples for SST25VF080B,4 h' A! x" M% h/ L! G& G9 I
  9. Serial Flash. Extensive comments are included in each routine to describe 8 i: b" d1 E/ R/ ?8 D
  10. the function of each routine.  The interface coding uses polling method ( X. B; k* l/ |" N
  11. rather than the SPI protocol to interface with these serial devices.  The3 M$ s3 |+ g; l: D, s
  12. functions are differentiated below in terms of the communication protocols
    6 w- f, M! ~9 R
  13. (uses Mode 0) and specific device operation instructions. This code has been * `' P# c! W* M0 m9 h! ~
  14. designed to compile using the Keil compiler.; ?& i: n# I. A) K
  15. 9 l2 I2 ?" J" o+ A( r
  16. & B/ r( [' }5 |$ O6 H0 {2 `
  17. ABOUT THE SST25VF080B
    7 b$ c: M7 e( {" Y2 }) K; j/ o1 m7 f, F
  18. ) B' R4 @! y( n% `. d$ D  N0 m
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    3 r( }: e% G! l, C0 s7 \' W
  20. conjunction with this application note for a complete understanding 9 ?9 U% ]+ j! N* E
  21. of the device.( D/ g4 l3 |! Q6 S1 ^5 \! v
  22. / l2 y9 `0 w$ Y* l- @) A
  23. 2 |. p5 G  r& B
  24. Device Communication Protocol(pinout related) functions:( J9 b# F$ Y0 A5 g  m5 D
  25. ' i& B9 b" u3 N$ J* f
  26. Functions                                    Function, F! L2 O' d# G+ j$ v$ u( t
  27. ------------------------------------------------------------------5 G2 [! u0 c! A8 U" |
  28. init                                        Initializes clock to set up mode 0.
    ! r1 ?. Q  L* P  \& ^# x& ?
  29. Send_Byte                                Sends one byte using SI pin to send and
    - q2 w9 R: x3 J/ f" b8 C* S; r2 s
  30.                                                 shift out 1-bit per clock rising edge
    5 b( V" f& L8 V3 P% k6 w* d! d
  31. Get_Byte                                Receives one byte using SO pin to receive and shift % U' i1 e1 g3 C% w) P
  32.                                                 in 1-bit per clock falling edge
    # E. P/ ^# p/ R: g
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
      ^7 ^: J0 m4 J
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high1 n; F9 e1 D2 N2 B7 A
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    9 M9 ?) a# X8 |" Y" P9 ~! Z
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    7 Q) g; Y" s( P3 b
  37. Unhold                                        Unholds the serial flash. z0 c; R# h# b! j5 b3 p
  38. WP_Low                                        Clears WP pin to make serial flash write protected/ ~% M& D; b9 R- _5 N3 N
  39. UnWP                                        Disables write protection pin6 h% ^; @7 N9 ]2 q

  40. ) l4 I7 `3 M  S
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ( a8 k  M9 G5 v/ p- {) N  O- A
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    9 k; P7 {4 T1 S  d. d. d
  43. software which should reflect your hardware interfaced.          - `+ k- n+ Q) S
  44. 6 T4 g; {5 b3 i+ S. c/ _0 n: `" I

  45. 8 \/ b/ f) a3 n6 ?, r7 O) {) I! t
  46. Device Operation Instruction functions:
    ! X3 O. G9 f* m# o

  47. 3 W' ?  K& s. `+ x3 D
  48. Functions                                    Function6 l% }9 r& b/ J, A+ p( g
  49. ------------------------------------------------------------------
    ( Y, X* U' ^0 [2 |' g
  50. Read_Status_Register        Reads the status register of the serial flash& M7 O7 @/ Q' ^  }7 ?- G9 w8 S
  51. EWSR                                        Enables the Write Status Register. @: c- _5 @# `% S0 P/ z. w+ D
  52. WRSR                                        Performs a write to the status register: {' p% }( B  |
  53. WREN                                        Write enables the serial flash1 r, l6 Q5 C- i% d
  54. WRDI                                        Write disables the serial flash" \+ {: v1 Z' G
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    0 {. E+ h* C( L! y" G
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    4 d& T3 U: H* w1 k1 h1 I
  57. Read_ID                                        Reads the manufacturer ID and device ID8 U( w* ]. T2 S& S: U
  58. Jedec_ID_Read                        Reads the Jedec ID# A; W( M# H) N* S/ [) l
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    - i/ F# s7 D; F1 o/ l8 ^. i
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)- _+ I! G0 @: Y8 ?! u
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    - R- M: K! k5 M8 {9 L
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    . |# K; _. t" K5 @7 B
  63. Byte_Program                        Program one byte to the serial flash7 A% Q8 ?  V( C, I. ^7 ]5 g
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    / S4 `" j3 v0 Z/ V' V" ^
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation3 x9 Z! t& p. I. q$ i
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY. V8 `8 a+ t) W2 P
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY# S# n; m6 {9 q1 M2 q! Y) }
  68. Chip_Erase                                Erases entire serial flash9 Z" \7 n# L0 i  [: s6 q
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash+ B2 n) @. p$ j# m
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash" P: y8 V+ O, p3 H! j& G
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    3 T3 \$ E3 p5 Y! X' E
  72. Wait_Busy                                Polls status register until busy bit is low
    5 D/ M' O# J: h9 }, f+ Q5 t
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    , q/ j% K2 C# H2 d
  74. WREN_Check                                Checks to see if WEL is set7 F# x+ R9 J: L+ _! g. X' I
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set: }: }! E: y2 F1 w. ?1 R: K6 J5 p

  76.   Z  R7 C: }4 {+ S! @' _7 V

  77. 2 F0 i! a! l9 g' e' l$ z* P/ w: }0 k: t; s
  78. 2 @: V( h. X* g7 o; e. \% Z
  79.                                                                      
    $ N: f# q' ]1 N/ t3 v2 n' ^
  80. "C" LANGUAGE DRIVERS : i# X) X3 ]; b. `% r

  81.   R, B# a# z; l5 y
  82. /********************************************************************/
    / d# W  s& ^* _  ~  l
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    1 K$ s. W) J) z7 b
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    " I: ?) b2 c. K9 n6 Z
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    % P7 d4 o, S$ g" _8 O6 t
  86. /*                                                                  */
    # S# Q  w8 T7 ]2 g
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    * U8 O+ r2 _' v) s4 q: Y
  88. /*                                                                  */
    3 y/ H7 v5 G/ v% F5 n0 a. P- {' T
  89. /*                                                                                                                                        */
    5 S' C" \  s4 M/ d' ~0 J
  90. /********************************************************************/
    ! ~4 N( l, K( v3 ?
  91. ! E* F; \8 p0 m5 p
  92. #include <stdio.h>. L# }5 b6 _4 V5 j* _
  93. #include <stdlib.h>
    ( e4 j& A9 N' e2 c1 {  ^/ ~' P

  94. % Z, ?: O+ [) `9 d' b7 F
  95. /* Function Prototypes */, a! W# b1 _/ T4 H( |% ~7 Q
  96. 8 M  g( p5 G% o7 a' F
  97. void init();
    2 `- O; s* p$ p$ K/ G
  98. void Send_Byte(unsigned char out);
    * x* J2 \: u% \' t; P  r# K
  99. unsigned char Get_Byte();: a3 d& s0 \1 C/ y, Z' H3 n7 q
  100. void Poll_SO();9 \. c/ q8 k' A6 s9 Z9 d
  101. void CE_High();
    $ }/ Z. [. c* Q
  102. void CE_Low();8 H. K) G7 h/ t% H0 D( S( S
  103. void Hold_Low();! A1 V5 l8 r( G5 \2 M
  104. void Unhold();& k# c0 P- z7 S2 ]% c' y
  105. void WP_Low();
    ( [4 B: W5 p" s$ O5 t0 \8 ^
  106. void UnWP();* `" i* R8 @7 o. P/ t- ~" N
  107. unsigned char Read_Status_Register();4 w2 s% a- p5 ]& x
  108. void EWSR();
    " f9 P* Q& f2 o; x* q
  109. void WRSR(byte);
    . C0 k0 a1 [0 J( e; W+ p; Q9 v
  110. void WREN();
      |- C- @! [# O. _; f- D
  111. void WRDI();
    6 D1 k: \  }! ~' p4 I) n! e; e" C
  112. void EBSY();
      @+ g/ x7 E! }8 D  l
  113. void DBSY();  v8 Y+ P$ f7 _" @. Q9 L3 ~9 z
  114. unsigned char Read_ID(ID_addr);
    0 c; B, O2 V5 `: p" ?: |, Y& Z
  115. unsigned long Jedec_ID_Read();
    # b- k% u$ d! G# h
  116. unsigned char Read(unsigned long Dst);
    7 X8 e! n7 S1 l6 Q+ l
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    " U1 r- ~5 A% \% \& q$ N; @; A
  118. unsigned char HighSpeed_Read(unsigned long Dst);   n0 }. Q0 a2 ~' Y. v4 q
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);7 M9 X8 c) r; t. K& `( b. x5 K
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    5 y  p' x4 B0 b4 c
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);% l7 k5 Q9 m7 {2 b
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);+ n7 H( h% [  z2 V, k
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);# I+ k/ E3 T4 O$ W* ?! l
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);1 W, h$ J( g! Z. \
  125. void Chip_Erase();. J' v; [, n* e  G6 n! Y& i1 }% G8 T
  126. void Sector_Erase(unsigned long Dst);+ b0 X9 ^6 r0 ^" d
  127. void Block_Erase_32K(unsigned long Dst);
    ! F, m( Z' p3 n& ]
  128. void Block_Erase_64K(unsigned long Dst);* W% u9 z* i7 v; h0 p
  129. void Wait_Busy();( Y7 Y6 J5 Z  E* _( f5 N
  130. void Wait_Busy_AAI();
    + {4 l$ e- p' ~9 j  ]
  131. void WREN_Check();
    + B0 f3 R; `7 u& X3 H$ f" U3 `7 l0 W
  132. void WREN_AAI_Check();" I& T) A* n' }, J

  133. ' m) l* s& V& z. g8 Z1 [
  134. void Verify(unsigned char byte, unsigned char cor_byte);8 B7 E  J' i# K+ B
  135. 9 u5 A, V& g- z7 a1 {
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    6 b( p6 k3 k% s9 n6 Q# p& K! G
  137.                                                                                 /* to upper RAM area from 80H - FFH */- r7 V- I/ h7 q- K, p/ r1 C2 V
  138. 0 B: o9 W# y! ]+ r( d; `
  139. /************************************************************************/
    4 f% W7 g, `6 b. d
  140. /* PROCEDURE: init                                                                                                                */
    5 N# j  D" b5 ]( n
  141. /*                                                                                                                                                */
    - C: `$ E! K: Z2 z
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    4 b" L. u* Z# L
  143. /* setting up mode 0.                                                                                                        */8 X7 s& W  J  j" r9 S7 B3 U
  144. /*                                                                                                                                                */: V/ Q0 |1 ^' w* ~; ]+ a
  145. /* Input:                                                                                                                                */
    ' B, j3 C/ g- c: |6 I
  146. /*                None                                                                                                                        */2 z5 j, G3 `  X
  147. /*                                                                                                                                                */7 s+ J+ |# z& [% J  \  H: Z
  148. /* Output:                                                                                                                                */
    2 d- q" p$ l3 {4 i. u9 A% B
  149. /*                SCK                                                                                                                                *// n# z6 m6 [/ S: {3 ]* }
  150. /************************************************************************/' \: V3 |/ e& w
  151. void init()3 [" `$ B9 \: q9 p# u: l  P
  152. {0 H3 |& b1 w5 W8 S' J
  153.         SCK = 0;        /* set clock to low initial state */
    . b, }7 I$ P( n( L- o& y
  154. }
    4 a8 ?: z7 w) r2 }

  155. 7 C: U- e. l. U% b( ^  y
  156. /************************************************************************/4 e) T1 S# a" n, X- K* M4 |) q
  157. /* PROCEDURE: Send_Byte                                                                                                        */' c  K# O9 |+ i; [
  158. /*                                                                                                                                                */4 T# J: ]0 M  e- q7 q0 K9 X" o
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */1 S' y+ l/ F* G' N- W" W
  160. /* edge on the the SI pin(LSB 1st).                                                                                */- T6 I' Q" @% g6 w
  161. /*                                                                                                                                                */
    " [# L. m8 J2 u3 k3 b6 F
  162. /* Input:                                                                                                                                */
    5 h& H' d* V% R: D) g
  163. /*                out                                                                                                                                */% V1 d+ w: d1 s" Y
  164. /*                                                                                                                                                */
    . S+ `" d! r* a9 h, B! _' C9 ~
  165. /* Output:                                                                                                                                */; r/ L6 ]8 B! S3 Z8 |* _2 ?5 e1 I
  166. /*                SI                                                                                                                                */
    & P7 n, s+ N) p
  167. /************************************************************************/& I8 W  |, [1 p0 B# h, M: f
  168. void Send_Byte(unsigned char out)
    ( @) x% z9 e# h
  169. {
    2 V; N+ e) R0 S& ^* E% B
  170.         - z" \3 f) a  A
  171.         unsigned char i = 0;3 l$ \& y: [9 n( w6 s
  172.         for (i = 0; i < 8; i++)
    8 x& ~8 f. W9 n( ^7 d9 ]5 d
  173.         {
    6 q3 _. h4 y( ~# y1 v' c4 A
  174.                
    ( h- W3 W2 I& V1 G8 s
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    + R* L2 s; O# K4 m
  176.                         SI = 1;) |% H. g$ _' e/ y5 \& O. f
  177.                 else6 M, `1 d+ z/ h. V
  178.                         SI = 0;                                /* if not, set to low */% C9 v- c5 h" `2 o8 h* z* x' S# K
  179.                 SCK = 1;                                /* toggle clock high */& {9 q. P/ N6 A( \! U1 n$ ?
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    : d5 p* ~; }5 J3 j
  181.                 SCK = 0;                                /* toggle clock low */# N% ^" f. z; i0 d$ l
  182.         }9 _- w3 P1 @: k: Z/ L! n1 b1 a2 f
  183. }% `; K, P2 w7 f) a- Q
  184. " d. i; Z' k: k: V! o; D; D
  185. /************************************************************************/
    / ]  B( d9 f+ H3 K9 D2 [, V
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    5 H8 C  }7 B/ l7 N0 i6 i: B
  187. /*                                                                                                                                                */: u3 `( Z2 `0 E2 Z( c
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */& C* k: d; G9 y6 X6 y6 C5 H5 E
  189. /* edge on the SO pin(LSB 1st).                                                                                        */9 S$ P; o5 m8 c" P1 X4 b2 f2 h
  190. /*                                                                                                                                                *// R  O  Q# m1 V4 W- q
  191. /* Input:                                                                                                                                */
    ( }; S2 j- `3 w2 ], Z( ?
  192. /*                SO                                                                                                                                */
    . R. @# g; C& i4 U: A
  193. /*                                                                                                                                                */9 z9 B4 o6 s. J/ Z, D
  194. /* Output:                                                                                                                                */
    $ e) {/ _6 E7 @  P" c5 k
  195. /*                None                                                                                                                        */! p% w# R4 T* C4 {* r9 _2 Y
  196. /************************************************************************/4 U4 {! [  r3 s3 z4 H' f0 K
  197. unsigned char Get_Byte()
    3 ~; e! \9 a( e8 y! h+ q
  198. {7 b1 A- L" Z) d" c
  199.         unsigned char i = 0, in = 0, temp = 0;2 {& Y6 C% D7 c$ u' ~) m8 h2 @
  200.         for (i = 0; i < 8; i++)& T0 r/ l$ v  }" H6 K6 F
  201.         {
    1 r. m( d4 F# Z: M4 Y
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */& s1 X, y7 s# g! k
  203.                 temp = SO;                        /* save input */1 K7 v% J9 Y5 M4 h& i% l. |0 A
  204.                 SCK = 1;                        /* toggle clock high */
    2 N4 \6 |) S! @- t' F
  205.                 if (temp == 1)                        /* check to see if bit is high */7 l! C* X) b6 g7 z% X
  206.                         in = in | 0x01;                /* if high, make bit high */
    # ?& u+ C6 w+ ^( Q  w
  207. " k! o' Y* {, V1 a1 N
  208.                 SCK = 0;                        /* toggle clock low */
    % Q  B' Z9 d, y7 }
  209. 8 d1 U" J( `$ |1 G: m# W% W
  210.         }
    7 M% y* @% ^( b0 ^, [9 r$ w% D
  211.         return in;
    ; k9 ^! ~( m0 Z. A( b: Z
  212. }, N" ?+ J2 ]: I5 }" W( w- i6 m. C

  213. 0 Z7 b7 o$ _1 J7 g. G" }. k
  214. /************************************************************************/& Q' k/ h. e& I& J1 p8 }8 {' ~
  215. /* PROCEDURE: Poll_SO                                                                                                        */" r  ^& I  Y" j+ n
  216. /*                                                                                                                                                */
    & m; I  ]7 k5 j( O+ G
  217. /* This procedure polls for the SO line during AAI programming                  */* X6 K5 r9 r, }1 h3 P6 ?
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    2 v% ]$ N6 ^9 i" V. v
  219. /* is completed                                                                                                                        */$ W4 P. g6 h, v
  220. /*                                                                                                                                                */
    ( j/ U6 q5 d( {+ G
  221. /* Input:                                                                                                                                */* ]: \5 U4 c2 q- x
  222. /*                SO                                                                                                                                */
    + `1 n. l6 ~0 I% ]5 @: N
  223. /*                                                                                                                                                */
    1 Q$ u% V2 Y( o7 z+ x% j
  224. /* Output:                                                                                                                                */& |7 W% e' C% i/ T+ S
  225. /*                None                                                                                                                        */
    * t, g1 S! y: O
  226. /************************************************************************/5 j0 r/ A9 n  H  w  ?
  227. void Poll_SO()
    , J, D1 v# T3 [
  228. {5 E$ P6 T8 F4 q6 V7 k: U$ m/ k2 f* ^
  229.         unsigned char temp = 0;, j1 ^; ~7 A6 l5 E4 U
  230.         CE_Low();
    & c; O$ X* p# \$ K
  231.     while (temp == 0x00)        /* waste time until not busy */
    5 e. d( L0 N! Z; j" z3 t3 B& m
  232.                 temp = SO;
    3 ?5 c: }& N- {8 ]* ?0 G- x
  233.         CE_High();
    , |' C& Q9 C( s- a" w9 B
  234. }: ~2 S7 b3 p: D( M5 e
  235.   s8 W. x2 _. M. ?% T! p
  236. /************************************************************************/7 G  ^9 [. A2 @# \& W
  237. /* PROCEDURE: CE_High                                                                                                        */
    " i' s, c2 ]4 l1 {# V) L- e
  238. /*                                                                                                                                                */# G! _7 H$ t! F; k7 ~$ ]
  239. /* This procedure set CE = High.                                                                                */
    2 X; g# X' k+ E& n: \6 D! T
  240. /*                                                                                                                                                */
    $ M9 y, P7 L$ g7 n2 A( e6 M8 `! s. v
  241. /* Input:                                                                                                                                *// I( Q2 f) e6 p/ r1 W3 D1 y* @
  242. /*                None                                                                                                                        */
    6 i& ?  R3 b: l6 g
  243. /*                                                                                                                                                */
    3 n0 R; I8 s! y0 [3 K' y2 [
  244. /* Output:                                                                                                                                */
    + b2 T, W' Q& _1 D$ j/ y4 c
  245. /*                CE                                                                                                                                *// @1 x" d! ]- d& F7 G
  246. /*                                                                                                                                                */
    ! R/ x7 Y4 ~6 ~- v: M! ]# D7 V
  247. /************************************************************************/
    ! W+ C3 ~! W, P4 y! ^2 o
  248. void CE_High() * x" C1 u* _: b" |1 X0 n
  249. {' X- K: l- |& Z5 E* i' n7 j
  250.         CE = 1;                                /* set CE high */
    6 Q' t) K8 v' _. h/ v# Q
  251. }
    - N' U0 |2 _  L/ o( V5 P

  252. ; X, a/ P/ |( N( r. L
  253. /************************************************************************/
    8 }3 {/ P9 W; l- D: s4 [) U4 H
  254. /* PROCEDURE: CE_Low                                                                                                        */
      s  \+ ]) P6 E! T$ v$ d% F# \7 b
  255. /*                                                                                                                                                */
    % H9 g- S7 j* G+ \6 J. L
  256. /* This procedure drives the CE of the device to low.                                          */
    & E8 t2 n$ X0 Q- i0 i4 l
  257. /*                                                                                                                                                */( e* K! Q- q% c: `
  258. /* Input:                                                                                                                                */7 q* F' m; H+ ~. G
  259. /*                None                                                                                                                        */
    2 }& ~' m/ T6 r* V: z1 `+ t
  260. /*                                                                                                                                                */
    ! D% @/ W" f7 [' Q7 S: i: A
  261. /* Output:                                                                                                                                */
    * Z/ N! K0 v6 Z( H- a
  262. /*                CE                                                                                                                                */. y8 _: _4 }- `
  263. /*                                                                                                                                                */% L- t5 ^% b3 ~, F
  264. /************************************************************************/. ^# @% P# Z1 _7 ?) Z$ ]! L
  265. void CE_Low() % ~" Y! S. g8 F7 D3 |2 G: `( C
  266. {       
    8 X- h3 c% i8 U4 a
  267.         CE = 0;                                /* clear CE low */; ^  z' f% L" {3 q( Y. B2 Y
  268. }, n4 u7 @5 e5 {: d8 b- k

  269. ! {: o; H, x( Y. ~5 O3 |) d
  270. /************************************************************************/
    # K8 j+ V# `+ w# d0 z  G$ [
  271. /* PROCEDURE: Hold()                                                                                                        */3 D, O- ?9 m( b
  272. /*                                                                                                                                                */
    4 |/ L1 o* N$ h* S; d7 q, v
  273. /* This procedure clears the Hold pin to low.                                                        */
    " N3 z, T5 e" s% o0 e4 Y2 E
  274. /*                                                                                                                                                */
    3 P* M- ^0 d: F5 A
  275. /* Input:                                                                                                                                */
    " W. c7 y* U7 I
  276. /*                None                                                                                                                        */
    6 ^  Z, ?' T" X
  277. /*                                                                                                                                                */4 \0 x0 W9 ~+ H; @+ @$ k  M
  278. /* Output:                                                                                                                                */5 l0 C* U' i; J8 d
  279. /*                Hold                                                                                                                        */* v7 G" ]9 [* z+ ?4 C: o
  280. /************************************************************************/
    + c4 a, @$ i- S
  281. void Hold_Low()
    9 V9 o- O" q  {3 C% b1 A6 s& G; f% e
  282. {
    6 l1 r2 `7 T1 A2 Z+ B- G2 D
  283.         Hold = 0;                        /* clear Hold pin */. L* [0 L' B3 x  O7 T
  284. }( a6 @$ Y5 s3 F# s/ _; I1 y+ O4 t

  285. ' L! |0 d$ d; O' s% D9 D
  286. /************************************************************************/( G6 N& q2 Z+ c' v3 w$ t
  287. /* PROCEDURE: Unhold()                                                                                                        */% N4 B3 t( f1 t
  288. /*                                                                                                                                                */
    % G2 H4 f% ?, q8 P( e+ v, c
  289. /* This procedure sets the Hold pin to high.                                                        */5 a  N4 u# q7 u: N
  290. /*                                                                                                                                                */
    0 e6 a9 \% ^1 M1 L& q9 E- I, K
  291. /* Input:                                                                                                                                */! F8 N0 ?  w% b) c3 }
  292. /*                None                                                                                                                        */- G( A- P' N0 U7 z+ F3 |6 X
  293. /*                                                                                                                                                */' h( }5 Q% O+ S: U) h7 |
  294. /* Output:                                                                                                                                */; S# |" v1 o5 O$ O  {% z
  295. /*                Hold                                                                                                                        */
    2 T- \& G* q* l; \, V$ s
  296. /************************************************************************/
    2 {, ?% p$ k/ L  h5 S  K
  297. void Unhold()8 G% w+ s0 B1 j* q6 l1 y
  298. {9 b; L& E2 Q. ]  Z3 O  i: R; x
  299.         Hold = 1;                        /* set Hold pin */6 ^8 _- S2 ~3 [* T
  300. }/ l& U0 i! s9 y

  301. . J% a* }" V7 V3 ~$ \
  302. /************************************************************************/* V0 P0 W. g# \8 Y0 B
  303. /* PROCEDURE: WP()                                                                                                                */) I/ Y- V/ q, X+ _) U. Z0 r
  304. /*                                                                                                                                                */
    2 l- h% `0 m! N0 T* S
  305. /* This procedure clears the WP pin to low.                                                                */
      N+ H+ t  N! e' f. i
  306. /*                                                                                                                                                */
    9 E6 N2 q/ i. d% n  }
  307. /* Input:                                                                                                                                */
    # R- b- q$ w* P: w: [& C. g# L) |
  308. /*                None                                                                                                                        */) y/ }; V4 F4 F1 ^  n2 p# P
  309. /*                                                                                                                                                */
    - t8 P1 {5 Y$ ~8 Z0 \: ]
  310. /* Output:                                                                                                                                */
    ; o0 |- V, T2 z' z1 }1 w$ |
  311. /*                WP                                                                                                                                */* s7 r- M4 J# M; |7 V
  312. /************************************************************************/7 M0 S9 D4 `! s
  313. void WP_Low()! l; y1 ~& p7 V) L
  314. {
    9 g  [) g$ [; R! ]4 l' z) y/ V
  315.         WP = 0;                                /* clear WP pin */* R2 }; m! M2 F8 ]/ Q* |
  316. }
    1 ]4 J/ Y# P3 Q1 f" k

  317. / [, `$ M) \+ x% H3 V% ~" N- r
  318. /************************************************************************/
    0 _( W( E# j' k& c
  319. /* PROCEDURE: UnWP()                                                                                                        */- c+ \- j7 w) o2 S( v
  320. /*                                                                                                                                                */6 k7 L2 M9 [' [3 v3 z& h# X
  321. /* This procedure sets the WP pin to high.                                                                */
    ; @+ @) [8 W  D- f& P" e
  322. /*                                                                                                                                                */" K  p6 y0 U8 Y& l# A0 b
  323. /* Input:                                                                                                                                */+ K, Q( X3 B/ p' d# a5 {
  324. /*                None                                                                                                                        */
    2 w! A. t. [$ i4 _8 P5 G
  325. /*                                                                                                                                                */
    9 ~$ X0 }+ h5 @, i! o6 A$ v
  326. /* Output:                                                                                                                                */
    0 T$ c' d% t! R8 i/ `3 r( a! a
  327. /*                WP                                                                                                                                */3 D& l2 m( \- j2 N. F
  328. /************************************************************************/
    & ~/ X" {, m/ r, t5 {8 G2 K
  329. void UnWP()) `  l/ }2 K1 D
  330. {
    ; q3 b5 v) j' s9 S: H, L- V
  331.         WP = 1;                                /* set WP pin */; R5 a) L+ Z4 z* v
  332. }1 ?* Y1 C, t% @* ]
  333. , k- }6 P; u- k# I& S. s, B
  334. /************************************************************************/
    0 V2 A' \# Y8 M0 d7 h3 b5 C! t
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    + e/ D6 L$ {1 i# W% t3 e3 G7 m
  336. /*                                                                                                                                                */; C) J6 p$ Z+ m; g: J0 j9 W
  337. /* This procedure read the status register and returns the byte.                */- c2 N3 Y6 E% t1 w) p5 C7 S4 }
  338. /*                                                                                                                                                */
    7 D3 `" j7 l- e
  339. /* Input:                                                                                                                                */+ J7 q2 G% f3 n! |
  340. /*                None                                                                                                                        */
    ' h7 B, U5 c# i% a
  341. /*                                                                                                                                                */
    ) b. S$ b7 a- S; F% Y- E5 `% e* x5 Q
  342. /* Returns:                                                                                                                                */# M3 g% F1 q6 I% n: O+ p( c
  343. /*                byte                                                                                                                        */$ Q1 P) d+ c# d! \; P- R  X- j
  344. /************************************************************************/% ?! o, C! x+ s8 W% ?1 v
  345. unsigned char Read_Status_Register()
    $ H2 J9 U+ P- L9 X4 c  o# M! `1 o
  346. {
    ; o* H: E. \" w5 {. b7 p
  347.         unsigned char byte = 0;
    . q4 @& P1 M* y% X( }" X
  348.         CE_Low();                                /* enable device */  d+ `" b2 g0 F+ S2 G# }+ W8 `
  349.         Send_Byte(0x05);                /* send RDSR command */
    2 `9 t/ D4 O$ ?" n& S8 ]( e# I
  350.         byte = Get_Byte();                /* receive byte */
    8 b) g# m5 r% b- `* W  ^7 l
  351.         CE_High();                                /* disable device */
    8 E) h7 ?- W9 k- ^9 ?; l
  352.         return byte;
    9 C: ^) C) F5 E$ w: q9 X
  353. }% u$ U. s5 M2 a3 |: v8 L8 `% R

  354. 3 x4 m/ f+ g' w- l5 f
  355. /************************************************************************/
    6 P  u4 I6 `, j
  356. /* PROCEDURE: EWSR                                                                                                                */, C: P! |: p6 M  `/ h+ @
  357. /*                                                                                                                                                */, [+ P3 J3 L" h" i& Q# E
  358. /* This procedure Enables Write Status Register.                                                  */  X" a+ w' b4 V9 i7 E+ o9 G
  359. /*                                                                                                                                                */2 ~: T0 N& L& ]& [, o' B) a
  360. /* Input:                                                                                                                                */& a8 T# L: X) X' R1 Y
  361. /*                None                                                                                                                        */
    - F$ a7 y" A3 W4 h1 J0 D; a8 y, S1 v. q
  362. /*                                                                                                                                                */
    " P  G+ A3 r, n- i4 e
  363. /* Returns:                                                                                                                                */
    3 C7 [# {3 Z2 b; w! A! _( {
  364. /*                Nothing                                                                                                                        */
    : h: {& H! d5 v$ z% f
  365. /************************************************************************/* d$ K2 P2 e; Q( @0 @- z# L: x8 x: T
  366. void EWSR()4 z3 j8 Q- {9 B
  367. {
      S$ j0 N5 u& ~; _- R. P4 Q
  368.         CE_Low();                                /* enable device */# ^: G$ _5 C4 r  d0 F+ L  Y
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    7 }/ ?# W* o7 P1 f0 y8 V% Q  `. W
  370.         CE_High();                                /* disable device */
    % q( S6 i$ X; |2 x/ C: v
  371. }: C8 ?; R* C& o0 {" {0 }

  372.   p  M/ v. X! o1 x( D% d
  373. /************************************************************************// l, S2 A  X4 [8 K7 w/ |
  374. /* PROCEDURE: WRSR                                                                                                                */
    ' w- s- x) H) w: B6 E
  375. /*                                                                                                                                                */9 |* q& W! K7 j4 x6 @
  376. /* This procedure writes a byte to the Status Register.                                        */; x5 L7 G5 [' u) B5 K
  377. /*                                                                                                                                                */
      p' ~1 W8 M! \! k% ^) E: w( `
  378. /* Input:                                                                                                                                */8 l. C* v7 e' t  Y0 g9 b* w3 _0 K
  379. /*                byte                                                                                                                        */
    3 j7 ?, h3 J5 I
  380. /*                                                                                                                                                */
    $ @; {  f$ \2 O/ D2 P
  381. /* Returns:                                                                                                                                */
    + j, j( t2 d, F# V' ?6 M" J
  382. /*                Nothing                                                                                                                        */% ^0 p$ k5 w% r: k6 d
  383. /************************************************************************/
    2 w, L/ o" `. @
  384. void WRSR(byte)
    $ f" i8 S3 q0 E) `) F# H; b- N
  385. {
    ) o. j  n6 [* v. K3 s6 Y
  386.         CE_Low();                                /* enable device */# m2 `* Q# N0 G7 `
  387.         Send_Byte(0x01);                /* select write to status register */
    . W2 j6 K2 c6 Z; a/ J8 l4 x, m, e
  388.         Send_Byte(byte);                /* data that will change the status of BPx ; X4 U' O; }% q7 `) W0 @
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ! a" ^. U4 ~2 G# C
  390.         CE_High();                                /* disable the device */
    1 C1 Q) f( z" R, @1 P  o1 e- c
  391. }) Q% H" K: R) G, _6 F# T! }
  392. 0 o2 R* z8 @3 q; d
  393. /************************************************************************/
    # l% |( N6 e7 S' S  J) }7 ~! x# a
  394. /* PROCEDURE: WREN                                                                                                                */
    3 b. ?9 [/ _* O; Y. ?- ?
  395. /*                                                                                                                                                */9 ^& Q9 E9 E8 v# u- w0 W# B
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    + h  C9 K) u) X: P& @6 Q
  397. /* to Enables Write Status Register.                                                                        */; y  S. ?# r8 l+ z" ^
  398. /*                                                                                                                                                */" j. p7 |- b# o; b4 q
  399. /* Input:                                                                                                                                */
    1 T1 u, x- a5 R$ s7 B$ P# S5 o* o
  400. /*                None                                                                                                                        */
    : [/ |0 r9 D# s0 c
  401. /*                                                                                                                                                */
    3 Z" Q* F1 G* X
  402. /* Returns:                                                                                                                                */
    # @: I7 z  c! N" d* L; ~2 i
  403. /*                Nothing                                                                                                                        */
    % Y6 }7 o1 e0 ?, E6 S- Y7 s
  404. /************************************************************************/
    . a  `0 t+ F6 {/ [6 b3 g
  405. void WREN()
    8 s/ r2 s+ s$ T: q1 V& ?- D* E% w
  406. {% \+ Q5 R0 @) Y6 q1 L" g# e9 j
  407.         CE_Low();                                /* enable device */  [& s: b: e+ k, C8 E
  408.         Send_Byte(0x06);                /* send WREN command */
    & N8 i7 n; q$ d" s& w, R
  409.         CE_High();                                /* disable device */
    + Z, Z- c- m/ L' H& e% w
  410. }
    1 f5 R5 A/ ?; `* D# U
  411. ( I) A# m( ~" p& |) e& U
  412. /************************************************************************/# P0 d+ O0 \  o+ Z. y' a. |& U8 D
  413. /* PROCEDURE: WRDI                                                                                                                */* k6 l5 a2 r* O7 H
  414. /*                                                                                                                                                */5 j% K4 p) _9 s5 R: }
  415. /* This procedure disables the Write Enable Latch.                                                */
    . B- k$ F3 Q9 P. \; r
  416. /*                                                                                                                                                */
    1 K$ v: G7 q4 v2 W
  417. /* Input:                                                                                                                                */
    & \% d- ?2 y, z! c
  418. /*                None                                                                                                                        */# n/ W8 ?0 {/ @* c2 a+ P/ y/ t
  419. /*                                                                                                                                                */
    2 C! T5 J! ]3 n9 [$ h/ S0 s
  420. /* Returns:                                                                                                                                */# |" {+ @8 E8 a% S$ ^5 u3 e' M
  421. /*                Nothing                                                                                                                        */1 s( {; l* I8 E( `4 \5 _
  422. /************************************************************************/% y7 m) ~1 E) P8 q- S6 J$ o0 v3 o' ^
  423. void WRDI()
    - _- v& s3 ?; Q/ K. l! i0 l- I
  424. {  m3 Y* n, K) b7 q& q- C
  425.         CE_Low();                                /* enable device */
    0 u* k2 y, k+ ~( t: i* \
  426.         Send_Byte(0x04);                /* send WRDI command */
    9 T: E8 t; ?# B. l* F. `9 t) z0 D
  427.         CE_High();                                /* disable device */3 K1 e9 ?: b+ h3 T- X. h
  428. }: _  k, b! ]* D2 [3 @! v) N

  429. % F$ J$ V9 T6 p7 B! k
  430. /************************************************************************/% G, k4 U2 a5 y+ J3 G/ t
  431. /* PROCEDURE: EBSY                                                                                                                */8 }' n3 J0 G/ a3 n
  432. /*                                                                                                                                                */( E' C" }+ W, T- M( b
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */% |: k. n3 H* u  w
  434. /* programming.                                                                                                                        */! _) @$ a9 |" L# ^) A8 z
  435. /*                                                                                                                                                */, @8 v; u, Q8 x6 E# Z, J# ^4 g5 X
  436. /* Input:                                                                                                                                */
    - @3 F0 p: `8 a0 d7 g
  437. /*                None                                                                                                                        */
    ' {9 ^6 P+ d0 i* I. l% `
  438. /*                                                                                                                                                */$ @! W1 b) {. d* L
  439. /* Returns:                                                                                                                                */1 K1 C, ~4 D2 ?/ y) [- A0 t
  440. /*                Nothing                                                                                                                        */
    & l) T2 S+ K8 C
  441. /************************************************************************/
    % _/ `% l: b* W6 B( {4 m
  442. void EBSY()
    ) c7 b$ m" X& m) N. C
  443. {1 _" ?4 }2 ]+ M5 c6 B) Q0 e
  444.         CE_Low();                                /* enable device */" M! \0 C# p, x5 x, D
  445.         Send_Byte(0x70);                /* send EBSY command */
    4 R5 I8 h( R1 t0 h
  446.         CE_High();                                /* disable device */
    # o* i' ?' w( D- D1 C  `. H
  447. }& n6 v7 _- X' U  t6 g

  448. ! J( m/ M6 B2 O3 R2 d
  449. /************************************************************************/+ ]) \2 G7 P8 U# e* u
  450. /* PROCEDURE: DBSY                                                                                                                */+ a# s. ?. Z8 J$ B. _, T
  451. /*                                                                                                                                                */  g- d: H$ d' ^( @4 z; n4 ?, w
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */" U# q2 c1 u, |7 L
  453. /* programming.                                                                                                                        */
    ) c3 t) @& S4 j: c
  454. /*                                                                                                                                                */  w$ a! ]& }* T& Q! \5 s/ \
  455. /* Input:                                                                                                                                */
    + @8 z8 U7 p' U7 _
  456. /*                None                                                                                                                        */' b4 n) a7 i! k- K2 l/ X1 K
  457. /*                                                                                                                                                */
    8 q$ y+ t& D6 {% ]; S- E! w
  458. /* Returns:                                                                                                                                */$ D6 H8 k- _+ P  _
  459. /*                Nothing                                                                                                                        */4 f1 N  R4 F$ n) c
  460. /************************************************************************/* u, U8 ~  Y8 k3 \# w" ~
  461. void DBSY()
    " Z5 x& K# ~, m/ d8 ]
  462. {
    " Z- }, V7 Y+ t+ c$ n
  463.         CE_Low();                                /* enable device */% Z  j9 H# i7 e. b, |% u
  464.         Send_Byte(0x80);                /* send DBSY command */
    ) }% L! ^/ y5 q1 w7 X6 s% r
  465.         CE_High();                                /* disable device */2 w# R% M( t( g7 }, v" d) q
  466. }
    ( `" \# J* _6 v5 e/ `  v- t

  467. ! T3 w6 u/ C- o$ O
  468. /************************************************************************/
    : q) r. i  _$ p4 o8 I7 j( M* G
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ) Y1 f+ x$ U- Y( e; J( r6 A5 e
  470. /*                                                                                                                                                */2 i9 D5 {3 C2 K/ |' W0 m3 H8 M
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */0 S1 {1 M9 O, l& G
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */" y8 T. _' S, K$ V
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    5 V1 T- l+ |8 }1 C. l
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    ! W1 V, e$ a/ v5 ]
  475. /* first.  Please see the product datasheet for details.  Returns ID in */! L( B9 H3 y6 _+ b5 r
  476. /* variable byte.                                                                                                                */& P/ U, E8 c9 R1 S8 s
  477. /*                                                                                                                                                */# }$ E8 U) X8 H
  478. /* Input:                                                                                                                                */
    5 B: c3 N/ ?1 _8 l6 q
  479. /*                ID_addr                                                                                                                        */
      h6 ]- y  M4 D: {( i3 l* \7 I1 r" Y
  480. /*                                                                                                                                                */: G; w% }: C/ U) q
  481. /* Returns:                                                                                                                                */# v0 G$ J& m( V# }" y
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */+ f0 x9 L% ]4 e" @
  483. /*                                                                                                                                                */
    4 ~" J: |) S3 z1 u
  484. /************************************************************************/
    ) Z. L) t* j+ o& j  A$ h- b
  485. unsigned char Read_ID(ID_addr)
    " ]$ D$ X6 p% i3 I  a7 t0 s
  486. {
    & O5 u2 Q6 G! d$ i5 Z
  487.         unsigned char byte;8 J% O# H; T& o% u5 K; Q
  488.         CE_Low();                                /* enable device */7 x% [& V2 f  l" s, h
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */  A, H+ N2 A: K# D
  490.     Send_Byte(0x00);                /* send address */8 @& O  s3 Q" a; S
  491.         Send_Byte(0x00);                /* send address */
    . }1 |- V# e# |7 |# i
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */! P6 }0 {3 r+ k5 |( B- T; l& d
  493.         byte = Get_Byte();                /* receive byte */8 Y( }% n% V! a' H5 V, b# S9 @
  494.         CE_High();                                /* disable device */
    / v$ a) Q. U( z  }
  495.         return byte;
    5 F2 Z. M  c& p; w3 }2 n2 ]! e
  496. }
    3 L4 [1 F7 D3 m0 k9 Q6 o
  497. $ ~6 O. m: L+ t  J; b2 ]
  498. /************************************************************************/, ?, q) _  R( H; G  D7 n# U1 u
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    . P4 J, h. Q/ B8 ]5 X! K
  500. /*                                                                                                                                                *// s3 x- U9 x/ c5 o
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    6 E7 V: `& Z3 v! N# g/ z
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ( X/ E) w$ p$ o' f; T: j- {
  503. /* Please see the product datasheet for details.                                                  */
    $ q* G* e2 ]. H' j- [& Z0 A) b
  504. /*                                                                                                                                                */
    0 U  S9 O1 U6 o: D# |  x) \& Q# v
  505. /* Input:                                                                                                                                */1 I7 ~( {! l3 i  Y. z" [
  506. /*                None                                                                                                                        */
    5 e* l; g3 i" a! ~6 I/ J
  507. /*                                                                                                                                                */( x( |$ w  p! K$ I
  508. /* Returns:                                                                                                                                */3 i/ U4 \# ^. v4 \) ^+ F
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    / }2 @: x/ Z6 _+ w3 X
  510. /*                 and Device ID (8Eh)                                                                                        */1 y9 f, G% I  N9 O' P/ G+ T0 N
  511. /*                                                                                                                                                */
    0 i$ O: E; R% L* W5 C+ I- p4 J9 ~7 H
  512. /************************************************************************/0 u# K8 w) z8 t$ E' E
  513. unsigned long Jedec_ID_Read()
    7 Y7 f/ s$ }& B  F" j/ k
  514. {
      n$ W/ b" @3 m0 G- L
  515.         unsigned long temp;
    0 k3 x, S$ \6 F# G2 M
  516.         # m8 m) r) E) i! u; n$ Z0 K' G
  517.         temp = 0;
    " T/ u: W2 S$ v! R5 f0 O

  518. 2 F! J8 s. k6 }  n/ S# ]. k- Y
  519.         CE_Low();                                        /* enable device */
    1 |& r3 L  y: N7 i. o
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    * w8 f3 I# M  l4 R3 u
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    / T! x$ M: O! ?* g
  522.         temp = (temp | Get_Byte()) << 8;        ) @1 \, T7 W/ Z
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */. l- w7 k9 g: P: q1 }  R2 A
  524.         CE_High();                                                        /* disable device */" m1 H: U% l8 p7 J; @

  525. 2 Q  o3 b6 ]- h( F4 x
  526.         return temp;3 v# }/ J% v6 {% H* D8 V9 C
  527. }  O/ k8 @; F( D' T3 Q  \" a  v: P+ t5 J
  528.   c: H( t$ Y  E. F! s6 w
  529. /************************************************************************/5 h; x0 Q& P5 \0 k/ g, Z4 d
  530. /* PROCEDURE:        Read                                                                                                        */
    ) }. k$ _- o6 P( l1 V3 ?8 w. `
  531. /*                                                                                                                                                */                4 ?1 |% A( R: R$ X% o) ~6 ?
  532. /* This procedure reads one address of the device.  It will return the         */$ y, w3 f* X' ~0 h, o% z
  533. /* byte read in variable byte.                                                                                        */
    8 S- q5 X+ v# y+ a
  534. /*                                                                                                                                                */
    % q9 i, |( {. i' ^+ X8 r
  535. /*                                                                                                                                                */
    / a6 `7 }/ x& R+ T$ k; a
  536. /*                                                                                                                                                */
    ' k1 P! a" C" l2 b: _
  537. /* Input:                                                                                                                                */
    4 ^! J4 D( L; B$ n3 r4 D
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    * s' e3 l" O" K) ?  w) Y9 O  E% O
  539. /*                                                                                                                                      */1 o# B! e7 \! n5 r+ Q# a
  540. /*                                                                                                                                                */
    5 G0 z6 w: x  k9 h5 W
  541. /* Returns:                                                                                                                                */5 f, X/ k- `! }- T/ u) l& Z5 V
  542. /*                byte                                                                                                                        */8 J2 K$ t& {" M: K5 o+ d: i2 q
  543. /*                                                                                                                                                */
    ! a8 [/ U! @! O$ ]1 V
  544. /************************************************************************/6 L8 `* I/ q6 V
  545. unsigned char Read(unsigned long Dst) 3 K% [" ~# k2 F+ B4 U; G
  546. {
    ; d, E& d- I' g4 B
  547.         unsigned char byte = 0;       
    3 B9 M& q7 d' A. H; V0 ~. U/ M- V
  548. / }! J, A! H" i: {
  549.         CE_Low();                                /* enable device */
    8 D2 U: ], O0 d! J6 X& f% T! @
  550.         Send_Byte(0x03);                 /* read command */
    + |# q7 _; T: R; d; V+ E1 z% s
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    0 _' g$ U8 I- `- N# ]. X
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));: Z  o$ G# J) I  ?$ [. D+ N
  553.         Send_Byte(Dst & 0xFF);. b. i3 E3 F; N
  554.         byte = Get_Byte();6 H; \  T* O9 N3 O5 \
  555.         CE_High();                                /* disable device */
    ! o9 `$ P- B3 @. ?; b7 H
  556.         return byte;                        /* return one byte read */
    4 S. Y  J( R1 [: |! u
  557. }
    ' O! G) c- @+ _/ f
  558. : t% c: w( G3 g. a( k
  559. /************************************************************************/
    , L* w- I- x) ]
  560. /* PROCEDURE:        Read_Cont                                                                                                */
      Z$ V$ G0 _* N/ i4 C
  561. /*                                                                                                                                                */               
    5 s" E/ F) D+ e1 I) ~6 ]
  562. /* This procedure reads multiple addresses of the device and stores                */8 C- N7 V5 X3 |/ t; C5 o
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    6 p9 b) p5 u/ z* y  a
  564. /*                                                                                                                                                */' k8 t# y% N. I( g* Y# I+ W  U
  565. /* Input:                                                                                                                                */
      [4 F9 Y! n2 Q$ v2 ]
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// t( |: N  z$ o
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    , B$ d6 E; ?" m
  568. /*                                                                                                                                                */
    # W$ V0 q+ }( H& H2 J& p$ r: E2 G+ H% W
  569. /* Returns:                                                                                                                                */6 w2 M( s* q9 Z) R
  570. /*                Nothing                                                                                                                        */# N+ c  }( d/ V$ K- n
  571. /*                                                                                                                                                */
    2 U5 m; b1 G( u& e+ o) F+ o3 _
  572. /************************************************************************/6 V  K. ^$ t! f
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    " S; |3 }- K4 u7 t
  574. {! F2 h- }0 x( v6 H# e; c
  575.         unsigned long i = 0;4 P7 ~5 Y/ b- O/ V! f
  576.         CE_Low();                                        /* enable device */7 G0 j' P5 \" R* Z) G3 ^
  577.         Send_Byte(0x03);                         /* read command *// v# b1 H5 _" ~$ H0 K- {# V: e0 p
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */6 f" D# ?; A$ m; ^
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) G8 Y* b( f2 ^. @/ A+ J  ~) J8 j
  580.         Send_Byte(Dst & 0xFF);2 E( k6 ?4 \' n3 r
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 z9 X% T0 I& k( ]3 e9 r1 c. F5 j
  582.         {5 T+ q) ^+ @# e. v1 ?/ {
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    . }& g: i8 [* t" G7 K  F6 U
  584.         }. P* B5 v" Q1 s  t8 S4 L/ H
  585.         CE_High();                                        /* disable device */
    % [  z# S, W  l5 D( [+ c
  586. - u2 I1 v8 y1 r
  587. }
    8 x1 A  a; r8 k2 M4 `# \
  588. ) g( _; [3 z  u* o% m0 o
  589. /************************************************************************/
    % \- y$ @/ f# y: I7 f* u
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */3 w$ B7 d) s2 D5 J
  591. /*                                                                                                                                                */                - S8 g( m0 {. ~" ~3 k
  592. /* This procedure reads one address of the device.  It will return the         */4 P" ^" {! x7 {/ G! B5 y
  593. /* byte read in variable byte.                                                                                        */
    4 j+ b. a: k9 n/ c" v* d- s
  594. /*                                                                                                                                                */
    & o+ i9 e: J3 t; j! \
  595. /*                                                                                                                                                */% X# v$ o( e& p
  596. /*                                                                                                                                                */
    3 B, p3 |7 v# n: K7 P
  597. /* Input:                                                                                                                                */$ v6 o, D- x* [" C  k
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    " ]- U6 B% {* i" B. M) n
  599. /*                                                                                                                                      */% R5 z! r, e$ S5 Q' y# {. I8 ]! b
  600. /*                                                                                                                                                */$ |0 V* u) X' Y1 N& U( v- b, g
  601. /* Returns:                                                                                                                                */
    8 Q1 L# V! B0 H  v* [  n! c- y
  602. /*                byte                                                                                                                        */
    * M$ O6 c: \" J7 w. V/ c, L. l
  603. /*                                                                                                                                                */
    # w$ |8 X6 R9 Y0 y
  604. /************************************************************************/
    9 _+ F1 O0 }& V4 ^" r# G9 h
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    . G% D; g& \6 P$ o% ~2 y# d5 k
  606. {$ P! l& V! I8 Y/ p* B5 V
  607.         unsigned char byte = 0;        - I3 j, c/ B. {( s' z+ }, R2 n0 [
  608. 7 x* n) I# x& K2 C) v" H! ^
  609.         CE_Low();                                /* enable device */+ q, H/ [5 \- j( \9 _2 P
  610.         Send_Byte(0x0B);                 /* read command */
    4 e# c' C0 g4 g& T% _
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 O1 J; T% A/ i+ E, K" S
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));1 k  Z! @6 u0 H  J
  613.         Send_Byte(Dst & 0xFF);
    * K* |4 x) _. V9 W' k0 ~0 Z
  614.         Send_Byte(0xFF);                /*dummy byte*/* m3 u2 @1 n) r  n( K/ B
  615.         byte = Get_Byte();3 w  _9 X* j) x: U. i7 b" e9 w) v
  616.         CE_High();                                /* disable device */3 T" G9 r) @! o4 q
  617.         return byte;                        /* return one byte read */
    - r4 o3 \9 m, H
  618. }9 n7 Y9 C) N2 x2 O/ _2 T, |
  619. : w; |3 y. z8 V/ M, d
  620. /************************************************************************// b' }4 Y. o! \0 O9 z& }
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    7 U6 _6 T/ Z1 y% n% O2 l1 C- F
  622. /*                                                                                                                                                */                " t4 n8 f0 s7 K; v' s! Q9 x0 p
  623. /* This procedure reads multiple addresses of the device and stores                */, A/ j4 @1 ?7 U; O( M
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    % i6 Y6 L+ W" _
  625. /*                                                                                                                                                */) q, L# r: p3 e$ G& K5 N# O3 G6 j8 v- B( V
  626. /* Input:                                                                                                                                */
    , v' F- Y  |) |! ^- ^0 V
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 n" }- `4 [6 n* J+ w
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    4 f, ^0 L- ]3 H+ Q9 k/ x3 l
  629. /*                                                                                                                                                */7 }5 R- A- c0 l
  630. /* Returns:                                                                                                                                */
    1 G& p0 l# _2 D3 u( L+ W
  631. /*                Nothing                                                                                                                        */
    " H6 F5 M( E+ B" g, ?4 G9 C1 i
  632. /*                                                                                                                                                */! j5 w: {8 j% {+ M; f
  633. /************************************************************************/
    8 W+ r' e% ^6 i& e- T
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    4 a5 F3 V# X- V: i1 L3 v0 Q5 [
  635. {
    5 |, N3 }  ~: ]1 s% U+ x( ?* M1 ?
  636.         unsigned long i = 0;0 P% k* o% `) K. ?2 `
  637.         CE_Low();                                        /* enable device */
      f. V4 O( c6 @+ t0 r& O8 F( Y+ m
  638.         Send_Byte(0x0B);                         /* read command */4 U& j8 q1 _- l& \4 e4 Q6 O# s  r
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! O6 ^. S- `1 v9 Z- _9 s3 e
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 B5 m3 v0 n( N& u' {' f/ k1 P
  641.         Send_Byte(Dst & 0xFF);
    % t+ s* l4 D5 g9 V: R
  642.         Send_Byte(0xFF);                        /*dummy byte*/1 Z' I3 k8 r/ q7 S  @6 _
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */% v! g4 }* ^' \7 ^0 A
  644.         {) w1 T5 w' ]& q2 W% e$ @+ G1 b
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    . Z5 O+ t9 V) p1 ~3 N/ x7 |
  646.         }. n* [  n0 n6 Q% z8 l# z
  647.         CE_High();                                /* disable device */
    # s" B( C/ M! P1 a/ E' y# L( K
  648. }
    8 E# ?. _% T) f' @1 W

  649. + C% w9 [. N7 o+ Q' Y) b& ^
  650. /************************************************************************/' R* U6 `/ }! u: H) |0 c
  651. /* PROCEDURE:        Byte_Program                                                                                        */3 d! w% i: z9 }1 m9 Q0 w: q6 b
  652. /*                                                                                                                                                */
    2 I/ w0 k/ h; h5 s; Q% c
  653. /* This procedure programs one address of the device.                                        */
    4 ?' M) P) _5 s2 ^+ z
  654. /* Assumption:  Address being programmed is already erased and is NOT        */6 ?* d! K0 h3 K6 f+ P1 I1 O
  655. /* block protected.                                                                                                                */+ P# o( c" _- w' K+ H
  656. /*                                                                                                                                                */# S! r1 b# ^( k+ Z
  657. /*                                                                                                                                                */; g  F* E# l. T
  658. /*                                                                                                                                                */1 V: ?! q) o/ n8 ~$ E# s" Q; I7 u' f
  659. /* Input:                                                                                                                                */+ a/ s1 P+ [% r1 m8 e  M5 A7 }
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : D( n* s7 F: k) D2 K- v
  661. /*                byte:                byte to be programmed                                                                */
    ! V3 A* y! G" ?7 W2 U
  662. /*                                                                                                                                      */
    : A6 B# a& M* F" i# J( a5 t
  663. /*                                                                                                                                                */
    7 @7 k6 S* c; q( R4 g7 a3 i
  664. /* Returns:                                                                                                                                */
    . I' f) b. w5 z: @6 o
  665. /*                Nothing                                                                                                                        */. w" N( _+ J+ Y* ?
  666. /*                                                                                                                                                */) T" C$ d0 M$ q" ?* _4 P( z
  667. /************************************************************************/
    8 h+ c0 F; m1 b) |+ m
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    ; e& Z, L9 H& d3 l$ S0 ?- N
  669. {/ N* L( _* |4 Z
  670.         CE_Low();                                        /* enable device */2 d( K; \( e# Y, u* @6 s
  671.         Send_Byte(0x02);                         /* send Byte Program command */8 g* U* ~2 Y2 c+ S
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    * @* M5 S9 v% O# @- I
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));* t0 _% f! l& R; U6 ]
  674.         Send_Byte(Dst & 0xFF);
    0 M# t/ l( H" y; ^4 |# V
  675.         Send_Byte(byte);                        /* send byte to be programmed */3 G# q; b7 U" r1 w7 U
  676.         CE_High();                                        /* disable device */
    * z$ n' r0 c  g; t9 [' B. c) z! d) @
  677. }
    * d5 Q1 x- s. I" [8 N6 q# g! n+ K, S$ g
  678. ' M) m+ D0 Z" n- r1 Z
  679. /************************************************************************/" |! A( p8 y0 S* N
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */' S; C, J) d! D& @" c6 I
  681. /*                                                                                                                                                */% [5 u! u0 R) h1 ]
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    3 J/ m( i0 K5 {! b6 n
  683. /* the device:  1st data byte will be programmed into the initial                 */
    ! X% c" X6 u) T9 D. J
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */; ]' v* E# c- `$ `/ i% U( U
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    $ @7 y4 V9 H; g
  686. /* is used to to start the AAI process.  It should be followed by                 */) z$ l  K/ e9 v
  687. /* Auto_Add_IncB.                                                                                                                */
    , y5 m( |! Q7 n4 G  d. e( y
  688. /* Assumption:  Address being programmed is already erased and is NOT        */+ c0 [& k' X" t& b4 L0 V$ v" |
  689. /*                                block protected.                                                                                */
    % i2 K& \0 I/ a* g+ O" p
  690. /*                                                                                                                                                */
    ; o" {8 ]* G# @4 T5 B0 k
  691. /*                                                                                                                                                */
    ( X/ K( e/ t/ {- }2 W- y
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */$ V$ a- ^0 }5 Z4 D5 K# _
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    0 t* r* [) C( p$ a, @1 f# {
  694. /*         unless AAI is programming the last address or last address of                */
    * r9 s0 N; o% _  {, @2 x
  695. /*          unprotected block, which automatically exits AAI mode.                                */
      L0 z6 @- n  c  s
  696. /*                                                                                                                                                */
    $ k6 {( r0 g+ X9 Y9 ~) Q% y. E/ @+ A
  697. /* Input:                                                                                                                                */3 S! l( m; R% `/ u
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* ^% J$ w, R+ C% r$ e; Z. T7 F
  699. /*                byte1:                1st byte to be programmed                                                        */0 F( ~  X) W* |* W* ~& k
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ) p# h7 s5 ]9 ?, ]8 v& k' v5 ^
  701. /*                                                                                                                                                */  t4 W  c9 V7 \
  702. /* Returns:                                                                                                                                */
    0 l  Z; r. S8 G- D  A; k
  703. /*                Nothing                                                                                                                        */% l' u" \- `+ U0 ^# d9 V
  704. /*                                                                                                                                                */9 R5 H! S, u( r+ H( _
  705. /************************************************************************/
    6 u; d/ t6 b7 p. g
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    + W( Q: n' R$ G% _# l; r  V
  707. {
    $ }$ V7 a# B6 d6 ?( W
  708.         CE_Low();                                        /* enable device */
    " v' {" T* G0 b5 r0 X: J* L
  709.         Send_Byte(0xAD);                        /* send AAI command */7 V9 \8 I+ ~  \/ N
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 A4 e4 `3 }, A; M
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    9 C! O* k+ R& ~& b* y( j  B% H
  712.         Send_Byte(Dst & 0xFF);7 V& i8 b: P* K1 ?/ [4 g
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    3 y% L$ |* Z6 b7 l4 e: w7 Y
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , f5 ^/ o5 y4 h6 p3 V$ w6 w
  715.         CE_High();                                        /* disable device */
    , u& `# s; W4 u
  716. }) D. [: Z& d2 m; j4 s, m

  717. - T9 `& B/ C7 o, l3 J
  718. /************************************************************************/
    % p+ ^9 b) }( S7 H% F
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    & ?9 G+ k$ _7 K
  720. /*                                                                                                                                                */
    ! D, b- I" I% q- r8 a0 y# W; A
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ( x$ x& V; y  m( u; x# y  J# U' u0 F0 ]
  722. /* the device:  1st data byte will be programmed into the initial                 */( q4 h, E" m9 S7 L; l
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */8 H. D* o' u1 O
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    1 E8 i& F! W, h0 p* T  W
  725. /* is used after Auto_Address_IncA.                                                                                */! R# v" \3 P1 `1 n2 A& W- w
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    # N8 ]# V' ^6 a. [6 l! K
  727. /*                                block protected.                                                                                */% U. u1 \' t, k3 r
  728. /*                                                                                                                                                */( J# q2 {% B  k" ?, n
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */) P: }9 @! ]% r1 D# Z4 R0 c
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */1 T- Z9 v( N5 w: }
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! ~; P& o: B) p2 P. V
  732. /*          to exit AAI mode unless AAI is programming the last address or                */! X2 Z. J+ g* A! ~# G; v
  733. /*         last address of unprotected block, which automatically exits                 */: j) Y2 M; V, y3 H
  734. /*         AAI mode.                                                                                                                        */5 P# ]* b* ^" s$ n9 H
  735. /*                                                                                                                                                */, {. i" @4 j2 k! H3 A
  736. /* Input:                                                                                                                                */1 P9 S2 {. S' J/ O0 m. H
  737. /*                                                                                                                                                */) u0 D/ l; `' Y7 e7 T% k, s
  738. /*                byte1:                1st byte to be programmed                                                        */
    6 @7 C' ?/ q$ j8 p9 m
  739. /*                byte2:                2nd byte to be programmed                                                        */) c$ f1 |' y+ s9 K& V8 q
  740. /*                                                                                                                                      */
    : F- G) N( e& Y/ o  h) _% N
  741. /*                                                                                                                                                */+ P5 y- G# B3 w9 v8 y5 m
  742. /* Returns:                                                                                                                                */
    $ X- s$ C9 t. @0 U7 k/ T  L8 a
  743. /*                Nothing                                                                                                                        */. L6 R: q: U% J1 y0 z
  744. /*                                                                                                                                                */0 j* P2 E7 I$ W: w# r, @- `
  745. /************************************************************************/1 J6 l9 p  ?" f+ X+ \; ]2 h
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)$ m5 Y* ^; h: f* Z. j& o8 k
  747. {
    % C" D2 X( m2 D
  748.         CE_Low();                                        /* enable device */" p' V$ D' U6 C9 H" {; E1 I  O1 Z3 I
  749.         Send_Byte(0xAD);                        /* send AAI command */
    : d; g9 B, ]# [" K% _
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */% j- S0 \; \. U! }6 s6 F6 |- z
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    . G2 N. [+ e* {1 b* G* H) q% |
  752.         CE_High();                                        /* disable device */$ F) Q$ X) h# Y0 h
  753. }, o$ N# i' ]- ^- X0 Z2 u. j) E6 y1 ~. o

  754. * ~3 G6 i( l9 k3 u0 |# F( S- h5 z5 D
  755. /************************************************************************/
    ; J7 Z* U' L7 I0 D; B0 X, [
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    8 P0 @) w+ B) N) ^. [5 N5 V
  757. /*                                                                                                                                                */+ g$ c) k( M, ~* p% B5 J
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    $ g; W  a# p% _2 h4 l0 J, ~
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */) F- A' c7 K; |& v3 g* B) W: O
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */" b' E* ]2 s" [: B8 Q
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ' ]/ ~5 A$ \. h3 F& i, V
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ) ]) U* E* V7 _
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */! k5 [2 C2 @8 w4 Q/ m
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */2 J9 l) Z0 t3 W2 J' X
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 m1 J) B/ I- B  D* L$ G
  766. /*                                block protected.                                                                                */
    " H7 z# f8 T4 a% U
  767. /*                                                                                                                                                */, \2 l6 E: w' _: W9 x: V
  768. /*                                                                                                                                                */2 `! u/ e7 ]9 x$ W' d
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' z: e% c1 U& `8 c
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    * G% o$ S0 i2 r5 \3 I
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */- L$ [( y8 e& {* G8 Z# _
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    7 p# P- G. d* q/ o7 c: P% d3 L+ _
  773. /*         last address of unprotected block, which automatically exits                 */
    $ U4 Q2 g* m) k1 d2 _2 \+ x
  774. /*         AAI mode.                                                                                                                        */
    " ]4 Q$ ]. |, a4 c
  775. /*                                                                                                                                                */
    2 D" _/ P( V) f( X" [0 F
  776. /* Input:                                                                                                                                */( p( B7 ?% x' i7 `- B! i* ?8 y) w2 R
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: `5 E3 ^3 X( I8 W$ ~
  778. /*                byte1:                1st byte to be programmed                                                        */
    / c' V% V5 b( Z$ i) b8 U
  779. /*      byte1:                2nd byte to be programmed                                                        */+ m' j1 X4 `8 z, S+ y5 {
  780. /*                                                                                                                                                */. p) s" L7 ?7 @4 c$ m$ w% I
  781. /* Returns:                                                                                                                                */2 a- r% K5 d, i0 d( m, K  x! }' k: J4 Z
  782. /*                Nothing                                                                                                                        *// _) D! u! \5 Y( R7 D  w6 e
  783. /*                                                                                                                                                */
    * g$ Y& n7 x1 S; i0 B( J; H
  784. /************************************************************************/0 j/ ~& k/ A! [2 P4 C
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)2 k) J6 i8 |, a% M
  786. {
    6 y) V( s) N; l
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        / S+ J  n1 u/ k9 W* H" M4 {/ p2 q

  788. / W( s+ _+ K# V0 n# f# Q
  789.         CE_Low();                                        /* enable device */6 ]; ?  g* [" k; C7 \7 M9 F
  790.         Send_Byte(0xAD);                        /* send AAI command */' l! ^- L% D, H* H4 F
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# s- x5 i9 L  K. ?4 T
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & [; ^, W) \$ K
  793.         Send_Byte(Dst & 0xFF);* E! P' K; j! i) h1 x
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        8 \4 u! c7 L$ M7 Y6 e) u" H
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ! ~9 g. I5 b: n. U: d
  796.         CE_High();                                        /* disable device */3 h9 [3 m8 c4 [: s% A8 ~2 Y
  797.        
    3 b  q" D$ \5 ?. F' Q4 u
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    & Q( j4 S3 V* V  r$ Y9 d

  799. 1 m3 A# M; Y" n' V
  800. }2 `& L: ^3 h/ i' Q. s) _

  801. ! s5 X" T# a# w
  802. /************************************************************************/
    9 W+ J8 D& [% ~- A% e. i  o
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */( Y$ i7 _/ y  ~9 X. L9 D
  804. /*                                                                                                                                                */! p2 J* S9 e+ T) ^0 [
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ' ?, h) q! A/ _, C. a7 r
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */! Y6 |9 F5 b* P2 H. H  Z
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ; y/ J, \& ?8 Y) H
  808. /* the device.  The 1st data byte will be programmed into the initial   */, f( X) X# c# z: c
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    . Q, [6 U+ _8 k0 P0 \) T$ W9 K
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    * B" U9 ~+ S; _; j/ v
  811. /* used after Auto_Address_IncA.                                                                                */0 P  X3 U' H; k5 f
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 u* i- \' M/ j) V( X( m) ~
  813. /*                                block protected.                                                                                */) [# J" b1 B8 d+ a) i2 f+ {/ R, Q
  814. /*                                                                                                                                                */
    $ _9 u# Q# q& t3 Y
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    # C, P3 J5 D2 [0 o, w! u2 C9 c, `7 a
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */  \, ?6 v; Z# \7 r( D, @) l1 t: {
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    3 T5 ]: f# {% u" K
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    : _" |; V* J! w2 ?) p  t
  819. /*         last address of unprotected block, which automatically exits                 */* B) j+ T! L( L6 {; \% [
  820. /*         AAI mode.                                                                                                                        */) s# y3 n: V7 L# P: Z
  821. /*                                                                                                                                                */
    , L+ ]. d8 {/ T: m, T- x/ X$ @6 p
  822. /* Input:                                                                                                                                */: m! N2 O* P/ }# v2 k
  823. /*                                                                                                                                                */$ z+ `( O: r$ [0 _' G$ |5 @' C5 _
  824. /*                byte1:                1st byte to be programmed                                                        */3 O% B/ O4 d/ m. M" E
  825. /*                byte2:                2nd byte to be programmed                                                        */
    0 r& K' V% M7 ]6 L; y, q- L
  826. /*                                                                                                                                      */& Z" U5 y0 G$ p6 A3 ]  ?
  827. /*                                                                                                                                                */6 M2 l9 L/ B; D9 O& N; G/ o& x5 G# q# c
  828. /* Returns:                                                                                                                                */1 b4 i% `" Y5 a- I
  829. /*                Nothing                                                                                                                        */
    : I4 f0 k% ^5 W% W$ I5 o  H& X  B
  830. /*                                                                                                                                                */
    % J8 E% Z4 z  k+ s. H2 L
  831. /************************************************************************/
    5 O; ^, y4 R8 P
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)+ R8 l8 j5 d( o
  833. {
    ; R) x( A0 Q  H5 n- K
  834.         CE_Low();                                /* enable device */# V9 a/ E# y. w" P" p, j9 v, ]
  835.         Send_Byte(0xAD);                /* send AAI command */, l. s# i3 S/ `( A  J
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    / U1 n* d0 m+ ~1 O8 i" m* a4 z
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */" y" v0 B/ o4 A& I/ s
  838.         CE_High();                                /* disable device */" C" a0 U$ H( ~( t9 j9 F  p

  839. ' Y; N+ t+ b, c5 w
  840.         Poll_SO();                                /* polls RY/BY# using SO line */3 x& N5 k& K- y" f) `6 i
  841. . L3 ]4 \; i3 [
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    7 v" m6 Z* n( }" V5 x9 C* C2 Y4 ^
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */# n/ V7 `0 j+ i- ?
  844. }
    & @! ?3 k& c" X6 \5 S) i- A; P, L
  845. / z) p& K( Y4 }
  846. /************************************************************************/
    ' E! X: W+ Y* E9 ^4 A! r. `" t
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    6 l& w' g1 S  N* |2 C
  848. /*                                                                                                                                                */% H/ `( S' M# }8 z' ]6 y4 t
  849. /* This procedure erases the entire Chip.                                                                */  D$ u' Z  g2 J6 _, b1 N
  850. /*                                                                                                                                                */1 I  T0 }& D# ?- L* d
  851. /* Input:                                                                                                                                */
    - f6 _, c( n  ?! |" |
  852. /*                None                                                                                                                        */
      k" v- t4 m, s7 S% m$ p1 J
  853. /*                                                                                                                                                */
    - C  u- E& q3 c: R4 `% m* w
  854. /* Returns:                                                                                                                                */
    : `2 G4 o. n0 i
  855. /*                Nothing                                                                                                                        */" k6 p8 `* }- h; h, i! i( @+ g4 V% N
  856. /************************************************************************/6 x0 t' D2 @* U! a6 }! H8 ]
  857. void Chip_Erase()" M+ n7 P( m3 G2 B- M' a& U
  858. {                                                # B9 y8 X  }7 L- E$ X, s9 p( d" O
  859.         CE_Low();                                /* enable device */: n) h& P+ F- `$ w- S: _) l0 X4 a
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    6 }4 l! H$ Y% p+ p: N
  861.         CE_High();                                /* disable device */
    + r+ [* v) }! [( p0 b% R2 A
  862. }
    ' E0 {+ Z$ g7 J5 D& n! M6 b/ V

  863. 2 f* c3 S7 X1 V8 J
  864. /************************************************************************/& |, b: p! ^5 j. n. W% N1 d
  865. /* PROCEDURE: Sector_Erase                                                                                                */3 y/ i: i2 w7 O+ E
  866. /*                                                                                                                                                */" v3 \7 {3 ~' D5 l. O7 a
  867. /* This procedure Sector Erases the Chip.                                                                */9 B& `/ ~7 }/ A) J- g
  868. /*                                                                                                                                                */0 J; t% p! F2 o; P2 I
  869. /* Input:                                                                                                                                */
    & M8 ?4 {! _* Q
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* k7 A9 e+ F) Y, m
  871. /*                                                                                                                                                */5 v  ?! s! B# Y6 I" [' V  S" A1 J
  872. /* Returns:                                                                                                                                */1 I2 C3 G; {+ x1 @4 D0 k
  873. /*                Nothing                                                                                                                        */
    ' u& h. I; [" u/ o
  874. /************************************************************************/* C6 {9 D5 R  \) w. q
  875. void Sector_Erase(unsigned long Dst)7 k7 z- |; {- u* a$ l: j
  876. {4 a* C/ W( o/ B6 J/ D

  877. * ^& N, Q. j) b+ o* s
  878. . G$ ^  U( d2 K! E5 q% c
  879.         CE_Low();                                        /* enable device */- `# g" A! R: V/ q' k5 q
  880.         Send_Byte(0x20);                        /* send Sector Erase command */& [4 p4 `; R+ H: ~5 ]# P
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 k/ p& I2 J1 \0 J& k) E
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % x2 _3 D$ r7 m2 B. L
  883.         Send_Byte(Dst & 0xFF);
    ; b# @! E# b6 j! l
  884.         CE_High();                                        /* disable device */
    , g/ |6 R5 G! ~7 y4 ~  B5 d# M# t
  885. }       
    ' I: L3 T: S3 m! w/ Q
  886. , m" q8 [& y' n. J4 l( v1 }
  887. /************************************************************************/
    1 h, k, s" ^: S# h+ j, \
  888. /* PROCEDURE: Block_Erase_32K                                                                                        *// T: ]; U! e4 v1 M3 K& k( H9 f; n  u$ t
  889. /*                                                                                                                                                */
    6 Z) k/ M4 b/ \0 U3 Q& X' `# _# p, L/ P
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */# D( q# {# {) {4 n1 I5 ]! e  A
  891. /*                                                                                                                                                */
    $ W% n; z% y8 i) P1 V: r+ R
  892. /* Input:                                                                                                                                */. ?# Y1 i$ ^+ f' S( d+ k
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 {/ U% v4 `- Q3 K
  894. /*                                                                                                                                                */
    ( t1 y7 m6 c  x) j) s: d" m0 ^+ d
  895. /* Returns:                                                                                                                                */
    ' q5 K- N$ o* w0 u) e: s" }
  896. /*                Nothing                                                                                                                        */
    7 u5 Y( l* L" o5 @1 N
  897. /************************************************************************// c2 b# M6 s  D7 e) X6 z4 a) D
  898. void Block_Erase_32K(unsigned long Dst)2 J& I, ]1 P9 j- t  i" |. k
  899. {
    , n+ b# r6 }; ?* Q
  900.         CE_Low();                                        /* enable device */
    & }+ l" H0 R+ O7 q: A
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */6 D0 x) ?: b) b7 P
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      `8 h' r; W0 W) D* M* I" {
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & _/ d/ a9 B0 N. l% v2 I
  904.         Send_Byte(Dst & 0xFF);' n7 p" m3 K& B* t
  905.         CE_High();                                        /* disable device */
    2 }4 ]5 K4 Z& a2 U0 H; A
  906. }
    + E+ X& ^# w! W* d) a
  907. 8 @5 V) ~; V/ v4 I6 `
  908. /************************************************************************/
    " h( I# [5 l  G9 f3 N
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */0 t3 O* T& H  t- W
  910. /*                                                                                                                                                */) X2 B" Z; k, J0 a: A
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ' Y" d: R& I  l6 F# y
  912. /*                                                                                                                                                */
    7 y$ s1 D+ r- m6 t
  913. /* Input:                                                                                                                                */7 E0 D8 J: E% G! k/ m' a
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */- t7 p4 g' S4 ]8 |6 h8 x
  915. /*                                                                                                                                                */* B: ^' ^  i! }
  916. /* Returns:                                                                                                                                */6 n6 L8 |. S3 u3 T$ a
  917. /*                Nothing                                                                                                                        */
    / g9 s, m- K: p
  918. /************************************************************************/) q1 o: R" ~1 S" \6 c
  919. void Block_Erase_64K(unsigned long Dst)& m+ X& k( G3 \/ [( b0 J0 ]' F
  920. {
    1 K- A! o5 Q9 H" ]% Z
  921.         CE_Low();                                        /* enable device */0 q: o7 r1 g; o
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */. r$ r" d2 d4 e
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 Z- h( e1 p! m3 r$ C
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 O. o% N7 g- s+ Z9 h% O( R: `! q
  925.         Send_Byte(Dst & 0xFF);
    8 u' o3 \3 m# B% p1 t, D; N6 b
  926.         CE_High();                                        /* disable device */2 ?5 Y5 b6 `) y
  927. }
    # w! C) a5 t8 K- v
  928. 3 I$ C# \6 H* h) Z* L( E
  929. /************************************************************************/
    . M; `# x% I! C
  930. /* PROCEDURE: Wait_Busy                                                                                                        */: ~7 Z) Y7 _; W5 }5 E8 F
  931. /*                                                                                                                                                */. S- U. m. J% @
  932. /* This procedure waits until device is no longer busy (can be used by        */: a# I1 m/ `8 S  t, L
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ! I# b, M, L* M, ^' X: x
  934. /*                                                                                                                                                */- k! Y1 h1 w% v& \% ?" h* |
  935. /* Input:                                                                                                                                */
    . J7 n; c# ?  v: i( ]4 ^
  936. /*                None                                                                                                                        */
    / H+ \9 U1 U! Q# T3 E# z5 F
  937. /*                                                                                                                                                */3 C' R- T6 g! h& W. g) l; ?
  938. /* Returns:                                                                                                                                */0 _* P; a( d9 D# B. t) w
  939. /*                Nothing                                                                                                                        */- v' G2 q. q5 m( N
  940. /************************************************************************/
    ! l3 n: G4 e/ W, P& m& a0 x
  941. void Wait_Busy()
    6 R$ e8 Z. D4 U' @6 f0 |
  942. {. S  z  ^* }0 m- D  o6 Q
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    9 {$ N" s* W! h4 C
  944.                 Read_Status_Register();0 i) I% P( f1 W( P
  945. }9 P' @1 ?  a! T0 ^
  946. * V$ n0 D  a4 a, v6 [# M
  947. /************************************************************************/6 W$ u, _1 \$ _. \
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */! `, P; w) ?) D; _! j' P
  949. /*                                                                                                                                                */, p6 Q+ h2 W) b1 s' q
  950. /* This procedure waits until device is no longer busy for AAI mode.        */) A8 _1 S( a8 Y
  951. /*                                                                                                                                                */+ i. U9 g2 z3 s3 D- ^( F) Q
  952. /* Input:                                                                                                                                */
    * P, j, r7 a% P7 ^- O
  953. /*                None                                                                                                                        */
    3 L6 {9 T# c  T" Q' I
  954. /*                                                                                                                                                */, E4 v+ d/ D4 }8 s3 w
  955. /* Returns:                                                                                                                                */
    6 ~) j& U1 t1 s: n# ?! [
  956. /*                Nothing                                                                                                                        */8 Y" n! r/ _9 A9 ^3 c9 c
  957. /************************************************************************/- A7 f9 p7 q' N, X2 U; B2 Z8 y
  958. void Wait_Busy_AAI()
    6 W% o. T# `) g/ k6 I  V
  959. {
    1 w" M( g" a& P6 z) b; Q+ s
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    + ~- I3 e9 X% ?( g+ Q/ S
  961.                 Read_Status_Register();/ t  W  ~6 A8 G# r0 M: ]
  962. }
    ! y7 Z* O# B1 C/ A! m3 t: c

  963. / l! i( r7 ^3 Y" y& f
  964. /************************************************************************/
    / s1 @/ a+ E8 n+ v6 |; [* i
  965. /* PROCEDURE: WREN_Check                                                                                                */
    ; z) p3 \% U4 A9 ^! d6 z) M
  966. /*                                                                                                                                                */
    1 k3 L) l! E) R1 H3 E8 X4 W
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    8 q/ r6 S  k# J* n
  968. /*                                                                                                                                                */
    1 z  J- l7 c5 Z7 U* f$ t- R
  969. /* Input:                                                                                                                                */
    , u* o5 Q  D: g& k2 L$ {
  970. /*                None                                                                                                                        */! F: c3 s% P, f. i, D: p
  971. /*                                                                                                                                                */" B0 k4 @9 }9 m+ M6 v: O/ C
  972. /* Returns:                                                                                                                                */; z/ K1 G# T4 o' F8 s1 m0 h
  973. /*                Nothing                                                                                                                        */
    + ~. Z. Q  k/ `( m
  974. /************************************************************************/
    4 O7 s- r7 l6 m% H* x9 G* r9 E5 f" Z
  975. void WREN_Check()! E+ |8 ?) D" `: c
  976. {
    8 d, c6 C; z" b! y' h
  977.         unsigned char byte;
    $ d& m" r9 Y3 N. Q+ ^
  978.         byte = Read_Status_Register();        /* read the status register */) r: ^) \0 `* U7 X5 P
  979.         if (byte != 0x02)                /* verify that WEL bit is set */$ g$ D) L. E) X
  980.         {
    # U' {3 D5 F  J, Z- `$ `& U1 U
  981.                 while(1)
    " B2 G8 J. \) e& D
  982.                         /* add source code or statements for this file */  z9 e3 ?; g( w: }; O
  983.                         /* to compile                                  */
    . D$ X5 a2 c& k- r# x  L+ h$ n
  984.                         /* i.e. option: insert a display to view error on LED? */
    4 N% O/ r0 L  P$ N5 p
  985.                  , P# M0 `8 O$ Y6 `/ ^% s% @
  986.         }% M8 q( H4 S$ e& |  {6 L5 e6 {& Y
  987. }
    5 g0 ?' V* D+ B- A6 \

  988. ! z) {2 {; v$ q, j: `
  989. /************************************************************************/+ F1 {* t/ u1 s. d! O: [5 D) q
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ) {% Y3 t7 `1 r6 Y/ J' t  f
  991. /*                                                                                                                                                */+ m  @. J  G/ W# j7 ^- ]" |: `
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    7 K  r( |9 ~* e; \5 }9 {
  993. /*                                                                                                                                                */
    % C% I) i/ m, W  C
  994. /* Input:                                                                                                                                */0 t# n$ [2 l; \' J4 S! C; ]0 [
  995. /*                None                                                                                                                        */5 }9 E0 X6 ]5 ?! p
  996. /*                                                                                                                                                */6 Y- U$ G& Q' J% T9 }& v* M
  997. /* Returns:                                                                                                                                */5 [6 Y3 i4 F4 ^5 k
  998. /*                Nothing                                                                                                                        */
    7 a, W0 {' E* o. q1 A
  999. /************************************************************************/* N/ O) \' {' ~1 r% b
  1000. void WREN_AAI_Check()% k1 O" N) H. H% I0 _) V" H8 M
  1001. {) N4 _  g# ]* g2 i
  1002.         unsigned char byte;: U" z$ q. P& }6 U& r! x, @& C
  1003.         byte = Read_Status_Register();        /* read the status register */
    $ i) H0 J6 ~& u
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */% g& i- L! T  p$ J
  1005.         {  l8 p! B5 V7 x' a
  1006.                 while(1)                ! b; o5 D$ u/ Q$ e+ q3 B
  1007.                         /* add source code or statements for this file */- d7 ?2 q' P& ?" S7 ^* S, c
  1008.                         /* to compile                                  */3 t0 I: L& a8 r( @" R/ p' H
  1009.                         /* i.e. option: insert a display to view error on LED? */
    + J1 f$ g- Q4 U4 U# j! L) S
  1010. 2 `* ^: j( U; U) k4 D9 G8 }1 \5 j
  1011.         }
    * a, _0 x: x" K/ C$ I, L! o
  1012. }
    ) J. }$ h- l; s' S3 @

  1013. 9 n8 ?  ~+ R- k
  1014. /************************************************************************/( p* j6 K* `/ {% f* b- Q
  1015. /* PROCEDURE: Verify                                                                                                        */. r+ e* t% N; T: n
  1016. /*                                                                                                                                                */
    5 M. O' x3 `% o4 n9 s- \) |; x& u; g
  1017. /* This procedure checks to see if the correct byte has be read.                */$ r% `; ^; T7 E+ i) F
  1018. /*                                                                                                                                                */) T9 w' t0 }+ k
  1019. /* Input:                                                                                                                                */' z; p$ x5 T3 `; Y* ^+ Z8 H
  1020. /*                byte:                byte read                                                                                        */
    6 E( t, g( u! L" o) G
  1021. /*                cor_byte:        correct_byte that should be read                                        */5 ]: a. e1 D  n) G) E1 N2 T
  1022. /*                                                                                                                                                */
    % o9 V$ ~8 _1 U! J( I$ H
  1023. /* Returns:                                                                                                                                */
    + s1 d: X: J. b
  1024. /*                Nothing                                                                                                                        */! B. x) ?" c" D/ h! L+ @' n  q
  1025. /************************************************************************/0 L: n  k6 B6 d, l2 n- Y
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    0 s$ z+ [3 E. m" I4 A7 b0 w  \# R* |* I
  1027. {( w# |6 u8 ^8 B$ z8 N9 j
  1028.         if (byte != cor_byte)  X8 A. c( i2 B& ~; i* T- e
  1029.         {
    ( R2 m# h# Q/ ?. M$ n
  1030.                 while(1)
    2 @" q) G( x& c5 J7 w' l1 O
  1031.                         /* add source code or statement for this file */
    2 v- S# K: A4 l0 h8 ?
  1032.                         /* to compile                                  */! d, k! a1 k3 N) K. D
  1033.                         /* i.e. option: insert a display to view error on LED? */
    # h. C5 E9 ^' h( ^2 P" V0 ~- E
  1034.                
    ' j) c. [2 J' x: v9 U2 m  Y
  1035.         }: Y( D- d3 t, T2 e1 \: Q1 d
  1036. }
    " B8 l  S- f7 G2 m7 p# i' \
  1037. ) m% o6 c( e: j& b+ U/ ?" N$ ~

  1038. 4 U) N  t2 U2 d: B1 s) r2 U0 \# w! w
  1039. int main()
    2 i3 S  ?/ r* l5 e+ i: @
  1040. {
      l( {& |/ {- p# N8 _9 E
  1041. % z- e3 L6 D' E) X$ e" g8 a
  1042. return 0;
    # j1 G! {9 ?" ~" {+ g. c
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
( Z- \" C  M6 u& d2 Q   main()
9 q2 u+ `9 d, o1 Q$ m5 v1 O   里面怎么是空的呢?2 ^, Z0 a* T5 h  @  Z6 G+ b2 k; w8 l) P
   发一份给我吧# |* L  N$ K( j% a$ y  W
mail:luyijun2005@hotmail.com7 a( |; d. u( k% c
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。7 T' M7 p( p5 T! B: m) A

+ g+ e$ e' k6 l+ y0 C8 X( p[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
! W6 Y$ C0 x+ r; C) I7 cEC的代码在哪跑,你看DS的说明,每个EC都不同的。
- z+ N) p: V  U( x3 F& q. lOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?8 Q, `- [4 g8 r2 D9 m" g) V9 A; Y0 Y
上面几个问题是你没看任何东西而白问。  \, _; d0 j: |" I

+ o, M. E$ b# `6 `5 t. t至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

9 u2 m& G* c& R" v  ^$ f关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!9 q: u) S. i; j4 u# a" J2 x  q

5 E' A5 ^% `9 V' R6 s关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”" x- ?/ Q& j* \; _. U( a4 S% G' ~
0 S- @+ O2 R  N1 U3 P) v0 \/ c
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
$ U+ ^( {3 Z% B- H8 ~, k  m: p
3 ]# {+ |3 |6 \  T0 p/ G, K5 _不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样8 E% x- y2 _2 q9 E
似乎要把SPI能support 到最大,这EC chip应该有好卖点
$ s  `! }1 b' H' T# N" x2 ZBIOS功能要不要强大,也就决定了SPI Flach的大小/ x/ x' _  E; j6 V  {/ ~0 `- P2 o
我是这么想的~让OEM去决定要挂多大!; Z* y2 K2 \7 k$ \: b2 Y
如果我司有BIOS工程师就好了~哈9 X' M$ R  M$ {7 T( [
WPCE775应该算很新的东西,来看它支持到多大?4 Z5 y% S& y4 k  X
5 q  g  e$ _+ t- E0 \4 p
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte, R( M" I0 q% g% r
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
* S' y! u$ r0 D$ j8 L9 V7 V4 x% q( W+ o
这份driver收下~希望以后有用到1 |. J" h( F0 V
谢谢bini大大; ]  ?5 P9 K8 T- F9 [' z9 u$ Y4 o

) _6 `2 F" c$ e很新很新的新手,如有错误请指正 (准备看第二家的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(): K; R: J  p9 `0 w  A' d( f1 b
{
- {+ ?  b/ E# c& @2 N6 U        unsigned char temp = 0;
" @( f7 p. y& b; t$ ]        CE_Low();5 C2 {4 w! k. z/ h
    while (temp == 0x00)        /* waste time until not busy */; N" Z* M8 f* G. ]0 {+ U
                temp = SO;6 P' p4 Q5 A* @9 ?. H, O
        CE_High();
. \4 H/ ~8 |; V# N5 d}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)  l: n: E- P/ U3 @; Y
{
4 l) g$ Y: k& E! j: c        
8 }6 M1 o5 {' c  [; G# d9 ?; N        unsigned char i = 0;
' e( T0 j, A0 N6 X        for (i = 0; i < 8; i++)" Q) X! E6 M$ J2 f( `9 J" y: w/ d+ A" p
        {
7 B/ Q% C) l* w) ?                3 k$ J4 Z2 s" Q; k* P1 K* N3 [7 @
                if ((out & 0x80) == 0x80)        /* check if MSB is high */$ d( A8 r+ t. l/ U
                        SI = 1;+ e1 i1 @9 s/ B2 J
                else
) \! z: e: a& w2 p                        SI = 0;                                /* if not, set to low */
. b; \9 `1 E" [/ I( ?, O 问              SCK = 1;                                /* toggle clock high */  v' C+ c, P. ]* @; \: E3 K2 E, X- a0 p
   题            out = (out << 1);                /* shift 1 place for next bit */  ~2 v* h1 d' u* @1 j0 n
                SCK = 0;                                /* toggle clock low */" e6 }+ ?& g( v! ~) E) g: o1 I
        }1 `- B2 ?" e: D- }% N# f  _/ w$ [: N
}
5 [. q! t$ \% y 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-21 02:15 , Processed in 3.646106 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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