找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55975|回复: 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) x% ]6 b; H2 ^) ^4 a9 p1 G% n
  2. 5 O+ s. A* F4 v: P" d5 S, n; ?
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    $ b1 W5 [; U# [' E: @5 H
  4. * Q2 I4 E: ?# P' g
  5. November 4th, 2005, Rev. 1.02 u/ W5 g5 ~+ E! T
  6. # U: C2 N1 @- h( L( M8 I
  7. ABOUT THE SOFTWARE
    - P  G( }3 C, M! A0 B
  8. This application note provides software driver examples for SST25VF080B,
    0 _$ e; `( w  f# v, h+ |
  9. Serial Flash. Extensive comments are included in each routine to describe : v( H( {' o6 r. G0 d) w
  10. the function of each routine.  The interface coding uses polling method . u( l* Z: v& x! Z
  11. rather than the SPI protocol to interface with these serial devices.  The; N$ V& A0 o6 h/ e, p" \7 W5 B4 y
  12. functions are differentiated below in terms of the communication protocols
    7 w% d) ^9 g" d" Y2 c- x* G
  13. (uses Mode 0) and specific device operation instructions. This code has been * m$ m7 T, {0 q- r0 ]3 {& _
  14. designed to compile using the Keil compiler.
    1 S4 }6 s2 F3 W3 t/ I
  15. & D( X/ v3 U' Z9 b6 K  i

  16. / Q# X# ?& C1 Q1 s% Q3 i
  17. ABOUT THE SST25VF080B; Z$ Z1 J8 {% a* K
  18. + l8 t5 {6 X3 Q4 T5 I& c& D
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    5 `$ a8 {7 M3 P  e, M# y* s; ?
  20. conjunction with this application note for a complete understanding * M) H& Q/ Y+ }. B- d- F
  21. of the device.
    0 Q5 ~( ?" |( \/ J+ j
  22. - f8 o' ?& @( k9 B4 Y& Q

  23. ; n3 t# h# ?! \, ]+ G. W, z
  24. Device Communication Protocol(pinout related) functions:
    7 Z+ y) N( e! K
  25. 8 O8 P) [' k& t5 S( M/ j
  26. Functions                                    Function
    4 _0 T& O1 H" Z* R* I  h1 N3 O- Y
  27. ------------------------------------------------------------------
      a8 R# K, O; C: C; H
  28. init                                        Initializes clock to set up mode 0.
    * H1 Y' n0 y0 v+ A
  29. Send_Byte                                Sends one byte using SI pin to send and ( x: Z( K. u9 X% u& ^: c
  30.                                                 shift out 1-bit per clock rising edge9 `5 N9 B5 ^+ W
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    / j* _% |# Z2 b7 {( A. C, u# _
  32.                                                 in 1-bit per clock falling edge8 X4 ?* D1 ?' L) D1 G
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming$ v- p# h- C9 s8 ~
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    $ D  Y% X( T: v% ~+ L8 Z
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    , I: q- A7 q9 @9 r3 Y+ S
  36. Hold_Low                                Clears Hold pin to make serial flash hold+ a. E; T3 t- c
  37. Unhold                                        Unholds the serial flash
    - w) B3 |* Q1 w. T9 x" S+ c- E6 \
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ! L5 Z9 D; R: [7 K5 z
  39. UnWP                                        Disables write protection pin
    * `7 d8 w$ O/ X2 T

  40. ! O# l0 n1 p! y, D" J; _
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ! d. b- v1 Z  r& l
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your% m1 @+ k5 a$ j8 }  W$ h) s
  43. software which should reflect your hardware interfaced.          
    & f7 Z4 a$ V# Z5 K, z# [

  44. ! |' `" X6 o, {' {. `

  45. ) F! U6 Y5 ~' W5 Q
  46. Device Operation Instruction functions:( B' B6 B4 M: Q+ `# L$ N
  47. 1 A+ k& a0 B2 p9 A- G2 O
  48. Functions                                    Function& i% a0 \* r. h, E0 }0 ]
  49. ------------------------------------------------------------------$ T( m+ W' f8 H' s1 A
  50. Read_Status_Register        Reads the status register of the serial flash
    & q, l  {4 K9 J
  51. EWSR                                        Enables the Write Status Register! V5 o6 R8 q% ~
  52. WRSR                                        Performs a write to the status register1 v$ k3 x3 |- Y: a. A- |
  53. WREN                                        Write enables the serial flash
    * C& H) |4 g8 s1 l! j
  54. WRDI                                        Write disables the serial flash1 `/ U& V' \" ^% v+ y( V
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    4 Q' s( H: f) J# c5 t
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming, _1 \) n! Z7 r
  57. Read_ID                                        Reads the manufacturer ID and device ID* v2 s' C6 Y6 b7 k. n, h% [
  58. Jedec_ID_Read                        Reads the Jedec ID( S, ^  [7 h$ C" l
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    + J, W5 \, f0 }+ d+ N+ g& R8 r
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)0 M5 g5 Q6 G$ ]* ~# ?3 J
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)1 p" S  i- Y) ~* P
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)4 f  [4 _! r4 O$ P1 N
  63. Byte_Program                        Program one byte to the serial flash& u0 y" x" i" ~2 e: R1 m
  64. Auto_Add_IncA                        Initial Auto Address Increment process+ n7 o) X0 C6 X% @) h) I8 ]
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    9 Z5 K" ?0 p0 s; ^
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY/ b. r8 K- K- D" ^8 F7 r+ y3 }
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    " e- r8 ]1 X9 ~3 m7 t9 `) D! K
  68. Chip_Erase                                Erases entire serial flash; F3 u0 ^+ Z! q3 a' L! T
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash0 o0 x8 D: @3 L' Z
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash4 K! p, W# T7 i4 f) ]
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash! j7 J1 [& W( h& N! p
  72. Wait_Busy                                Polls status register until busy bit is low
    # @: H" t( p; @9 T0 j+ M7 Q
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming5 d, \  |) F, N' O1 C. n: ^, l3 s
  74. WREN_Check                                Checks to see if WEL is set
    + D3 V/ t+ n" \8 ~2 e- x: E" u
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    7 l! z0 S( L5 w7 P
  76. 2 V1 b7 J0 A9 M2 N/ ^5 U5 C
  77. # N4 M* M! l4 V% X% y: r: [$ _
  78. 1 n, p" Q$ R! ?7 U
  79.                                                                      " Z5 R5 x7 I5 e% i, c& w
  80. "C" LANGUAGE DRIVERS
    6 Y: B: G1 ~/ Y- i
  81. 6 D+ u* F% k6 L- X1 l
  82. /********************************************************************/
    % g0 G, _, o% |+ y7 r: O# o; E
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    / z: \% x, r0 _7 ]% `. F& F7 @" t' d$ [
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */# B8 t4 _2 i# f5 F9 ~( S1 l# E4 b
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    7 E0 G9 C) b  o1 G
  86. /*                                                                  */
    + U- V7 s4 E5 y6 @0 R
  87. /* Revision 1.0, November 4th, 2005                                                                          */   ' g7 l2 p. L5 d" O$ W
  88. /*                                                                  */
    ) Y7 i" N3 q1 k) g5 B- i! D
  89. /*                                                                                                                                        */& ?9 E4 y& K# C: [$ n# Y3 s! E: {
  90. /********************************************************************/6 Y6 N/ o. t" @. }+ j

  91. 1 _, E& s9 p5 r+ d0 q8 h) [' P
  92. #include <stdio.h>
      n/ X/ H1 J2 i( X% {6 f
  93. #include <stdlib.h>. A; d, [9 @' f
  94. # S& m1 L! e* u  c
  95. /* Function Prototypes */
      I0 {" m' w( ]0 K  m2 g1 |
  96. 9 k* c2 E8 |- k: R
  97. void init();" b' @2 K; R7 c- x
  98. void Send_Byte(unsigned char out);. K3 q1 j6 ~- m* Q7 S, |
  99. unsigned char Get_Byte();1 E  N3 R: L7 f2 e, Y# @; \
  100. void Poll_SO();
    : h" [: i7 l8 |6 ^. ^7 p
  101. void CE_High();
    * }/ ]8 ~! [% g
  102. void CE_Low();  Z0 d- h5 F$ R. a+ N
  103. void Hold_Low();! J5 i& i% Y, k9 {4 R% \
  104. void Unhold();; u0 b& [% [2 q6 b
  105. void WP_Low();' J; O$ G2 S' u3 C7 l
  106. void UnWP();) Z8 H$ x: I5 C$ j
  107. unsigned char Read_Status_Register();
    5 |+ e1 u5 j' K7 }: z
  108. void EWSR();  x5 ?% y) D( |1 K
  109. void WRSR(byte);3 M: X! Z  }% C; ~
  110. void WREN();  s. h( ~: Y* {2 H
  111. void WRDI();& p  K7 x* `9 x2 p4 o6 H+ l
  112. void EBSY();# C; I2 @) ?5 X, i1 ]4 n% X1 Q- [
  113. void DBSY();/ O* e. P# w) o% \* x
  114. unsigned char Read_ID(ID_addr);/ ^: t1 K" q- W) X( Y* E) w
  115. unsigned long Jedec_ID_Read();
    % a$ ?7 l5 \0 O4 n/ C7 ?' x
  116. unsigned char Read(unsigned long Dst);
    ; ^) l" F. R) S8 u4 g
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ' q+ y& w# G3 @5 g9 d3 J( d
  118. unsigned char HighSpeed_Read(unsigned long Dst); 8 }& {% q% P7 R3 v$ T) E
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);; C4 \7 G* t8 M
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    , j/ e8 A: a' C) a1 {: E% K
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    1 z& X; f' e$ W+ f! j/ R3 G; }3 C% e
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    ( A; V# z7 R, @! f( `
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);5 ~) t9 g( L% |& B/ X# W: \$ P
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);  M( l" H* I0 j, ]- {' p) k
  125. void Chip_Erase();( ?1 m; l2 }2 s0 z3 [" Y
  126. void Sector_Erase(unsigned long Dst);
    ; ]2 ]1 y$ @+ h' S2 s  g5 D! m
  127. void Block_Erase_32K(unsigned long Dst);1 O& U/ Q) i2 m1 C# K+ E
  128. void Block_Erase_64K(unsigned long Dst);) @5 C* i2 U) R! U/ i
  129. void Wait_Busy();5 d( _6 s) e! |  E, }' M* R7 `
  130. void Wait_Busy_AAI();
    9 R  y, r! p0 B* l7 m( I, N" ~
  131. void WREN_Check();
    9 ^/ ~' [9 d  t6 y- F
  132. void WREN_AAI_Check();+ V# e5 C( l1 I; o. I3 K# i
  133. ; |! E4 I; [# ~2 x$ M) j
  134. void Verify(unsigned char byte, unsigned char cor_byte);7 a5 S- O3 i3 p4 j3 ~
  135. . P; x3 ^9 m  C
  136. unsigned char idata upper_128[128];                /* global array to store read data */0 z% s: @5 v2 K  x
  137.                                                                                 /* to upper RAM area from 80H - FFH */6 k' g1 L  i( l, h

  138. ! j8 `& q8 @2 }2 q
  139. /************************************************************************/8 j& ]6 L- k! U. X: l! J3 [
  140. /* PROCEDURE: init                                                                                                                */( l- ]2 H! s* r2 R" B
  141. /*                                                                                                                                                */: L' H9 w7 r( k0 _& S6 F' s
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    5 q. T# w. a7 `& t; b
  143. /* setting up mode 0.                                                                                                        */8 y6 K) s/ W1 S+ d# Q6 n, p! B- t
  144. /*                                                                                                                                                */
    5 Q1 W8 X+ E8 [- [' B9 x
  145. /* Input:                                                                                                                                */0 d# {0 u1 c' b
  146. /*                None                                                                                                                        */9 v' m" E# z2 a0 H$ y
  147. /*                                                                                                                                                */9 w* w4 ~0 Z$ M  \! d  D
  148. /* Output:                                                                                                                                */- v; Y$ U* s: P3 d
  149. /*                SCK                                                                                                                                */' F, a! c& g- F8 W2 d5 y
  150. /************************************************************************/
    ) n. p0 m" H  a
  151. void init()
    ) `4 @0 e7 X: U
  152. {
    5 o1 G/ s1 O& Q% T: {) q) l
  153.         SCK = 0;        /* set clock to low initial state */9 l* {6 C; I( S
  154. }# n2 _2 F5 y" K/ |

  155. / l. Y* ^  @! H
  156. /************************************************************************/8 W4 `+ v- p0 u" p/ O) }
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    9 S5 e% ?8 W, ], {7 a
  158. /*                                                                                                                                                */+ U/ n; A7 y7 ^( ^
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */1 K1 ^% f$ O$ q$ g
  160. /* edge on the the SI pin(LSB 1st).                                                                                */. T4 \; k; L) s1 N  U, j
  161. /*                                                                                                                                                */; E( L, P, B1 @2 t' x$ [0 `# ]- k
  162. /* Input:                                                                                                                                */
    * ~8 w; R" r; e5 t
  163. /*                out                                                                                                                                */
    & k& U* W9 ^' e) `  u$ \$ ]
  164. /*                                                                                                                                                */
      e) n8 k: K& ^" V0 p
  165. /* Output:                                                                                                                                */, J) N* o3 {& v/ `
  166. /*                SI                                                                                                                                */
    - n- l; o) L) j  ~' B% i7 i) m
  167. /************************************************************************/" k+ l: }5 m  c  A7 i
  168. void Send_Byte(unsigned char out); w1 |$ Q: R) e6 L& x
  169. {
    : c. O# Q7 w1 P& d9 q
  170.        
    + F+ o' O9 J$ G' ?& c- m
  171.         unsigned char i = 0;! {9 N2 a5 @( |9 Z2 K' Z' s. ~" v
  172.         for (i = 0; i < 8; i++)) n" m; i1 g4 ^
  173.         {4 _6 h4 {4 D0 f' ~# o' j5 b% t+ @. u
  174.                
    + t0 \+ }: G; b0 {0 A# S
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */1 c0 h, @: P2 N: _
  176.                         SI = 1;
    ( ~# W+ {, o4 [# s" m
  177.                 else( H  ?9 |  K: i3 b
  178.                         SI = 0;                                /* if not, set to low */' @/ t, w# P5 W
  179.                 SCK = 1;                                /* toggle clock high */
    4 B" ^  m9 d6 `
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    $ c2 s* o/ i9 o" N" i. A3 s
  181.                 SCK = 0;                                /* toggle clock low */: D/ a. W( Y4 P
  182.         }) `9 R, `+ g+ }% N/ L, k! |
  183. }
    3 T6 Y& b. O9 f6 D

  184. , ^5 W7 Q$ F7 \( y; x  z
  185. /************************************************************************/
    " ]* i3 x, L2 }
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    $ g. P- V3 l8 B. Q
  187. /*                                                                                                                                                */3 P* @: M1 M& [+ N
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */; I, j, }4 H- F4 A- Y8 [1 n
  189. /* edge on the SO pin(LSB 1st).                                                                                        */0 K; D) I& Q3 B* S0 V; z) P
  190. /*                                                                                                                                                */
    $ B2 u/ D$ ^1 e7 G, c
  191. /* Input:                                                                                                                                */
    4 A; a, q! U6 a' C4 O5 t2 {6 S
  192. /*                SO                                                                                                                                */
    ! n9 M1 s% A* ]: z/ D/ D+ l- [
  193. /*                                                                                                                                                */
    - k. I5 y/ C7 u2 D
  194. /* Output:                                                                                                                                */
    5 h. B- S- t% I+ R4 h
  195. /*                None                                                                                                                        */" F- q8 W7 I: V$ ^9 f" b
  196. /************************************************************************/$ w. F1 O3 n, {. l
  197. unsigned char Get_Byte()! o3 T6 S8 J0 p0 K' Q$ b  m. |
  198. {! ?# X7 y( h" _  s* n
  199.         unsigned char i = 0, in = 0, temp = 0;
    " v2 x) m+ ?# Z; _9 T& O# H6 X7 B8 |/ ]9 j
  200.         for (i = 0; i < 8; i++)
    9 h/ l) v1 E& S5 E( W
  201.         {0 b1 P! Z, b. y
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    ! F% T& q& S6 k- [' ~
  203.                 temp = SO;                        /* save input *// k2 Z7 v$ n0 |& W* {3 U' B. ^# u
  204.                 SCK = 1;                        /* toggle clock high */
    % v$ p! v" x' \
  205.                 if (temp == 1)                        /* check to see if bit is high */
    - {' z+ D0 v" @9 _
  206.                         in = in | 0x01;                /* if high, make bit high */4 d' w. ]7 c- }; {
  207. # B% H$ o" l% B6 N, T
  208.                 SCK = 0;                        /* toggle clock low */" n8 T9 P  g+ g5 q% ~  d* x9 i

  209. ( a- X4 P$ G& z$ ]1 p
  210.         }9 J1 p' Q! m) q0 s1 B0 t0 ~1 O
  211.         return in;: v+ G' J$ m1 k0 K9 c
  212. }
    2 b( d$ Y. o, h, [! f6 X5 T+ W
  213. 0 A. L8 l# j: e, W6 |  Y% r: l1 o
  214. /************************************************************************/
    6 ~' ^5 Y( n5 I# S$ x$ E: v
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ) [9 c! t/ o' W/ {3 {# r1 M/ e! P
  216. /*                                                                                                                                                */
    7 T  V3 A' z7 E% e. e) t1 r' \
  217. /* This procedure polls for the SO line during AAI programming                  */, |2 n% T4 T' ^% `1 w: V% y
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/4 D+ U% ~: K! \
  219. /* is completed                                                                                                                        */5 U% M) P/ {, X% ]% N. m
  220. /*                                                                                                                                                */! r1 c: c$ U: A& ?
  221. /* Input:                                                                                                                                */9 O& Q( x4 z. ~
  222. /*                SO                                                                                                                                */- h8 ?3 g8 K) v' Y
  223. /*                                                                                                                                                */
    / e  ?& h5 |* y3 t8 Z
  224. /* Output:                                                                                                                                */7 \2 X, @% D+ F
  225. /*                None                                                                                                                        */
    $ A; G7 D) L- g. F4 P
  226. /************************************************************************/* m6 f8 F8 t1 f, v
  227. void Poll_SO()( T8 x0 r' u- t7 i) ^
  228. {5 F; M. L. r# X1 p6 @  o
  229.         unsigned char temp = 0;  h0 [  C- f$ @0 k* l; I
  230.         CE_Low();
    ) U4 t$ w8 N. B. b  v' L
  231.     while (temp == 0x00)        /* waste time until not busy */
    / y' ~) c1 u2 j* C, G  g
  232.                 temp = SO;3 e0 N7 [/ E- h
  233.         CE_High();1 ?$ M6 d+ H, m8 o% R
  234. }. j, I1 S5 O2 d$ T$ g8 t
  235. 0 h0 E: |0 F1 p" R8 r! D0 W0 e: o
  236. /************************************************************************/. `; Y4 ?; I# O/ v
  237. /* PROCEDURE: CE_High                                                                                                        */9 ~* X& ~) ~4 ^! I' S
  238. /*                                                                                                                                                */9 g' z" D" t) o5 c' e9 v
  239. /* This procedure set CE = High.                                                                                */! |$ J5 D) |$ `* g' A
  240. /*                                                                                                                                                */- q; i# b% Q! c6 B' u: q) p% Y
  241. /* Input:                                                                                                                                */& A  Z3 A  S  c- S3 k
  242. /*                None                                                                                                                        */' A- C! p2 I+ q4 e* K  {
  243. /*                                                                                                                                                */
    ' e8 g' a" O. k3 Z* b$ D* T. n$ i
  244. /* Output:                                                                                                                                */* k" r0 i( g, N
  245. /*                CE                                                                                                                                */
    9 j- _4 v; O/ N0 l9 I+ U
  246. /*                                                                                                                                                */" m: L3 g: U: _0 C2 J/ L3 x
  247. /************************************************************************/
    4 e, s' y3 T. n
  248. void CE_High() 8 S% f. K! @! p) U% l: v: O
  249. {- K) z' t# t( e, A) q# D  l
  250.         CE = 1;                                /* set CE high */9 t% C5 h1 {' s- i
  251. }/ E  t0 C4 P) D/ P9 @- O
  252. 0 w3 r5 j0 }/ r( ]
  253. /************************************************************************/
    : s2 D; n/ ~# ]* D! O" U% t
  254. /* PROCEDURE: CE_Low                                                                                                        */
    8 A: n; }1 r% c. M* E& G) ]# h. A1 ]
  255. /*                                                                                                                                                */9 M; Z' D$ p4 k5 N- i* e' v! m
  256. /* This procedure drives the CE of the device to low.                                          */- @! o: S2 s  m5 v) O" T
  257. /*                                                                                                                                                */+ v1 A$ I  d7 z! ?5 N1 w! D
  258. /* Input:                                                                                                                                */
    2 x8 x5 V" m9 |6 L& S
  259. /*                None                                                                                                                        */+ b. q0 ^8 f! Z5 g
  260. /*                                                                                                                                                */8 |9 M( u, D4 J5 A7 v% ]; o8 y9 k
  261. /* Output:                                                                                                                                */0 F4 ]7 u. U( Y- c, H5 h2 d: q
  262. /*                CE                                                                                                                                */+ z( ?0 J3 h4 ?, o3 a) e- k( _
  263. /*                                                                                                                                                */
    8 {3 m+ T3 k! G  {' W
  264. /************************************************************************/8 w/ Q( Q- w6 e. K( W  G
  265. void CE_Low() 7 I3 [0 v8 _5 C
  266. {       
    , Q" x" M2 k& Q5 [" Y- s6 c
  267.         CE = 0;                                /* clear CE low */$ B+ ?7 _+ C) S4 `  b
  268. }3 z* D# k1 _$ E' I2 g( p0 m* i

  269. & c+ e. K$ x. j% k8 G3 S
  270. /************************************************************************/& c. y% ]+ d+ a
  271. /* PROCEDURE: Hold()                                                                                                        */
    . i9 I; l7 M: q
  272. /*                                                                                                                                                */
    : _3 r! a5 A8 Q
  273. /* This procedure clears the Hold pin to low.                                                        */8 F0 O. D/ ?( o+ O0 g
  274. /*                                                                                                                                                */- Y* @# [7 K! p9 X' W
  275. /* Input:                                                                                                                                */, `, _4 T5 ^8 L1 s4 I- s$ q
  276. /*                None                                                                                                                        */
    ' @; u& R, e7 X6 V* c+ _
  277. /*                                                                                                                                                */* V1 z- N; `- K4 c# s  g
  278. /* Output:                                                                                                                                */) X  U$ c0 z! z  `! m0 t+ c. a
  279. /*                Hold                                                                                                                        */4 [4 v, v- z9 V; o' k
  280. /************************************************************************/
    4 w5 ?6 n' A2 {9 }# R
  281. void Hold_Low()
    " P4 _7 _1 a8 y# t/ g2 d6 g- B" d4 o
  282. {. f" q. U! n  m4 ^2 A- D: @
  283.         Hold = 0;                        /* clear Hold pin */$ Q! T! S* @5 M. T9 z- _
  284. }
    ' O! m% J+ L1 b+ d: R
  285. 0 U8 U  ?" M4 _7 R
  286. /************************************************************************/
    3 h; {& g7 W4 R5 m! ~2 Q7 m9 R
  287. /* PROCEDURE: Unhold()                                                                                                        */3 [: S7 W; v! h  u/ V, ^
  288. /*                                                                                                                                                */; U  a6 K5 G, \! w+ l+ n
  289. /* This procedure sets the Hold pin to high.                                                        */! x+ h8 e2 ]: `6 m/ H
  290. /*                                                                                                                                                */
    2 Z4 {3 v; s1 e! L4 b4 U
  291. /* Input:                                                                                                                                */. A9 H0 U6 y7 Q, t; K" `. I. n# o7 }
  292. /*                None                                                                                                                        */
    2 u) ?+ i( W% q! g% o* _) X& Z
  293. /*                                                                                                                                                */
    $ E4 m) O6 Q3 M, i
  294. /* Output:                                                                                                                                *// {3 T5 y& O: ?: j' P) V
  295. /*                Hold                                                                                                                        */
    ; \# C5 a1 i6 n+ R' G& t
  296. /************************************************************************/
    , y. L* o" c. x, j9 {6 E
  297. void Unhold()
    + [" h, U. t0 M( Z' b1 `. ?
  298. {
    , V' w. k  Q( A
  299.         Hold = 1;                        /* set Hold pin */
      p) y* V9 c+ z/ ?- U. e
  300. }
    0 b/ B* X- ?' c+ ^. }
  301. ; x- {7 S; O: ?: M( I" C/ r+ g
  302. /************************************************************************/* G* F9 l7 v0 `! Q  Q
  303. /* PROCEDURE: WP()                                                                                                                */
    # f) N4 Q5 y) V4 m) C; F( ]
  304. /*                                                                                                                                                */
    2 o/ Z" ~5 R* G; ^5 A
  305. /* This procedure clears the WP pin to low.                                                                */
    $ d7 `& s7 g$ O0 A, G' z
  306. /*                                                                                                                                                */! ~2 v3 Y: u: m3 ?, t+ f2 p
  307. /* Input:                                                                                                                                */4 `. P  N0 D/ B( a3 }/ U7 s
  308. /*                None                                                                                                                        */$ i' M! m7 d8 F* |3 [2 e
  309. /*                                                                                                                                                */
    - n2 g0 m" U! \' j' t0 _, l
  310. /* Output:                                                                                                                                */
    3 r* v1 g' I2 B+ f3 O
  311. /*                WP                                                                                                                                */
    $ t- n/ i  |! j0 ~  E4 c; D
  312. /************************************************************************/
    6 a+ V1 y) A9 j
  313. void WP_Low()
    $ q7 X; l3 i3 w$ `& Z9 n
  314. {: u/ e+ q( @% o! L6 b4 V
  315.         WP = 0;                                /* clear WP pin */
    $ _& Q/ @$ ]* e1 x
  316. }6 |( J2 u1 m3 J, k! H1 K( o
  317. 3 l7 ~! {0 O9 {5 I
  318. /************************************************************************/1 \' h% ?! w' j2 g0 a6 v) P, C" }
  319. /* PROCEDURE: UnWP()                                                                                                        */
    . k7 B8 c, i3 W' O% H$ N& k
  320. /*                                                                                                                                                */- w7 T& y9 ~! {( h* y
  321. /* This procedure sets the WP pin to high.                                                                */& G! E3 u; o- ^% O6 u. x6 Q/ x
  322. /*                                                                                                                                                */. B$ l: [' F' W1 p6 e
  323. /* Input:                                                                                                                                */: c: C6 g2 D; y* O
  324. /*                None                                                                                                                        */
    1 w7 n# i) G9 T4 |  W9 A$ `1 @
  325. /*                                                                                                                                                */
    2 @8 v' c3 |$ p8 z
  326. /* Output:                                                                                                                                */
    - G, p. e+ w  U) F2 U  }+ ~4 ^; \! o
  327. /*                WP                                                                                                                                */
    ; d" {/ T# G* D0 ^% k/ S' [
  328. /************************************************************************/
    ' B  G$ q; S4 ~" A& S$ X
  329. void UnWP()
    * F5 ~# W: c: U% n
  330. {
    3 h0 Q) X7 O5 h, y2 ~6 L# W' u  D
  331.         WP = 1;                                /* set WP pin */2 a- f! ^) H, v2 \( B
  332. }2 x3 |% @2 l: {0 D* v% I

  333. 4 W; s! ]* s/ A5 P( d
  334. /************************************************************************/9 F' c: p7 H, }2 z% t
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ! f& e7 E, t; ~+ M7 ]
  336. /*                                                                                                                                                */
    ; [. s/ G" U9 \; z1 `, r8 B
  337. /* This procedure read the status register and returns the byte.                *// z. \0 k2 i. X2 K! V" C7 u
  338. /*                                                                                                                                                */
    - A9 X& M4 b/ |/ r6 t* i$ L
  339. /* Input:                                                                                                                                */  w: V" K2 G" e  @- W, p
  340. /*                None                                                                                                                        */
    7 x/ i) Z( \; {2 |6 [
  341. /*                                                                                                                                                */3 t+ c7 ]7 s% o) q9 J# T- D
  342. /* Returns:                                                                                                                                */) I% N. O: B, L  p3 f
  343. /*                byte                                                                                                                        *// f: s" O2 y2 p( j/ {4 u
  344. /************************************************************************/7 x7 r/ f  k3 g7 ^- k- P
  345. unsigned char Read_Status_Register()
    6 u+ V. @1 _' c2 |# P: ~' K
  346. {& ?7 p% Z3 Y& Y6 s  U; @6 }
  347.         unsigned char byte = 0;
    8 C  m% h* Z! Y& }9 y6 ]
  348.         CE_Low();                                /* enable device */3 X' I/ Q# r: l) w, u. a7 Q1 k
  349.         Send_Byte(0x05);                /* send RDSR command */
    " E. z- b- j: Y! I
  350.         byte = Get_Byte();                /* receive byte */
    " r6 W5 o) k( A2 r7 ^7 X( H
  351.         CE_High();                                /* disable device */
    - q+ M$ a* x. Q8 i6 l- S
  352.         return byte;+ x3 Q+ h! f3 x5 {* r
  353. }4 B) P5 T6 t* A+ f4 m
  354. 9 D. b" [* [& c9 i6 B9 [
  355. /************************************************************************/" R5 Y1 I# Q* w3 y: n/ p
  356. /* PROCEDURE: EWSR                                                                                                                */
    4 w2 M: S* k% {; C4 S
  357. /*                                                                                                                                                */0 ~$ v2 y0 G1 @! B1 N
  358. /* This procedure Enables Write Status Register.                                                  */
    % k% S9 c) e- G8 ?
  359. /*                                                                                                                                                */
    % G, u1 l3 k! D9 s; k- P" K9 U- Q* k1 D
  360. /* Input:                                                                                                                                */" @$ T9 k# Q6 v* a/ o3 u2 b& _
  361. /*                None                                                                                                                        */$ ^4 n& f3 h# m( S) Y9 W8 |" `
  362. /*                                                                                                                                                */, r# y1 `5 }7 G7 ~1 @8 A- E& S
  363. /* Returns:                                                                                                                                */
    2 E1 I+ P  G. b7 z; J
  364. /*                Nothing                                                                                                                        */; i2 Q: o5 V8 g) p1 b
  365. /************************************************************************// l* d% H% @' o
  366. void EWSR()2 `" [2 W" H$ W$ E& F# H
  367. {" _* c6 X; l6 Q5 d. V7 c/ K, v
  368.         CE_Low();                                /* enable device */% a, h% f4 A5 ]) H
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    0 F5 P: j1 L9 _+ I$ ?- z' l$ Q; O
  370.         CE_High();                                /* disable device */! s& J" ^; L; R. d! \( O; R3 a" n! k, K
  371. }4 t! H7 X. X4 \
  372. 6 X( ^  ?: z9 Y3 ?5 E; ]
  373. /************************************************************************/
    + E+ L  _& j0 ]
  374. /* PROCEDURE: WRSR                                                                                                                */
    / Q3 y' |" l" O9 d1 F/ @) @
  375. /*                                                                                                                                                */& e! n7 }9 F/ n
  376. /* This procedure writes a byte to the Status Register.                                        */
    ' S# i( ~6 n( Q8 _4 R1 `. [5 h7 S
  377. /*                                                                                                                                                */4 {0 G4 s' U/ ]) ]  T* O
  378. /* Input:                                                                                                                                */8 V2 M" n- X/ I
  379. /*                byte                                                                                                                        */7 |& s( l% w% K. v- z+ i
  380. /*                                                                                                                                                */9 f) P) {, i8 c( k4 K7 I
  381. /* Returns:                                                                                                                                */7 m8 N9 t: Z" t; T8 K4 E
  382. /*                Nothing                                                                                                                        */6 s3 i% q/ n; B, K, Z# T
  383. /************************************************************************/2 h1 e& m# g5 |
  384. void WRSR(byte)
    2 Z0 b" N- e, m/ X* b3 D+ k3 g
  385. {- `, Y/ w" {" p! d+ p9 V, V: V- k
  386.         CE_Low();                                /* enable device */
    9 X5 I2 b: o4 Y1 E0 g8 y5 H
  387.         Send_Byte(0x01);                /* select write to status register */) m! ^. Z" F7 n
  388.         Send_Byte(byte);                /* data that will change the status of BPx
      _* }/ g9 X' X. Z
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */5 {; _) d: Z( \6 ]: |, Y3 f
  390.         CE_High();                                /* disable the device */6 Q, V6 ~+ p7 v
  391. }$ l* X; }4 ?. @! a5 k9 k2 K! m
  392. - G1 g1 T$ S  z) R! p" h/ ]  c
  393. /************************************************************************/1 L3 H: s; E% |
  394. /* PROCEDURE: WREN                                                                                                                */
    / L+ `6 X# ]( t" `# Y; H4 d4 o
  395. /*                                                                                                                                                */
    ' \, g- W0 g* l' q. v! b
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */0 M0 N3 G  L/ p7 o
  397. /* to Enables Write Status Register.                                                                        */; x( J2 ?. G* m, k
  398. /*                                                                                                                                                */
    9 C' P2 w# g% s% w0 m" i4 Z
  399. /* Input:                                                                                                                                */5 s7 c8 U- d9 {4 B8 z: {* }* ]: Z
  400. /*                None                                                                                                                        */" x# I" ?3 u2 c9 ?9 y
  401. /*                                                                                                                                                */
    - D  m' k2 H* ?! b
  402. /* Returns:                                                                                                                                */, T. ?- _7 D" e8 y. i! o$ j
  403. /*                Nothing                                                                                                                        */
    0 X* X# U. h" _+ ~; a% k
  404. /************************************************************************/# }5 h: X% K8 M4 C
  405. void WREN()
    ' `. l7 Z- A$ R' o  r2 v9 j
  406. {
    4 [7 x! R7 q' X6 ?3 Z9 c
  407.         CE_Low();                                /* enable device */$ F6 U% q+ x' F. z
  408.         Send_Byte(0x06);                /* send WREN command */
    8 N0 f7 N; N7 J& \& j0 x
  409.         CE_High();                                /* disable device */
      Q, @+ F% M" k: W
  410. }. Y5 C3 _. |9 u
  411. 0 P- v7 n7 c# t
  412. /************************************************************************/4 c+ a* |7 z6 W8 ~8 _3 i$ l- v
  413. /* PROCEDURE: WRDI                                                                                                                */$ O" l! a# Y: v7 M" @
  414. /*                                                                                                                                                */
    ( ~& j1 s0 g: Y  S* M. ~7 y
  415. /* This procedure disables the Write Enable Latch.                                                */
    ; H! ?4 z  g0 F8 F& y$ ^0 {
  416. /*                                                                                                                                                */7 U' A$ U, u' z8 v& e
  417. /* Input:                                                                                                                                */2 D7 G& m7 T$ f: ~! T* J
  418. /*                None                                                                                                                        */
    / U3 m+ C9 s" B$ K) s; @
  419. /*                                                                                                                                                */; f: g. T. ^6 Y0 e6 A8 ?  O) N$ i
  420. /* Returns:                                                                                                                                */
    : E3 ~2 S. g6 {; z# A- d
  421. /*                Nothing                                                                                                                        */
    6 z8 {/ i4 V. Q
  422. /************************************************************************/
    , d" {6 k. N3 L8 z' v
  423. void WRDI()8 h2 a: Y& [+ ^
  424. {
    - b* s" Z, i" {! W
  425.         CE_Low();                                /* enable device */$ J' O7 {  ~( K
  426.         Send_Byte(0x04);                /* send WRDI command */! `) [$ D- Q; s8 l' r
  427.         CE_High();                                /* disable device */
    9 e& N# ^3 Y" h* n  ~# d, d
  428. }
    $ e- N6 J; j$ v1 K5 m, a

  429. 9 L% W; S0 {8 h8 h( _$ I
  430. /************************************************************************/
    ; u( e: W. ~) W( v6 v3 r) w3 p
  431. /* PROCEDURE: EBSY                                                                                                                */
    : g! @3 z: R/ U
  432. /*                                                                                                                                                */' e2 n+ k7 U7 S$ X: s9 K. H
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    , c; p1 M$ R9 `5 z$ f7 s, u. p
  434. /* programming.                                                                                                                        */5 k; {" ?' k7 x& X; d! B& f0 H
  435. /*                                                                                                                                                */( v" r6 X: p+ k& w) z0 @
  436. /* Input:                                                                                                                                */
    ' [8 @: c5 `# U- C
  437. /*                None                                                                                                                        */
    # H. P! K6 a# p$ @- {
  438. /*                                                                                                                                                */. h0 C( Z. T" i+ b1 u
  439. /* Returns:                                                                                                                                */+ F* @8 a8 b. h! T
  440. /*                Nothing                                                                                                                        */- [4 k- J0 n. U" J  ~9 D2 f# d
  441. /************************************************************************/3 a- o' x& a( M3 l& H
  442. void EBSY()' \& Q2 J- w9 u6 ]& b0 r: F! u
  443. {; m! Q, w! \) R, z" `% K& B& y4 i2 U
  444.         CE_Low();                                /* enable device */. @# S0 b# t( {! z8 E2 ~: S. }" Z
  445.         Send_Byte(0x70);                /* send EBSY command */( s5 e0 Y. F4 Y
  446.         CE_High();                                /* disable device */
    % \0 W& U$ N, k) w
  447. }  o- }8 |/ r2 e1 J: I

  448. ( f9 h/ h- l6 {2 v# i& H
  449. /************************************************************************/8 k/ T2 S1 n  n# l
  450. /* PROCEDURE: DBSY                                                                                                                */" t# u* F' `+ ~
  451. /*                                                                                                                                                */& t! q+ \& P, X) E3 i
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */3 X& @9 t. k; X1 S* w+ E% W; k: _
  453. /* programming.                                                                                                                        */) w. M8 @3 \4 Z: ?1 u1 q
  454. /*                                                                                                                                                */+ G* s0 C( {2 e- d9 U3 P, _
  455. /* Input:                                                                                                                                */
    ' M$ P. V( L: S3 L7 m  d
  456. /*                None                                                                                                                        *// k" P: a! R4 B, ]! E. |+ I" d+ }
  457. /*                                                                                                                                                */
    % [- T6 C- Y: x0 @
  458. /* Returns:                                                                                                                                */
    & e" Q  C0 @& V% u2 \
  459. /*                Nothing                                                                                                                        */
    7 k( p; z; s( v
  460. /************************************************************************/
    / @, I- O% Q6 ?# p
  461. void DBSY()* _" ]( I! y  {- K6 K3 C  e
  462. {! S# k2 _3 K9 M- z* q  m# t
  463.         CE_Low();                                /* enable device */" P* M9 W& S$ B1 g* a
  464.         Send_Byte(0x80);                /* send DBSY command */4 T% U5 S0 P- Q2 l) n3 `; j9 O& \% W% H  V
  465.         CE_High();                                /* disable device */2 K+ |, k: A  i# l! i* p
  466. }
    6 l6 |) O6 }1 C) r

  467. ) r# R+ t5 |' H) W1 L- N% g0 t- \
  468. /************************************************************************/$ j9 Q' P2 V$ F
  469. /* PROCEDURE: Read_ID                                                                                                        */
    0 w) b" S. l- J8 \* ]- _' z
  470. /*                                                                                                                                                */& R0 Z- E: [  @" y0 U' R
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */3 j6 A. U5 @. l$ O2 w
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    & U6 G" \$ ^& i  W- i
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    % |& C! V2 T: v+ E) d$ Q+ M3 V
  474. /* whether the device outputs manufacturer's ID first, or device ID         *// C7 R1 L/ {& ^1 t  a
  475. /* first.  Please see the product datasheet for details.  Returns ID in */8 h3 w$ s; G$ b8 a7 A+ a& ~
  476. /* variable byte.                                                                                                                */
    $ R9 ?$ w  Q* `- C8 h. Q3 m- |- f
  477. /*                                                                                                                                                */" h; N7 n/ R( b( x
  478. /* Input:                                                                                                                                */
    9 Q) P9 S$ ^- L, l/ |6 W* J- h% R
  479. /*                ID_addr                                                                                                                        */
    1 C: d6 s5 z; _* ]
  480. /*                                                                                                                                                */
    & K1 J! J% T) J* v' F
  481. /* Returns:                                                                                                                                */( S. k2 k' w0 n/ m+ T
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    , ^6 H/ D! q& X" h# x" W
  483. /*                                                                                                                                                */: c# R4 ~. d  S* `+ r
  484. /************************************************************************/
    , M+ [3 `5 P0 ?' E  J: x7 _, \
  485. unsigned char Read_ID(ID_addr)3 x$ ~4 q$ S8 m5 K7 z+ c
  486. {
    ' O/ t1 \% m, N/ ]9 y
  487.         unsigned char byte;$ \: t" T/ l" Z' h8 \0 Q: q0 B
  488.         CE_Low();                                /* enable device */
    6 m6 U: P  I- G2 J. q
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */+ i; F* B$ t# ]& `
  490.     Send_Byte(0x00);                /* send address */! j3 F( D3 F6 ]/ b9 `9 V# }5 N
  491.         Send_Byte(0x00);                /* send address */
    9 C0 l, T; x; }' p
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */; `" {5 h) H# ]+ p
  493.         byte = Get_Byte();                /* receive byte */
    7 \$ @/ t+ T0 f$ u$ F
  494.         CE_High();                                /* disable device */& W' }5 R& y- w4 s$ I0 s- p1 [
  495.         return byte;1 ^  s# T9 c% Y/ m% s  C4 b' q$ u5 V
  496. }
    ' K6 ?% z( r( w9 U+ L" A# b; o

  497. 0 f. Q4 C6 T/ @0 r+ \  Q6 x
  498. /************************************************************************/
    - b/ h3 r! C* k7 N( L) T
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    3 b$ n  @! z* q5 v6 V( Q
  500. /*                                                                                                                                                */: a) \0 }: A" g0 M
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    & x7 @# e1 ?9 W
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    3 |8 k3 c% J# C8 }
  503. /* Please see the product datasheet for details.                                                  */
    , _) \3 b: {( B6 d4 h  w$ v1 p( t
  504. /*                                                                                                                                                */
    * A2 X) y: G) |1 J& u. A
  505. /* Input:                                                                                                                                */
    $ B* T2 ^( F& _7 a# D* s+ b2 |' _  q
  506. /*                None                                                                                                                        */
    8 M# K4 {9 X$ O6 \
  507. /*                                                                                                                                                */: {) S9 e5 @8 U6 p9 E+ r; x
  508. /* Returns:                                                                                                                                */
    2 G& X% o8 z/ U/ O* t1 k  O
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */0 M, B# A* ^* k$ v9 y+ s
  510. /*                 and Device ID (8Eh)                                                                                        */
    8 e  R6 ^7 t* H* v
  511. /*                                                                                                                                                */; y0 ^! r2 Q+ z: P% [! i
  512. /************************************************************************/
    3 J' a1 M7 h6 U) S5 `
  513. unsigned long Jedec_ID_Read()
    5 n+ f1 I: x1 ^
  514. {% R1 a/ I9 c* c$ A/ V$ A0 L
  515.         unsigned long temp;
    ' I+ a2 |: v) o! t# }
  516.        
    ( c/ u) x5 `6 S) ~; W$ r
  517.         temp = 0;8 A6 x5 O, S& d% {: _% n- h

  518. " [9 U1 `3 K% B- c# p
  519.         CE_Low();                                        /* enable device */
    ) \# r& i' ~' G' I  d0 y* ]: j
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */, F4 x' [: L7 `+ W2 I
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    " o) s& m3 z- `3 I
  522.         temp = (temp | Get_Byte()) << 8;       
    ( F* G; g6 j' V: P
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */* V# x1 Q% D* x1 R  C& _' o5 A4 l
  524.         CE_High();                                                        /* disable device */- d) t/ J! E( M) H3 r5 h$ \
  525. * K- v! S) B; U# Y  j1 k+ t
  526.         return temp;) b3 p2 B' Z# \; }5 S# Y
  527. }' \8 ~& [% r, T; a
  528. - _& H2 K5 ?  i- I
  529. /************************************************************************/
    0 s6 f; g$ E8 B2 S7 L# I$ {8 s" }
  530. /* PROCEDURE:        Read                                                                                                        */
    1 k  {  p8 X- j7 P7 V! [# {
  531. /*                                                                                                                                                */                ( [7 W2 D, `7 f! g
  532. /* This procedure reads one address of the device.  It will return the         */0 m8 Y. f3 h2 G' z) Z7 k/ t( b3 q
  533. /* byte read in variable byte.                                                                                        */
    " f; ?! Z" E$ Q; c$ t
  534. /*                                                                                                                                                */$ y- t  M4 l" I9 C& {. d( j' v
  535. /*                                                                                                                                                */
    . O, d( h7 Y: t7 j6 j0 F
  536. /*                                                                                                                                                */
    ) T. ]6 e) K+ T8 R$ I
  537. /* Input:                                                                                                                                */0 D. s0 U; O- p/ H0 @, t6 ~
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */# H! n/ Y* i! o+ s2 r
  539. /*                                                                                                                                      */1 @  r) i8 V5 u& Z5 v! c/ v6 E. ?
  540. /*                                                                                                                                                */& A% B2 l- C% Q! V  s
  541. /* Returns:                                                                                                                                */
    ) ~9 ?+ O0 M. U' q0 Z
  542. /*                byte                                                                                                                        */
    % b8 ]1 S- r; [
  543. /*                                                                                                                                                */+ R( ~: T3 F8 s( V6 U
  544. /************************************************************************/5 \* d, `0 c( ~
  545. unsigned char Read(unsigned long Dst)
    , K4 n/ H! }7 y' a
  546. {( y1 ~& g# X: ?5 o- y! E, ^. i& {
  547.         unsigned char byte = 0;       
    8 m# K0 w) |! L, N) l& L

  548. 8 Q9 y1 `: n& ^/ b, M: \/ H; ?; _
  549.         CE_Low();                                /* enable device */3 {  u8 r: ]+ a6 K6 A
  550.         Send_Byte(0x03);                 /* read command */+ @. n- n' ~4 q
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    * k- f: ?. Y4 y* i0 w$ ]
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # ?8 x! ?+ j3 O
  553.         Send_Byte(Dst & 0xFF);* G' |! q# m3 c: R' x2 r
  554.         byte = Get_Byte();0 t; C" C6 _* @4 @% q% k
  555.         CE_High();                                /* disable device */
      _" c+ ]  [8 a! p8 b/ Z( u
  556.         return byte;                        /* return one byte read */
    5 Z. k+ ~9 b8 O. Q6 g) J
  557. }
    0 a9 G" H! z  M
  558. % N$ v; L- }; j  t: v- N9 N
  559. /************************************************************************/
    ( w: H% B3 Z$ _
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    . Z* ~' e7 a( J) B& x
  561. /*                                                                                                                                                */               
    5 I. C/ J) i: w$ C
  562. /* This procedure reads multiple addresses of the device and stores                */
    5 j' f+ M( j7 J6 n
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    % X' w. j/ x; H) i8 s# {
  564. /*                                                                                                                                                */
    " F0 \- q2 z: P- P* z, w# p
  565. /* Input:                                                                                                                                */6 k5 `' R8 k2 s
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + `) |* E. z8 N$ P; W6 T; _
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        *// G# v% i2 Y; \' V
  568. /*                                                                                                                                                */
    7 [0 A: {, f1 ]1 [9 J  H, J: d, j8 }
  569. /* Returns:                                                                                                                                */
    9 p9 a$ ~0 U$ M2 S% w! g
  570. /*                Nothing                                                                                                                        */) g$ d5 M4 N% r' [+ H. B0 I
  571. /*                                                                                                                                                */3 e2 _( N' P: e' F: o6 Q
  572. /************************************************************************/
    : }% @  \' m& V5 X% A& R% I- z
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes); @+ n( B0 T$ l! a7 G+ W
  574. {
    . ^, f3 |, S/ C# O6 Q9 e" c- e
  575.         unsigned long i = 0;+ |( q" D7 y3 y: @- O
  576.         CE_Low();                                        /* enable device */) F0 d5 @) y' v* h. e, m
  577.         Send_Byte(0x03);                         /* read command */
    * E* n' h4 ~: \8 U5 H& p# Z& i7 e
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # z; \' H2 i3 P& y" A4 q
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));& Z2 F6 P8 w3 c' O: s& `' r
  580.         Send_Byte(Dst & 0xFF);2 X% f8 Z+ Y4 H
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    1 T; I( L  q" I4 v" i. v
  582.         {& h4 c# x/ y5 J
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */; c: E1 w9 {* x- Z# H0 e. G1 v: F
  584.         }7 z+ S5 L2 Z) Q# N$ w- L
  585.         CE_High();                                        /* disable device */
    ) ^% ^/ z$ a: i; d* Z' _( X
  586. ( o# s1 c% v) n  l3 s+ c
  587. }! ^1 \4 f- Q* n4 U8 g0 f& Y- A

  588. 8 }2 D6 d9 C6 j* c; I+ W
  589. /************************************************************************/) K" h  Q' n$ c# z7 g2 }  `$ p
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    2 S: f2 T8 b* m9 `5 {: W9 P
  591. /*                                                                                                                                                */               
    . s5 Q+ Y2 A9 f4 `
  592. /* This procedure reads one address of the device.  It will return the         */( N5 W, @, _! m. T
  593. /* byte read in variable byte.                                                                                        */
      j9 M( R  [" q# ?$ T
  594. /*                                                                                                                                                */3 d7 n+ v  O" w. p5 V# e
  595. /*                                                                                                                                                */9 z# Y# ~4 |. d1 Y3 C
  596. /*                                                                                                                                                */
    : T- q  W  r# h$ ?  W- v
  597. /* Input:                                                                                                                                */
    ' n2 q5 s4 G- y; {- m; s  K; E+ b
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% f* ^8 w) J' k8 a2 D0 c
  599. /*                                                                                                                                      */& \/ X7 ]3 c. M
  600. /*                                                                                                                                                */
    ' f0 q, _1 F# j$ H, k- V
  601. /* Returns:                                                                                                                                */1 v- n+ v' d( i7 w( s
  602. /*                byte                                                                                                                        */7 c, q4 G$ O- \) @( S3 e( t
  603. /*                                                                                                                                                */
    ; d: P; k" |! H3 D- d, i% f
  604. /************************************************************************/( q7 H; o  K+ W4 C' u( j5 R, F
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    . ]. `! l: H; u! Q( f( c9 i( l# z
  606. {
    0 `4 x+ m$ H1 {0 V
  607.         unsigned char byte = 0;        / |3 }# B+ o& s( n8 e

  608. 5 g1 h2 h; W4 {6 \) x& f; n; u$ V
  609.         CE_Low();                                /* enable device */
    / Y: ]9 R' |8 Z+ e9 H8 A1 C
  610.         Send_Byte(0x0B);                 /* read command */
    " }9 Z# n; G% W/ r; M  n% F; X
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */+ U1 b& m" L4 l, L. T8 m9 @# B! V
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - b5 }' X. T0 n7 Q
  613.         Send_Byte(Dst & 0xFF);* x3 Q, w: q7 B% y
  614.         Send_Byte(0xFF);                /*dummy byte*/
    0 b  Z3 L1 t4 j% B# _
  615.         byte = Get_Byte();
    4 ]; U6 S9 w! f; t8 o' t
  616.         CE_High();                                /* disable device */
    ) B; e+ \, c6 C" L2 w/ Y) b
  617.         return byte;                        /* return one byte read */7 p; T1 D/ |5 x
  618. }
    4 B4 Y3 l# |8 l! T; b
  619. 5 [, y& _* M& _2 [# t. C5 O0 v; L: }% o
  620. /************************************************************************/
    9 g5 Y! A" t( m  u; N' R; N/ x) K
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */, U; [0 N% |4 c+ j
  622. /*                                                                                                                                                */               
    0 m: M# J7 u( R5 Z8 X, y
  623. /* This procedure reads multiple addresses of the device and stores                */
    * L4 z" q" S8 J- F# s( F2 S
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    2 X6 B4 m/ t/ L* x& ^' h; w2 \# w% I
  625. /*                                                                                                                                                */* R" y: `2 k0 r( p! o2 ?5 [' ^- q
  626. /* Input:                                                                                                                                */2 ]  h* X6 T) ?2 h9 Z
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */5 R- S3 R, h& \3 b
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ; g: F# J. r4 G; N9 n5 b; J; q+ ]
  629. /*                                                                                                                                                */( W" K# Q9 q& d* p$ S6 q, k7 S/ s
  630. /* Returns:                                                                                                                                */, p4 }8 ^9 D' @$ L
  631. /*                Nothing                                                                                                                        */
    $ z0 |* W8 s8 Z- C$ @$ i# D9 {: m
  632. /*                                                                                                                                                */
    7 s* k7 P9 b* w, n" F/ @, T
  633. /************************************************************************/
    " Y: d3 n/ T! G% i
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)2 O# `- I) t/ m9 ^/ _; V1 t8 i3 @
  635. {
    2 b& b. c; o- K
  636.         unsigned long i = 0;# {, u( c! @; g8 @, }  v
  637.         CE_Low();                                        /* enable device */' d5 f+ y& H7 {1 f6 s
  638.         Send_Byte(0x0B);                         /* read command */4 G- c- q" p9 k1 B# P# l9 C
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    9 M8 v' E- N5 _% f/ [# f# ]* p
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));7 ^; Y4 |- _) Y5 M# x
  641.         Send_Byte(Dst & 0xFF);
    ' X! E+ f" r* A9 A9 L
  642.         Send_Byte(0xFF);                        /*dummy byte*/) G& E( J: e2 N/ ^: N8 R, A
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ' e- p/ }0 O2 D8 `
  644.         {8 `. w9 c: r3 M/ Z/ S' Z
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */2 g  b- o2 s2 q4 f& q2 V, T9 M5 l
  646.         }
    + N- p- W5 Z2 M5 r" ~# w4 n
  647.         CE_High();                                /* disable device *// {& I8 m0 T7 @# \2 j, x
  648. }& N0 k- @4 V" e* o, A6 e' `# J
  649. + d1 e: h1 n5 v2 D4 q
  650. /************************************************************************/
    * g. u( p5 U# b7 g+ T! R4 R" |
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    " o) i8 w8 B% J( v. [3 g4 U" X, j, @
  652. /*                                                                                                                                                */; @0 d7 c2 @+ B: I$ V
  653. /* This procedure programs one address of the device.                                        */7 `& M$ a9 }$ l6 Z; _1 U$ {
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 N# ~4 q$ i# C7 h- _. \
  655. /* block protected.                                                                                                                */
    ( [' q2 X7 q! E$ L2 I6 B8 ^- g6 w
  656. /*                                                                                                                                                */+ g' p! a6 {7 O$ D
  657. /*                                                                                                                                                */+ Y7 K3 l+ A5 J# r1 X5 z
  658. /*                                                                                                                                                */4 g! y$ S0 E! A) P; V
  659. /* Input:                                                                                                                                */  W' g6 b) ^1 X0 K- Z' }$ f
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / |& T2 D  x9 k0 K1 D
  661. /*                byte:                byte to be programmed                                                                */
    % h0 k9 K* v8 x! b# r. v8 z
  662. /*                                                                                                                                      */4 p. F! E3 ~# U! `# x- I
  663. /*                                                                                                                                                */
    ) Z: c9 D, y, A; h, v) ^
  664. /* Returns:                                                                                                                                */
    , F3 q# ?, p: E: S  Y- ?% Y9 C
  665. /*                Nothing                                                                                                                        */
    & o& T1 E! `3 D# c
  666. /*                                                                                                                                                */5 H- G9 Z# u! Y% A
  667. /************************************************************************/
    ' z" n' V; ~# m: m7 i3 Q% v5 ]
  668. void Byte_Program(unsigned long Dst, unsigned char byte): k2 b, ^% `% e* C
  669. {/ `; m# z6 c; q. O$ V% ~5 z$ C
  670.         CE_Low();                                        /* enable device */
    + ^$ M4 `" I: j
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ; Z5 r$ J, v% L& A
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    8 ]" c) a9 M) m" ?0 o
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));8 o8 z. i) A4 s( d) K( H
  674.         Send_Byte(Dst & 0xFF);
    * J' {  j; Q$ c  Z
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    6 z6 ?7 L: ?3 Q1 P
  676.         CE_High();                                        /* disable device */6 I6 R, u& L/ s$ h( Y8 i( S
  677. }
    + a- W% [( Q3 ?0 P

  678. 2 G' X9 ?; H9 G1 J# m0 D) u
  679. /************************************************************************/
    + L2 J+ Q7 v4 W# C6 j- N( P7 q( \. O
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        *// |. [( R  ]+ W+ e5 K# a
  681. /*                                                                                                                                                */8 W/ V! [8 \  ~2 P4 @
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/8 x  d4 k6 {  Q0 a0 d  Q  G8 e
  683. /* the device:  1st data byte will be programmed into the initial                 */
    1 y" d" p: H- Q, p- M8 h
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
      ]8 i+ g  y+ ^7 w% q) S# H9 w4 p
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */9 K/ ?* p+ f9 Y) ~  {/ |6 Y
  686. /* is used to to start the AAI process.  It should be followed by                 */
    / H1 P. e4 P7 O& @" `
  687. /* Auto_Add_IncB.                                                                                                                */
    % F" q1 W& D, ~' ~9 i- X* A. ]
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 C9 a( ~: g. A4 p# F0 [& C0 M0 Z  \
  689. /*                                block protected.                                                                                */
    " a$ y$ k$ B  n
  690. /*                                                                                                                                                */8 i5 _, o! G* z/ Q& r" t3 q
  691. /*                                                                                                                                                */
    ' j( H0 `5 d% p9 P; r5 r( R
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */2 I( S4 A% h: O1 m5 w
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */0 \7 L. }+ L  t1 r
  694. /*         unless AAI is programming the last address or last address of                */
      x1 H. R4 |" A" y1 Y
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    5 f6 o6 ^$ m+ A! B/ u
  696. /*                                                                                                                                                */
    % {, y0 v  B1 K$ H8 n. a
  697. /* Input:                                                                                                                                */1 I3 @  v! W" U1 E3 @1 ?+ V
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# [4 d* z5 m" @+ N
  699. /*                byte1:                1st byte to be programmed                                                        */2 }! A" }: L" T9 F' `
  700. /*      byte1:                2nd byte to be programmed                                                        */  ^" U1 \3 L+ x+ W6 P3 ?  j- a7 o
  701. /*                                                                                                                                                */1 [" t$ s% ?' w8 I: m" N
  702. /* Returns:                                                                                                                                */
    ) c: b" s: F' w
  703. /*                Nothing                                                                                                                        */
    : G5 E8 _+ p7 K
  704. /*                                                                                                                                                */
    6 T( h. K. @) z
  705. /************************************************************************/: N2 ^: C8 T& G. q6 I: w4 k- p
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)3 C# y- k9 d$ J5 ~% u4 H* M
  707. {. s  b' D( u& ~% j% C
  708.         CE_Low();                                        /* enable device */' z$ |+ `$ H# N) b. ?2 @
  709.         Send_Byte(0xAD);                        /* send AAI command */' i, {* }9 Y# z0 n3 P! W
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    - U3 ~0 F  p+ Q8 K  S  L
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));* C, O4 }0 t1 A- f6 r
  712.         Send_Byte(Dst & 0xFF);. g  k: I% V; O# B3 K" I6 @; H
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    " [/ B( Z$ a% _) B: }
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */1 h3 k2 ]  k8 n2 ~' p3 x
  715.         CE_High();                                        /* disable device */3 d& w9 a: [% C# U, Q7 g
  716. }
    6 D+ u& o3 X+ r
  717. ; b# n/ Z3 `9 R( ^5 \: F
  718. /************************************************************************/& Q  ^8 X( ]0 u% F' ]3 w
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    : y# r+ h7 s: h, B5 e4 W4 }
  720. /*                                                                                                                                                */
    * T/ C( m9 t8 ]. f( P
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/) e2 z) n9 s, q3 o% M4 R5 Y) d
  722. /* the device:  1st data byte will be programmed into the initial                 */6 q% S! k& V# n+ h* z* t# i
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    / ^$ ]$ i" {2 F7 R9 T$ h" G
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    7 s0 o1 S: u3 N" L. ?
  725. /* is used after Auto_Address_IncA.                                                                                */
    $ F$ T/ m  y1 Q, g2 B9 A7 M7 C
  726. /* Assumption:  Address being programmed is already erased and is NOT        */& L& U! `2 N# I- N
  727. /*                                block protected.                                                                                */
      G. d0 G' `4 U/ L9 B8 Q) N
  728. /*                                                                                                                                                */& i9 O+ N! g4 o) }: z* a
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         *// G- \- j7 ]- o% K- m
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ; ^5 ]; ]: t+ K9 N. O! O- N  z
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */, r# Z. p/ d, _
  732. /*          to exit AAI mode unless AAI is programming the last address or                */: W9 W3 ^! J- X7 h1 g1 L6 c. l
  733. /*         last address of unprotected block, which automatically exits                 */
    - o* l9 P" y. n  Y  j; t& d! I
  734. /*         AAI mode.                                                                                                                        */
    % u2 C& [. u/ h! U' ?, o4 `  @
  735. /*                                                                                                                                                */# O* t  {( s2 W' H1 n# k5 o' a
  736. /* Input:                                                                                                                                */0 {/ y  [, p9 }- Y) p0 B
  737. /*                                                                                                                                                */
    8 u0 h+ F' a, A7 o
  738. /*                byte1:                1st byte to be programmed                                                        */
    2 b6 [$ K" t" s3 \, {' O
  739. /*                byte2:                2nd byte to be programmed                                                        */% d% N$ |1 @, f" m7 M# ^! ?. I
  740. /*                                                                                                                                      */5 i4 m4 ]: x+ q: q
  741. /*                                                                                                                                                */
    ' u5 U" d; [( Z
  742. /* Returns:                                                                                                                                */+ p  @$ [8 x0 v) V5 _
  743. /*                Nothing                                                                                                                        */
    ) f# t' _" q7 H/ a' C1 v3 M
  744. /*                                                                                                                                                */5 U, Z) t/ e6 {4 m5 ~
  745. /************************************************************************/% V6 m: }" U- S7 q' G# f6 a
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    % K/ ]7 `4 q" I9 _* ~$ r
  747. {. s# t/ g+ A+ \3 s* y' w
  748.         CE_Low();                                        /* enable device */  v) F6 ~4 e* G# R4 o* ]
  749.         Send_Byte(0xAD);                        /* send AAI command */
    3 G! A- ]- h  C. M- p7 q1 ~7 c; h
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    1 d- [. x- H7 c& S) Y: a4 K/ d
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 f) Q  \( o9 O8 Z0 }" ^3 N
  752.         CE_High();                                        /* disable device */' u, _9 }' _( c% H- _
  753. }
    9 M6 S- v0 F* f9 k7 G

  754. 5 \# ~1 G) \, Q  F0 ^5 H- \
  755. /************************************************************************/
    9 `0 [/ z/ R! k/ V- u
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    + `/ ^/ d7 q) v3 g# ^/ `# \& y+ Z
  757. /*                                                                                                                                                */
    ; K) D% R, d+ B3 O, A7 ]
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */. M6 |/ Q4 ~" E5 L8 H+ F3 D; T' C
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    9 u9 C. Z& u5 j' w; c( G8 o1 h; F. H
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    . o1 `1 K# f+ L2 J, K* v8 d
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */" I7 U1 d) F, T0 N! U$ \
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    7 \) s) w: L, ?1 v
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */! w2 F% |% f# {( @2 w
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */. [: i% |6 k$ m' t9 M
  765. /* Assumption:  Address being programmed is already erased and is NOT        */  P3 V( X+ q6 g0 r  z
  766. /*                                block protected.                                                                                */; @6 b. f* H* @! c; E0 M* E
  767. /*                                                                                                                                                */
    : u3 U& N3 C. H5 ^  w
  768. /*                                                                                                                                                */
      L* _0 w) \) R% E
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    0 y- V4 a! X! L) {
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
      J4 \3 d0 p9 k) g4 V. c
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    $ k/ r$ K0 U4 o
  772. /*          to exit AAI mode unless AAI is programming the last address or                */9 X! L! ~8 v# O
  773. /*         last address of unprotected block, which automatically exits                 */
    8 S8 P( n8 K# {; B4 t
  774. /*         AAI mode.                                                                                                                        */
    ( p5 E2 }  D$ }8 @* D( g( n
  775. /*                                                                                                                                                */6 {5 h- b. A- c3 o3 B9 A) h7 X
  776. /* Input:                                                                                                                                */, I  ^. H5 U0 t# x: B) }" W! f* ^
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - |! r9 Z: l! m- l: D
  778. /*                byte1:                1st byte to be programmed                                                        */0 B% E3 _) f4 }& Y* e1 x( _
  779. /*      byte1:                2nd byte to be programmed                                                        */7 p6 r! T- B, G4 r/ F: i6 O, a
  780. /*                                                                                                                                                */# E" U- _, O1 Y  j9 r! f; y5 A$ F0 W0 B
  781. /* Returns:                                                                                                                                */
    # `' m/ R# B3 M3 y$ R
  782. /*                Nothing                                                                                                                        *// s- e$ n* _9 M2 k( j. _# b, h
  783. /*                                                                                                                                                */0 q$ `* ^* @! V, |& X' R6 v
  784. /************************************************************************/4 D' ?5 Q$ h5 h4 B$ d
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)' x) v  b9 t, ]( `( y5 h
  786. {
    ' W% {) Q8 e+ K6 \
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    7 A. F5 D2 U9 a, g& X7 A" E& B
  788. 4 P! c1 ^+ M0 d$ s. Y2 P" `
  789.         CE_Low();                                        /* enable device */
    # S0 Y2 ]) e$ A# B. L+ n2 R4 O$ P
  790.         Send_Byte(0xAD);                        /* send AAI command */' S" h+ ^: d* ~2 E$ R
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% e3 T7 r  S# i3 w. _. \1 E+ O: k
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));3 \3 H. ]* N# l- I: O  }! E. B6 J! U
  793.         Send_Byte(Dst & 0xFF);9 Z4 Y3 v$ F) @' q8 }0 d. p
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    8 D; E; f( E) ?# s3 n* l4 B
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */! n. _5 d- S& P3 F' r4 Q9 ]% h( w* p$ O
  796.         CE_High();                                        /* disable device */$ x2 }5 ?$ o% @& o, U# d& B
  797.        
    7 [0 t& q4 P% `9 `
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    * B+ M: N- S' s) N( w+ U# x

  799. 8 o3 R% p& }  ~  u* I
  800. }
    4 v- u4 ]" ~+ e# ]  z9 f

  801. " Q3 [) X3 C3 ?5 {
  802. /************************************************************************/
      _0 w, e. _2 f! O: H  H
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */9 N4 Y/ g* b, L+ k3 S' a7 L6 B
  804. /*                                                                                                                                                */) w1 m7 \, w* Z
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    . t, l5 @1 t. y0 A( f7 e1 C+ _: z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */4 _  |8 K- A$ f9 `
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    3 y- H/ ~$ E( n; r7 u2 f- _/ V
  808. /* the device.  The 1st data byte will be programmed into the initial   */* y3 [. Y% B2 J/ w! h" G
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    . N( s! F# E( O2 t
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */% j6 z% |; p1 ?. F! q+ X3 M+ _- }
  811. /* used after Auto_Address_IncA.                                                                                */; U4 k7 [( u* Z$ w5 E, |4 F4 \7 ?  l
  812. /* Assumption:  Address being programmed is already erased and is NOT        */* W8 T( N7 [( N0 ^# f, l# p
  813. /*                                block protected.                                                                                */  L, M0 r% l$ p) C
  814. /*                                                                                                                                                */* j; @8 G: K. `! i4 m: Y
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */$ I* ^; Z! W6 u( r. w
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    " }3 K" ]+ w* S; d6 V
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. |: Q! ]5 _7 d3 O& X. a
  818. /*          to exit AAI mode unless AAI is programming the last address or                */  p  V. A5 A) R( T! r- Y3 x
  819. /*         last address of unprotected block, which automatically exits                 *// a/ W/ @# d. X+ p. p5 h! b5 f+ L  r
  820. /*         AAI mode.                                                                                                                        */0 T5 r- m- V/ `$ j1 r6 v% D
  821. /*                                                                                                                                                */, t8 ~' N/ t9 ]; U! L6 n( J
  822. /* Input:                                                                                                                                */
    # T+ j) `4 W: X/ f6 i; B( T& A
  823. /*                                                                                                                                                */7 L4 p% H& X! \1 C: p/ r3 @' D
  824. /*                byte1:                1st byte to be programmed                                                        */
    2 J! C, ?# T, C. D- l% l/ P* L
  825. /*                byte2:                2nd byte to be programmed                                                        */
    , _1 E, P+ s8 g+ j$ Z
  826. /*                                                                                                                                      */1 ]0 ~$ t0 t3 J7 P! J* E
  827. /*                                                                                                                                                */
    * ]& y# C+ a2 }; [" [. A- \
  828. /* Returns:                                                                                                                                */
    - w' D" u7 o$ f/ e& _1 [) `3 `
  829. /*                Nothing                                                                                                                        */
    ' D5 ^" o6 d' Z) z' l+ |
  830. /*                                                                                                                                                */
    & H5 R) g, e4 Y" _0 M" W
  831. /************************************************************************/* J& Z5 l" |/ {# s# l# j- t* O- D4 V
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2); z4 {& x* \3 r* f
  833. {
    4 f4 I$ }( C  _1 G9 j
  834.         CE_Low();                                /* enable device */6 h8 D; A. P, Y% n
  835.         Send_Byte(0xAD);                /* send AAI command */
    % @* M+ r  N- P% N
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    4 A* J) _4 T3 H- Z+ R4 K
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */8 v0 _. C; W1 t1 ]1 X" _2 A
  838.         CE_High();                                /* disable device */; H+ |: W% e/ t: F

  839. 9 O0 S8 Z9 u* w4 [
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    , N/ Q4 E( c, z* o' f9 P3 w/ G

  841. . A$ Q0 w6 f: w4 H
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    $ _: _2 ], @! ^1 o9 _; h$ E. c
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */; y& k% {; [3 ?0 {
  844. }/ t% V# r* }& C7 C& C( h

  845. - Q( y3 C2 D  O' ]1 ?
  846. /************************************************************************/
    7 P6 p, ?6 G+ X+ D% ?9 B: j
  847. /* PROCEDURE: Chip_Erase                                                                                                */! [  l4 U) h9 ^8 W) w4 X
  848. /*                                                                                                                                                */7 ~. _" M% `! Y
  849. /* This procedure erases the entire Chip.                                                                */: L2 U) F. ?0 Y: L
  850. /*                                                                                                                                                */
    5 Y% Y% j( I8 I5 u; A
  851. /* Input:                                                                                                                                */9 Q4 R7 T- l+ s9 z7 r
  852. /*                None                                                                                                                        *// g$ M4 Z6 `) T+ W; I
  853. /*                                                                                                                                                */
    9 t* {5 R" g2 O0 t, \7 m
  854. /* Returns:                                                                                                                                */
    , W6 h# q' e1 G7 i4 f  {$ c" s$ j
  855. /*                Nothing                                                                                                                        */
    ! H. N* ~- Y$ A9 V5 Q# N9 ^
  856. /************************************************************************/: U6 \5 g& u  t
  857. void Chip_Erase()+ J" t/ R2 \: J3 P( X+ V; b' f
  858. {                                               
    ) l* H! v8 P. T, F5 ^' M0 I8 z4 U
  859.         CE_Low();                                /* enable device */
    & B& u7 P6 T2 v+ N8 b2 `' l1 l
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */- k- R9 R: W' p3 N& R
  861.         CE_High();                                /* disable device */% {. |8 |. q2 d& z$ G) S/ z5 `
  862. }; W: P6 Q7 [1 O' P! u
  863. : P5 ]  e) h3 ~
  864. /************************************************************************/  U# ?& W4 J) C, {" ~) Z
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    7 I$ z! b! r! j7 D1 T
  866. /*                                                                                                                                                */: y/ n& H" S7 u6 }" h+ ?
  867. /* This procedure Sector Erases the Chip.                                                                */
    0 }9 ]7 ]5 F  t4 D9 U2 X0 _& l" P
  868. /*                                                                                                                                                */
    9 C9 q- B2 Y$ W1 b! s+ }
  869. /* Input:                                                                                                                                */
    + F/ x) b: n9 P1 _
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! ?8 c5 [3 Y4 Y4 |1 Y. ~3 @
  871. /*                                                                                                                                                */& p, Q/ ]. b) L2 j) T. s/ U2 q
  872. /* Returns:                                                                                                                                */
    0 ]4 S4 }) x) Z$ \* |
  873. /*                Nothing                                                                                                                        */: w. ~4 k; R) M% A+ ^
  874. /************************************************************************/
    0 V4 a. \8 B) C0 l  F9 X) S
  875. void Sector_Erase(unsigned long Dst)$ P* g3 [5 i+ P4 {3 R7 T! Q
  876. {6 L# L. v: G. b* j1 F* r/ u# v$ w

  877. 6 y# x/ [+ l  z( V3 g2 l, \

  878. " Y- F4 v- d# L# \  \3 I; |1 H
  879.         CE_Low();                                        /* enable device */
    4 H& @4 S& }4 |- P$ Q, _& k3 o
  880.         Send_Byte(0x20);                        /* send Sector Erase command */  Q) V$ c' y5 v- T
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! }! H! Z. t  w) q8 C' l) M" k  Z* t
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));. M$ X& z5 S. ~
  883.         Send_Byte(Dst & 0xFF);1 ~& k5 m1 g$ M2 L* s, X" |
  884.         CE_High();                                        /* disable device */, ]% r9 b- A* c- a8 O9 {9 o/ l& w( J
  885. }       
    $ e5 V) P5 L) `- M+ l: {
  886. $ K6 p5 W% x. Y+ U$ y
  887. /************************************************************************/# r/ ]3 y' E! |' C. u
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ( N5 k' E$ @5 N8 J
  889. /*                                                                                                                                                */2 `7 \; z2 @  o; n( ?
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        *// A9 c5 Q0 P$ N. |. J7 R& ~! J
  891. /*                                                                                                                                                */
    4 r( ~. W& v9 f# `: n1 p
  892. /* Input:                                                                                                                                */$ B4 Q, n1 Y8 g/ b; c3 g- I
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ; V4 l8 p4 t7 n4 Z4 q
  894. /*                                                                                                                                                */
    2 N% r% X: Y$ _
  895. /* Returns:                                                                                                                                */5 U* o' s3 Z5 W: q9 q+ k; E; r
  896. /*                Nothing                                                                                                                        */! e0 i5 v2 E2 ~
  897. /************************************************************************/
    # r( e; l: x" _: e( |  h
  898. void Block_Erase_32K(unsigned long Dst)/ l) E) g5 H- n% |7 _
  899. {. r5 ~( C) y+ N: @- @( z; D2 }
  900.         CE_Low();                                        /* enable device */
    7 E: b3 z/ T3 j% c
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command *// }9 a" q0 q- S3 U& y! `3 M
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */- x# J6 |$ X8 G+ i1 E7 D5 v# T5 N& b9 }
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));! w7 s3 t7 F" Y$ s# x3 q, ^& O
  904.         Send_Byte(Dst & 0xFF);
    ' l+ W6 M! u# i8 M  L/ _
  905.         CE_High();                                        /* disable device */0 M3 E2 G+ ^* w( Z+ w1 D) H% e
  906. }
    4 R  p# {" }5 c

  907. 0 q) Z, t/ C& |& a5 e0 L9 v. n# M
  908. /************************************************************************/
    " R  J. U& r& M' `/ X7 Z
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    2 _% f- i& J  T( O3 `+ f. H; j
  910. /*                                                                                                                                                */- G, U/ r, [. ~/ q0 a7 v
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ! I7 |# E7 o2 b% N) E
  912. /*                                                                                                                                                */
    8 ~% _. ?0 e! D7 S- E/ O9 k; `4 u
  913. /* Input:                                                                                                                                */
    + Y6 a) `4 s9 C" @/ i
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 \3 V- J( g% ?8 O( u& O
  915. /*                                                                                                                                                */( C7 D1 O! f- O- {" _- K
  916. /* Returns:                                                                                                                                */: m" v' d) G' b# [2 a  t
  917. /*                Nothing                                                                                                                        */
    & C0 \. e( I5 G
  918. /************************************************************************/
    ( f" E2 k, p) R
  919. void Block_Erase_64K(unsigned long Dst)  Z0 B8 l* ?8 ~4 a/ f7 r
  920. {
    ; g: h7 `3 Q5 H0 p: P* n
  921.         CE_Low();                                        /* enable device */) y% `; z3 H5 U  |
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */. |- n0 U7 b/ h6 q" {" J
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      h1 z9 ]/ ~% G" o, I2 ?$ d' E
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));- @( a" H0 ~' b8 U$ s1 V2 t
  925.         Send_Byte(Dst & 0xFF);; @; t; u( E8 Y) ]  [+ A- B
  926.         CE_High();                                        /* disable device */; n9 }/ \) Q+ w+ O2 s1 ?
  927. }9 ]+ x+ M  N6 P- B! |. \  w) j

  928. ; O: s6 ?: ~% C+ i
  929. /************************************************************************/. _8 M7 Y4 T0 u4 I
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    0 n% Q+ R/ ?  U; `2 B3 }& ]
  931. /*                                                                                                                                                */  G) |# x1 k3 L; \/ w$ c7 o3 W. I
  932. /* This procedure waits until device is no longer busy (can be used by        */
    ) K" c/ J! n& w
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    5 c( p& A2 w" W' Y2 e3 r% ~% m/ w
  934. /*                                                                                                                                                */
    : I) E7 x' O# N6 ~/ l( [' [
  935. /* Input:                                                                                                                                */: S# t# a  j( ^0 k
  936. /*                None                                                                                                                        */
    ' j' G4 V4 r; t/ d% |5 \) T/ c6 o. B
  937. /*                                                                                                                                                */
    2 Z9 F0 d' ~- m  @
  938. /* Returns:                                                                                                                                */
    ) G6 y, H/ f  `+ |1 Q; h; x3 s: s' Q
  939. /*                Nothing                                                                                                                        */. V# I8 {8 n# d9 x& j# g
  940. /************************************************************************/
      T) @, _. P3 x4 D
  941. void Wait_Busy()
    % u) l6 i& {4 G: ]) o- I6 N) m7 K
  942. {9 {$ F2 ~! g- T/ V- P2 h
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy *// u# b5 w" P/ Z9 ^
  944.                 Read_Status_Register();  Y8 i, g8 l0 E. o  H# {6 S! Y
  945. }2 P! A+ K. d. C' }9 @' |

  946. % Q$ E8 w0 M: Y2 Y
  947. /************************************************************************/
    & D3 F5 C- J0 Y& G8 @9 V9 |
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    7 z+ N+ o8 X3 N& s2 }7 F7 L
  949. /*                                                                                                                                                */
    - c- I  S( Y+ `; i+ X1 e
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    - |9 E. K& T- [% P4 [
  951. /*                                                                                                                                                */- f8 w; K; f1 k9 N1 L
  952. /* Input:                                                                                                                                */
    * X  w2 }2 d. Q. W$ e3 B
  953. /*                None                                                                                                                        */
    4 ]  M9 H+ A4 W; k$ C
  954. /*                                                                                                                                                */( _% y; w% N% W8 p& j5 m
  955. /* Returns:                                                                                                                                *// M5 C  }: q! b3 x
  956. /*                Nothing                                                                                                                        */0 @3 M6 I4 z" D/ b- p# C5 k: W, q
  957. /************************************************************************/
    6 J* B: i# _/ B* @
  958. void Wait_Busy_AAI()
    0 h; G- _. m+ R  c/ G. |
  959. {
    ( K- p3 ^+ ^2 L, h* l* n
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    8 G$ L  l' _* |2 M( O, n
  961.                 Read_Status_Register();
    9 x- m; t# Z0 e' B
  962. }
    - G3 s6 p- U2 _- t+ @

  963. + Z* G( N5 F. i, f! v
  964. /************************************************************************/
    : N& u6 S. _  v" o: {
  965. /* PROCEDURE: WREN_Check                                                                                                */
    * E& d, H( D3 m& I( _
  966. /*                                                                                                                                                */  n. q  T' w8 T
  967. /* This procedure checks to see if WEL bit set before program/erase.        */$ O4 e9 r; b- E1 C4 |0 P+ j
  968. /*                                                                                                                                                */0 q% r" L2 N' b9 Y, R* d
  969. /* Input:                                                                                                                                */8 _& q5 G" z, K. ^+ f2 b
  970. /*                None                                                                                                                        */
    3 z3 @% }* r! w& v& w% W; i
  971. /*                                                                                                                                                */% O! R1 e4 |9 `8 `- Z
  972. /* Returns:                                                                                                                                */
    / Z5 ~/ H% v4 s
  973. /*                Nothing                                                                                                                        */
    9 ?" g) i4 O( i% O
  974. /************************************************************************/6 O: w7 f: a4 `' V: d0 h8 B* c
  975. void WREN_Check()* {, }6 a# s# q" I8 Z' Y6 E
  976. {, N- m! P/ ~' X. g$ S0 \
  977.         unsigned char byte;
    & J: y0 {5 O. x' f. D9 n
  978.         byte = Read_Status_Register();        /* read the status register */
    + k7 K- D+ v9 T9 r& x. Z
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ( V" U" }4 o  c$ a
  980.         {
    + m# Q7 r: C  F% T; ]; s
  981.                 while(1)8 X0 `5 Q% J$ b" b( q
  982.                         /* add source code or statements for this file */
    1 `: `) q* m. @
  983.                         /* to compile                                  */
    - T! b9 p3 g( e- y* U% `
  984.                         /* i.e. option: insert a display to view error on LED? */
    6 L5 j6 K* Q" P5 Z4 a2 I
  985.                  - T6 w  s& T' o, R
  986.         }
    # Z* b" Y  u4 [, M7 K! j
  987. }
    9 g1 r5 l( @6 C: P4 o- G) i

  988. ( }4 M5 i+ d9 f* D; _- T
  989. /************************************************************************/
    " D$ o( Y* x) ~9 l
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    . y) p+ o1 c( Q
  991. /*                                                                                                                                                */7 c* h4 f. ^# @! F) J
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    0 z6 j& k7 V6 F4 d) x) M# d
  993. /*                                                                                                                                                */  I( [3 C0 B- O
  994. /* Input:                                                                                                                                */0 m! ^/ A* Q! G: x7 {
  995. /*                None                                                                                                                        */( H% Q3 |1 B" O+ {2 u0 y
  996. /*                                                                                                                                                */
    / z# d9 c  [  Z" a! |) J+ C
  997. /* Returns:                                                                                                                                */
    4 v/ }% J  C6 d3 ~
  998. /*                Nothing                                                                                                                        */. }* ~1 Y3 y: S
  999. /************************************************************************/
    + C; ~' ~, {- q* h
  1000. void WREN_AAI_Check()
    , S& |% b* B4 e) C, I
  1001. {) P8 a1 W" Y" A1 i
  1002.         unsigned char byte;9 e% S6 i7 d3 M0 L
  1003.         byte = Read_Status_Register();        /* read the status register */
    0 B, B0 N. G8 `7 K2 Y" M0 D4 k9 ]
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */# A, d, l+ S; w9 d6 q
  1005.         {
    9 b) V% Z3 J- @/ m: H
  1006.                 while(1)               
    1 h. d+ q  Y* `
  1007.                         /* add source code or statements for this file */
      y5 k3 _- I/ b7 M
  1008.                         /* to compile                                  */
    8 M9 r- N5 }; _, Q) P
  1009.                         /* i.e. option: insert a display to view error on LED? */
    & M2 U. s5 R7 j1 P

  1010. " Y6 w/ h3 A/ c7 K
  1011.         }
    " V6 f6 |& O0 _! t! T
  1012. }
    9 z0 ^7 P& Z, P) `: d7 }# F

  1013. / q% e2 p9 q5 u8 a8 T6 C
  1014. /************************************************************************/( [$ H  m+ [. ]
  1015. /* PROCEDURE: Verify                                                                                                        */
    5 a4 ]# D9 n5 b  U4 F
  1016. /*                                                                                                                                                */5 X3 F. K3 d9 N9 o
  1017. /* This procedure checks to see if the correct byte has be read.                */
    8 c, m; B% Z+ _4 h! a( a
  1018. /*                                                                                                                                                */; ]% B3 v) A+ J* b, N
  1019. /* Input:                                                                                                                                *// w& l0 X9 t$ A3 ~% I
  1020. /*                byte:                byte read                                                                                        */  i# M4 S# G5 d2 E# Q  F9 R1 n
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    / H* H: f( `+ w3 l
  1022. /*                                                                                                                                                */
    : n- P: f) q- A. A
  1023. /* Returns:                                                                                                                                */8 h0 }/ ~" x. |& j4 P" G
  1024. /*                Nothing                                                                                                                        */$ S' E% e1 N" ~) w! e
  1025. /************************************************************************/
    : d! }$ m$ \" s4 i3 F
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
      H: N* m$ t/ E$ S4 j9 S
  1027. {
    , w' j6 q# Z4 f4 d- s+ P- d
  1028.         if (byte != cor_byte)1 @7 F5 P7 k1 ?9 U/ z- {- E
  1029.         {+ g! v* D/ r) o8 c0 X( P
  1030.                 while(1)
    5 {9 @9 s+ }/ P
  1031.                         /* add source code or statement for this file */
    % U# e3 t7 O! X" C: P
  1032.                         /* to compile                                  */1 y! j! i+ i. Z, b5 f7 l9 h0 T
  1033.                         /* i.e. option: insert a display to view error on LED? */! ]: V* }  B4 R( }" Q# P7 p+ p
  1034.                
      R) H% i3 H2 n5 S4 ^: Y
  1035.         }+ H$ a7 Z7 |; J% b
  1036. }. K" o6 u: a) e/ M  e& _
  1037. ' ?5 w' P8 p. s, X4 x) |: a* t

  1038. ; q; h# s+ s+ l; S5 r7 i
  1039. int main(). j. }  s7 n& p& ~
  1040. {
    2 C: r9 L  E1 G0 q% O7 \
  1041. 2 y% S" ^4 [: v# d
  1042. return 0;
    ! u+ Y  L( f8 i" z5 i
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:* g2 V: F# r0 _3 t+ f5 u, @0 H( o. h
   main()& Z' M7 O3 F% L" i8 M# W
   里面怎么是空的呢?
& B8 H' i0 l  E, g& R' |& _/ a   发一份给我吧
: J+ B6 V3 V* \! e: I" Lmail:luyijun2005@hotmail.com
; \/ A# |0 x6 a' P4 a咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。9 f- ~: D5 t% J! Y

# ^" O% l0 P7 {" m$ Z6 r[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。$ w# Z* u- ~% C: q" B9 S! A5 Z
EC的代码在哪跑,你看DS的说明,每个EC都不同的。1 e& R5 _0 a$ l: [5 J5 |3 z/ T
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
  X1 C& n. Z' A5 ?2 N2 V4 q" A/ `上面几个问题是你没看任何东西而白问。- ~0 n8 u9 H2 \  p4 {

) i* [  q" h' H& V: R, T至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
( o6 [: I5 J) V" ?
% ~* c8 u' U& Y/ Z' @9 Y关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
6 f4 e( Y1 N  m$ _4 n  _
5 S5 G9 J& H6 m7 h关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
7 M1 w* X  V7 N8 E% }; P7 {6 U$ p
- N; D$ w/ l+ m  z* B6 X, f' D关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
2 y6 ~, @, i* r
+ B7 j. X& _/ V  `  V. Y% }/ \" s不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
+ |; N1 H( V) i. k5 }& ]似乎要把SPI能support 到最大,这EC chip应该有好卖点1 a: z' Y8 e5 V4 @3 }
BIOS功能要不要强大,也就决定了SPI Flach的大小. E, K: {8 G+ i- ^  ^: y- M0 _9 i
我是这么想的~让OEM去决定要挂多大!
# d' j. G/ U  z" `$ R如果我司有BIOS工程师就好了~哈. m3 W5 p- V4 t( I
WPCE775应该算很新的东西,来看它支持到多大?/ A# V& ~. W4 S5 z; b. [+ u
0 @) @7 Q* V; L, E+ C
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
8 }9 y8 u1 q; k! o3 y其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.7 c$ t9 L9 l2 t; M
; D1 O8 S' d4 t6 x& N2 `
这份driver收下~希望以后有用到
$ L" J6 K2 l9 H  p谢谢bini大大* g( X0 o& o3 U( B+ f9 P1 {/ T8 x7 l6 Z
% C: }& y7 C- k" F$ w* w
很新很新的新手,如有错误请指正 (准备看第二家的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()
7 r7 e7 G& g* b+ r& F{/ V0 r! `$ r% N/ a- ~( n5 q" s9 }
        unsigned char temp = 0;
, E9 N, a, I* _* M5 f        CE_Low();
* T) w; }% |2 P8 z    while (temp == 0x00)        /* waste time until not busy */
# U7 }* p2 m1 A. u                temp = SO;: f/ X% B/ e1 |2 \
        CE_High();
* [- }( B) f/ {  s}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out): `; s+ q# R5 c3 p, _
{
, I% I" {8 ^6 x1 E( _        
" Y) M* A2 t8 w9 r3 j) `/ M        unsigned char i = 0;/ V5 S. d# I$ E6 b+ A
        for (i = 0; i < 8; i++)9 P( @3 M) n5 j) J1 B7 f4 q
        {
: `+ ?, t- q, k9 L! R( G( k" @               
6 g5 q9 `  c8 I8 E                if ((out & 0x80) == 0x80)        /* check if MSB is high */7 W- Q' O9 G( T" x* [
                        SI = 1;
: P6 b1 E$ C/ W' s. j                else
5 `" V; j5 E2 Q/ o4 d. @2 ^                        SI = 0;                                /* if not, set to low */- A6 S: S! _' h& [' `
问              SCK = 1;                                /* toggle clock high */
5 L" G8 |$ o6 c: j, f   题            out = (out << 1);                /* shift 1 place for next bit */
5 q' _$ `4 G; c" ^                SCK = 0;                                /* toggle clock low */
& M' O" v5 c% w# |        }; i# L+ \2 a( z/ ~) ^5 c; \
}( X& U& L, {' d7 y' C
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-19 12:18 , Processed in 0.080291 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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