找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54192|回复: 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
    : {( b1 Y( e) [6 @$ K" r

  2. / A6 b& P7 }  K1 \( c% K
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory9 @: u5 X% @7 \  b" }, U2 L
  4. ; W$ d+ Y8 g0 Y7 ^
  5. November 4th, 2005, Rev. 1.0( h; v0 ^2 l9 W& d# U0 i
  6. $ P5 U3 K+ P- @" ?) Z* N
  7. ABOUT THE SOFTWARE& V, b1 _5 d) U- E: }3 c$ q" C
  8. This application note provides software driver examples for SST25VF080B,
    % l( u3 n4 s, s$ _% R+ p/ c2 y) G
  9. Serial Flash. Extensive comments are included in each routine to describe
    % w1 M* I) W' U8 Y% d% o) c& b
  10. the function of each routine.  The interface coding uses polling method & M. |' |6 m6 F& L3 w
  11. rather than the SPI protocol to interface with these serial devices.  The
    " H) e) c: Z% ?% ~
  12. functions are differentiated below in terms of the communication protocols
    2 Q8 S2 S) O  _6 `2 Y
  13. (uses Mode 0) and specific device operation instructions. This code has been
    & \6 Y  B6 |1 ?
  14. designed to compile using the Keil compiler.
      O) M- Z/ G& G$ |
  15. ; b! [; g' o, U
  16. ' f  }5 i% G2 @1 }8 L" M
  17. ABOUT THE SST25VF080B
    ( l1 |% }" G8 J8 J
  18. . R$ o. r  N  R. S# _1 S
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    6 u4 Q9 a- M" s  X9 p5 ^+ r
  20. conjunction with this application note for a complete understanding
    ) G  ?1 l' J* y# F
  21. of the device." d$ X3 g4 G/ j8 i% P" c

  22. 1 j7 \$ s) C7 d$ z/ _- V3 _

  23. 5 E8 V, H/ k* f' X) \5 c& u
  24. Device Communication Protocol(pinout related) functions:
    0 H/ P: p# @7 Y
  25. 8 P6 s( \/ O' N7 [% M
  26. Functions                                    Function( S. B- E4 c  h! r4 Z
  27. ------------------------------------------------------------------& j+ E' v5 ^* p
  28. init                                        Initializes clock to set up mode 0.0 Y' I9 X% `7 ~5 z  I/ r
  29. Send_Byte                                Sends one byte using SI pin to send and . u7 R" I$ K: ~8 J& l  c
  30.                                                 shift out 1-bit per clock rising edge
    ( E0 x( U) D8 E7 ]) l/ O
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    " f. h5 p( a7 Y4 n' w$ \
  32.                                                 in 1-bit per clock falling edge  [  d% C: D$ R
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming7 p% j" S$ Q# B
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high* a. K3 ~1 D* O1 t) |0 |
  35. CE_Low                                        Clears Chip Enable of the serial flash to low/ z1 R" I8 H$ f* |( e
  36. Hold_Low                                Clears Hold pin to make serial flash hold5 z1 T9 i, m3 Y1 Z% b  n# C
  37. Unhold                                        Unholds the serial flash& i( e. ]4 y" d/ n: L8 R3 d' ^
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    2 _8 {4 q1 b; z, [
  39. UnWP                                        Disables write protection pin
    8 L9 Y/ t7 _4 l3 ^

  40. 3 t1 y. K0 N3 e. V
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code& q# |8 _. n9 w) S1 K6 N
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    - X+ a' x- o. D9 O1 ~1 I
  43. software which should reflect your hardware interfaced.          6 ~5 d% B6 g' ~

  44. 8 r0 z+ x4 U! r3 [. D. a" L
  45. # ]$ U# b, s* a
  46. Device Operation Instruction functions:4 }% S3 B8 h4 B3 R, G0 V* |# [/ ~/ F5 H

  47. 5 z- J5 T# D9 ^) p0 ~, O
  48. Functions                                    Function, E: e3 j' C- y" R
  49. ------------------------------------------------------------------
    8 `% j$ U# F& E" l8 k( e9 p
  50. Read_Status_Register        Reads the status register of the serial flash# ~" c) w2 D$ I# I  x
  51. EWSR                                        Enables the Write Status Register. L0 p  z. |3 B' Z
  52. WRSR                                        Performs a write to the status register$ F5 I& C& W: Q( e, z# _4 f" W
  53. WREN                                        Write enables the serial flash  Y) j3 t; {; b$ r3 R
  54. WRDI                                        Write disables the serial flash5 _( g- s8 N/ M
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    - y' w. \6 F1 [2 v0 y8 L3 g
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming3 z! k* l- e  s$ f" k) p: n
  57. Read_ID                                        Reads the manufacturer ID and device ID
    $ [' k$ G! C8 g5 I
  58. Jedec_ID_Read                        Reads the Jedec ID1 I: i: k! z. [1 O6 W& T* B
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    : D: ~& [2 U/ ?/ I& T4 b
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)! M( d6 D' {- ?. c* f& B; g9 S) @
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    . N( o$ z: E# u3 a
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    $ n7 o0 a1 h& B. V7 C. l
  63. Byte_Program                        Program one byte to the serial flash% R- r" Q5 v3 @9 M' }9 J8 e" n
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    , T5 _2 M/ s1 Y2 U
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation# u' F. N+ j1 u! e" N* K( i4 A
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    - E) Q( i2 y2 c
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY* M& o7 A0 I+ e4 E5 X6 l
  68. Chip_Erase                                Erases entire serial flash
    2 U/ W& F5 P# s4 k( R
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash  v* e7 _, i$ u$ @
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    ; n/ e6 r. _! [+ N- Y' N2 t/ t# r" y
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash6 _& F" U3 b$ \' H( ]& x2 A
  72. Wait_Busy                                Polls status register until busy bit is low
    9 {4 ^  k; z. c! b. e
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming7 v' H* M. d) G, l- {6 L7 X( U6 r
  74. WREN_Check                                Checks to see if WEL is set- [' k) E$ W8 ?/ }
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    0 X) s. N% A# O% a

  76. , I2 h5 H! Q% K, ]6 y

  77. 5 n' K3 l8 X, N% F( L; A1 T( U

  78.   b' ^' S1 D3 r1 S  `7 I$ w
  79.                                                                      
    9 {) q0 `7 }) D4 P3 _9 n
  80. "C" LANGUAGE DRIVERS
    + ?% Y4 s5 p6 u# f/ K+ L; k
  81. / K: }0 E! e! Y
  82. /********************************************************************/) m# ^  Y* ?' B7 Q% q! n- \
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */* u+ q) q' H2 D; P" w
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */9 D* z. V( ?3 G8 r' E: t+ y0 M0 |1 ^
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */9 C" E  K& B; D. N6 g* C0 ~
  86. /*                                                                  */; h* K% l) N6 i% s/ f
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    . Y  @: |+ z! M0 Y1 x4 V) g' s" @+ L+ J
  88. /*                                                                  */1 m0 }- j. B) Y0 R; r& v, [
  89. /*                                                                                                                                        */% S5 ^+ D) K% h+ O+ M, o+ U
  90. /********************************************************************/
    * D3 i" a( A# p: S+ U% S2 R, R
  91. : h9 n9 S6 T% P8 I1 q$ {' d
  92. #include <stdio.h>
    5 ^; T7 |- \3 y. f" ~4 G. q
  93. #include <stdlib.h>
    0 b: T  S5 u4 J* j+ B' L
  94. . V! D$ o, _, ]4 S8 R( q
  95. /* Function Prototypes */9 Z+ G& M' V7 ]6 J/ ^
  96. ) ^1 e; \" ?( W0 _  r( ~
  97. void init();
    $ H! R0 \: C) `4 y& G/ J
  98. void Send_Byte(unsigned char out);; n/ U# |8 R& B8 ]9 Z
  99. unsigned char Get_Byte();9 Y0 G" ~' w. d0 n& J" }
  100. void Poll_SO();
    * F2 O# a' w6 ^% }) k
  101. void CE_High();
    6 I  W0 N: D4 v) G& E$ s2 X1 j
  102. void CE_Low();' H' L' |+ H/ @. M  ^+ O2 k, V
  103. void Hold_Low();
    4 d3 W! M" p5 h" f/ E2 k3 h
  104. void Unhold();
    2 e3 c  f: x, H/ L" w2 p3 d/ N5 V. Y
  105. void WP_Low();1 ^3 h% W) m. [2 l3 p0 \
  106. void UnWP();
    $ U! O' U- O$ Z+ B
  107. unsigned char Read_Status_Register();
    1 ^, r3 l7 I  e- C3 X
  108. void EWSR();; a+ d$ T/ H. u  c
  109. void WRSR(byte);
    + L' l) P4 ^! C+ c7 i$ c, K! {5 u9 q
  110. void WREN();
    4 T/ A9 m* b, ]* i$ X5 g$ [
  111. void WRDI();0 K$ M/ ~  P# K  v
  112. void EBSY();$ G3 C5 }  G$ U1 `4 O6 d$ ^$ }
  113. void DBSY();
    % ^) z4 \( r! E, E5 `
  114. unsigned char Read_ID(ID_addr);+ y4 p! F2 g$ w& J  J
  115. unsigned long Jedec_ID_Read(); # h- }0 \2 v. a. t3 N
  116. unsigned char Read(unsigned long Dst);( [) S9 C6 h% Z' J- S" Q! X
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);, }' }' q* f9 [; V% D
  118. unsigned char HighSpeed_Read(unsigned long Dst); $ S8 h5 x* R! G
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);$ Z, c" {4 V6 [' ]! B- K6 x
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    2 P( o- }5 E* w; X/ Q! m6 n
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);9 l2 B# K  y6 i' d; q" N+ m6 S- `
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);' y7 ~$ ~' ]3 D
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);) v8 L0 `$ Q' k. c, K2 `
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    : x+ J7 ?* h, H7 o# a$ K; X1 o
  125. void Chip_Erase();
    : r# z. Q. B: x! I* U4 J
  126. void Sector_Erase(unsigned long Dst);
    ; F$ o3 N- _  {0 @* d( b3 L' O/ S
  127. void Block_Erase_32K(unsigned long Dst);5 b) l" i" `) b6 w) Q, y% B
  128. void Block_Erase_64K(unsigned long Dst);0 {7 M) T( _3 h
  129. void Wait_Busy();
    8 f0 f: f9 H# f0 P$ z! a
  130. void Wait_Busy_AAI();
    + c3 \& y" y8 M
  131. void WREN_Check();7 x& E, P- U7 S. n1 r
  132. void WREN_AAI_Check();
    ) ~9 q. S7 `$ P( c, ~
  133. ( Z0 L- U" T( s7 }* [
  134. void Verify(unsigned char byte, unsigned char cor_byte);( j% `' u6 N2 A( S
  135. / m; H& P# z% Y0 P1 T
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    1 a: w9 h3 C' K* _
  137.                                                                                 /* to upper RAM area from 80H - FFH */6 \3 Y9 V( H' T, c2 ~) h# t
  138. ! J; p7 w: J% Z- W' K
  139. /************************************************************************// w+ ]. s; R5 |. {
  140. /* PROCEDURE: init                                                                                                                */
    ! d- R2 ^* Y! z9 t6 L& g4 P/ n
  141. /*                                                                                                                                                */
    - W7 P  u: m4 N1 Z4 [& d. Z1 D
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    9 N: a  ^' `8 g8 y
  143. /* setting up mode 0.                                                                                                        */6 W* h- W& x6 s+ g* x
  144. /*                                                                                                                                                */) n$ C. ^8 Q' L* }& ~
  145. /* Input:                                                                                                                                */
    ( j, n6 S* A  N) N/ e
  146. /*                None                                                                                                                        */( c) X& e* E& d/ G  _% O7 \
  147. /*                                                                                                                                                */8 Q  y+ J% Q/ Y& a3 Y0 Q
  148. /* Output:                                                                                                                                */
    , w8 W" L" T# |; }
  149. /*                SCK                                                                                                                                */
    ' ]1 @; M& P5 L4 `) W
  150. /************************************************************************/- o9 R2 h/ s, n' k: L+ f; [5 K
  151. void init()
    . N- L) V% G- V& i; \
  152. {" U! F3 p+ v7 y. V2 V
  153.         SCK = 0;        /* set clock to low initial state */8 T( z$ T, A$ [7 T
  154. }% o% c0 u0 r! i7 J. h& c
  155. 9 D- c' ~' U- s/ U
  156. /************************************************************************/+ J1 _# n9 X# A/ R% ~
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    , X/ O5 O# Z9 A
  158. /*                                                                                                                                                */
    % q: L5 w& R; x) ^% W
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        *// P$ c5 B6 i" f
  160. /* edge on the the SI pin(LSB 1st).                                                                                */6 n  Y  z: l4 s0 E. F5 f3 a
  161. /*                                                                                                                                                */- @- G# p  p2 G3 R$ V9 O3 o( q
  162. /* Input:                                                                                                                                */
      n  U8 B  d# {4 C. R6 K
  163. /*                out                                                                                                                                */
    - c* S: i3 ~# {6 u
  164. /*                                                                                                                                                */
    1 c8 `  f2 C- q5 G
  165. /* Output:                                                                                                                                */
    0 e6 K$ w0 e9 Z7 I, x
  166. /*                SI                                                                                                                                */) B) L! p' E; z% W; o. Y9 [, \8 {
  167. /************************************************************************/0 ]! S2 Q( G3 c  g& P  w# H) j
  168. void Send_Byte(unsigned char out)0 I8 D6 n+ h- q0 y# J- @
  169. {
    + V2 F: x$ W8 @3 `/ G, z0 Z/ a) u
  170.        
    2 b2 |7 a. M) j$ ^; ~* [- \
  171.         unsigned char i = 0;$ h; U8 a/ }/ \+ S
  172.         for (i = 0; i < 8; i++)3 j& d" H" P4 s- R: A8 Z: B7 \: o
  173.         {$ B" X5 l2 H2 [' f& ~
  174.                
    3 p2 R1 K, B# a( C
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high *// V% Q2 h% h2 \; Q' v7 L* S! ?
  176.                         SI = 1;
    ( \, l0 o/ f/ b' R8 i( a  S
  177.                 else
    ) r2 \" j5 ?* z1 j
  178.                         SI = 0;                                /* if not, set to low */0 P) ~* `+ U% T/ q8 i+ K
  179.                 SCK = 1;                                /* toggle clock high */
    : B, V7 x/ j* ^+ t
  180.                 out = (out << 1);                /* shift 1 place for next bit */! T1 P; l7 }, r* |- F5 h
  181.                 SCK = 0;                                /* toggle clock low */5 Z4 m5 S$ t( ]5 w& ^5 h* ~& J% n8 D
  182.         }6 {: M6 ^+ Q6 G. C; H! y9 s
  183. }  ^' i1 V/ i! _8 T
  184. * d  J: x5 N- u( r) Z# A
  185. /************************************************************************/
      x! D; ^! N# R) Z0 @' `7 t
  186. /* PROCEDURE: Get_Byte                                                                                                        */! `; y3 e+ s- S! h1 Y# \+ c3 n6 O; B
  187. /*                                                                                                                                                */8 p4 K; |" i  E+ f/ E* G0 t
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */$ }5 F2 m/ r4 f6 |
  189. /* edge on the SO pin(LSB 1st).                                                                                        */# r2 S$ z  P' Y  K
  190. /*                                                                                                                                                */
    6 _* N: v/ C# J! q9 `- g0 \5 h* ^
  191. /* Input:                                                                                                                                */
    ! {7 k6 Y2 G5 I* @* g
  192. /*                SO                                                                                                                                */% Q$ k0 Y; A  }' n: b, v
  193. /*                                                                                                                                                */% Z2 n2 o/ @7 z, z6 I: \, m
  194. /* Output:                                                                                                                                */
    $ d& D2 z( q# o; ~% |
  195. /*                None                                                                                                                        */
    # l( `' m4 s4 q- r
  196. /************************************************************************/
    5 z8 v0 ?( K5 v
  197. unsigned char Get_Byte(), Y: X3 \2 N9 z5 L3 h. {- h2 J
  198. {% b: R! Z5 M- O' E' u% D
  199.         unsigned char i = 0, in = 0, temp = 0;
    ! K+ M$ [$ r6 O# n3 U3 e% o
  200.         for (i = 0; i < 8; i++)
    ( I. Q" t* z( _9 x- k9 t
  201.         {! B: o) o' X- [( _1 e2 j; V
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */, N" z9 j2 Y  l
  203.                 temp = SO;                        /* save input */: Q( `# [" {% Q& s8 O
  204.                 SCK = 1;                        /* toggle clock high */- ]( D6 s1 u% u( ]  P) ^
  205.                 if (temp == 1)                        /* check to see if bit is high */
      r8 u! M; l( z# b( C; f
  206.                         in = in | 0x01;                /* if high, make bit high */' s' [5 w, u; a+ P% f: j' j

  207. - m5 H0 P- R  Q& N8 E  y" C2 I
  208.                 SCK = 0;                        /* toggle clock low */
    0 D; w- v/ A% `# H! ~
  209. 9 c! A& J8 A2 J- s% |& F
  210.         }$ A& _$ g. [. t8 g& z" u
  211.         return in;8 p$ v2 k7 |% n  s, T, H; \& d
  212. }5 J) z( Z- i4 R4 C6 O, f

  213. 5 k- |1 q" K# W3 Y) g7 f
  214. /************************************************************************/3 ~" ]/ B3 C; j+ P$ K, e( e+ A
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    & ?8 Z+ @3 w# f4 Q
  216. /*                                                                                                                                                */! V. M8 K% ?7 t/ c, b1 G* F4 x
  217. /* This procedure polls for the SO line during AAI programming                  */0 x5 Z1 g! o/ N6 P' ]( c
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    3 l1 @0 X6 [7 u3 D3 X' k3 [
  219. /* is completed                                                                                                                        */
    0 ~3 ?- a0 ~$ n+ N
  220. /*                                                                                                                                                */4 n; x/ f+ S8 A- Z: N8 ?
  221. /* Input:                                                                                                                                */
    - r+ @, o& Z* N& Q( N- P7 N) _
  222. /*                SO                                                                                                                                */
    3 {. ^' f- \4 A3 N4 d5 [% x
  223. /*                                                                                                                                                */1 ^2 I5 O" S" J! z. M( @, P
  224. /* Output:                                                                                                                                */0 R& C# p# P4 G" w. M
  225. /*                None                                                                                                                        */
    / k. s* p/ s; `' O: i& k" i
  226. /************************************************************************/
    / W; z; b& v7 G( A
  227. void Poll_SO()" `" h! G( d6 [, Y* Q4 r
  228. {( ^: q/ J9 W1 M$ u- q
  229.         unsigned char temp = 0;9 t, r0 P/ q9 B
  230.         CE_Low();
    ! B9 f4 y6 m" X! B- B2 {
  231.     while (temp == 0x00)        /* waste time until not busy */
    + O! N$ Y6 ]' a; ]( x
  232.                 temp = SO;4 k2 S" b+ a8 E' C6 x' W  c
  233.         CE_High();
    1 E& M& q1 M& ]% }7 U: a$ k1 o
  234. }( \; n; L2 @9 `, G2 |2 I9 W

  235. 7 K; a8 b' Z# ~
  236. /************************************************************************/; n' `8 I" U9 l$ a5 X* Y
  237. /* PROCEDURE: CE_High                                                                                                        */
    1 J$ |% Z& i3 y5 }* _5 s1 |
  238. /*                                                                                                                                                */7 G& f& h) E9 y+ A8 r' C/ r
  239. /* This procedure set CE = High.                                                                                */
    8 j1 e* |! ~4 f( M2 w
  240. /*                                                                                                                                                */  @6 r4 I& Q( O% z/ a+ n
  241. /* Input:                                                                                                                                */  s/ G: W  I, B' `" H
  242. /*                None                                                                                                                        */
    6 R' }: U5 ~5 L
  243. /*                                                                                                                                                */# D! |* r, L' v) M  c$ L
  244. /* Output:                                                                                                                                */  M+ G7 W" \+ D2 m0 v( I; @
  245. /*                CE                                                                                                                                */7 W9 O, X3 A* u
  246. /*                                                                                                                                                */
    9 E" u) a; U2 d- J% H  H" x
  247. /************************************************************************/
    - D/ q3 s2 a6 f& Y# b
  248. void CE_High()
    : R9 Y7 f: {) v. A: E3 `$ n  ^
  249. {% v2 A2 o, R0 a! ^
  250.         CE = 1;                                /* set CE high */
    0 w1 G# Q2 i8 s# T1 Q
  251. }6 L" P' i) B- K- u# C( H
  252. ( B; D7 |( Y) Q& @
  253. /************************************************************************/
    : @. ~3 {8 `+ e1 l- }
  254. /* PROCEDURE: CE_Low                                                                                                        */
    . a7 E2 E* v7 U% n; Q; r* n
  255. /*                                                                                                                                                */
    2 m( L, `* _0 }* z! n& B
  256. /* This procedure drives the CE of the device to low.                                          */
    ; g9 w% Q; u; q: @
  257. /*                                                                                                                                                */
    9 H# {6 e" R# `" ~
  258. /* Input:                                                                                                                                */0 w/ C: D2 u! a+ |; t
  259. /*                None                                                                                                                        */1 L& u! d; B  k# |1 w
  260. /*                                                                                                                                                */
    : ~7 ]1 j) u! ]$ G0 g8 n: |4 E
  261. /* Output:                                                                                                                                */
    7 f* k$ k" m; E  r
  262. /*                CE                                                                                                                                */* p- b& g" J7 V
  263. /*                                                                                                                                                */
    * ~. V1 Q; N0 e6 s/ c. [) ]. P
  264. /************************************************************************/
    7 y/ Y) j# L0 J; z3 Y+ H
  265. void CE_Low() + P: q. v( w2 P; |+ z( o
  266. {       
    7 x& w0 R2 |/ z
  267.         CE = 0;                                /* clear CE low */# |) j& j" u* U! o1 h
  268. }
    2 Q& P' {+ G% z, N! n; z8 N

  269. , x) J, K" c5 H4 |
  270. /************************************************************************/
    - [, j6 D& N7 P
  271. /* PROCEDURE: Hold()                                                                                                        */
    % f# A- H# L) n
  272. /*                                                                                                                                                */
    " F0 e3 g0 F4 l+ `) U
  273. /* This procedure clears the Hold pin to low.                                                        */6 Y9 R1 S9 ^3 l8 `
  274. /*                                                                                                                                                */
    : {5 }) k2 X/ V6 ?6 g4 v% j' p* K
  275. /* Input:                                                                                                                                */( d# I0 w' n$ f- ~# F  O
  276. /*                None                                                                                                                        */
      }# z9 O9 H! ]8 I- _
  277. /*                                                                                                                                                */
    ) d# |5 I/ ]( ?; @% J8 j% R9 {- N: K
  278. /* Output:                                                                                                                                */' D$ m) V9 b0 ^) O; X2 L9 u9 H
  279. /*                Hold                                                                                                                        */
    2 v: }3 u4 u0 C+ o6 ^' p) m
  280. /************************************************************************/
    & _2 k$ E! n$ P7 F( }* T% |
  281. void Hold_Low()9 s8 F- Y6 K; @
  282. {& x6 \2 {$ s3 @
  283.         Hold = 0;                        /* clear Hold pin */
    ! C7 U3 E3 C8 T) I* `
  284. }/ @( Y- z. l7 P6 x1 y9 w& j1 \* @

  285. 3 O' ]3 e+ f( t  n$ _
  286. /************************************************************************/
    % X, s; K+ V2 I. K4 S6 o* Q  J
  287. /* PROCEDURE: Unhold()                                                                                                        */6 C, n+ G" T6 o# q0 A
  288. /*                                                                                                                                                */
    0 L4 x: L' D: \6 E6 _5 N
  289. /* This procedure sets the Hold pin to high.                                                        */
    3 D/ l3 u' w) o$ u0 P7 x6 A, a
  290. /*                                                                                                                                                */# R4 Z/ [8 d. g# p( @
  291. /* Input:                                                                                                                                */
    ( J5 ^( N1 v( Z0 e& E* B8 `
  292. /*                None                                                                                                                        */( G" y( n8 h! ~0 |- k3 {& ~
  293. /*                                                                                                                                                */
    % P3 K1 f9 Z7 g
  294. /* Output:                                                                                                                                */
    7 j: R- n% j$ z# J
  295. /*                Hold                                                                                                                        */
    ! d0 Q7 ^) k1 J% l- V& Z, |" K4 x. R
  296. /************************************************************************/5 D) ^1 W. R% P' Z$ o
  297. void Unhold()2 A0 n! ^9 D7 m+ d( P& H/ e
  298. {
    ! y0 m1 t$ {$ ?. t  \+ ]
  299.         Hold = 1;                        /* set Hold pin */
    " ^- n7 t6 Z  O: c- C% h
  300. }
    4 r# B8 B( E7 p* b3 _

  301. ) }( U9 r( F$ W3 `
  302. /************************************************************************/
    ( f' A0 G# H& Y; c& b+ D. i
  303. /* PROCEDURE: WP()                                                                                                                */
    * e1 k9 U: Q+ \2 U2 o) x
  304. /*                                                                                                                                                */" B& p% \  ^9 X3 J: A2 e, L
  305. /* This procedure clears the WP pin to low.                                                                */
    ! r4 {* e- {2 q' F' s
  306. /*                                                                                                                                                */, S# J* ?- ]! \8 q
  307. /* Input:                                                                                                                                */
    + w; Q% V4 c, \7 K- L6 C
  308. /*                None                                                                                                                        */
    4 S* v6 ~) r5 I  z& q
  309. /*                                                                                                                                                */
    $ r% v8 N2 m3 W$ r3 A9 o
  310. /* Output:                                                                                                                                */
    ' z" _$ p' y( }! H4 A' i  y& r) t" |
  311. /*                WP                                                                                                                                */( A9 W  m# U) v
  312. /************************************************************************/
    + m# x- B+ i& O" d$ c
  313. void WP_Low()/ A) f7 }$ D* \$ u7 w5 Y( |* c
  314. {
    0 u1 R$ a/ P8 X; t# l1 L7 i
  315.         WP = 0;                                /* clear WP pin */! E7 z0 b7 \6 e- z
  316. }
    + Z7 @  V$ M" }9 k
  317. 6 p/ G! w. u; s/ [9 S
  318. /************************************************************************/
    $ ?  S$ T: C9 ]' C: P
  319. /* PROCEDURE: UnWP()                                                                                                        */
    0 f- i- A; ]& l5 A7 G/ P% x, K
  320. /*                                                                                                                                                */
    ! h3 E/ L/ N5 |! p& y) Q& O
  321. /* This procedure sets the WP pin to high.                                                                */
      G# L" U; T5 `. F6 s; Y% _' y7 `& T0 J
  322. /*                                                                                                                                                */3 C2 h" B7 ^, p) K% _) {1 K9 b
  323. /* Input:                                                                                                                                */
    & Z! S% B- `0 L
  324. /*                None                                                                                                                        */( K2 Z* T% @: `. a6 E2 l
  325. /*                                                                                                                                                */
    * K" h# h; t/ I6 ?& w
  326. /* Output:                                                                                                                                */
    / o) L: J0 O' S( ?% ?! N* y
  327. /*                WP                                                                                                                                */
    # f  e, A* H! D
  328. /************************************************************************/! [+ r2 @) C6 M; Z% F9 l1 f+ ^7 k
  329. void UnWP()0 I" [; D6 G6 F$ ]1 A0 k+ I% H
  330. {. u: U  n+ E! F, N  z
  331.         WP = 1;                                /* set WP pin */
    & F- M" u& A8 i6 T# _, I1 q' d
  332. }$ l  T: H/ X+ q  I1 |' l

  333. & ^  ^' n7 Z5 R  ^. V! c5 \3 U
  334. /************************************************************************/
    8 _; ^9 s  j. N# t1 P- Q' I
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    / F, u! [6 |* I
  336. /*                                                                                                                                                */' y* j1 K# K2 e5 o. s
  337. /* This procedure read the status register and returns the byte.                */# N' |7 q) T5 _: O/ e9 ~  t0 `
  338. /*                                                                                                                                                */# `/ W7 }7 j2 Q* s
  339. /* Input:                                                                                                                                */9 ]' d/ q) V; z  h/ ^" V
  340. /*                None                                                                                                                        */8 |* O( e( d2 ~
  341. /*                                                                                                                                                */3 H  o& x: y  E
  342. /* Returns:                                                                                                                                */) T* S& |0 i2 K" G' z6 C0 g
  343. /*                byte                                                                                                                        */' a* s3 {. Y! \9 Z+ U8 M3 k# I
  344. /************************************************************************/9 e$ @; j, a1 q# }
  345. unsigned char Read_Status_Register()1 @) |1 Z' Q6 G2 V( ^; X& S
  346. {
    5 W  @3 O9 P, C# f1 y% w) g
  347.         unsigned char byte = 0;6 Q( U. \* \( t- a9 O/ b6 f/ W) R
  348.         CE_Low();                                /* enable device */5 q9 ^* l) F; Z$ Y, m2 Q; S3 e, j, l
  349.         Send_Byte(0x05);                /* send RDSR command */
    : T/ V$ _/ k8 T2 Z9 J
  350.         byte = Get_Byte();                /* receive byte */9 v% x6 G0 I2 E( v4 T- D, |
  351.         CE_High();                                /* disable device */' ~' L7 {# ~1 X) s$ O/ a
  352.         return byte;
    ' P# Z% k5 x8 r0 b5 l/ \' p- V
  353. }
    , {8 p+ s4 g# Z, Q

  354. 1 P9 P1 s$ q4 f1 e$ k
  355. /************************************************************************/4 S( R; u, C, U) s9 x% l
  356. /* PROCEDURE: EWSR                                                                                                                */9 w- |/ ?( A$ b+ |
  357. /*                                                                                                                                                */6 l% ^+ ^2 t" G2 P
  358. /* This procedure Enables Write Status Register.                                                  */
    4 r( t2 ]* t/ m3 W; B
  359. /*                                                                                                                                                */1 Z. |1 G8 }9 h& k
  360. /* Input:                                                                                                                                */7 e) }4 u9 v- H8 Y) d: D7 ^6 b2 q
  361. /*                None                                                                                                                        */
    0 F1 o; T- L* N  ?2 c8 d; A
  362. /*                                                                                                                                                */
    7 @& P( e! e9 r9 m( H% ]$ V/ y0 m( L
  363. /* Returns:                                                                                                                                */. n: [. Z) K) P3 s
  364. /*                Nothing                                                                                                                        */4 P- I5 u4 W) p0 B6 U4 S6 U
  365. /************************************************************************/; Y/ p2 B( w4 ^' ]- r- V/ [4 b
  366. void EWSR()
    ( j; `" F1 N3 b9 q. Y% I4 L' l
  367. {
    " v6 l+ M. e* @0 v) H4 L" X7 {: v
  368.         CE_Low();                                /* enable device */5 o' S5 _% }, |7 c2 x
  369.         Send_Byte(0x50);                /* enable writing to the status register */: G* _& v$ S& ^! t
  370.         CE_High();                                /* disable device */
    0 a3 I+ P; a: b0 G
  371. }
    * O; M/ J- G9 v! |( I' y

  372. / g, O. a# n! e; e% R0 x
  373. /************************************************************************/
    $ P5 W1 z( B5 ?% a( N: d
  374. /* PROCEDURE: WRSR                                                                                                                */
    5 r5 ~: @6 ~' N
  375. /*                                                                                                                                                */
    : W$ H/ o7 \7 r8 i% b
  376. /* This procedure writes a byte to the Status Register.                                        */
    - C( H( N7 O; \& g
  377. /*                                                                                                                                                */, U" c6 s3 ?8 `! F4 K0 b+ ]. `
  378. /* Input:                                                                                                                                */0 U' a; M1 d! i5 Q6 x# z5 B  }
  379. /*                byte                                                                                                                        */" o. F4 _4 m5 o* X' h0 i
  380. /*                                                                                                                                                */1 h0 E1 \0 {9 [- j, U& r
  381. /* Returns:                                                                                                                                */
      Y4 C  _9 M& G* ]" q1 s$ t* h# `0 Q
  382. /*                Nothing                                                                                                                        */0 |8 Z' w+ z: B% d5 T; m
  383. /************************************************************************/
    * ^7 V$ ?) V# ^9 l( Y% z; ^7 [  o
  384. void WRSR(byte)
    $ N; u+ @5 ^5 K1 t
  385. {
    : M% Z, m8 @9 _8 }
  386.         CE_Low();                                /* enable device */3 c7 Z, K% ^0 k" f: F1 c4 q# X6 e
  387.         Send_Byte(0x01);                /* select write to status register */% A4 Q" |0 v0 g
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    . U7 R9 L& u3 j) ~( [0 T1 ~
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    & f, u3 L& b, d( T+ d" X
  390.         CE_High();                                /* disable the device */
      I% d7 G  W% Z' [7 G2 e7 s" w+ `
  391. }
    ! r% W1 V3 l0 O( C* @2 C

  392. , h2 E( S; M6 i7 S0 Y
  393. /************************************************************************/
    / n; W* |6 h4 r( z% ~! w" @
  394. /* PROCEDURE: WREN                                                                                                                */5 O5 J9 E1 k0 Z4 @1 M
  395. /*                                                                                                                                                */6 c) z+ p1 Q$ _+ j
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    1 y3 f# v6 J' L- f, d0 c, o, t
  397. /* to Enables Write Status Register.                                                                        */
    $ r9 s5 J  z4 S) c8 _) M
  398. /*                                                                                                                                                */( A5 T6 b; `; b" |1 ^1 ?7 R0 Q
  399. /* Input:                                                                                                                                */1 ^- r' b1 ^  ]9 r0 G3 [. O0 g
  400. /*                None                                                                                                                        */3 Y+ c! W; b5 p: W" T
  401. /*                                                                                                                                                */
    $ o+ N' j$ i6 J% ^2 ~9 w+ Y
  402. /* Returns:                                                                                                                                */
    3 s* e! f" k/ H; E; j4 S( k
  403. /*                Nothing                                                                                                                        */4 H. l9 g1 p- T, ?3 s( b
  404. /************************************************************************/  D# O( b) R& A  v2 `) d$ A
  405. void WREN()
    - \- |7 }) D; v, w9 G
  406. {* h+ a* k) B6 U0 _0 M
  407.         CE_Low();                                /* enable device */  W$ A. P# G, l1 g
  408.         Send_Byte(0x06);                /* send WREN command */
    # O5 I, W/ D5 z9 p/ b' F3 {& |
  409.         CE_High();                                /* disable device */8 k. ]& ^& W% T' g- r
  410. }
    ' }, v/ d" b8 X

  411. " `' L# Q( G2 j! s: F- n
  412. /************************************************************************/& }6 Y1 A4 g4 D# \* E9 g) _5 S
  413. /* PROCEDURE: WRDI                                                                                                                */8 d- y5 c9 |. B% w, L; e3 |" k
  414. /*                                                                                                                                                */$ L8 l  C/ V& B4 s# C$ q& g3 b' ?
  415. /* This procedure disables the Write Enable Latch.                                                */' H$ c' d% f  v! q
  416. /*                                                                                                                                                */) q- L* z! r2 n/ N5 H" n
  417. /* Input:                                                                                                                                */
    ! Z0 e5 Z5 _2 Q* x6 D4 I: u
  418. /*                None                                                                                                                        */
    % w. j$ c  m! u5 }# M; S
  419. /*                                                                                                                                                */
    ; _7 F) I" n* I# V) }0 N; @
  420. /* Returns:                                                                                                                                */! Q& }# r) s1 m
  421. /*                Nothing                                                                                                                        */5 R# O# n6 z( }' H" Q2 c
  422. /************************************************************************/
    & ?. h, |* v% [) z  C& q8 j
  423. void WRDI()
    : z. y8 ?) A- D( O
  424. {
    3 `  H, g5 S9 w- b- B5 w
  425.         CE_Low();                                /* enable device */
    9 Q& V: n, Y# V6 G
  426.         Send_Byte(0x04);                /* send WRDI command */
    ' }5 y9 O3 o( G, H
  427.         CE_High();                                /* disable device */
    + `$ l8 Q1 t9 U) U1 T
  428. }) Z! Y) p/ W5 h1 f

  429. 8 M; ^9 ^- c3 L* c% J. P) T
  430. /************************************************************************/: u- R" Z3 X, O# `- h: O6 b
  431. /* PROCEDURE: EBSY                                                                                                                */
    1 ]' P) Z$ E& F( g; c, G$ f
  432. /*                                                                                                                                                */
    3 }  a; j1 E5 S6 j- l
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    * D/ d9 k$ |% I
  434. /* programming.                                                                                                                        */
    $ p3 F% o% O1 d1 @8 o' }
  435. /*                                                                                                                                                */
    7 F/ _4 ~" s  z& O7 `, B3 u
  436. /* Input:                                                                                                                                */
    ( d1 M$ C( b5 b& n
  437. /*                None                                                                                                                        */( g4 w/ K9 i  p* R0 s7 N
  438. /*                                                                                                                                                */5 H! ^2 \9 K3 V3 M( h7 f6 {
  439. /* Returns:                                                                                                                                */
    7 P9 ?  }8 q2 I/ K( W
  440. /*                Nothing                                                                                                                        */. a4 f, G  ]: K+ y! B: o
  441. /************************************************************************/
    ! T+ u  b1 C3 h+ O; N
  442. void EBSY()4 U. F5 P3 W. ~# K* ~
  443. {
    4 [- m% U# f+ p' G' k8 F  E
  444.         CE_Low();                                /* enable device */
    5 _( @5 C( [" M  o- l, [5 \7 ~
  445.         Send_Byte(0x70);                /* send EBSY command */
    # C" ?: p2 ?3 I( F" `/ A. e; R$ G5 k
  446.         CE_High();                                /* disable device */
    % ~, P( }: w2 k3 w1 w
  447. }
    8 V/ q" f0 T4 S# x& W* c

  448. $ T' e- L. k% T: [
  449. /************************************************************************/9 T- \) n# R0 ^" Z% ]# i
  450. /* PROCEDURE: DBSY                                                                                                                */
    6 O3 i, C/ {9 C# x1 [
  451. /*                                                                                                                                                */
    2 p, W; Z$ M: E4 g9 P
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    1 c* i. H, v; N, s  ^
  453. /* programming.                                                                                                                        */; u4 ^6 @/ s* S
  454. /*                                                                                                                                                */$ L6 {% A7 J% V8 a1 s
  455. /* Input:                                                                                                                                */. F, ]$ s6 V% Y
  456. /*                None                                                                                                                        */, z% M( J/ ^5 H" a5 J; Q
  457. /*                                                                                                                                                */
    9 P' L, _1 a2 H( H( T6 q
  458. /* Returns:                                                                                                                                */
    % b" b+ I4 C( P( n0 p
  459. /*                Nothing                                                                                                                        */
    # L6 A/ k3 ?1 I4 [- M
  460. /************************************************************************/
    % `! R( k1 E4 ^7 e1 t* Q& {
  461. void DBSY()
    3 B% u) P3 r* a9 w- n0 i
  462. {! k  C6 T9 W" ?6 t. q4 F' i
  463.         CE_Low();                                /* enable device */; o$ M4 Q$ {  k5 u% S5 z
  464.         Send_Byte(0x80);                /* send DBSY command */
    . \+ R* E+ D1 E
  465.         CE_High();                                /* disable device */" h3 O2 b- _! j5 C( p
  466. }3 }% F+ v  w! R2 m1 ]5 T

  467. % |$ d  o/ q  m
  468. /************************************************************************/7 s1 L/ ]4 T0 l
  469. /* PROCEDURE: Read_ID                                                                                                        */. p* B: ^; F! m5 S) c8 G
  470. /*                                                                                                                                                */
    ' {) Z/ x$ y" N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ) B. Y- g( _) V+ H
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */$ k$ {+ j- e# a) k; V  ]
  473. /* It is up to the user to give the last byte ID_addr to determine      */, B# L* V: f0 S8 U% ~3 d& v
  474. /* whether the device outputs manufacturer's ID first, or device ID         */. [* \1 u/ L: J3 o
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    $ T5 j2 |8 V0 t  P
  476. /* variable byte.                                                                                                                */
    8 C0 S6 E2 w" U* x9 }# B9 I  M
  477. /*                                                                                                                                                */
    . O  d2 z5 k8 k- A3 N. Y
  478. /* Input:                                                                                                                                */1 c  X% h4 n, J9 f
  479. /*                ID_addr                                                                                                                        */
    ( r8 Z: U& y3 {" d# h+ J" D6 T0 F- N8 N
  480. /*                                                                                                                                                */( ~6 T' N9 L4 V) X( z" a
  481. /* Returns:                                                                                                                                */
    6 O2 o' ?6 h( `- P  c# j5 d8 h$ u
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */( @+ n: S' `2 a) J" U
  483. /*                                                                                                                                                */
    ( Q8 A7 k8 o; p8 `- x8 f
  484. /************************************************************************/
    & L2 w; P" ], W0 V
  485. unsigned char Read_ID(ID_addr), g% ]: p. e: B( b% T
  486. {
    / K- m  Y1 r( U. O$ Q+ O, h2 t
  487.         unsigned char byte;( }: K9 N7 y; J$ z) F/ b
  488.         CE_Low();                                /* enable device */
      w2 p: k4 O, s- `2 g# Y! z
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */$ O- X, A0 J8 _" Y4 [2 J% z$ L
  490.     Send_Byte(0x00);                /* send address */: F3 @! k( L( j9 L# l$ r& W
  491.         Send_Byte(0x00);                /* send address */' Z  \" B% V9 w% e* X
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ! c% f& S( I& v  Q0 B# V. ?: V% G
  493.         byte = Get_Byte();                /* receive byte *// w7 q1 m1 I/ m# ^3 ?# P, ^
  494.         CE_High();                                /* disable device */
      j' ]- V" @5 G( b1 t9 L4 G  ~# T: u3 A
  495.         return byte;
    6 I9 ?% Z- `. ^0 M
  496. }
    9 b; e1 q2 E* l7 J- |3 Z

  497. ( H. t1 a* l5 h8 z+ t0 v* S
  498. /************************************************************************/5 p. x" z5 x$ o, n$ n
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    % N: P, x( D) H
  500. /*                                                                                                                                                */
    5 d7 p2 e' y8 i0 g7 I6 n
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    * e) d0 B( @, s- o
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    8 ]2 h, Y1 l4 O: ?  @
  503. /* Please see the product datasheet for details.                                                  */
    8 [/ [* `  P- [
  504. /*                                                                                                                                                */; U" z- [1 V7 Y+ S
  505. /* Input:                                                                                                                                */( |; a/ u: w8 o1 w8 {2 a
  506. /*                None                                                                                                                        */
    + z- e0 v3 R6 K% H/ m9 c  ]% L, b
  507. /*                                                                                                                                                */3 P! ?7 w5 X9 @: z  T
  508. /* Returns:                                                                                                                                */
    ) w( K: f) m' E: o* q. T$ t8 l! H3 M' r
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    ; d2 @+ F/ t8 S- a1 Q7 T
  510. /*                 and Device ID (8Eh)                                                                                        */
    ) f, O; k$ B$ U
  511. /*                                                                                                                                                */
    0 ~  }/ V1 @; p+ q
  512. /************************************************************************/% O8 }* \3 Z, d4 a; {$ T
  513. unsigned long Jedec_ID_Read()
    ' k8 [4 o1 K7 i3 t
  514. {  z7 }; W4 j- s- [, G8 T, y+ e
  515.         unsigned long temp;' r2 ]+ R# o/ j3 l0 {: ]* C
  516.        
    5 v) {( _5 b! Q  L
  517.         temp = 0;$ b8 b$ F  y9 s5 K
  518. 8 j7 m+ w% C+ O4 j' {! g0 a, Z0 i' ]
  519.         CE_Low();                                        /* enable device */
    & n, e# [; E3 h0 l  n
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    5 r! j. ?0 r8 c) k3 i. P; X
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */, J* a1 u( L; U3 ]8 i
  522.         temp = (temp | Get_Byte()) << 8;        0 I2 n# F! N* q4 o) D! T; j
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    2 w: m* U) O8 }' E: s" k7 U
  524.         CE_High();                                                        /* disable device */1 P! l! v& W: g  i% e4 z6 W& X

  525. 8 o+ ?9 g/ P  n6 g9 O; M4 E% Y" [
  526.         return temp;7 K% Q3 @: P0 b1 P5 H, v% A
  527. }/ `9 j  [" w6 d" w& y; A) ~1 I

  528. # [( Z0 U+ f+ A
  529. /************************************************************************/! N4 v9 N' {( n
  530. /* PROCEDURE:        Read                                                                                                        */
    8 x( w6 I4 g  W
  531. /*                                                                                                                                                */               
    # t, L) ~; I1 O! G* u  u
  532. /* This procedure reads one address of the device.  It will return the         */
    3 c+ ?3 j8 c" P
  533. /* byte read in variable byte.                                                                                        */! N2 V+ y: N' Y- ]4 T& R; }0 X
  534. /*                                                                                                                                                */$ c0 r* u, r( x- H% j) y
  535. /*                                                                                                                                                */
    * u8 G* ]* L7 @7 @
  536. /*                                                                                                                                                */+ e0 U3 V1 E$ {  ]4 C& X
  537. /* Input:                                                                                                                                */
    # G$ \2 o- N( H5 {  ^
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */: C; \$ V$ s. Y2 H, n
  539. /*                                                                                                                                      */6 _: x7 V/ [$ v8 Q
  540. /*                                                                                                                                                */
    9 y. O2 N2 s& |. f2 x
  541. /* Returns:                                                                                                                                */
    , b4 @. X  d# f, l9 r
  542. /*                byte                                                                                                                        */
    % m1 v  b/ q& {; R: m/ n( l, \
  543. /*                                                                                                                                                */% M4 T/ d% K" [$ j: J
  544. /************************************************************************/# F  O- P% X0 s5 y& P2 }$ k
  545. unsigned char Read(unsigned long Dst)
    & e' L) U4 S4 B0 x. i4 V! t  P
  546. {$ W! f2 v$ S% p" w, a
  547.         unsigned char byte = 0;        - r& ^& `! V/ I& l% C) g. t

  548. " Q0 q3 P  x  M5 [
  549.         CE_Low();                                /* enable device */
    * j: |% a9 H4 @2 C+ t
  550.         Send_Byte(0x03);                 /* read command */& M. U) j) h9 V9 i3 X
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# P4 G& ^! E1 y0 O: U
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , T+ h8 S. H, [) C0 v& n
  553.         Send_Byte(Dst & 0xFF);! F1 i9 A- e# E' s- |/ A
  554.         byte = Get_Byte();2 i/ X% a; h1 E0 D) R3 v. S3 e
  555.         CE_High();                                /* disable device */
    : Z) Y7 ~2 w5 T
  556.         return byte;                        /* return one byte read */, V# U: o+ z9 Q" m: j: P( W8 J
  557. }
      v- I, p% U/ A  a) p- Z

  558. " a1 H7 F% V, `& Y  d- k% k
  559. /************************************************************************/- C; S+ J( V* L2 s0 o9 u* R, T
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    4 ^3 e5 \1 Q6 [( z& K! `* a  ]
  561. /*                                                                                                                                                */               
    " U1 B" p3 M+ \% b
  562. /* This procedure reads multiple addresses of the device and stores                */4 O" E! D1 {7 B) K. [1 t  A. ~) r
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ( E4 u2 q6 w; Y5 X
  564. /*                                                                                                                                                */
    8 m' E' N* F8 _
  565. /* Input:                                                                                                                                */
    ; K1 n4 ~8 G  G; z0 B
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / v9 x- V# o: W6 \1 I# W
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    " m+ u6 H4 u+ Z3 I6 S! v
  568. /*                                                                                                                                                */9 N$ T, m2 Q2 w) g7 }" G( M
  569. /* Returns:                                                                                                                                */2 i2 x" u# T8 u6 M: a. A7 H- p7 i7 z
  570. /*                Nothing                                                                                                                        */6 X, ]# E& I9 o) \4 z6 l0 n3 i! d
  571. /*                                                                                                                                                */
    ( s6 C- b" Q/ o% R0 l. I7 H; @
  572. /************************************************************************/* h! H1 [/ y/ k7 W5 X
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    3 \! m3 R4 P) K. s) p/ B
  574. {
    * k! U& M% {' ~" @0 b! a
  575.         unsigned long i = 0;
      W& J; B. F- d" q  s. @) O
  576.         CE_Low();                                        /* enable device *// S1 X; j6 m( Q/ Y. O
  577.         Send_Byte(0x03);                         /* read command */
    8 k, L2 V  \8 C% Y$ ?
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ o! @4 a! N9 B- v8 K& t! t% b
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));$ w* }3 T: t- c* h; S9 C% {
  580.         Send_Byte(Dst & 0xFF);* K9 W1 V# @9 h3 J
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    $ K$ r: U$ Z+ [+ n: S. `3 ^
  582.         {$ R8 L  B# k3 _
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */+ R' L+ r! f, A3 W
  584.         }
    7 s0 A% F+ _3 _& w- J' D
  585.         CE_High();                                        /* disable device */
    & R- M2 y% j: r6 ]8 F; k6 {8 t

  586. # `5 Y. T6 l- Z; s; n
  587. }2 p0 I  v' g# B* F+ Y) E
  588. ; g' j  k: Q& n
  589. /************************************************************************/
    3 G# v; _) }6 A& J
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        *// [# t+ c, ]+ N% c. s
  591. /*                                                                                                                                                */                8 b& Z, g' u' D" X  G7 c( o
  592. /* This procedure reads one address of the device.  It will return the         */
    + O6 k+ y1 p: o5 r% Z0 s
  593. /* byte read in variable byte.                                                                                        */. A1 e4 W  c& _
  594. /*                                                                                                                                                */
    9 Z# S4 A/ E8 b9 @
  595. /*                                                                                                                                                */
    ( ?* w% L8 J0 @+ k8 w1 c, A
  596. /*                                                                                                                                                */) v) G# Y2 y4 t+ _8 H( G, t
  597. /* Input:                                                                                                                                */7 M; S2 B% h5 J
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */' |  d  C$ c+ O
  599. /*                                                                                                                                      */" l) N$ A$ J' e3 i
  600. /*                                                                                                                                                */
    # y2 z" a7 b, B6 ]* d5 V
  601. /* Returns:                                                                                                                                */6 o" E+ p* ?& ^
  602. /*                byte                                                                                                                        */
    2 w; _+ s. @8 H; W  J
  603. /*                                                                                                                                                */
    ' o; ]/ |8 P8 E8 X0 p) |7 e
  604. /************************************************************************/  C1 N  [& _4 w. a; L* W: }0 S
  605. unsigned char HighSpeed_Read(unsigned long Dst)   U' i. C9 h, N  C( \9 L* K
  606. {! x5 O  v3 ^  v( _% K9 v
  607.         unsigned char byte = 0;        ( w6 @* J2 D7 F/ A2 K

  608. + Y- o4 J+ M- h' D# T! R
  609.         CE_Low();                                /* enable device */
    6 p2 H( N0 N4 Q. O
  610.         Send_Byte(0x0B);                 /* read command */
    ' ~$ \6 ~6 c! k8 ]' |/ c2 H( w
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */4 g& ^* {3 z0 m! Q& [
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));- p3 y7 O( g- U0 m+ W5 w& P
  613.         Send_Byte(Dst & 0xFF);: A( x6 {, n7 B$ p0 y0 w
  614.         Send_Byte(0xFF);                /*dummy byte*/
    9 ?7 q% ?( V( p# _% D7 G. p
  615.         byte = Get_Byte();1 W( S" X8 O! t; z+ v' i1 y
  616.         CE_High();                                /* disable device */
    6 ]; w7 X/ G# `6 z; @
  617.         return byte;                        /* return one byte read */  k) N2 `+ m' u/ Y' n% E
  618. }& U  {4 R6 @9 @- K. y& r+ n2 {

  619. 6 U  |$ U. D* x! b! y! @) z6 p
  620. /************************************************************************/! [. v  F/ n/ w' g
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */& v) Q& Z4 v- e7 G
  622. /*                                                                                                                                                */                ; X' l9 H0 Q) \# [% F8 b) ?9 h3 D
  623. /* This procedure reads multiple addresses of the device and stores                */
    7 L; A" _. ~2 V) [
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    . u. c+ F3 `! |6 f' E
  625. /*                                                                                                                                                */+ A3 ^; [) F. Z
  626. /* Input:                                                                                                                                */
    2 K& X- f$ b5 F% J5 i3 N. G% m
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 n$ y, V) I, ]1 v5 B
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 Z6 L( q, Y& y
  629. /*                                                                                                                                                */
    ( i* u2 U& b- H1 N4 ^8 j
  630. /* Returns:                                                                                                                                */* c% z+ m" k. |# M4 i6 l2 l2 b
  631. /*                Nothing                                                                                                                        */0 m0 J4 q- w8 _/ `' K
  632. /*                                                                                                                                                */- s3 l4 d- |8 `. }9 ]
  633. /************************************************************************/
    1 g$ V* r7 |& o
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    0 Q! k7 ^9 V! ~; J1 S9 h
  635. {
    0 @* S1 n% z) w
  636.         unsigned long i = 0;% c  v- v1 W3 E- c0 M( t
  637.         CE_Low();                                        /* enable device */
    " `* v# E& J4 h5 d+ K+ m  g
  638.         Send_Byte(0x0B);                         /* read command */+ [7 g9 g  u5 ?6 o: {
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . }* q$ D  T0 K% G7 s4 e; F
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));  q" j6 P+ X+ [( a
  641.         Send_Byte(Dst & 0xFF);( s" U3 s1 ~0 t/ g4 H
  642.         Send_Byte(0xFF);                        /*dummy byte*/" [% V* K, u5 ~0 ?$ H" X( c* G
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    4 R1 i  ~2 J" ?+ |
  644.         {6 w8 e5 o1 [, a% E6 {& b, ~( k" [
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */' D, G$ O) [; C* R5 W' X! r
  646.         }
    : M4 t  z  M* k
  647.         CE_High();                                /* disable device *// [0 u, q% E0 U: A  u
  648. }, n- k9 ~7 D( {% A' m; C2 y

  649. $ i* _; o! i/ v. N* k) S& u
  650. /************************************************************************/% C+ ?% Q% z2 v3 b! w1 B. e- D
  651. /* PROCEDURE:        Byte_Program                                                                                        */7 S" ~+ v$ N0 @! ~/ t7 |
  652. /*                                                                                                                                                *// F- @7 d* w& O3 k+ b2 P
  653. /* This procedure programs one address of the device.                                        */
    0 Y# {1 o; g1 s1 A9 a% }
  654. /* Assumption:  Address being programmed is already erased and is NOT        */) B3 c1 E$ ~# j
  655. /* block protected.                                                                                                                */) L7 ?" J7 U; n" o6 U% W& I5 x
  656. /*                                                                                                                                                */2 v1 A# Y' G. T1 O: W
  657. /*                                                                                                                                                */
    # i4 z. V. {9 u
  658. /*                                                                                                                                                */- r' G, G% G4 B6 G
  659. /* Input:                                                                                                                                */5 m& y5 S4 O& Z% e7 x# I0 k& U
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ; z; Z" ~! w' `3 E  M
  661. /*                byte:                byte to be programmed                                                                */" J! |# h3 ^% x4 e3 s
  662. /*                                                                                                                                      */
    8 E+ j: {1 q7 O; `0 ]' b  H  ?
  663. /*                                                                                                                                                */
    1 x% A( ?& H. m; ?+ u& p' C
  664. /* Returns:                                                                                                                                */
    8 e2 d. s2 @( L1 f( ?: B  d
  665. /*                Nothing                                                                                                                        */
    0 z# |! i5 z9 T- c2 s8 d# k6 C& \# U
  666. /*                                                                                                                                                */2 \4 n. `9 Y3 A6 ~+ i+ z( f) d
  667. /************************************************************************/
    6 N6 u9 x$ b& y3 ]1 b2 g! ^5 U
  668. void Byte_Program(unsigned long Dst, unsigned char byte)6 T7 u- l+ j! A$ b5 g
  669. {0 k7 x% F- k, T$ e- ~9 C
  670.         CE_Low();                                        /* enable device */
    6 \' c# ^* u1 R  ^
  671.         Send_Byte(0x02);                         /* send Byte Program command */1 O6 y: E) B5 L/ u# a
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */+ e/ w3 n/ }) f- I0 q
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));) {* c1 q4 f1 v: c: C. M# B
  674.         Send_Byte(Dst & 0xFF);3 W& `3 W, f5 y1 l
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    + B* v, g3 p, Z$ j/ h* m, p0 C
  676.         CE_High();                                        /* disable device */
    # \- b- x0 u' c" t% v  Y" Y
  677. }6 m7 Z) z6 `  T' v% K( Y$ ~+ l/ B

  678. # L6 X* ]5 O( f" h: d" |, T4 I
  679. /************************************************************************/' l" L% q  r6 q% c! u, f
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */' j! O" k. n9 |- f3 k) M& ~( b
  681. /*                                                                                                                                                */; U# z9 g- B' s2 \3 Y4 [% s
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    5 |7 ^+ Q3 m7 Q9 v: ]
  683. /* the device:  1st data byte will be programmed into the initial                 */
    ) B' l/ N: o; E% n+ x
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    7 Y" m8 o) ~7 J/ G
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */9 \3 A8 m) C5 F& B5 D
  686. /* is used to to start the AAI process.  It should be followed by                 */
    # l: x' {! p, J
  687. /* Auto_Add_IncB.                                                                                                                */
    : j5 ~4 L% h  {) e& p" Z
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 B) g9 T: q& j' s5 g( B
  689. /*                                block protected.                                                                                */
    ) E9 L5 U6 |8 E+ C+ m3 C8 ~
  690. /*                                                                                                                                                */
    ( w0 Q, \3 \1 _3 j8 t& ?. Y
  691. /*                                                                                                                                                */
    9 s7 o, V8 I, V1 n8 ]
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */. O1 [9 L! s# j; l  N) i( Q8 t
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    & T7 q% i' d  G
  694. /*         unless AAI is programming the last address or last address of                */8 r) n2 R" r: G( s3 y# x$ E
  695. /*          unprotected block, which automatically exits AAI mode.                                */( v6 s2 e. k! c& o2 {4 ^
  696. /*                                                                                                                                                */
    & ], n: @3 |0 |
  697. /* Input:                                                                                                                                */
    8 y6 r& q( Z5 y( H4 @
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - c+ Q' ~' U  Y" b$ Z; o- J
  699. /*                byte1:                1st byte to be programmed                                                        */  u. w# ]' R5 N. }
  700. /*      byte1:                2nd byte to be programmed                                                        */
    7 j9 y7 P1 {) l3 S' U, f: S9 [
  701. /*                                                                                                                                                */! k- r  \/ n) `6 c4 S
  702. /* Returns:                                                                                                                                */+ e! q8 c4 Z/ @# y% n! G
  703. /*                Nothing                                                                                                                        */; R( @! a6 r" K9 y5 `4 v
  704. /*                                                                                                                                                */) @0 e' M& V0 h0 ?) G
  705. /************************************************************************// C8 T" o: d( X4 w
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ) b8 ]: Y# {% }9 x4 A
  707. {
    7 v/ w4 c2 A( @0 g1 X( V
  708.         CE_Low();                                        /* enable device */! S4 T! v/ c) a
  709.         Send_Byte(0xAD);                        /* send AAI command */
    . a% W* `8 b2 ~7 `$ e
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ S! |4 _* S6 s! P
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 g7 U! @; }( o5 C2 P
  712.         Send_Byte(Dst & 0xFF);
    ' f/ `; a+ X, Q3 ]  j; m4 S5 B
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        # H% }0 _2 M9 L
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    * p% u% F" y3 I. C/ }8 \& b
  715.         CE_High();                                        /* disable device */
    5 z9 y8 [& M7 v' x$ S/ G0 d
  716. }0 u8 a8 k: F# n9 x; ]

  717. % r1 l( Y, o  J4 [
  718. /************************************************************************/. N6 |5 P2 r% r! Z2 m% c1 X
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    - O6 e2 f2 H) k2 _
  720. /*                                                                                                                                                */
    8 B$ F1 F+ S* D& X
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/' a* n5 R* O. S, C+ `7 J
  722. /* the device:  1st data byte will be programmed into the initial                 */
    - t& s% ], Z. q, \$ z
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */, H  d9 I# P) M* Q
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */% r9 T" s3 R" e9 h6 w; Y& z( c
  725. /* is used after Auto_Address_IncA.                                                                                */
    . t: \. i9 K, t; }4 z) G7 q3 j2 I
  726. /* Assumption:  Address being programmed is already erased and is NOT        */% Z# `! l- c  o
  727. /*                                block protected.                                                                                */
      \% }; b3 }! k( X! W$ A! h" Q
  728. /*                                                                                                                                                */" _/ ^8 U9 E3 n8 k, h  C
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    % P; l- c3 p/ D, W/ Z& Q2 d
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */9 m2 `6 ?+ t' o5 m3 ~
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */( x$ [& p6 N! T! I$ ^1 ~0 ?: Q
  732. /*          to exit AAI mode unless AAI is programming the last address or                */4 @5 O0 {, u8 y
  733. /*         last address of unprotected block, which automatically exits                 */, M# e* u# A- w/ R0 }
  734. /*         AAI mode.                                                                                                                        */- m, {4 e. d! T- z- v2 ^6 U$ B
  735. /*                                                                                                                                                */- t* Z" |4 w6 x( w1 J9 H0 l
  736. /* Input:                                                                                                                                */
    7 H+ G5 a! @1 q) F2 t6 m; P
  737. /*                                                                                                                                                */( m  t; b( _2 E* [; p4 U: N
  738. /*                byte1:                1st byte to be programmed                                                        */
    & k- L2 ~7 B+ x6 _" N3 @
  739. /*                byte2:                2nd byte to be programmed                                                        */
    8 O4 X( U; B- m( E
  740. /*                                                                                                                                      */- j/ L& U; r0 d0 b; y
  741. /*                                                                                                                                                */
    & G* G: y: ]- ]* k+ a
  742. /* Returns:                                                                                                                                */
    / l# x/ U8 d  n, k/ h( f  {
  743. /*                Nothing                                                                                                                        */
    , s& Q8 i6 b7 b+ d2 S# Q5 Q
  744. /*                                                                                                                                                */
      S. K+ d. ~$ i) L
  745. /************************************************************************/7 ]  z  D9 m2 {
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    ! t; M; D2 A% X1 ~% Y7 h! S; Q
  747. {
    * {3 N0 z" p. T6 @5 Q6 ?, O6 ~  M  a
  748.         CE_Low();                                        /* enable device */  i2 ~) ?1 \  o: {
  749.         Send_Byte(0xAD);                        /* send AAI command */
    , o5 _9 ~- D. H0 Q3 E. u+ ?! a% ^3 [
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed *// |# I6 G2 ?5 _) `3 }; N+ _- J
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    $ m. ^3 F3 @1 [1 F+ i4 b9 x0 Q+ R* d
  752.         CE_High();                                        /* disable device */" ?2 ~, d# D: u
  753. }+ G. s, ?% F. }: _- I; C( M

  754.   ^2 K6 Q. w) w3 H& I
  755. /************************************************************************/
    4 N: z9 {( k1 i. s
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */+ z$ L; H3 Z4 i! ~" q
  757. /*                                                                                                                                                */+ R6 P  w( o! D
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */& f3 y, b/ ?2 l7 i% f0 f( Y. P5 X
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    ! [2 W5 {( e/ J& i$ D
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ) O5 R, O% S6 X& P+ K; U5 ?, P( y
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    + ^# z6 X/ U" l- q  U$ w
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */0 ^2 T" ~. |" H
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    , b9 G- g7 ?8 W" l; B- m& I
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */3 \, J) u" Z; K3 `* `
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    # V+ y2 t) J- Z# q# D4 y( k
  766. /*                                block protected.                                                                                */4 _# D8 `: ^) |2 u8 S4 k
  767. /*                                                                                                                                                */4 Y! Y# |4 G8 ^9 B% H/ m# V4 `
  768. /*                                                                                                                                                */) |. _: j+ o) u, N' \0 ?
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    3 n3 F' v! Z; u4 b/ L2 W
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    4 o( |& B* ~8 p( f
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */2 \: k% o# L: t1 s% l" f
  772. /*          to exit AAI mode unless AAI is programming the last address or                */7 M6 M% W/ l. j( r0 G) c9 @
  773. /*         last address of unprotected block, which automatically exits                 */
    2 r& c- S# H/ g, M! {9 q1 A
  774. /*         AAI mode.                                                                                                                        */
      Y+ S- m' O( V1 e2 u
  775. /*                                                                                                                                                */
    : o5 V/ V$ `3 H
  776. /* Input:                                                                                                                                */: i( k) \  H/ _5 Z2 `; d. X2 k
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */$ Y1 |. I# l% J$ l" a
  778. /*                byte1:                1st byte to be programmed                                                        */
    1 Z# p  d/ [; R: ^
  779. /*      byte1:                2nd byte to be programmed                                                        */% P; ~; H8 ?) Y) o3 J
  780. /*                                                                                                                                                */
    ( t# r$ a; M3 p, Z
  781. /* Returns:                                                                                                                                */
    5 T3 S* j2 G* I6 Y2 w6 f
  782. /*                Nothing                                                                                                                        */$ l1 u  H; V) [1 u# l6 c
  783. /*                                                                                                                                                */8 B9 M) M: P, |/ [4 V, T" t
  784. /************************************************************************/
    0 }% ^7 r6 T# q+ K+ U7 h
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2): C0 f8 I2 A5 k1 T$ j- G
  786. {
    ( m' y. Y: Z* A5 H7 J4 m
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    8 r- Z+ Z, _; K0 @) r1 W: r/ c
  788. $ P; k  Z3 h: m1 N9 n$ A/ n7 w6 q
  789.         CE_Low();                                        /* enable device */6 W, p- y6 w  X* A! _
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ! W2 x( x  f, `; H( k# ]3 G
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % p# _$ z3 f% _  T- r
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 j  W' Z7 h. {2 d: j# }. q
  793.         Send_Byte(Dst & 0xFF);$ ^) o* F- r# m# X3 u# T5 n/ k" B$ r
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    $ r. w' N$ z. P5 ~" \
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 c; S, @# U; V& e
  796.         CE_High();                                        /* disable device */
    : J' o/ k3 C2 K4 e. y4 d8 @
  797.         ( s$ H% Q5 [4 [7 E$ b  Q& m$ N
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    1 {) j; r, e4 v: w/ c. h: U8 k9 T/ H

  799. 1 N/ F# \, ~- ?0 C2 r/ Y
  800. }
    , h' Z5 }$ G- O" g$ Q* W; u
  801. ! q" q* b. G4 o
  802. /************************************************************************/% a, `: H4 B$ ?
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    7 Q1 t0 L' |/ o* I
  804. /*                                                                                                                                                */
    ) M- ^$ c+ x! r$ ^3 ^! R: [% Q
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */( j4 L' D; C) C7 x6 X
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */$ Y6 v) k& F' e# z9 v9 j
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ) }5 }1 Q' e$ X/ |5 ~' I3 C5 {
  808. /* the device.  The 1st data byte will be programmed into the initial   *// j; n+ v3 [( P% r
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */: ^4 t1 d3 }) _, H  g3 T9 u1 @
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    , |7 Z; b8 r  A0 o- r( `
  811. /* used after Auto_Address_IncA.                                                                                */. f8 B- H7 c% a7 h& G% J4 u
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 j0 ^) T0 t0 A& p6 o1 e# A* H
  813. /*                                block protected.                                                                                */# O2 f* |: C1 V& ?$ a
  814. /*                                                                                                                                                */. [) P/ \* w4 ~/ c8 ~" q" B+ W( }
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    4 k+ `+ J: y' j; R/ m" @3 d  z. s, Q
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */! x' _$ d. b% ^# A" z
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    9 V" ?  X* r/ o* }7 y
  818. /*          to exit AAI mode unless AAI is programming the last address or                */( n2 J' z: N' C2 O3 X  u+ i
  819. /*         last address of unprotected block, which automatically exits                 */
    + g8 v2 X9 J; }
  820. /*         AAI mode.                                                                                                                        */
    - |+ z& {& }# P/ P7 u, e' V, j. O
  821. /*                                                                                                                                                */
    + P$ C% f' ~" F/ x; V
  822. /* Input:                                                                                                                                */; }# k) W$ a: H4 q3 K6 B# R( J9 A4 a
  823. /*                                                                                                                                                */+ m. {9 G% K/ z0 \# B
  824. /*                byte1:                1st byte to be programmed                                                        */4 e+ M1 _& \+ |) l7 A
  825. /*                byte2:                2nd byte to be programmed                                                        */
    $ x6 y+ F1 l$ F! T9 ~
  826. /*                                                                                                                                      */
    : E9 z$ y1 f9 L) b
  827. /*                                                                                                                                                */
    " I8 p: ~7 o; o" e& y9 l
  828. /* Returns:                                                                                                                                */7 ]: P, D0 v/ ^+ Y* O: `7 }
  829. /*                Nothing                                                                                                                        */$ H2 x9 ]" L4 g1 T# J* R+ F
  830. /*                                                                                                                                                */
    ( h& _0 ?2 P! ]! P
  831. /************************************************************************/- q- m& H# ^2 E& d- m
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    # S* ^/ }' R# G: |8 b
  833. {
      p; m, P. D: Y7 _
  834.         CE_Low();                                /* enable device */$ K( d8 Y. z8 q& |* a2 D  q
  835.         Send_Byte(0xAD);                /* send AAI command */+ n! s( ]" {* n3 ]
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */0 x' ^( |0 w/ L2 `. t2 o- w$ Y
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ( f; e4 [' |7 ~: W+ w& C' _
  838.         CE_High();                                /* disable device */' g1 F. d3 b! x

  839. - B4 a* M) T8 b) G& c& u' b: {
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    - [6 ?7 Z0 x( L  v3 l
  841. 7 F2 r. w7 v' s
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    4 L- }0 u/ E! g+ c# p' y+ W( z  P
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI *// ]6 q( o( K6 V
  844. }; m' l7 j$ b- c: D1 C
  845. ' k1 H( P' U+ A/ _
  846. /************************************************************************/; i( o2 q  h2 ^# q% U0 B
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    1 f7 F& u! i4 e- ^. i8 Z6 J3 R! @
  848. /*                                                                                                                                                */
    3 n# a% e1 ?8 K- l5 t% r% g
  849. /* This procedure erases the entire Chip.                                                                */4 Y+ E. a7 }$ y2 h
  850. /*                                                                                                                                                */
    ' p+ z$ X' R$ A4 I1 e* `3 Y* B
  851. /* Input:                                                                                                                                */8 E( ~: x% G- ?: I: h7 L
  852. /*                None                                                                                                                        */5 l! P* E- i# ]- D& x) V
  853. /*                                                                                                                                                */  k3 z$ B1 M- S$ s
  854. /* Returns:                                                                                                                                */7 {+ M' b7 A. |( H& u
  855. /*                Nothing                                                                                                                        */! r# v# ?  a( P% y$ ~
  856. /************************************************************************/5 I* Y) N0 `+ Y' F, D1 z- ~
  857. void Chip_Erase(). D  n( E, t/ G% W# J  J* m$ F
  858. {                                               
    ! H, b$ l0 x6 L6 ^; c# m% l2 L
  859.         CE_Low();                                /* enable device */1 ~' K2 @* e  C$ _1 ~
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    ( j: s0 b: {  N/ `* L- ]
  861.         CE_High();                                /* disable device */
    ) S3 r- g! q/ C: S/ |
  862. }
    + s) P3 q" {( i" E+ }

  863. 1 {: h# S  L( w) [0 F
  864. /************************************************************************/) ]  T7 c' c3 T. ^( V
  865. /* PROCEDURE: Sector_Erase                                                                                                */' m+ z5 B: m% V& s
  866. /*                                                                                                                                                */$ N( b: C" o: e5 B5 U0 Y
  867. /* This procedure Sector Erases the Chip.                                                                */
    ( c8 v# ^( V2 {
  868. /*                                                                                                                                                */
    " N" j- e1 N; I9 D. L) }. F# Q
  869. /* Input:                                                                                                                                */
    " S" b  j# B0 \) A: ~
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # b9 _5 ~" U+ o% }1 A: L) S+ \
  871. /*                                                                                                                                                */4 J8 Y/ M. q+ a) L
  872. /* Returns:                                                                                                                                */
    , O4 f8 H3 C* w4 [8 u
  873. /*                Nothing                                                                                                                        */! i( t1 H/ o# K  w0 Z
  874. /************************************************************************/  H) @5 T5 T' G, X  ~# a
  875. void Sector_Erase(unsigned long Dst)
    , [+ _$ \0 S5 q& @; w7 {4 h
  876. {% }1 n% ]& Y9 f, f( f) j; `$ q

  877. , E  h+ z+ r2 t7 x% h/ j! @
  878. # G7 Q% R- d+ b. N# [
  879.         CE_Low();                                        /* enable device */5 W! M  S) r. a! ]) x, t
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    / @: Z  M/ M. d, H0 K
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 g- n% i& L: G1 t5 y: K# l; Z
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 _1 j; L8 Z5 s, E7 P, P
  883.         Send_Byte(Dst & 0xFF);& e1 K1 o& N: T4 H5 o0 f. }
  884.         CE_High();                                        /* disable device */5 O9 |. _; x& t7 @) ?! `" N
  885. }        3 R1 S/ C4 ~1 H# P" }
  886. 1 N6 c6 {* f' t" v* G1 u' g
  887. /************************************************************************/
    ; _* P% O3 @# D" m$ M6 {& C
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */2 @' I. t" D# c+ L- m& T" {, D& u
  889. /*                                                                                                                                                */. o- b3 Y7 a4 h6 b- y; y. A
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */7 d* X  ^1 U/ Z: ?, z/ ~* ?: i
  891. /*                                                                                                                                                */
    ( d  y: d' N2 t. A9 g" e
  892. /* Input:                                                                                                                                */8 v$ L9 l, J: U3 y/ h
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ B- u. V' f; ?. N% h# P1 y
  894. /*                                                                                                                                                */
    7 G+ K( A) Q$ U7 F
  895. /* Returns:                                                                                                                                */! w: Y. m" f+ w) b# N
  896. /*                Nothing                                                                                                                        */! K1 Y3 `$ N" \
  897. /************************************************************************/
    5 C! L: }* K" A% f, X1 X
  898. void Block_Erase_32K(unsigned long Dst)4 d* O, l% l/ z- [% a0 e
  899. {- m: c( T% H: b6 {, K
  900.         CE_Low();                                        /* enable device */. u, f8 p3 N# P4 S9 B
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ! N$ N& C0 w$ S/ t4 K# ]! h
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 C$ h* w7 h3 X' E0 }
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));1 m8 w! `# f5 @. l* T; t2 Y3 Y+ ^
  904.         Send_Byte(Dst & 0xFF);5 F6 R! D( ]# W5 W9 |6 d
  905.         CE_High();                                        /* disable device */' W' m' C6 c5 X2 V. T& J/ m
  906. }  ~# B4 D) \+ I& o8 E: E
  907. & \, M% w, `+ t7 I+ x
  908. /************************************************************************/! q$ H+ x; }, o( h4 R
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    + O% k6 {" z) C1 c
  910. /*                                                                                                                                                */
      h$ {2 W/ k' d# A
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        *// a) b- j# J0 T+ A+ |5 _$ U2 S" U! d; R
  912. /*                                                                                                                                                */
    ) f7 z. s' f5 ]
  913. /* Input:                                                                                                                                */
    + i/ i* {( `) p+ E0 e( G- Q5 h
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 Z8 K. ], w+ H: C: W, L5 C
  915. /*                                                                                                                                                */$ R. u( I, f" ?1 I' ]
  916. /* Returns:                                                                                                                                */' k- |+ k2 C  |. L) i
  917. /*                Nothing                                                                                                                        */- w$ ~9 i5 L  h- a: y* e0 E) G$ f
  918. /************************************************************************/& f& D" S: `! |/ b# r$ p, Z: b# a# e- ~- F
  919. void Block_Erase_64K(unsigned long Dst)
    + L  s5 R4 }" N2 {4 v( s$ F
  920. {* s) \# D; e% X! K) Q9 y: N9 `: D; g
  921.         CE_Low();                                        /* enable device */
    ! s# L# ^: o3 q. M+ w1 `
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command *// ^: ]  s; o/ g3 D8 T& Q
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 _  x: ^2 h) l& H2 t
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));3 D8 w$ A9 o; H0 u* A  n- [
  925.         Send_Byte(Dst & 0xFF);, H" L" u0 E/ ?- W+ j; J4 N% G
  926.         CE_High();                                        /* disable device */
    ' K6 u" x( y$ P( W: j
  927. }0 u+ N# S2 |( t5 \

  928. ; g8 P- l# l- @7 S( D
  929. /************************************************************************/9 y, d. I* C3 J
  930. /* PROCEDURE: Wait_Busy                                                                                                        */3 b( |9 X/ Z' d9 h8 r
  931. /*                                                                                                                                                */7 i/ v3 j, J8 ~! P" q
  932. /* This procedure waits until device is no longer busy (can be used by        */
    6 u. R" n3 A8 f3 o5 x- {/ G
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    9 w5 R; u8 L/ r% s, ~9 R1 Z
  934. /*                                                                                                                                                */
    + Z3 M% K# E: d- e
  935. /* Input:                                                                                                                                */  V. s" Y3 t* {* j6 z4 s6 ~% E  d
  936. /*                None                                                                                                                        */+ S- R4 F) C0 v5 |( K% \* g  q5 q
  937. /*                                                                                                                                                */
    + j8 k3 d5 c1 m/ J  D
  938. /* Returns:                                                                                                                                */1 i3 |1 [6 S6 q' r- O
  939. /*                Nothing                                                                                                                        */
    * V& d, u2 G0 n% x# v
  940. /************************************************************************/: B/ }, _& Y# ^4 E1 L
  941. void Wait_Busy()# x- D$ Y, |4 \/ h* Z
  942. {3 O+ [$ b8 R/ `
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    0 r9 M4 N: |& ]
  944.                 Read_Status_Register();
    9 F% v' c1 t/ _, ~5 K! j2 q
  945. }
    & s  S4 i, E& g$ [+ c

  946. 6 q4 S7 d! Z) q/ {
  947. /************************************************************************/
    ' M5 K7 e8 x, O4 z" ?
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */+ O$ q% U8 M# V. {- j
  949. /*                                                                                                                                                */
    8 d  K' q$ w5 \9 T+ c4 p- l
  950. /* This procedure waits until device is no longer busy for AAI mode.        */3 I+ W. w3 p% C1 E6 P8 C
  951. /*                                                                                                                                                */  v5 `( J5 ?1 A) V) O
  952. /* Input:                                                                                                                                */
    ; y, v' F' ^$ c( Z) S; G
  953. /*                None                                                                                                                        */
    1 B: {2 s* N0 s6 p  z! C! `
  954. /*                                                                                                                                                */% E; d" S, \: O+ G
  955. /* Returns:                                                                                                                                */
    ) {) U# P! w# a8 k
  956. /*                Nothing                                                                                                                        */) S* d2 O& t# C2 J& y
  957. /************************************************************************/) U% A4 [# E* D/ O, m
  958. void Wait_Busy_AAI()
    " p6 v% R+ S5 I; Q. \5 |
  959. {
    1 v! O- p) Q/ M
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    / u$ X/ m. d" w$ g4 u7 o! N
  961.                 Read_Status_Register();* E; V  X( }- [, a& h% J/ E
  962. }9 ]- A" e& @9 m1 w* k

  963. 9 g" @: D. a5 N) U( v
  964. /************************************************************************/" a2 n! Q) M! v1 X2 t# b! m
  965. /* PROCEDURE: WREN_Check                                                                                                */8 y3 o  I" V2 N/ K) h! O
  966. /*                                                                                                                                                */* N' l% E6 S6 V2 T
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    / m, q! t: \5 T. ?( q
  968. /*                                                                                                                                                */2 U' K+ E; a; Y2 f  `1 b
  969. /* Input:                                                                                                                                */
    8 y+ }" r) X" W: \  h: c& b
  970. /*                None                                                                                                                        */! d! ^( D- _4 L9 u6 n3 F' N
  971. /*                                                                                                                                                */
    3 l( b. }/ @7 C5 J/ E* z, d
  972. /* Returns:                                                                                                                                */
    ; J+ O) a! t  ]
  973. /*                Nothing                                                                                                                        */
    8 K( m4 e: A5 s  K* Z
  974. /************************************************************************/7 |& j) x6 S# }: s3 Q" f. M0 m
  975. void WREN_Check()
    + c9 n! \5 f' P, m* M/ [6 k/ K) p/ Q' h
  976. {1 Z6 M7 m; o  M- ~5 y9 E
  977.         unsigned char byte;. s! q# \* E0 i: \1 k' Q
  978.         byte = Read_Status_Register();        /* read the status register */( V; o# X3 l6 Q6 b# h) j8 L4 i1 `
  979.         if (byte != 0x02)                /* verify that WEL bit is set */  x( K8 k8 X5 Q, q* U
  980.         {
    3 \2 S; s- q3 W8 }/ P
  981.                 while(1)9 S. z% y, v, r7 H7 l5 ]0 v
  982.                         /* add source code or statements for this file */
    6 Y. P6 q# Y4 u( S
  983.                         /* to compile                                  */
    " X, H) @8 y$ w, @
  984.                         /* i.e. option: insert a display to view error on LED? */: _3 i- c% L9 K7 x* ?
  985.                  
    ) F) x# X2 n+ z  s
  986.         }$ ~: o! [  _# K& c
  987. }
    " y2 ]1 o4 ?% A' d6 B' W% X
  988. " K3 t  r* J, a: y  y  n+ s
  989. /************************************************************************/
    0 S& M. L& I8 [6 E) i4 y
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */% R+ b! j6 E; v8 e9 p
  991. /*                                                                                                                                                */
    9 z. |0 K: M' b2 G% Q, R
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */6 h( m% i4 O5 {2 A
  993. /*                                                                                                                                                */( K- b4 e' q+ a' d9 ]% C# a& t8 W7 a
  994. /* Input:                                                                                                                                */
    ) x4 H$ W7 i$ r! [
  995. /*                None                                                                                                                        */! Y& n. o- K+ Q4 ^: l4 w' n+ c
  996. /*                                                                                                                                                */0 \/ \1 v$ M" J9 ]" ~
  997. /* Returns:                                                                                                                                */
    . l3 |& B6 ^" Z; j. W0 e5 _
  998. /*                Nothing                                                                                                                        */. @: D# Z# k3 d" I9 n- A+ U
  999. /************************************************************************/
    , J! @8 i3 {1 l& f  V+ F- z& _2 B
  1000. void WREN_AAI_Check()
    3 Y2 ~. w/ _2 P; C
  1001. {- E; ]3 z' n9 c- X
  1002.         unsigned char byte;
    ( \, J: P+ W' a8 Y
  1003.         byte = Read_Status_Register();        /* read the status register */8 h) K0 i, M, C, G$ [3 B$ w
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */2 ?4 f8 ~# Q+ }1 c% D* v
  1005.         {  G! {4 N" j5 N% \9 g; O0 B
  1006.                 while(1)               
    3 U& ~6 }% ?2 C! f, K! q5 _4 @
  1007.                         /* add source code or statements for this file */
    ; Z. s' y+ X" }; B5 U
  1008.                         /* to compile                                  */; G" k; A: l$ K, n  p8 L/ n
  1009.                         /* i.e. option: insert a display to view error on LED? */$ i7 a- e# C4 D1 u! @6 a3 m
  1010. , F- r- [5 C: h8 p0 x$ O
  1011.         }
    ' k/ p& R; Z3 |1 b  `) M. \
  1012. }
    * x: Q: M  R6 Z5 U, A

  1013. - I0 i$ Q. v3 V8 Z; n, R3 O  h
  1014. /************************************************************************/
    % R, a% {. \& `9 s& m& ^
  1015. /* PROCEDURE: Verify                                                                                                        */
    3 i( v- ^4 S4 z4 x+ d" T
  1016. /*                                                                                                                                                */
    % i* @- x& e4 n4 `: y, M
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ) ?" {- @( y& c8 F. K- q4 T; \
  1018. /*                                                                                                                                                */+ w9 y0 @* P+ ?8 F1 A; l
  1019. /* Input:                                                                                                                                */
    # E) W$ Y% H" {
  1020. /*                byte:                byte read                                                                                        */
    " D# ~4 M3 ^; |( q. d$ _2 y6 ]) L
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    , e! ]6 k+ ^3 M! c9 v
  1022. /*                                                                                                                                                */9 u$ w* o% k: V4 k+ ~1 j
  1023. /* Returns:                                                                                                                                */! Y) W$ G/ P+ q$ D" b
  1024. /*                Nothing                                                                                                                        */
    * d( |2 A6 F. S* H
  1025. /************************************************************************/: Y; u8 \. p6 a% O- G" P0 D
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
      ?- K, k3 Y2 b
  1027. {
    $ D( W$ }! y  [7 K
  1028.         if (byte != cor_byte)
    * z# U1 Q2 L5 f" P9 \4 K
  1029.         {
    - `& S0 |$ S3 T
  1030.                 while(1)' P, B3 N! Y2 n5 ~8 z; c! L
  1031.                         /* add source code or statement for this file */) z* W7 ]6 |3 S4 N
  1032.                         /* to compile                                  */: p, ?8 [" h0 h% X* k: q1 u0 h
  1033.                         /* i.e. option: insert a display to view error on LED? */! K- P) ^) q" P9 e7 X: V$ U
  1034.                 ' Z" \3 G- t! E% R  D. X/ c
  1035.         }
      i9 D/ D2 s9 Y) {0 T
  1036. }0 N8 t! I0 r* ]& Y# J

  1037. / G" P. p0 p5 C0 H' O1 }  }/ W
  1038. $ L4 E- h* u4 F$ x0 f! i
  1039. int main()
    6 E- x4 c/ @- u' u# g
  1040. {% \7 {+ K5 W, S* J: k
  1041. . T/ c3 E# s  u& ~
  1042. return 0;
    ' f& F6 A4 }1 c9 L. U6 h- ~1 F
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
- F0 b6 F* B  j$ P   main()
5 d* P& a! V" `% f7 S   里面怎么是空的呢?
. P: e9 _) U' g7 a3 N1 ]0 j1 w   发一份给我吧: P) o; {+ l: E0 X2 i4 L- I( z
mail:luyijun2005@hotmail.com
, L$ C5 H! n) D: n; M# L3 r# v% \' e咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。+ |$ J6 J2 C& b9 n" l/ \
" c" `  ~& d* O
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
4 d( i6 L% p" }% ^+ H* l' \EC的代码在哪跑,你看DS的说明,每个EC都不同的。
- S9 E0 C$ g- W6 u  `OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?0 u; j1 x# R3 {$ J: q+ o
上面几个问题是你没看任何东西而白问。
+ ]& H+ t* z) L/ z
3 y# H7 D0 \1 C; n& E( I7 N至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

# o6 M; r, F- ^, o( Q关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
4 D6 i4 `7 T9 R6 g& K4 Z1 U+ i9 D1 ]/ \  g
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
4 d& h. Q' x+ U& M$ q* M0 e
) l+ |; D4 v  x) v关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...) S0 k  B! I- z+ `

' }+ t7 h) S' b3 `( S5 f& R7 Q不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样! R0 g6 ?- J/ t8 o  |
似乎要把SPI能support 到最大,这EC chip应该有好卖点
  n1 t2 ^! b% w/ e! E& X- D2 |2 fBIOS功能要不要强大,也就决定了SPI Flach的大小
( R5 K! h, N0 \2 Y我是这么想的~让OEM去决定要挂多大!  ]5 l7 h  P. a  F- H8 ?- ]
如果我司有BIOS工程师就好了~哈
) i# ~/ K8 N7 |" B4 \' \- |4 ZWPCE775应该算很新的东西,来看它支持到多大?
- x: p( W* L3 x( Y6 k* t8 i# a- ]5 I3 y. u* J  `
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte7 w5 x+ n; e' t
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
5 ]$ B, Z- c" ^6 l9 S" V8 G* Y# D  v; W- u8 B
这份driver收下~希望以后有用到
& w/ }% J2 |- l/ s. T" J' s6 V谢谢bini大大
  d: X. J( w" r
6 U5 Z% g" p/ `3 ^5 }! u% G5 r' \很新很新的新手,如有错误请指正 (准备看第二家的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()
5 u6 g* U. A! w6 [{
1 `# e2 X& }- v1 S4 f3 S; b        unsigned char temp = 0;
1 ^; q7 |% G9 g) l        CE_Low();# L* N0 R: ?% X+ P9 Q  ^7 G
    while (temp == 0x00)        /* waste time until not busy */- q7 l8 l' h6 m9 F# o
                temp = SO;
: y) `5 {5 l8 a% @7 _- E        CE_High();$ }# H3 a: ^% t) i
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)( D2 b$ e) z9 Y* P4 W
{
4 _- s0 n; h, ]" ?& E8 G# F; b        0 o/ h8 E" g5 C& y$ c" b& z
        unsigned char i = 0;
3 C+ a4 O" z4 [  m7 z/ }% x        for (i = 0; i < 8; i++)# T# B4 ?( z* n. ]0 w( J7 C! E# c
        {, D, n* D9 Y6 `3 d5 E
                ! h: O' C0 l8 Y; ~& b8 C" S
                if ((out & 0x80) == 0x80)        /* check if MSB is high */: v( H" L+ [5 u2 v$ _+ d0 E7 C
                        SI = 1;4 e1 z( v, o1 `7 I* y( H$ U
                else
, B. v" S. n% |' [4 r! r  O                        SI = 0;                                /* if not, set to low */* a8 O/ S$ }5 X
问              SCK = 1;                                /* toggle clock high */
# L" n  N. u! s) O" v   题            out = (out << 1);                /* shift 1 place for next bit */* w+ @1 k8 |& _, [
                SCK = 0;                                /* toggle clock low */0 Y# V. z  [3 @6 P; N
        }
0 a; \' f3 z$ g1 _6 b}( V: A4 e( C& C
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-29 05:47 , Processed in 0.035473 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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