找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55586|回复: 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
    + X2 n8 w9 O" E, r4 j

  2. - {, a2 }1 l+ C. F
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory6 P% H" ~6 k' E

  4. + R# R1 x' F) l
  5. November 4th, 2005, Rev. 1.0
    $ n4 U9 Q: g1 K% z

  6. # M3 T. M( H/ F& c
  7. ABOUT THE SOFTWARE
    ; }" ?$ v7 Z( N0 Q# F8 f9 ^
  8. This application note provides software driver examples for SST25VF080B,
    , v% p4 ?# m& u" B: D
  9. Serial Flash. Extensive comments are included in each routine to describe
    1 u2 B) I8 K7 |" t4 ]1 f2 y
  10. the function of each routine.  The interface coding uses polling method
    # J5 J6 l3 H9 f5 D# {' o9 d
  11. rather than the SPI protocol to interface with these serial devices.  The! h& R4 `. u* @% m/ }
  12. functions are differentiated below in terms of the communication protocols
    9 q# t% e5 H3 H
  13. (uses Mode 0) and specific device operation instructions. This code has been & S, Y% U/ R5 q1 m# L
  14. designed to compile using the Keil compiler.: a( d0 E3 Y7 Y# X9 S- m  G

  15. 4 p8 h+ ~, d: k" O- s

  16. : u, U, D: C5 }# z
  17. ABOUT THE SST25VF080B8 v) T& M/ S4 b5 Y8 z

  18. 1 a) s: B5 y3 Y/ i* v
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    ! l: Q/ s$ p% Z- V
  20. conjunction with this application note for a complete understanding , `7 q* z+ w7 D* I* V. s
  21. of the device.4 D7 |$ O+ B; y/ ^7 H
  22. ( ?" A  Q: q7 A" C
  23. % {( k( L6 @  R' T# s
  24. Device Communication Protocol(pinout related) functions:) O4 [  U6 w/ J+ F- s3 r( w& b

  25. & @. R6 u/ t* P! b# i- O. g% K! }
  26. Functions                                    Function) b; ^) Y! ^  U; C% [4 D
  27. ------------------------------------------------------------------7 N$ _) w4 m/ m$ i. T/ V" u% k
  28. init                                        Initializes clock to set up mode 0.
    # R8 I6 u$ l. V0 p+ R
  29. Send_Byte                                Sends one byte using SI pin to send and
    * L: w5 y# {, v! {1 `
  30.                                                 shift out 1-bit per clock rising edge9 @2 t- j( k+ B" n5 Q
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    2 Q# }" |  L* q% }! D  E
  32.                                                 in 1-bit per clock falling edge+ S# @- p8 }9 q! c: ~2 J
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    8 I4 n& I6 c; _/ {  z
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    6 n* j; t* r( F4 X# v* C2 C* t
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    % \' R- ^9 I8 B: }* O/ j/ L% c
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    & l  R4 W$ _, _* n
  37. Unhold                                        Unholds the serial flash
    2 p8 j: s* }1 j0 e5 i3 i+ a
  38. WP_Low                                        Clears WP pin to make serial flash write protected0 R1 n" ~# g* `& t# W2 `
  39. UnWP                                        Disables write protection pin
    * u5 y0 b8 Q6 v. F' o/ Q3 S

  40. 2 f: X- r8 ?9 V7 G
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    . g# `( @0 T% V. s; |, p! s
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your" ~) q& D) j- E$ Q
  43. software which should reflect your hardware interfaced.          
    8 o, T% {6 M$ |3 h
  44. ; C2 X5 `3 r9 H- b5 p" V5 O

  45. 7 P! F# f# @" X0 f" Y
  46. Device Operation Instruction functions:% q; x! l1 a$ z
  47. 0 g9 I6 g# P7 e3 D6 l
  48. Functions                                    Function
    ) n7 ?- k* `$ V" c& x9 }1 M4 N" ^
  49. ------------------------------------------------------------------7 J1 ~4 ~4 N+ J, s
  50. Read_Status_Register        Reads the status register of the serial flash
    7 E$ E2 x  L% _; Q  J- y
  51. EWSR                                        Enables the Write Status Register
    * V2 v/ K0 d% F$ e" ?5 y8 E* s# |
  52. WRSR                                        Performs a write to the status register
    1 [6 e/ {9 ?4 t; e9 {
  53. WREN                                        Write enables the serial flash: }9 \# o6 o1 i
  54. WRDI                                        Write disables the serial flash+ L) q/ K2 |* B' @4 Y6 F+ t9 e
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming' S4 V; h7 a3 n! @# Y/ F
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming9 o# C9 k6 t+ f2 b
  57. Read_ID                                        Reads the manufacturer ID and device ID
    6 O: s3 k- ]& t7 [1 X
  58. Jedec_ID_Read                        Reads the Jedec ID, o+ B$ b& Z, n1 Y% J' x
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    8 c2 @$ c! p$ p8 a, r9 E& j3 ]3 p! t
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    % R* ^- Z/ _8 L% B# j. _
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    4 A, |' l1 \8 c1 x* k4 O
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)' \: O" Q" \9 y* H- ^9 g& L
  63. Byte_Program                        Program one byte to the serial flash, u. {1 A) t, [8 u7 y: W
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ) p, y/ D! s: A  [( N
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    $ e- l" ], K, V* P* c
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY, N4 ?% B7 d9 F+ I3 P2 Y  `$ z7 s
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY5 q2 E0 D- D* e- m
  68. Chip_Erase                                Erases entire serial flash' [! _/ R# T' r# R5 y
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    8 t! d- V- g0 U# C% D4 ~7 I
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash: M4 G' e3 {/ A& a" _) t
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash% C/ l' s- q' C5 g* J% Z7 b3 Y
  72. Wait_Busy                                Polls status register until busy bit is low2 l6 z# `8 h/ A- g7 t2 l1 K; \
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming0 \  p1 w7 `' |
  74. WREN_Check                                Checks to see if WEL is set
    : I7 |( x- T) d% A
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    % l8 b- e7 R& q
  76. # \6 f" }9 G% F4 h# X

  77. * N- i( m  h0 \0 S% z: S" @, O: v

  78. . R! J; L$ l& A3 S: e& d. w  c0 d
  79.                                                                      $ r* p/ U8 {* ]6 H
  80. "C" LANGUAGE DRIVERS ' A# }% _# [- h# U7 k) P
  81. ; U# f8 z' u3 _" I
  82. /********************************************************************/. }4 ~  E& e6 J3 E+ y) v3 F
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */# M6 e' a. j& x. S
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    $ _! ]9 V# N* h
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */1 O( ^" J7 y( I+ o
  86. /*                                                                  */( d* D* Y5 ~2 @- k# r4 [
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    4 P0 B, @  j& i% O, O% U
  88. /*                                                                  */( q2 U$ G: V5 m! d  H6 {
  89. /*                                                                                                                                        */
    : ~8 ~  S0 Y# l1 d7 _( r7 O
  90. /********************************************************************/
    3 f# }3 {& }! Q) _/ w
  91. $ Y: \2 i7 k7 n. N' y
  92. #include <stdio.h>
    5 J: e3 e5 N9 u- n6 d
  93. #include <stdlib.h>7 e3 \6 K9 k2 c% o0 L4 g3 ?
  94. " x$ y) K1 c6 b) [
  95. /* Function Prototypes */. Q% D1 G5 p1 c/ R1 e6 Y
  96. & ^" Q6 v3 j$ t% I
  97. void init();
    + t# ~& s$ S( t; K6 o
  98. void Send_Byte(unsigned char out);
    & n* w8 i. b& N0 \9 S$ }
  99. unsigned char Get_Byte();
    # g0 H4 g0 K7 L/ Z/ A  }
  100. void Poll_SO();7 w( S6 ^! N5 j+ D+ ~# I
  101. void CE_High();5 f- V! ]5 E/ ?, n# [( n, a, g
  102. void CE_Low();
    9 M' [0 x. i, \  ~
  103. void Hold_Low();4 `9 `' T) T' m. T6 e) t5 @1 L( U
  104. void Unhold();  c, u4 t% r+ k; j' P
  105. void WP_Low();
    ! w2 ^: R/ w6 u* m# h. E
  106. void UnWP();
    1 x. z: H/ f& {: A8 _+ \. g/ q
  107. unsigned char Read_Status_Register();
    / y0 Q9 j5 f$ \& {5 x& P" B+ [
  108. void EWSR();( i& X! F( Z& \4 h* M
  109. void WRSR(byte);
    % f( h5 t  X: ^; Q# S* |
  110. void WREN();3 A) h. z3 G6 D* t# J. p; l" k3 U
  111. void WRDI();* j/ E, t# V; s% X( ?& O) r
  112. void EBSY();1 V  m1 Q: ?9 Z, \6 I9 @
  113. void DBSY();
    1 A( T% Y; f/ n- ]2 |4 k) R
  114. unsigned char Read_ID(ID_addr);
    + y8 V9 l- V  F$ e/ E1 L
  115. unsigned long Jedec_ID_Read();
    6 Q7 @3 T. a3 h! |
  116. unsigned char Read(unsigned long Dst);3 \! ?1 y: R' T% `  S% K- m
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);5 C% e) V( \: j4 \) k
  118. unsigned char HighSpeed_Read(unsigned long Dst); + I" R1 R; @% C
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);2 ~) }4 H6 a- g( d' ]* ~8 L* a
  120. void Byte_Program(unsigned long Dst, unsigned char byte);. s" ]6 D& {  I, C1 K0 J1 f6 T. H
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    0 [0 d  M9 F$ q( |9 p6 X# Y
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);4 k: e+ F" B" f9 n0 n# n! `6 N2 ], Q
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ! c" x3 u- V8 R
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    $ @) y7 J0 N, X1 V2 t3 T4 \9 i
  125. void Chip_Erase();
    7 o3 V7 T! Z& n3 N! O/ D
  126. void Sector_Erase(unsigned long Dst);
    . `1 {0 P2 O; I
  127. void Block_Erase_32K(unsigned long Dst);
    ( A7 ^) S$ k: o( v' Q
  128. void Block_Erase_64K(unsigned long Dst);
    ' y+ Y2 p3 ~# z; {0 U$ W8 r+ F+ k
  129. void Wait_Busy();
    / t# ~! r4 U0 x: n) n7 u* _
  130. void Wait_Busy_AAI();0 \' G; J# ]6 |; J( _1 ^0 }  ]: h
  131. void WREN_Check();: ^( z& K2 F- h) i/ u$ H
  132. void WREN_AAI_Check();* s) l- f2 s1 |# [$ G1 U# f2 R

  133. 9 t% ]7 Q' Z: c9 o- I4 N( }3 e. e4 Z
  134. void Verify(unsigned char byte, unsigned char cor_byte);& ^2 x- O* \$ d4 ^8 h/ Z7 o4 m$ S' A+ v

  135. . F/ _; [( ^6 Y* a
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    & I* K$ l# S7 F+ i: t" ?6 \
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    4 a5 H4 J* u. R( F; q) {4 R

  138. 6 Z2 {7 r0 c6 z) R5 L
  139. /************************************************************************/
    ' ?- b3 W' }3 R7 m. a
  140. /* PROCEDURE: init                                                                                                                */3 q, b8 Q" w+ t) R. J4 T9 }/ {
  141. /*                                                                                                                                                */1 L2 i+ U1 D. q1 p' M  f; K
  142. /* This procedure initializes the SCK to low. Must be called prior to         */% n: j$ Z( T0 _+ k
  143. /* setting up mode 0.                                                                                                        */+ _' G3 }9 G" x9 C! B. @6 i
  144. /*                                                                                                                                                */: M5 D1 q; ]. b8 Z; o* H( j  r
  145. /* Input:                                                                                                                                */. r% r6 _1 t6 d7 o* X0 Y. Y
  146. /*                None                                                                                                                        */
    2 q/ D( `# P* M/ S
  147. /*                                                                                                                                                */$ J2 s, m# k4 u. F0 q
  148. /* Output:                                                                                                                                */7 i0 S3 q5 m# C/ G2 ]7 V) D
  149. /*                SCK                                                                                                                                */' ], q  X) N) u/ f8 t, c9 ^- s; `
  150. /************************************************************************/
    ( A3 m. m" F, W4 |# h0 [
  151. void init()1 m' s4 r0 P8 b# s$ Y% v. W
  152. {2 A$ D* f9 q% g* W8 r: _/ f8 h
  153.         SCK = 0;        /* set clock to low initial state */8 @' K/ P) B- ~) Z& @% j" d
  154. }4 v4 I4 U$ P; b& `3 R2 U/ G

  155. * y& v; H5 o& b/ y% u
  156. /************************************************************************/
    , P8 G$ g4 W* O' u1 v
  157. /* PROCEDURE: Send_Byte                                                                                                        */9 n" B4 H$ s2 e: v, R- p3 {9 ?
  158. /*                                                                                                                                                */: l) b# E+ E5 ^( |
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */5 M) M) ]% b( s8 Y7 f) ?- l! i
  160. /* edge on the the SI pin(LSB 1st).                                                                                */, ?0 l8 u4 m; ^
  161. /*                                                                                                                                                */2 t8 ?  ^* z9 ?, ?3 h, `3 g4 `
  162. /* Input:                                                                                                                                */
    3 X" P* o% g* f# N) S
  163. /*                out                                                                                                                                */
    : L0 j' w. ]$ {0 S' a. A+ s8 Y) l
  164. /*                                                                                                                                                */9 B* w3 o# x  u2 |* C
  165. /* Output:                                                                                                                                */
    - @' X" F* Y3 x/ n  C
  166. /*                SI                                                                                                                                */
    " J1 {: y- q: }3 U& x
  167. /************************************************************************/
    1 b, s. y8 Z3 ?; u1 w
  168. void Send_Byte(unsigned char out)1 z" h; }/ r" D  L$ H
  169. {
    * d1 g' E: _. k) K  b" \" w; w
  170.        
    4 W# T) X% H+ {5 V. S
  171.         unsigned char i = 0;
    1 b& {* q3 N/ J, s* I5 u0 S
  172.         for (i = 0; i < 8; i++)! |- Z- R3 L7 L' d
  173.         {" _- q2 V6 B8 ?6 D6 t$ k& G; h
  174.                 2 Q$ `# o* L' a- `; I2 |6 @/ h
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    0 H* k! E+ h2 P) \  L& d$ s
  176.                         SI = 1;/ ]5 k% M, _( x
  177.                 else
    2 z0 F* J9 ]: `( l
  178.                         SI = 0;                                /* if not, set to low */7 L- s* N# w& b( u. G" g; n
  179.                 SCK = 1;                                /* toggle clock high */& t8 p( E8 m, L4 W4 C# y6 `/ j1 b
  180.                 out = (out << 1);                /* shift 1 place for next bit */" W5 ~# Q0 n0 Q2 H4 j, R4 n
  181.                 SCK = 0;                                /* toggle clock low */
    / C9 l8 Y; Y- o+ }
  182.         }, |9 F* l, r2 u$ ^5 ?0 [
  183. }0 u/ `! W+ |2 T3 B+ f
  184. 2 e) O* e7 X" y# k$ z  }
  185. /************************************************************************/7 j& k) T7 R. V
  186. /* PROCEDURE: Get_Byte                                                                                                        */, H' B# M! U$ y, p- S
  187. /*                                                                                                                                                */9 @! [& @: F8 R8 k
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */9 d# v0 H* p; t# |  y
  189. /* edge on the SO pin(LSB 1st).                                                                                        */( C3 |: C- z7 d9 m0 l
  190. /*                                                                                                                                                */
    3 S. _( D; Y& V, `
  191. /* Input:                                                                                                                                */: j0 j$ h+ Y9 T) [- @
  192. /*                SO                                                                                                                                */
    3 m8 }, n- X  R4 G% [( i' t
  193. /*                                                                                                                                                */" e6 n2 _: G# c. [. d
  194. /* Output:                                                                                                                                */
    6 E9 n# i# G* ^9 _
  195. /*                None                                                                                                                        */( q+ o, F1 |4 _  `9 {
  196. /************************************************************************/
    1 s1 S+ C$ P' B, H& m
  197. unsigned char Get_Byte()
    ( x/ u; A9 U3 a5 u5 x( d
  198. {
    3 c# |1 W! d. n' C& q
  199.         unsigned char i = 0, in = 0, temp = 0;
      H- i0 e: J, Q. p& l/ ?
  200.         for (i = 0; i < 8; i++)
    5 q- Q! O  A5 S1 `- s3 t; {
  201.         {! j/ T3 G  }7 |8 G
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    * L: v9 A" `. x5 x. K
  203.                 temp = SO;                        /* save input */- Q- q+ g6 P9 T! P' [5 K
  204.                 SCK = 1;                        /* toggle clock high */
    % ^) s4 \2 n1 g; ~: J% V! o% `
  205.                 if (temp == 1)                        /* check to see if bit is high */
    / }5 h* d3 q3 h" q
  206.                         in = in | 0x01;                /* if high, make bit high */
    4 O7 S  }4 ~  y# A( a1 _- e, m

  207. + T: |7 y5 p! v' r9 Q% w+ \0 ?
  208.                 SCK = 0;                        /* toggle clock low */$ v* C( f( y+ C0 k

  209. ) _& v$ z: h( o* U% b
  210.         }: ]0 y) V! _! z+ Y
  211.         return in;
    2 ^! ^8 T% C, p- i9 w( p/ B0 S
  212. }) i  l* G& M3 ]4 b! A
  213. ; A4 n3 q, v9 [& Q4 \
  214. /************************************************************************// x/ [5 W# M* D% l6 W% @
  215. /* PROCEDURE: Poll_SO                                                                                                        */* k) M+ w! w2 l* p# J
  216. /*                                                                                                                                                */4 N. r) d" v; \' b- a* ]! q. ~
  217. /* This procedure polls for the SO line during AAI programming                  */' U2 z' i' ]5 g8 H
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ( o  p0 G: I4 I* _) |
  219. /* is completed                                                                                                                        */
    + W* d1 l# |# O) N
  220. /*                                                                                                                                                */
    9 n6 K: v5 p  K/ B# S
  221. /* Input:                                                                                                                                */2 F* B) I1 |- R9 H- a  ~/ m
  222. /*                SO                                                                                                                                */( I7 [4 d2 N9 y, u4 k' v) S
  223. /*                                                                                                                                                */" Y( K" P+ p0 S! q  x
  224. /* Output:                                                                                                                                */( L+ S: i0 Y* `  g* G
  225. /*                None                                                                                                                        */0 l  i' w3 V* x3 i* d" z
  226. /************************************************************************/
    + C3 j5 l% w& D( }. j, Y8 i9 n
  227. void Poll_SO()5 P. M% W+ F; |* x
  228. {
    9 D5 ^9 B7 ]4 T
  229.         unsigned char temp = 0;
    2 F- W3 ]9 U& F/ |5 @
  230.         CE_Low();; w7 O# A: S1 E. [
  231.     while (temp == 0x00)        /* waste time until not busy */
    7 K& Z+ [% B( }: x
  232.                 temp = SO;* |& B3 [$ m9 r# O4 z' H
  233.         CE_High();# j. r2 ^# ]; k4 w; _0 a
  234. }
    / `4 c; c: G- q2 M9 j9 t2 M- Z$ P) Z
  235. 0 [9 R7 U' z3 @5 }
  236. /************************************************************************/) S# L" y  ]8 t  G0 p
  237. /* PROCEDURE: CE_High                                                                                                        */6 }8 T. {4 l, o! G/ u4 c
  238. /*                                                                                                                                                *// }! j, b+ ^) y9 p5 R
  239. /* This procedure set CE = High.                                                                                */1 c! f, Z' Y6 M/ |5 c0 N
  240. /*                                                                                                                                                */
    2 x6 m! x# R5 P; x
  241. /* Input:                                                                                                                                */
    9 h' ~$ q4 h2 }3 M+ y8 c2 o
  242. /*                None                                                                                                                        */# E# V3 K5 e/ p' d
  243. /*                                                                                                                                                */# o& ?9 M6 q. N% M' `2 Z
  244. /* Output:                                                                                                                                */( P3 y0 u) O4 V% r, P. Q8 J7 `0 r
  245. /*                CE                                                                                                                                */4 Q: N! K# W7 @3 A( k
  246. /*                                                                                                                                                */6 _; M& R. ]7 U! @* |9 N& @
  247. /************************************************************************/# K3 j) [3 d% C3 y8 k# p
  248. void CE_High()
    ! F3 C; }+ r1 \3 M2 n
  249. {
    / g; w7 I) M6 [
  250.         CE = 1;                                /* set CE high */
    ) Y' X- M  X2 n  Z! d5 x/ I- @
  251. }& `1 q% ]( B5 k  j4 ~5 E+ `

  252.   g7 u% T, \. F) \# f
  253. /************************************************************************// Z0 B8 V9 P4 E6 i' K8 D
  254. /* PROCEDURE: CE_Low                                                                                                        */
    , r4 x, m, A- W( g2 P$ D/ a
  255. /*                                                                                                                                                */
    - U+ k4 O8 Q8 C1 R# g
  256. /* This procedure drives the CE of the device to low.                                          */
    . l9 h4 T! N+ }8 `$ Q
  257. /*                                                                                                                                                *// r* |; b1 X3 T. K# X
  258. /* Input:                                                                                                                                */0 r, |- s* d, d/ |& r4 H& t4 J
  259. /*                None                                                                                                                        */
    + Z) T5 E0 Z& ~7 g/ X
  260. /*                                                                                                                                                */
    0 B' h+ @2 C2 c8 c6 u4 r2 T
  261. /* Output:                                                                                                                                */: Z* F/ u9 B" a9 k  t  ?
  262. /*                CE                                                                                                                                */
    : r1 m: y, u- v' d6 Q4 ~% M' o
  263. /*                                                                                                                                                */
    ! w+ R1 o! F# r$ T
  264. /************************************************************************/8 S: P5 h7 Y" W0 ~
  265. void CE_Low()
    4 `9 P& w+ C7 }
  266. {       
    : I2 H' @# N6 V4 n9 O
  267.         CE = 0;                                /* clear CE low */3 M1 |4 E5 @6 G
  268. }2 P5 X: f, B, A( r/ h7 P3 t. \: v: v
  269. # B9 f) n4 c. |: L
  270. /************************************************************************/' k2 _9 y6 Z8 ]
  271. /* PROCEDURE: Hold()                                                                                                        */! I2 B. F0 e$ s# {- O
  272. /*                                                                                                                                                */) R% `" d/ j! f% ^- X  D* s* |
  273. /* This procedure clears the Hold pin to low.                                                        */
    7 m/ Z2 L4 I  _- G! K
  274. /*                                                                                                                                                */& y  i4 ~( O1 V. W
  275. /* Input:                                                                                                                                */  ^4 R+ j- \. F  L: D4 `
  276. /*                None                                                                                                                        */
    1 z( X1 I' U  i% t- o4 h( W
  277. /*                                                                                                                                                */
    & ?/ b. p5 S! h& s
  278. /* Output:                                                                                                                                */' O! c# B" O8 \! x  y7 t
  279. /*                Hold                                                                                                                        */
    8 p; z* t9 w3 N# S# N; Q
  280. /************************************************************************/
    % K7 A: K: q; U8 q' |1 s5 ~
  281. void Hold_Low()' ~) E3 x0 \, o1 g0 @0 F
  282. {" l& _; v0 }( W) l4 J
  283.         Hold = 0;                        /* clear Hold pin */4 e8 Z( ~6 Z6 V& ]/ A, ?. B, _* H4 K
  284. }
    6 ~" a6 ~1 A" p1 r- o# n

  285. 6 t+ k, ^' w0 b
  286. /************************************************************************/& D1 ]! X  b. Z4 F) p. [; Q
  287. /* PROCEDURE: Unhold()                                                                                                        */+ V: N' y! s$ f/ }7 y5 f( t7 O- Y
  288. /*                                                                                                                                                */( i* {3 L' ~0 u) N
  289. /* This procedure sets the Hold pin to high.                                                        */
    6 h0 b  F9 L* o" K- s
  290. /*                                                                                                                                                */
    " d- E+ i" ?3 V5 o! T
  291. /* Input:                                                                                                                                */
    % ~: [8 g6 q, p7 }; }
  292. /*                None                                                                                                                        */
    " S; O! z7 W1 V, p# \
  293. /*                                                                                                                                                */2 s+ h9 u' H6 z3 T
  294. /* Output:                                                                                                                                */
    5 L+ ^0 c5 F# O# g1 a: p: G7 ~7 D
  295. /*                Hold                                                                                                                        */1 ]: [4 [$ N  a1 d6 J
  296. /************************************************************************/
    3 I: |  {; k  Q, v0 a$ ?0 |3 }, D% i
  297. void Unhold()
    9 L' h2 `8 Y) Y9 \& O$ P3 K
  298. {
    ) x, D$ Z. u2 |+ o" b( G
  299.         Hold = 1;                        /* set Hold pin */
    1 m/ s' ~- ]; i' G- c3 H4 z. P& T
  300. }
    ! P+ @, Z% _1 t6 }8 P+ Z6 c; F
  301. 1 F, H+ x' {0 t. p$ R( c1 f
  302. /************************************************************************/
    " e" M* [8 ?7 v6 k
  303. /* PROCEDURE: WP()                                                                                                                */+ P, p. }4 u) x! d* x
  304. /*                                                                                                                                                */
    : G* h7 Y+ h$ Y' \7 {
  305. /* This procedure clears the WP pin to low.                                                                */$ H3 c" j9 |: e; A7 S+ H
  306. /*                                                                                                                                                */4 {/ W: u" ~: v8 t+ }
  307. /* Input:                                                                                                                                */
    4 k& g* x( f- j9 E+ m6 H
  308. /*                None                                                                                                                        */
    9 M) V% J$ e' M8 Z
  309. /*                                                                                                                                                */
    & d" g! v6 y0 r5 n
  310. /* Output:                                                                                                                                */
    ! d7 G$ M/ P2 z
  311. /*                WP                                                                                                                                */
    8 G$ S( j" g2 ~3 e
  312. /************************************************************************/
    ; ?# `7 x- \1 A
  313. void WP_Low()
    4 ^! [0 x/ j, p7 a
  314. {
    & k( a, ~( C2 p2 ^# |
  315.         WP = 0;                                /* clear WP pin */
    , G. B6 h5 Q) J7 z: |) ]. O* m1 m
  316. }
    . T# }; L, g" X& }
  317. # A# l' U! o- c, x. {5 _& J+ i
  318. /************************************************************************/: @/ U" ~4 o- y2 n- l6 e
  319. /* PROCEDURE: UnWP()                                                                                                        */
    5 X# j& p: Y$ X+ Y2 f
  320. /*                                                                                                                                                */
    + J% U, C/ C# F3 w& P
  321. /* This procedure sets the WP pin to high.                                                                */
    $ q, h( k. L0 j3 m1 k
  322. /*                                                                                                                                                */: U0 K) F, n+ R0 N/ ~2 {! y
  323. /* Input:                                                                                                                                */* J. Q$ \) l4 d8 i/ Z& b
  324. /*                None                                                                                                                        */( b" _, v( f3 v) D' |) n
  325. /*                                                                                                                                                */
    : v; b: {& R( @+ {7 t' a
  326. /* Output:                                                                                                                                */
    8 s- p8 T6 Q8 w* `1 ]
  327. /*                WP                                                                                                                                */
    7 o/ S! I$ W$ \7 p! E) q
  328. /************************************************************************/. {3 ~% _% x+ g- c( f9 w
  329. void UnWP()  b3 B( y6 u+ d4 x& g1 a# L
  330. {& y/ v, \. R; u# J/ ^) k
  331.         WP = 1;                                /* set WP pin */
    / U- R7 j/ J( ^. d& W# V
  332. }! `2 B/ ~0 Z: I" O+ N
  333. 3 l+ V, k# ?2 b( I) t6 m
  334. /************************************************************************/  @1 |4 e2 W/ p
  335. /* PROCEDURE: Read_Status_Register                                                                                */: f! K& |/ I; R, n' F, I
  336. /*                                                                                                                                                */
    , `& O0 T7 g) O4 U
  337. /* This procedure read the status register and returns the byte.                */
    3 P2 O8 M& M1 m: H: k
  338. /*                                                                                                                                                */' Y" p! a' b5 e
  339. /* Input:                                                                                                                                */. _$ S8 M7 a! {5 ~& M0 l' {( Q) N
  340. /*                None                                                                                                                        */
    ; @5 G% A% H4 h8 t* S. _" ^
  341. /*                                                                                                                                                */
    ; @3 X  x9 v; S6 u8 X6 O% g# M
  342. /* Returns:                                                                                                                                */
    8 {& B" e3 U2 \; E  |
  343. /*                byte                                                                                                                        */' s; [8 ]: _& {( ~
  344. /************************************************************************/2 V( k, |* _# e0 }' B
  345. unsigned char Read_Status_Register(), ~' k$ R# O; H; Y9 z* n6 Z
  346. {5 X; m4 U  F, w" J: J
  347.         unsigned char byte = 0;( B' |6 \1 v  d3 \; w6 K
  348.         CE_Low();                                /* enable device */
    + x6 g/ {6 l9 U  u& u, Q
  349.         Send_Byte(0x05);                /* send RDSR command */  I+ L! U4 x3 g7 q
  350.         byte = Get_Byte();                /* receive byte */
    : y) R& [; G# U) M0 a" w
  351.         CE_High();                                /* disable device */, O; y+ [# e* Q: s- J; V
  352.         return byte;, `( w- B& q0 R, f  O# X7 ~: n
  353. }
    2 p0 j$ ?6 L; x: X8 ^

  354. 8 l( \6 }/ |" q* `& C
  355. /************************************************************************/  u$ {  e. R$ P
  356. /* PROCEDURE: EWSR                                                                                                                */
    - [# B* {) q) m
  357. /*                                                                                                                                                */
    ! A) \' k! @6 }; f5 U4 B8 j
  358. /* This procedure Enables Write Status Register.                                                  */
    1 V$ p* o; l+ ]  @! m
  359. /*                                                                                                                                                */
      h6 Q, v4 m4 i' z
  360. /* Input:                                                                                                                                *// a+ h6 W& G" Z" G& Q/ K5 x
  361. /*                None                                                                                                                        *// N! H$ {3 D' w% I9 {1 X9 Z$ L
  362. /*                                                                                                                                                */, ?9 R" |+ B  _5 m$ e, e
  363. /* Returns:                                                                                                                                */7 d$ j. S; D* y7 {
  364. /*                Nothing                                                                                                                        */
    " \! A* n$ |% ?
  365. /************************************************************************/! ^2 n2 ^7 H' {: a
  366. void EWSR()" \7 u% q4 v( o) N$ g" R5 B
  367. {6 D! D8 R/ V/ B  I1 d
  368.         CE_Low();                                /* enable device */& B- x; ^; E, F& o; \) U& x/ U
  369.         Send_Byte(0x50);                /* enable writing to the status register */5 p) R- N. d; ~2 q5 H1 Z
  370.         CE_High();                                /* disable device */
      _7 R' A9 r5 x5 E( ^( T0 j
  371. }3 W: A+ u+ O+ ~7 O% H
  372. 7 _0 n4 @; k0 i# U' m, ?; ^
  373. /************************************************************************/3 A' i* a- d! ^7 t. A  ?
  374. /* PROCEDURE: WRSR                                                                                                                */5 ]7 R0 D. @  v0 i9 \0 f/ J
  375. /*                                                                                                                                                */" \5 r  Y$ }, J9 K0 I
  376. /* This procedure writes a byte to the Status Register.                                        */
    & p. |8 _8 [3 Y; D
  377. /*                                                                                                                                                */: G# |& i+ P! \1 U+ S$ c
  378. /* Input:                                                                                                                                */
    9 L7 {+ q' `- e' j7 Y8 l: r1 u
  379. /*                byte                                                                                                                        */0 Q0 k( ?% a' j4 o, n% S
  380. /*                                                                                                                                                */
    3 Y3 U* o. G, S$ Q
  381. /* Returns:                                                                                                                                */
    $ I# I6 T/ [) y  ?; L5 K
  382. /*                Nothing                                                                                                                        */
    ( `9 s1 k9 O$ K( B2 ~6 H& u
  383. /************************************************************************/5 i- s; w2 f9 n/ k, z: `/ J# Y$ O3 G
  384. void WRSR(byte)
    1 C4 h) _8 {* D/ F  a
  385. {, R0 r0 X& u% I, B4 O2 y: B5 k1 c
  386.         CE_Low();                                /* enable device */
    / \9 q" b# o+ x; R
  387.         Send_Byte(0x01);                /* select write to status register */
    $ o% @! g2 V4 _
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    & k! D0 h( S# V! q1 s  z, H
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ! _: w7 W* V1 |- O. [1 q) A
  390.         CE_High();                                /* disable the device */' C2 n6 c, _  S( L. E& L
  391. }
    ' k1 x# D; c  E4 @! w0 d

  392. ' ^0 z6 N' V6 j
  393. /************************************************************************/
      k0 J' ~* r  {* {6 M# a
  394. /* PROCEDURE: WREN                                                                                                                */4 q+ x: d: S8 I
  395. /*                                                                                                                                                */1 b3 X  N/ s9 v4 m1 P- R2 b
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    7 f$ L2 ]* T4 c3 ?7 B
  397. /* to Enables Write Status Register.                                                                        */5 q: I( G& o3 |0 y" {& [
  398. /*                                                                                                                                                */
    ; W2 ?% H0 \6 z. \  W
  399. /* Input:                                                                                                                                */" H3 A( f5 a5 j+ P& E" B  _  a& f
  400. /*                None                                                                                                                        */
    , N6 q+ o0 }( E9 d3 v( A7 B
  401. /*                                                                                                                                                */( n! p" G% K. N$ v) n
  402. /* Returns:                                                                                                                                */& x3 V0 O; @  N/ @. }- l+ c
  403. /*                Nothing                                                                                                                        */
    / x/ K$ z1 Q2 g* j6 x" U. _7 y
  404. /************************************************************************/$ u( {: M# y' S) t* z% a! p% x
  405. void WREN()
    8 _! _& ~1 a7 k- V1 W  h
  406. {( X) t, h7 T) ^- D: J
  407.         CE_Low();                                /* enable device */* m& ?) T! Y" v; `7 Y/ O
  408.         Send_Byte(0x06);                /* send WREN command */
    ; q/ G  L7 K) }6 m+ r' ^
  409.         CE_High();                                /* disable device */
    " @# O( V. g% v- k: o0 ~6 ~. P& ]
  410. }; i1 ~9 P% }8 p, H& p

  411. ) O' I/ E7 r, l9 N: C5 Z* B
  412. /************************************************************************/
      y% V& P2 w- n8 X7 m8 ~
  413. /* PROCEDURE: WRDI                                                                                                                */
    / O2 L* q* B2 F0 r6 `
  414. /*                                                                                                                                                */. K6 E, i5 W" b+ n' ]" g$ f* t
  415. /* This procedure disables the Write Enable Latch.                                                */
    + m& O% w  c1 Q4 n) |# D  o
  416. /*                                                                                                                                                */% p: w# f2 C  Q, R- n% r0 h
  417. /* Input:                                                                                                                                */$ a/ B" S9 Y& N9 q
  418. /*                None                                                                                                                        */& M5 u' I& i2 \0 l9 p. b7 O% Q
  419. /*                                                                                                                                                */2 `7 g/ X0 h" m% v* ~$ s' w- N( i
  420. /* Returns:                                                                                                                                */) s, {+ W7 s+ I8 Y
  421. /*                Nothing                                                                                                                        */# w2 I) I; F: Z/ }6 }) ]1 g. o
  422. /************************************************************************/2 M0 m6 {- A+ N2 Z$ C+ Y+ ^, o
  423. void WRDI()
    * U& D: x- x% b, Z$ z4 y
  424. {2 A) ^% h- `, a9 c- L
  425.         CE_Low();                                /* enable device */' K0 [- @9 v# a! ^- C5 y7 r
  426.         Send_Byte(0x04);                /* send WRDI command */. f2 r3 u( ~% R% i/ m: A
  427.         CE_High();                                /* disable device */
    ! m( z7 Y/ l) a8 I
  428. }& i, @  ^2 u( d; g7 z! X: u
  429. 0 I3 u) A' s8 w$ C$ D8 j" l4 S4 L
  430. /************************************************************************/
    ' Q& _" S; [" P+ U$ c) t5 t2 P9 t
  431. /* PROCEDURE: EBSY                                                                                                                */; b! j* b+ g+ J2 a
  432. /*                                                                                                                                                */
    $ Y% v+ U" r4 {
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */# V, w  Y$ e. k. |1 E1 M
  434. /* programming.                                                                                                                        */
    9 \/ n4 ^8 M$ J8 ^% @8 X
  435. /*                                                                                                                                                */1 _0 K. u: c8 x, d: d, E9 k+ s: k
  436. /* Input:                                                                                                                                */
    2 p5 p! H$ g( }+ b  ^1 n
  437. /*                None                                                                                                                        */
      G3 z8 N+ I" R
  438. /*                                                                                                                                                */) q) d& P) w" b6 s" _: ^) t
  439. /* Returns:                                                                                                                                */
    6 {: ?4 ^+ L, l/ h$ D4 s3 X( V* W
  440. /*                Nothing                                                                                                                        */
    4 A# @0 _! C; j6 X
  441. /************************************************************************/$ u  |% p3 A3 w9 b' T5 T. @  m
  442. void EBSY()
    ' b5 y& y( A7 X( D0 g  }$ g' \
  443. {) {9 N. p& Z* r/ E
  444.         CE_Low();                                /* enable device */
    + R+ r1 g/ |( B. A- ^, c) }" M' X
  445.         Send_Byte(0x70);                /* send EBSY command */& v8 j: f* e! n9 Z4 x3 j, x
  446.         CE_High();                                /* disable device */8 u: }) ^2 r+ Y, A5 U7 P3 f
  447. }
    8 w. X$ b2 H; _& h2 k4 q) S) q! Z

  448. 4 F4 g4 l: @; T: B4 S0 N
  449. /************************************************************************/
    9 _/ S+ t) x9 p% O3 S
  450. /* PROCEDURE: DBSY                                                                                                                */
    + _" X$ z" s( y
  451. /*                                                                                                                                                */$ J1 A% @* F% ^% ^3 _
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    8 }( Q8 c( W  @1 j
  453. /* programming.                                                                                                                        */  w/ {/ C+ k' ^6 {
  454. /*                                                                                                                                                */# i/ V: ?3 Q& l
  455. /* Input:                                                                                                                                */& b; a9 C+ R$ ~5 T! Y( ?( q+ h
  456. /*                None                                                                                                                        */
    / A7 T  K2 ~# P" f' U( P
  457. /*                                                                                                                                                */! W, |- c3 G: T7 n4 M* f& @
  458. /* Returns:                                                                                                                                */" s: ^8 ~; s$ t1 J; o
  459. /*                Nothing                                                                                                                        */
    5 x% ?* k3 G. F; w" }, h
  460. /************************************************************************/
    ( |9 N) S7 m0 T- f1 e' u0 G
  461. void DBSY()% ^# X+ I! W% s9 ^9 V7 U
  462. {9 v, b3 m( x" j8 ~
  463.         CE_Low();                                /* enable device */* [; u7 J! g7 G$ q  \
  464.         Send_Byte(0x80);                /* send DBSY command */  }( M) e4 A0 `& ?$ y) f# i
  465.         CE_High();                                /* disable device */
    * L5 o# @/ y( T4 t  U# r
  466. }
    $ I# `) m# K( R
  467. 3 ]  k2 m( @4 M; b
  468. /************************************************************************/
    5 b/ N& r& P4 _+ j1 i: `* l
  469. /* PROCEDURE: Read_ID                                                                                                        */
    $ _8 E( q7 h0 J# e# j
  470. /*                                                                                                                                                */7 A8 _+ J0 A/ E  j9 E
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */: @5 D- o! J7 Q; y& G4 J
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    - L# S# c0 O1 B$ D! T! K
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    % r2 P* o8 @! L0 r
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    % Q( G9 t# J* V
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    0 f5 T5 g, w5 X' ?( p- p$ H
  476. /* variable byte.                                                                                                                */
    # p1 f' J6 v& r6 k8 X
  477. /*                                                                                                                                                */
    8 a5 y- `/ L: b7 C9 U0 d
  478. /* Input:                                                                                                                                */
    + K% f% Z3 [6 P' G
  479. /*                ID_addr                                                                                                                        */
    # N; ^/ M6 `& n3 s+ O& Y
  480. /*                                                                                                                                                */
    & f+ r7 n9 k* ^& b1 }8 L
  481. /* Returns:                                                                                                                                */! n$ |. r; `- h; U3 w. P' y' q
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */" o) w1 `6 A7 F9 u3 S1 B, t5 O
  483. /*                                                                                                                                                */# i4 m8 t# C+ x6 p1 c2 ?
  484. /************************************************************************/
    9 f5 A0 k' n7 J4 H
  485. unsigned char Read_ID(ID_addr)( o6 t5 w8 {$ d0 P9 O1 ^! K6 _
  486. {" H  w5 Y- w$ n+ w9 o
  487.         unsigned char byte;: k% f, A: d" Z0 j8 B
  488.         CE_Low();                                /* enable device */6 V, I( n& t, f4 B- X; s4 Y
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */+ c, E* _2 c" u+ `9 _0 k
  490.     Send_Byte(0x00);                /* send address */' Y4 t) m) s8 h+ W% u& b
  491.         Send_Byte(0x00);                /* send address */& N5 g' W- ]" V4 T
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    : w2 }  J9 ]" b
  493.         byte = Get_Byte();                /* receive byte */$ Q9 _' F/ [# K8 t1 z' B: X* ]0 R0 p
  494.         CE_High();                                /* disable device */) C* X6 H# h  @
  495.         return byte;  [( y5 \; }! t& l
  496. }! e  j. b, h; h5 o# |. j6 I

  497. 6 ~3 F8 V1 S9 F/ T4 \3 J* c0 b
  498. /************************************************************************/
    ( k3 R$ m. a2 d6 |/ o. x- |, i
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ( A# X" m4 ?! G3 |" Q# y
  500. /*                                                                                                                                                */
      R% T2 l6 u4 o8 U3 M8 y
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  *// J7 Q" y) c; ]5 y  e# e
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */2 {9 v2 ], U& t+ G
  503. /* Please see the product datasheet for details.                                                  */
    ) w- f9 e2 {6 z5 D& ^
  504. /*                                                                                                                                                */
    + T- `- `* B. S
  505. /* Input:                                                                                                                                */
      J" W2 x3 w% }; A$ ?' o; B
  506. /*                None                                                                                                                        */
    6 i: X! \5 N. o( B2 p8 Y
  507. /*                                                                                                                                                */
    " @1 q5 M* x/ J( C9 \4 @: ~
  508. /* Returns:                                                                                                                                */. g! Q, p, i; U$ L6 ~
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */' v: P1 c( y- E. {! o
  510. /*                 and Device ID (8Eh)                                                                                        */5 Q* \: E: [: {5 q( z
  511. /*                                                                                                                                                */
    # Q5 R$ L& G$ l+ G
  512. /************************************************************************/- g- H$ B- ?: z% k2 M1 l# y" j
  513. unsigned long Jedec_ID_Read()
    0 I% S0 P1 p2 }# K3 }5 R5 M+ q
  514. {; K. Q/ i, }$ k: a; {- Y
  515.         unsigned long temp;
    ; s, t$ X: f" I7 c1 d/ W
  516.         3 l/ x0 s6 p: M4 F) l
  517.         temp = 0;
    % ~" j8 y* \. d0 N) W$ K
  518. , W. \: [  s4 e. ^
  519.         CE_Low();                                        /* enable device */3 G% V% b3 R9 F9 l
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */; R3 N7 Q3 C% e4 ^8 B4 s( I: u& V
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    " ?9 r! O: x! o  r" R, f6 p
  522.         temp = (temp | Get_Byte()) << 8;       
    - K  j: b/ h0 A
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    $ C. l0 M' I+ ?1 q1 v
  524.         CE_High();                                                        /* disable device */# o, t: i8 b/ Q6 O0 j: ]' Q' |

  525. 6 Q5 W) V4 G- H2 m
  526.         return temp;
    ' E7 X7 [; D7 T
  527. }
    3 [9 g2 ?; Q1 d$ {- ?/ }6 C

  528. % q9 \; n- @; j# W) `
  529. /************************************************************************/* R: \3 P5 Y9 C+ N& t3 z
  530. /* PROCEDURE:        Read                                                                                                        */# t) }8 {! T5 S5 U
  531. /*                                                                                                                                                */               
    8 a+ X3 w) ]9 j
  532. /* This procedure reads one address of the device.  It will return the         */8 v1 k, Q/ D: g5 d9 d
  533. /* byte read in variable byte.                                                                                        */
    , U0 A( h1 J8 R5 W+ l
  534. /*                                                                                                                                                */* u$ m2 n' n/ J* b* {% `
  535. /*                                                                                                                                                */
    2 o- V7 ?9 D  H. m( u( O! x
  536. /*                                                                                                                                                */0 s- N3 G5 j; w$ N( P* j) i
  537. /* Input:                                                                                                                                */
    " F, p/ @8 B: |# m3 u4 R
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        *// J* d: _% @3 d% p
  539. /*                                                                                                                                      */1 v8 L/ v, u! W
  540. /*                                                                                                                                                */6 O( H( b# a7 l+ L7 R3 n
  541. /* Returns:                                                                                                                                *// T5 Z9 M4 l* c+ r6 o2 ~) z/ e
  542. /*                byte                                                                                                                        */6 M1 \# i8 P2 s1 i
  543. /*                                                                                                                                                */1 G$ c) u# M9 }2 ]' ?! t
  544. /************************************************************************/8 _  s: C" }# Z5 q$ J8 l  v
  545. unsigned char Read(unsigned long Dst) / k+ a* T4 H( O- {& A8 _
  546. {0 ?/ J% B% z# \" T! _
  547.         unsigned char byte = 0;       
    6 t/ M+ p* q* {: _' y, O: i0 v
  548.   r  @/ d) w* m, c1 @
  549.         CE_Low();                                /* enable device */
    * x: j; F( i1 M9 {5 F$ Y: A& N
  550.         Send_Byte(0x03);                 /* read command */
    * Y9 b' m5 ^& s, S" t7 h/ w
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ! f3 ?  m/ Z& M+ V
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));- P# J# s. ?* a, o
  553.         Send_Byte(Dst & 0xFF);, {- v7 d  J$ w
  554.         byte = Get_Byte();1 G$ d' N2 T: G, r
  555.         CE_High();                                /* disable device */
    : U) `2 x5 x0 ]' n' Z+ L& r
  556.         return byte;                        /* return one byte read */( p% i, q. y1 r) A1 e, H5 o5 b
  557. }; {/ p4 q- I* }  Z: H" F/ ^! b
  558. - `, j( G! U# \0 a% T' G; B' ~
  559. /************************************************************************/
    ) G5 N. T/ M+ W+ a: o5 ^
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    9 h6 `) ]! f8 e2 @$ b6 Z
  561. /*                                                                                                                                                */               
    ( q1 y# B% z* E& P
  562. /* This procedure reads multiple addresses of the device and stores                */
    , I# I# [$ c1 _" `. j$ J2 Q; }) L
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/% x, ^5 ~& x# Q: `$ u
  564. /*                                                                                                                                                */6 o& H" b% h; H
  565. /* Input:                                                                                                                                */
    $ r7 ?# o" ^- I  r  i  W  ]/ {
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : u" v( ?& e7 s- C8 j. {
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */0 \5 D7 F1 o- D. k, M
  568. /*                                                                                                                                                */
    2 c3 C! ~. d2 u
  569. /* Returns:                                                                                                                                */
    " M, I: K6 A! \% q) d
  570. /*                Nothing                                                                                                                        */
    3 c! @' i! N( Z0 p+ u; G! [
  571. /*                                                                                                                                                */9 T& ?3 D: x) a% U9 [
  572. /************************************************************************/" ?9 M3 `  o( I6 D* s$ i
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)( I* n  R% L, L4 d
  574. {
    ) v1 b* L/ e8 l* d6 h. s) T
  575.         unsigned long i = 0;
    ) r, q) T& Z& g3 S
  576.         CE_Low();                                        /* enable device */9 Y; p6 \$ ^# n$ z$ {1 C
  577.         Send_Byte(0x03);                         /* read command */, t6 b0 h* G6 q( c
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* Y/ P5 y9 f0 c5 v
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));5 m2 b1 j4 p3 S7 N
  580.         Send_Byte(Dst & 0xFF);$ n. V; y  n6 f2 g  i
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ( [6 j/ N2 R0 L$ l' O
  582.         {% g  [1 k7 `% d1 B- B! J& ]" l
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */% I) ~, n* K# B, O
  584.         }
    ) |: f2 _/ P' A& I/ `5 J, z
  585.         CE_High();                                        /* disable device */
    8 S+ K2 D. H3 ^) r. V8 i6 C+ [
  586.   ~9 }' F: m2 `' D4 T) P( v
  587. }
    $ |( m4 D7 E1 d  ?3 t; Z' z

  588. * i( P0 X- Q- C4 C
  589. /************************************************************************/2 x( t3 V! P; Z( j7 q8 K
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */( q$ f8 }' h$ v- ], N& f* Y
  591. /*                                                                                                                                                */                4 P  b: e' L: w* _- I
  592. /* This procedure reads one address of the device.  It will return the         */+ H  Z; K" ?) |" r! S! K( `
  593. /* byte read in variable byte.                                                                                        */
    6 v8 q9 a* ]7 K5 ?5 _/ v* q
  594. /*                                                                                                                                                */
    3 w+ F( k4 D! |
  595. /*                                                                                                                                                */5 f9 E; _+ \# P% H: m+ g- l$ c- [$ |1 }
  596. /*                                                                                                                                                */) y% {  p$ O0 Q: Y/ p
  597. /* Input:                                                                                                                                */
    ! x, a9 n; C# w# A0 j7 K
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */1 d/ Y& y9 `' x
  599. /*                                                                                                                                      */6 U0 _" F) |3 H& P
  600. /*                                                                                                                                                */
    9 t3 i" j- F- s: R. A# N+ e
  601. /* Returns:                                                                                                                                */
    0 D% _' x4 ]  k, X1 X3 ~
  602. /*                byte                                                                                                                        */+ l  p  |, z2 J6 g0 l
  603. /*                                                                                                                                                */
    . m3 H  ]) P4 s
  604. /************************************************************************/9 i* H! W- i# U% b/ L
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    ) ^; P" v, w' p2 ~/ N. r* g
  606. {2 f$ `7 v: g" w5 J+ h! J
  607.         unsigned char byte = 0;       
    . H( |5 j7 S0 }$ s

  608. 7 p! `6 [) a+ j1 s/ [
  609.         CE_Low();                                /* enable device */, {: F4 y7 [4 n/ {
  610.         Send_Byte(0x0B);                 /* read command */) P# t) y+ {1 h
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */4 F0 r, T2 U) b9 G  l/ p
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));3 W" f  Y7 J6 `& W8 p, J9 |6 x
  613.         Send_Byte(Dst & 0xFF);# D4 s% M0 M6 l" _% b% E
  614.         Send_Byte(0xFF);                /*dummy byte*/! K' S/ R8 H1 E
  615.         byte = Get_Byte();
    # \( a( y2 q" }; K: A
  616.         CE_High();                                /* disable device */; J3 @- I3 l' Y7 E# A9 W" i
  617.         return byte;                        /* return one byte read */
    & u: T' Y. `) r6 {2 ?
  618. }1 D# V$ Q* {: F% d0 v- `) V( _
  619. % R2 g- h" N  O6 N* N: Z
  620. /************************************************************************/
    : G% }* f$ o: H9 B% {: G& X+ m
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    ( d( ^6 V+ {: h1 |
  622. /*                                                                                                                                                */                " e0 D( P; _/ r6 J$ A
  623. /* This procedure reads multiple addresses of the device and stores                */$ v8 B0 k# g' S- A% W
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    9 q) ^7 T' m5 h$ I+ K. H0 L
  625. /*                                                                                                                                                */! t( G) h, b, D( c  l
  626. /* Input:                                                                                                                                */- L$ O: J" E4 A6 m- r& w
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * V: u. u7 x5 S2 W. H) Z7 X
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ' C, T8 C6 {4 c/ O" B
  629. /*                                                                                                                                                */
      D! _2 l8 A4 S( ]/ o$ \' m
  630. /* Returns:                                                                                                                                */
    ! o& ^1 I; s8 s* A
  631. /*                Nothing                                                                                                                        */
    4 O$ s" a1 A) Q! D% f
  632. /*                                                                                                                                                */* S" C' E# z9 w
  633. /************************************************************************/
    2 u- n* b2 e( N% t1 }
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    2 a4 t, ]' N/ Y! Q  |
  635. {  w: L( y+ I) Z( J7 h6 J" d
  636.         unsigned long i = 0;1 ~& h6 l0 m4 v: B* s
  637.         CE_Low();                                        /* enable device */
    2 W+ S/ _9 Z: ~3 B1 k) T
  638.         Send_Byte(0x0B);                         /* read command */
    ( q. m  A0 ~  ]* ~1 Q4 Q- @! D. j
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    9 j& a8 j( J% F9 ?/ ]
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 r$ V/ s! A9 r6 S- m7 w3 X% O
  641.         Send_Byte(Dst & 0xFF);0 `* `1 F; m& x/ V/ f8 K
  642.         Send_Byte(0xFF);                        /*dummy byte*/& X" v5 ^' g& m: X. l7 c
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */! w/ t; R, B0 u6 }& `
  644.         {
    ' ?! w0 @2 u8 x' k* R  u$ [9 p( T: n
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    0 `7 a, J+ g' O4 e2 a
  646.         }! s' ~" y% f1 I2 B8 g- a% q2 r5 [
  647.         CE_High();                                /* disable device */% |% I2 x: C- @6 W2 e
  648. }
    ! ?! B3 S( f, p# M. R: f/ h

  649. ( n1 _- m& Y, S# ^
  650. /************************************************************************/: j, P% B8 Y  e' N/ F: x
  651. /* PROCEDURE:        Byte_Program                                                                                        */! {1 B( v! L0 I! v: v
  652. /*                                                                                                                                                */3 L( }6 U1 L( m+ \( T$ p
  653. /* This procedure programs one address of the device.                                        */
    , @4 L. g. J: I2 _( H0 s
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 o; a% m( p' K! c  C: R
  655. /* block protected.                                                                                                                */  s9 Q( |5 \- ?1 M/ A
  656. /*                                                                                                                                                */8 m% C. x) j( G* A9 a
  657. /*                                                                                                                                                */8 a" G/ C4 F% y4 C+ ~. [" r$ P
  658. /*                                                                                                                                                */+ y+ I, k4 I  C" u" T9 v
  659. /* Input:                                                                                                                                */+ E% n0 y/ i/ U% k
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) C+ n1 `, w3 h7 @# d$ T+ l
  661. /*                byte:                byte to be programmed                                                                */
    2 B1 J9 Z* p  [! z# P2 G* n( u
  662. /*                                                                                                                                      */' J; Q2 J* u+ Q
  663. /*                                                                                                                                                */
    8 d4 y4 }% |( f: L
  664. /* Returns:                                                                                                                                */
    9 Z  k3 Q2 e2 g0 y/ R
  665. /*                Nothing                                                                                                                        */3 z* ^+ U' z) y/ B
  666. /*                                                                                                                                                */
    4 s: K% Y! p+ R5 S* c( ]
  667. /************************************************************************/% e- o6 o/ p7 C7 u
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    5 e' U. i2 a6 N* `% h. R0 o
  669. {8 |$ v2 g2 l' y2 ?( J
  670.         CE_Low();                                        /* enable device */
    + j. ?7 y8 D5 }2 L
  671.         Send_Byte(0x02);                         /* send Byte Program command */3 @8 Y" S4 R. Q+ ~+ l* }) d
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */7 y2 L2 ]: I' W
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
      {. t8 j) C( K9 Y! i; b2 G
  674.         Send_Byte(Dst & 0xFF);# H3 k+ n# Y3 o! I" i
  675.         Send_Byte(byte);                        /* send byte to be programmed */' U7 U+ ~; g$ Q
  676.         CE_High();                                        /* disable device */
    ' j% o  e# ^0 B$ p1 e" T7 z
  677. }4 d' c" ~# o; O) M; o

  678. 6 N: Q1 I3 x' i
  679. /************************************************************************/
    4 q" `. G% y( ^+ Q4 k
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */  q8 K: u# J: G$ g' L
  681. /*                                                                                                                                                */
    ( q6 n4 @; o" I
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    + y8 w" {. G) X( J" l6 ^+ z
  683. /* the device:  1st data byte will be programmed into the initial                 */7 [2 I! D* M7 r& R2 J6 n4 n" Q+ P
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    8 H7 S" w1 S1 k( r( `5 @; ^& V3 W/ \
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */. A: ]: K- B* |9 n* Q3 L9 ^
  686. /* is used to to start the AAI process.  It should be followed by                 */1 z; L8 K% c, r& i8 X! C: c) _( D
  687. /* Auto_Add_IncB.                                                                                                                */0 h6 h6 x2 J3 m; k1 e
  688. /* Assumption:  Address being programmed is already erased and is NOT        */. k3 x; A# f7 \0 Y
  689. /*                                block protected.                                                                                */
    , V" e; u0 e: Q$ x; f) m; H7 Q
  690. /*                                                                                                                                                */
    2 g# Y+ e+ s7 C: R6 \6 c3 G" k& v: ]3 g
  691. /*                                                                                                                                                */
    " ?8 Z4 \! g- \# _  u
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */6 n) x* Y! T% f1 ]' d1 W
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    " C  L# c0 b: M* K
  694. /*         unless AAI is programming the last address or last address of                */
    & _+ _4 G  P0 d1 |
  695. /*          unprotected block, which automatically exits AAI mode.                                */7 X, H: g2 R  t) E0 R6 T5 z: |3 h7 ]
  696. /*                                                                                                                                                */
    2 S, p8 ?# z5 f. R
  697. /* Input:                                                                                                                                */
    + a9 @" z$ t7 P7 y
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& t1 x4 }/ M& X4 h9 ~
  699. /*                byte1:                1st byte to be programmed                                                        */& ^+ w) y, _- }! a' s$ X
  700. /*      byte1:                2nd byte to be programmed                                                        */1 w! s2 G* }9 Y1 q% S. L
  701. /*                                                                                                                                                */* H6 {$ [$ |8 U7 H# t4 U' A
  702. /* Returns:                                                                                                                                */
    ' o6 V$ `0 c0 M' Z
  703. /*                Nothing                                                                                                                        */
    - a$ w+ P  y) {2 w* `. U
  704. /*                                                                                                                                                */8 I9 `1 [4 N3 X, q
  705. /************************************************************************/6 K9 P1 d! h- G' n# \* J$ g
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    " Y. e6 O; ?4 p3 }6 q* z+ \6 v
  707. {
    " _- q, l) V' s3 i* M5 j
  708.         CE_Low();                                        /* enable device */
    9 W" ~4 W/ ]8 S% P
  709.         Send_Byte(0xAD);                        /* send AAI command */
    5 B9 o) h, ~, W5 v& G) `. C- n
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 W1 `# c! e& u3 W5 [
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));9 V' V( F7 k% E4 q9 g  A# Z
  712.         Send_Byte(Dst & 0xFF);; z! v8 J2 q1 J( p! _. E9 n
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + c, P+ M, K4 `: a6 O5 t9 Y
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */2 \( p6 x* w! B, @7 ~8 G9 i  d
  715.         CE_High();                                        /* disable device */2 c" I' V% i& L+ G; V
  716. }
    / p- w  Y* s& J+ c( Z
  717. " U, {9 Z& |% ~/ o
  718. /************************************************************************/
    % z; x$ e) c. S: n% H
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */# s1 w# }# g: j- G
  720. /*                                                                                                                                                */
    , e+ k  j9 ]8 B
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/) ]9 v( N7 A6 K7 a- K- q
  722. /* the device:  1st data byte will be programmed into the initial                 */
      l0 @% z1 i' [& P  o" o' y" U  g
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ( K( ]" ^4 j# u: D- a* M) n
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    , ~2 s1 o, X- Z" W6 W% ]% m1 l1 s
  725. /* is used after Auto_Address_IncA.                                                                                */
    ' }/ T* Q( G% x0 d" ?
  726. /* Assumption:  Address being programmed is already erased and is NOT        */0 [/ {2 {* t7 F  \2 C4 f! P: I
  727. /*                                block protected.                                                                                */  }0 a: j. L+ [7 b- X
  728. /*                                                                                                                                                */
    " H( Z  a/ p, N; R
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' p* ^* k, X" I1 ?9 z1 u
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */0 m/ ?5 P# G6 o# |/ g  d
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ F4 G" c* ?+ @! r. a- k
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    & {# [; `, K2 K9 \
  733. /*         last address of unprotected block, which automatically exits                 */
    / x6 [$ v" i* j7 Z0 X% ~3 F; G
  734. /*         AAI mode.                                                                                                                        */
    " e0 I! x& Z7 T
  735. /*                                                                                                                                                */
    2 d( d: I  y# P" m" K2 z
  736. /* Input:                                                                                                                                */* I1 Z1 c  e2 _( Y0 X- X
  737. /*                                                                                                                                                *// C* S  P; N) b" G1 V; d
  738. /*                byte1:                1st byte to be programmed                                                        */6 i. t9 n+ B' A# z+ ^( y5 J
  739. /*                byte2:                2nd byte to be programmed                                                        */
    7 M: N2 z& i1 f) X0 R/ ?
  740. /*                                                                                                                                      */
    : O4 o# Z* c% ?/ u6 \
  741. /*                                                                                                                                                */
    & R% A- c% D, L8 r% |/ l4 D
  742. /* Returns:                                                                                                                                */) B* B5 D" G: k
  743. /*                Nothing                                                                                                                        */
    0 U- D* A- k# Y
  744. /*                                                                                                                                                */
    8 E/ O/ `" V. _, C" u
  745. /************************************************************************/: o% U) q. _9 Q# ^2 ]
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)8 b5 @, x: h' f# R
  747. {
    4 G3 h5 L1 x2 h$ c  b& m
  748.         CE_Low();                                        /* enable device */
    - m5 C$ h1 ]8 n* I7 H( o
  749.         Send_Byte(0xAD);                        /* send AAI command */
    & {' ]: p4 c' b9 E9 g) _
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */  U8 Q, L3 Z/ h3 @( @& q: m6 V3 A
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */( h2 q5 X1 t' `; \4 p/ }1 _
  752.         CE_High();                                        /* disable device *// o$ |# p, I- v" E# j) |& m
  753. }
    - A9 l) B1 E: @: @8 m

  754. $ {: }0 F) K3 y
  755. /************************************************************************/" I/ ~0 a, a$ \: y, f: b3 F" R$ M
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    + I8 M9 H1 y4 y6 B  T) V
  757. /*                                                                                                                                                */
    9 n/ J0 K1 u9 H
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */+ p7 |2 B2 C, I
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    1 W$ b* S. H6 i" T' y
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    4 s% U, M) x2 c2 Q5 z
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */! B9 E7 e! l$ o) p) x
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */% c( W7 v: y9 \7 X) b% q
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */0 ~) W! u% R2 i" |6 ]+ w
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    : @9 ~, }0 {* h! ~! h! I0 G
  765. /* Assumption:  Address being programmed is already erased and is NOT        */5 z' u! j7 Z8 |
  766. /*                                block protected.                                                                                */
    1 @9 U# W" [# R; e
  767. /*                                                                                                                                                */
    ' `+ _( T' @3 z  _7 t0 g
  768. /*                                                                                                                                                */
      D, L' [" a% D4 s6 h
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */. N) _  u, f0 d
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ( _" N7 X, B9 ~2 R/ h' b
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */) _: L/ z; P8 y
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    . \( b7 k5 G& t9 q# S
  773. /*         last address of unprotected block, which automatically exits                 */
    ' X8 v' [) C4 R. h0 U: p" i$ C
  774. /*         AAI mode.                                                                                                                        */
    5 Y; N% X4 F! f5 {6 \: }
  775. /*                                                                                                                                                */* ^' O4 f5 z1 `' N% e  U9 C
  776. /* Input:                                                                                                                                */4 [9 e% G, i; T! p* A# R
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 T% u( D/ Q0 b5 y0 z" \
  778. /*                byte1:                1st byte to be programmed                                                        */" p" X; _3 {0 e5 d
  779. /*      byte1:                2nd byte to be programmed                                                        */# `; A- x' `. F3 b3 t) W" h
  780. /*                                                                                                                                                */
    " f* X5 u' T/ x: O" z
  781. /* Returns:                                                                                                                                */
    + I$ N3 u8 A* D; O1 c2 i+ z, `
  782. /*                Nothing                                                                                                                        */) t+ Y4 }+ b3 `( A; s  _/ z/ y
  783. /*                                                                                                                                                */0 T- l. }7 m" @* h' g+ A  a: a
  784. /************************************************************************/1 E" N* B; V$ k7 M; Y
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    6 F2 \. U: s1 j
  786. {
    7 R% Q3 v; k9 I0 s1 x" r0 i
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    - J" M: B/ A( y  d/ _
  788. 1 Y: A' z( C) N2 B& h
  789.         CE_Low();                                        /* enable device */
    * `' j: h' `! t( @
  790.         Send_Byte(0xAD);                        /* send AAI command */+ R$ h( K: V# _# Y1 S
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 s- ^1 x5 P& ^  ~& f$ d
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));5 r1 X3 }; s* d6 F
  793.         Send_Byte(Dst & 0xFF);
    5 r% C1 B2 k9 ~- n; o, l& z  X
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        3 z- q8 Q9 n* ~9 I' A6 W
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    8 T( d/ o' B1 N9 ~- Z! l3 }
  796.         CE_High();                                        /* disable device */" s/ g+ V  \+ P6 N# I+ s9 w
  797.         ( n# I3 N- V% ?
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
      \& U% C- b, f) m4 h+ y

  799. 7 x( b% M# ~4 Q, m
  800. }
    9 Z% m1 e$ v' Y$ b
  801. ! R) L5 S% g% S% ^- m
  802. /************************************************************************/% Q! x! U& G4 v: i- f* L+ D
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    9 N! J! P" h, L. h
  804. /*                                                                                                                                                */
    ; ^+ S0 O$ Q$ ^" t6 l' s1 s
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */* [6 p5 [: C' m' Q. ^( I8 M; k) o
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    ) ^& R' n: ]' C
  807. /* AAI programmming is completed.  It programs consecutive addresses of */$ y# C0 r/ b& h% G
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    0 t) q8 u) w' K/ C. j$ i
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    " I+ N/ L  G6 A' [# ^% k* a
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    " K" N4 `! G5 L$ T/ C
  811. /* used after Auto_Address_IncA.                                                                                */
    5 r. {) m$ ^" _2 E
  812. /* Assumption:  Address being programmed is already erased and is NOT        */7 i7 p6 g  e. N2 J" |! `, h, b
  813. /*                                block protected.                                                                                */: g$ d0 m4 O. d- A2 P8 _
  814. /*                                                                                                                                                */7 J3 b1 [$ ~# v+ O  T, p2 ~
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */8 p0 p4 J, c( n! i( f
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    3 T! R# I5 l% J2 N' p, b1 t
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */2 N7 n1 D4 P$ o& y* Z  U
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    5 q' u  [, _+ U! O; G7 N6 |5 V, T
  819. /*         last address of unprotected block, which automatically exits                 *// j9 O# ?0 Q  Q
  820. /*         AAI mode.                                                                                                                        */1 l" J6 N; [0 i8 `. z
  821. /*                                                                                                                                                */
    . \, i2 @/ c! y, v
  822. /* Input:                                                                                                                                */
    6 i+ {2 m3 f6 J# ]$ y
  823. /*                                                                                                                                                */
    ; E- S$ A, s  e* Z5 \) s
  824. /*                byte1:                1st byte to be programmed                                                        */. L7 x) v+ h7 b0 P! x; C
  825. /*                byte2:                2nd byte to be programmed                                                        */
    * ^# ?0 N( n1 d+ N3 e# @
  826. /*                                                                                                                                      */
    9 O# Q" j4 l! C- P3 P. c
  827. /*                                                                                                                                                */
    - Y( T3 S% W5 m3 d4 a! Z0 X: x& e6 j
  828. /* Returns:                                                                                                                                */6 D/ P  S* R# Y" F/ Y8 D
  829. /*                Nothing                                                                                                                        */
    7 W8 S$ y: p0 U3 s
  830. /*                                                                                                                                                */
    9 V) i' j( Q3 }9 k# }$ D" |
  831. /************************************************************************/
    # K7 B7 {/ L" Z0 X3 N
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    3 U- x* z# X$ b) s, A5 S
  833. {! i; ]8 y; n: Y$ M" [
  834.         CE_Low();                                /* enable device */3 }$ E& u1 u( ?% _' A# m6 a: q' }
  835.         Send_Byte(0xAD);                /* send AAI command */
    " s! i5 R0 N! u" V
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    8 U/ {3 x  i- S
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed *// ?9 ?/ T3 V4 L1 G  Q
  838.         CE_High();                                /* disable device */
    3 K. a5 t. y7 `- Z5 X
  839. 9 L  M  x; z7 ~3 I
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    * I' R  |- x0 W" s7 Z# G* w" }

  841. 7 L/ r* u# `; Z" j! S6 ~' k, V* s
  842.         WRDI();                                 /* Exit AAI before executing DBSY */! T  k# ^* r. ]! y
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI *// W/ i: v5 G$ I+ W4 E' z( T+ G
  844. }
    ( t9 q4 W/ K( Q" R
  845. 3 M" G5 y: C  T. ?* R- G
  846. /************************************************************************/( ?) ~0 i) c0 Y( b. l( o
  847. /* PROCEDURE: Chip_Erase                                                                                                */8 ?. g! \3 G4 u: g5 E* n; R/ m( |
  848. /*                                                                                                                                                */
    ; C$ I: r' R( }8 Y- N
  849. /* This procedure erases the entire Chip.                                                                */
    & ]1 Y* @8 V% R0 l2 j% g
  850. /*                                                                                                                                                */( A  w3 K: B" k3 b
  851. /* Input:                                                                                                                                */
    1 V* \( c6 i5 j; b3 y( c& k
  852. /*                None                                                                                                                        */
    9 ^( i9 s- c# B" A6 r4 b5 X
  853. /*                                                                                                                                                */
    ; L4 y/ d% L2 k9 l" H
  854. /* Returns:                                                                                                                                */
    . |$ I; Z0 ~2 e. R0 T' o& j
  855. /*                Nothing                                                                                                                        */: q4 b* L* r) t7 e9 w5 C
  856. /************************************************************************/8 Z5 {' C* m( L4 }! O
  857. void Chip_Erase()( X7 G* y. v. f; g# m7 O
  858. {                                               
      i0 o" X* b+ @- W2 D- A6 m/ z8 ~
  859.         CE_Low();                                /* enable device */
    : g$ d+ g; y5 V7 o
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    9 C* Y% i5 j" f" \9 _' d
  861.         CE_High();                                /* disable device */
      z$ v. I8 k% v$ f
  862. }
    8 c+ P( ]! j5 f6 J3 i4 f# h

  863. , h# r1 O7 G' h9 p, ]" [2 h2 i" x
  864. /************************************************************************/9 V* l+ m8 r: A8 T' a
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    - m4 ?! _% V0 G# x/ D
  866. /*                                                                                                                                                */5 C% U0 ?* A. {  H& U
  867. /* This procedure Sector Erases the Chip.                                                                */
    # e) H5 I) h9 U7 j1 u1 {9 b
  868. /*                                                                                                                                                */
    $ G/ d( t+ `# ~
  869. /* Input:                                                                                                                                */
    * l, L/ w4 X, i
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 s& H! {4 }/ S
  871. /*                                                                                                                                                */7 H' `3 C+ a9 N$ i' Z
  872. /* Returns:                                                                                                                                */
    # |' n5 v+ F2 o) [9 M# X
  873. /*                Nothing                                                                                                                        */
    6 i, v$ |7 a. M5 H* f
  874. /************************************************************************/
    5 K! l: _; d# x7 W
  875. void Sector_Erase(unsigned long Dst)
      h0 |% T& y3 |' ^
  876. {5 u6 l7 `) }* ^% S0 }

  877. 8 Y5 n( u% l2 l( ]
  878. , s! v/ s9 R. ]1 t
  879.         CE_Low();                                        /* enable device */( ?* h& O) y2 i9 D
  880.         Send_Byte(0x20);                        /* send Sector Erase command */' F. A+ J0 p3 [, W2 w
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 A4 W+ P" |/ R( M9 `+ J8 \! L7 l
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));% K+ @) r8 A' x
  883.         Send_Byte(Dst & 0xFF);% S* G; d# f: d9 t( n' i8 ]
  884.         CE_High();                                        /* disable device */4 F- S8 e( s+ w) X6 A, Q  m
  885. }       
    & M3 c2 p. j8 K6 U: b
  886. 1 m3 g+ Z- f0 A- i( S6 K$ @: ]
  887. /************************************************************************/7 Q$ Q# x+ l4 P% {4 a
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */" Z" l& E& C5 d+ U6 R' I' z
  889. /*                                                                                                                                                */; n  `9 s* ~. D+ N' `' D3 U4 o8 ?
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    9 P& T& T' K. I" }7 }" t
  891. /*                                                                                                                                                */
    5 I* y0 S2 d2 P$ u, o
  892. /* Input:                                                                                                                                */
    & _- T, }( M  H/ u% O6 ?; X
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 v9 H8 @/ S+ V
  894. /*                                                                                                                                                */
    " }  N$ B7 P7 l3 _
  895. /* Returns:                                                                                                                                */
    8 q; v) H$ K2 e+ ^, Z; R
  896. /*                Nothing                                                                                                                        */8 P5 h3 l& G) ]6 F3 H1 `
  897. /************************************************************************/; G1 Q0 u* ^* a  v* I4 K
  898. void Block_Erase_32K(unsigned long Dst)5 w8 Q6 h" v; b4 p/ Y
  899. {- o  r) Y4 E5 D6 `
  900.         CE_Low();                                        /* enable device */- r; ^" p4 T) s$ g: U* h: ~! k
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */% z+ E0 V4 J2 S5 ?+ d) Y. Y
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 s0 ^+ U& Y  b# Q: ^8 j1 A
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) e$ C: L8 r- p; i2 x( J$ s
  904.         Send_Byte(Dst & 0xFF);
    ' k4 c# e1 w9 B5 T0 n
  905.         CE_High();                                        /* disable device */' W% b; n  ?) ]: L/ C6 d
  906. }
    5 h/ N/ Y: S' Z1 f/ z
  907. 3 y9 \* f! F: I5 g
  908. /************************************************************************/
    2 Y) V5 b) [! M: \$ z7 u
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    / N6 y: L. w$ }
  910. /*                                                                                                                                                */* g% Q( C. T3 g& o" I
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */& m/ R! L. B7 u8 C; G+ G
  912. /*                                                                                                                                                */' v& y$ }* R7 n
  913. /* Input:                                                                                                                                */
    2 v4 j, m1 _8 X8 Q) t
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , B3 D; s0 \0 \4 i+ I
  915. /*                                                                                                                                                */
    3 k1 b, I+ Q9 G! H" P4 C
  916. /* Returns:                                                                                                                                */: u5 E/ n8 L/ @$ N  v
  917. /*                Nothing                                                                                                                        */
    ) a4 S& `) W: x3 B
  918. /************************************************************************/
    2 N" |7 v  i8 v6 a+ G2 F4 E# i
  919. void Block_Erase_64K(unsigned long Dst)7 p0 R  g2 l8 _: Y& B8 w+ r
  920. {( Q, j9 ?" @1 I$ d$ }, R
  921.         CE_Low();                                        /* enable device */5 x: E! a9 o$ d7 ]6 V( j6 R& k
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    " H) Q) S. K  Q" y4 G
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */- p9 t( H: T$ d2 I  z% ^. l
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));8 Q! A( X% g6 h6 v4 Z+ k
  925.         Send_Byte(Dst & 0xFF);
    8 m, i' u3 ~( X
  926.         CE_High();                                        /* disable device */
    . t8 H0 K. K, q; q9 h
  927. }
    $ E: f4 }9 G2 W' l9 }. }

  928. % m. I/ @! W5 [  `% R5 n, n" ?
  929. /************************************************************************/- w' x5 ^5 Q: T1 J* C5 h7 t8 ^
  930. /* PROCEDURE: Wait_Busy                                                                                                        */3 d+ Z. U. @* _
  931. /*                                                                                                                                                */
    9 u; _4 L/ O9 D! a: ^; A
  932. /* This procedure waits until device is no longer busy (can be used by        */7 F6 }3 p" l5 o& p. V0 n
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */" J( y0 B5 O' y* v
  934. /*                                                                                                                                                */) }# T" c, d/ m8 S3 y+ m3 X
  935. /* Input:                                                                                                                                */
    4 C2 a5 W4 U2 M5 m+ B
  936. /*                None                                                                                                                        */& M  k0 H. A5 n
  937. /*                                                                                                                                                */  U0 m- z0 @: d4 C6 E- x
  938. /* Returns:                                                                                                                                */8 K3 ~1 x0 C1 H
  939. /*                Nothing                                                                                                                        */4 Z" o) m4 Q; l2 }3 i
  940. /************************************************************************/# d8 D% v* ^  r% ]; U. C
  941. void Wait_Busy()
    9 S& O. A. A  a. o0 i. d! i* `) l2 z
  942. {8 }( H4 P* j; H. U' ~  U3 u
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    * U! X5 Y: S5 P( \3 a' z
  944.                 Read_Status_Register();9 M8 S" t0 w" l- x" u* ~
  945. }- j9 Z4 s$ b  p4 D
  946. " c7 e% F- z, V8 H$ c5 S
  947. /************************************************************************/
    & }5 b* I" v3 z/ W1 X  }$ O+ i: n
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */" a' N0 q) E; j+ J: U4 L
  949. /*                                                                                                                                                */
    4 D0 j- _* F" M5 f# Y' l! {
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    0 H$ A: y5 s4 V9 L7 R" j
  951. /*                                                                                                                                                */9 D8 z, n2 r7 D. s! S- P) l
  952. /* Input:                                                                                                                                */
    7 b+ ~( k' L4 V$ a6 \) r
  953. /*                None                                                                                                                        *// K5 }; P5 w. j# v5 L
  954. /*                                                                                                                                                */' r: k! g5 e; e0 U1 I
  955. /* Returns:                                                                                                                                */: _! @/ S% i0 F
  956. /*                Nothing                                                                                                                        */
    ' I! j, k1 E9 ~: Q
  957. /************************************************************************/
    8 \& Y2 u0 T' M: y2 t- m9 j9 P
  958. void Wait_Busy_AAI()
    $ _; j8 G0 X3 v" G- |5 L
  959. {  X) G  S8 f' r" S0 s1 @
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    9 ^- l: Z5 ?  h
  961.                 Read_Status_Register();
    3 q" n4 D# V1 b& [* n' N9 A! p( ?
  962. }9 m7 n, x6 `" _* F4 X
  963.   i6 m. S7 m3 k  L
  964. /************************************************************************/8 I7 H6 s8 L0 ], \
  965. /* PROCEDURE: WREN_Check                                                                                                */
    # ^( S( J' @* K" Y- v* z. }
  966. /*                                                                                                                                                */
    ! c- I5 X0 E( H6 \, n
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    3 b% I. K% a9 e. Y
  968. /*                                                                                                                                                */6 t+ |* D# t, U7 s) [
  969. /* Input:                                                                                                                                */
    ( o0 p* {% j& t0 T
  970. /*                None                                                                                                                        */7 M8 l# A0 @) f6 v  A- ~
  971. /*                                                                                                                                                */9 H" T/ u% U% r( i- T9 _6 ~+ S
  972. /* Returns:                                                                                                                                */# j7 E& X8 g5 z! H# g4 X, A' {
  973. /*                Nothing                                                                                                                        */; g; c* }2 R: N. Q' V1 |& g
  974. /************************************************************************/
    9 O' C3 Q; A4 _6 A# l! U
  975. void WREN_Check()' `* S7 @! K/ q
  976. {
    ; F5 r: ~- y9 M# ^7 g+ I
  977.         unsigned char byte;3 t/ A: I; V" a6 |/ P
  978.         byte = Read_Status_Register();        /* read the status register */3 L9 g1 ~% E- F; ]1 v- E
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    " h8 S$ z9 e/ p  o: u; Y* A
  980.         {
    + G6 u8 F/ f6 F1 x, R0 a* a
  981.                 while(1)7 L; [5 z" H, N# b2 D1 o
  982.                         /* add source code or statements for this file *// [1 a% F: p( V
  983.                         /* to compile                                  */
    : W; u1 W! z3 ?" j. U4 v) A  h6 n
  984.                         /* i.e. option: insert a display to view error on LED? */0 ~, b3 [6 B; R/ F' s
  985.                  
    ) ?1 `2 V$ e! f% H: n
  986.         }1 W: z0 ^# S8 W) J2 U9 Q
  987. }
    0 e' ~# A8 I: `

  988. 2 k- V( g) A8 p# @" ~- z
  989. /************************************************************************/1 U* p) |( j1 @9 s* `2 X1 F& s6 v
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    7 J- O- R4 r4 k7 w% Q
  991. /*                                                                                                                                                */8 Z- ^" d7 A5 o1 o; ^( C! u& F
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */4 P' _3 D8 `6 k4 U* q
  993. /*                                                                                                                                                */; m0 v9 e! Q7 q7 @5 J
  994. /* Input:                                                                                                                                */* ~, O" W5 g) Y, ?  B
  995. /*                None                                                                                                                        */
    2 {5 ?3 r6 M) s( a4 P
  996. /*                                                                                                                                                */* t  S: U* G2 Q) f
  997. /* Returns:                                                                                                                                */
    1 v$ X0 k" t2 v) K  Y$ w+ d1 ]
  998. /*                Nothing                                                                                                                        */( O0 Z( h0 C) t( D& V9 \& ?
  999. /************************************************************************/
      t8 D: f: b9 T$ d( z- z
  1000. void WREN_AAI_Check()$ X0 T# l$ U% `2 Z4 f6 V
  1001. {
    ( e5 x8 d7 D; n& z4 V/ G
  1002.         unsigned char byte;6 i, B+ x* v6 k' N) P0 K+ I/ V( J
  1003.         byte = Read_Status_Register();        /* read the status register */0 I4 X" J1 O" ~( R
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    1 y2 D! E* T1 \" D: p# U; P$ s
  1005.         {) Z$ o- U! q2 T  `) i; O: d% p
  1006.                 while(1)               
    / b9 _, a& O% e
  1007.                         /* add source code or statements for this file */
    5 L8 G/ |' V7 `# {  ^7 I
  1008.                         /* to compile                                  */
    1 ]6 e& \9 T# ^4 l+ H
  1009.                         /* i.e. option: insert a display to view error on LED? */4 F! P4 F$ S4 X3 U1 K' |% R5 A
  1010. : r' c7 O/ N5 z
  1011.         }
    6 y* x& T9 u7 S2 E' }$ L7 G" u, m1 }& X
  1012. }: f9 n1 C2 ?0 k& o

  1013. 4 D, ~: M  s, u! N7 f6 x2 u
  1014. /************************************************************************/, ]" ?1 f9 s: X. Y: g) L" y& x% |8 J
  1015. /* PROCEDURE: Verify                                                                                                        */
    ; i* h9 y. o8 ^0 t, g( W
  1016. /*                                                                                                                                                */
    9 K+ b" S7 ~3 P( C: J0 i8 G
  1017. /* This procedure checks to see if the correct byte has be read.                */
    & @# q% u( b* W9 s
  1018. /*                                                                                                                                                */
      `: a" x! U+ @4 K" d0 U& _
  1019. /* Input:                                                                                                                                */
    8 @# V9 j& U4 d
  1020. /*                byte:                byte read                                                                                        */
    5 K2 E: h* L% ?& w) W# ^2 h* M
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ) O3 q. e' D' l) e. s
  1022. /*                                                                                                                                                */
    : J8 X. `4 r! [% p) E, l# n) P
  1023. /* Returns:                                                                                                                                */
    7 R- f6 C" O/ F# F  w& M
  1024. /*                Nothing                                                                                                                        */
    ! P' X  j; |1 l9 G) e
  1025. /************************************************************************/! J( ^7 l; Q9 b
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    # l: J+ h1 ?7 N, c% T5 n. _9 m7 K+ `
  1027. {+ F6 b; z! Z; J. ^  G
  1028.         if (byte != cor_byte), ]$ _0 Y# g2 i% J4 n7 O% x
  1029.         {  }; @$ f+ e/ |" z- b
  1030.                 while(1)6 L7 k, m) `) H  w! e# y1 G* R
  1031.                         /* add source code or statement for this file */
    1 j/ C. F5 i2 F  v7 h6 C4 `
  1032.                         /* to compile                                  */
    4 e% d. u; j) B4 I+ I% p0 ]8 p
  1033.                         /* i.e. option: insert a display to view error on LED? */( e* u- v( G$ Y* E- l% U
  1034.                 6 a) H5 M1 E' |  }  ^/ n
  1035.         }# g3 |: Y2 N0 U+ u9 ?
  1036. }2 x) ~# ~4 M; R. j
  1037. , t7 A+ Y( r2 G+ p6 R* e6 ~8 b2 V

  1038. + z2 _2 i; p, b& B5 L8 Z* s- y; l, m# f. j
  1039. int main()
    . G  x, \3 Q: _+ q$ E7 ~8 q
  1040. {
    + o2 ]" C3 v* ^% g- V( Q
  1041. % ~3 U) T, `9 @5 p
  1042. return 0;
    0 o- V* B9 z  u- Q$ m( T) z. e' X. C
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:4 T$ t. m  q$ Y0 u) Z2 E
   main()  J2 V- P* g, @& J0 F% u
   里面怎么是空的呢?* p" L' s) S( f7 Q3 k$ W
   发一份给我吧0 I7 P/ P; S& E; U
mail:luyijun2005@hotmail.com5 K8 p" S3 s& f& `  c7 }( W' r
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
' r, X+ T/ Y3 v) H3 m0 [+ G$ M+ A4 R8 b; b
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
3 `# q' Z  n8 t) ~! u. v! r0 P. W, u$ eEC的代码在哪跑,你看DS的说明,每个EC都不同的。
) @6 ~6 _# X5 h8 s5 j! M/ fOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?0 c/ o1 g! v6 m) p* x& O
上面几个问题是你没看任何东西而白问。1 G2 `" n# @3 T. A

( o5 g7 k' K: N8 C' s! ?' s& \; A至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

! x8 [% Q' U2 w" ]5 j; |' N+ J关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
# y. z$ ^6 A0 z' U* |0 X" Z% K
9 f  Y. F0 ^0 X" g$ z+ Q: |$ i& I5 |关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”: Q9 Y+ O" v$ e
. u+ H8 e* w; \1 E$ @+ b
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
9 T9 Q6 @# x- T) l/ [5 @* y4 R7 Z" ~, h
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样$ ^8 F; ^, J& f7 e# f5 }/ Z
似乎要把SPI能support 到最大,这EC chip应该有好卖点% S' s. T, F* L* H( J8 Y/ ?; W6 L0 W
BIOS功能要不要强大,也就决定了SPI Flach的大小
0 W+ o- V( H/ w: ^$ ?/ V; t我是这么想的~让OEM去决定要挂多大!
2 U2 U( E, a. l5 s0 S/ l  q7 b如果我司有BIOS工程师就好了~哈- u- J/ m/ t4 p3 F; ]1 p" K) v
WPCE775应该算很新的东西,来看它支持到多大?
6 |8 Y+ h, _& H1 V) N( H" }# G1 @' p) A3 ^( u- A5 E7 R
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte# O1 r2 |( _& u! D
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.# y8 N6 S, M( D( a
2 h4 n5 a& E8 ]* w
这份driver收下~希望以后有用到
' e' s7 |: N" w' w6 }谢谢bini大大
. C! v) I3 v3 Q/ z9 `
1 F9 t: c' n" u4 L/ ^很新很新的新手,如有错误请指正 (准备看第二家的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()
, |) L" t" [2 H, X$ Z{
! v7 t7 }: N+ ~$ X8 b' \: V! M1 q        unsigned char temp = 0;2 L. ^4 e+ R% `, T; {, D1 C
        CE_Low();4 T1 H" ~: C) C1 b- q' |: k3 J$ j
    while (temp == 0x00)        /* waste time until not busy */1 _5 A" P7 Q' l: ~
                temp = SO;0 Q8 N$ H4 C. p' k! _
        CE_High();' p3 o$ a6 Y+ N7 ?& {
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)- K! f, Q0 ?# _* O' e* @* L
{8 r$ z7 o  ~, s! I; ~! q; z
        
: \5 J9 V5 S4 s        unsigned char i = 0;
4 b# y" s) v* U5 v' @8 t. [1 t        for (i = 0; i < 8; i++). X0 }& S, n8 N0 u: @& n
        {, m. X5 h! L$ e, ]4 K, p
               
$ Z/ H& b# P+ Q  N8 c, ^( y2 x5 A                if ((out & 0x80) == 0x80)        /* check if MSB is high */
9 o7 x: m8 ^( Y- b1 B  S% z                        SI = 1;, P/ ^% z: H7 L4 I, {0 ~- w
                else7 o7 L3 ~2 x# y, L& O" S) q
                        SI = 0;                                /* if not, set to low */5 e  S* v1 P6 c* C2 ^) x8 g$ e) C# a
问              SCK = 1;                                /* toggle clock high */7 a& l, f+ |; M
   题            out = (out << 1);                /* shift 1 place for next bit */
# W% {6 m  f4 v+ z9 X# Y                SCK = 0;                                /* toggle clock low */
* e% Q2 P! L% ]% F8 f. s+ Q        }- R2 _7 I. P0 x  f4 A& U' S) Y
}
7 ?) f5 `. P6 }* z% t. _, { 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-20 08:37 , Processed in 0.276894 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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