找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55317|回复: 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; ]4 c/ S' i, Q+ R+ u

  2. & M: T% J' m& p2 f, _
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory7 x' n7 S) _" n& }; t6 o
  4. 3 F. b& F( a  n" L4 x0 m- E
  5. November 4th, 2005, Rev. 1.09 l" V8 U0 O* S# x

  6. ! x+ _; `$ D- M$ Z0 c! T" r
  7. ABOUT THE SOFTWARE
    4 O8 q# m  N1 J+ N
  8. This application note provides software driver examples for SST25VF080B,
    ! w! e' J8 ~1 A* p7 ?& S* K2 G
  9. Serial Flash. Extensive comments are included in each routine to describe
    , x8 H4 a+ o9 \4 L. v  F
  10. the function of each routine.  The interface coding uses polling method ( u' C( F( z$ m! ^
  11. rather than the SPI protocol to interface with these serial devices.  The$ L  L, i4 \4 D$ ^5 r) w5 A5 J
  12. functions are differentiated below in terms of the communication protocols5 Z8 m  B' K6 N' @
  13. (uses Mode 0) and specific device operation instructions. This code has been
    2 D0 f( ?' T+ l' g- A+ F
  14. designed to compile using the Keil compiler.
    9 @7 s. K2 R1 {9 G0 \8 K2 {
  15. " G4 q, l- X( a# p! H* M
  16.   w: f* A) K9 {3 H
  17. ABOUT THE SST25VF080B3 }) Q$ D; u0 t( G' v/ ?
  18. ) O. M0 \7 p# `  m# F
  19. Companion product datasheets for the SST25VF080B should be reviewed in - g: W( y) |# d0 P
  20. conjunction with this application note for a complete understanding ; t* l# _) P# C' Q- i
  21. of the device.
    + I" D0 a7 I. N
  22. 6 C& L" X9 T  l5 K' e5 q& `1 k
  23. : E6 O5 n/ ]6 p) l
  24. Device Communication Protocol(pinout related) functions:0 E- f% T7 L/ N- j9 z

  25. 4 n) d3 g2 n' ], M3 H1 X
  26. Functions                                    Function+ D+ ^: {1 g- P; y1 w4 W
  27. ------------------------------------------------------------------
    ) Q3 _" S! i1 I: E& V( U6 M2 {; r
  28. init                                        Initializes clock to set up mode 0.$ @3 X  j* r, F3 Q7 M
  29. Send_Byte                                Sends one byte using SI pin to send and $ I. X# `, i/ ?6 I. `
  30.                                                 shift out 1-bit per clock rising edge1 N$ o( i* F/ t' u; |) {0 v1 B0 S
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    $ o0 W6 P  p" a
  32.                                                 in 1-bit per clock falling edge
    8 w1 t; l$ h- j  f+ R
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming8 E5 Z2 P0 T& c( d0 Z4 Z
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    ' I- |) _  J/ u* U. n
  35. CE_Low                                        Clears Chip Enable of the serial flash to low0 ^/ _3 |* L8 S" b* g
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    * l, ~& |* W; H8 S2 i& f
  37. Unhold                                        Unholds the serial flash/ J9 u: _, @6 G8 D+ R
  38. WP_Low                                        Clears WP pin to make serial flash write protected2 q5 A: i7 v, s  U# B
  39. UnWP                                        Disables write protection pin
    9 \# U. F% X% O* V& X3 z

  40. - S! g. k& D/ e: w" h: e7 e+ l
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code& K" z( y" Q7 h% m  y
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your$ @* c3 v: w0 O' `1 t2 n, F
  43. software which should reflect your hardware interfaced.          6 h: X+ K: J2 `' X8 e6 `) t* @3 C
  44. & L6 Z! s* i# {, B! \

  45. " i, K: Q3 Q; D' j9 k
  46. Device Operation Instruction functions:* \' I7 _8 f" {' H( U* p, d

  47.   E9 l- b! e7 o
  48. Functions                                    Function
    * f1 F5 a6 ~, X
  49. ------------------------------------------------------------------
      `- s# X3 H' V  t) |% R% K
  50. Read_Status_Register        Reads the status register of the serial flash7 q) z& q- B# ?8 U# O2 n; M
  51. EWSR                                        Enables the Write Status Register
    : E" ^/ G! x$ j
  52. WRSR                                        Performs a write to the status register
    6 ~# S  J0 f% ]% l$ L2 r) z
  53. WREN                                        Write enables the serial flash
    & s" K% T1 O( Q) X
  54. WRDI                                        Write disables the serial flash5 n* @7 Y! Q8 O$ o$ l
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    2 A6 Y; u3 d7 c# m
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    ; E2 O8 W% e3 D8 m& J
  57. Read_ID                                        Reads the manufacturer ID and device ID. o9 n1 G  u9 k- U6 Z; [3 C
  58. Jedec_ID_Read                        Reads the Jedec ID
      I& \! w4 p7 q# b$ q3 p" g
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    # K0 {' ^* G2 ^# I( e
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency), ]* f) ~* |) Z5 L
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)" P) q% F( H+ j$ `% p' l
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    : J3 N2 P# l  [' I' m1 \& M- N3 {( h
  63. Byte_Program                        Program one byte to the serial flash
    & J' C; R- z+ V  l0 n0 a" C
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ( G! x2 f0 N! H1 G; J
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation3 R% r: l2 G4 X: V* k
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    6 v) i+ @, o3 s3 p8 H
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY! |: o! h4 G) H. I2 |8 B) \
  68. Chip_Erase                                Erases entire serial flash
    + S9 a: ^. k' {# T6 l! c" u1 [
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    5 `1 p( U% |: n# V4 m9 o' R
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    4 K( s( r8 _1 k8 z
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash7 {& B- y" Z/ }$ a) E& @
  72. Wait_Busy                                Polls status register until busy bit is low
    ) R& r8 {* @0 g$ ]* Y: [5 U
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    ) Y4 z  T- E7 t6 a" I# g. C
  74. WREN_Check                                Checks to see if WEL is set
    ; |) H- c0 v0 A+ m4 ~: {
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set4 z. z$ ]/ R2 ?1 k! n6 [
  76. 1 {; C: a) x9 u- C

  77. * c$ p7 a: Y( m& ?' x+ o/ t
  78.   F( f6 N- H2 \; Z; t+ `  |
  79.                                                                      8 G1 o( \. ~5 p; H
  80. "C" LANGUAGE DRIVERS
    9 g0 I( Q0 J% z1 @2 G; q# z( k0 B

  81. + i/ P% Z2 E4 b5 Z7 w  V
  82. /********************************************************************/
    ' i: B& e8 y9 E5 B4 k4 `
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */& l( I9 O) b/ x' \7 ?
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */) n( Y0 m7 c  I# W6 a$ R5 a
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    / i) ~, d9 u4 g' a$ L/ r! q
  86. /*                                                                  */# t9 x9 V9 \( h% I
  87. /* Revision 1.0, November 4th, 2005                                                                          */   9 T) [* z0 [6 n+ R" u9 X# u
  88. /*                                                                  */
    9 Y7 j  I* u) A  N6 r5 P1 A
  89. /*                                                                                                                                        */2 |: n9 d( D5 c; J7 I: ]5 H" ], \
  90. /********************************************************************/) K6 L3 @3 t+ r; Q

  91. # G3 c, N# \! i) K
  92. #include <stdio.h>
    " U3 w: m8 O8 r
  93. #include <stdlib.h>
    % N9 C, J, m) ^! W: ?2 f, L; H

  94. 7 u+ `5 ^/ e( T. s
  95. /* Function Prototypes */
    . {3 D# E. k1 o- g! \) J
  96. " X1 t1 Q  f* i. T1 M
  97. void init();
    . U6 w5 L. [) V- @! s2 Y# l
  98. void Send_Byte(unsigned char out);
    ' ]8 Y9 B4 Q4 X, s
  99. unsigned char Get_Byte();& k0 z% O+ ]$ h4 Y6 D: C
  100. void Poll_SO();4 o- E6 Z; q8 x
  101. void CE_High();
    1 j* I/ u& C- M2 u4 m" ^
  102. void CE_Low();2 l/ U7 g2 X) M/ O
  103. void Hold_Low();. ]$ l5 f/ `- R/ r8 ?) J
  104. void Unhold();% B0 c* {( e; ]8 R
  105. void WP_Low();
    0 V& r9 `4 C8 M2 X
  106. void UnWP();
    . [# `6 |4 B! {! z
  107. unsigned char Read_Status_Register();3 j$ c0 P. j3 T! y3 t0 _
  108. void EWSR();: \8 f+ R; M4 C( X
  109. void WRSR(byte);
    6 _. Q+ f1 O" V. a4 P
  110. void WREN();
    ; g( _0 \. o0 x# {! N8 x5 w
  111. void WRDI();
    ' H3 n; r! \* P5 R3 ~1 D
  112. void EBSY();
    4 X# f% T9 F1 L: ^4 X: m
  113. void DBSY();
    0 ~: f% n: M: I2 O
  114. unsigned char Read_ID(ID_addr);
    / X. _) g" N( f4 p
  115. unsigned long Jedec_ID_Read();
    2 C$ V5 {. H) u- r6 `, @
  116. unsigned char Read(unsigned long Dst);' n. v/ _$ t$ K% h2 `& F
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    5 x) x) g' b& r7 s; B5 \. ]
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ; O& Q: j. [& q2 c. ?, G8 K
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    5 C3 h: R; Z  M# ^' @+ J/ D; R
  120. void Byte_Program(unsigned long Dst, unsigned char byte);0 d  ]) O! {* c: S( [
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);4 e2 a/ x1 `: u( O; }0 W5 a( q1 c
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);' l5 o1 e+ C5 U/ G( l' x
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    . o; {4 ~: X* Z6 B9 u6 v# g
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    1 k4 x% r5 y0 w' i$ r8 H
  125. void Chip_Erase();
    1 Y, p6 r% k: k7 u
  126. void Sector_Erase(unsigned long Dst);- [& [9 K/ {( Q0 D3 \. K6 b
  127. void Block_Erase_32K(unsigned long Dst);
    ' B$ C+ t3 `; k8 N! J
  128. void Block_Erase_64K(unsigned long Dst);
    + |1 l. A. B9 ?
  129. void Wait_Busy();" p+ _$ Y4 a% @, X
  130. void Wait_Busy_AAI();+ y$ M: m& j( z6 h& S
  131. void WREN_Check();( H0 N2 H; U) g9 d
  132. void WREN_AAI_Check();
    * U0 A  y- J  N; |+ W# M

  133. 4 ?) R( o+ W0 n/ U7 i  o- E- U
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    - v5 P' u% z* q
  135. - s) z1 K6 U) F5 v) j! b1 b. L
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    - P8 g9 s+ v1 C
  137.                                                                                 /* to upper RAM area from 80H - FFH */( ^' D! g, A% b. t
  138. / x" {# b+ {7 W0 m: _" k
  139. /************************************************************************/
    ! ^5 B) ]' v$ z' r  I: |1 }
  140. /* PROCEDURE: init                                                                                                                */
    " w! |1 `! \! z4 e3 w" x
  141. /*                                                                                                                                                */9 u' b/ s" _2 d9 }
  142. /* This procedure initializes the SCK to low. Must be called prior to         */" y% B  V) _& ]2 I- R
  143. /* setting up mode 0.                                                                                                        */
    ; g+ O0 O; X$ |5 x2 ?) x8 ~1 {
  144. /*                                                                                                                                                */
    . P/ ^' ~8 }+ d- A7 U
  145. /* Input:                                                                                                                                */# o/ Q! R0 S( M7 w
  146. /*                None                                                                                                                        */1 X# r( M$ n* i0 s, e/ ?2 d. p
  147. /*                                                                                                                                                */
    ' |, k  A4 w; F4 p) D6 p4 k. C
  148. /* Output:                                                                                                                                */( |+ f2 R8 U4 w% z  p$ U
  149. /*                SCK                                                                                                                                */  O  _8 y: T) _! c& A- e' g
  150. /************************************************************************/
    1 r3 y2 [2 U+ T* `# a4 g# V) `( N
  151. void init()
    2 K. e$ E2 P$ A9 b5 l/ s5 b/ f- I+ h4 D
  152. {5 f0 o2 r- ?' d0 n$ z5 V
  153.         SCK = 0;        /* set clock to low initial state */
    $ g  V, F- P8 u1 @( C
  154. }# P" K1 ^" p) c: F
  155. 5 ]- ~' ], _( ^7 [. i* ^' R3 h
  156. /************************************************************************/
    . r6 Y  j9 d: o; l
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    5 v4 f; u( T/ }8 p& d
  158. /*                                                                                                                                                */5 `# Y6 ?6 M0 P
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    5 _* v; b# I9 z& X- S1 @
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    1 q+ I4 Z; Z' K% t3 p4 n. o
  161. /*                                                                                                                                                */$ F# `. M! X" @1 u6 J4 o
  162. /* Input:                                                                                                                                */
    / p) }: @. U, g* [7 s
  163. /*                out                                                                                                                                */( E& n# u0 ?; c5 N8 [) m0 U
  164. /*                                                                                                                                                */% {; v2 F8 I+ P! r$ G
  165. /* Output:                                                                                                                                */
    2 G/ B% h. w% Q
  166. /*                SI                                                                                                                                */* l7 o) [1 z5 m- Z2 I9 m
  167. /************************************************************************/
    7 p( h. e8 z# n8 X; Y
  168. void Send_Byte(unsigned char out)( d, o7 d; F; f: z7 N  I/ X
  169. {; c9 Y! G7 P6 ]/ S; H! D% }1 R
  170.        
    1 P3 h  R3 ?3 T' D
  171.         unsigned char i = 0;
    3 p6 j3 D. n. ^1 b
  172.         for (i = 0; i < 8; i++)9 ]: \6 b; i1 f  T2 I, N. I
  173.         {
    * p2 W% O- |8 |1 h) @3 F7 f
  174.                 4 K" D3 K, E0 x+ G2 P
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
      A9 V0 U6 e8 W1 q! x
  176.                         SI = 1;
    : N. D+ Z8 b* M( ?/ b, P
  177.                 else
    9 `2 l" S9 b+ v) g. |9 I6 n
  178.                         SI = 0;                                /* if not, set to low */' P- Q7 Z1 L5 h+ Z. D8 F) u# }
  179.                 SCK = 1;                                /* toggle clock high */" ]' X. k# a, \+ U: w" f  ^# M. ^( {
  180.                 out = (out << 1);                /* shift 1 place for next bit */4 p4 X5 `( k: m/ }2 I1 Z% Z
  181.                 SCK = 0;                                /* toggle clock low */2 `2 |! o7 G4 O
  182.         }
    ! ?0 ^/ G" i. ~9 s% o: M6 V, @5 G
  183. }
    1 \% i* c# b6 Y! n2 Y# x' @
  184. 9 |8 x3 C* h" a' @7 m6 m1 f1 w2 N
  185. /************************************************************************/) k: d; o  y" M
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    " j: K' _  k2 A% h' d7 R
  187. /*                                                                                                                                                */
    - R; }3 N4 f; @0 M8 D8 n, B1 G5 x
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    : F3 F: M) t- [, L& a. m
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    5 J1 {# C8 O; `5 e  c9 d/ d* m
  190. /*                                                                                                                                                */: a1 A: x, k, D: _6 \! s8 L: D
  191. /* Input:                                                                                                                                */
    8 Z7 C1 `& v! u" e/ T
  192. /*                SO                                                                                                                                */# U: n& y, _+ q: N4 v0 I. d1 A
  193. /*                                                                                                                                                */( \: F5 N" h0 C
  194. /* Output:                                                                                                                                */9 ?6 [+ A0 A: c; a7 P+ P9 M: B
  195. /*                None                                                                                                                        */8 T8 H& p; L$ A$ D4 g! F/ ~
  196. /************************************************************************/% f0 E, E3 M" C8 T5 I4 c8 C0 g- m; f/ P( C
  197. unsigned char Get_Byte()
    ) ~/ L0 k% F; T3 `
  198. {
    8 [; Y8 u2 A+ R
  199.         unsigned char i = 0, in = 0, temp = 0;( h0 m" _7 T% R& H  u  {3 k( ~% z
  200.         for (i = 0; i < 8; i++)
    . ~# E4 u8 E: w" N0 Q. n- O
  201.         {$ K) w; x9 m# j' O
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */5 X1 L" _1 t* v# [% t8 L% k
  203.                 temp = SO;                        /* save input */
    # ]8 E6 G* S3 P# r- \
  204.                 SCK = 1;                        /* toggle clock high */3 K/ _* c1 R! y5 c% m7 `  P# M, ~
  205.                 if (temp == 1)                        /* check to see if bit is high */4 e; G+ d4 `) `4 F5 g* H2 f% ?! J
  206.                         in = in | 0x01;                /* if high, make bit high */! m! E, F+ `. e, o4 ~; c9 I
  207. $ `& y  }: L. j; _
  208.                 SCK = 0;                        /* toggle clock low */" B, Q9 f6 W8 W1 N9 U
  209. - r( b" w- D" J/ X" m) I! f
  210.         }
    % Q6 B, B$ \" r! a
  211.         return in;
    + J( V# ?) W5 w+ A0 \
  212. }) O) T: K$ [7 ~1 e8 T
  213. . m- \! Q% `6 l7 P
  214. /************************************************************************/( G( J# R. s  Y( p, @( j$ N
  215. /* PROCEDURE: Poll_SO                                                                                                        */7 k4 F( o& N8 k/ s; V
  216. /*                                                                                                                                                */1 c7 l- G+ o6 ~! S& W1 v" i; |
  217. /* This procedure polls for the SO line during AAI programming                  */+ h- h4 Q4 V* K
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/9 Q7 K. G) \; |9 g  w
  219. /* is completed                                                                                                                        */( Q0 W7 ?/ v7 E  h7 T5 v
  220. /*                                                                                                                                                */
    * Q' d, b  [3 I  ], ^- o' E& v
  221. /* Input:                                                                                                                                */  l$ U: W4 b  ~% d! |
  222. /*                SO                                                                                                                                */0 D( n1 s( ^& P; |& V6 a1 x
  223. /*                                                                                                                                                */6 J& Q5 T, c" }0 L$ ^2 ^1 V! }  j
  224. /* Output:                                                                                                                                */
    8 m# h7 K0 H( i: Y- G5 A
  225. /*                None                                                                                                                        */
      D$ x% U* B5 Z9 O3 e1 Q1 X
  226. /************************************************************************/
      q8 }; a' T$ ?4 V& [. d
  227. void Poll_SO()5 A5 v( \) D  |0 b* K
  228. {" Z4 b9 U- p, v* B& \! k0 ?
  229.         unsigned char temp = 0;
    8 X. |3 _: W7 m  i, u
  230.         CE_Low();; O$ I9 x& N' B3 t: @% |; s. w1 H2 X
  231.     while (temp == 0x00)        /* waste time until not busy */- f' F# r0 j5 i+ E) u4 v9 |
  232.                 temp = SO;
    ) u  _& P) F, z3 D
  233.         CE_High();
    " a1 n' k' Y4 [9 j7 L  s0 g0 W
  234. }: m" F* B' h6 X  \# ^9 C3 `

  235. 5 d% D3 H( Q7 x  \' W6 c0 O* ?  ~
  236. /************************************************************************/
    . f0 ?1 r3 R9 e7 n6 x, }  Z9 o
  237. /* PROCEDURE: CE_High                                                                                                        */' J" q# X* Y6 `
  238. /*                                                                                                                                                */6 Y/ T4 c5 o4 u( x* |
  239. /* This procedure set CE = High.                                                                                */7 x' m/ |3 x5 w8 D+ z7 U1 u. X
  240. /*                                                                                                                                                */- c8 K" A' o  v3 }: }& _3 g  u
  241. /* Input:                                                                                                                                */( ?$ j$ M. C$ y; s6 ]/ x
  242. /*                None                                                                                                                        */
    $ Z. N9 E4 W6 c/ [- u3 Q
  243. /*                                                                                                                                                */, t, t6 R8 v; G" c. T
  244. /* Output:                                                                                                                                */$ N8 s0 R, r: t6 C4 K
  245. /*                CE                                                                                                                                */$ [3 |- U; n% \$ y0 p
  246. /*                                                                                                                                                */6 `9 X1 K' ~6 u- F- M
  247. /************************************************************************/. n& b: s) t# Y& w0 D
  248. void CE_High()
    ) X4 F" l/ u  Y* o" F3 z
  249. {
    4 N: x0 j6 d4 p* M. c5 g
  250.         CE = 1;                                /* set CE high */
    : ^# Y) ?) G0 o1 ]4 }2 L
  251. }' }% J1 d" o; U

  252. * b3 S! @$ D! J, u
  253. /************************************************************************/
    6 h% s5 h4 G+ B, I/ O: V: ^
  254. /* PROCEDURE: CE_Low                                                                                                        */
    4 Z  l. K  v9 l$ s: S; M3 h, w
  255. /*                                                                                                                                                */
    6 U8 E% E* r0 {
  256. /* This procedure drives the CE of the device to low.                                          */- V. n' l1 K6 q" G: V0 R- B, e7 ^
  257. /*                                                                                                                                                */
    9 s# {1 J1 B$ M/ i/ r) m
  258. /* Input:                                                                                                                                */
      `0 ^$ S' U  |& X
  259. /*                None                                                                                                                        */
    4 _! K* o* e. [  ?- i
  260. /*                                                                                                                                                */
    ( e, c2 }# g2 t5 J
  261. /* Output:                                                                                                                                */1 Z0 I7 d, z) _3 r
  262. /*                CE                                                                                                                                *// n) W" i3 l$ ~' d8 v
  263. /*                                                                                                                                                */- e8 ^- h) w1 y+ f& o5 [
  264. /************************************************************************/" H9 k: S% p9 k- w
  265. void CE_Low()
    5 O7 W4 ~. C3 a' l3 t
  266. {        7 {4 d0 d9 g: ]
  267.         CE = 0;                                /* clear CE low */0 n: c2 |! `/ ^/ i: t3 A% Z1 O
  268. }
    " U  @" F2 I0 m2 k3 a- @

  269. : c; p9 a" A9 H8 A
  270. /************************************************************************/
    1 N, s# k2 {3 P0 r6 J  m
  271. /* PROCEDURE: Hold()                                                                                                        */
    : l; r7 f' D  y5 n
  272. /*                                                                                                                                                */
    ! c3 S2 z# C' a0 S4 n( h4 ^
  273. /* This procedure clears the Hold pin to low.                                                        */3 G) j! |% v5 S) q" F; S
  274. /*                                                                                                                                                */
    ' I* ]$ m' H" V
  275. /* Input:                                                                                                                                */% f/ |" X; d5 v( |" R) E
  276. /*                None                                                                                                                        */2 x# \# `# r" u, K% o+ r
  277. /*                                                                                                                                                */
    / K7 F  |1 G" O4 |9 P
  278. /* Output:                                                                                                                                */
    ! d/ t* k- ^7 G# p
  279. /*                Hold                                                                                                                        */
    ' j+ `0 l+ i/ p0 N$ L$ N* z
  280. /************************************************************************/: c; |6 J5 o, E7 N
  281. void Hold_Low()
    ; M2 ~& O2 n' c4 w# J2 R' Z
  282. {
    ; K2 w+ Z! u6 A6 O/ x
  283.         Hold = 0;                        /* clear Hold pin */
    7 I7 A# y( Y, R$ r1 M$ D
  284. }5 b3 y: R* s0 @8 G6 f1 c) v" d
  285. 9 T6 Y! n! M% Y
  286. /************************************************************************/
    & ^5 m0 ]: o# G% V5 y& k, l6 G( t
  287. /* PROCEDURE: Unhold()                                                                                                        */
      q, g. C5 S+ b% i* ?/ g
  288. /*                                                                                                                                                */
    . ]2 V+ Z  i6 P. A/ L1 f
  289. /* This procedure sets the Hold pin to high.                                                        */
    & X8 S' I" E% T; {7 N! O
  290. /*                                                                                                                                                */  K# {/ [* {# \
  291. /* Input:                                                                                                                                */2 b( z# C8 Y8 R7 C: C4 b! _- a* T0 I
  292. /*                None                                                                                                                        */' n% B% D9 m+ B0 `. ?
  293. /*                                                                                                                                                */
    7 z" {5 M6 p2 D2 R: Z! x# }
  294. /* Output:                                                                                                                                */
    + s; q; }2 l# V5 b* n" c! S% u
  295. /*                Hold                                                                                                                        */
    6 h2 S4 e$ W0 B& k
  296. /************************************************************************/
    % n, U# @" I3 q
  297. void Unhold()
    4 e3 a2 k; |$ g8 e* c
  298. {. @6 \% J5 I# O6 S% d) l, r  `
  299.         Hold = 1;                        /* set Hold pin */: p" k- h% S1 l1 G
  300. }
    / W8 ^! A" L7 W; x. |0 i) R

  301. ! ?; M- C. ~9 f  {' Z( U! \( w
  302. /************************************************************************/
    5 d# M- A/ P& f3 X7 l
  303. /* PROCEDURE: WP()                                                                                                                */7 X2 U# f4 Z% f2 u# W  ^' q$ t
  304. /*                                                                                                                                                */: J( {, p4 q/ [) L$ B1 A
  305. /* This procedure clears the WP pin to low.                                                                */
    4 Y6 d# Z3 H, s3 b4 N( D
  306. /*                                                                                                                                                */
    , f0 f1 q2 p+ [4 r; F; E  b/ w
  307. /* Input:                                                                                                                                */
    4 n: Y( g/ e% f2 x( f
  308. /*                None                                                                                                                        */
    ! q( r: I: o( w: D  c7 T
  309. /*                                                                                                                                                */: n4 g9 z; P- l3 @
  310. /* Output:                                                                                                                                */
    # v9 N9 f7 D1 M9 |6 r. {( _# s  c
  311. /*                WP                                                                                                                                */
    1 x  m4 \2 D  x$ X6 I( X6 g
  312. /************************************************************************/
    ; o- A' g0 s) _  V# A: Q6 u% [
  313. void WP_Low()
    6 j' e% |9 v/ W
  314. {1 A- Y+ S" R5 ]: v6 e
  315.         WP = 0;                                /* clear WP pin */' Q8 L3 Q1 Y8 P8 ]
  316. }
    ! g7 J( p0 ?0 J2 r' k2 l2 a

  317. ! w( ~9 e5 ?3 _; J3 B
  318. /************************************************************************/
    ! j' v- v3 ~8 V. \+ F8 T* _: s
  319. /* PROCEDURE: UnWP()                                                                                                        */3 L: F0 R0 }2 ^& I8 \8 i7 N6 S
  320. /*                                                                                                                                                */
    ' u' i+ y) x# _  t) V
  321. /* This procedure sets the WP pin to high.                                                                */( X' V8 M9 I" a# `2 {
  322. /*                                                                                                                                                */! x% J( {* `; H
  323. /* Input:                                                                                                                                */. Z' z" }# _, S, ?8 B" F
  324. /*                None                                                                                                                        */1 y8 r; b  ]4 v$ Y* M8 v: i0 v
  325. /*                                                                                                                                                */5 o+ b" ]8 \* l& H' u
  326. /* Output:                                                                                                                                */0 S7 a. A! D( m+ ^- Y+ o
  327. /*                WP                                                                                                                                */( p$ _2 }: d$ M+ j- n
  328. /************************************************************************/
    * V7 p. z6 }; X# z* e" B
  329. void UnWP()' E; P& ~: q5 h' a
  330. {
    3 E! t. ~3 C6 Z- d2 C
  331.         WP = 1;                                /* set WP pin */; O+ o9 I) M2 W6 @8 L
  332. }
    0 D4 P& u' ]% g
  333. ) g; F5 X' p7 s4 A5 h. \
  334. /************************************************************************/' m% |1 x/ V# }
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ( A; `7 D% i" [1 G* S7 r
  336. /*                                                                                                                                                */
    9 @" F3 z+ z7 [& z9 J" J
  337. /* This procedure read the status register and returns the byte.                */0 o' W0 e( t) P. a$ h
  338. /*                                                                                                                                                */$ Q( i: F7 x- m6 |* u% y0 W  O4 N
  339. /* Input:                                                                                                                                */
    0 e8 g( I1 {& Z% R5 u
  340. /*                None                                                                                                                        */
    + ]+ m2 V+ i; B
  341. /*                                                                                                                                                */
    - W4 ~7 D- Y. V3 Y' i7 {5 s
  342. /* Returns:                                                                                                                                */
    $ H, e3 K8 S) g1 w1 H4 D7 e: d0 W
  343. /*                byte                                                                                                                        */# r/ K0 K; i+ P
  344. /************************************************************************/
    9 ?1 I, h0 A+ c' y0 D: e& D' I
  345. unsigned char Read_Status_Register(); b1 |" @0 ]$ N6 m
  346. {
    # A4 r2 x0 D0 u' O) y
  347.         unsigned char byte = 0;$ c3 ?1 p' I' X
  348.         CE_Low();                                /* enable device */* p3 s( n: A( m' q5 ]
  349.         Send_Byte(0x05);                /* send RDSR command */
    ! W' K1 C2 a8 D/ i2 D& I
  350.         byte = Get_Byte();                /* receive byte */' T/ A5 W  K) Q( }$ y% q7 _
  351.         CE_High();                                /* disable device */* @. E- M5 O0 P0 c
  352.         return byte;
    " c' _$ J  |9 W8 K8 g- v
  353. }
    / c+ Z) ^6 K1 |
  354. ' e) c' ?2 J+ J7 s
  355. /************************************************************************/
    3 _2 l0 Q# a8 V
  356. /* PROCEDURE: EWSR                                                                                                                */
    , Q+ M& ~. c/ d0 K
  357. /*                                                                                                                                                */
    : O' C& f4 {- h$ b% w
  358. /* This procedure Enables Write Status Register.                                                  *// J& |2 X) V; ?) h  E" O
  359. /*                                                                                                                                                */
    2 p0 l' U6 _  W8 r; x$ H: @
  360. /* Input:                                                                                                                                */
    3 I. s3 j& a3 R, G" \
  361. /*                None                                                                                                                        */2 D& w6 Q5 h, z, d
  362. /*                                                                                                                                                */
    1 l8 u; G) S, z6 A; o  s
  363. /* Returns:                                                                                                                                */
    9 m- |/ s6 s, U( l$ P2 [. R8 `
  364. /*                Nothing                                                                                                                        */5 F/ v; |1 a' n' \& e. D
  365. /************************************************************************/# M9 r4 _: q. y1 w
  366. void EWSR()
    ; K, S! G! S' G# B* r* C" o1 s
  367. {  [$ T& M; A( o! ], l
  368.         CE_Low();                                /* enable device */
    4 o- l) q" w4 B4 |. N2 V: S/ x
  369.         Send_Byte(0x50);                /* enable writing to the status register */+ ]2 _; ^- H9 N
  370.         CE_High();                                /* disable device */* S9 b+ g: C6 {' d) F
  371. }
    + m4 e; y* d6 |. e3 z. l! y0 A: T- w

  372. # }7 n: ?! w/ Y1 |1 h9 D
  373. /************************************************************************/
    $ i9 s+ R4 z0 B5 d4 J; a8 a8 }
  374. /* PROCEDURE: WRSR                                                                                                                */0 p; f' b" p2 c3 A  ~3 w& G" d
  375. /*                                                                                                                                                */
    & m, L. Y6 c. L/ l# v& Z! y
  376. /* This procedure writes a byte to the Status Register.                                        */
    0 G1 D0 _; o8 R( L
  377. /*                                                                                                                                                */
    5 Q/ ~& ^; q6 P4 z) L1 M: p8 l; M
  378. /* Input:                                                                                                                                */
    . x8 J! g0 K: {0 p. U
  379. /*                byte                                                                                                                        */
    " R: y4 {( O. f  F
  380. /*                                                                                                                                                */6 k& |, H+ c2 m6 B: N; ^( H
  381. /* Returns:                                                                                                                                */
    * X3 k4 r9 U6 h3 V
  382. /*                Nothing                                                                                                                        */5 o% ]& H: P4 J3 v; m: l+ i
  383. /************************************************************************/4 j! @8 S8 A# w: o. d
  384. void WRSR(byte)
    8 k2 j& S1 u( w7 }
  385. {2 g: _' P( {7 }. f' p% [
  386.         CE_Low();                                /* enable device */
    3 J& `% s. d. m7 t3 x
  387.         Send_Byte(0x01);                /* select write to status register */7 [6 b4 p2 c1 b2 p/ j- L, p
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    , p' U$ N/ `) G8 @" y7 \) l$ I
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    / j; c* T' @0 a5 `: F
  390.         CE_High();                                /* disable the device */0 F; [2 Z; x3 a9 h% o/ C; d
  391. }
    7 _  A) E0 a! W9 d9 w' t# o
  392. 3 I& p( `3 e3 S4 J- j2 w$ a  h
  393. /************************************************************************/( s3 Z" R. a& l$ j! a9 z
  394. /* PROCEDURE: WREN                                                                                                                */+ C& e3 _  E" p4 R  Y& u( O
  395. /*                                                                                                                                                */  G2 F3 `3 }: z" Y6 ]! ?2 {: g
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */0 l3 n7 ]" j* U9 q! A- W9 A2 L
  397. /* to Enables Write Status Register.                                                                        */
    . ^4 e" ^" F2 w
  398. /*                                                                                                                                                */
    ! S4 L. T9 ]7 F5 w; x
  399. /* Input:                                                                                                                                */" x7 \* n$ a1 ^5 P$ E- |% |9 P
  400. /*                None                                                                                                                        */) \% q2 T2 n3 \5 A, o, q3 u
  401. /*                                                                                                                                                */
    % j/ a8 e& b) t! \( L
  402. /* Returns:                                                                                                                                */7 ^, N% F% m' A9 t- }  X4 T
  403. /*                Nothing                                                                                                                        *// e/ G1 D" D( F& R
  404. /************************************************************************/) J8 M; q; S* S9 m* w- K
  405. void WREN()
      ?, [  y0 c1 g, h
  406. {1 }' o, B. U3 o4 x; n# I
  407.         CE_Low();                                /* enable device */
    * Y& j$ `! @7 Y' d" W- p3 E
  408.         Send_Byte(0x06);                /* send WREN command */! ]8 d5 _: F! R# n, S  r* `
  409.         CE_High();                                /* disable device */
    ) g. H, z9 C0 D/ h! S+ N! |- v6 K
  410. }6 y3 y, |  N8 |
  411. $ r( ^, g; H1 o1 K  c" @" S* }' B
  412. /************************************************************************/
    7 i/ v8 ?* c7 a4 v4 y/ y
  413. /* PROCEDURE: WRDI                                                                                                                *// C4 H( N# k! t
  414. /*                                                                                                                                                */
    ) o4 W( H: D" M, |4 X
  415. /* This procedure disables the Write Enable Latch.                                                */' [9 }  h) Q5 h! }, Q
  416. /*                                                                                                                                                */; h9 U& L/ z4 |, y, ^
  417. /* Input:                                                                                                                                */+ {$ C: e# ?7 m- [9 Y  G
  418. /*                None                                                                                                                        */( P/ E" ^6 l* `- ?" m, ^- R
  419. /*                                                                                                                                                */
    4 W4 L4 n/ i9 X) m! ^" b7 @
  420. /* Returns:                                                                                                                                */2 C& T5 E, v( F
  421. /*                Nothing                                                                                                                        */2 U, r, [8 a+ w" r
  422. /************************************************************************/
    ) d% E* _( c3 y" F
  423. void WRDI()0 F* R1 K0 j" i
  424. {
    6 O$ I% I" I' y: D: F: \3 n
  425.         CE_Low();                                /* enable device */
      O; ]0 F; c5 m# @  `
  426.         Send_Byte(0x04);                /* send WRDI command */
    $ b( o5 s! q6 v6 ]
  427.         CE_High();                                /* disable device */
    * K- c8 [! {3 S0 g% x+ L
  428. }/ ~5 P0 C( ~, L. n
  429. " u. w6 R' m: W  {# U' ?5 F
  430. /************************************************************************/
    : x, K# B& c# n" \. A  w
  431. /* PROCEDURE: EBSY                                                                                                                */2 j* J4 U& T9 N5 E9 p
  432. /*                                                                                                                                                */
    4 Z, l  a  S5 L- g7 G' L, x) `4 Z' M
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    2 x4 h, ?9 i( c
  434. /* programming.                                                                                                                        */
    6 b' d+ H" q4 C4 e6 N
  435. /*                                                                                                                                                */+ d8 @% L4 {. a4 b- a
  436. /* Input:                                                                                                                                */) o5 b% F8 ~- K5 @
  437. /*                None                                                                                                                        */
    ' d" I/ c4 Y$ d/ ?3 J( y6 y7 U
  438. /*                                                                                                                                                */
    9 ]; @% `3 m' u
  439. /* Returns:                                                                                                                                */
    5 \8 A, s2 |/ ?9 ?4 l
  440. /*                Nothing                                                                                                                        */2 |( A, g3 h! g7 M/ t5 b: l
  441. /************************************************************************/
    ) M( m. W! M- p  X9 j- _
  442. void EBSY()
    , c/ `6 A" j7 ?8 [0 @7 f
  443. {- y# ?8 w- ]- ~& T. N; D8 W
  444.         CE_Low();                                /* enable device */
    + w2 d. J$ f3 R. \/ a8 C5 d
  445.         Send_Byte(0x70);                /* send EBSY command */+ p9 }8 W& r& W6 ^- N: X' P/ I% `* k
  446.         CE_High();                                /* disable device */
    1 r' U0 n0 o- c/ L4 g# G# D" f
  447. }
    7 ?' i6 S  T$ {; C7 k1 m/ v

  448. 8 x( A0 V+ S9 l6 [" v; G
  449. /************************************************************************/+ q  @% X9 W% T! `+ U% d
  450. /* PROCEDURE: DBSY                                                                                                                */
    " f& _2 p% K$ h" [. ?
  451. /*                                                                                                                                                */
    8 Q/ w" y& [1 T6 ]0 V1 ]( Y. J% _' O
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ' p+ L* K& s- Z2 J0 w" _  U( t
  453. /* programming.                                                                                                                        */
    " f0 P% e+ I" U- i
  454. /*                                                                                                                                                */
    % S& j  f, p1 }1 `% u: f3 h1 z- Z1 l' N
  455. /* Input:                                                                                                                                */
    # d+ ~. D: e7 A8 t/ ~: ?9 F8 c
  456. /*                None                                                                                                                        */1 k/ p/ U3 z' m" S
  457. /*                                                                                                                                                */0 h: H0 v; P' A' j
  458. /* Returns:                                                                                                                                */
    : ^9 n& n4 _) j$ e! u1 b
  459. /*                Nothing                                                                                                                        */
    0 d! C& C! q# i
  460. /************************************************************************/
    & w$ h) ?- |( A* C6 |
  461. void DBSY()- `' V! m9 g8 {1 Y* M
  462. {, E9 W0 m+ U3 o* p
  463.         CE_Low();                                /* enable device */. d2 |9 `, [$ k
  464.         Send_Byte(0x80);                /* send DBSY command */
    + O% y7 X, u, j2 j
  465.         CE_High();                                /* disable device */. t5 b" Q  t* _* Z) |
  466. }
    , d% f& f/ U- ?  ^: I: I

  467. 9 _- t7 a- T% T$ c; ^9 z! H- @# d
  468. /************************************************************************/( a" M9 m6 a" b7 |( Y
  469. /* PROCEDURE: Read_ID                                                                                                        */
    3 E9 E$ `1 ]" C" M7 T, l
  470. /*                                                                                                                                                */
    1 M9 G, @8 d; L% [8 F7 m% K
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */- _0 i# l. x. f
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */7 [3 \1 a* ?8 J
  473. /* It is up to the user to give the last byte ID_addr to determine      */0 a8 ]9 g& K- Z/ B- C
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    + D/ `6 h) S7 E( h
  475. /* first.  Please see the product datasheet for details.  Returns ID in */3 z- s( \7 B1 V, j* R2 T$ y
  476. /* variable byte.                                                                                                                */, P% X; z* u" j
  477. /*                                                                                                                                                */
    6 O# P/ X+ D, |3 w/ k, B0 `
  478. /* Input:                                                                                                                                */
    " O9 I, H; I% O/ n8 Q; i: q
  479. /*                ID_addr                                                                                                                        */
    ; o& W7 F# n5 C8 r) a) r  O+ `& [
  480. /*                                                                                                                                                */
    9 N- t! K3 y! {# H
  481. /* Returns:                                                                                                                                */
    : O+ I3 C' k& F, _  y' q* R
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */) z9 `% x4 F! Q- s  ]9 y# w  H
  483. /*                                                                                                                                                */* [  y% ]) B3 h
  484. /************************************************************************/" S1 s0 d4 I! d
  485. unsigned char Read_ID(ID_addr)/ v% d4 T8 t3 U% X$ j: i& c8 d
  486. {5 g2 k2 r8 W9 l% ^& G1 B# d
  487.         unsigned char byte;9 K+ N; Q3 h- A9 M
  488.         CE_Low();                                /* enable device */: ?3 P; q/ v# m8 m- |* ?
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */& d/ }+ h6 @! U7 `
  490.     Send_Byte(0x00);                /* send address */2 ?2 D& [3 N6 ]3 U/ i8 q
  491.         Send_Byte(0x00);                /* send address */
    $ T9 I$ ?- `% L2 ~/ m  ~: r5 a
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */* l, K- O( e, d, Y1 w- h1 Y  t5 q" k# y
  493.         byte = Get_Byte();                /* receive byte */
    + N5 O  g" ^) y% A
  494.         CE_High();                                /* disable device */
    3 G; |4 @/ v0 D& X% c
  495.         return byte;
    # N0 M. b$ \& {" j
  496. }- P) ?+ |5 H& h& V, U, l; G3 a
  497. ) o' D: r* x3 q* [6 P
  498. /************************************************************************/
    ) f2 y& Z: n4 X* d) z
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */2 u% G* [" N' Z! U& F7 _$ t8 d
  500. /*                                                                                                                                                */
    " k/ ^, y  f! y4 d# D& B) ^% n
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ) ]; q( J4 L& K% f* C6 ~
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */; K/ Z8 e5 n& |3 r% w) E& N
  503. /* Please see the product datasheet for details.                                                  */: y" J5 U8 }4 j; S$ l) P# {4 }
  504. /*                                                                                                                                                */7 y% g! p9 d# d, d
  505. /* Input:                                                                                                                                */
    + }  g2 l8 \( i1 q& P
  506. /*                None                                                                                                                        */) Q. B+ C- D  T, ?9 U6 f0 e
  507. /*                                                                                                                                                */9 |; j8 ~7 z+ Y7 n
  508. /* Returns:                                                                                                                                *// `$ V3 t9 m1 [" j  `4 M
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    . W6 Q3 {$ p& [2 x+ X
  510. /*                 and Device ID (8Eh)                                                                                        */
    5 h: Y$ q1 u6 M# y8 x
  511. /*                                                                                                                                                */
    $ o& e7 a! Q+ U7 G1 E7 X4 d) S
  512. /************************************************************************/
    , c6 j+ \. |2 M. j0 R
  513. unsigned long Jedec_ID_Read()
      k% z8 J1 c# t* D# L' k) W# h
  514. {3 W; F% f8 h3 i  L
  515.         unsigned long temp;
    . Y% a* j& ^* z. M1 C
  516.        
    ; q" y6 c6 M8 |3 o: U# d5 l
  517.         temp = 0;
    7 o* D8 N+ ], v/ q  ~1 ?

  518. , h+ z7 @1 d7 t) w. O
  519.         CE_Low();                                        /* enable device */* X( e9 z( }2 x$ l9 d
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */5 Z+ W. n0 i7 r6 x
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    & i. [0 w* @% B- n7 s1 ~3 L& i
  522.         temp = (temp | Get_Byte()) << 8;       
    * ^1 c4 @7 ^  ^5 e8 F
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    5 n2 M  E" y" G9 ~5 H( k
  524.         CE_High();                                                        /* disable device */
    & {6 m, q3 ]4 W* D0 q
  525. 0 t! H! s; `- T8 w8 t
  526.         return temp;
    2 F) |7 |  ~( l+ T! w
  527. }) [6 R# U& L# F9 Q0 v9 J+ {  n( z
  528. 0 b: R0 ?' m9 \3 y
  529. /************************************************************************/) X; X, @6 t- P" ?/ A% s. ^
  530. /* PROCEDURE:        Read                                                                                                        */- Z& P) l6 g1 D3 t
  531. /*                                                                                                                                                */               
    : m- v, _% y' m, N- h
  532. /* This procedure reads one address of the device.  It will return the         */+ i" E! f5 X; R1 C- N
  533. /* byte read in variable byte.                                                                                        */
    3 t' E/ G% r, b0 ]
  534. /*                                                                                                                                                */. T4 e* q& u1 p' u# l' A, D! V' t% I, V0 q
  535. /*                                                                                                                                                */1 C# C3 ?$ H) W* ]
  536. /*                                                                                                                                                */
    ( q/ t# j5 m: a1 h
  537. /* Input:                                                                                                                                */
    ' w3 Q  \& {) _! b( o: D
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */6 v$ U; v* K$ F2 A5 B1 b0 @
  539. /*                                                                                                                                      */, {1 R" J6 y" }4 }
  540. /*                                                                                                                                                */
    / h; ]( |" \9 u/ G4 \, _$ B1 X
  541. /* Returns:                                                                                                                                */
    6 m% W) j( z; t& u5 k* p; D
  542. /*                byte                                                                                                                        */5 j. b2 \# Z- P- {
  543. /*                                                                                                                                                */# @$ `; \2 I3 i- Y8 N" k; K4 {6 T) H7 k
  544. /************************************************************************/7 Y5 Z/ j$ d& x
  545. unsigned char Read(unsigned long Dst)
    + I- Z# X0 Y. t7 O" q# L% O8 F4 ^
  546. {3 O' ~, c6 E9 K: i/ T& S6 d
  547.         unsigned char byte = 0;       
    7 t: R4 J# g8 p5 O' f7 ?  P( N

  548. 4 Y: e! x+ G0 m0 Z6 k6 `
  549.         CE_Low();                                /* enable device */
    4 [" c- H0 t1 O: {
  550.         Send_Byte(0x03);                 /* read command */
    * b+ {. G2 m" H! z  O
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    % D! _) G& M  O% S4 v
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " e  ?1 I5 d$ N4 R
  553.         Send_Byte(Dst & 0xFF);/ B% ?6 ]& n! g0 ^
  554.         byte = Get_Byte();
    6 R. m3 h* t! }4 x
  555.         CE_High();                                /* disable device */; p7 J8 n" \4 w3 f/ U% v' N" D, L
  556.         return byte;                        /* return one byte read */
    % E8 z8 y5 E+ h) y
  557. }
    . s) l4 k! j6 U9 k" C+ s) q0 W; Y

  558. 7 a2 a, }" l& ^- Y  g! P, \1 |2 ]5 N9 m
  559. /************************************************************************/: j7 _; N' J3 d& o$ O( ^% c
  560. /* PROCEDURE:        Read_Cont                                                                                                */8 S; a' M- ]# ^) n. k: ]
  561. /*                                                                                                                                                */               
    # ?% E6 w4 K6 _- I5 |5 F
  562. /* This procedure reads multiple addresses of the device and stores                */
    7 U) q- J4 n! Z6 x  K% I" V  K) N9 h
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/+ z9 a3 @6 ]4 b/ l+ j; O' E
  564. /*                                                                                                                                                */  b+ {( [- M# N0 a9 _$ _; W
  565. /* Input:                                                                                                                                */
    9 S/ r9 l) v. U0 z* U* U' `' s% M
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) w/ }; H, k9 Y1 M8 A$ I
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */* P5 V9 \) J( R7 ~% S
  568. /*                                                                                                                                                */
    , c# E2 {8 X6 [. b
  569. /* Returns:                                                                                                                                */8 U. Z7 W, g0 j- G6 E
  570. /*                Nothing                                                                                                                        */0 P# L7 y# M/ j1 \
  571. /*                                                                                                                                                */
    " s1 a: k2 x# z0 Y) v8 A3 h: O2 l
  572. /************************************************************************/
    ' d: i. V  G' l6 E! ]1 A
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    , j+ t; U/ Y0 f6 B! U+ S8 s
  574. {
    3 K0 T# p  o  h; E: I4 Q
  575.         unsigned long i = 0;
    / {) E. o' ^: h- u  S& ~6 m
  576.         CE_Low();                                        /* enable device */
    9 m- a/ W9 \4 X' k- C! C1 A% Z; Q
  577.         Send_Byte(0x03);                         /* read command */
    0 I2 Z6 b  @( ^" ^" U
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* @' v7 G1 N5 y' M0 }0 e
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));1 m4 ]( a% X. |; P, U# s" j' W
  580.         Send_Byte(Dst & 0xFF);
    & D  Q- k3 K* O
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    9 E4 ?/ F! L/ r# J: q4 K' O! p
  582.         {- K$ W8 E- P4 H5 }3 Z  V
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */' W+ a" F4 S7 x- ~
  584.         }
    ' B% {5 [* p% e; j
  585.         CE_High();                                        /* disable device */
    $ l8 `8 U, J% |6 R9 p5 [

  586. ( s% Y8 ^1 X  Z! f" n7 X
  587. }" N# [/ i' n* O# {# z

  588. ; M3 @" [! q' }( V* z! I2 x
  589. /************************************************************************/5 E9 X) |" I/ b
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */& f# N& V6 j: ~6 G" I+ |$ |9 f+ c
  591. /*                                                                                                                                                */                ) F4 w# P. m8 Z5 {7 |$ T
  592. /* This procedure reads one address of the device.  It will return the         */
    * I% c5 k7 ^( y& W$ o+ O! r
  593. /* byte read in variable byte.                                                                                        */8 t% s% V; s4 F, W; _
  594. /*                                                                                                                                                */7 `' @) Z. m6 ?& D. M3 e  B  d" d
  595. /*                                                                                                                                                */
    , n% _8 |% x+ \( _5 F+ j0 U
  596. /*                                                                                                                                                */
    - R" ~1 |5 ?& r0 ?( e0 I* h
  597. /* Input:                                                                                                                                */
    7 w5 @8 l* T8 T2 E1 X* F$ W
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    # i) F! \5 G% P4 J
  599. /*                                                                                                                                      */% }6 B8 G* ]4 X3 p% i
  600. /*                                                                                                                                                */
    0 C5 q4 F; W9 F/ x8 l
  601. /* Returns:                                                                                                                                */
    7 Q' Q1 b6 A2 b7 o( _, U  P5 ]; ^
  602. /*                byte                                                                                                                        */, p5 z" ~  K8 h7 X: `( I$ V- \
  603. /*                                                                                                                                                */
    7 ~# L3 B# b6 i( j4 t% [+ |( |  r
  604. /************************************************************************/
    : m7 i! `5 b" f- k
  605. unsigned char HighSpeed_Read(unsigned long Dst) : a9 R! R# @3 V6 t5 J8 k4 p; }
  606. {; c5 ]0 a# V5 l! Q. B: D0 D
  607.         unsigned char byte = 0;       
    ( S& A" x9 \5 M
  608. 0 |& p( ]% k% P( j
  609.         CE_Low();                                /* enable device */7 w6 C5 n' M$ x* A% {. d$ E
  610.         Send_Byte(0x0B);                 /* read command */* }0 r7 K# [3 Q8 W6 [
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */2 @/ T) ]% h; _5 q1 U* B: c0 h8 F5 l7 p
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));/ r+ V: w. {7 N  V
  613.         Send_Byte(Dst & 0xFF);' ]$ e; @8 J/ s( B
  614.         Send_Byte(0xFF);                /*dummy byte*/7 U6 {6 g/ F8 q
  615.         byte = Get_Byte();
    - M! {+ P' v- j+ J: `- @, u* u
  616.         CE_High();                                /* disable device */
    ' T) m9 V( e% T# Q' `
  617.         return byte;                        /* return one byte read */$ d$ @0 a0 P3 z5 k
  618. }. u+ I( [5 O% R2 {! S. V" u
  619. 4 }9 o' L+ P( \& ^- k, n
  620. /************************************************************************/. _! ^, Q: A9 j# m8 |% M) c" B; R
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */: V" J* y1 V' ^5 B
  622. /*                                                                                                                                                */                2 u& V. S2 T+ {# o6 F' I
  623. /* This procedure reads multiple addresses of the device and stores                */* W8 p8 M5 J8 \
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/7 c0 G# y* {$ }+ u! ~# B
  625. /*                                                                                                                                                */
    ( p/ A" E( ]$ X0 j$ p8 B
  626. /* Input:                                                                                                                                */. z" d# _1 _- |; O3 u
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# s2 y; n& T6 d8 Z. i+ Z
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    : f: q2 S  _, l7 Y4 N# T9 P
  629. /*                                                                                                                                                */  y, n. o1 |7 ^7 t  G& v' K$ A7 v& ^/ S
  630. /* Returns:                                                                                                                                */1 j1 V2 f0 |# }
  631. /*                Nothing                                                                                                                        */
      C& c8 p! U" y/ k0 j1 K) B2 p
  632. /*                                                                                                                                                */
    ' J0 q7 h/ C) {- D* ^5 s$ z
  633. /************************************************************************/+ F6 X* X: I. A# j9 Q7 g
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    1 ^4 }5 y6 T9 G5 d( i$ I
  635. {$ a. _0 D0 ?  X8 N& w* R
  636.         unsigned long i = 0;
    + |" a! B' H6 T, H& a- R& f
  637.         CE_Low();                                        /* enable device */: }) z9 K' L' {
  638.         Send_Byte(0x0B);                         /* read command */
    ) h% t( a+ r6 U: N' }4 Q; B! n
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  ^% Q$ ?$ K8 N, o0 [. [8 _
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & ?& e* {6 f3 i, v8 X) p2 A
  641.         Send_Byte(Dst & 0xFF);6 _% Z" N  @% G& z+ v( b
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ) z$ K& S8 f5 v+ s5 j4 e8 s  [
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    # J+ ^& D# r, w: i- v6 i# d
  644.         {
    4 ^9 _8 X# ?! Y2 p
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH *// J) W( g; |7 f% _( D% Z' y
  646.         }; F" J+ s. g0 ]( n5 M$ t, f
  647.         CE_High();                                /* disable device */- N, w, ]; Y/ [% h/ ]
  648. }
    ; L+ u1 `, Y8 |7 F" r
  649. 8 n" g6 F" S8 N4 P, M7 B) c% J3 X
  650. /************************************************************************/
    : E) I' D/ `& n! [4 h
  651. /* PROCEDURE:        Byte_Program                                                                                        */9 ?) |4 B6 \( S3 h
  652. /*                                                                                                                                                */
    8 l* `0 d8 E! n1 |
  653. /* This procedure programs one address of the device.                                        */+ Z7 N4 ^) k, w* _
  654. /* Assumption:  Address being programmed is already erased and is NOT        */1 O5 g% s8 R. w, w
  655. /* block protected.                                                                                                                */! t( n, C4 W; L7 E( p- m% p9 b2 m
  656. /*                                                                                                                                                */
    & W9 Z" u8 R4 ^) n3 |
  657. /*                                                                                                                                                */7 |: I. I  P# t" ~, h( |; Z
  658. /*                                                                                                                                                */. U: z3 D/ y9 h& V9 R7 n& S
  659. /* Input:                                                                                                                                */- y( w' p0 n  V/ z
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 o; \7 E. }% r' m
  661. /*                byte:                byte to be programmed                                                                */
    7 M/ [. _6 x3 k( d
  662. /*                                                                                                                                      */% X! i1 a7 [$ E/ `, v+ f2 L* j* k
  663. /*                                                                                                                                                */0 V3 Z! }: O" h7 R% u
  664. /* Returns:                                                                                                                                */+ Z1 \' b& c; S5 a6 v  e" h
  665. /*                Nothing                                                                                                                        */
    / G  ^; S' U; Z* Y% _
  666. /*                                                                                                                                                */
    1 ~& o+ [* }% d' V  P
  667. /************************************************************************/
    # f! }) T  e1 y, M! B9 ]3 ~9 W
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    9 K5 U  x" u1 G( ~  `
  669. {; u, W* q( d& ~. z
  670.         CE_Low();                                        /* enable device */
    9 A" K0 F2 |5 b: i2 s
  671.         Send_Byte(0x02);                         /* send Byte Program command *// ^+ U- ]& M1 ?+ A
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */+ G# C4 c% ^5 ~0 b$ K! J
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));! s% ]* P* z! `
  674.         Send_Byte(Dst & 0xFF);
    + s0 Q9 o; I. `7 W/ ?+ \6 i8 C  S
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    / `* N9 i9 C2 f. n' O/ E3 D
  676.         CE_High();                                        /* disable device */
    $ @- C6 l- A7 u/ S  |* z
  677. }
    , C+ L/ ~. h7 K5 i3 z0 ]7 @

  678. 0 Q: t) C/ U5 D0 C3 E
  679. /************************************************************************/
      w9 d; }" @! V& J1 G
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    7 m" ?; |' }. i' Q) U. {
  681. /*                                                                                                                                                *// k3 f) p8 V) l7 B
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/( K% e; g; }4 k$ b9 V1 [1 g) U
  683. /* the device:  1st data byte will be programmed into the initial                 */
      a( l' [+ B( `) {' \8 e
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    1 a& O9 x# s3 `( h9 ?  ^
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */, g. l7 c6 W2 @/ x/ V8 ~
  686. /* is used to to start the AAI process.  It should be followed by                 */
    ; V  K8 t* W8 o. K: B3 C5 u3 U4 d& Z
  687. /* Auto_Add_IncB.                                                                                                                */. a9 t2 h( z# W# |7 ^
  688. /* Assumption:  Address being programmed is already erased and is NOT        */# [% \  J5 ?% ?8 I6 C! r4 J* Y
  689. /*                                block protected.                                                                                */: U, t$ w0 C2 a6 ^6 x
  690. /*                                                                                                                                                */
    4 H! h2 h3 e" f# K' I# a" ^/ g; ~
  691. /*                                                                                                                                                */0 |' X' n, J  {( K# I
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */* `' h6 q, w. A# x% |
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */: C7 L4 S2 _0 P5 {
  694. /*         unless AAI is programming the last address or last address of                */* u) ?' Y/ [3 l
  695. /*          unprotected block, which automatically exits AAI mode.                                */- a2 G+ ~8 |/ i2 U0 ^6 N. x
  696. /*                                                                                                                                                */! p  X' t. P, T7 W
  697. /* Input:                                                                                                                                */
    ; o2 o. o# a  H0 H* F9 ]
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      k. U" ]0 u  P8 n+ g8 g
  699. /*                byte1:                1st byte to be programmed                                                        */8 c6 d' R, _6 X0 _) l0 }
  700. /*      byte1:                2nd byte to be programmed                                                        */$ a" y" N6 a- X6 V4 l6 y# D  F, I
  701. /*                                                                                                                                                */) f% [0 [, {/ b1 e+ s# I1 I0 V
  702. /* Returns:                                                                                                                                */
    4 ]  R6 H- U/ H& D( [; W0 n; d4 Q
  703. /*                Nothing                                                                                                                        */
    + Z3 f% c) e! p' M- h
  704. /*                                                                                                                                                */
      c4 d, t9 [" B' D0 c
  705. /************************************************************************/
    - L) Y# H+ ]  `5 d# y: F% |* L
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & F: w4 o4 x0 W* k9 M( _$ j
  707. {
    9 d. d( F0 o. j6 V, s* Z
  708.         CE_Low();                                        /* enable device */  S7 k: l2 r: e
  709.         Send_Byte(0xAD);                        /* send AAI command */
    2 Z% u. G2 b, N6 U
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 ^# G1 {6 Z8 s4 y1 P
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 `! T9 s$ {( _% V1 F
  712.         Send_Byte(Dst & 0xFF);- A4 B' `1 B; |5 [* L" h6 Z) I
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    - A, L6 n* w2 `
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */& D) S( X7 A5 m9 p( @; [+ `5 ^& ^
  715.         CE_High();                                        /* disable device */! B( Z- `! }" q8 _9 |* P
  716. }
    1 N; ?9 s; N& E
  717. % ^  b7 }9 b7 v- a/ i$ `# K. Q
  718. /************************************************************************/
    ( q; \1 o9 P# p% F8 n/ c
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */" @1 }: F, L: K9 R7 y, s) D# N, F
  720. /*                                                                                                                                                */
    1 k" g& ]2 J& v- ]' _' b3 A
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ; l& C( `3 x2 s" \! Q' A
  722. /* the device:  1st data byte will be programmed into the initial                 */
      O* T' [/ T0 Z4 o& ^
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    0 R8 S* N1 s$ I9 q5 o& j7 H
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */$ J; k2 V" b( o$ i3 r( s1 A; B
  725. /* is used after Auto_Address_IncA.                                                                                */2 f8 b# B  I' [% E5 S1 l5 H# p) n6 O
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    " }3 {. F; a2 b/ o0 i6 u  o
  727. /*                                block protected.                                                                                */
    , B) |4 {- D2 R8 y2 L
  728. /*                                                                                                                                                */
    " E! E; s7 p* n6 y
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ; m5 G# z) Q  M8 A! z% y- b
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */( G, w8 ]! ^- j7 N' ?
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. A" v3 _5 q+ o! J" h
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    , y9 j1 e& L- M3 c5 s" C
  733. /*         last address of unprotected block, which automatically exits                 */
    " J- D' M+ Z. @% C: ?8 h- j8 r
  734. /*         AAI mode.                                                                                                                        */) H/ ]0 n5 n7 E! F/ W
  735. /*                                                                                                                                                */
    - [# W1 J- }( }- h3 I8 M3 q
  736. /* Input:                                                                                                                                */
    ' q& J  ]7 u4 p/ l' u0 a0 [3 q
  737. /*                                                                                                                                                *// T1 y/ t2 \; ^4 O4 }+ v0 P
  738. /*                byte1:                1st byte to be programmed                                                        */2 @: y$ O0 f4 C2 w. f& k- _
  739. /*                byte2:                2nd byte to be programmed                                                        */
    1 C) j  t9 u2 |
  740. /*                                                                                                                                      */# z6 w. J( E% X6 V
  741. /*                                                                                                                                                */3 p( P& Q3 s& ?8 o* W2 h+ n
  742. /* Returns:                                                                                                                                */  {* T7 \' [) r- }: A
  743. /*                Nothing                                                                                                                        */
    " P: |* M' {. P- h
  744. /*                                                                                                                                                */
    : M- q2 ?% ?. H* g5 Y% S; @
  745. /************************************************************************/
    $ V  E1 H3 f8 U7 M+ i& l2 z
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    - T7 J; e2 `* N1 a$ v  N
  747. {& O4 _" p( n; b; z. C, E0 B6 p3 N
  748.         CE_Low();                                        /* enable device */; }3 [7 j: F( d( x/ h$ o
  749.         Send_Byte(0xAD);                        /* send AAI command */# a1 b' L, X! `+ c$ `8 k. k$ f$ r$ j
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */6 ~, s4 R3 k5 f$ E$ B* [% s
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    - S9 [- o3 {* m6 L9 W$ J6 d
  752.         CE_High();                                        /* disable device */
    & I/ X- H* L& t+ ~' H2 ?* a& I& k
  753. }# A6 O, Q& u! C6 V9 p

  754. ; m+ l7 i# Z. e; |
  755. /************************************************************************/
    0 }! H" V, l+ w
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    * ^7 Q' A- Y, A! [3 g
  757. /*                                                                                                                                                */
    " K; Z, `, I, v0 U) U* n
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    4 K/ E. [2 n2 L" ]  k
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    + i7 {/ A0 M4 F  n
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    3 C) W; p3 X/ l
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    . C; f" e/ s- s0 c' r
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    3 G+ t; _0 s; ^( `
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */8 g3 `8 }9 v& M/ g7 g0 |9 M, r
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */: F7 m1 N  j9 G% n" ?
  765. /* Assumption:  Address being programmed is already erased and is NOT        */: p9 l4 ^7 l( V1 |3 O' X- @" w; _
  766. /*                                block protected.                                                                                */2 t3 e, S% z6 a6 d! R
  767. /*                                                                                                                                                */
    2 K# |6 o7 q, l2 e* I
  768. /*                                                                                                                                                */9 s1 d3 z. V% P6 ^# s; z- M
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */# G1 x' w. q% Q, O" f
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */8 }6 n! c5 I1 Y& k3 X8 h
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    8 X/ ~% O. v5 t% I
  772. /*          to exit AAI mode unless AAI is programming the last address or                */2 ]+ l" f" F  s& _
  773. /*         last address of unprotected block, which automatically exits                 */" T: _/ H; d( u% z
  774. /*         AAI mode.                                                                                                                        */
    5 C- V% q, C- L- m
  775. /*                                                                                                                                                */
    . x5 J" R8 w( o4 s& |
  776. /* Input:                                                                                                                                */
    , V4 p+ A+ m9 M4 H8 F" y" A. ]
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& S; L( j) E" U' t# N4 G
  778. /*                byte1:                1st byte to be programmed                                                        */! d( ]4 W2 I" N+ e, Z4 x. u
  779. /*      byte1:                2nd byte to be programmed                                                        */
    8 n  `# `% \/ J5 R/ a( Z! T- C
  780. /*                                                                                                                                                */0 Q% {! a0 `; s$ Y
  781. /* Returns:                                                                                                                                */2 c! v% B2 m0 ?' P0 j4 v) G
  782. /*                Nothing                                                                                                                        */- f1 }/ m- X# i
  783. /*                                                                                                                                                */
    , ]* g( z9 M  s( [8 A8 `/ g' j
  784. /************************************************************************/( z6 u2 P# r: X6 n8 o
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ( B8 y; X) e$ Q! S/ j
  786. {+ A, m1 _! U* [  a! d
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        ; l& q% m4 ~# ^3 @
  788. 5 K" y+ u3 J3 f
  789.         CE_Low();                                        /* enable device */
      h& |5 t0 h. X2 z3 h  S6 p- v; t
  790.         Send_Byte(0xAD);                        /* send AAI command */
    % ~5 g) U! b. Q$ v% ?
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! r) @: y( W* U4 D" {- h5 h! a' x" ]1 Z! j4 N
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));% r3 q/ u0 l' L9 W5 p/ F8 H
  793.         Send_Byte(Dst & 0xFF);
    . s) ^$ J" O+ T) A
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    # z) {  w0 g! X0 c4 v5 D
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */. J( u3 R3 ~0 _( ]* j7 s
  796.         CE_High();                                        /* disable device */
    ; P5 e2 @2 k2 W& w4 l% n- L# c, n/ c
  797.         0 n1 C1 F8 G& H0 E" m
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */% |% _) A' f3 }
  799. $ n; Z) r( S+ s, h4 @
  800. }# T! h5 y! E- b8 C! X4 p# D

  801. 9 c! L4 x; Q3 O/ Q: r
  802. /************************************************************************/
    3 |/ Z& }& V6 K  l- |% Z
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    2 h' s" ], X0 s/ q! H  C3 F
  804. /*                                                                                                                                                */
    ( I8 [8 M( s4 l0 h8 W: W1 Q; z& h
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */$ D" A/ W1 }- t/ R
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */% ]" |+ o* u; x! P7 z
  807. /* AAI programmming is completed.  It programs consecutive addresses of */% s$ i3 @$ B0 c! p
  808. /* the device.  The 1st data byte will be programmed into the initial   */8 r9 Z8 t: v* R) g5 C, @- q
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */, m& @' x0 z4 z8 i' j3 i
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */! Y- S, |: ~  k8 q. k) z
  811. /* used after Auto_Address_IncA.                                                                                */
    7 J# `/ _, a4 a: b, I: _5 r2 q, [1 l1 P
  812. /* Assumption:  Address being programmed is already erased and is NOT        */' {% J/ z! u6 y& T- \- J+ {
  813. /*                                block protected.                                                                                */
    3 x0 N0 G( U' h' S) \9 m1 |
  814. /*                                                                                                                                                */3 J, u4 I+ |! s4 L: O5 }
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */2 T" S4 e& d# L5 O0 ^3 c: L
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */- F; c$ }: D& [
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        *// }2 Y! h8 n8 R% z
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    % \$ p. B5 w& y& m" ^
  819. /*         last address of unprotected block, which automatically exits                 */9 E7 h; B# t8 L# g
  820. /*         AAI mode.                                                                                                                        */
    , M9 ^$ n" B( N# `! e
  821. /*                                                                                                                                                */  z$ ~, {8 k4 Z6 T1 E0 E
  822. /* Input:                                                                                                                                */' y" ~0 a( r" d% W; E
  823. /*                                                                                                                                                */
    - t8 y4 m  m( e6 t4 f& W7 U
  824. /*                byte1:                1st byte to be programmed                                                        */
    ( V" j6 c/ G; K, E3 Z; k
  825. /*                byte2:                2nd byte to be programmed                                                        */
    $ c' R* S  I" B' l8 y& S
  826. /*                                                                                                                                      */( L0 c' [0 ]/ W
  827. /*                                                                                                                                                */
    ( f2 L: ?$ K; o& ^8 G6 U) b
  828. /* Returns:                                                                                                                                */" h% }  H$ M2 o
  829. /*                Nothing                                                                                                                        */; r$ R  u+ @+ a- V; S& U
  830. /*                                                                                                                                                */
    ; v# C& G7 u. P, X3 o
  831. /************************************************************************/
    : `. J7 |+ {$ `' d6 \7 F  t
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)1 q8 k6 n% v* o5 z. ~* a9 N
  833. {
    6 k: C/ t7 T8 q; I
  834.         CE_Low();                                /* enable device */
    : V, t2 v- O4 R
  835.         Send_Byte(0xAD);                /* send AAI command */
    ; T" D* U: N  |5 M$ D% `" _
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    , l/ a/ q# V& o' M; J
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    # S( x* ~* P% R3 U
  838.         CE_High();                                /* disable device */
    ) S6 J1 T+ n5 n8 Q' |( X
  839. , W! p( I( p, x. J
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    1 Z9 L" [; I' s- s; T8 `

  841. - Z3 s# f% x/ m. B% y: t: P2 Q$ k
  842.         WRDI();                                 /* Exit AAI before executing DBSY */- y. n1 k8 y* A, C+ Z$ b5 d
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */' Q1 x! [/ G7 {) E1 }* r+ e
  844. }
    * p! ~5 H9 k( a# _* ]1 P: E

  845. ( g6 N, s4 B9 Q6 F! ^9 J6 z( y' W
  846. /************************************************************************/& d+ u6 b  @- ^" _2 F# I
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    2 O* Y( c* i) s% `! W  ?$ `  I
  848. /*                                                                                                                                                */5 }: j. V* C# _- Y* g5 P) w, G9 z
  849. /* This procedure erases the entire Chip.                                                                */1 B$ _, M4 r1 t
  850. /*                                                                                                                                                */
    6 s& ~1 U1 G" x
  851. /* Input:                                                                                                                                */6 P" V) J' {: z6 v+ \7 g
  852. /*                None                                                                                                                        */
    3 j: S2 U* N' c8 [( M3 V& `1 R
  853. /*                                                                                                                                                */
    ( q0 Z- H- v9 F2 R
  854. /* Returns:                                                                                                                                */# p/ c9 s3 N9 V
  855. /*                Nothing                                                                                                                        */
    1 D2 v) {' [; j+ ?0 v' G- w9 G% Q
  856. /************************************************************************/
    / w2 C- Q5 z( e( w! J
  857. void Chip_Erase()
    ( s6 }, u1 J5 V
  858. {                                               
    ( H, x6 m- w% b+ y" a8 z# j
  859.         CE_Low();                                /* enable device */
    / |; e" E5 g# ]" o( a1 H7 z3 K
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */- t* q& l" V, m
  861.         CE_High();                                /* disable device */; F: h6 ^3 `1 _0 _/ P- b- t
  862. }
    ) T6 V6 G2 T6 T- c2 z2 ~
  863. ; d. Z, n% c+ p7 Y2 V7 r8 j
  864. /************************************************************************/
    , P- D1 E( n; }& @  t) G: _7 m
  865. /* PROCEDURE: Sector_Erase                                                                                                */7 H5 S5 e7 [! {, T1 F4 a; Y) _
  866. /*                                                                                                                                                */( F1 j1 C1 N& x8 O9 B/ J7 V1 i
  867. /* This procedure Sector Erases the Chip.                                                                */7 U% V3 L- P9 Y7 O5 r
  868. /*                                                                                                                                                */
    : ]1 t8 A, r3 j
  869. /* Input:                                                                                                                                */- f9 J8 R  }5 M' `, U8 M) A
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! q% R7 o* h8 d1 a% c
  871. /*                                                                                                                                                */
      O: A* c) G- Z/ Q3 |7 O' s5 \
  872. /* Returns:                                                                                                                                */
    $ @/ O- F( Z2 ~; J& u' m9 Y# Y
  873. /*                Nothing                                                                                                                        */
    0 f3 u8 I3 \1 F  y1 a! T
  874. /************************************************************************/
    8 |; z* I8 c+ S
  875. void Sector_Erase(unsigned long Dst)
    + z. g9 x# ~' S) c1 N. t- k
  876. {
    & L# O$ k2 ~" f+ g

  877. 3 ^$ |; l) r& R3 z; a8 S
  878. & t! e5 Q# a, b2 j+ U+ P$ e( L; T
  879.         CE_Low();                                        /* enable device */
    ! f6 J- g; R2 q8 K( q) Y
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    7 D3 z& x! {3 g& g
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# V: i" g% ?3 j0 t' V
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));' ]3 @6 K, _& m# l. T( G2 L
  883.         Send_Byte(Dst & 0xFF);
    5 G) g* E1 U& T$ w8 `
  884.         CE_High();                                        /* disable device */9 d; u+ R. G# N8 s  U8 O# v
  885. }       
    ! d% t. O0 H$ K# d& G9 ~+ N, u
  886. ' `  Z/ e- M9 ^7 |' o0 i0 r% E5 L) q
  887. /************************************************************************/
    ) {( _' r3 C7 Z  R) A. i2 h
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */2 g7 z+ V) ~/ W3 @6 }
  889. /*                                                                                                                                                */9 m  K+ ^1 q5 G$ U0 y
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */# s9 R8 d2 k( V' D6 B
  891. /*                                                                                                                                                */' Z) ]7 w, m9 h* p
  892. /* Input:                                                                                                                                */0 W$ E8 @$ `" y. S, O4 {+ z
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ q) a5 X9 z* [) f& F
  894. /*                                                                                                                                                */& `& e+ l% t- v: K% l
  895. /* Returns:                                                                                                                                */
    - B6 ?( f& e% t* n, H7 g+ d8 s
  896. /*                Nothing                                                                                                                        */
    , e9 |( q/ M+ _9 n) u* A- U
  897. /************************************************************************/( J. Z  w, e4 d6 w  }  e$ U
  898. void Block_Erase_32K(unsigned long Dst)
    3 m, R  p0 P% }" [
  899. {( F# [% v, r' @7 L& g
  900.         CE_Low();                                        /* enable device */! _2 M1 J* a# k. S7 x5 u7 ^* B7 b
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ' {& Z: `2 r2 `5 k, b
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  X+ f6 p7 l6 x: }) R
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
      Z1 }: |9 t4 o' N- B* R$ E$ r
  904.         Send_Byte(Dst & 0xFF);+ b, K. [& k/ O* O
  905.         CE_High();                                        /* disable device */
    ) M3 W$ x* c+ O+ a( {/ O9 d
  906. }
    5 \2 o% y/ |2 J% g
  907. # K6 a" E. \$ q2 ^& Z: f: O
  908. /************************************************************************/
    2 W& ?( I0 Y+ I) }
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */6 Q' k9 ^5 u  I+ t7 e
  910. /*                                                                                                                                                */- o/ j+ x0 |6 j, \3 U9 e/ G
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */: E5 B  I4 M( ~6 S
  912. /*                                                                                                                                                */
    + ?! }& T* F5 j  z3 G- ]
  913. /* Input:                                                                                                                                */
    " T  K! o3 E! ?9 y. O" c% a- y
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    3 ?0 y2 B0 G1 r( V/ ?0 w
  915. /*                                                                                                                                                */& Q: B7 t# y" P+ m! j
  916. /* Returns:                                                                                                                                */7 X& f. v6 _2 H  o
  917. /*                Nothing                                                                                                                        */( V6 M0 Y+ i' w$ ~+ H
  918. /************************************************************************/
    7 w, O, J+ F6 r( {: h8 ?
  919. void Block_Erase_64K(unsigned long Dst)9 e) G7 ~/ R+ g( C+ ?
  920. {% e+ j+ k+ G+ T/ Z) J. T7 i: H
  921.         CE_Low();                                        /* enable device */. b/ B; T' m! w; {% T! J
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */: E9 J/ l8 l  k, }' [& N: x
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      x" h0 R, g! v9 B4 I
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * S& b* H" H9 ~9 u( l) H# S: J
  925.         Send_Byte(Dst & 0xFF);
      ?. v1 q8 W. @" s% r3 n* A
  926.         CE_High();                                        /* disable device */; s- K: {& ?' r' ~8 I5 m, R
  927. }
    + p2 G; E9 R* T' K
  928. " z2 E6 C. x+ u
  929. /************************************************************************/: ]6 T3 u+ s4 K. k
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    3 E* s6 j- s& K" H5 ^
  931. /*                                                                                                                                                */3 o/ T+ D* N$ ^
  932. /* This procedure waits until device is no longer busy (can be used by        */2 e1 I, y: W# v9 ], Q+ Q
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    8 G, m( _0 q2 N5 J+ y, Z5 A  B
  934. /*                                                                                                                                                */
    ; ]0 v! P( N& }* v+ ~) W
  935. /* Input:                                                                                                                                */
    ! c; }' k% _6 m
  936. /*                None                                                                                                                        */! y( c& r  Z$ X- J$ L- Y
  937. /*                                                                                                                                                */
    8 c6 h, z% t8 a& ~+ G
  938. /* Returns:                                                                                                                                */
    4 c" @/ c! S, i
  939. /*                Nothing                                                                                                                        */! q( a5 l& X* I' f7 l- c2 h* s9 |
  940. /************************************************************************/! o$ ^$ m/ Q+ g) K$ O! s3 h
  941. void Wait_Busy()2 P: D4 R4 o4 N5 s
  942. {  ]$ x* `. _  a% z5 k/ |
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */5 G9 Z. H( Q( N# F/ T; T9 S8 S$ W
  944.                 Read_Status_Register();
    2 }! W* i) k; X' q3 C
  945. }
    - L8 Z& M, _9 u4 e  k# \! r6 t5 \8 Z' S

  946. ) t, W' `; I, X
  947. /************************************************************************/- Q7 q: ^+ ?$ k8 o
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    $ n" J. e. h" R
  949. /*                                                                                                                                                */6 ?% L: q! X$ A# H4 i2 d+ }
  950. /* This procedure waits until device is no longer busy for AAI mode.        */3 N6 ?* l1 Q) E$ q
  951. /*                                                                                                                                                */
      O$ {5 c% \9 s9 D' [
  952. /* Input:                                                                                                                                */1 ^# B! B7 b5 B% k3 e
  953. /*                None                                                                                                                        */1 X* w9 f' F" T1 ]. L& J
  954. /*                                                                                                                                                */8 V6 K( j' I8 n$ b$ _
  955. /* Returns:                                                                                                                                */
    ! L6 j" F5 U1 {; M4 d; V
  956. /*                Nothing                                                                                                                        */; }5 L1 U+ M& ^
  957. /************************************************************************/
    3 S9 u" C) {4 q; Y# u' a1 c& o
  958. void Wait_Busy_AAI()7 F* |, Y4 {  N
  959. {9 U+ [3 e* g4 o0 {) U1 }) K0 _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */! Y+ j  k5 r( a3 ?" }# X
  961.                 Read_Status_Register();* g7 ?+ ^: I1 W, h& C
  962. }( Z1 L4 g2 }- H1 P8 [8 c( F5 b
  963. 1 r$ M1 t2 B: F0 x9 s& U2 ^$ S" |
  964. /************************************************************************/$ b" \" W/ v7 _$ v) I; p
  965. /* PROCEDURE: WREN_Check                                                                                                */, H! ]9 b9 q; u9 P" g* a2 U! f" _
  966. /*                                                                                                                                                */3 S" s& V9 G( i) t+ A0 m
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    4 z# D( N/ F. R9 ]6 j/ l
  968. /*                                                                                                                                                */
    1 s, Z  n  `" H
  969. /* Input:                                                                                                                                */
    & g; V- N( h: R6 _  K5 ~; |0 p
  970. /*                None                                                                                                                        */$ _- r) q) l& ]; T
  971. /*                                                                                                                                                */% J: y6 ^: h) |
  972. /* Returns:                                                                                                                                */' n* g7 h4 u9 h' a; j
  973. /*                Nothing                                                                                                                        */1 u0 _" [% o5 k$ \! r% F
  974. /************************************************************************/6 f  \& B, {) s) x- u0 `4 j
  975. void WREN_Check()* ~! z+ Z$ d1 T* N9 F
  976. {) `$ c) e' s9 P' }; z% S" x
  977.         unsigned char byte;
      F9 B( Q$ A: r: U5 d
  978.         byte = Read_Status_Register();        /* read the status register */
    ( @. B/ Z5 L+ }. ^* U+ v$ P) P
  979.         if (byte != 0x02)                /* verify that WEL bit is set */6 @/ @# L/ V( J4 X0 `
  980.         {3 |% w, {9 e3 s
  981.                 while(1)
    3 u2 L7 Q- e! }& n
  982.                         /* add source code or statements for this file */- z& ^; E; b% D" u! {
  983.                         /* to compile                                  */
    / F9 B: K  K* L. g0 @0 H& M
  984.                         /* i.e. option: insert a display to view error on LED? */  ]; R1 X3 Z$ G1 g
  985.                  + {* `% @0 L: x% Y- W
  986.         }
    2 q# U/ [# I% n6 x) [
  987. }% {7 |/ X7 l9 T+ u* a
  988. % v* H" L7 y: a1 e
  989. /************************************************************************/, t; j$ F; k" L! `/ k4 O( x
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        *// Q1 D2 s2 t- ~; o4 o. E
  991. /*                                                                                                                                                */
    + B5 t! t. |6 y3 ]0 n. K
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */% C9 V1 M' S. i- [
  993. /*                                                                                                                                                */
    9 J& ?) J7 {. z5 f" Y- V
  994. /* Input:                                                                                                                                */; Y/ n8 O4 e; s, B
  995. /*                None                                                                                                                        */
    4 }9 f: P) y/ ~7 u
  996. /*                                                                                                                                                */
    8 v5 o8 T7 s. h9 r5 K
  997. /* Returns:                                                                                                                                */
    1 g2 b$ u2 i8 u0 T( k# D
  998. /*                Nothing                                                                                                                        */7 U4 q2 A4 Z! L
  999. /************************************************************************/
    & f% z* h$ D. A* }) m+ d" T  A  J8 v
  1000. void WREN_AAI_Check()
    $ P( a+ g5 |' f$ S
  1001. {$ z2 i% [1 V; O) e" {) F
  1002.         unsigned char byte;
    * N' p! \0 D8 u/ X
  1003.         byte = Read_Status_Register();        /* read the status register */
    " _2 f3 ^3 N9 I* E2 g, o- u; D: C
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
      w% c7 J, s7 Z' w& Y7 [
  1005.         {
    # R5 E/ @6 o  l" j: C4 u
  1006.                 while(1)               
    5 B; L3 u! S' |  g. k) p7 y5 I
  1007.                         /* add source code or statements for this file */, `- ~0 o) @+ _) d
  1008.                         /* to compile                                  */# d# {% z3 Y! ?5 r& |5 T; |
  1009.                         /* i.e. option: insert a display to view error on LED? */
    4 T5 j6 ]0 x' W! M# Y7 c6 F
  1010. 9 U0 C5 |, i% `5 W
  1011.         }
    1 j7 D8 [9 x% W! h
  1012. }
    8 S8 `" }' e2 P, d/ Y
  1013. ) u1 L' l& b* G/ H: ?
  1014. /************************************************************************/
    # X+ x9 Y; E% M. i3 ~
  1015. /* PROCEDURE: Verify                                                                                                        */1 Z0 _3 r$ X& `6 z- ~
  1016. /*                                                                                                                                                */
    + }1 K! N8 C& I
  1017. /* This procedure checks to see if the correct byte has be read.                */
    . B5 H; L3 r; B1 n' J2 l2 p* }
  1018. /*                                                                                                                                                */" t4 T* W" _) G
  1019. /* Input:                                                                                                                                */
    ' \" |  X2 ?( |2 J+ Z
  1020. /*                byte:                byte read                                                                                        */- A8 `  ~' [% i* S( b
  1021. /*                cor_byte:        correct_byte that should be read                                        */) y9 ~, C) I8 H. _# ?9 x
  1022. /*                                                                                                                                                */
    9 b8 I* `6 ^& O( u& e! s, z% M/ b
  1023. /* Returns:                                                                                                                                */: I7 h) E$ x; M6 o
  1024. /*                Nothing                                                                                                                        */, g+ f* v5 S' a' i
  1025. /************************************************************************/% `9 C) o3 x, q9 `
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    6 F( a& i- t: m7 Z: b- f9 x3 @( X
  1027. {: G* u# o6 _2 t3 P, K; P% c# I
  1028.         if (byte != cor_byte)
    0 j7 G# M1 p! i6 V4 s& W$ Z
  1029.         {
    ! V' {9 @; j+ ^2 o+ j) E6 L
  1030.                 while(1)
      e/ y( k7 A3 ]# \
  1031.                         /* add source code or statement for this file */
    $ g$ k  e) ^( x' u' E0 b5 ?
  1032.                         /* to compile                                  */2 b7 b; ~" f, T
  1033.                         /* i.e. option: insert a display to view error on LED? *// C8 q, x6 D- r3 [5 C8 i2 X9 P5 g
  1034.                
    ; Y, s) s* f+ ~& k1 A
  1035.         }
    ( e( ~0 C- `" U, o; _: a8 z4 ~( i) l# g
  1036. }
    / @+ H9 u% e# l) y: Q
  1037. # W, T; F+ W+ I, j" v& J7 N! B

  1038. & |7 v& [$ b- _: v; d2 h; g3 X/ P; H
  1039. int main()/ t8 ^! s& ^! }
  1040. {3 y' e5 h5 ]$ U1 s% l
  1041. ! }9 x! D3 d- G  ]
  1042. return 0;2 X+ g% l, _9 Y+ H- t7 [5 W
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:( @9 s0 R3 x" u0 A# b
   main()
1 }, I1 |5 Q) g5 J; L   里面怎么是空的呢?" M) d/ N3 k, M; @: k' q, P( j. f
   发一份给我吧0 E# m+ ~2 z: [6 U$ x
mail:luyijun2005@hotmail.com  B  v! L! S+ J. s
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
" A/ r" b+ S- n5 |' i4 J# {/ E1 ?; q' `- y+ E- E
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
. F! c2 A) E$ z) HEC的代码在哪跑,你看DS的说明,每个EC都不同的。
, K- @% y& p- ?- V( ~OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?0 I% v+ H! E/ V" b
上面几个问题是你没看任何东西而白问。
. s" _4 ]. ]7 r6 ?$ L& A/ f7 M2 }" j( d
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
8 G# m) T9 [4 S6 n7 K& Z  b. ^) a! H6 J& j' P# ~
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!' I; j% d8 l) }2 A# h+ A
7 K1 ?  ?  t7 _: w; I
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”/ c7 ]! i) }% b; Y

+ m+ {4 h' R4 W! M4 Y, o关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊.../ r0 X, Q) T4 H7 _$ I  X( _
0 \& K' q- i* N4 c
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样; y0 \; s" g/ w8 u! O
似乎要把SPI能support 到最大,这EC chip应该有好卖点8 O' }4 y; o# X1 p
BIOS功能要不要强大,也就决定了SPI Flach的大小
9 r* f1 P$ \  T- Q. n3 _我是这么想的~让OEM去决定要挂多大!: k) Z5 }! M; S8 a# b6 v5 k! g
如果我司有BIOS工程师就好了~哈3 H$ U. J9 {2 [
WPCE775应该算很新的东西,来看它支持到多大?
+ l+ p) ?* |% Q- O# d7 e0 w/ a' X  S. s/ \
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
" f5 [& H* h5 g9 h3 t3 }4 G  H其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
- l9 h1 x) K! ]) ^& r+ `4 x  N* `1 ?5 W& L+ Y) s
这份driver收下~希望以后有用到6 U' X# ^4 B. b9 e* }3 Q# u
谢谢bini大大' g& R, g- ~! ]8 e$ {+ }6 V
1 c3 o0 U& g9 w  Q: w/ W( g0 G
很新很新的新手,如有错误请指正 (准备看第二家的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(): e. R# G/ B3 E  ]4 g1 r" G
{
6 ^6 B' B# p& j* V" `0 B  I1 [        unsigned char temp = 0;$ Y7 n# o  `+ c8 s. i
        CE_Low();4 G' K8 J$ m# v( Q
    while (temp == 0x00)        /* waste time until not busy */
$ V; O9 r4 G9 |$ ^' z' n3 ?                temp = SO;
  Q$ D- l& X: l# N: V  J0 }        CE_High();
! B1 Y$ s. [' U, c, h5 \. |) o, Q* q}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
" f5 r6 l* \9 W# T{# [7 h7 D: D6 @+ R
        9 o' K! H& n; L+ t' |) b
        unsigned char i = 0;
( M- h1 Z# |% I: t        for (i = 0; i < 8; i++); \% m. Y! g. {+ {- x
        {
+ a$ d. P) m# Q" }* F3 C$ e                0 Y2 ~7 k# c4 u4 a6 Q( r
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
/ U. \2 G8 K' B6 @                        SI = 1;
' q7 k$ `0 Q& S4 x4 M- `+ j* |                else/ ?: M3 i) t" j3 B0 a3 ]7 X
                        SI = 0;                                /* if not, set to low */
' i6 L/ q2 N$ ] 问              SCK = 1;                                /* toggle clock high */! F  Y1 R9 T; k& {
   题            out = (out << 1);                /* shift 1 place for next bit */9 b( W: q# l& j, E4 F7 n
                SCK = 0;                                /* toggle clock low */
4 N" ^1 E4 H6 |2 ~: s4 T2 l        }- v1 f9 n5 p; a0 B: d8 |
}, z% D1 q1 j& p
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-11 16:04 , Processed in 0.055295 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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