找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55498|回复: 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
    / y8 u- f2 R; V- w

  2. - F/ a/ ^' b. Y5 a: {; m9 L' v
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory7 X+ m1 Q8 Y- F5 U# b& a
  4.   N% D/ T$ D9 p& Q- b- S* D- w
  5. November 4th, 2005, Rev. 1.0' G! H2 C6 t8 m' d6 q

  6. * I9 R1 {: v. S# t0 }7 L: s0 X
  7. ABOUT THE SOFTWARE1 Z% p, f6 H$ j( q! M* C  r2 l
  8. This application note provides software driver examples for SST25VF080B,
    & P, w$ J- C* G) ^$ W, H
  9. Serial Flash. Extensive comments are included in each routine to describe 7 \) ~, x% @4 i3 m
  10. the function of each routine.  The interface coding uses polling method 9 J3 i: ?. F, l# W
  11. rather than the SPI protocol to interface with these serial devices.  The+ y) F6 x' b8 v1 n+ B' y9 k. g3 z  S
  12. functions are differentiated below in terms of the communication protocols
    2 ~, z; B5 ?$ _: v9 h$ `
  13. (uses Mode 0) and specific device operation instructions. This code has been & I: l. Q" ^) Y0 b' k7 f9 \
  14. designed to compile using the Keil compiler.  {/ o- g3 f# ^2 t& Q

  15. + F/ N; P! m, P

  16. / O; E: m8 ?4 B9 m2 `
  17. ABOUT THE SST25VF080B8 [1 G4 I) y! E- |9 X
  18. 5 O- K+ P, `9 K7 ]( F, a: E& j
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    # b/ ~7 Y- v. H; v: {- q
  20. conjunction with this application note for a complete understanding
    ( y9 E" v7 J$ P5 [* [( l
  21. of the device.
    # e+ A7 k- }& G
  22. 2 X$ m, o. G0 z1 `! @9 P
  23. # \" _5 Y- n8 e& Y
  24. Device Communication Protocol(pinout related) functions:
    " z* Q% T  \: a1 J
  25. . t$ w- [4 [+ }  Q
  26. Functions                                    Function* h. b. O0 F. A5 K. M; B
  27. ------------------------------------------------------------------, y4 g/ w' l* N. y% W
  28. init                                        Initializes clock to set up mode 0.
    3 Q4 V; I% X3 ~5 \0 {3 b
  29. Send_Byte                                Sends one byte using SI pin to send and
    1 ]) p- N6 \7 E* b5 H! r
  30.                                                 shift out 1-bit per clock rising edge3 u5 P0 O0 X; M  \) C  `& v
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 5 ^. z5 Q- n# h( |" d* C# w/ _! e+ p
  32.                                                 in 1-bit per clock falling edge' I0 X- K' C: ?! X* A; F. V
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    + q8 t+ f9 o& b" w5 ^& f
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high% f, |, j2 S" {. h. E. u
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    3 p' z) ~! x& S6 \# S+ o
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    + B; @+ I( Z( L9 C3 s' M7 Q6 d/ v
  37. Unhold                                        Unholds the serial flash& _; j7 ?1 V8 V' o- B/ \
  38. WP_Low                                        Clears WP pin to make serial flash write protected) y1 Q/ I! k$ _# p  U: v
  39. UnWP                                        Disables write protection pin
    9 Y" Q! L1 `+ J& s) R% \
  40. - B. f  x! ~; i
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    $ S3 u8 L5 L" o; a& _' I6 C4 L5 ]
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    5 E. i5 ]/ [0 t+ [0 i* [
  43. software which should reflect your hardware interfaced.          
    9 M5 c# U6 I( D8 j
  44. # x" w+ g% l# ]3 ^% V
  45. - Y& @  K! K2 {- k/ V
  46. Device Operation Instruction functions:7 ]5 n8 X7 U4 R' j

  47. ! e5 ^1 `; }" m+ }3 u0 S
  48. Functions                                    Function1 I, {# W) x+ J$ v/ A0 F- x
  49. ------------------------------------------------------------------4 v! d/ J) q( k, V9 N1 a
  50. Read_Status_Register        Reads the status register of the serial flash
    & n% z8 V4 q0 D) `1 A6 ?6 ^+ ^
  51. EWSR                                        Enables the Write Status Register7 f& W8 H" {. P  ]& ^% \  P5 `
  52. WRSR                                        Performs a write to the status register
    . Z  x% g; w' J: f
  53. WREN                                        Write enables the serial flash9 O  M% w. e6 V2 p. b+ P- e2 J3 C
  54. WRDI                                        Write disables the serial flash
    6 `' V3 }' A7 H" E4 ?
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    : ^3 W- _" i6 M% ~: C: {
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming6 X) @$ O% Q3 w' G* z$ f' M
  57. Read_ID                                        Reads the manufacturer ID and device ID3 e  ]1 ~) J6 y" G
  58. Jedec_ID_Read                        Reads the Jedec ID6 B/ p! x; ~. @+ z$ |/ o$ a
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    ; o, T, T* ~* H" B. y# M
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)5 M+ m- {. Z& C! \7 N
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    ) S( S' L* m& C7 [+ e5 ]
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    0 W; c6 W9 x! z& q3 X% V) P+ ~# w
  63. Byte_Program                        Program one byte to the serial flash9 B- T6 i* ^. y5 k5 C
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ' g6 W$ F; u( U6 N4 Q. n; G/ V- o
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation  @$ E. ?) t* d, U2 X  H8 V
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY. t& P% I6 I' f3 o* `
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    : V5 v  k$ o9 y1 U
  68. Chip_Erase                                Erases entire serial flash6 B* Z) n) f& F8 C# d
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash% G# E: r8 T! f! ?% B$ x  c) k" R2 l+ c2 b
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash- B* ?3 G: [( u7 o
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash( Z3 U  O1 X* V: b
  72. Wait_Busy                                Polls status register until busy bit is low2 w7 v* Z" ~  |8 N
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming9 ]1 L3 \0 ^/ l/ R7 B) l& J
  74. WREN_Check                                Checks to see if WEL is set
    - M* l% s# @& t4 M
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set0 z" Z  y7 t8 o6 B2 W
  76. - e$ p6 }0 ]8 K! M+ J

  77. 6 d5 R1 P$ r) H8 M2 ~

  78. " \8 J: `- L8 t! }* s, c3 H  F" H2 a
  79.                                                                      4 B/ T9 P$ v# f1 E( R
  80. "C" LANGUAGE DRIVERS ; }  R  b9 F. `7 n( @# J9 d( ?
  81. ( p9 m9 O; N' {
  82. /********************************************************************/0 B! q3 V9 {& r9 X$ `
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */: ~6 y! d2 [: C8 F$ V6 I; ^* q* K' C
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */8 @2 G0 i* o4 T# a' z. w
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    & L7 O! P+ T) ^8 |" s$ y4 q
  86. /*                                                                  */7 h7 E  A' Q) @: \7 ~$ k+ i
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    9 K* j$ X' `2 g" `( P' q
  88. /*                                                                  */
    ( O2 X9 e2 R5 y) z7 {
  89. /*                                                                                                                                        */
    * |* x" ~2 y  A
  90. /********************************************************************/
    ' S8 `0 y  V& ?" _

  91. 9 o' i& t1 z. U% \* ]5 e( s4 h
  92. #include <stdio.h>/ Z, g. v2 h+ B* `5 @$ ]
  93. #include <stdlib.h>% _' W9 N( U4 u6 c
  94. " Y. r9 }+ B0 T2 j; w% d$ u
  95. /* Function Prototypes */
    5 G$ h" |/ f) |! |5 W& Z1 E* F' P
  96. 3 ^4 k' r7 V4 l5 u* _
  97. void init();
    ) M: R6 L/ C5 B. H2 C' h
  98. void Send_Byte(unsigned char out);. E' L- S; k+ M/ X' T
  99. unsigned char Get_Byte();
    3 {6 T2 O* m: r# K2 k" S( _
  100. void Poll_SO();
    & h$ n( g% C8 _6 R
  101. void CE_High();
    ! s, ]* ]6 s2 y. p' f
  102. void CE_Low();" H( @3 G$ v. b% |% U
  103. void Hold_Low();
    & d8 ?8 S/ o4 H+ ?
  104. void Unhold();) k5 h4 c. A/ F/ \0 u
  105. void WP_Low();
    1 S  a+ }  C/ Q
  106. void UnWP();0 B8 o% M5 e# O/ G  |$ }0 w0 _
  107. unsigned char Read_Status_Register();
    . R* w/ ?/ O: H& y& A* e
  108. void EWSR();+ E2 Z8 a3 u6 P5 c. ^
  109. void WRSR(byte);
    : ~) U* s7 M/ O$ `& w
  110. void WREN();
    0 M# f: Q# }! p, N# B& O
  111. void WRDI();
    / r' T  j  u  }, I; u7 s2 H8 h
  112. void EBSY();+ c9 W$ c, p! _1 y" U
  113. void DBSY();
    2 ]7 J' F, K" b  d, o
  114. unsigned char Read_ID(ID_addr);. g- b0 t% W$ j% x+ Q: Y
  115. unsigned long Jedec_ID_Read();
    # n3 p  a9 ~9 \2 }
  116. unsigned char Read(unsigned long Dst);
    ' ^* `; M, G  c  Q9 g
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    & J4 f% ?" G+ h3 d0 J; _
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    / \: t3 Z% Y' A9 E3 y* Y( e! \% H
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    . {- o" e3 U( a2 F, l0 }) B
  120. void Byte_Program(unsigned long Dst, unsigned char byte);4 L' U" H# j+ G2 F; r0 d3 @; B
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);1 e: @# {7 p$ N
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    : x. Y8 Z- {3 f5 {3 k: Q
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    6 x  W: \4 @" {4 i2 o& H5 o
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);! d0 S7 F8 r& t2 D* r8 o
  125. void Chip_Erase();
    ; v, Q5 F; o1 G# V( c2 H+ t. i6 V
  126. void Sector_Erase(unsigned long Dst);
    4 `& j8 s! p* i( t7 M! H
  127. void Block_Erase_32K(unsigned long Dst);0 D0 e7 n. A$ y9 N
  128. void Block_Erase_64K(unsigned long Dst);
    1 ?7 e  \/ W& J( t$ I" X
  129. void Wait_Busy();  s" f7 u( i6 a: F- k2 q
  130. void Wait_Busy_AAI();: h) Y, y0 d% a9 J8 l
  131. void WREN_Check();
    2 d! C7 W0 ]- D
  132. void WREN_AAI_Check();$ d4 H5 j: [* `: Q) s

  133.   V, ], N: r3 g/ F7 Z
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    + K% ^5 ?% g0 M- u: F& \; k

  135. ! ?: I% e( Z6 y. Q& W2 J2 x  a
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    $ x& }, [* r. u1 J  i
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    ' X4 u( A% g  K) X7 h6 u( J
  138. ( d; a8 `4 L- y
  139. /************************************************************************/
    % ?! R7 z5 S$ ]& \2 Y
  140. /* PROCEDURE: init                                                                                                                */2 p5 U" X, ?/ S  `
  141. /*                                                                                                                                                */
    1 @$ q, y* D( e
  142. /* This procedure initializes the SCK to low. Must be called prior to         */$ P, c$ a6 b: u& V: @5 ]( Y' J
  143. /* setting up mode 0.                                                                                                        */
    ) m. R4 |# O7 K& U- B" C
  144. /*                                                                                                                                                */
    ; z2 `! h) e, P0 I" {
  145. /* Input:                                                                                                                                */1 G" L7 v& D, f8 ]! N4 J
  146. /*                None                                                                                                                        */
    % S# ~, X  o4 F% q
  147. /*                                                                                                                                                */! I- b/ @4 E. B$ U, X7 r+ F
  148. /* Output:                                                                                                                                */
    8 [3 k; y2 `( e) X
  149. /*                SCK                                                                                                                                */
    % K: J# J7 l+ A9 V/ z/ l0 k/ N6 I
  150. /************************************************************************// h6 K& {6 Z& H2 ?+ r5 V
  151. void init(); {4 |  Z# M. ?; P
  152. {
    * l) x/ \2 i% f: Q4 Z# g9 `& j
  153.         SCK = 0;        /* set clock to low initial state */- j; u7 R  R$ j2 W* j6 v
  154. }! F% }3 @: f. I& i+ ]7 }  L
  155. 5 r3 K0 a1 T; t# X, X
  156. /************************************************************************/
    * t7 m; |8 x/ P+ `  X$ j7 f
  157. /* PROCEDURE: Send_Byte                                                                                                        */9 _8 c: C( Y; R$ Z9 G/ M4 F
  158. /*                                                                                                                                                */5 M+ d& c% ?. ~' `- D1 v& }! Z
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */" \. [! `& E; o% R% e# h
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    / d2 J, f0 S0 A$ j
  161. /*                                                                                                                                                */
    . C* ~5 M# G5 e' ^9 I# j7 y9 v
  162. /* Input:                                                                                                                                */  U% L, Y3 G! a. e
  163. /*                out                                                                                                                                */
    : M% c- I+ g5 |, ~
  164. /*                                                                                                                                                */* l# h# j6 r3 c/ `
  165. /* Output:                                                                                                                                */
    2 U  {+ ~/ e# m$ m$ Y: ?5 P5 q
  166. /*                SI                                                                                                                                */) F2 Q* ?- W4 J, d
  167. /************************************************************************/
    5 n9 d$ e! d; m7 j- e* r! Y5 X: L
  168. void Send_Byte(unsigned char out)
    6 W  W: S1 K5 U7 R: }$ V2 ]! i- P
  169. {6 r& ?/ L( x( X5 t' u5 p5 X4 V
  170.        
    & e, ~9 I: N! y
  171.         unsigned char i = 0;
    + X: F& X( C1 i, |. x) h
  172.         for (i = 0; i < 8; i++): }& P  b1 r/ ^8 j
  173.         {) [9 F2 \/ t  W5 z5 W& V4 S
  174.                 - S8 X& Z+ E! h* E
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    0 f, |) L6 K* k
  176.                         SI = 1;9 a5 S( A; j0 K' Q3 H  q
  177.                 else& q0 S- N7 F1 M4 e
  178.                         SI = 0;                                /* if not, set to low */2 L6 W- A; @: ^
  179.                 SCK = 1;                                /* toggle clock high */
    . T: a/ W6 Z2 {* C( E  j  Q( i1 Y
  180.                 out = (out << 1);                /* shift 1 place for next bit */8 r. ^& z. {0 u# z6 |: ~
  181.                 SCK = 0;                                /* toggle clock low */7 K) V9 H; P3 y* J
  182.         }* c3 [/ ^- C8 _4 p* ]8 D
  183. }  `2 M. w" r) g8 t1 c7 B& B

  184. ! Q+ E) y7 x5 i0 \
  185. /************************************************************************/' D$ D* J. J, R/ p, }
  186. /* PROCEDURE: Get_Byte                                                                                                        */: e, q7 E+ [  H7 W- t; O
  187. /*                                                                                                                                                */; C' L. T; R9 @( q4 X3 {
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    6 ~* {& |/ e# V' {% d4 L" {
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    9 k) J# |! ^$ F% d1 _
  190. /*                                                                                                                                                */
    : ?' F7 M3 r8 {/ I* e+ h$ J
  191. /* Input:                                                                                                                                */# L) p7 N8 D: W# r* F# ?9 J
  192. /*                SO                                                                                                                                */, t- P* o7 W( l' k
  193. /*                                                                                                                                                */
    5 P: M4 y" L7 u, [) K4 S& A7 d$ X
  194. /* Output:                                                                                                                                */
    9 i4 G+ L7 z8 |) H; I
  195. /*                None                                                                                                                        */
    : z$ k, b7 ^9 X- X( A' b+ P, R" A
  196. /************************************************************************/
    9 N- |, |6 o: h
  197. unsigned char Get_Byte()
    / O" E8 T+ l5 f+ u/ Q6 q' z, i
  198. {
    9 l  ?6 I9 G2 r; Z: w, a: p
  199.         unsigned char i = 0, in = 0, temp = 0;
    % Y2 E) I, X% U
  200.         for (i = 0; i < 8; i++)
    + U8 o% @- v! v, ^
  201.         {
    0 E. N  C2 s, F+ @2 R% E$ h
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */2 M+ H5 M- S! ^4 A2 }  V
  203.                 temp = SO;                        /* save input */
    & e9 z* A/ i* r$ ?
  204.                 SCK = 1;                        /* toggle clock high */! p  n8 O- j8 I, i" G
  205.                 if (temp == 1)                        /* check to see if bit is high */% u$ l" W* W5 P
  206.                         in = in | 0x01;                /* if high, make bit high */. a  j  ?3 H. [5 R8 ?9 c" b
  207. 1 I0 [) p. q; K) H$ _, n% f
  208.                 SCK = 0;                        /* toggle clock low */
    4 x- Z- Q7 e+ ?2 }; m( Q/ E

  209. 4 {2 M1 W% C  [! b8 \, ^& A
  210.         }
    - K- T, Q$ T/ W
  211.         return in;# s5 v2 P4 L, `! |9 {) @9 i( H/ [
  212. }* t, r+ {! G) E. k6 a3 b9 |: @

  213. % n4 ^7 G8 y! p/ n% Y5 \; B
  214. /************************************************************************/8 Z" D% h$ B8 J
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ' [4 R) k; w0 k# O# Z& i  t
  216. /*                                                                                                                                                */
    , ?- s- S; Z: {% i' d. ]/ V7 L" T
  217. /* This procedure polls for the SO line during AAI programming                  */
    7 z' e+ R8 @8 p( ?0 p
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/" `& N1 D3 E' t$ z
  219. /* is completed                                                                                                                        */
    5 z9 Y3 I3 @" f: i2 s) v
  220. /*                                                                                                                                                */
    % N8 z7 M1 O" E( k; d2 q  s% e
  221. /* Input:                                                                                                                                */
    / w& w2 h5 e  \
  222. /*                SO                                                                                                                                */8 j4 w5 Y7 u0 f; n3 {5 ?
  223. /*                                                                                                                                                */
    5 ]" w4 ^" R: P
  224. /* Output:                                                                                                                                */' T1 q( p3 f, O9 e# d4 E
  225. /*                None                                                                                                                        */. ~) _5 `  a4 I/ @' i
  226. /************************************************************************/: Q( }, q  L- c+ N1 G* D
  227. void Poll_SO()
    , z+ @$ _# b+ @" P7 {' ~1 u( A
  228. {# q- v: U! {( F/ t
  229.         unsigned char temp = 0;
    6 \5 Y, m" s: ?: \* l
  230.         CE_Low();( O9 T. j! g$ r5 J$ }! X
  231.     while (temp == 0x00)        /* waste time until not busy */
    , {0 L5 F" I! Z, r5 K/ |
  232.                 temp = SO;
    * k# V( d7 B4 S$ s$ [) S
  233.         CE_High();3 ?" b9 S% N+ p
  234. }6 _) w* c7 G% b
  235. 0 f" t! O1 Y% D
  236. /************************************************************************/
    ; J6 x* W$ _. a0 o
  237. /* PROCEDURE: CE_High                                                                                                        */
    ( Y1 O7 E" `4 S" A' t4 ]; Y
  238. /*                                                                                                                                                */
    1 i8 P0 C" V3 C8 z9 r
  239. /* This procedure set CE = High.                                                                                */
    6 O" y. M/ U7 A+ {- W" D3 S0 y
  240. /*                                                                                                                                                */; S3 t, Z; h+ d. H5 d" \8 e3 x
  241. /* Input:                                                                                                                                */
    + o; b' f: a. D1 E. W& q
  242. /*                None                                                                                                                        */; K2 _/ n- @: ~" Z5 D
  243. /*                                                                                                                                                */
    * _3 U/ K6 y) B% F; Y
  244. /* Output:                                                                                                                                */8 B8 F2 v/ U, X1 F; w5 s0 n
  245. /*                CE                                                                                                                                */
    ) c+ n+ s6 E* i/ O4 Q: ~8 z
  246. /*                                                                                                                                                */
    # V) ?7 L& E- K, s$ a* z: W
  247. /************************************************************************/
    ) ~+ _! a3 F# K$ {
  248. void CE_High() : S$ w5 _' l+ i* o! e0 K+ H
  249. {0 R9 [9 @1 I8 R9 X. e
  250.         CE = 1;                                /* set CE high */
    # _7 C% U/ x( z% @
  251. }# X- m/ R5 d* a" P1 Q( M. W

  252. ; V, H7 `' F  ]
  253. /************************************************************************/
    4 Z( y3 P' i7 J- A
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ( I* K# b; |0 A6 V: ^
  255. /*                                                                                                                                                */
    * k1 f$ M7 c8 r
  256. /* This procedure drives the CE of the device to low.                                          */
    ' L. p1 T, w2 U/ ^/ Q; }8 I
  257. /*                                                                                                                                                */
    4 a# U9 \; g# e6 ^3 T3 g
  258. /* Input:                                                                                                                                */
    / z. [$ }5 X/ N: s
  259. /*                None                                                                                                                        */& b7 s. M& {% z4 A( o/ g( B
  260. /*                                                                                                                                                */* X0 E" |" `, n$ A2 [
  261. /* Output:                                                                                                                                */; S+ q" m2 w3 f5 g2 @% \
  262. /*                CE                                                                                                                                */
    : [8 p8 Z% ?. V: k" j7 S
  263. /*                                                                                                                                                */
    ' d! f* H, _; Q% r1 S8 p/ A0 `
  264. /************************************************************************/
    2 {7 M2 v( O6 T$ f! s/ A
  265. void CE_Low()
    % P; E9 f2 B' c4 d
  266. {       
    " S, D5 `3 ^5 U  J" V4 W7 `( ^* D
  267.         CE = 0;                                /* clear CE low */; }7 B# G) y* L1 O
  268. }) Z% b5 Z4 o% ?$ R2 ?! `) C2 P

  269. + P" A8 u+ M% ]; [1 x( R
  270. /************************************************************************/
    ! X8 K8 h9 _( L6 a, V: h
  271. /* PROCEDURE: Hold()                                                                                                        */
    : R8 y; M& o: O) U0 U
  272. /*                                                                                                                                                */
    , D, Y/ u) X/ m2 C9 ?7 Q) Y9 z
  273. /* This procedure clears the Hold pin to low.                                                        */) C/ [4 }4 n$ \9 E: ^2 z" @% e: v
  274. /*                                                                                                                                                */8 L; T( ^# D# _! g3 }3 Q3 \4 K
  275. /* Input:                                                                                                                                */$ E' Y0 K' g" B+ Z& w8 M# ?
  276. /*                None                                                                                                                        */* B! t0 @0 v& |9 x
  277. /*                                                                                                                                                */# z) S' d5 V5 `. ^4 l
  278. /* Output:                                                                                                                                */) y: V8 @; \( B7 j
  279. /*                Hold                                                                                                                        */
    8 S7 \( P4 }) |4 c: V: ~: D
  280. /************************************************************************/5 _* [0 {; a0 c0 H& z0 F
  281. void Hold_Low()
    + [. o- c1 a3 z4 n( [- T/ K( J+ v
  282. {
    / B% ]. Y7 \$ A9 H' N6 {$ U
  283.         Hold = 0;                        /* clear Hold pin */+ f6 Y5 h# O7 F3 f8 S% j
  284. }" x( \6 W& a& U  N" v# ]; Y

  285. 3 T# g/ p$ c6 v+ r
  286. /************************************************************************/
    + J" C/ U& q3 ~
  287. /* PROCEDURE: Unhold()                                                                                                        */
    $ B! Y; U5 }9 b  k$ U1 y7 h% E
  288. /*                                                                                                                                                */
      v, g, |" e! u2 Z6 B9 E$ b3 b4 J
  289. /* This procedure sets the Hold pin to high.                                                        */
      s& i' T$ b/ I% W! I
  290. /*                                                                                                                                                */: [3 ~# L% Z  u$ K: W) k: `
  291. /* Input:                                                                                                                                */- }9 U; Z( Z; o' @
  292. /*                None                                                                                                                        */% y9 s* ^% H- g' G
  293. /*                                                                                                                                                */
    $ z5 P, G, a9 [! `8 t
  294. /* Output:                                                                                                                                */
    ( t6 ^$ ~; y' e" w  y
  295. /*                Hold                                                                                                                        */- Q4 p$ S$ h* h1 ~$ J+ F2 U" ^
  296. /************************************************************************/! V! V9 a  J4 A& w9 d' l
  297. void Unhold()
    9 N1 u  ^/ ?" D, P4 Z6 e; U
  298. {
    7 }& y! Z7 H7 a# w
  299.         Hold = 1;                        /* set Hold pin */5 d+ W9 s5 K' m# K$ g8 ]
  300. }; |& T! d! |3 ]2 c9 o+ C" T0 n9 a) B
  301. 6 Q9 v9 W+ o8 p, x! t1 l2 F
  302. /************************************************************************/5 m$ e; w9 v3 i- i! S# e
  303. /* PROCEDURE: WP()                                                                                                                */8 S2 h( }- W. U) D
  304. /*                                                                                                                                                */4 E- ~3 T, I8 K7 b
  305. /* This procedure clears the WP pin to low.                                                                *// ]4 N9 g6 a! U  l6 B
  306. /*                                                                                                                                                */
    % c+ f9 ~# E7 k/ v3 F( `! S6 B
  307. /* Input:                                                                                                                                */
    7 H8 R2 b9 e* V# T$ t8 \% H
  308. /*                None                                                                                                                        */
    : j( j9 \7 d' C) R' @
  309. /*                                                                                                                                                */  H) d8 d, [% p- x. |
  310. /* Output:                                                                                                                                */
    / E6 C& ]: o. T% U* ?1 ?( T
  311. /*                WP                                                                                                                                */
    7 @$ @( [4 p9 ~$ q6 Y$ K% Q: t
  312. /************************************************************************/
    - V/ e; \* ^/ B. N+ P4 N
  313. void WP_Low()
    # A8 ]1 a+ q% }, x" H$ S% o. I' U
  314. {5 O8 n! [& R' T( `; Q- }
  315.         WP = 0;                                /* clear WP pin */
    $ t+ ^6 S' p: k! y
  316. }$ O  {" a' ~5 m* g; _% B. o
  317. 6 U. H) W7 f( q- V
  318. /************************************************************************/
    ) T# B  H; m5 x
  319. /* PROCEDURE: UnWP()                                                                                                        */
    * l( H7 T, B% d; W0 J
  320. /*                                                                                                                                                */
    3 x2 }: _% ?) _: Y' E& \) h& D/ w
  321. /* This procedure sets the WP pin to high.                                                                */% }3 |0 o( n8 M
  322. /*                                                                                                                                                */
    ( _, `9 h7 A: {" p, l
  323. /* Input:                                                                                                                                */6 C$ i0 @- a& X/ u
  324. /*                None                                                                                                                        */
    + s+ g2 U: l" [7 Q+ I5 a* O
  325. /*                                                                                                                                                */% W8 O2 ?: \, g6 @( I- \* i3 g
  326. /* Output:                                                                                                                                */
    / L; U5 S  F! \5 Q, v+ l! t' @$ _
  327. /*                WP                                                                                                                                */7 E, [& H% O; K9 Z; G$ i4 j! z# k
  328. /************************************************************************/4 Q  W. \$ p4 ?' m
  329. void UnWP()$ [9 o+ M6 m, e+ f" o  V
  330. {
    4 @% b) j% b) ]" o+ o8 Q1 h0 [
  331.         WP = 1;                                /* set WP pin */3 `! Y# v( N& w. Q8 r  ]2 E
  332. }7 X6 c: @' m+ F3 N  e  F, y' S

  333. # [9 a8 W7 e' \- [1 N" h) K
  334. /************************************************************************/
    1 p/ y- T+ s3 |6 N
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    / r- u) _! K' Z& h4 ?
  336. /*                                                                                                                                                */
    5 }% Q7 m4 |9 L9 X. C: m0 D
  337. /* This procedure read the status register and returns the byte.                */
    5 D. h4 M4 K, g/ K% c
  338. /*                                                                                                                                                */4 x6 e0 Q+ Z& G( K
  339. /* Input:                                                                                                                                */
    + S; x0 ^. F- w) i# W5 B
  340. /*                None                                                                                                                        */5 ?) E+ T; Z& k, Z8 b
  341. /*                                                                                                                                                */. Z6 t" _' u2 a+ B( a* K& ~# q$ b
  342. /* Returns:                                                                                                                                */: {/ U  e4 p" a+ n2 G
  343. /*                byte                                                                                                                        */5 l9 M6 _9 Q! {/ V' G% _, J/ D
  344. /************************************************************************/" L0 U! r9 f& @1 n! D6 g" z+ N  O
  345. unsigned char Read_Status_Register(). g  j4 b0 Q4 f& R3 h; _) @
  346. {. G. W: o$ J: K# A3 g( V
  347.         unsigned char byte = 0;
    % N; z3 |1 R( ]" ^, z, P( \( w6 {
  348.         CE_Low();                                /* enable device */" v' v6 w& l% a4 u) U* e2 _
  349.         Send_Byte(0x05);                /* send RDSR command */, p: H: Q( _) x0 {5 d4 u7 U" t
  350.         byte = Get_Byte();                /* receive byte */
    + c* e* a1 l2 I% B% q$ z) }
  351.         CE_High();                                /* disable device */! e) P; H' c& u
  352.         return byte;
    " c% R8 X6 L+ `. O* R2 }; |9 V
  353. }" m! F9 F3 d2 `' o$ B- d" g

  354. 8 x* r. N6 {  h7 R( g  B
  355. /************************************************************************/
    2 r$ b7 u. I# X8 y
  356. /* PROCEDURE: EWSR                                                                                                                */
    9 o: c" J# r% N' n- H7 a
  357. /*                                                                                                                                                */5 i, H! D6 y$ R
  358. /* This procedure Enables Write Status Register.                                                  */" ]# R6 D( Y4 |; [0 U- \5 O
  359. /*                                                                                                                                                */  @4 l; k2 w# J, k3 J* q" g) p& a
  360. /* Input:                                                                                                                                */
      U' p# x0 b5 E; @  E
  361. /*                None                                                                                                                        */
    $ U) T3 D; A9 |: V" C
  362. /*                                                                                                                                                */4 n9 \! b  c9 m! Y) C( k
  363. /* Returns:                                                                                                                                */
    0 n5 s) E' o: T( q* X( d
  364. /*                Nothing                                                                                                                        *// M/ x8 H1 w0 b. X2 {5 C
  365. /************************************************************************/: d1 h8 H+ s: P+ L) f+ N, {' E  _
  366. void EWSR()
    ! G- C5 ?+ M7 P( D$ g
  367. {' G7 c' o% p5 x0 d! D' t6 ?- _1 t
  368.         CE_Low();                                /* enable device */
    4 V% n; Z/ ~" T  y/ m6 V$ C
  369.         Send_Byte(0x50);                /* enable writing to the status register */( Y/ b: j: B  b9 S+ ~/ }  q
  370.         CE_High();                                /* disable device */
    / u" F  ^) M7 G) [) w2 K
  371. }
    $ A! p/ p  D' D( Z& l) q

  372. $ r  c; A& }: W9 @& h' k/ F
  373. /************************************************************************/
    1 v7 M! F2 r$ Z( M# ^, E+ v
  374. /* PROCEDURE: WRSR                                                                                                                */3 K0 p' K  m" S- f* x' }) f5 v; k
  375. /*                                                                                                                                                */
    8 j7 r' e! z' ]7 a6 v' G( [
  376. /* This procedure writes a byte to the Status Register.                                        */
    . y# L9 c7 C  S( ^/ }  X! `
  377. /*                                                                                                                                                *// n4 J7 {3 z- |
  378. /* Input:                                                                                                                                *// P! i$ a5 L* c
  379. /*                byte                                                                                                                        */! H. l% M3 Q$ K
  380. /*                                                                                                                                                */9 ~$ w* o% T8 m! k6 O1 i
  381. /* Returns:                                                                                                                                */
    , Z) }+ D3 S+ m" Q0 z
  382. /*                Nothing                                                                                                                        */
    , d2 A2 d  b2 r4 x8 r$ M
  383. /************************************************************************/* S: m$ T+ Y+ W7 }: I7 y
  384. void WRSR(byte), ~  F5 }' m: y2 y. K
  385. {: ^* L' @7 u% r. k- ^. i! u
  386.         CE_Low();                                /* enable device *// ?+ I  Z! U' e( ^- v
  387.         Send_Byte(0x01);                /* select write to status register */" `" R9 j( Z- s4 N$ S' Q$ x
  388.         Send_Byte(byte);                /* data that will change the status of BPx ' K' [" J0 G; q; V7 f$ b; h
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    & u' B7 g" @. E! W. |: ?' y6 U6 A5 A
  390.         CE_High();                                /* disable the device */) C& F% u6 {3 s
  391. }
    * k: B9 L9 d8 E

  392. ; L% [0 L) \' @3 G( C. _6 E
  393. /************************************************************************/0 r" n9 _# o: Y$ P1 s: x( M% ?
  394. /* PROCEDURE: WREN                                                                                                                */
    3 M9 b6 V* L! ]- _9 F1 o# Z
  395. /*                                                                                                                                                */
    . z9 f7 W' X: t" e4 R5 V) d/ g
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */# G& _; u+ O$ \1 ~0 G9 ]- M  @; W
  397. /* to Enables Write Status Register.                                                                        */" R9 t1 W# n) o+ `  b# u
  398. /*                                                                                                                                                */' L; e9 a3 u! r  F, N! x" p0 D
  399. /* Input:                                                                                                                                */3 X0 o( s+ Q3 S1 z# Q) k
  400. /*                None                                                                                                                        */
    1 Q  I. y% o; u0 _9 t, d% X3 C% B
  401. /*                                                                                                                                                */9 j9 p! `+ E$ ?7 F. v
  402. /* Returns:                                                                                                                                */* X- h5 @1 Q/ A& i9 O$ ~- f6 l
  403. /*                Nothing                                                                                                                        */, {$ I" A# _; k3 s4 u% f
  404. /************************************************************************/
    5 ?- P' u7 N, R* U+ c
  405. void WREN()9 y/ _" L2 Z4 X# @" Z
  406. {% h# W+ w  M1 Q4 X# v+ B6 h
  407.         CE_Low();                                /* enable device */
      Q$ _8 f1 ~, Y( q3 b
  408.         Send_Byte(0x06);                /* send WREN command */% p8 \" i0 B2 G: G' O
  409.         CE_High();                                /* disable device */
    6 E. q( \2 Y+ f* u0 @. {
  410. }
    : O8 B, v/ u  D( ~9 k0 d
  411. . k  m) E( s8 o, `  _
  412. /************************************************************************/
      d' n  Z# j8 ^4 N6 k
  413. /* PROCEDURE: WRDI                                                                                                                */
    4 a0 |: O) O3 Z: j5 h
  414. /*                                                                                                                                                */
    ! _5 k: D4 T8 A# D3 ]3 A
  415. /* This procedure disables the Write Enable Latch.                                                */
    2 j( F; r" g7 b% Y- v  l
  416. /*                                                                                                                                                */
    , {+ R. n7 @% P! J  W
  417. /* Input:                                                                                                                                */0 s& x% L+ s& b& C8 p7 B/ B6 {+ m
  418. /*                None                                                                                                                        */# h3 @/ E, o+ W% ?* t, \2 C0 }
  419. /*                                                                                                                                                */! f7 i6 {7 i8 `  A8 ^' J+ e
  420. /* Returns:                                                                                                                                */
    # @- @. F  h9 m1 O( Y1 D
  421. /*                Nothing                                                                                                                        */0 g; ~! U: j$ ], b2 S, _
  422. /************************************************************************/" G" [# H+ \  I4 ^6 \* |
  423. void WRDI()
    9 \( E4 B( T5 ~$ I$ S
  424. {: }! D6 \. M  V, b1 L7 |6 m
  425.         CE_Low();                                /* enable device */$ C1 F6 i& s% K( q8 b2 W+ y
  426.         Send_Byte(0x04);                /* send WRDI command */
    ; g! \/ `) A/ J% l5 w9 S
  427.         CE_High();                                /* disable device */
    9 `; s& p2 A4 `$ O# ~6 i) U) b8 ^( e
  428. }* b% V0 b( v7 a( O
  429. ) e+ b& b: @- ?9 E. h  R
  430. /************************************************************************/
    , C* u6 t3 ?! I# s
  431. /* PROCEDURE: EBSY                                                                                                                */9 L! \' L1 J- ^$ O
  432. /*                                                                                                                                                */- _& n% g& I2 m
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */! X! S& J/ K! Z. h
  434. /* programming.                                                                                                                        */& Z5 W, M1 t/ U- q5 A2 B0 W; c1 s% w
  435. /*                                                                                                                                                */6 u0 o9 R) g# @" c
  436. /* Input:                                                                                                                                */
    4 `9 D9 l4 v- p& x
  437. /*                None                                                                                                                        */
    : b2 J$ d* k3 t9 n/ T
  438. /*                                                                                                                                                */
    + r7 m+ e. z" Q7 f2 C
  439. /* Returns:                                                                                                                                */9 E% s  h* N+ I0 E
  440. /*                Nothing                                                                                                                        */4 }+ Q; Z( E8 `0 b- _( i. L# V
  441. /************************************************************************/$ Z) N9 ~/ F" @5 ?" m
  442. void EBSY()
    9 E) [) M* j0 @$ y
  443. {7 [, D, \' b3 c1 S7 t: s7 R
  444.         CE_Low();                                /* enable device */
    / x) R; r9 x8 A3 a& Y, M) l" X! E
  445.         Send_Byte(0x70);                /* send EBSY command */2 S) H, a; O4 j9 o+ ?
  446.         CE_High();                                /* disable device */
    3 n; {8 @) ~& {; w% U+ h1 R
  447. }
    7 I& S( z/ x, @5 @, T
  448. 5 {( v9 e! o5 B8 H
  449. /************************************************************************/) ^& c9 a; |4 W; H$ P8 \9 ^
  450. /* PROCEDURE: DBSY                                                                                                                */
    * k5 s* v& f6 y4 S" Q8 @. Y
  451. /*                                                                                                                                                */
    / ]! }+ c. o8 P1 A% V5 X
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ! T$ o7 D) r0 C( C
  453. /* programming.                                                                                                                        */
    3 z0 ^2 f7 v9 m8 y3 |' P
  454. /*                                                                                                                                                */9 V* A4 ?2 N* a& c! @. t9 `! g
  455. /* Input:                                                                                                                                */
    " H! P6 @: v3 `. ]( ?9 b. ^
  456. /*                None                                                                                                                        */2 p. W+ H. I+ U  I5 Y
  457. /*                                                                                                                                                */0 J+ e3 V$ A! I! R/ ?! A$ _4 j
  458. /* Returns:                                                                                                                                */
    7 V7 _3 s/ r2 Z) @$ l, m1 l, B; P
  459. /*                Nothing                                                                                                                        */
    2 k3 Z# Y6 U2 _7 v* G& M
  460. /************************************************************************/
    ' R9 c. k! X: q/ h
  461. void DBSY()4 }: V+ N7 ~* S1 j
  462. {2 k$ p" ~4 a! v( t
  463.         CE_Low();                                /* enable device */
    : C1 a; W+ }* p
  464.         Send_Byte(0x80);                /* send DBSY command */" [, ^, S. N& z- Q6 `& X
  465.         CE_High();                                /* disable device */2 `8 p3 ], ?- ]! o: V0 a5 o
  466. }) S7 r/ G4 f; H& P: O
  467. * W% ~* y' \7 k* ?
  468. /************************************************************************/
    / q6 t! T; l. k9 i9 K1 H, Q' U
  469. /* PROCEDURE: Read_ID                                                                                                        */
    * ]! M4 N$ L# e! t% I. _) _
  470. /*                                                                                                                                                *// k6 @0 Z0 L$ }( N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */: @4 y4 q! D) X/ g: d. i
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    $ a: E: c: G% Y0 h9 V( A+ i7 T+ f" ~2 D5 |
  473. /* It is up to the user to give the last byte ID_addr to determine      */3 N! Z) d* H8 h3 r% j
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    ! B( I9 b0 `) j( Y
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ) j# Z* d* p, _3 R9 b
  476. /* variable byte.                                                                                                                */9 i% _+ o7 F4 j- J* x5 O$ R
  477. /*                                                                                                                                                */- q/ d. K2 k7 k9 I( x8 J3 A
  478. /* Input:                                                                                                                                */
    : F8 O$ p) l. _
  479. /*                ID_addr                                                                                                                        */
    + ]) e$ T8 X6 W: B
  480. /*                                                                                                                                                */% t8 q2 j* P  E1 T5 p* l
  481. /* Returns:                                                                                                                                */
    0 E  l, i" u" U( o" K- @! @% [9 t# ^" }
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */0 @1 `9 [  Z4 a
  483. /*                                                                                                                                                */
    7 Z3 L: A! ]4 X; V2 L
  484. /************************************************************************/
    5 ^  R( `! j& ?
  485. unsigned char Read_ID(ID_addr)0 c! ^' J' M( H5 e7 d
  486. {
    6 Z/ \, {5 S5 K3 F1 O! q
  487.         unsigned char byte;& C5 K9 V; i/ K* f/ M% H
  488.         CE_Low();                                /* enable device */
    % T' R! M% A# v: B
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */0 G2 H3 P2 S. _! E# m# ?6 C) N+ g
  490.     Send_Byte(0x00);                /* send address */
    , d- g& g" g0 t# K4 v: G
  491.         Send_Byte(0x00);                /* send address */
    7 p8 q: z" E5 O2 p+ _* [2 P
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */! J& u9 p5 }: {6 I5 O
  493.         byte = Get_Byte();                /* receive byte */
    - v; M8 p" F  t: a' J
  494.         CE_High();                                /* disable device */% N0 j1 W+ ]  W1 c* D
  495.         return byte;
    9 [) S% k* K6 _: D+ r  j* \
  496. }
    5 |! G# h' E4 h

  497. : @, N7 @' G5 }1 M
  498. /************************************************************************/
    # ~# ~; U& [* P+ Q: _
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ' `8 C0 y$ b5 q6 L0 N
  500. /*                                                                                                                                                */
      Y; u& _" z, E" Z& r1 M5 r9 Q5 I* {
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ' S8 R/ I# ]6 Y% R- U
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */4 q/ o8 A' c5 w1 l
  503. /* Please see the product datasheet for details.                                                  */' q# X3 S0 Y9 Y
  504. /*                                                                                                                                                */
    $ T: S2 S1 v4 n, T8 S3 }1 S3 U
  505. /* Input:                                                                                                                                */
    3 ?( i/ R2 A0 J& M7 _+ y7 C
  506. /*                None                                                                                                                        */$ `/ K4 d- J. u9 }% L2 o
  507. /*                                                                                                                                                */
    * H, Q5 I" |- z/ s# I7 n
  508. /* Returns:                                                                                                                                */; ~0 J& M9 R* y  e% C5 ]
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    3 u2 t: h0 ?7 Q2 x( e
  510. /*                 and Device ID (8Eh)                                                                                        */8 m( ?0 L1 w9 y' I: a5 q# R: v5 ?
  511. /*                                                                                                                                                */
    8 R" |) w; Q/ f2 N3 E! R
  512. /************************************************************************/
      ?2 K0 q9 l  n- |2 f- _+ a
  513. unsigned long Jedec_ID_Read() 3 S9 l  m: ~# I
  514. {
    " U; z$ {: T# I1 ~
  515.         unsigned long temp;
    % c" J2 H  k: P3 B: E& ]2 P' r/ L
  516.        
    ( h* L7 P8 c5 u# D2 {" q
  517.         temp = 0;
    ( s/ g; f+ L/ @3 k& V
  518. $ i  j/ w# A1 F4 E; t+ f  ~
  519.         CE_Low();                                        /* enable device */
    ; s$ x% O5 J3 V
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */9 f7 I+ U0 r+ j$ K- J7 |
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */! V+ B( J9 r4 `, L5 `
  522.         temp = (temp | Get_Byte()) << 8;       
    3 @* T4 ^* Y) H' A
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */( r; y3 e' x9 `+ [
  524.         CE_High();                                                        /* disable device */) S, i  M, y- k- x2 T
  525. 3 h* B4 b, `6 N, B$ [" |
  526.         return temp;( D  p) d* c) \
  527. }
    3 A4 Y4 \6 g! ^

  528. 0 [+ W, S: S# d$ @# J3 A
  529. /************************************************************************/
    - }& K+ H0 j# q3 D& y! n* K3 O' U
  530. /* PROCEDURE:        Read                                                                                                        */' P8 _4 e: P, s; c8 m( O# E$ ~$ P( X
  531. /*                                                                                                                                                */                ( D! `& d, a* P1 U
  532. /* This procedure reads one address of the device.  It will return the         */) Q, W, n& D5 f, E: f7 f
  533. /* byte read in variable byte.                                                                                        */
    $ ^4 E6 S" Q/ V
  534. /*                                                                                                                                                */3 J+ y' ?; W2 _- ~5 b
  535. /*                                                                                                                                                */
    ' d' m" y& D& z4 Z0 V2 P
  536. /*                                                                                                                                                */7 e6 A% r3 S5 Y6 o- N" z
  537. /* Input:                                                                                                                                */
    3 K& V( Z7 ~, z) C# s9 |& S- y+ I
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */; ~! p! M5 ]( L7 I; \) @
  539. /*                                                                                                                                      */
    % Z) ~& z2 [  t" }7 g7 D
  540. /*                                                                                                                                                */
    6 r' x% i  N+ Y
  541. /* Returns:                                                                                                                                */6 {# U- [) q, e
  542. /*                byte                                                                                                                        */
    - S9 H% c% a5 y  t+ R
  543. /*                                                                                                                                                */) \& Q/ ~. q  p" O2 K- y8 Z5 @- b& c
  544. /************************************************************************/8 P+ |' ?! N: \5 I% x
  545. unsigned char Read(unsigned long Dst)
    . U- o" J* [7 @+ g# p
  546. {! o$ h  ?7 S: d& y
  547.         unsigned char byte = 0;       
    9 I4 H' @+ c+ m2 v* [' O1 e1 U

  548. $ r1 S  a2 E) b  b* \
  549.         CE_Low();                                /* enable device */
    : I6 ^! Y3 H: Q3 h; ~7 r5 N/ C
  550.         Send_Byte(0x03);                 /* read command */
    : M8 `4 w& x0 f6 z9 q' s+ f
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# P! `, T. I# j$ W+ D
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 N2 Z( Y& M8 o5 Z% ~, G( o/ u
  553.         Send_Byte(Dst & 0xFF);
    8 d/ B) h5 y( Z, @) Z
  554.         byte = Get_Byte();
    / i- ~, k+ |" L
  555.         CE_High();                                /* disable device */
    & w4 m5 E: z. A
  556.         return byte;                        /* return one byte read */
    4 q! E' u) O/ i) c
  557. }& K3 R7 Y; z4 F: h' n! P
  558. : f: Z  j% h! m5 t
  559. /************************************************************************/
    0 x. I0 X6 v6 z
  560. /* PROCEDURE:        Read_Cont                                                                                                */  n1 l) T. o9 U  u- i) ]
  561. /*                                                                                                                                                */               
    . O5 {1 E8 v6 W3 t% h
  562. /* This procedure reads multiple addresses of the device and stores                */
    * ~% [' Y+ y4 ^9 l- T- v
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/! x& @1 [/ e* T9 g3 X1 P  b
  564. /*                                                                                                                                                */
    * Y8 R) r7 U0 W! u6 C
  565. /* Input:                                                                                                                                */
    0 [1 \! n! q4 f4 M
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */  t6 c( |; r5 O. w! D
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */# s# U, Z4 _# p: B! Y9 @6 P- h8 V
  568. /*                                                                                                                                                */
    4 n: R; O, w. _1 z- A
  569. /* Returns:                                                                                                                                */
    3 @6 G; n' }5 `: e8 \! T
  570. /*                Nothing                                                                                                                        */, [  G( x" `5 J0 c
  571. /*                                                                                                                                                */, j/ @1 e5 T0 J6 ^3 j! g/ @
  572. /************************************************************************/2 _* K* W: w) ^  s
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)8 ~! ]: W2 O; b2 ~) ?) h) R. Z
  574. {
    * g$ j( W  ^$ g% e
  575.         unsigned long i = 0;7 z. w) ?6 Z! s: D' G6 v! G
  576.         CE_Low();                                        /* enable device */
    6 e/ T- m  y, _& T& J6 y
  577.         Send_Byte(0x03);                         /* read command */
    ; z8 D8 A! s- I5 y+ a
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  E+ |: t" K* p- |4 j
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : h' H; ?' T7 ^. J8 N
  580.         Send_Byte(Dst & 0xFF);
    + k0 ~1 @; B  s# f* Y6 {
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */0 L1 _  v# y$ ]. R: Y
  582.         {1 _- o% j/ S7 ^; o% E* p# Y# ~
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    2 p7 m# A7 N. P
  584.         }
    ' h  S7 H! u7 U* C! B1 R# w: k
  585.         CE_High();                                        /* disable device */
    0 U" w  i8 W1 U  Y+ ^' y& \0 i( O
  586. ! A2 ]9 J! o6 i0 x2 C7 j  B5 Y
  587. }9 t9 d5 m9 F$ @) e( q
  588. 7 Z3 P9 ?  k, \7 h* g0 V
  589. /************************************************************************/
    4 l( K# G  _. J8 I
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    ' E& @" ^7 [  f, r, H
  591. /*                                                                                                                                                */                  V( }2 c6 L; x) p' f& Y4 S$ l7 L
  592. /* This procedure reads one address of the device.  It will return the         */( w* k8 J9 c  H- ], `* I: {
  593. /* byte read in variable byte.                                                                                        */& }1 c4 L# y4 W" ]
  594. /*                                                                                                                                                *// K1 A2 I! k; x0 d1 F0 U
  595. /*                                                                                                                                                */
    4 J+ I: j$ J& U8 ~" A6 J
  596. /*                                                                                                                                                */3 U2 E. r2 Z; V/ j$ J$ A$ J
  597. /* Input:                                                                                                                                */
    % S% {; M7 ~6 b2 T7 Y
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */  E8 n3 I0 N5 w5 L/ x
  599. /*                                                                                                                                      */
    : f4 @8 Z& v) ^
  600. /*                                                                                                                                                */
      E: L+ W& w+ H
  601. /* Returns:                                                                                                                                */1 w( _( Y8 Q) l& r9 O2 l1 ^8 t
  602. /*                byte                                                                                                                        */
    3 E9 C/ g9 p  E" c, f4 f
  603. /*                                                                                                                                                */
    ) `( N! o& ^- _+ \0 z
  604. /************************************************************************/4 {1 [0 s  I6 R5 |$ ^8 ~' S+ r/ j
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    * i+ a# W! p' t  a. Z1 ~$ l( C
  606. {2 X/ V9 ]7 C+ Y8 k$ ?$ @- h
  607.         unsigned char byte = 0;        : p1 E. Z6 g  `

  608. $ V, U4 p5 _0 d8 \" L, Y0 @" R" h
  609.         CE_Low();                                /* enable device */; S, ?' g- y: ^( N& p
  610.         Send_Byte(0x0B);                 /* read command */
    2 L7 q$ h- t2 M2 b4 E, c' z1 f
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */! g& T: s) K% ?+ `
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));. |( O( i' [; b  R5 x
  613.         Send_Byte(Dst & 0xFF);
    0 `# S( O: ?$ t9 R' J
  614.         Send_Byte(0xFF);                /*dummy byte*/
    ( J' x. Z  }, |9 q
  615.         byte = Get_Byte();
    6 ]% G) K1 }' w. h  c0 y
  616.         CE_High();                                /* disable device */3 `2 w5 \7 a& j2 m) _$ m
  617.         return byte;                        /* return one byte read */
    9 t5 e  g+ l1 i0 X7 M
  618. }
    ' e1 D- u8 A" ?: v
  619. % P5 g8 c0 H; R: j! w1 x
  620. /************************************************************************/
    ! r  |9 \3 B/ L$ j- w/ L, U
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */. A1 D: y! I, ?6 q
  622. /*                                                                                                                                                */               
    : ]" X* V4 A3 P; l: w5 D5 L
  623. /* This procedure reads multiple addresses of the device and stores                */
    # f% {- W  @  g
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/6 K2 U6 q$ i) ]
  625. /*                                                                                                                                                */
    - f3 L3 Q, \/ W, n" g3 p4 v6 s$ p
  626. /* Input:                                                                                                                                */
      a  @# L4 E4 w
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 F5 a; b. W: u3 V4 z
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */: D/ V7 i$ J% R" M7 D+ O* j! k: j
  629. /*                                                                                                                                                */
    4 Y- T% r/ j  f. ~# |9 U- @" k3 F3 s8 z! x
  630. /* Returns:                                                                                                                                */
    2 T6 s4 b9 H: j4 c' V' n  F+ Y; k
  631. /*                Nothing                                                                                                                        */
    , f* M( G- Q4 k8 e
  632. /*                                                                                                                                                */1 `1 m. ^4 g8 f7 x! @$ C
  633. /************************************************************************/
    6 T9 d. T3 X" z, j, N4 u
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)6 C0 u, t6 ]/ P; X
  635. {4 c: Y* d# G) ^9 u+ N: z' V
  636.         unsigned long i = 0;$ |* \  `% D' G0 n) k4 L
  637.         CE_Low();                                        /* enable device */5 _( i- \) l  B' I) ]- k( C
  638.         Send_Byte(0x0B);                         /* read command */
    $ x" e) \+ ^" R1 Q  y- E* ?
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    9 s9 h' U3 C8 \; w9 }
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) N% C/ _1 m" i4 G: L' |1 m: w* V
  641.         Send_Byte(Dst & 0xFF);
    $ [& i8 D9 g* G) x
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    + a- Q6 ~8 l$ E* Z' _* ?# m8 _! _
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */. A) K  C1 c4 G
  644.         {9 w8 M1 h- y; q( K* H0 ~6 [
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ( o# q1 Q! o* ^  g3 \# t
  646.         }) T; g/ w" x( k( R  o
  647.         CE_High();                                /* disable device */, k& A6 h* ~. j1 H; ^9 d- j
  648. }; r, I* r, y( e) M- k

  649. , d; x. g' I: Z5 h8 c5 f) G* v4 p
  650. /************************************************************************/" A9 J' O1 i% \, u: J
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    # z1 Z7 D; o6 Z! Q) x/ Z
  652. /*                                                                                                                                                */
    ! K" g0 X: z( L. L! r9 e
  653. /* This procedure programs one address of the device.                                        */
    ( r0 ^/ `/ j- m
  654. /* Assumption:  Address being programmed is already erased and is NOT        */" a7 u, L" m5 r
  655. /* block protected.                                                                                                                */
    % H+ q$ e1 S: [) T0 z) w, U
  656. /*                                                                                                                                                */
    4 u  `2 B1 J( _7 c
  657. /*                                                                                                                                                */
    + X4 _) R) q8 [& C3 h
  658. /*                                                                                                                                                */. ~9 F/ Q' V4 ?
  659. /* Input:                                                                                                                                */! W5 p! F9 P0 z; L! U" z
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) [0 c- T+ T& w  o7 r
  661. /*                byte:                byte to be programmed                                                                */
    + S6 z* @; O4 D+ ^* [
  662. /*                                                                                                                                      */4 x8 X2 M( N3 I4 _# s+ L3 N
  663. /*                                                                                                                                                */
    ) M3 w9 l2 R$ w* i) G! e' p
  664. /* Returns:                                                                                                                                */
    3 e; h; L4 s4 ?6 K; L. K- D
  665. /*                Nothing                                                                                                                        */
    2 _2 T$ h% F1 b* z! ^: X: _
  666. /*                                                                                                                                                */+ a1 w/ U# I# c1 N3 E  e
  667. /************************************************************************/
    % X- r3 {* F" J. f! m- @
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    & o6 P/ q* k  `
  669. {
    * f, a. j7 e$ J0 h. Z% Q
  670.         CE_Low();                                        /* enable device */' e. Z1 h0 U' f6 i9 q" s+ [" V* [
  671.         Send_Byte(0x02);                         /* send Byte Program command */
      D3 X1 I3 ^: M# p/ T9 |- |1 X$ [
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */6 A. `# ]  x, E
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));: R3 e, E: n1 b/ I" }/ J
  674.         Send_Byte(Dst & 0xFF);  F7 `; h; a$ T8 ]  _
  675.         Send_Byte(byte);                        /* send byte to be programmed */. N  j! @. D( w, C$ c# f1 ?- C0 L
  676.         CE_High();                                        /* disable device */& _7 y, `1 d( ^* g" u- m
  677. }
    , y. F' k6 [1 j- X# `" F8 A; d
  678. % ?% i$ t1 F3 r! q  u. u  P
  679. /************************************************************************/
      ?  B4 n1 t7 J- a; V& `
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    $ v, t/ m) O# U. `: ]3 o
  681. /*                                                                                                                                                */
    + b( k$ z$ E1 P( p
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/, w) x3 f" O. ^9 H# _
  683. /* the device:  1st data byte will be programmed into the initial                 */
    8 ^2 {8 E9 r+ H( [0 f' U8 e/ |
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    . i/ L/ p4 y& C: F: i
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ! N# D; o- A7 m% N* j  [) f
  686. /* is used to to start the AAI process.  It should be followed by                 */
    0 l# f4 _- `1 y2 m/ x# @  u$ H6 c
  687. /* Auto_Add_IncB.                                                                                                                */) Q/ R% n- Y* Q8 e7 B* l8 B
  688. /* Assumption:  Address being programmed is already erased and is NOT        */; ?. m- p, p% E% d( m9 a
  689. /*                                block protected.                                                                                */
    5 N- t, W+ x+ y9 k2 R2 G" k
  690. /*                                                                                                                                                */
    6 x% e, a+ e/ y- H/ y
  691. /*                                                                                                                                                */8 E) [3 J8 N/ P' G' T! m. E
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */) w1 H! {  `4 W% t4 P; ^
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */2 _2 x+ U2 c  b3 i" `9 y
  694. /*         unless AAI is programming the last address or last address of                */3 W7 R1 M9 V2 k5 i* ~/ y
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    4 T& I4 Q: L  Z, W
  696. /*                                                                                                                                                */2 [2 G! a/ z9 \9 `( W
  697. /* Input:                                                                                                                                */
    + v* v3 a2 ^5 o( L* w
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 N# K/ M; X* R
  699. /*                byte1:                1st byte to be programmed                                                        */
    , I7 k( E2 o( E5 W$ |$ Y  |
  700. /*      byte1:                2nd byte to be programmed                                                        */
    9 Y+ y3 |6 K# t4 y: w" S! q: s
  701. /*                                                                                                                                                */2 P5 ?- X! E  N/ ]7 |; d+ ]0 a
  702. /* Returns:                                                                                                                                */0 T7 `  z6 z* E0 @( x3 R! ?
  703. /*                Nothing                                                                                                                        */6 A7 t: F+ w9 d7 o7 S! s# v; X
  704. /*                                                                                                                                                */, v) Y8 f7 L' M( R, t+ ?5 m; w
  705. /************************************************************************/1 |$ A* `6 W: o, Z/ E
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    6 S% ]- m4 n0 f6 B* H3 m
  707. {
    " ^9 w8 b7 d( ]3 C& P# X
  708.         CE_Low();                                        /* enable device */& \6 c, K" A% o
  709.         Send_Byte(0xAD);                        /* send AAI command */
    5 L; u5 z3 j) g$ q
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */8 r: @+ a2 q) t" Q
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));% E" Y/ A; h& w3 D, {
  712.         Send_Byte(Dst & 0xFF);
    0 l+ c1 N8 ~7 b- ~5 H( v
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        $ z; C4 T+ ]# a
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */+ e  ~6 X: G# s+ n5 M8 ~
  715.         CE_High();                                        /* disable device */
    ; [) r3 Q' e1 k# \% |& E( P8 |
  716. }3 \  h1 r  v; S3 x9 q3 D* e

  717. ) u3 A: U7 g' J$ J
  718. /************************************************************************/4 }. Z, d- i) z" P# C+ }
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */7 `4 s, L2 e3 _) z
  720. /*                                                                                                                                                */7 d/ o3 `  ]4 A
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/' a- c- M2 v2 K' m4 d: H# J
  722. /* the device:  1st data byte will be programmed into the initial                 */3 |3 P; j7 a0 o* c  f& p0 _  y6 X
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    " a! S& |7 P$ w/ K
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */. g3 m8 k% G% {# _
  725. /* is used after Auto_Address_IncA.                                                                                */5 v) p$ {, c! l% s3 C; w$ B7 Z+ N
  726. /* Assumption:  Address being programmed is already erased and is NOT        */; a* M3 }2 `/ x% t9 c
  727. /*                                block protected.                                                                                */( G1 s1 E" a( e! j
  728. /*                                                                                                                                                */! W0 x7 C+ C  n" `
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */1 L$ R7 K) ^" X+ b
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    8 \2 K0 b4 `9 D
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    7 z( c6 n$ ~$ q7 v6 v, M4 r# h
  732. /*          to exit AAI mode unless AAI is programming the last address or                */1 ]& }, S+ ]- O6 c! y3 K# t- w
  733. /*         last address of unprotected block, which automatically exits                 */
    3 d0 Q4 A. o0 n; A  O# G5 `2 T
  734. /*         AAI mode.                                                                                                                        */
    5 a+ @/ k' H6 H: ]7 N/ Z
  735. /*                                                                                                                                                */
    ! q5 ?0 m; E8 W, |& I
  736. /* Input:                                                                                                                                */) u2 r1 s% a+ {. T6 y/ ?' S
  737. /*                                                                                                                                                */
    ! \/ n9 F7 m9 ?: v9 V
  738. /*                byte1:                1st byte to be programmed                                                        */
    3 M) g. H4 O& T& S7 k
  739. /*                byte2:                2nd byte to be programmed                                                        */$ _* Z; S, J: C* w+ A3 p" [6 M0 ^
  740. /*                                                                                                                                      */
    * E4 T1 }8 Q5 b: T
  741. /*                                                                                                                                                */7 U$ M0 i9 E4 J% h
  742. /* Returns:                                                                                                                                */- c. f0 P" \* M
  743. /*                Nothing                                                                                                                        */, t5 `" t& E5 W) _
  744. /*                                                                                                                                                */8 O1 B1 h0 ]/ t+ K# q
  745. /************************************************************************/
    8 a' v  F! H( K1 `4 L* }, ]6 l
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)& [4 F1 P& W8 g7 \8 a3 N
  747. {
    ! a! Q8 C$ T* F' C& M6 `$ ^8 o
  748.         CE_Low();                                        /* enable device */: J; v5 ^. |; U+ T3 l  Q; V# @1 y
  749.         Send_Byte(0xAD);                        /* send AAI command */
    & a/ T) [+ d* @4 E$ `" ]
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */. E% z* n* z+ }2 u
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */9 r, g+ c; T- _
  752.         CE_High();                                        /* disable device */
    + o& T0 O7 b, N% F, G* |7 b
  753. }
      F6 s0 T. {; y7 `

  754. 0 D9 d+ K; C$ \+ J6 p, `3 ^! G
  755. /************************************************************************/
    5 w9 x6 z9 w/ i8 `. B
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                *// Q2 k4 j) u3 G0 L& S1 e2 P
  757. /*                                                                                                                                                */
    ( a( ^0 s3 }: j& X" ?- c
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    $ ~+ t0 M2 j' b4 H, U# j
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */+ V. t# X8 K+ x" h
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */' i/ C4 o( ]) L/ j6 ~5 L) N
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */- D, b8 n' _* ~8 E7 i; T) P
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    / r) b* d7 w( v$ C! u
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    6 R: }4 @* U) X5 X. }& F
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */8 J- P" {' A  r' r' ^' z
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 P/ [5 {* t) W
  766. /*                                block protected.                                                                                */
    3 S- l3 ]  r' l6 J8 U
  767. /*                                                                                                                                                */
    * B5 J! J. Z: y) Z; i3 y: Z, n
  768. /*                                                                                                                                                */
      ~5 r+ ^1 K" t2 f/ ?! ]/ ?/ n" ?3 M
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */. x8 c- s5 j8 c0 Y6 ?5 ]6 G
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */% t* [2 J! ^/ L! N; D! x9 q# ^
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    7 k0 O! t9 c! C* z$ Y0 G& T2 ]
  772. /*          to exit AAI mode unless AAI is programming the last address or                */  _, e4 M, X+ l3 e- k3 t0 l
  773. /*         last address of unprotected block, which automatically exits                 */
    2 \) j+ i, |) Z1 o% C/ a4 x
  774. /*         AAI mode.                                                                                                                        */7 ^, U) B, L0 B
  775. /*                                                                                                                                                */
    : K9 |! |6 K9 S6 [/ Z
  776. /* Input:                                                                                                                                */
    1 Q; ]/ r! t, B% X9 n/ a! m) g
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & l7 E2 E# T+ @& n/ C3 Q% u9 q9 z
  778. /*                byte1:                1st byte to be programmed                                                        */
    $ ]6 G4 t4 {$ N  [% P* K+ l% L
  779. /*      byte1:                2nd byte to be programmed                                                        */: Z( P3 {: S! p  Y; z8 R' C
  780. /*                                                                                                                                                */
    0 u! z: Z8 O6 h5 o
  781. /* Returns:                                                                                                                                */8 x5 D* c/ S2 W- h2 I( S! @7 x
  782. /*                Nothing                                                                                                                        */
    9 _& E+ ]3 n1 h; |
  783. /*                                                                                                                                                *// i6 L% q- U! d  e8 X: h
  784. /************************************************************************/
    6 s) @/ B$ s! f. m+ f# P1 i
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    5 a* ?$ B0 j! c
  786. {% ]2 ]8 Z- f' X
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    4 f4 E5 c+ G( ^0 I: _$ n

  788. 9 Z$ d1 h6 e# A& ^0 p' R' x  {# ^
  789.         CE_Low();                                        /* enable device */
    0 i3 G1 e( X2 `1 Y! _" G
  790.         Send_Byte(0xAD);                        /* send AAI command */+ J) ?: e% ^+ N2 B* u
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */6 t# c3 O2 p' |. P
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 m5 d4 n& ]$ r& z" _; B
  793.         Send_Byte(Dst & 0xFF);
    : P$ I1 e3 y6 E; z: k9 t, |
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        $ B% j; A( |4 F! A5 p8 k! F+ j+ S
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */. X! `) w1 e3 S: |! K7 V: c
  796.         CE_High();                                        /* disable device */, U, ]3 J, @1 B1 U% S' F4 }
  797.         & u5 `! B: G" z. k, \; D" @0 f0 p
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    ' v2 h0 {$ S2 m7 {0 w( ^

  799. ' l" g2 H, c# G! H( A0 n% @
  800. }6 _  d8 C7 v# W, [8 H1 _
  801. 5 _& S; A# i+ |
  802. /************************************************************************/
    : i0 W: L0 e' r& Z/ `* I
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    2 z) H' S8 O  \( m% C
  804. /*                                                                                                                                                */& F0 f, t1 Q3 J; t+ M6 G% o
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */" [* u) |6 J3 {$ s/ t2 a
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        *// i6 n+ B: X1 Y& n
  807. /* AAI programmming is completed.  It programs consecutive addresses of */. O/ }# K& B  V! }; l
  808. /* the device.  The 1st data byte will be programmed into the initial   */2 I" f" @" p5 ?: p* M4 I" y
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    ! h1 X1 V* S, i% T0 }6 T! A2 O
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */6 {- E/ G% R. Z. w" Y
  811. /* used after Auto_Address_IncA.                                                                                */
    ' V, ]0 S* o" q, M( H- W
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    7 W& I# y5 t& `8 |: l0 e! L
  813. /*                                block protected.                                                                                */
    ; g% \( V# ^& n/ X; f
  814. /*                                                                                                                                                */$ Q; L! R, ~0 P7 J/ G  i
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */1 u" J: Q' s" E) h; \. {
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */& e6 C' b, o) b0 n
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */) |" \# U! ~0 i8 N/ y9 @
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    " f: Z7 V7 g" v6 b  a. J
  819. /*         last address of unprotected block, which automatically exits                 */
    ( y% D- x5 V. k. W+ }8 o' M
  820. /*         AAI mode.                                                                                                                        */! w! v% L2 L/ x& \- k  Q+ h) {
  821. /*                                                                                                                                                */' `5 p. b* l; x! e3 J$ B' `
  822. /* Input:                                                                                                                                */
    5 u# F4 l( t! q6 X' f; ?5 w
  823. /*                                                                                                                                                */
    . }1 J: j& q! D+ h4 Y( f" A: R
  824. /*                byte1:                1st byte to be programmed                                                        */* _2 q$ I" V3 i1 C" J8 i: q; m
  825. /*                byte2:                2nd byte to be programmed                                                        */! o1 N4 l! F1 f% w+ i' j- J! Q
  826. /*                                                                                                                                      */8 h: }, l  I- t1 C! N
  827. /*                                                                                                                                                */
    1 T5 s" |' G- e3 b6 D4 R
  828. /* Returns:                                                                                                                                */
    1 W6 C7 B+ T8 u$ e1 Y2 i* \
  829. /*                Nothing                                                                                                                        */5 c3 K' s( ~  L$ Z8 J
  830. /*                                                                                                                                                */
    , N$ Z7 @% g, w- I. P, a
  831. /************************************************************************/
    & Y& `2 N5 B6 j% q. f
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)# Q0 q! d7 k+ p0 |6 m% X' Q% O  J
  833. {
    4 {7 v- l0 e7 e7 j) U) d
  834.         CE_Low();                                /* enable device */
    ' n. `" K8 t& `- u
  835.         Send_Byte(0xAD);                /* send AAI command */
    & j) M9 c  P) u) l) L
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */4 G( z- ]* h9 T/ D$ W; x
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    4 \1 H; l" I  S
  838.         CE_High();                                /* disable device */
    0 r% B1 k+ e0 f" `. ~5 l
  839. 0 D$ n: B0 T. Q7 d/ ~) Z4 L3 C
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    3 Z+ e  w+ S! n, D/ r
  841. 3 u  N" B( |. p  P. D% C( C. J
  842.         WRDI();                                 /* Exit AAI before executing DBSY */' |: F' i6 f6 n9 _9 Z& ^
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */8 H% ~, P8 ?! [3 u
  844. }' c/ n2 ]& z1 G1 U. a% i

  845. $ y2 Y3 {, b. w4 e7 g
  846. /************************************************************************/. E, ~7 D/ u4 D
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    5 A! U9 R3 J9 u
  848. /*                                                                                                                                                */
    8 P' M* @" x6 {2 ?3 u
  849. /* This procedure erases the entire Chip.                                                                */4 J* A4 B  A' m+ I" @1 a/ h: C
  850. /*                                                                                                                                                */- C8 m8 B; G4 n& p
  851. /* Input:                                                                                                                                */& j1 u& j( N8 d- z4 z. p% P' i
  852. /*                None                                                                                                                        */1 M2 I; D0 Q% K: j0 U% }, J
  853. /*                                                                                                                                                */
    $ y' [9 x7 L1 q
  854. /* Returns:                                                                                                                                */1 f: F5 t; _, R' v& Z% U
  855. /*                Nothing                                                                                                                        */
    2 P: s( y1 }1 G
  856. /************************************************************************/" b# c- q4 K5 n
  857. void Chip_Erase()# y; S; a* \3 }1 Y9 K6 L
  858. {                                               
    " a; N  f: ?% N" S. d4 V. S# @
  859.         CE_Low();                                /* enable device */
    ! i" C/ z: `& W0 y
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    ! j  i+ b) j1 l: C2 W
  861.         CE_High();                                /* disable device */
    2 H0 z$ `- ~3 `. f; W
  862. }+ ^' S) V# t! K- h7 ~" R
  863. , G8 U+ ]. z; [+ X5 v* r% ]4 j
  864. /************************************************************************/1 ]0 E9 ~' R- o. C$ a, ?7 C3 @: H8 ]
  865. /* PROCEDURE: Sector_Erase                                                                                                */' _& N4 W& O( L! r. t% [
  866. /*                                                                                                                                                */
    9 d  s) |) ^  W5 e, r
  867. /* This procedure Sector Erases the Chip.                                                                */$ \  n6 I" b8 i- R: e+ u
  868. /*                                                                                                                                                */0 D2 T: y4 U8 n8 W! h; }! _
  869. /* Input:                                                                                                                                */
    . I4 y8 E( u9 r' m' @9 \2 N: g
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */7 ?' i7 q& Q# ?4 }' D6 @
  871. /*                                                                                                                                                */$ s8 `3 Y& S3 s
  872. /* Returns:                                                                                                                                */* }' ]6 F6 P) N) x) G/ a( T/ X+ S/ P
  873. /*                Nothing                                                                                                                        */$ t7 j  I5 G5 u& j* O* l6 L
  874. /************************************************************************/
    ! E$ r: X2 w- _% u1 E
  875. void Sector_Erase(unsigned long Dst)
    5 s0 y% G/ k5 }! A( j0 K/ T7 i
  876. {. N: z1 y8 d7 q4 x
  877. 4 F" L  x/ H7 ^
  878. ) Q3 ^; R2 M8 ]" ?5 _8 q
  879.         CE_Low();                                        /* enable device */# \+ r* w( u' R; {# N  d
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    / p+ F6 M+ j4 `9 m: f
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . M* _! W* s4 c3 O" c( f
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));5 [! v$ e. f2 E5 D. c6 S
  883.         Send_Byte(Dst & 0xFF);# |1 F6 G0 n  Q' z3 D
  884.         CE_High();                                        /* disable device */, q- [: P2 j- D' H) {4 \- Y% @
  885. }       
      `. j) k& ~( X1 L

  886. . _" b7 Z! @0 z, a0 @
  887. /************************************************************************/1 P; D$ l9 A6 W8 a" V- c9 k
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    9 b  d  v0 U9 P6 l
  889. /*                                                                                                                                                */: L% Q0 t2 W+ }5 N" j1 ]
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */8 V" ?7 L  ^% `# X! @9 }) d; p2 {, z
  891. /*                                                                                                                                                */
    8 f+ E* N0 G' u7 K# _
  892. /* Input:                                                                                                                                */
    5 p) k( \/ G% Z7 B0 w# c7 }' Z
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 Y6 X! E8 u3 s9 h
  894. /*                                                                                                                                                */
      |2 {# ~7 s) T/ z2 Y
  895. /* Returns:                                                                                                                                */
    / K! m/ j8 G( b$ l
  896. /*                Nothing                                                                                                                        */
    # u7 w4 B8 X3 X3 `' z
  897. /************************************************************************/# ]0 ~# V  s4 j+ M3 h
  898. void Block_Erase_32K(unsigned long Dst)
    9 Y: e5 v( L% k2 V2 W
  899. {
    * e5 g# S- o# G4 Q! P+ y) Y) j
  900.         CE_Low();                                        /* enable device */
    : q# p# e' o% N3 U4 a
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */& [9 Y$ J2 s& ~9 p6 x
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 g) @7 q! f2 R$ J5 a, U
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 C1 \  A: T9 {0 N' P) _
  904.         Send_Byte(Dst & 0xFF);
      _0 K8 S7 |' ]. P) z- v
  905.         CE_High();                                        /* disable device */
    - I5 g" y8 o; ], x
  906. }+ p% ?$ h8 {1 R2 p  r& u8 v/ x

  907.   y: O* b* Q, ]  h9 f; B
  908. /************************************************************************/
    $ D0 P/ s4 d" }, T( J+ b
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */0 [: m) L( o- c; t
  910. /*                                                                                                                                                */
    ' C* F2 G7 u9 c) V! P+ g& }
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */$ i5 Y5 t0 i% s4 U
  912. /*                                                                                                                                                */6 C* u! N$ L' k" R: Q
  913. /* Input:                                                                                                                                */
    3 `& g8 [9 X/ P) b) O9 k7 h
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. R! M6 \: e: n+ W' z' ^8 t# e
  915. /*                                                                                                                                                */
    ( V- N$ [; c! X
  916. /* Returns:                                                                                                                                */
    - K% i+ e6 l" h- H- p# E4 t; u  H1 s
  917. /*                Nothing                                                                                                                        */
    . x4 L) _: ]! J) U2 ?! d- Q, o5 Y
  918. /************************************************************************/
    0 Y5 k: x+ d! m6 q8 X& ^2 ^- q5 X' r
  919. void Block_Erase_64K(unsigned long Dst); X; W2 c8 |7 O
  920. {& G: ?7 |; Q1 f/ G8 j+ J% {
  921.         CE_Low();                                        /* enable device */7 L$ Z" S; A" u( Q! b4 N# g  g+ A
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    , `! J9 k" q* D- p& R
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ H0 O' N$ P! ]+ g. R
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));$ g3 P8 j: V6 u( @
  925.         Send_Byte(Dst & 0xFF);
    + S0 Z6 Q$ H: o5 Z
  926.         CE_High();                                        /* disable device */# o9 b) }$ X' h6 h; D! \9 N8 ?- [
  927. }
    3 i! H# F1 W1 b& e8 b& @. _7 |

  928. / y$ {) }. b- J6 j
  929. /************************************************************************/
    8 g0 S) _% S  M* i4 J+ f
  930. /* PROCEDURE: Wait_Busy                                                                                                        */3 d/ Z; N9 I; j% O/ d6 v, y6 m) n
  931. /*                                                                                                                                                */& H# B& x# U) O7 S
  932. /* This procedure waits until device is no longer busy (can be used by        */
    , s& ?  q" ^3 X! T4 T, y# I
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */! W+ q" f8 m& f& m+ ^' X
  934. /*                                                                                                                                                */+ r! O7 F! h3 \  m% @
  935. /* Input:                                                                                                                                */* h$ U( q6 v! p
  936. /*                None                                                                                                                        */
    / l$ b+ o4 B  x5 U
  937. /*                                                                                                                                                */
    9 m: @$ e/ v) x' f& o& `
  938. /* Returns:                                                                                                                                */
    ) L) D2 C5 d: t: Q4 z  _( O
  939. /*                Nothing                                                                                                                        */
    8 c/ D! M; r3 }, M8 F
  940. /************************************************************************/
    ( e, [- f/ E1 @
  941. void Wait_Busy()# j3 a9 g% C2 U7 M9 f* ?
  942. {$ {0 _& g* K3 o$ O6 D
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */3 \4 v9 b1 k( R8 r! [/ _
  944.                 Read_Status_Register();& b, P) f! C+ e. e
  945. }' B! B/ M6 l* k9 V0 K3 N( h
  946. 6 i% x  O2 C( k* o, i/ R
  947. /************************************************************************/
    , z3 B; ^/ ^* Z0 k, E
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */; p, a8 X( I; X2 q" \3 o8 Z" y
  949. /*                                                                                                                                                */3 n# M, C. r* X8 }; m. w+ Z$ g
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    $ n& U' Y5 m3 Q
  951. /*                                                                                                                                                */; i2 w5 y8 e; {& M/ d2 A7 H- _# ^3 u
  952. /* Input:                                                                                                                                */
    . d! _  [2 m: X+ P
  953. /*                None                                                                                                                        */
    $ `! |; J! @: u1 h1 S) f, {% r
  954. /*                                                                                                                                                */
    % J# w6 L5 W5 Q( w( k
  955. /* Returns:                                                                                                                                */! S& y2 V" a7 I  |* l9 B( Z
  956. /*                Nothing                                                                                                                        */
    ! e$ l9 I0 w5 T+ V
  957. /************************************************************************/
    2 y8 X1 q- p% d0 v/ g4 w
  958. void Wait_Busy_AAI()1 r* S& }4 T4 V9 [
  959. {
    9 `5 S1 z  W0 ?+ G7 {; j
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    % n; \& e7 E( h; K% r/ m& v0 Y- ^
  961.                 Read_Status_Register();
    . Y% }8 P: s; D: ~2 ?9 ~* v( c
  962. }
    2 q$ A( E$ J$ N

  963. ' v* i0 M$ y" L' x! t
  964. /************************************************************************/
    : T  u6 I$ N8 s
  965. /* PROCEDURE: WREN_Check                                                                                                */% g+ t2 p, }9 {3 d' k
  966. /*                                                                                                                                                */
    ; |" l7 x8 g% A! m$ P; J
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    & Z3 r! ]. m. I+ C% Q0 u7 Z
  968. /*                                                                                                                                                */
    5 l2 t  f7 B# |0 ~" o
  969. /* Input:                                                                                                                                */, b" T9 ?7 u# C+ T
  970. /*                None                                                                                                                        */
    1 W# Z' O1 H: Q4 `# \. X
  971. /*                                                                                                                                                */! F% M% J: w& N& w" V; a# d" Y
  972. /* Returns:                                                                                                                                */7 L( n8 G1 V4 }  c
  973. /*                Nothing                                                                                                                        */) K6 s* E6 X2 {! M! C  O
  974. /************************************************************************/
    9 ?0 }; f& m7 H/ L- N
  975. void WREN_Check()8 `  C; g* j5 n  a2 T
  976. {/ B  S% ~! k: W: Y
  977.         unsigned char byte;  t# K, d& I/ M+ x. M
  978.         byte = Read_Status_Register();        /* read the status register */- }, M1 b% O; E" {, ^& [
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
      N& p) H0 v* d2 G/ u  J- z' J9 f
  980.         {2 d: y3 v8 m& X0 o8 g4 K+ u  O
  981.                 while(1)5 H. q, q* r5 ]) y9 O! ?: x% k
  982.                         /* add source code or statements for this file */& |0 ^8 j3 Y/ L* J& v
  983.                         /* to compile                                  */
    . I# M. `! G2 N* y# }1 B" F; k
  984.                         /* i.e. option: insert a display to view error on LED? */
    " V" x  e, Y. J# Y2 C' J8 T2 G
  985.                  
    2 Y4 }* I4 s; ~, M: t$ s. |8 j
  986.         }
      y8 j* t' l& h1 Q( x3 H8 t
  987. }
    3 R5 @" G! G$ p# k9 X0 Z
  988. # P& k* f3 @6 t; a/ Y3 B
  989. /************************************************************************/
    . e* {. F: F, E
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */8 J  O, O! V3 P6 S9 B
  991. /*                                                                                                                                                */
    ; S( b! W0 S- N; _4 I' o6 g
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */! M6 m9 i2 ?9 S9 i8 n
  993. /*                                                                                                                                                */& z" p1 y6 L! I+ R" u1 V
  994. /* Input:                                                                                                                                */9 A8 @$ E* S: G* m* I/ ^- d
  995. /*                None                                                                                                                        */
    % M8 K- N; h' H6 O1 H7 W& Z1 e
  996. /*                                                                                                                                                */8 ~/ N, k  `+ Y# ]8 \
  997. /* Returns:                                                                                                                                */- t; A+ k: ]0 z$ V
  998. /*                Nothing                                                                                                                        */
    2 _7 i0 N. p% Y) M" K, n" o
  999. /************************************************************************/: o6 ~( p: v! f- K, ^: y4 a& ]5 R" d  h
  1000. void WREN_AAI_Check()
    - J# w! T! `& }* y! m8 o# _
  1001. {1 n8 @3 g' ~+ H# b9 n) l8 A& R
  1002.         unsigned char byte;* @- d; F: Z4 S. J
  1003.         byte = Read_Status_Register();        /* read the status register */" L4 u3 g% O7 G& k+ o. P- ?
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */# R. b3 G1 x( R2 [
  1005.         {3 R. I2 h# F7 S. q$ a. N/ w( @
  1006.                 while(1)                9 r) ~0 H! g! h; a. o$ [2 [
  1007.                         /* add source code or statements for this file */
    $ M6 W5 G( V+ m6 b: ]
  1008.                         /* to compile                                  */
    0 i: ~! p8 p5 f$ ?8 q* |+ ~6 ]0 m
  1009.                         /* i.e. option: insert a display to view error on LED? */
    " z* t  n$ W6 I; r

  1010. . ~- A2 N, Y  ^8 n
  1011.         }2 N. {9 R* G4 \6 e& B8 }, y/ g
  1012. }* K1 i# w8 t8 s8 ]  O/ b+ f
  1013. + d" c, [( u- Q, Y
  1014. /************************************************************************/
    " Y1 i1 ^# ?6 d' m; G6 v& l$ o5 N( g: q
  1015. /* PROCEDURE: Verify                                                                                                        */
    ; I. y/ |7 W: m$ {, e
  1016. /*                                                                                                                                                */
    9 w' ]" L/ M. H4 Z: ]) z# F
  1017. /* This procedure checks to see if the correct byte has be read.                */$ Z* c; f7 Q6 m' K
  1018. /*                                                                                                                                                */
    ! }% ]7 ?' A1 g, n1 D) U, s1 i
  1019. /* Input:                                                                                                                                */6 l3 o8 w. x" ]5 ^5 B1 Z
  1020. /*                byte:                byte read                                                                                        */- Z6 f0 r/ |8 j. ^( y
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    - D8 U6 ^/ o8 x9 t
  1022. /*                                                                                                                                                */
    3 b! q0 Q8 K& L* n) ?1 i
  1023. /* Returns:                                                                                                                                */9 H( g' i' `1 ^5 g9 x
  1024. /*                Nothing                                                                                                                        */
    ) l  Q. c6 b; t: r+ S: Z+ U4 E* [
  1025. /************************************************************************/
    ' t8 R, T" `& @5 M5 v6 c
  1026. void Verify(unsigned char byte, unsigned char cor_byte)8 Q( o7 U1 Z% U  w' b
  1027. {1 X& f3 I' f1 F% Y
  1028.         if (byte != cor_byte)4 v$ x2 g. s: r9 a" F0 }
  1029.         {# o+ w) @- r8 g4 G1 Q$ e
  1030.                 while(1)
    " @. f, g6 G, I- Y3 J" R
  1031.                         /* add source code or statement for this file */4 b% Q* T2 a+ k9 V
  1032.                         /* to compile                                  */% w1 [; D8 E, M4 B; Q3 I6 d3 @
  1033.                         /* i.e. option: insert a display to view error on LED? */6 u+ z5 L+ K2 Z9 J" C) }: {' S( z
  1034.                
    9 w$ p- ]. b7 S) u: I6 m  F
  1035.         }
    / ~& f2 r' h/ O  ~
  1036. }$ V( u8 O. ?% l7 y% {. C
  1037. 3 V* O4 w$ [( y3 R
  1038. % l3 D/ v: ~$ Z2 K  }7 Q0 h
  1039. int main(), i/ D; T: P1 C: V1 m, |; F. x
  1040. {. ?; D5 r5 H0 d; b5 E
  1041. 0 v; y- P' K  Z" Y3 F5 h  P
  1042. return 0;
    2 M# T( j6 n0 O+ `6 A/ q
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:% a& Q  y- x) j
   main()# B0 ?8 m& W( k& i: g) H& \1 d
   里面怎么是空的呢?
5 i' H' ?  n; u6 a1 v3 x9 O. e   发一份给我吧
9 x) ?; v2 C/ y; E7 [2 Fmail:luyijun2005@hotmail.com
  a/ Y! l' c% L4 f: t咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。& y' W+ |7 g" E; ^

. v: L" k9 e8 ]* }! i[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。6 W# Z' A8 z- c/ l# s' _
EC的代码在哪跑,你看DS的说明,每个EC都不同的。, a! q0 I8 f' f# v' |
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?" h" h  i2 e  Y8 q5 D# D
上面几个问题是你没看任何东西而白问。' Y3 X  h/ N1 b6 P
  R& V; b4 F) U: M$ L
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。1 i: z" t* `, l. L# x: _. B0 f6 Q
, j9 Q3 _+ K1 p+ W4 B6 r
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!! u5 n& q1 W' l

8 E' Y5 w8 R7 J9 s' {关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”9 G* k7 d( g/ {+ g2 G
# k7 ^  X0 N. V/ G' i: U0 N9 a
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
6 g4 l! G( H! N8 u1 R& ^. k
% ~7 O* M# q- _8 i& G* T不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
; M9 t( f- }/ C" \! W- A似乎要把SPI能support 到最大,这EC chip应该有好卖点
9 u5 J2 I  J$ z9 H2 W% zBIOS功能要不要强大,也就决定了SPI Flach的大小
# X8 w1 J* s, N; Q6 G' C我是这么想的~让OEM去决定要挂多大!" E5 A3 ?5 e& \  E; m& N* m# {1 I
如果我司有BIOS工程师就好了~哈3 h0 q1 A. T) t
WPCE775应该算很新的东西,来看它支持到多大?
2 z4 k/ K' s7 f0 }( j3 K
0 R) u( Y0 Z' a# L另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
. X' m. y; p4 ~& U% Q& w, ^其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
: X+ [1 o& x5 ?4 t9 [7 ^
3 c5 P' c: n3 t- X) h这份driver收下~希望以后有用到; d! |' @0 C$ Q4 ]6 S
谢谢bini大大* A  q8 t' v. |
& i! P2 O* P7 \
很新很新的新手,如有错误请指正 (准备看第二家的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()
  ]) x# Q- O0 d3 s( i2 h{
7 ]1 b' c9 t1 I9 E# \1 k8 ^8 j        unsigned char temp = 0;
- d) G7 g, h; L2 b        CE_Low();
  e6 X2 {+ j" C; s8 H, _0 G    while (temp == 0x00)        /* waste time until not busy */3 l3 e+ {! @# f1 ]2 p; H. a
                temp = SO;2 K2 @. n" a0 w! @9 b! h$ u
        CE_High();6 {: e& E0 }" `
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
" `2 T6 G/ P) o" o{! m6 ], U# d1 `
        
& A5 v- g- k7 V6 [        unsigned char i = 0;" J* t2 O2 ^1 R6 ]% l
        for (i = 0; i < 8; i++)( z8 O  {9 j$ u2 X$ V; S. m9 r6 O
        {3 a) c- _3 s- S. l8 ~
                + K( o' `+ k2 h3 ?# Q: G" a0 U
                if ((out & 0x80) == 0x80)        /* check if MSB is high */& w) j. o) m% s
                        SI = 1;% j. n$ N3 m, @3 |- U9 o, y
                else7 p& b3 M) e4 Q: x. X+ K& z
                        SI = 0;                                /* if not, set to low */: G2 {7 l  H1 v
问              SCK = 1;                                /* toggle clock high */
) v9 B8 a. F( z  G! a# h   题            out = (out << 1);                /* shift 1 place for next bit */; I4 i, e% N( O  q; ~
                SCK = 0;                                /* toggle clock low */2 h# u) O* N0 F; E
        }
: `* h" g" l6 Q9 F}$ m5 ^+ \# d3 C; N; k
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-21 22:28 , Processed in 1.300751 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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