找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55976|回复: 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. S/ [9 y$ q% K

  2. & e/ M- K% N! t. p2 x2 T) h/ s/ v7 S' I
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    6 v4 t$ j$ k6 s% Z$ `
  4. 3 u, E" e, L  a! E1 F- g1 ^4 n/ y
  5. November 4th, 2005, Rev. 1.0
    7 F; |! j) T0 p8 J9 c8 F5 @  W  h  j

  6. - ~7 L2 E- r: ]  f9 [  v
  7. ABOUT THE SOFTWARE  p+ {0 e7 t" E$ a( i
  8. This application note provides software driver examples for SST25VF080B,
    # |7 a* [- y6 f0 j! X9 |- _
  9. Serial Flash. Extensive comments are included in each routine to describe
    ; I9 w0 \$ G( k3 n5 _
  10. the function of each routine.  The interface coding uses polling method
    1 D. _& Q  }, U) ^. t# c
  11. rather than the SPI protocol to interface with these serial devices.  The; X' R/ m: i& ?* f* h" |
  12. functions are differentiated below in terms of the communication protocols6 S9 ]9 X/ g6 [, }4 x/ i: s+ _
  13. (uses Mode 0) and specific device operation instructions. This code has been ( L7 y7 V0 k3 M1 `
  14. designed to compile using the Keil compiler.
    - T  [: f: n0 f5 }" H
  15. : q5 S* Z; Y) Z2 o0 U/ ^
  16. . s  ]  B$ G7 z1 U$ U8 V) w: V
  17. ABOUT THE SST25VF080B
    ) |2 l, ~, T8 L* a) e' c7 Z

  18. ) P1 `, t& E1 E1 U0 G+ I1 D! |2 j
  19. Companion product datasheets for the SST25VF080B should be reviewed in ( L1 X! R6 O* `! ]$ T8 f
  20. conjunction with this application note for a complete understanding
    ' m) L" u0 q, H
  21. of the device.
    3 U; L, L$ r7 `% E

  22. & Q( e! H! g) a3 z, ]

  23. 8 B& e' @$ [3 i4 m3 ~
  24. Device Communication Protocol(pinout related) functions:6 i2 H- ^3 D9 ^0 m
  25. 1 [* A) y  U2 ?: Y6 x7 E1 T
  26. Functions                                    Function
    2 ]" ^% P- _- m) u
  27. ------------------------------------------------------------------# @$ z4 }, c5 u5 k$ w7 F! Y% j
  28. init                                        Initializes clock to set up mode 0.; v" }8 L6 O) T# z7 D0 S
  29. Send_Byte                                Sends one byte using SI pin to send and : X( b) k# R1 v/ k4 m7 v
  30.                                                 shift out 1-bit per clock rising edge7 r  A* a( G; a, T
  31. Get_Byte                                Receives one byte using SO pin to receive and shift # g) C7 I. `. e5 r0 ~+ U2 m2 z
  32.                                                 in 1-bit per clock falling edge3 O0 U7 l( w  |; R7 E
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming7 l! k; s% `4 ?0 ]$ R
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high# G( Z! M4 t1 }* X  e+ ^, ?: p8 h
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    : \9 d7 ]: G, s* a! ^$ f5 Y+ a
  36. Hold_Low                                Clears Hold pin to make serial flash hold$ S: B/ G, j( k7 w
  37. Unhold                                        Unholds the serial flash
    , f+ b: F: |8 {. N! f1 o
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    + M$ ]# G' N! c( p: k
  39. UnWP                                        Disables write protection pin
    1 y* Q$ U* Q! l# [2 ?  V3 z

  40. ) G: V$ c* h5 h4 M3 Z
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    3 ]* z; I5 s3 q. D8 T3 o
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your5 ^4 E- G( m0 |# _/ `
  43. software which should reflect your hardware interfaced.          % F6 u: [$ R% u" Q) Y0 N
  44. 1 L2 L) B" P" L$ K' X

  45. ! B" _1 V+ h" d
  46. Device Operation Instruction functions:
    3 D+ _% S0 p& v3 j
  47. , L8 Z3 f* A% R8 A) x& T" u
  48. Functions                                    Function
    - {' Y8 t7 w4 C
  49. ------------------------------------------------------------------
    ( ]  t2 P% s5 O- j4 L
  50. Read_Status_Register        Reads the status register of the serial flash
    - l' ~3 K2 M4 p6 D' Q* C# @
  51. EWSR                                        Enables the Write Status Register
    & v. U0 g3 b& I/ g# l0 T, g4 d
  52. WRSR                                        Performs a write to the status register( ^0 o- h, L7 q2 U6 V" i7 W  u
  53. WREN                                        Write enables the serial flash
    - R) V, Y9 R  H$ d0 a: j: w
  54. WRDI                                        Write disables the serial flash% B# v. o2 H% p& v. J$ |- J" ?
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    7 M/ `' }+ Q* `% E
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming$ U% i9 A, Z# k. o; Y
  57. Read_ID                                        Reads the manufacturer ID and device ID1 \% O5 W0 H) h6 h$ W9 P: a+ w8 L
  58. Jedec_ID_Read                        Reads the Jedec ID+ t& s" T# j, d- Y3 Z
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    7 x% T% f7 e4 @3 O" p1 {# t
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)5 G4 C1 f% F+ y1 @# Z
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)4 X( @0 a) G* k
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    + J  m/ e4 e1 N* g* o$ S6 H
  63. Byte_Program                        Program one byte to the serial flash0 h" P$ c$ k6 W/ m
  64. Auto_Add_IncA                        Initial Auto Address Increment process0 C6 H" l0 h+ i
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation) \0 r) K7 p! }7 X/ F% i8 ~+ H' T
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY; _: D6 m. K6 J( E) t: P
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    2 N* c; C0 w# z- |2 N8 z6 W
  68. Chip_Erase                                Erases entire serial flash
    ) ?* w! O; B# K' D* C7 Z+ e! V0 r
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ( t1 u8 D$ d3 G1 o0 v
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    4 j4 ]+ E0 y. o7 d
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    6 F5 `$ p1 E& s
  72. Wait_Busy                                Polls status register until busy bit is low  W% Q. W* N9 n' t4 z6 y
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming2 G; N5 H- ]. l7 H
  74. WREN_Check                                Checks to see if WEL is set. B- Y/ n, P: S/ d  e, P6 K
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    8 C* Z( v7 e+ g6 w: [6 k( n" y

  76. ' t% B" @5 m9 k7 Q. W
  77. 0 T2 ^: @/ _4 k" |
  78. , O9 n% k2 A+ I. f5 L
  79.                                                                      
    . F8 u0 `$ ?, J) _
  80. "C" LANGUAGE DRIVERS
    - `3 ^2 Z) N( I& A
  81. 8 B0 C& T: C5 N  p# [
  82. /********************************************************************/1 B3 J; V+ F; z) p7 ^0 I, v: h
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */* V  [' m5 ?5 o, s; `6 j6 u
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */: I( F0 H, z7 G* {, Y: h' I2 I6 L
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    4 f3 e2 Y1 x: o$ w  c. ~
  86. /*                                                                  */0 [" T, p8 I  n  |2 z
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
      G" w& s' N) N7 k
  88. /*                                                                  */6 C: `6 e3 ~/ `2 h6 [
  89. /*                                                                                                                                        */
    0 c% u3 U4 \1 L; t; c
  90. /********************************************************************/
    3 h" m/ _+ L8 R) Z5 d
  91. 1 x1 X1 W* Y* G$ l
  92. #include <stdio.h>3 q; L' U% Y& s0 Z" F3 T9 w
  93. #include <stdlib.h>& J  m0 X" A! Q) O$ q- W6 p
  94. . g4 d" M1 i8 N3 N; g
  95. /* Function Prototypes */3 E1 K6 V& r; e0 R& C! e7 t
  96. + ~/ d: ~2 L* g
  97. void init();+ m  {7 m+ X! k! |9 C
  98. void Send_Byte(unsigned char out);9 [/ y: @( R! i7 @3 Q+ p
  99. unsigned char Get_Byte();3 z* y( w, X  V" n  r0 B; h
  100. void Poll_SO();
    ! c9 E+ m- |" I% n
  101. void CE_High();; }* R8 `- F" p/ |, s5 H6 z! z
  102. void CE_Low();
    / w- t! Z0 g$ e2 ?' L
  103. void Hold_Low();' b7 h3 x8 N  G! a1 g% O( D
  104. void Unhold();
    ' _- H; F( ?6 u- U: a7 r
  105. void WP_Low();. y& B8 p5 u7 ^. K) ^
  106. void UnWP();
    / M, U4 ~5 [' l
  107. unsigned char Read_Status_Register();* q6 P1 v% ?% j4 j  i6 U0 E
  108. void EWSR();" |1 T3 _9 i% |" b3 C4 y
  109. void WRSR(byte);
    $ J' Z2 R; R5 s5 X7 t- n0 N) [; _0 N
  110. void WREN();0 i- N. R  V- A9 |  U9 R0 @
  111. void WRDI();" p1 V0 ]  @1 i! J: _
  112. void EBSY();: Y& k4 ~" U2 a3 F; P+ @
  113. void DBSY();4 G1 Z3 z, z/ N0 v& b, t# i
  114. unsigned char Read_ID(ID_addr);  q5 Y* @9 K+ g5 \* ^2 Q9 [! j
  115. unsigned long Jedec_ID_Read(); 6 Q4 d# `' p% k
  116. unsigned char Read(unsigned long Dst);3 W' ]" o: ~( L! U
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    7 u8 `; f9 B1 f. O) y4 V9 Z
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    & n& M* @# N# q. h! `7 |1 O
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    / [* w# i, O: T! r1 `; P
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    6 P' t! M1 H; n- ?1 M
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ( g3 S: I* N+ N$ U! p) s
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);; B5 h9 `3 g& @, j) l* x3 s8 ~' [3 M
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    6 q9 c( @" g2 y2 P8 i
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    2 S9 ?, H: s% U4 `
  125. void Chip_Erase();# h! l7 a. }* \3 E( n2 Q1 K
  126. void Sector_Erase(unsigned long Dst);
    + t2 l, R" F: _4 K4 J1 M0 I& K; F
  127. void Block_Erase_32K(unsigned long Dst);$ B, ?" h, e  F2 ]# Y( o$ h
  128. void Block_Erase_64K(unsigned long Dst);8 X% A. f3 J3 w
  129. void Wait_Busy();7 J; r) G* ^9 `2 \( U* \
  130. void Wait_Busy_AAI();
    8 A1 Q" F& ]. a. f* o
  131. void WREN_Check();
    7 b" I5 Y0 [( {5 s4 Y4 m# `* A5 V; T
  132. void WREN_AAI_Check();3 c9 x( d+ d5 L( j2 {* ]
  133. # U+ N8 y; K1 i
  134. void Verify(unsigned char byte, unsigned char cor_byte);4 d9 t- N" j8 u1 ]' W! f
  135. 8 O/ g8 r# X3 Z8 S, }
  136. unsigned char idata upper_128[128];                /* global array to store read data */1 D7 G' z. p* s; ~/ @) b, [7 Y0 r9 D
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    ! _) `* z9 }3 J" X+ V

  138. 5 [/ C4 [/ r+ C, p+ x8 m
  139. /************************************************************************/
    2 m% s4 _: ?, U; l% Q' v; r
  140. /* PROCEDURE: init                                                                                                                */% Y; I  k: P0 J) H. e( a$ A
  141. /*                                                                                                                                                */
    ( I- g. u/ B1 s9 }$ ?8 J
  142. /* This procedure initializes the SCK to low. Must be called prior to         */  o+ S4 V; x5 W" x  V$ x! A. \
  143. /* setting up mode 0.                                                                                                        */
    5 }% }8 [9 Q3 }- E
  144. /*                                                                                                                                                */
    5 Y6 T+ a) o, ~) s
  145. /* Input:                                                                                                                                */
    2 k8 `; t" f9 S$ B
  146. /*                None                                                                                                                        */
    4 H: `7 Q* Y; J5 f
  147. /*                                                                                                                                                */) i' c) Y* v% ^8 S3 N3 l9 C
  148. /* Output:                                                                                                                                */
    * g8 o5 Y' a5 T% R5 u
  149. /*                SCK                                                                                                                                */
    + n7 @7 L' I- A& B$ ~
  150. /************************************************************************// j, y# y( u7 O: f
  151. void init()
    7 ^5 s: n& R3 ^; g1 G8 @  y! d/ o# Y
  152. {
    , N. o+ L2 U% l" V
  153.         SCK = 0;        /* set clock to low initial state */5 W5 y3 s* q/ j5 C% L
  154. }* t9 ~/ b. S8 T+ ~
  155. 9 M- ^) \3 @* R9 x
  156. /************************************************************************/4 d9 g/ W8 t$ ~# b
  157. /* PROCEDURE: Send_Byte                                                                                                        */  @7 T" R, ]6 G1 I8 S, o) P% z
  158. /*                                                                                                                                                */5 A% o0 B& D& s8 D6 g; i, f% f) I
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */. E# o8 L! M1 _# x
  160. /* edge on the the SI pin(LSB 1st).                                                                                */7 G9 X$ X7 R. }+ L1 a/ N# a
  161. /*                                                                                                                                                *// h! E# x$ O; k( Q% `. I6 o
  162. /* Input:                                                                                                                                */
    $ G$ M% |5 `+ j' ?3 O
  163. /*                out                                                                                                                                */3 w: ^* U; }5 X" U, w" G
  164. /*                                                                                                                                                */+ b) e6 k) W9 V- {
  165. /* Output:                                                                                                                                */, k8 u3 y  Z# y9 K
  166. /*                SI                                                                                                                                */2 O6 ?$ Y9 N" U2 L* g
  167. /************************************************************************/6 D; J3 A2 G2 N9 F8 B% v
  168. void Send_Byte(unsigned char out)1 z2 o4 p5 C) N1 X, i0 c2 ?# z: E
  169. {3 u! G4 q1 J7 `7 ~: U/ F& V
  170.         2 k9 t! w8 S4 V5 n3 X# P
  171.         unsigned char i = 0;* ?# j9 D- G9 }9 W
  172.         for (i = 0; i < 8; i++)6 X4 F! |3 ~' L2 R
  173.         {) S# G0 e. u: x8 T2 D
  174.                
    . H- _, n; e& W
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */: D4 ^4 m' q. i6 ]. R4 p+ C
  176.                         SI = 1;. K- N6 ?4 Q. B' o7 D9 O* ?# i
  177.                 else
    # ^- b# d: w2 b) t: N
  178.                         SI = 0;                                /* if not, set to low */
    $ e& v" q" G& n  x; t8 g
  179.                 SCK = 1;                                /* toggle clock high */
    5 a- L! ]  o1 o3 ^
  180.                 out = (out << 1);                /* shift 1 place for next bit */) G+ V2 |! P/ Q/ y/ @
  181.                 SCK = 0;                                /* toggle clock low */
    " B/ d, C$ p3 R
  182.         }9 K1 n7 h: f: e: F
  183. }7 ?4 e, C6 u3 _0 n0 Q3 f' R& h# [1 D
  184. + u; r, h& e3 ?; F" \5 `9 K
  185. /************************************************************************/  ^, d- S, R/ m* ^7 k: E8 _
  186. /* PROCEDURE: Get_Byte                                                                                                        */( \# x8 _4 a+ l0 k; D) b  t" X
  187. /*                                                                                                                                                */8 s$ [- n2 H5 U8 P
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    7 @- }9 `- t+ k1 H  O2 v
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ' N# H  y; M7 k5 [
  190. /*                                                                                                                                                */
    ) J& _' ^& M5 y( e2 A
  191. /* Input:                                                                                                                                */
      Z- _3 d, y% ?1 r" n
  192. /*                SO                                                                                                                                */8 O  P- X. u1 T3 W/ E$ }/ j
  193. /*                                                                                                                                                */' f" S' p; @( O1 p
  194. /* Output:                                                                                                                                */) F' }6 f4 _/ e2 t) v
  195. /*                None                                                                                                                        */& m+ ^; g6 ^; ?+ H: w* Q
  196. /************************************************************************/, k" J% |7 l5 F) e& U' O
  197. unsigned char Get_Byte()' R0 S) o- Y: N- I" f, }
  198. {9 ]( B  b- ^3 v1 O  d% ?% ^) d5 `( @
  199.         unsigned char i = 0, in = 0, temp = 0;
      e$ {; H" t% @3 x9 C
  200.         for (i = 0; i < 8; i++)
    ( J7 X$ _7 s  p* t
  201.         {5 o. o1 C# ~* k5 `* _
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    7 J& m0 Y7 b4 A! i
  203.                 temp = SO;                        /* save input */9 k% w. x- D" \. J0 ^: H1 e  l# l, A* d
  204.                 SCK = 1;                        /* toggle clock high *// q1 R* ^% b& k) e. Y# v. ^5 P1 @% l  T
  205.                 if (temp == 1)                        /* check to see if bit is high */
    8 K0 h0 y8 X% ~5 ]' U- ^
  206.                         in = in | 0x01;                /* if high, make bit high */
    4 D( ?; _. a$ J9 \4 w
  207. / {" B4 s8 M. C7 j6 u/ {' B/ A1 G
  208.                 SCK = 0;                        /* toggle clock low */
    * V; s1 n2 Y7 ]3 Z2 X( h

  209. . m1 M. ?! g/ c# [4 P
  210.         }7 ]" h! K3 b9 M1 c+ U- l
  211.         return in;
    ( h, W, J! X2 H! u( H6 z4 ~
  212. }8 f. ~2 Y: }0 ^1 S+ E; l* d3 ?( G

  213. / Z  |6 `. y6 F; ?' G) A/ M
  214. /************************************************************************/
    ! W" B" o, b! h6 V2 n& L
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ; b$ h" \# V; |6 u
  216. /*                                                                                                                                                */
    $ e; l% |6 K5 t- {
  217. /* This procedure polls for the SO line during AAI programming                  */
    . y$ i/ b  l7 J6 p' ]9 d
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/4 J" W- [* k/ R9 L5 n1 n0 y% v- T' ]
  219. /* is completed                                                                                                                        */* w7 ?" |1 A$ G7 P5 r% @
  220. /*                                                                                                                                                */
    ; _/ z- ?5 @1 p- S6 i/ o  q
  221. /* Input:                                                                                                                                */5 e6 e6 ^  Q, z3 ?
  222. /*                SO                                                                                                                                */
    ) h$ Z9 ~( v. t* B  o
  223. /*                                                                                                                                                */
    4 o/ P$ P# x9 ?
  224. /* Output:                                                                                                                                */
      N( z; K" r% Q" [( k2 E- v
  225. /*                None                                                                                                                        */
    6 F$ C. Y: v4 D. c! U- j: H( @
  226. /************************************************************************/
    ( C: f& b9 \  x; T% I7 ]
  227. void Poll_SO()+ Z  m% k) g% b  m/ L
  228. {
    9 P( W* J; y. K% F2 v
  229.         unsigned char temp = 0;
    1 q: }5 ?3 }$ X* a/ D* J" g
  230.         CE_Low();
    6 ~0 _! T! q5 @* }$ u- `
  231.     while (temp == 0x00)        /* waste time until not busy */  \6 |) j3 j- d: d
  232.                 temp = SO;0 k& R6 N- u5 S+ u7 K& `) R
  233.         CE_High();  D& S+ J1 E: D
  234. }
    + X  F9 a9 b$ T. e& a- M) K

  235. 4 V) y: |- T/ f8 X# n" s& O
  236. /************************************************************************/
    1 o# I6 ?, w$ b$ q+ P
  237. /* PROCEDURE: CE_High                                                                                                        */& l1 o/ ?4 @! T4 Y* p4 x" r) q7 q
  238. /*                                                                                                                                                */
      {5 X( u1 t! g9 ^( K
  239. /* This procedure set CE = High.                                                                                */& h& L3 U1 K" j3 ]
  240. /*                                                                                                                                                */. u' p; H$ ~& V" h) E( _& |8 ~
  241. /* Input:                                                                                                                                */
    ! Q- d/ A% l, @7 K/ t; H
  242. /*                None                                                                                                                        */+ ]5 A2 }4 P* f: f% _
  243. /*                                                                                                                                                */
    . O8 l& C$ G2 l- X( F# m
  244. /* Output:                                                                                                                                */
    5 c  z: _# X% d) |4 X) I. B* l
  245. /*                CE                                                                                                                                */
    ) W' a8 z" B# ^7 Z( q
  246. /*                                                                                                                                                */( M/ [- F  z% R; N* w/ \1 j, s% C
  247. /************************************************************************/7 {  G  L* ]0 U
  248. void CE_High()
    ' }; k/ X$ v* C0 |' g
  249. {
    6 K# p4 p1 x# n/ J1 G) T
  250.         CE = 1;                                /* set CE high */2 I6 X! H' T( h9 ]# l, g0 r
  251. }1 b; x9 g8 ^/ X; s- P1 n
  252. + {6 N& ^; C, k- d& L
  253. /************************************************************************/% P4 f; ^2 K, O
  254. /* PROCEDURE: CE_Low                                                                                                        */' M$ o9 k& q8 }+ ~! Y4 {5 Z
  255. /*                                                                                                                                                */9 T: z3 S2 V! U) O4 j. t& L
  256. /* This procedure drives the CE of the device to low.                                          */
    : K4 d* s; y& F) I4 k0 w
  257. /*                                                                                                                                                */* \" }6 v5 X3 i" F# R5 \1 l
  258. /* Input:                                                                                                                                */  y, D% _; F- ~; u
  259. /*                None                                                                                                                        */- F. m6 Z4 [8 U; U" @4 U3 y1 s
  260. /*                                                                                                                                                */
    6 N& _7 h  [. {( ]* l8 [9 ?; l
  261. /* Output:                                                                                                                                */
    - s* M5 C% O3 O% {: A
  262. /*                CE                                                                                                                                */& D6 a" w% i5 ]9 L5 m
  263. /*                                                                                                                                                */8 {- l$ e  \) y( T8 u6 N% N
  264. /************************************************************************/7 F- p( s4 C$ ~& j) H- q
  265. void CE_Low()
    ( Y8 p: [* ?& J$ R4 T+ Y
  266. {        / q8 c+ H3 g' w2 F
  267.         CE = 0;                                /* clear CE low */# n4 l# x7 \5 w) H0 \" f
  268. }
    . n8 B$ U. ~& `

  269.   [# s- Q' {1 a0 Z
  270. /************************************************************************/% k+ N, @' \$ E8 [5 ~
  271. /* PROCEDURE: Hold()                                                                                                        */$ g1 G1 Z8 T- ]) M1 q
  272. /*                                                                                                                                                */- X$ \7 @( {4 Q  x6 y0 r
  273. /* This procedure clears the Hold pin to low.                                                        */
      B& l4 |7 j- N& [( }) Q0 b' @+ e- n
  274. /*                                                                                                                                                */. [- p8 v* n/ w4 r
  275. /* Input:                                                                                                                                */1 p0 b7 f/ y" c$ X7 C% [' j9 o# V
  276. /*                None                                                                                                                        */' J5 V7 O1 Q+ _! Y2 e7 V8 z
  277. /*                                                                                                                                                */
    " j( A+ @* b' Q) r
  278. /* Output:                                                                                                                                */
    7 t5 H" q8 k  _9 R+ t, u
  279. /*                Hold                                                                                                                        */: X+ ~) ?2 t/ |' {% j6 e
  280. /************************************************************************/
    6 Z' \! i  F1 W* T, I
  281. void Hold_Low()! H4 ?5 O, A4 I" T  s
  282. {' ^5 E% Y1 b7 W$ a
  283.         Hold = 0;                        /* clear Hold pin */
    ) N, p% q3 O- c+ p& t  e
  284. }$ m: r7 V$ o9 o: N

  285. ' H: x7 N& ~6 ~# r9 T5 R- Z
  286. /************************************************************************/& h5 M' G0 R% Z. L: A2 i: R
  287. /* PROCEDURE: Unhold()                                                                                                        */
    7 j/ A! {  E: H1 g' s% r
  288. /*                                                                                                                                                */
    ! N& {* m" k7 Q
  289. /* This procedure sets the Hold pin to high.                                                        */+ y9 `  N7 t6 `& w
  290. /*                                                                                                                                                */$ W. p; C" J* I' ]! W/ a1 p
  291. /* Input:                                                                                                                                */) R; I: e4 [, r) Y
  292. /*                None                                                                                                                        */
    6 D3 z1 P. E4 V$ y8 P
  293. /*                                                                                                                                                */$ r. ?1 K% e- p) v+ T
  294. /* Output:                                                                                                                                */
    4 Y- b7 m$ W9 e
  295. /*                Hold                                                                                                                        */
    6 Q" K6 N7 N! ^: r  ^
  296. /************************************************************************/9 }* w( Q& E1 n+ @& |% @
  297. void Unhold()% `6 k" P3 F% T1 L6 O
  298. {( m/ T  t, z5 B% k" n/ h" G
  299.         Hold = 1;                        /* set Hold pin */+ ^  X  C# q! I/ y
  300. }
    $ q' X8 s5 U& m

  301. . z3 R7 }3 S$ k3 b" S3 h
  302. /************************************************************************/
    8 j3 s& [* A9 }8 I; A; N. V
  303. /* PROCEDURE: WP()                                                                                                                */& m4 D: G9 l) _0 }$ {4 ]4 _/ c
  304. /*                                                                                                                                                *// ]1 t; @2 q/ l; w, ~; x$ P
  305. /* This procedure clears the WP pin to low.                                                                */8 P: @6 K- V9 U: Y& O3 W$ P
  306. /*                                                                                                                                                */
      `! ]. j$ ?4 a) c2 H
  307. /* Input:                                                                                                                                */) N/ `9 b: j0 I! A; |, Q: _; h
  308. /*                None                                                                                                                        */; |6 {/ {; |* Y: T$ r
  309. /*                                                                                                                                                */
    & c) E+ ]. p9 m! Z3 U! x# S
  310. /* Output:                                                                                                                                */
    $ T& f0 y6 @& L3 J5 U
  311. /*                WP                                                                                                                                */. ]' j" p6 D$ _2 z$ D
  312. /************************************************************************/
    - D' X' j% m+ e* r7 }
  313. void WP_Low()6 i/ N- o: I+ P+ e% \5 g+ F: j
  314. {# [' p/ s' z, P9 i
  315.         WP = 0;                                /* clear WP pin */
    ( g. _9 Q& @4 l) l
  316. }
    0 d# P2 |* A# n: w2 f$ ]
  317. 7 h4 V' v: I' y
  318. /************************************************************************/
    ; }% Z8 `( s- ?! S2 K/ u; i
  319. /* PROCEDURE: UnWP()                                                                                                        */1 T3 g" h4 D. L( N! ]3 k
  320. /*                                                                                                                                                */8 f" b" w! B! g9 v
  321. /* This procedure sets the WP pin to high.                                                                */5 n1 \. I; i* A. H  P4 E# B" B
  322. /*                                                                                                                                                */) c7 q* \3 R8 g! a& P: |
  323. /* Input:                                                                                                                                */  F3 ~- m5 Z! M# A
  324. /*                None                                                                                                                        */
    ; @' Q" K! M2 V/ V2 m( X
  325. /*                                                                                                                                                */
    0 _+ z3 o3 J% ~3 }  @/ F7 `+ X8 q
  326. /* Output:                                                                                                                                */2 u$ O& W8 U! p/ c( e
  327. /*                WP                                                                                                                                */
    - l( w3 Q5 U; Z* t  _% E/ j& P, P
  328. /************************************************************************/) C1 V. @! a) D" i% |  l2 f' c
  329. void UnWP()
    - h0 D8 X: d0 J" X' J7 r. v8 K4 J  F/ s
  330. {+ z0 [6 q2 _5 m2 G! ?! n- z
  331.         WP = 1;                                /* set WP pin */
    ! u' C% u& f! D$ M
  332. }
    ! n1 U) w* }$ F6 {- f4 p
  333. 7 T  L: V9 n$ k% H. |' Q' P& ]9 ~
  334. /************************************************************************/9 g, F( ~1 v6 k6 s, v4 p  N) \
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ; {2 x$ f1 G3 {4 |/ ~
  336. /*                                                                                                                                                */
    / f2 V3 @; W' `2 A' O0 {
  337. /* This procedure read the status register and returns the byte.                */
    . ?9 o! ^2 }$ t- g6 k* J
  338. /*                                                                                                                                                */0 X$ Y# f2 P3 A& l6 |
  339. /* Input:                                                                                                                                */* I  E( d2 @. r% C
  340. /*                None                                                                                                                        */; S2 @- y. V" ~1 ~( I5 g
  341. /*                                                                                                                                                */' v) i6 G$ @, r& i& B9 c( n& O
  342. /* Returns:                                                                                                                                */
    8 ^0 j5 b  V6 x
  343. /*                byte                                                                                                                        */7 W8 o) [) A9 Z* H
  344. /************************************************************************/
    $ f- e0 V6 c4 q2 m
  345. unsigned char Read_Status_Register()
    ; L' r6 b+ `& t" _
  346. {  f9 y6 ^- J6 P! G; a9 ]: p
  347.         unsigned char byte = 0;; J/ q9 s7 f1 ?
  348.         CE_Low();                                /* enable device */# ]9 y8 t+ ~5 x; G/ m$ A
  349.         Send_Byte(0x05);                /* send RDSR command */
    , t: N/ K, A0 t1 }9 O/ g
  350.         byte = Get_Byte();                /* receive byte */
    $ u" J+ C/ N! B8 a/ D+ i
  351.         CE_High();                                /* disable device */* E4 {2 S' p8 I  D7 R
  352.         return byte;, M3 a' K9 g, c- h
  353. }9 n. I0 u- Y+ q, v0 k6 L

  354. 0 L; j5 [: Y& k1 }
  355. /************************************************************************/) z' f- X4 F# g+ ?( F
  356. /* PROCEDURE: EWSR                                                                                                                */
    * r0 _0 O( R% o9 Z$ I
  357. /*                                                                                                                                                */" \( [8 z3 `2 L% s& Z1 d# s9 }9 O
  358. /* This procedure Enables Write Status Register.                                                  */
    / f3 s' h2 B/ e5 K
  359. /*                                                                                                                                                */
      {. k3 ]+ g7 y7 G9 J, e2 c
  360. /* Input:                                                                                                                                */
    : E, w7 u3 [/ x( }- d
  361. /*                None                                                                                                                        */
    6 \, T. p0 r% k0 j( c
  362. /*                                                                                                                                                */
    " _5 N" p7 {% D9 [2 ^
  363. /* Returns:                                                                                                                                */0 K$ @0 R2 F$ W! c
  364. /*                Nothing                                                                                                                        */7 H1 M2 e9 ?& [& v* \3 R1 ^/ S2 J
  365. /************************************************************************/6 W! ]8 _6 e, K: t- e
  366. void EWSR()
    8 s: c* f. e$ g* }
  367. {
    ) `  R% t0 c  }) N0 z
  368.         CE_Low();                                /* enable device */! F6 L7 v( B( p3 E
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    0 [) [% S  S  v6 n0 N. |  I& l
  370.         CE_High();                                /* disable device */; s' q, |! _$ g5 L4 J
  371. }
    8 N+ W9 J( w# z! c
  372. 9 r* b0 G; Z  O! d
  373. /************************************************************************/
    ! q9 ?/ [) m9 A6 d/ }; D6 V
  374. /* PROCEDURE: WRSR                                                                                                                */
    0 Z" V7 g! g) H% b- q: N/ V' j
  375. /*                                                                                                                                                */
    - s0 @5 @2 ^  c2 U. T9 }  \# D4 s
  376. /* This procedure writes a byte to the Status Register.                                        */
    5 x! r1 ^6 W$ e" a
  377. /*                                                                                                                                                */' ^# D- Z. @8 X
  378. /* Input:                                                                                                                                */! m. {' \& u) {  ]+ y) B
  379. /*                byte                                                                                                                        */
    ! ~% _: u  t1 B3 J$ d
  380. /*                                                                                                                                                */& ]+ |% X( t+ U% W
  381. /* Returns:                                                                                                                                */( _9 u5 h) ]  S1 f0 @! f* t% I
  382. /*                Nothing                                                                                                                        */$ a- M' E' D% v5 m& d" C( m
  383. /************************************************************************/
    2 k3 i% j3 d- Y' T# `
  384. void WRSR(byte)
    ) D% _# E% {  v; l; x8 r
  385. {2 w: g6 {8 u8 M8 `6 T" x, R8 I
  386.         CE_Low();                                /* enable device */5 u; u; T- {* q% W5 f
  387.         Send_Byte(0x01);                /* select write to status register */' X, u. g. S" W/ H
  388.         Send_Byte(byte);                /* data that will change the status of BPx 0 z3 l% ?! {5 G/ ~8 ~4 w
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */" _# N- @& K- x. |$ ]( A
  390.         CE_High();                                /* disable the device */% {/ A) S, U* I
  391. }
    % {7 h0 z( R# A1 R5 N2 x0 f5 u
  392. 8 b# r1 k& A$ Y% w
  393. /************************************************************************/9 Q9 p. ]6 H! X* R1 k( L& l! T
  394. /* PROCEDURE: WREN                                                                                                                */: `: E! V2 ]! Z1 e1 [) [0 e
  395. /*                                                                                                                                                */
    " k: m! L' g" n' p3 D
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */# g, u0 B0 m$ A. ?7 |8 L( @
  397. /* to Enables Write Status Register.                                                                        */
    ' v7 k- S" Y. ?. Y/ |
  398. /*                                                                                                                                                */+ I( ]3 q  S4 A. z9 }
  399. /* Input:                                                                                                                                */1 _- p* R' ?/ r
  400. /*                None                                                                                                                        */
    ' M( b# X' k0 o
  401. /*                                                                                                                                                */
    % @& w) V% f; {' ]6 d, L; h. ^
  402. /* Returns:                                                                                                                                */
    8 Y. l7 R5 n5 m& ?# I& N* S' M
  403. /*                Nothing                                                                                                                        */4 S9 H2 I8 t; t# n+ N  H0 m
  404. /************************************************************************/, W2 F1 K8 p3 k, T: _4 o
  405. void WREN()' H8 Q6 c$ e$ b' _  U0 N
  406. {4 [; ]3 D/ m7 u( M
  407.         CE_Low();                                /* enable device */
    & V+ v  M. W% a, F- o
  408.         Send_Byte(0x06);                /* send WREN command */
    ' a( x0 u! P. b3 J7 R6 a* v
  409.         CE_High();                                /* disable device */
    2 I. F& ], |6 v- H
  410. }
    7 @/ x& Z( {  j0 I

  411. ( ^5 t; F; ]! x9 r  G* @
  412. /************************************************************************/
    " f3 f1 j5 d+ T: q8 x% x/ s
  413. /* PROCEDURE: WRDI                                                                                                                */
    8 {/ @$ ?2 i+ ~& s8 v: [
  414. /*                                                                                                                                                */9 p' x4 T' A# p8 ~
  415. /* This procedure disables the Write Enable Latch.                                                */
    9 |" t3 t" Z2 L7 {  b
  416. /*                                                                                                                                                */6 E# n  J- ~9 w; l
  417. /* Input:                                                                                                                                */
    4 W7 X8 p. g& ^
  418. /*                None                                                                                                                        */
    " V$ B+ R* j- O# I1 d
  419. /*                                                                                                                                                */: g& ~) E; Q! Z% w; B/ ?
  420. /* Returns:                                                                                                                                */  `: V9 D2 W" Y
  421. /*                Nothing                                                                                                                        */
    ' J0 O( `1 ^" u" f; X3 I8 o
  422. /************************************************************************/
    9 S  V9 Y( j+ y, ~6 G
  423. void WRDI()
    7 j4 I: n1 }2 Q- w
  424. {
    ) Q9 U4 }( S' Z7 \4 Q+ o% v
  425.         CE_Low();                                /* enable device */
    - M9 p$ _: [3 m+ C
  426.         Send_Byte(0x04);                /* send WRDI command */
    . X9 I3 m6 @7 o9 G1 \/ p+ F5 I
  427.         CE_High();                                /* disable device */
    - q1 Y! f$ ?+ T' D) L/ [' ~
  428. }) R3 q9 N& M+ O6 Q7 L+ L) g

  429. ' A: V( P) m0 b0 A! _2 {
  430. /************************************************************************/
    5 W( R6 |0 N. B0 u5 O
  431. /* PROCEDURE: EBSY                                                                                                                */0 C2 e: ~5 G5 u' e$ O, o
  432. /*                                                                                                                                                */; T4 U/ T& c5 n. s& `
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    3 M! V4 U5 t( }+ g% N3 Q* ~
  434. /* programming.                                                                                                                        */$ A+ a/ Z% W! G, b
  435. /*                                                                                                                                                */
    & a: |% o. A0 B* ?+ u! s
  436. /* Input:                                                                                                                                */
    2 a$ M* |1 b% C1 X6 w
  437. /*                None                                                                                                                        */4 F; e: Z$ u+ W6 M3 h4 `
  438. /*                                                                                                                                                */
    : T/ {0 l6 n1 A5 p0 ^# \7 e- P- s
  439. /* Returns:                                                                                                                                */
    $ Z5 i6 p+ c. l* l9 R7 C$ r) n7 M
  440. /*                Nothing                                                                                                                        */
    ' U$ S, i( s* z
  441. /************************************************************************/
    8 Y# Z3 A8 G2 E9 m
  442. void EBSY()
    ' ?; z" Y- V1 o7 r. X2 D0 P  J
  443. {# g6 [$ E0 o* p+ N4 l4 s/ b/ D5 P
  444.         CE_Low();                                /* enable device */
    4 H& I& H( ]) c: n$ f$ p/ E
  445.         Send_Byte(0x70);                /* send EBSY command */$ s- k% S# u2 c: D, C( x* ~9 O
  446.         CE_High();                                /* disable device */
    - V7 U7 t. ^: k+ Q, }* K
  447. }- [* R& V& J( i7 l2 s( n

  448. * ~$ B  f) l6 u3 _; c
  449. /************************************************************************/! _, r4 c( n! |- ^
  450. /* PROCEDURE: DBSY                                                                                                                */( s7 u- [4 x4 a% f! A  r2 w
  451. /*                                                                                                                                                */
    ! j& y8 R8 y6 l5 |0 E
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    1 X9 C( `0 ^6 Q+ t( T* C5 z7 [
  453. /* programming.                                                                                                                        */! u4 A6 c3 H& t' g0 W9 X1 I
  454. /*                                                                                                                                                */' k4 {* k5 V; s3 h
  455. /* Input:                                                                                                                                */
    . a1 r! w* b. n/ U
  456. /*                None                                                                                                                        */
    # C0 v% [2 s6 [9 M8 L
  457. /*                                                                                                                                                */+ |% x, \' Q( {6 d& K
  458. /* Returns:                                                                                                                                */
    : Z" t+ U; a4 e# B- n4 m: d
  459. /*                Nothing                                                                                                                        */! N3 O; l  c2 Y+ ?# A
  460. /************************************************************************/0 A# _1 g: x: R
  461. void DBSY(). g  a5 {- |  o! u( o  _# v0 T
  462. {
    & @; s- L) x! Y4 M4 \& V  h; W1 X
  463.         CE_Low();                                /* enable device */
    ; G# [: ?' a* I. _$ U
  464.         Send_Byte(0x80);                /* send DBSY command */' k& ]3 \* [% T) `* ?" j1 n" y  L
  465.         CE_High();                                /* disable device */& @- b: E- g( G$ V
  466. }+ H' K# ^9 B, |; y- _( _, o, y
  467. ) h+ L4 [: l0 G7 ]1 [* F
  468. /************************************************************************/
    , T* z) l) q: q# J! a
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ; W& o8 r4 G- K* {
  470. /*                                                                                                                                                */
    , [" d  j# x2 j
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    " Q' a- i( E# v# h' P
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    % y0 o. x3 C% H! ^) v) ]0 s
  473. /* It is up to the user to give the last byte ID_addr to determine      */! {( Z: t6 e8 p7 z' O8 y; x. E$ `
  474. /* whether the device outputs manufacturer's ID first, or device ID         */' `: _( Z" [! i/ x9 w
  475. /* first.  Please see the product datasheet for details.  Returns ID in */9 o$ C) B0 X: S- J# z0 g2 K
  476. /* variable byte.                                                                                                                */
    3 |! F5 d0 N# D& Q, e
  477. /*                                                                                                                                                */% b1 y, v, N/ W' ]+ c! U% T' B1 H8 o
  478. /* Input:                                                                                                                                */
    $ v, s0 Q# C' `( T3 V4 _; ~, [
  479. /*                ID_addr                                                                                                                        */
    * f" ~2 v+ D+ z0 H7 P- y! @" i8 b
  480. /*                                                                                                                                                */6 V; T- N9 T0 a! j
  481. /* Returns:                                                                                                                                */
    9 ^/ S9 ^3 h+ T) `! m4 q
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */2 n' h8 b% t$ K, V& P
  483. /*                                                                                                                                                */* K1 B% x. v; ~* C! Y, b9 N
  484. /************************************************************************/0 i% w" h6 m+ D( Z
  485. unsigned char Read_ID(ID_addr)9 y( r: S0 V9 h  A" J
  486. {
    - Q3 C* Q3 I+ _1 I3 t. C
  487.         unsigned char byte;. [, g, Q2 z- M$ L  o  s7 p- T
  488.         CE_Low();                                /* enable device */1 h/ S( A1 @8 M  R( [$ U$ P$ Z
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */! H( V1 |! a  o
  490.     Send_Byte(0x00);                /* send address */# S7 z1 w3 y  Q  d+ A' M+ k
  491.         Send_Byte(0x00);                /* send address */6 F; x; Y/ F, `2 \! V! S
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */1 M2 W! h5 V) e2 f
  493.         byte = Get_Byte();                /* receive byte */" \! ~- J" M- |8 N5 D
  494.         CE_High();                                /* disable device */7 ?+ n2 ]# X$ Q% R: B( t
  495.         return byte;( b6 N, M; x6 W
  496. }- J$ Y# }( G% v
  497. . h" X8 \: {' D. A# `
  498. /************************************************************************/
      Z8 r7 X; x. T/ t
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */: I; d5 z+ H4 M
  500. /*                                                                                                                                                */3 v* h. h) ~1 k) p6 b
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ' K* t! g: V% g: a9 ?. G  c1 G
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */" \$ X' X1 Y9 b
  503. /* Please see the product datasheet for details.                                                  */: \' W# H# l6 e+ }" n7 N/ c& U
  504. /*                                                                                                                                                */
      p1 x  Y; Q* c' V7 j4 H! D
  505. /* Input:                                                                                                                                */) u: k% I5 I6 b4 t
  506. /*                None                                                                                                                        */% r. T2 o4 S+ H+ _: R
  507. /*                                                                                                                                                */
    4 i7 R) |8 {3 ?' v' A# q5 m7 _
  508. /* Returns:                                                                                                                                */0 S, I5 X- @- D* c
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */5 Q6 w$ R. e" t2 U) X- k3 |
  510. /*                 and Device ID (8Eh)                                                                                        */% D( R/ m( {7 J2 |0 x7 S9 ~/ B7 k! {2 d
  511. /*                                                                                                                                                */$ I7 t+ p5 W" {: ]1 P, Q" s
  512. /************************************************************************/) i& Q1 N; T! `0 M) ]( Y
  513. unsigned long Jedec_ID_Read() 3 p+ C3 Z( `+ v. r
  514. {+ `7 N" O% n/ M+ x+ X( `; ^- @
  515.         unsigned long temp;
    9 b6 J! f# l4 u  J6 R! d
  516.         ; N" v; n: C: ^5 ^/ E
  517.         temp = 0;2 H! l5 N( L/ T6 X- z) v! u) V
  518. 5 ]* I4 k" y  D/ O
  519.         CE_Low();                                        /* enable device */) |' d2 Q1 ~9 ^2 ^
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */' d1 K6 O+ d2 r
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    6 q! l+ {$ M( Y' V; ^# G3 y/ {
  522.         temp = (temp | Get_Byte()) << 8;       
    & Y7 p: T/ ~5 p! K$ Z+ ~# z
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    ( l8 v! b7 a. F
  524.         CE_High();                                                        /* disable device */" R2 @/ i! S. \' N5 K
  525. " Y* N* }/ `" g0 I. m" y' [  m* o
  526.         return temp;0 \# {1 K3 d% P: j8 g+ ~
  527. }# D+ p1 M7 N% }( R& V/ S

  528. 3 N+ C4 I+ R/ `8 e- h
  529. /************************************************************************/
    ( t% d3 r+ [% w8 u8 x5 L7 P
  530. /* PROCEDURE:        Read                                                                                                        */
    ; R# N' _' o: p, n5 @1 ^
  531. /*                                                                                                                                                */               
    $ ^% V6 ^5 D7 d  ^) ~% y: ]
  532. /* This procedure reads one address of the device.  It will return the         */
    " y- j2 ?% m3 x/ F) t# D8 n
  533. /* byte read in variable byte.                                                                                        */6 B, q0 f5 k- p9 C
  534. /*                                                                                                                                                */! k( T+ ?: q+ F2 r1 A
  535. /*                                                                                                                                                */7 P/ H! r' t) L5 b' d- f: C- g# U
  536. /*                                                                                                                                                */# J6 i7 u9 a+ R; E" d
  537. /* Input:                                                                                                                                */- E2 W, f" X2 S  v6 H
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */$ I! ^) G/ g! N) {5 z
  539. /*                                                                                                                                      */
    - r5 @: b: I& z+ ~
  540. /*                                                                                                                                                */
    * _5 r, s7 N' E- D
  541. /* Returns:                                                                                                                                */
    ; T  O6 j( C" P
  542. /*                byte                                                                                                                        */  y1 B, F6 g, j. [1 T( J
  543. /*                                                                                                                                                */
    ; J' u/ ^- t( v! t7 b
  544. /************************************************************************/% d$ w3 K" ~3 R6 G9 k3 q
  545. unsigned char Read(unsigned long Dst)
    . X: D* n3 n3 K4 S
  546. {* U) m5 w) i. c% [
  547.         unsigned char byte = 0;        # E/ \. A! k+ H" Z" o6 _* v6 D
  548.   j7 S8 G  G  H8 j. \: n
  549.         CE_Low();                                /* enable device */8 g# Z3 W$ v& o7 w: O7 o
  550.         Send_Byte(0x03);                 /* read command */8 Y( f; {4 Q# [0 Z2 [! J
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */: ~* s& v4 p8 t' @
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));9 D0 Y8 I8 e3 L: l' [; |: i
  553.         Send_Byte(Dst & 0xFF);
    ' Q' Z5 U: H. Y% s9 j
  554.         byte = Get_Byte();5 \1 Z" T$ I. e7 o8 v& w8 r
  555.         CE_High();                                /* disable device */- x3 s7 q. [* ?8 j
  556.         return byte;                        /* return one byte read */
    2 y% O" x9 E- f- p" C; c9 Q) {. b
  557. }( K5 S" ]9 f* n+ d
  558. - |+ N0 Y& v& i; X
  559. /************************************************************************/1 Z( u2 `* t3 h4 h1 F) h
  560. /* PROCEDURE:        Read_Cont                                                                                                */5 f4 p- ^, o9 j7 b* |4 |$ q
  561. /*                                                                                                                                                */                $ N; E( p  Z- L* ~0 q/ @
  562. /* This procedure reads multiple addresses of the device and stores                */
    + g1 Z$ ~% h% l8 M
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/" c: D7 v  ?7 c& J. v/ y2 w7 X
  564. /*                                                                                                                                                */
    ' h: d5 a5 g9 D4 o+ N
  565. /* Input:                                                                                                                                */
    ! u+ J6 g$ C6 R, F
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% `/ r2 u2 O  z- U; p
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */% }1 u# }  b3 {8 J6 l; J2 x
  568. /*                                                                                                                                                */. n' h2 A6 X. \
  569. /* Returns:                                                                                                                                */5 M5 f/ x" o" d
  570. /*                Nothing                                                                                                                        */
    & d+ \2 p8 y- X! g# C  z: L
  571. /*                                                                                                                                                */
    . U3 x9 g  ]3 w2 B
  572. /************************************************************************/
      a" D3 n5 Y8 r: {% V
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    : ~3 g; l' y" W' K
  574. {; U0 X/ }/ T* Z: }. z& A) a
  575.         unsigned long i = 0;9 k& b5 h' W9 \* e
  576.         CE_Low();                                        /* enable device */
    ; y! Z, c/ o5 \7 p( s* k* {& |4 t
  577.         Send_Byte(0x03);                         /* read command */
    " Y& I) F0 \( {$ `  g9 P: J
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' y3 }8 Q" ?) |, l4 l+ u: Y* A$ h0 u
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , V1 V, K7 p& v: Y( `
  580.         Send_Byte(Dst & 0xFF);' r: M8 u) w1 Y$ [
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached *// ?7 ?) B. K7 T. T- `- S4 B3 b
  582.         {
    - O6 v4 d  R4 s/ ^) O$ E9 s
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    & [$ F$ @/ I# S8 G/ A* r
  584.         }5 C. j+ m0 G( F( F& Y
  585.         CE_High();                                        /* disable device */- R+ O  P9 ?/ M* d
  586. 9 e  x" n  X9 K& A  K
  587. }4 F" C  r( z- @6 X

  588. : C3 S, P( i; F, c4 _1 I
  589. /************************************************************************/
    4 V1 w4 O8 i1 C; q3 Q& E" U
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */- P# A+ l) |2 t( f: `7 [1 @
  591. /*                                                                                                                                                */               
    % x' f: M; E7 M; |: \! m
  592. /* This procedure reads one address of the device.  It will return the         */
    . Z# G' M. q* @
  593. /* byte read in variable byte.                                                                                        */3 N; ?' F9 x# V$ S! m2 V6 e
  594. /*                                                                                                                                                */
    * D- V0 _; [2 |  `- J5 d+ N
  595. /*                                                                                                                                                */
    ; G* C3 P) t- B5 o; u& A
  596. /*                                                                                                                                                */- I& j/ @* `! o0 ]
  597. /* Input:                                                                                                                                */8 H* v/ N) Q6 J* q7 P1 ]
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
      n( [7 y' ~( C
  599. /*                                                                                                                                      */2 n2 F6 X8 m: @
  600. /*                                                                                                                                                */
    & b3 I2 J) v+ i8 J. n) t) ?4 b! A
  601. /* Returns:                                                                                                                                */
    - j1 \: L7 B8 J  v3 k, D& Q
  602. /*                byte                                                                                                                        */3 K5 p' l/ `, J) e: ^* m1 c& g
  603. /*                                                                                                                                                */
    3 Q( v% x  @4 `6 B; {
  604. /************************************************************************/
    ( c1 x% _+ ?; L) G
  605. unsigned char HighSpeed_Read(unsigned long Dst) 8 j# X" t) x/ Y
  606. {
    " w) r7 V* E: I  D% O' ^# C2 V
  607.         unsigned char byte = 0;        6 q' I$ ^& |4 a% q+ U: A
  608.   L6 |, l0 j7 ^
  609.         CE_Low();                                /* enable device */& L& \' v; j/ V+ E: c5 w0 `
  610.         Send_Byte(0x0B);                 /* read command */" M) g3 ~8 H! Q6 b: {
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ( m& g1 k4 L( ?6 _0 H$ K0 N6 ?
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % H" e( d0 J9 s# I- @) K: k
  613.         Send_Byte(Dst & 0xFF);8 W& B% [" `) e8 v$ O% ~1 ?: ]( d
  614.         Send_Byte(0xFF);                /*dummy byte*/6 x* W! d) Q5 h
  615.         byte = Get_Byte();
    % d( V$ M( x7 @: D$ ~. [
  616.         CE_High();                                /* disable device */
    5 a3 J$ e6 F' r% c/ y" s6 Z
  617.         return byte;                        /* return one byte read */3 y/ v& i/ J( f
  618. }
    : R5 t- j7 B1 a. ]% P8 b- t: d! G! d

  619. 0 O: Y$ y6 l0 {0 b) p
  620. /************************************************************************/
    0 L* X9 a% Y* {
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */4 L# v& }% J% L7 O! V3 I) ~
  622. /*                                                                                                                                                */                . W5 ~2 A, a" C3 T6 g% R& H
  623. /* This procedure reads multiple addresses of the device and stores                */7 u% i& z/ k& U2 A- C' K3 n% g
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/& x0 k. d' l: \4 @# L
  625. /*                                                                                                                                                */
    * v2 o1 P6 a" ]# j+ S$ i  e
  626. /* Input:                                                                                                                                */
    3 }8 R. U) z3 ^! y/ s' W! \- m
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; ^+ W% b  r* a& b4 j% i5 s' [
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */4 |% b' u2 m1 ^* t6 N# j  f
  629. /*                                                                                                                                                *// ]8 B" J7 c; ?: ^- v$ K4 S
  630. /* Returns:                                                                                                                                */, e1 K5 F: \7 s2 v2 p7 A; ^" f+ D
  631. /*                Nothing                                                                                                                        */
    2 d. R% K2 I# ?6 o
  632. /*                                                                                                                                                */, l# K: [4 p4 b& x4 {
  633. /************************************************************************/
    - h) i2 L9 P  `7 |% [
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)& J' a9 l4 p( C9 z% \
  635. {
    : ]* i2 u) I1 c
  636.         unsigned long i = 0;* S9 N, k7 V, H$ G8 c
  637.         CE_Low();                                        /* enable device */
    5 ]. H% b, @( T2 N
  638.         Send_Byte(0x0B);                         /* read command */
    ) b) f! ?1 w4 r7 Y; J. e7 p4 E9 ?
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ D. z2 R+ |0 ?
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 ?1 Q" U2 V! P& R/ J8 c  o* b% m
  641.         Send_Byte(Dst & 0xFF);; e3 S) u1 j  O6 Z
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    6 s5 J! e% Y) d( w# r, r
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    4 s. }+ |) d' n' T3 j* a
  644.         {
      _# W  Z2 ]& }) O8 C' J
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */" J1 f# s9 n) i3 P
  646.         }
    7 _, |3 M# O5 p
  647.         CE_High();                                /* disable device */
    & ?# a1 {' B- D1 I- z! J9 J5 ^
  648. }# M1 U5 |/ s, I7 J+ q
  649. ! c/ g# K- ]/ P+ d
  650. /************************************************************************/
    " B! I; _# S* O, j0 l9 @
  651. /* PROCEDURE:        Byte_Program                                                                                        */' {' f, D0 O' T* R0 I
  652. /*                                                                                                                                                */
    $ [0 |9 d, n' ]! `$ S
  653. /* This procedure programs one address of the device.                                        */! o4 l- ?9 z1 V
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    3 W7 K5 n4 z- Q/ y
  655. /* block protected.                                                                                                                */" f7 h+ ]- Q1 L" z" |
  656. /*                                                                                                                                                */+ B( e' l; d+ D% G& G1 G  U5 [
  657. /*                                                                                                                                                */% {5 Y) K9 F9 [; b
  658. /*                                                                                                                                                */
    5 o2 c% i  g% i$ u  V) J$ o
  659. /* Input:                                                                                                                                */, J  M7 m: {+ K. A; K
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 d) I1 w% C1 M# |0 `4 d' i) y
  661. /*                byte:                byte to be programmed                                                                */# S  ^$ S: g( X% |% E' Z! A
  662. /*                                                                                                                                      */
    % G9 `3 N6 ^) m0 W8 w& m# R' z
  663. /*                                                                                                                                                */
    ) I5 H5 h" x& k
  664. /* Returns:                                                                                                                                */
    5 R1 `6 l6 |. Q, S; u9 o: @
  665. /*                Nothing                                                                                                                        */* C' I" l5 ]6 ?% _
  666. /*                                                                                                                                                */$ W$ p8 {: ?0 \- \: e
  667. /************************************************************************/7 Y7 T! n7 e- m
  668. void Byte_Program(unsigned long Dst, unsigned char byte)5 k1 j8 B9 P' f" Y+ Y9 v8 F
  669. {/ p* ]1 c. j% {0 {1 G1 T
  670.         CE_Low();                                        /* enable device */. s. j; l1 `+ {" ]" f2 @& S$ j
  671.         Send_Byte(0x02);                         /* send Byte Program command */2 j$ n' T& E7 h- P
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ; p# a% z( k& Q% [
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' W+ A) Z) s% F: H; g- h
  674.         Send_Byte(Dst & 0xFF);
    6 O1 c! R, I9 A# m9 y
  675.         Send_Byte(byte);                        /* send byte to be programmed */, r, r# Q, b! @% x9 w
  676.         CE_High();                                        /* disable device */! |" u; }2 @; \
  677. }
    0 o' `  l4 J$ |

  678. / e2 {9 \  Z- {$ l3 I2 s6 y6 b. t
  679. /************************************************************************/7 M: w! R: H7 _7 a" ]" i
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ; m, P) [- j/ j( r' ?% T9 `6 w
  681. /*                                                                                                                                                */7 @# ~' D. H+ R4 ^, o$ {2 Z
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/0 t* P0 \  ^) e) _
  683. /* the device:  1st data byte will be programmed into the initial                 */8 A3 Y! r& y! H6 a3 v
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    0 F+ q' c+ f* F
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */  I; e3 E, j7 ?2 N: ]4 h
  686. /* is used to to start the AAI process.  It should be followed by                 */6 F: I# ?2 x2 W5 @: L0 _7 M
  687. /* Auto_Add_IncB.                                                                                                                */
    4 e& z& w8 _9 \0 q7 _
  688. /* Assumption:  Address being programmed is already erased and is NOT        */5 i: Z/ R0 w4 J1 C
  689. /*                                block protected.                                                                                */2 C1 ?0 a) ^  V9 |
  690. /*                                                                                                                                                */
    3 \, J4 X% a& R3 U
  691. /*                                                                                                                                                */
    - S7 F# q# `1 A% u) u, B
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    4 f' d$ D0 l# ?! r# E. S6 m' T( d$ z
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
      q, O$ v- ^! A3 n( Y( x
  694. /*         unless AAI is programming the last address or last address of                */
    6 m! F+ l+ g3 R8 v
  695. /*          unprotected block, which automatically exits AAI mode.                                */. Q# h- K, ]+ f
  696. /*                                                                                                                                                */1 @* _2 @2 r& C' H6 X& W( [1 U
  697. /* Input:                                                                                                                                */& k: I  o7 z: L
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& _* F* D0 i! C% S/ c: F+ n
  699. /*                byte1:                1st byte to be programmed                                                        */$ F! J6 w( B* P, E1 E
  700. /*      byte1:                2nd byte to be programmed                                                        */& E! ^7 Z( _4 B# A' }0 x; S
  701. /*                                                                                                                                                */
    # E% v0 q. ?9 t
  702. /* Returns:                                                                                                                                */" p3 q0 C6 d* w+ a  x
  703. /*                Nothing                                                                                                                        */6 A1 k* L" _+ |4 y+ E# e
  704. /*                                                                                                                                                */* H" a+ ^" \, \4 i8 T5 G
  705. /************************************************************************/
    / y& Z- Z. m: c
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)9 S! ?8 H- F9 o/ S, }% D$ L
  707. {* T. E, r& Y2 l, F1 a. T, B/ r
  708.         CE_Low();                                        /* enable device */$ {$ P( U8 j  N4 X
  709.         Send_Byte(0xAD);                        /* send AAI command */
    / T& B, u* j7 o& o& b
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 M- a% O/ A* l: p) ?8 S
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));' y' m& M1 ^" E- x) u% i3 b$ w
  712.         Send_Byte(Dst & 0xFF);; J' r+ G% e8 \  x
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        1 k6 X0 n! @2 g- F. Y$ F' c
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */- D; t3 t3 e" V: |# y! M: j
  715.         CE_High();                                        /* disable device */
    ( {$ r) ^& p; K, |0 z. N6 |7 ?
  716. }
    + q7 y& u: t7 \" C

  717.   I1 y( g0 K  x, f1 q. V# \
  718. /************************************************************************/# s7 D- q5 X! y  R6 x( m
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */0 T8 Z4 s: C0 v5 w( [
  720. /*                                                                                                                                                */
    # k1 W$ T1 u, H$ r) Y% g* o
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/. j/ m" \- s% _# S! P! P
  722. /* the device:  1st data byte will be programmed into the initial                 */4 L0 ]) R, E1 i1 A, X( j0 v( o
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    " S1 u* L1 T7 U9 }
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    & U; H3 a4 i" Z! t0 |8 H) x7 t
  725. /* is used after Auto_Address_IncA.                                                                                */$ K# ~  ~3 q: e7 E$ X. y4 O
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 G0 k& {: K+ v7 K( i
  727. /*                                block protected.                                                                                */
    * K" y- Y9 q' `: \# d1 \$ R; ~: l
  728. /*                                                                                                                                                */' R+ h& q0 O# l$ e' F
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */* [8 N" G# r/ U6 @) V( S# \
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */9 r, x0 Y, O  G2 g  P* l3 K
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */( ]7 u; S: |5 |  s4 e
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    7 b- Q$ x% s2 H7 a) O  U& B
  733. /*         last address of unprotected block, which automatically exits                 */
    # p. K: V7 Z! a1 g2 x3 J/ Z3 c
  734. /*         AAI mode.                                                                                                                        */6 @* ]2 o! {6 ~1 H
  735. /*                                                                                                                                                */* S- F; K* M9 [1 A
  736. /* Input:                                                                                                                                */% |  ^  Z; e+ V" d( p8 k7 y- Q
  737. /*                                                                                                                                                */
    4 r  a( C# m4 Z* D: p, ?
  738. /*                byte1:                1st byte to be programmed                                                        */. |' U* t! F8 r. k4 I/ C. P8 ~% [
  739. /*                byte2:                2nd byte to be programmed                                                        */
    2 O8 ~8 w! q. z5 W0 h* Y
  740. /*                                                                                                                                      */1 b) h) c, x6 u
  741. /*                                                                                                                                                */8 i3 L) R& ?7 G3 Z1 P4 I2 v/ a/ }
  742. /* Returns:                                                                                                                                */
    / T9 _* i) }  C1 ~5 [4 T
  743. /*                Nothing                                                                                                                        */' A) e: }$ ^$ A2 o2 t
  744. /*                                                                                                                                                */
      w' m) z: \) a" f* j5 f
  745. /************************************************************************/# e0 @5 Q  q, C& I, H
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    , [) d* Y6 Z. a3 A$ O
  747. {
    ; y3 U. \; a9 W7 Y
  748.         CE_Low();                                        /* enable device */7 k4 T. O2 P) i$ e  s+ Z
  749.         Send_Byte(0xAD);                        /* send AAI command */2 T5 g! Z4 V1 B" G' x
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */5 O. Q4 L% ?9 b( D: n. x
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
      U8 F% z! g+ U9 Q; r
  752.         CE_High();                                        /* disable device */
    $ E0 g) b8 p8 Z+ ]( ^7 h
  753. }
    ( t% ?& w" }$ \# a
  754. 5 g* j, i7 B3 E$ [9 B
  755. /************************************************************************/5 ^+ V+ x* q& D, a! X" U
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ! I, g3 A* k' d+ n% X9 N. h% v: b) l
  757. /*                                                                                                                                                */1 ]2 a/ ]% B/ v" ^! H3 Y
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */- x) J( `1 V; x3 ^0 d3 }
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
      h0 |! \4 S2 M+ N5 W& U- T
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
      @- K) g! e5 ~! n! O5 x$ J. l
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */+ T. A/ w3 {( o% |& o$ y
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ) T' x  q$ R) ~& a; l. f) V; ~. E
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */: X9 G' ]' M! M- }: t- ]5 `
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */0 b9 s1 X& y$ C- [$ ]. j# r$ H7 D! o( w# D
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 n. N( X  b7 {% }1 y) N
  766. /*                                block protected.                                                                                */
    % Y. b9 [* e! t7 R5 g1 [: t
  767. /*                                                                                                                                                */- m. W' E. M/ r, c' L" h$ O
  768. /*                                                                                                                                                */0 e6 E5 k: E2 z# |
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    # T5 t. b# D& @  n, J
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    / o7 e4 I: H- K1 F" f9 i
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    , Y- w: B3 L+ B2 a
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    3 e$ o3 B4 l$ r$ H/ I4 u
  773. /*         last address of unprotected block, which automatically exits                 */
    2 ^& S; d0 o% U
  774. /*         AAI mode.                                                                                                                        */# s; }+ X! x6 v% m' z
  775. /*                                                                                                                                                */- i& B! ?" C- w$ n$ a; g. c
  776. /* Input:                                                                                                                                */
    1 D, _$ Q9 w. ?/ P
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 y" e/ w; J3 i# @1 e# N
  778. /*                byte1:                1st byte to be programmed                                                        */
    6 J) w# j, A4 h. g! A/ G; ]- E6 ^
  779. /*      byte1:                2nd byte to be programmed                                                        */
    ( u" n( m) l  [2 a, P: e& g$ U
  780. /*                                                                                                                                                */. [) A% `, a4 N6 F! u
  781. /* Returns:                                                                                                                                */
    " e  |" B& ]6 s# d
  782. /*                Nothing                                                                                                                        */
    9 H/ {& L) H; z% n" l% \
  783. /*                                                                                                                                                */. n2 U2 n# c# K& b$ i  b% I
  784. /************************************************************************/& R; K& M) {5 ~. g& i9 X; y) L
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & L8 B/ ]/ e& Y/ B" {) l% D# c
  786. {! {7 K, q( Z7 ^& k
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    - F3 D5 g- u5 P' {+ f
  788.   l* w0 ?& e. Z4 e
  789.         CE_Low();                                        /* enable device */
    5 j0 A4 _3 x& \
  790.         Send_Byte(0xAD);                        /* send AAI command */& t5 F# J3 T- i% U" y" x8 R* L. B4 U
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! \3 Q8 q- a" w/ `" J* k+ S% G
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));' ^# C2 ^  B& ~, Q
  793.         Send_Byte(Dst & 0xFF);: j* s, D& N8 f: Z: f
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    9 n( q' l4 z, p) C
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */8 E3 a! C7 M/ Y! F) Q
  796.         CE_High();                                        /* disable device */9 L5 ]! k: s3 b; ]' c5 }- W
  797.        
    6 H7 b- F) G) N, {& ~
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    " G/ v4 D) J. L, c" L
  799. / L& d# u; H  d: V! v3 O
  800. }/ d5 B$ j( J  a. t

  801. - Y* x; q, L% v+ b
  802. /************************************************************************/
    % k, t  \# |- ]
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    5 `. Q& i( _5 @4 Y4 Q
  804. /*                                                                                                                                                */
    + Q. u" F5 w/ b1 c7 Q4 j) j
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */2 c: V- C- C( L; Q) H* q+ h
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    . }) v2 }3 a5 ^( P; B
  807. /* AAI programmming is completed.  It programs consecutive addresses of */& Y1 E9 a/ y3 y; g5 }
  808. /* the device.  The 1st data byte will be programmed into the initial   */$ g9 L0 a7 B- v9 }6 P
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    " P) ?4 v9 l& O' f& I- @4 X
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    # j6 C1 B2 t8 u( B
  811. /* used after Auto_Address_IncA.                                                                                */
    * {# X* C) Y1 l# d: l; u
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    + I  s# b6 p0 w8 u" S
  813. /*                                block protected.                                                                                */
    : @4 H3 w8 Y4 s3 p
  814. /*                                                                                                                                                */
    9 ?3 P7 s0 q/ t9 S
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
      m2 B, `  w2 O. v1 k, e0 I- @
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */  j* n  c$ c9 P& X6 P5 O/ B
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */; A4 D5 {7 l: Z7 U5 B; o9 D% V
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    & `2 B0 [" Q1 s8 V
  819. /*         last address of unprotected block, which automatically exits                 */
    & b) t* `0 ]+ K7 V
  820. /*         AAI mode.                                                                                                                        */
    3 J' m4 }5 j* ]7 Q' a$ ?
  821. /*                                                                                                                                                */
    5 \4 e. W/ T$ [% t9 J: \9 l
  822. /* Input:                                                                                                                                */
    " k4 c) m3 {: `( ]/ x
  823. /*                                                                                                                                                */
    # Y7 a& S  @! c* a
  824. /*                byte1:                1st byte to be programmed                                                        */
    . v" D  O! t7 |# k  _; q% ~
  825. /*                byte2:                2nd byte to be programmed                                                        */
    1 A) |, _4 i% N4 J) P8 k3 A
  826. /*                                                                                                                                      */
    ; v# e3 t8 @( {1 w2 I; E
  827. /*                                                                                                                                                */
    ! ]8 Z% q7 O$ b' c* U- E7 c8 a
  828. /* Returns:                                                                                                                                */
    ' `5 ?4 i# Z+ Q1 b  f
  829. /*                Nothing                                                                                                                        */' n. H6 J0 R, {4 W
  830. /*                                                                                                                                                */
    + z0 x2 ~% K3 G+ A& V5 a7 G1 i2 E
  831. /************************************************************************/
      L$ W; n/ a4 r1 j. d6 D2 {7 V7 J
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)4 k1 R! x( O. O4 j
  833. {3 W2 }! J  p. z7 C
  834.         CE_Low();                                /* enable device */
    . n0 `' ]# q6 J  z* A5 s" R/ k
  835.         Send_Byte(0xAD);                /* send AAI command */! W/ N6 k# Y- o% O5 J
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */  h) P/ S8 G8 c) l% `1 s
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    2 {! ^8 ]7 t+ E7 Y9 R. j
  838.         CE_High();                                /* disable device */
    6 y, H: p$ e6 r

  839. ( ]# Q8 {! y" O9 E6 B
  840.         Poll_SO();                                /* polls RY/BY# using SO line */' t7 N, U' ^9 O( t) Z% |6 h

  841. # R7 @5 h5 A+ I. R) d1 D( Y; T
  842.         WRDI();                                 /* Exit AAI before executing DBSY */+ y- N/ G3 H) F& V5 ~* |! D
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */5 T4 a' g- R- Y+ m! y3 i, u3 a
  844. }
    + B' ~( F* @( Q. t3 z: Z
  845. ' O/ c8 V0 k6 S0 E( s: Q
  846. /************************************************************************/
    ; i) P% c0 b) h3 i" ]1 T8 t
  847. /* PROCEDURE: Chip_Erase                                                                                                */% P- I1 o( ^/ k. T" r& k
  848. /*                                                                                                                                                */
    2 u5 s: B; D. Y
  849. /* This procedure erases the entire Chip.                                                                */' D+ ]  d; [' Y1 {) S1 J
  850. /*                                                                                                                                                */3 |0 p$ x- z$ H& W% U
  851. /* Input:                                                                                                                                */0 h* _, ?! l6 U% ]  d1 |
  852. /*                None                                                                                                                        *// |% a9 l$ ~+ p; u" K7 B" A
  853. /*                                                                                                                                                */
    - q. S8 l- z  {3 @2 z7 Z
  854. /* Returns:                                                                                                                                */
    ' w9 a, F1 C& Y
  855. /*                Nothing                                                                                                                        */& q& A3 c0 K" {) d4 n, g
  856. /************************************************************************/
    1 {5 }) q& W" N  {6 t  P
  857. void Chip_Erase()3 @) F, D3 P) u+ h2 U
  858. {                                               
    - i3 A: a3 ^# p# X; B+ p* K
  859.         CE_Low();                                /* enable device */
    , d/ k4 b2 h$ K" G" e0 Z
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */2 T7 V  ?8 s+ I
  861.         CE_High();                                /* disable device *// m2 y1 V  S9 V. j* w9 F  n, X. `
  862. }
    2 N. P0 |! H4 i4 U, t
  863. 4 s7 ~: Q! @* _
  864. /************************************************************************/
    " U( _6 R1 @( x4 Z9 v
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    . T9 z% R; l8 l2 h+ h1 b
  866. /*                                                                                                                                                */
    % I" C( P* E( f& H
  867. /* This procedure Sector Erases the Chip.                                                                */4 u: e$ l- g, M0 C8 H
  868. /*                                                                                                                                                */
    + q; e: a8 @" F' A! R
  869. /* Input:                                                                                                                                */6 w) G, V. A+ a0 w
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! Z: _+ J% y) Z' @5 Z' k9 o& Z6 {
  871. /*                                                                                                                                                */  p7 c! v5 J6 j; D7 P/ E7 a
  872. /* Returns:                                                                                                                                */8 b! D, Z0 L  w0 a
  873. /*                Nothing                                                                                                                        */6 J8 ~* N: _; J) H. o' K" r
  874. /************************************************************************/
    7 B& L6 w8 n- [. _+ A' M
  875. void Sector_Erase(unsigned long Dst)
    - W4 S7 Y& c: `3 s5 \& \% \
  876. {
    5 E4 U) ^; @9 A# j4 V
  877. 3 O% f- ]+ z! a0 {

  878. ) t  D! a/ k+ X0 a0 E
  879.         CE_Low();                                        /* enable device */
    7 x7 V7 b/ ?. |% r* [! m$ K, H
  880.         Send_Byte(0x20);                        /* send Sector Erase command */1 {+ p$ `( r# X: P7 m  B6 Z$ `
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! J. z% f) l# {8 _+ e+ Q' i$ [
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));: a- w+ c+ o2 N
  883.         Send_Byte(Dst & 0xFF);7 x3 `$ F% H1 a# C! z( b2 l; L# Y$ |
  884.         CE_High();                                        /* disable device */
    2 }0 ~: R5 v5 K. T! \2 n
  885. }       
    * C, L! N% R( j+ {, x
  886. 8 ]/ _& f$ B$ L9 T$ B6 Q9 Z* t, e
  887. /************************************************************************// D, z+ z- V6 `2 W0 D% j& l
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */; G$ @3 d4 q, z2 m* Z
  889. /*                                                                                                                                                */( B2 _. N& S9 h+ {) f
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */6 v/ c. i0 d7 E  O
  891. /*                                                                                                                                                */
    : n/ u5 o  R" H
  892. /* Input:                                                                                                                                */
      h0 @4 E2 B) G& ^
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * j2 v) C& c& ^. D; c& T
  894. /*                                                                                                                                                */
    " S& y* L7 a7 s0 l4 R4 @1 ~! {: ?
  895. /* Returns:                                                                                                                                */& c& m; i* J5 O7 H9 V% V& T
  896. /*                Nothing                                                                                                                        */
    , {, `6 h( h& v/ P" I% Y
  897. /************************************************************************/
    + N7 N% Z' c: W/ n+ v9 q
  898. void Block_Erase_32K(unsigned long Dst)1 T6 z0 X4 P3 a" Y% ^! b: E
  899. {
    0 _7 e- G6 j. V* R5 q- _
  900.         CE_Low();                                        /* enable device */
    ! w, L0 A& O  B5 I
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */% E) r+ }) ?- W5 n  |
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % E; c" d4 H3 q
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 c3 T! V! d6 I* J! @4 W' B
  904.         Send_Byte(Dst & 0xFF);
      V4 E: m9 @4 E& D7 m( ~+ S! ^5 y
  905.         CE_High();                                        /* disable device */
    % w4 E5 M, {- |3 R, ?2 {. @
  906. }* }8 A3 V6 A! v7 I4 J: a
  907. * ?3 @2 [4 e/ ^2 ~
  908. /************************************************************************/  O% o+ E* j+ v, `* q. y  r
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */2 N; J% O$ X$ I& U
  910. /*                                                                                                                                                */  C7 e9 @' b  ]3 }3 {+ s3 ?3 M& w
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    . U! V. ?1 c. ^7 b. {- }2 i, W4 u
  912. /*                                                                                                                                                */
    8 ]7 A4 ?" N3 R3 J% Y
  913. /* Input:                                                                                                                                */6 a9 A. y& Z3 |3 C" A
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */' F) l; j7 c0 h. U3 R$ @
  915. /*                                                                                                                                                */
    3 @  }+ z% ~' K/ I; E
  916. /* Returns:                                                                                                                                */, }4 g9 ~; d: S5 T/ ^
  917. /*                Nothing                                                                                                                        */
    ! W9 d, H* q% f
  918. /************************************************************************/
    " a/ Q9 m6 B# L3 U2 A9 {
  919. void Block_Erase_64K(unsigned long Dst)4 |. O7 p' V, O  g' u, E
  920. {
    ! d6 N2 l" a7 B3 H- Z
  921.         CE_Low();                                        /* enable device */
    2 E7 ^% O: c- n0 i( x9 n% |
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    # n% t2 G1 v2 w
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    : e1 m, d) q4 S( _8 @0 g
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 x2 [: c' m7 J4 j# k. c) i( T. n, L
  925.         Send_Byte(Dst & 0xFF);) i& L* M% j3 A0 V9 I( I0 C
  926.         CE_High();                                        /* disable device */  h; @! D# ?+ _
  927. }
    0 u7 q! v% e, S

  928. # j( E4 Y6 Z3 s) V
  929. /************************************************************************/7 `; t& e1 v+ W; u5 O" p$ D
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    - g# H. p/ E& }" Y, ?) g
  931. /*                                                                                                                                                */8 `$ y2 Z* o. d3 M
  932. /* This procedure waits until device is no longer busy (can be used by        */
    $ n) L0 T( Z9 R7 b3 _
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ) S% I' j6 c  L% w5 M/ m: j
  934. /*                                                                                                                                                */" d9 }8 V" _' Z8 ^' M$ n
  935. /* Input:                                                                                                                                */" Q# M2 l+ J" c- f# X; v
  936. /*                None                                                                                                                        */3 v+ z' c8 A2 v, Y" p! X
  937. /*                                                                                                                                                */1 a* Q0 {1 t) i! b$ O0 H
  938. /* Returns:                                                                                                                                */" @$ g$ N3 T! G
  939. /*                Nothing                                                                                                                        */9 U1 x* k- t8 _) v; S
  940. /************************************************************************/% _  _/ M# [$ D3 h
  941. void Wait_Busy()
    ! e) h/ y2 K/ |: \4 g( y: S# P
  942. {
    3 t2 m& D7 z) ^. v
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */. y. E" v. r& v' K/ z$ r
  944.                 Read_Status_Register();5 Z( i; J' }* T
  945. }4 m3 k# H2 @: C; J

  946. " @8 ]5 R7 m* z- l& H, u
  947. /************************************************************************/
    ( Z0 i5 h# @# V, t; s. ?
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */% I$ e, \4 A' N
  949. /*                                                                                                                                                *// v) C4 h- Q2 K+ n1 U8 {7 y- T
  950. /* This procedure waits until device is no longer busy for AAI mode.        */5 D5 P1 s" s- b3 x. c) Z
  951. /*                                                                                                                                                */' F1 D% I5 x! _5 J! B; c
  952. /* Input:                                                                                                                                */7 k6 i. ^' d& E. ?
  953. /*                None                                                                                                                        */* I/ a, `# p- l9 ], p
  954. /*                                                                                                                                                */  H( K! ?% n4 \& W
  955. /* Returns:                                                                                                                                */& u( k& P$ `; t2 i
  956. /*                Nothing                                                                                                                        */
    9 R, K/ q* n  w
  957. /************************************************************************/
    8 F( Y" c! e$ G: V# e# J& o
  958. void Wait_Busy_AAI()0 I( N1 g) {+ g' R7 c4 J
  959. {
    ) \* B! b$ ~& k* z5 i) _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */0 G0 L1 u6 `9 b! k
  961.                 Read_Status_Register();! G- O6 n( b7 c3 r6 V
  962. }
    + w. G. ^- ?7 R& @$ t  o2 F
  963. 3 @( I0 C* q$ u
  964. /************************************************************************/
    # _4 j( S, Y; H
  965. /* PROCEDURE: WREN_Check                                                                                                */3 K7 X% u9 I4 o8 ]( j
  966. /*                                                                                                                                                *// {7 A' l+ B7 y) d: ?- u
  967. /* This procedure checks to see if WEL bit set before program/erase.        */2 J/ m' \: A' a  r$ [' l
  968. /*                                                                                                                                                */- ~& d  T: \+ t0 d+ t
  969. /* Input:                                                                                                                                */1 t. w4 ?8 X" T% Y* L, d
  970. /*                None                                                                                                                        */
    8 }: X5 b3 m+ q/ {& g
  971. /*                                                                                                                                                */
    7 c5 L2 G) b" U" w3 t
  972. /* Returns:                                                                                                                                */5 P5 E2 ^) y6 ^, B% F$ Q1 l7 b
  973. /*                Nothing                                                                                                                        */
    . J% _; r: |# A3 }
  974. /************************************************************************/
    4 J$ r! q2 P$ Z
  975. void WREN_Check()0 K- x9 k4 v- J. {: Z, ~$ _- a
  976. {
    ; b! G8 A3 k! f* x
  977.         unsigned char byte;
    . X6 l3 I8 O" \' {4 g' q
  978.         byte = Read_Status_Register();        /* read the status register */
    # @8 A8 {9 s; y3 c$ W1 h* d
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    # d9 \. B2 L! j8 _: T# L8 B
  980.         {1 O+ I! b3 u' h0 [# C5 z
  981.                 while(1)4 U' ?3 k# U; a7 G; L
  982.                         /* add source code or statements for this file */
    . {, y' H: ?0 M% y; g; u- w
  983.                         /* to compile                                  */% m/ q) |+ {$ U2 e
  984.                         /* i.e. option: insert a display to view error on LED? */6 @$ r. R2 R, L8 |
  985.                  
    ; m) W9 j5 ^" n/ |1 n
  986.         }
    % X; q$ @# L- Z# m
  987. }
    4 Q3 m' S  N7 [0 C7 V* S! o
  988. 7 @* ~6 h3 ?5 c% `+ o- v8 p# [
  989. /************************************************************************/+ j2 @4 n, h4 b: f9 F
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    " i/ |* b/ p2 ]0 v4 x+ {! I+ E+ [
  991. /*                                                                                                                                                */
    * t; ^+ ]+ E: t$ ?0 o% }9 G
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */4 P6 K! Z1 c9 K6 O$ D
  993. /*                                                                                                                                                */3 Q' ?7 v0 t: f3 d
  994. /* Input:                                                                                                                                */
    ) F. t( d7 S5 q" x2 t( I$ |- _* M6 z
  995. /*                None                                                                                                                        */4 d+ E. z& {, J- P  S' Q; d
  996. /*                                                                                                                                                */0 \% J. I. j6 R
  997. /* Returns:                                                                                                                                */! Z3 U3 S$ `" O' y2 V/ d
  998. /*                Nothing                                                                                                                        */
    5 z! f0 |! Y9 ^$ D3 P
  999. /************************************************************************/& ^6 i* U- @  m+ P" m; O
  1000. void WREN_AAI_Check()
    & [$ n8 T) r' F8 }% _/ W
  1001. {8 X  K/ d, M0 W
  1002.         unsigned char byte;+ R% r  e  K# t. a9 Y1 R
  1003.         byte = Read_Status_Register();        /* read the status register */9 h. v' v, e9 d: ?, p. W8 e
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    $ d9 {1 P4 h! G$ ~- A0 o
  1005.         {/ I8 u( L5 n# o( d/ o
  1006.                 while(1)               
    % ?( _" H2 X8 u6 B
  1007.                         /* add source code or statements for this file */" m( y4 `9 ~2 @) {# l% E8 I
  1008.                         /* to compile                                  */
    . T4 U# u: a7 `, g
  1009.                         /* i.e. option: insert a display to view error on LED? */
    : i  K2 L8 {' @. T6 i

  1010. ; g$ [# g# C% c/ e
  1011.         }4 _! j' g2 ?) e+ {: ?5 j' O: q8 C
  1012. }4 {" \: x) A1 z' [
  1013. $ w3 n" z; c9 K7 f0 G
  1014. /************************************************************************/- z/ M& e. w' G! k$ k+ ], ?
  1015. /* PROCEDURE: Verify                                                                                                        */* _" f2 z) |: |' J$ b
  1016. /*                                                                                                                                                */# L3 s6 h7 d7 M) K9 g- O, b8 j2 B
  1017. /* This procedure checks to see if the correct byte has be read.                */2 k9 v( W+ t- h7 J
  1018. /*                                                                                                                                                */
    # U8 k$ M, M7 r) s) i7 t( _
  1019. /* Input:                                                                                                                                */
    4 }! n2 s5 N0 X3 S: _+ |
  1020. /*                byte:                byte read                                                                                        */
    : Y5 E/ {" n6 j& ^* F; A9 D
  1021. /*                cor_byte:        correct_byte that should be read                                        */) Q% e# }1 _) x' N
  1022. /*                                                                                                                                                */
    9 n  b2 M, `0 x6 M
  1023. /* Returns:                                                                                                                                */; ]6 x! P( P) i, t) b& E5 L# F
  1024. /*                Nothing                                                                                                                        */
    ( d3 n1 `- f+ l4 F, n! R7 l0 U
  1025. /************************************************************************/
    ; j' A! X* v* D' T* I$ d
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    5 ?0 s, S6 W4 n7 [  T5 T+ [) e
  1027. {
    $ {! L: W1 D  \
  1028.         if (byte != cor_byte)9 _* u7 ]6 [  [% D7 w  f
  1029.         {- j# t' N7 K3 c) V
  1030.                 while(1)  H- O. d  t, g2 q* N9 b
  1031.                         /* add source code or statement for this file */
    5 i" ?3 [& C9 m0 }) r$ M
  1032.                         /* to compile                                  */  @5 s2 M5 _  |% \
  1033.                         /* i.e. option: insert a display to view error on LED? */
    , }; u5 J& U0 n/ W" U4 G
  1034.                
    8 q. L7 F: l* b9 s9 F6 u+ e( u) k% E
  1035.         }+ k" a8 o3 C5 q1 Q$ e
  1036. }
    * z% O9 C% t! f$ d1 M6 h
  1037. 8 m( v2 ]6 C; E) R- O

  1038. ; U$ x1 ?! G" \7 o5 h9 Q
  1039. int main()4 _7 Y9 w! T) L) c/ C
  1040. {/ y% U/ g& ~: _# R1 y( D7 d; C

  1041. 3 B% Z* }; U; M- A. R' i3 ~' G- P
  1042. return 0;' B8 ~6 R4 Q% J2 @
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
- x8 A- Y1 z  O0 L1 M* z* @( v   main()
% Q' k5 F- v, d   里面怎么是空的呢?
. |1 a$ y6 p3 M. o  N7 `   发一份给我吧
0 j1 ~. l) v. B7 s0 G: cmail:luyijun2005@hotmail.com
8 Z& Z: I2 |# v! \咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。  w2 X+ i# L* O: I; w5 Y# t

7 O' g8 _1 T' f[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。* U% s5 u& p( p3 u, j' e4 v7 K& {
EC的代码在哪跑,你看DS的说明,每个EC都不同的。  v$ c- h/ m; g7 C
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
! I# P! }5 e. `: Q& m; j0 |2 t. [上面几个问题是你没看任何东西而白问。
- P/ h( k. b8 X+ i8 _% e
+ C+ U& [5 U5 J! m2 C# u' i至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

& j+ B; Q. @5 U7 m& O+ |  p7 R3 E关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!! J8 u4 J  o# C4 q
4 b" a* d) Z4 ^. b/ {  l" e
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
$ n. k& W8 _' c9 K, _
6 e& z" M* B- a关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
* h4 |: g0 _2 D0 [
& ]) O+ a5 A# `  B3 F9 r6 j8 I不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样) v# ^; ^/ l5 G" {, D- w1 K
似乎要把SPI能support 到最大,这EC chip应该有好卖点
2 Z' y& [# F" |- k! dBIOS功能要不要强大,也就决定了SPI Flach的大小
: f: m4 p' k4 R我是这么想的~让OEM去决定要挂多大!- h* c3 T6 D1 P
如果我司有BIOS工程师就好了~哈
/ u+ q5 Z; R# g* B/ VWPCE775应该算很新的东西,来看它支持到多大?* j3 t4 v! |5 `3 r5 W3 i

! |- H1 R, Y9 C4 C& d) F& m, o另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte6 f0 c! s3 l% o% {: ?1 @7 c9 W  ]
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.& F1 S" W( o: T5 Z) a

. N- m& s- T& W) X6 O9 i6 o这份driver收下~希望以后有用到
! N5 g" R! u  h8 L& a% W谢谢bini大大
# N$ o  R5 ?7 [- D/ F
" Q/ r* p. m) O很新很新的新手,如有错误请指正 (准备看第二家的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(): s' f9 T8 |4 I. b
{
' X6 |2 W# f- }2 S; @        unsigned char temp = 0;
4 o: K9 g# n9 U% o4 q& T: g8 n6 k4 f        CE_Low();+ r, y3 _$ ^( c& i' D
    while (temp == 0x00)        /* waste time until not busy */4 d5 C( H; \3 s% h
                temp = SO;+ S1 `3 Z0 ^. L
        CE_High();
) K% k) D7 ]) N. _}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)) z5 m) v2 R3 ]  K; o9 V
{
9 `# G4 Q4 q9 _' c4 u        / O9 y$ F& ^7 U" Q" `
        unsigned char i = 0;
! z" s3 A* {) W# n: M7 x        for (i = 0; i < 8; i++)' l; h- `0 h! v( }+ Z9 v) o
        {8 H  B) c  J, k' t. c1 N; y
               
# c' M! ?. x0 _6 B3 d                if ((out & 0x80) == 0x80)        /* check if MSB is high */4 ^* |5 q0 m$ |3 m7 X; A# ~
                        SI = 1;
, ?) d  c1 M5 ]                else& N+ M! V6 h5 J8 |1 W4 p- L
                        SI = 0;                                /* if not, set to low */: X: d- v2 b0 S, P
问              SCK = 1;                                /* toggle clock high */
5 c4 T; Q8 E8 u- j   题            out = (out << 1);                /* shift 1 place for next bit */8 t7 ?- ?, P1 M  d/ w  `+ O& z
                SCK = 0;                                /* toggle clock low */; G5 a8 n3 f  I. H/ G
        }
& q7 ~7 P' F: t, [}5 ^5 N! M" X- ]. @4 g9 f# e
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-19 13:38 , Processed in 0.054511 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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