找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55221|回复: 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
    + r, y' b# ^/ v' k* D0 X
  2. ! ?) L+ c3 q: h3 A" B7 E! |1 |* X
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory- Z0 ?7 C+ |8 m2 ]: c% I4 ]+ m' ^

  4. / {, [5 p8 X. ?/ u6 j
  5. November 4th, 2005, Rev. 1.0  Z2 l1 n, j' P
  6. * j- k+ R+ x2 w9 `- M& G3 F# T
  7. ABOUT THE SOFTWARE
    # p+ ?9 t# h  X. l
  8. This application note provides software driver examples for SST25VF080B,
    5 g. l, ?% ~+ Q2 `0 B: X% Y
  9. Serial Flash. Extensive comments are included in each routine to describe
    $ w  \( S: y1 G. @
  10. the function of each routine.  The interface coding uses polling method + a, f3 q8 m  |, x3 T
  11. rather than the SPI protocol to interface with these serial devices.  The% \9 b; ]$ z2 |& L5 m- ?( m
  12. functions are differentiated below in terms of the communication protocols
    ' V; T! {( K1 G* x1 e, F
  13. (uses Mode 0) and specific device operation instructions. This code has been
    / \1 N" [7 t" Y- e
  14. designed to compile using the Keil compiler.
    9 A  U' i1 k9 T% L* h
  15. ( J2 e* o5 T) }/ _# n8 c
  16. 9 |$ X5 _) F6 v& ?+ u: d
  17. ABOUT THE SST25VF080B$ x8 l2 t+ o/ `) y$ Q, u

  18. 8 U8 p" }  q$ x
  19. Companion product datasheets for the SST25VF080B should be reviewed in & @6 q) u1 }. w. b, x
  20. conjunction with this application note for a complete understanding
    / F( z1 s9 K% r) p. A- @
  21. of the device.
    " L+ M" M% b8 v0 p  z

  22. ( ]3 X' N0 A2 z& l  b( n

  23. + M, T7 D. j( p! d
  24. Device Communication Protocol(pinout related) functions:+ Q: ?7 @* I+ n. D( m) D4 r% b
  25. : T/ j8 x0 r0 N+ Q$ ^- ?- h3 i. G
  26. Functions                                    Function
    " [+ k. Z+ \7 M9 P5 U
  27. ------------------------------------------------------------------
    7 A) A) |2 O- F. p6 U9 e. e8 j
  28. init                                        Initializes clock to set up mode 0.
    1 s3 @1 z. E/ R0 y+ |& j
  29. Send_Byte                                Sends one byte using SI pin to send and ! s' s8 T% c0 Z# W
  30.                                                 shift out 1-bit per clock rising edge
    1 K. Z' X: e) o7 h1 ?% O
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    - @/ y6 `4 N  w& O: C) t" |. [
  32.                                                 in 1-bit per clock falling edge
    ; }# m+ ?! I+ ?- x5 W/ J- V; _
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    : ~7 g) }3 |( }% }) |- u
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high' D# j7 l! U, w" M; z
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    * x) x* a/ w" l' b  u, W; @
  36. Hold_Low                                Clears Hold pin to make serial flash hold& i# f; W; S: A, B
  37. Unhold                                        Unholds the serial flash
    ' }, R% I3 Q/ p+ y% C" X
  38. WP_Low                                        Clears WP pin to make serial flash write protected5 s; a% _1 W. B. S) q5 _+ G
  39. UnWP                                        Disables write protection pin: y" I/ s; \3 d( I, b
  40. , a4 W; D( c' F
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code  V* v7 Z5 _% R7 F* t" E
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your8 X/ \0 d* M2 n1 M
  43. software which should reflect your hardware interfaced.          & e( P$ |. n+ O) ]; _
  44. 7 g) L. |( q1 x5 @/ T1 W! ?
  45. % F- N3 h, x/ P, z
  46. Device Operation Instruction functions:
    2 t, F# `% B0 e; {
  47. 7 `  g' {# N4 p, B% d: Q" W9 ?
  48. Functions                                    Function
    ! L' U! i- O1 n0 ~& q$ S
  49. ------------------------------------------------------------------/ r' _' H- X" M0 J5 |4 M& |4 C: d
  50. Read_Status_Register        Reads the status register of the serial flash
    # i+ @) U$ n: {* z
  51. EWSR                                        Enables the Write Status Register
    2 x. _. N5 V% I7 c
  52. WRSR                                        Performs a write to the status register
    3 P; o, ?# R8 M2 i* {5 b; J
  53. WREN                                        Write enables the serial flash
    , a, L- o+ U  g! O
  54. WRDI                                        Write disables the serial flash% @+ o! b; `) w  M+ e+ m
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming' ]# V' g) h- G. q9 m: i* F
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming  I% o& |* T  G/ O0 t
  57. Read_ID                                        Reads the manufacturer ID and device ID- c# }* x" Z. s/ u, l" s( Q
  58. Jedec_ID_Read                        Reads the Jedec ID/ `3 D* |$ k" i# L
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    : ?9 D5 K/ g- N/ B, f! B& d
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency), N; Q6 N+ L- n* X* a* o
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    , f, I1 h' Y5 M2 i0 ^) i
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)$ k/ O7 \; q3 R. T; ]) ~  h
  63. Byte_Program                        Program one byte to the serial flash
    . \' ?% f# J6 }5 |* e
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    * y( f  a+ t# S% F/ a  D7 [
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation7 _$ ?, g, @8 N0 K9 a
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    & W4 u: f8 {& l4 q" b1 V
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    ' z- C9 L9 E9 m
  68. Chip_Erase                                Erases entire serial flash
    / d2 s* U- u5 b, p* I' p
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    " G( ~' G4 ], e4 u- q
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash& l2 p4 Z1 ?( h
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    5 i% H" d# M8 T4 T# m7 O
  72. Wait_Busy                                Polls status register until busy bit is low
    2 |1 i7 p) n3 C! I( n* M
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming" h* J7 B% P* G/ Z/ f7 ]
  74. WREN_Check                                Checks to see if WEL is set6 v7 U% `5 n% y; ]
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set  w) I1 n- h. Z- u, q/ p
  76. & D# b  x- l6 _' S, b

  77. 9 ^0 T- ^, U% O+ R$ T0 h3 E

  78. . s  t. {  R" J6 Y9 c0 G4 Z( e
  79.                                                                      6 y/ J8 q8 C6 U
  80. "C" LANGUAGE DRIVERS & I; t: P" d. p" c. m: {
  81. 0 `! }* U' t, l" C  ~1 B) W
  82. /********************************************************************/
    5 {# Q: v4 V% j& W3 k4 s
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    % S& c) b9 J5 x* {' U# y5 b% M
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    2 A0 F# R! r. V  v% L: r
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    # U) U& N, z- \  r
  86. /*                                                                  */9 N( _7 [* ~' y0 K
  87. /* Revision 1.0, November 4th, 2005                                                                          */   / |3 T0 n2 o* u( B' v3 `
  88. /*                                                                  */7 q5 P$ V1 C) U2 }
  89. /*                                                                                                                                        */# D2 n4 A9 w; K! E, |4 G$ W( W; F  o4 D5 @
  90. /********************************************************************/
    # N0 r$ l: f3 P' x5 Q, A  |
  91. 8 ~% D& V4 k/ C$ o( n
  92. #include <stdio.h>
    3 O) _/ j- K( ~  Z" s
  93. #include <stdlib.h>  j! y/ _9 j+ u

  94. 4 I6 Y8 W' ~, W0 X$ H* ?" k; u
  95. /* Function Prototypes */- H9 O& _- M- c3 `  Q7 d

  96. . d. s# n/ o8 \( n6 z! N
  97. void init();0 q! C, x  }5 Y) x8 x
  98. void Send_Byte(unsigned char out);/ L5 Z4 U. {% ~" @' N' n) J5 H" i) E
  99. unsigned char Get_Byte();
    9 u9 ~. ?8 U/ |7 p) t# r
  100. void Poll_SO();
    7 V# k7 H8 w$ l9 j0 S: K8 Q" `
  101. void CE_High();
    , x  d$ K2 E* o/ q
  102. void CE_Low();* _( _- _7 F3 P: X/ I
  103. void Hold_Low();
    1 v3 \! c, Z$ G. z, n" B5 r
  104. void Unhold();7 {6 F- t3 }6 w1 F
  105. void WP_Low();3 r8 A, N+ E/ U
  106. void UnWP();' m7 ?& W- F' `; J1 K( X  m8 {
  107. unsigned char Read_Status_Register();4 ]8 |  u: F. G: I
  108. void EWSR();
    + e6 I3 b/ S( T+ X: o* g# k) B1 R& E
  109. void WRSR(byte);
    ; w# H! P7 z) R0 _7 A% q# w
  110. void WREN();
    $ A; Y$ N8 ~# e1 s* N) R$ p
  111. void WRDI();
    4 ^% V/ N) ~4 l9 X9 x7 @' ^7 t
  112. void EBSY();6 z8 x6 ?" O& _4 p8 P& P9 V: W
  113. void DBSY();
    ' p1 q% x, i' N# z9 z* P
  114. unsigned char Read_ID(ID_addr);! k* A: w* J" v$ E+ b  R, G  @
  115. unsigned long Jedec_ID_Read(); * Q0 r, @2 g* J2 `
  116. unsigned char Read(unsigned long Dst);
    , v- i! U5 m, z
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);* B3 [) S% x/ Q4 N8 D( l
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    5 Y9 m" Q6 V- T- K9 s. R3 c. ^
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);! w$ C, \; [: {6 W
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ( x" w- ~( s4 D( x* u2 X
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ; g3 R5 L6 {' t6 z1 S2 D; Z# U
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);+ I! f) \+ z' C7 p# D$ f2 Z
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);5 Q' Z8 s  E, U, m$ b* T
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    1 ^' I# U6 L$ z- t* E( _7 O
  125. void Chip_Erase();
    ) c# g5 M! a; f7 N7 ^( E% @
  126. void Sector_Erase(unsigned long Dst);5 J! n* m6 Z9 V8 ~; D: y
  127. void Block_Erase_32K(unsigned long Dst);- N8 @* ]7 i; N( N1 Z" f" l- u1 a
  128. void Block_Erase_64K(unsigned long Dst);
    4 A4 T) L) L; f3 ?' F
  129. void Wait_Busy();
    4 n; P7 z0 S6 y& u& C4 D$ L
  130. void Wait_Busy_AAI();
    " k! X1 }. t% p& R: f( n: N: H
  131. void WREN_Check();  e9 w2 L" k% m8 X% ^9 L3 C$ q! R
  132. void WREN_AAI_Check();
    5 I7 \5 A8 [9 Q+ o- H6 f
  133. $ f$ x$ Y3 ?' Z! T# h
  134. void Verify(unsigned char byte, unsigned char cor_byte);/ q* {: ~, M, m4 {! ^+ _

  135. , {, H  r) G6 {4 e! [& Y9 }
  136. unsigned char idata upper_128[128];                /* global array to store read data */+ O% [9 E* Z- D7 @( Y' F. N
  137.                                                                                 /* to upper RAM area from 80H - FFH */7 \( D* K" L; d; l$ D

  138. $ I4 F; w, e6 `
  139. /************************************************************************/$ M- l; }" c! o
  140. /* PROCEDURE: init                                                                                                                */, ?. ?3 t% n( _  q. T
  141. /*                                                                                                                                                */
    * W9 v4 m& H1 A, w; U* @" \2 J/ C# c
  142. /* This procedure initializes the SCK to low. Must be called prior to         */* }) g* u% z+ y: o2 s; H* e9 r. u1 ^
  143. /* setting up mode 0.                                                                                                        */% g1 E0 H5 i6 X
  144. /*                                                                                                                                                */
    , j+ q$ v0 h( ^  T. X" i
  145. /* Input:                                                                                                                                */
    " Y  K$ G+ `2 Z* k/ p  ^# z& y; J
  146. /*                None                                                                                                                        */" g& {; w; E9 \1 n
  147. /*                                                                                                                                                */( y" p* f: j* s5 c( Y
  148. /* Output:                                                                                                                                */
    3 z/ Q( p( H  N7 o- c; v
  149. /*                SCK                                                                                                                                */
    : n- w) g  ~/ p* r
  150. /************************************************************************/) K* f- h, u  @3 D" y
  151. void init(), c4 Y1 L+ ]# t' \; E: L7 ^* g
  152. {
    % z$ E! s( Z5 ?
  153.         SCK = 0;        /* set clock to low initial state */, t9 l1 e. T4 m' l
  154. }
    # l+ z- x! F8 b# R" F
  155. 8 e4 T6 H3 Z8 ~
  156. /************************************************************************/
    7 m+ R3 ?9 F: U* j+ i
  157. /* PROCEDURE: Send_Byte                                                                                                        */4 v1 a; O! H3 u6 p  O$ {- l7 z2 U
  158. /*                                                                                                                                                */
    6 }5 W* v5 O' w2 \3 ?  I& z
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    - N& z! b' J& I3 C1 |
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    * m$ R( a1 F5 O  P* X4 x
  161. /*                                                                                                                                                */1 ~2 s- T8 H7 @" V3 A2 j
  162. /* Input:                                                                                                                                */
    $ i, ]7 l7 F) Z/ D% R! Y
  163. /*                out                                                                                                                                */
    - A  l( r/ M) h$ m1 k  e( y- K
  164. /*                                                                                                                                                */2 J3 g  S' O) \4 m+ T+ p
  165. /* Output:                                                                                                                                */! \5 `" w- @+ b* [! c3 I; B5 ]# ]
  166. /*                SI                                                                                                                                */3 L2 w/ L# O6 w& s7 `2 `; ~
  167. /************************************************************************/" V( S  j7 O* a% c+ B$ O8 L
  168. void Send_Byte(unsigned char out)3 ~: y6 S6 ?# A
  169. {
    + \% K. b: T6 }% U
  170.         " f4 y5 X! `: E9 ^
  171.         unsigned char i = 0;
    $ D7 _- r+ A, z* n4 ^
  172.         for (i = 0; i < 8; i++)! h8 O0 Z$ e! }& b0 t
  173.         {
    . X2 W# L( J" M. {! E+ s
  174.                
    ' C, [' R% P1 y
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */$ L8 P8 y. P  R: Q  I& u# U( u0 V
  176.                         SI = 1;- p0 ^3 c2 ]2 h( C2 |% l- K
  177.                 else
    ; V. Z9 e1 u+ ]" [
  178.                         SI = 0;                                /* if not, set to low */
    ( x' d  i5 d3 ~% \
  179.                 SCK = 1;                                /* toggle clock high */0 G' s9 n6 k0 Y0 D3 o
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    ; E, W' z, t& j
  181.                 SCK = 0;                                /* toggle clock low */# S$ m4 q1 `$ K" E
  182.         }- f6 I9 r1 L; u. j
  183. }
    1 i: z; J2 I6 y# q1 o7 \; J

  184. ) n. S) X5 u9 ~- j
  185. /************************************************************************/4 O" [, N5 R4 F% S, X5 W
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    & h$ D1 W9 G' p! @3 i/ U
  187. /*                                                                                                                                                */: o2 d' Z' x: J, r+ h1 [2 x# h: B
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    2 r1 i$ m; {8 u' \) K. m4 `0 I
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ( }' R, }8 _& t( M! p: G  j  @$ r
  190. /*                                                                                                                                                */
    3 J7 v4 `5 x% N
  191. /* Input:                                                                                                                                */5 o0 Y( {' S: n: G
  192. /*                SO                                                                                                                                */9 K  j+ z& J: ]: O
  193. /*                                                                                                                                                */
    + r  F5 c- @" ^, Q+ V2 S
  194. /* Output:                                                                                                                                */
    ! k1 p2 H- w; s4 G0 f0 F
  195. /*                None                                                                                                                        */& r6 M; r5 D2 J' _1 t
  196. /************************************************************************/8 e6 m8 J! P* h& E
  197. unsigned char Get_Byte()
    : a' D0 ~3 O4 v7 @+ q! t% N! e
  198. {5 s: `+ T4 u* ]" e! s4 W
  199.         unsigned char i = 0, in = 0, temp = 0;
    ) r4 n4 n/ U. s0 J% @/ }* v) E: i
  200.         for (i = 0; i < 8; i++)
      E$ W( @; K% K  s% c
  201.         {2 S4 Q5 v9 ?# s( M  T( B! y: \. [
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */4 O! j4 @/ t( b3 t1 l# Y
  203.                 temp = SO;                        /* save input */' {+ v; {$ e  D5 N3 ]
  204.                 SCK = 1;                        /* toggle clock high */
    8 F& V. t" d' b6 J2 s6 p. r% U
  205.                 if (temp == 1)                        /* check to see if bit is high */
    / [) b' R+ P1 @2 E1 `$ q) f4 c
  206.                         in = in | 0x01;                /* if high, make bit high */
    ( F& o! K, I6 I4 k
  207. ( O9 y7 a+ @1 e
  208.                 SCK = 0;                        /* toggle clock low */6 A6 V5 }# k+ [' p5 w
  209. , e  X5 Q& j+ ]8 J! V4 T
  210.         }
    8 Z2 _& G- J8 _2 r5 @! O
  211.         return in;5 l- \8 U0 j5 v7 W/ I; N2 ]& n
  212. }
    ! z/ I0 t6 c. @$ f5 {/ I7 w9 ^

  213. 3 X; ?" s- |3 _5 [
  214. /************************************************************************/, b7 f, w/ z% ^3 u. r2 `  y' e3 N
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    5 G% m; U! Z% F6 i& P* U- K" S
  216. /*                                                                                                                                                */
    9 _' e8 k# m3 e/ M' u
  217. /* This procedure polls for the SO line during AAI programming                  */
    8 ~& X) A) }3 ?( q/ ?6 G/ @
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/. r& b1 r& X, E5 t
  219. /* is completed                                                                                                                        */
    1 g' F- b6 z. L: ?; W$ S: t
  220. /*                                                                                                                                                */, p9 @( k! _( d, l/ V
  221. /* Input:                                                                                                                                */
    ; ?# e9 s- x9 ~. _$ O1 o& i5 n- r
  222. /*                SO                                                                                                                                */
    # h1 O* G  m8 m: Y' l# v7 D
  223. /*                                                                                                                                                */
    1 @, i1 r5 _! m: c& b
  224. /* Output:                                                                                                                                */+ ]  ]5 @9 o+ k; V- ^
  225. /*                None                                                                                                                        *// B6 O* p" `' N; f5 [
  226. /************************************************************************/
    ; z; t. |1 C4 X2 ?! U2 n# }
  227. void Poll_SO()- M  s& c; w7 d& _
  228. {' [' p; ]* H) V% h2 Y2 r* C
  229.         unsigned char temp = 0;% q% Q$ d7 c9 Z0 }
  230.         CE_Low();2 U7 C% L' T6 o* x
  231.     while (temp == 0x00)        /* waste time until not busy */
    9 n# H1 J$ y6 n- S4 k9 m( P  c1 u5 b; \
  232.                 temp = SO;, u$ [0 ?# C0 q  Y" O: e0 {; g
  233.         CE_High();
    + G! _" H3 g7 R1 M- U
  234. }
    % }9 r- o5 x2 Q  Q# K0 C
  235. & I$ W. v. o) X% q! j, S$ l
  236. /************************************************************************/( V1 A6 z' @3 s8 W1 M6 T1 D
  237. /* PROCEDURE: CE_High                                                                                                        */) K0 ^9 b: v, O; ?* N
  238. /*                                                                                                                                                */
    : U5 [$ X! W( y) G1 k3 E
  239. /* This procedure set CE = High.                                                                                */
    ) \- C8 P( {% C. [$ D3 X
  240. /*                                                                                                                                                */# L) p% t% J. y/ k; \* l6 N' b9 ]
  241. /* Input:                                                                                                                                */7 w" ?& h. S; `# @) M
  242. /*                None                                                                                                                        */# A& q) V. i* d4 M
  243. /*                                                                                                                                                *// u1 S+ E! G2 M6 x; n- M
  244. /* Output:                                                                                                                                */
    8 I' G4 u# [% Y9 [& y
  245. /*                CE                                                                                                                                */
    ' t- u9 S/ j. k- I' R
  246. /*                                                                                                                                                */
    / }9 X. y" K& \. L0 l( [. H5 \
  247. /************************************************************************/- G: _$ r0 ]. B% j+ l7 V( I  O
  248. void CE_High()
    + B- v. y) v4 h% u7 q3 p
  249. {7 K- m9 h, B$ \! |2 c% d( X
  250.         CE = 1;                                /* set CE high */
    ' l8 d5 R4 }8 w$ I6 ^7 L; G! B  U8 E
  251. }
    & k4 s6 K" R3 p: ]% g
  252. 7 C; r) I9 U& ?* p
  253. /************************************************************************/
    : G4 H7 {# u! R# l
  254. /* PROCEDURE: CE_Low                                                                                                        */. s2 s8 f) d8 R+ F( _; m
  255. /*                                                                                                                                                */
    0 M6 D& T5 v" B" T' l0 F$ M
  256. /* This procedure drives the CE of the device to low.                                          */
    ! p$ ~2 X, n* ?( M6 m0 \
  257. /*                                                                                                                                                */) R* d; h" R' J$ i+ }
  258. /* Input:                                                                                                                                */. L" S$ V8 o. B( B1 |' o, e1 q
  259. /*                None                                                                                                                        */" t* b* m8 m0 ]8 W+ s# e+ _
  260. /*                                                                                                                                                */
    $ U+ X9 h+ G% |
  261. /* Output:                                                                                                                                */
    * x4 v0 I$ _$ k3 W
  262. /*                CE                                                                                                                                */
    % y; I1 k! P* u/ R3 T
  263. /*                                                                                                                                                */" O' m0 o8 w2 y  y
  264. /************************************************************************/
    & U1 s1 J/ u6 p  F. D" A8 B
  265. void CE_Low()
    # W; ?2 U9 ]& q2 e/ F4 _2 y
  266. {       
    6 S# l  I  M% N" i  T$ ?8 B
  267.         CE = 0;                                /* clear CE low */2 ?; ]! j% r4 R
  268. }. M# }: a8 M. m) M5 v
  269. : \  A) B' b) B+ a1 H  @# f
  270. /************************************************************************/$ }+ d$ `; S% p
  271. /* PROCEDURE: Hold()                                                                                                        */+ N9 q6 E. P5 E. f- D
  272. /*                                                                                                                                                */
    8 Z0 D  s% t, H, P6 s
  273. /* This procedure clears the Hold pin to low.                                                        */
    1 d1 U7 u/ }. m" R  z. g
  274. /*                                                                                                                                                */
    % A- s: O& T. `8 ?$ t3 P( ?
  275. /* Input:                                                                                                                                */2 o. U3 e7 W% j7 A* w
  276. /*                None                                                                                                                        */
    ! I3 p! `# }5 X" n+ I
  277. /*                                                                                                                                                */* r% q  R/ z$ z7 P  z. F
  278. /* Output:                                                                                                                                */' e5 X4 [' {# V! f: N& W" C5 M& w
  279. /*                Hold                                                                                                                        */: B2 Y. e* I& T& f* U. Z/ v
  280. /************************************************************************/
    ' v' h  C/ ?# L) p- m  J& X
  281. void Hold_Low()
    9 u9 g" l8 y% K$ }
  282. {' X8 z2 l5 t0 [" r$ Q9 b; [8 k! t
  283.         Hold = 0;                        /* clear Hold pin */* z+ T# L3 L& i" V3 ^! V
  284. }; Z7 c5 W/ L1 G  G  e
  285. 6 X" B% O2 i6 |6 ^" a% l  Y
  286. /************************************************************************/% q( d' @- x8 S8 Q. N' s' P/ Y5 k
  287. /* PROCEDURE: Unhold()                                                                                                        */% N' E; `3 Q" V6 A0 H# N- `
  288. /*                                                                                                                                                */, S9 L! s. Z7 b: Y+ Q
  289. /* This procedure sets the Hold pin to high.                                                        */
    / K4 b& m; U( p$ w
  290. /*                                                                                                                                                */
    ) }0 U" k+ [; T. D4 K
  291. /* Input:                                                                                                                                */1 C; u0 Z& E4 Y) s7 V
  292. /*                None                                                                                                                        */1 i4 r5 b6 [8 S; Y. i
  293. /*                                                                                                                                                */
    1 ^5 ^4 B  U4 [7 @; k
  294. /* Output:                                                                                                                                */8 [; D: ?" \) C4 [: f% s" Q
  295. /*                Hold                                                                                                                        */
    8 K( s# H! W9 t' b  r: e
  296. /************************************************************************/
    4 u% B$ |; }" [7 @
  297. void Unhold()- j* X0 ~, c4 M2 ]
  298. {" [8 D* M. Z; k+ Z5 H3 A, y* k
  299.         Hold = 1;                        /* set Hold pin */
    : f1 a1 y; Y3 s. W
  300. }$ U. J6 `8 B9 I1 @

  301. 1 N2 ?$ D7 @% ~( C
  302. /************************************************************************/
    1 z/ {0 T/ f; _. h0 K9 r: P
  303. /* PROCEDURE: WP()                                                                                                                */) a1 h5 ^, Q4 N, m
  304. /*                                                                                                                                                */$ I- ?2 u0 ?" H, P5 `7 T. W
  305. /* This procedure clears the WP pin to low.                                                                */
    6 i  P, w1 G* v; l4 e' l( V
  306. /*                                                                                                                                                */3 A! F! ?6 r1 w
  307. /* Input:                                                                                                                                */$ Z* x; \9 O  S  l
  308. /*                None                                                                                                                        */
    1 u, D! D6 B' }0 J
  309. /*                                                                                                                                                */4 `+ h# p8 |6 @, }& D) t8 `
  310. /* Output:                                                                                                                                */  \& T; Y5 h7 S
  311. /*                WP                                                                                                                                */- ^" x+ V; F& f0 C" j6 g
  312. /************************************************************************/9 q( ]) y" u7 _
  313. void WP_Low()
    7 m8 a5 Y- o: k
  314. {/ ]- Q- p+ M. a" A  L
  315.         WP = 0;                                /* clear WP pin */3 R  X0 ^9 j" `0 T2 e. R4 ?
  316. }
    . n6 U" E+ x+ J5 D; A$ H- z
  317. , `& c0 N1 O6 m' U1 {+ e1 g' C
  318. /************************************************************************/+ v+ {" y: m6 y1 k5 Z6 _# s
  319. /* PROCEDURE: UnWP()                                                                                                        */
    2 n4 `- D8 i. \( A
  320. /*                                                                                                                                                */
    . {; r" K5 z: O/ S) k
  321. /* This procedure sets the WP pin to high.                                                                */
    % l% G: Z3 |7 B2 N6 s+ e2 }
  322. /*                                                                                                                                                */
    , a( S4 v) Z0 ~
  323. /* Input:                                                                                                                                */4 n& H* E# D# e$ v. B; F! f' i
  324. /*                None                                                                                                                        */- N  A; v" h  n! d+ p  E
  325. /*                                                                                                                                                */
    9 ^# w; C+ ^1 }& D; u  P
  326. /* Output:                                                                                                                                */
    2 T# ~1 E+ v. G6 l3 E, `. ]: m% S
  327. /*                WP                                                                                                                                */1 j. g# y6 s3 T1 l6 c  I
  328. /************************************************************************/# J" U1 M. K8 B( \- Y
  329. void UnWP()
    : f2 \0 n& K  ^: ~6 `; u
  330. {7 q  b) x: n+ l
  331.         WP = 1;                                /* set WP pin */% A/ h( B% Q. V0 \
  332. }* G# a: I% ?  ]6 T  W

  333. 0 r  I4 h) m+ p% F
  334. /************************************************************************/
    % f7 C6 @  A2 t# `& Q
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    1 F/ i4 a% d( S6 {
  336. /*                                                                                                                                                */
    + o& S  R: S5 ^. _% A; H0 s
  337. /* This procedure read the status register and returns the byte.                */- ~5 N/ k0 M; l
  338. /*                                                                                                                                                */
    $ o3 i2 v7 H2 Z# Y
  339. /* Input:                                                                                                                                */* J& }8 J1 j% \& z1 a0 i+ ^
  340. /*                None                                                                                                                        */! k4 W* ?) q: v& v
  341. /*                                                                                                                                                */, O+ A: w$ y4 l* k0 x
  342. /* Returns:                                                                                                                                */
    8 b, H% Y8 \: H( {3 }
  343. /*                byte                                                                                                                        */) j2 t1 n0 s8 l1 n
  344. /************************************************************************/- m# h+ ]8 P1 y, u0 E. q/ I
  345. unsigned char Read_Status_Register()/ n5 w2 V1 f; z% |. b' t+ w0 D
  346. {
    3 v8 Q. u+ u9 T3 Y* K; a0 |& h
  347.         unsigned char byte = 0;
    8 w: U  D" ^% q/ `4 Y5 Z
  348.         CE_Low();                                /* enable device */! b& Y: v8 H! J+ x
  349.         Send_Byte(0x05);                /* send RDSR command */
    9 H4 p$ V" W8 f4 ?+ J+ X
  350.         byte = Get_Byte();                /* receive byte */( z" v  X1 u# w- P. \' i
  351.         CE_High();                                /* disable device */  M8 s9 x* L& B/ L" N! q5 G* [
  352.         return byte;- D$ o% T* p- @4 X! V" H
  353. }
    " [1 w% G+ d9 @$ W& |: Z/ F
  354. 0 E) u  l0 Q" T( J
  355. /************************************************************************/1 Z% b* O! h5 d" R
  356. /* PROCEDURE: EWSR                                                                                                                */
    ( \( P8 x( @; c& p
  357. /*                                                                                                                                                */% Y' S4 T0 N- L, n/ @' |* @+ G
  358. /* This procedure Enables Write Status Register.                                                  */
    & X2 |/ @5 w4 m3 M+ t+ ]
  359. /*                                                                                                                                                */1 a- T9 }. d" s- b7 V* U3 q
  360. /* Input:                                                                                                                                */
    $ H6 Q9 c, T# B1 t+ q( c3 ]  z
  361. /*                None                                                                                                                        */
    ) C8 }7 P- i$ P& f2 {
  362. /*                                                                                                                                                */4 H1 ?$ v' p+ q& l1 B; @
  363. /* Returns:                                                                                                                                */7 x; @9 D6 }) n8 J3 `8 n
  364. /*                Nothing                                                                                                                        */
    # t0 W4 C6 i7 l: Y/ h  R( \9 j
  365. /************************************************************************/
    % J+ t/ c; v6 q1 K6 P+ P" P# o% \8 P
  366. void EWSR()
    # t! [. f( I7 d0 P  @  r
  367. {
    - f( K3 f( ]8 s& ~2 f9 O: \8 x4 H
  368.         CE_Low();                                /* enable device */
    - d3 M* @/ N, }# j8 }$ T
  369.         Send_Byte(0x50);                /* enable writing to the status register */5 u# }8 n) f9 R5 e7 N. m
  370.         CE_High();                                /* disable device */
    & f' ~* d8 j0 j3 @5 p2 z
  371. }
    / p, V% b" E. _/ h! @
  372.   n; F9 Z& {& U# f; W% o
  373. /************************************************************************/* {( q# K4 c7 u1 t- \
  374. /* PROCEDURE: WRSR                                                                                                                */: |; ]: m2 w  y1 i* s1 O9 M
  375. /*                                                                                                                                                */
    . k# ~' K6 L# _9 l6 |' M) x
  376. /* This procedure writes a byte to the Status Register.                                        */
    $ b6 V$ F6 c- K* W2 b
  377. /*                                                                                                                                                */5 x* ?+ O8 l3 ]4 V
  378. /* Input:                                                                                                                                */
      i7 u) z! q% g4 }7 g
  379. /*                byte                                                                                                                        */
      p. ?1 ~9 v% T+ s2 A8 u
  380. /*                                                                                                                                                */: V! o) E# C& S- f
  381. /* Returns:                                                                                                                                */
    " H5 v+ L) Q$ {" ^/ t1 |0 W
  382. /*                Nothing                                                                                                                        */) X: m' t6 w) X8 w5 T- \
  383. /************************************************************************/7 {# l9 F& U: r7 z0 E
  384. void WRSR(byte)  {% \. y) \& S$ Z' e& ~& F
  385. {! L( R5 Z) s/ d) z8 H; J
  386.         CE_Low();                                /* enable device */! b. [5 K/ B7 ?
  387.         Send_Byte(0x01);                /* select write to status register */" T& D% I% p4 i  Y
  388.         Send_Byte(byte);                /* data that will change the status of BPx : n  O. X" C1 _9 h: T& P7 t
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */: D  K6 _/ }' }6 _# p  n
  390.         CE_High();                                /* disable the device */1 R& ]& y; G) V1 p3 Q
  391. }  l) V8 i9 D$ R6 f: [. R( x1 a% o
  392. ! Y6 N) d' x2 T! O. x* ^5 u
  393. /************************************************************************/
    9 D% u' n& T- f0 s& [6 u3 H
  394. /* PROCEDURE: WREN                                                                                                                */- g. f2 }" Q. [2 e" F  D+ T
  395. /*                                                                                                                                                */
    1 f" r, w  b" Z1 ^5 S2 O" p
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */* g9 J3 {% X" M, m' U
  397. /* to Enables Write Status Register.                                                                        */, _3 a, Q6 t7 C( @1 N$ C  D2 P4 z; Q# g7 E
  398. /*                                                                                                                                                */% y  {6 ^1 b9 ~; o7 F9 A8 w
  399. /* Input:                                                                                                                                */$ _" ]0 V" d8 Z
  400. /*                None                                                                                                                        */
    5 Z+ l& k6 f* P9 }
  401. /*                                                                                                                                                */
    % ~2 w: J0 J7 q/ q3 J! d6 z+ Z
  402. /* Returns:                                                                                                                                */2 j6 I4 {' y' @2 p8 Y5 ]8 f
  403. /*                Nothing                                                                                                                        */
    8 Y' e' c) ?# s& a( G+ Z
  404. /************************************************************************// j+ Y2 o; V0 L" W7 |4 i: q
  405. void WREN()( w4 r2 Y7 a- v. Y9 Y( T
  406. {1 z- n) a3 O; L+ G/ @7 ?: T: p' C2 v
  407.         CE_Low();                                /* enable device */
    * `) |  g% ]' e% L
  408.         Send_Byte(0x06);                /* send WREN command */. m6 W/ L: ?- N7 x( I) ^
  409.         CE_High();                                /* disable device */+ r4 T; i& G9 K4 k- [9 c' P
  410. }
    ' n2 Q$ O! P2 @5 R

  411. 7 @5 N" Q" n1 l6 h. U
  412. /************************************************************************/0 A$ I& ~+ H  p# k
  413. /* PROCEDURE: WRDI                                                                                                                */
    # |; S( ?% X: S- T6 W
  414. /*                                                                                                                                                */
    , A6 N* G4 @) i0 s5 w
  415. /* This procedure disables the Write Enable Latch.                                                */
    / c9 p4 ?. n1 S) B  T, [) B
  416. /*                                                                                                                                                */
    0 F- G% u0 _2 M4 D
  417. /* Input:                                                                                                                                */$ k6 @# q1 I5 u
  418. /*                None                                                                                                                        */4 S9 U; p1 X+ ?  q) M& c# K! _$ N2 ?
  419. /*                                                                                                                                                */
    , k, J. ^0 P1 k/ h+ ]
  420. /* Returns:                                                                                                                                */
    + L& I, y$ R# _. ]
  421. /*                Nothing                                                                                                                        */5 z* W- b0 k8 q$ o# @
  422. /************************************************************************/% D% R5 |/ `2 M# g
  423. void WRDI()" F' ]% r* v) f0 s. w  c
  424. {
    " q, H, a( x! U/ o8 w' j9 W
  425.         CE_Low();                                /* enable device */( w8 M, P  K7 k9 n+ `$ D2 d
  426.         Send_Byte(0x04);                /* send WRDI command */
    * V. O; o$ J/ O5 e2 H* a; a
  427.         CE_High();                                /* disable device */. D2 n8 \5 y4 T5 E* m8 T
  428. }
    % S; z( _3 Q( m' Q: Z, A6 w( ?
  429. 4 {2 ~1 G, A4 {
  430. /************************************************************************/6 w' C% z7 B- O; t/ z0 Z
  431. /* PROCEDURE: EBSY                                                                                                                */
    8 h" l' f  K2 D: D- m2 T0 c
  432. /*                                                                                                                                                */
    - _0 X$ S: J3 X; K6 [2 G. R9 H' @
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    : D( g6 e! Q* N0 K* q7 g+ m
  434. /* programming.                                                                                                                        */0 r! R' z4 i9 P, n, f$ N
  435. /*                                                                                                                                                */
    % }% ]! q; C: c
  436. /* Input:                                                                                                                                */
    " [: E  w/ p; V4 ~9 _9 k
  437. /*                None                                                                                                                        */
    ; Y8 v! p7 u! T  a
  438. /*                                                                                                                                                */
    # g4 l+ ^5 O8 Y- }
  439. /* Returns:                                                                                                                                */
    % a1 E0 I7 m* f8 P
  440. /*                Nothing                                                                                                                        */
    2 }$ T3 w+ B! S- b3 @/ I
  441. /************************************************************************/; i0 X% |2 m/ o9 P6 r3 E3 A3 F2 k0 m
  442. void EBSY()
    5 z* W8 g% [0 r& K7 m
  443. {$ X3 `+ m$ w2 Q, P; B
  444.         CE_Low();                                /* enable device */
    5 r) j0 g  {7 b; E
  445.         Send_Byte(0x70);                /* send EBSY command */
    # M2 \# q. R- ^: Q$ I; P9 w
  446.         CE_High();                                /* disable device */
    3 v! u: l8 c; Z) s0 L
  447. }
    ; Q' }! P: A5 c$ u. y) L
  448. % K: m8 R0 |6 P3 _* L/ j8 |2 v- e
  449. /************************************************************************/8 e! d( V) E# ], h
  450. /* PROCEDURE: DBSY                                                                                                                */0 {# N) T; j) P! K- i
  451. /*                                                                                                                                                */- q7 j& q1 n% Y. p$ U
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    + H- u* `; w7 E$ ?6 l
  453. /* programming.                                                                                                                        */
    - }5 A) V' `- n4 ~* V* |
  454. /*                                                                                                                                                */- L3 a4 {; E" ~# W
  455. /* Input:                                                                                                                                */
    " S( ^8 E9 L$ m& B$ M7 ]% r% u  [0 ?
  456. /*                None                                                                                                                        */
    4 c) @6 ^; K, v+ ~. }3 R% a1 k
  457. /*                                                                                                                                                */; M7 H) z- X) G4 L5 x; B/ v
  458. /* Returns:                                                                                                                                */
    . a3 A& r" V/ o% D/ q9 q
  459. /*                Nothing                                                                                                                        */
    0 Q, x" X+ p+ o
  460. /************************************************************************/6 K9 J- L  C. D: D9 k
  461. void DBSY()
    - Y3 E6 W1 j$ E5 p
  462. {# c* M' p' b" v- c  ^6 N3 D. w
  463.         CE_Low();                                /* enable device */& D* q; I# m8 t6 Q; j
  464.         Send_Byte(0x80);                /* send DBSY command */- R' ]3 m8 Q+ d$ Z' B/ W! Y0 V
  465.         CE_High();                                /* disable device */
    , Q1 u8 x2 D6 i2 }( |5 O9 }& o( ?
  466. }0 j9 D9 s( |: Q, c; E! x

  467. " k* L; J% H1 I8 |
  468. /************************************************************************/0 J5 n7 J! J4 a$ `, S4 ^
  469. /* PROCEDURE: Read_ID                                                                                                        */$ @1 {, y; b. {
  470. /*                                                                                                                                                */, D7 y0 s: \8 ~
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    - U1 i  T  A+ S% x- X! x+ v7 U
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */, o: h- k$ ~4 p
  473. /* It is up to the user to give the last byte ID_addr to determine      */
      a  Q* q. S, W2 y7 D
  474. /* whether the device outputs manufacturer's ID first, or device ID         */6 |) C' [- Y8 H! j7 H& C- |, q
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    " {, G- u$ n% i4 M  u, K+ z
  476. /* variable byte.                                                                                                                */
    + N* a' Z; ~. e7 N4 J9 ^
  477. /*                                                                                                                                                */- h4 F2 B7 g+ `
  478. /* Input:                                                                                                                                */
    1 V1 G5 N+ T" p+ M
  479. /*                ID_addr                                                                                                                        */
    . @7 k: H, \3 g, V( Z; p& l4 O
  480. /*                                                                                                                                                */
    : s" r, y3 F0 Y8 {2 O
  481. /* Returns:                                                                                                                                */
    & T6 s: B4 b+ M# S6 p% e& j
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    " c, R" P8 N: {- A, J1 ~
  483. /*                                                                                                                                                */
    ; P5 j9 Y' Q3 ]4 S: ~
  484. /************************************************************************/' E& }9 j) j. j& o& k6 d( r
  485. unsigned char Read_ID(ID_addr)
    ; v2 ]8 I4 C$ [+ y0 H
  486. {- [2 f* t1 Q: s, y$ ~
  487.         unsigned char byte;
    % H& I* C5 t+ |4 a$ u
  488.         CE_Low();                                /* enable device */
    2 r- r4 @, m/ J# k; C" F# b- V* ?
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    6 ^* b/ J+ V  V
  490.     Send_Byte(0x00);                /* send address */
    9 r' q, s4 `6 ?3 @
  491.         Send_Byte(0x00);                /* send address */
    " N, x5 k+ r! J6 `
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */# V& S7 A& r8 L2 e
  493.         byte = Get_Byte();                /* receive byte */
    , c) k; P/ C# u9 w! D) M
  494.         CE_High();                                /* disable device */
    4 w, d# u( X  e% |
  495.         return byte;- k4 h) L' {$ I/ i4 F* t3 {
  496. }
    : K7 i1 L. }5 R" Y6 Y: r& z
  497. * I9 W8 S+ d: g# |1 m& ]
  498. /************************************************************************/; x( t$ l1 a- o" t/ K' N! A
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */* S8 p) ~9 K6 m9 ~( K0 C6 J# P9 X
  500. /*                                                                                                                                                */0 q8 f: b. F8 h$ M5 O
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */6 `4 H9 j3 V; [7 Y
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */- Q5 n2 P0 u3 Q$ U; E+ h! a: _
  503. /* Please see the product datasheet for details.                                                  */0 F+ o0 H. b- w
  504. /*                                                                                                                                                */7 o) \- R1 \- C; F3 l; P
  505. /* Input:                                                                                                                                */1 u5 h6 C! s0 B5 a, r  P8 ~3 v
  506. /*                None                                                                                                                        */, n1 Y8 ^* m6 ~2 O6 M
  507. /*                                                                                                                                                */" f* j5 ?: W  u9 a
  508. /* Returns:                                                                                                                                */. ?2 t& J/ }; o1 V; P. O: u3 o9 X
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    7 m# I2 D$ v8 K7 c" O% c+ n
  510. /*                 and Device ID (8Eh)                                                                                        */
    . \8 ?' j: \- Z: ?$ P
  511. /*                                                                                                                                                */
    7 P7 ~, F" k1 I
  512. /************************************************************************/( c5 ?. v& o" ^  o2 w; x8 u- u
  513. unsigned long Jedec_ID_Read() 7 D, B; C5 `. [. a  V
  514. {% c* g2 i( S- [9 S/ d& C7 d' K
  515.         unsigned long temp;
    8 t- R: U* I$ z+ n& B6 s# V9 @$ t
  516.         " J+ @2 z5 ~7 J) r1 F" \
  517.         temp = 0;
    ; Z! u  H) ?8 F6 G" q

  518. 6 t1 O9 g8 n5 ], Q$ G  Z% \
  519.         CE_Low();                                        /* enable device */- X; }/ Y4 {5 ?" D
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */$ X* {* j  s; k/ _; J
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */) f$ o/ |# \3 f6 O: S
  522.         temp = (temp | Get_Byte()) << 8;       
    ' V1 l& Y% w/ \% j- r+ `8 n, |) T
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
      x& `6 z  J1 ~8 r: H
  524.         CE_High();                                                        /* disable device */
    # m( ~2 n( G2 c3 F' u
  525. ' T8 G$ C7 f$ B4 \& E
  526.         return temp;
    ; p4 [. D# B* l3 B4 n: b
  527. }7 o/ w! R* J- [, V. {& h6 n: \
  528. 7 K/ g/ S( o1 t- b  F% W8 ~- q3 a
  529. /************************************************************************/# G/ L# N1 N3 \3 u" j7 c) [
  530. /* PROCEDURE:        Read                                                                                                        */5 a7 i5 U/ j$ t; H" e5 r8 W( v& F# d8 ^& ~
  531. /*                                                                                                                                                */               
    ( K9 u" F7 T: }
  532. /* This procedure reads one address of the device.  It will return the         */1 `" j' \9 ^9 V# l1 c& z
  533. /* byte read in variable byte.                                                                                        */
    6 Y: u* U* S- i- E
  534. /*                                                                                                                                                */0 O1 g3 u6 x3 h0 T0 I" S
  535. /*                                                                                                                                                */
    1 b2 h3 m. U9 J$ y* }+ ^" p
  536. /*                                                                                                                                                */
    # c0 Z2 g7 P3 k
  537. /* Input:                                                                                                                                */: r/ w$ B; V# P( G- I7 x
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */1 D$ t: v3 ?$ R: _
  539. /*                                                                                                                                      */2 W- n* U( F/ x1 r4 d
  540. /*                                                                                                                                                */6 N7 ?5 D1 }( J3 C2 M
  541. /* Returns:                                                                                                                                */
    ! D% H6 J) Y" Q& m2 T
  542. /*                byte                                                                                                                        */, x' }5 I4 A3 ?' O  f5 W; E# L8 m6 o
  543. /*                                                                                                                                                */
    - B1 l4 w% i; \2 s' |; f* F
  544. /************************************************************************/
    ! d) q$ l- U) R/ Y+ d/ S+ i
  545. unsigned char Read(unsigned long Dst)
    * b1 D. {* N: q" p' |1 }1 o
  546. {
    7 P$ Q0 l. C: `7 d, T
  547.         unsigned char byte = 0;        & V7 _- u3 X3 p0 E- D
  548. 8 B/ H* ]. R6 ?
  549.         CE_Low();                                /* enable device */
    7 w' H9 k" k+ A1 |5 T- f
  550.         Send_Byte(0x03);                 /* read command */1 R- f+ x  D: d( a1 }9 {: Z
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */: N) n7 m- `9 y3 ]) B& Y, H# K
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' c$ f, E1 P6 p. Z3 b3 g
  553.         Send_Byte(Dst & 0xFF);7 N6 F- P0 r# J! \# @
  554.         byte = Get_Byte();
    " w1 ?8 ~  j( U1 F: B
  555.         CE_High();                                /* disable device */
    3 ]- t/ Y$ L: Z5 a6 p3 A
  556.         return byte;                        /* return one byte read */" B& [3 X5 U, a  v! {
  557. }# e8 K; P, z5 m  y- Z+ _% x+ ~

  558. 1 F& {- n: V3 l8 J- ?7 r1 W# P5 q0 w
  559. /************************************************************************/
    ' c7 x: T/ p# I) a
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    : ~: \: H  }1 K- f+ k
  561. /*                                                                                                                                                */                - u; B" L/ P/ h8 k
  562. /* This procedure reads multiple addresses of the device and stores                */
    1 o5 ~6 i2 q/ {
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    : n$ K0 b2 Q+ z+ w" P
  564. /*                                                                                                                                                */
    9 l' x# _0 c% t
  565. /* Input:                                                                                                                                */" h0 n1 T3 ^9 Q3 e; b, {5 J
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */7 j# _; o& i9 Q; i0 H! y5 ?
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */  m$ o% }8 r8 G- Y4 P" u
  568. /*                                                                                                                                                */( m3 {* j% x6 b
  569. /* Returns:                                                                                                                                */$ y( N. l  I. x: o3 k
  570. /*                Nothing                                                                                                                        */
    / c$ ^5 M% o& Z
  571. /*                                                                                                                                                */
    * U- `& {) ]1 a; A- F  [
  572. /************************************************************************/( i8 X' P) \" \0 \3 {8 v
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)- y! k* Y" n% M' `: w0 Q! j  l
  574. {
    # b/ Y1 R9 w3 b/ O+ |, w) M
  575.         unsigned long i = 0;
    $ F7 z: N7 f1 Y
  576.         CE_Low();                                        /* enable device */
    3 ~# v1 A  C) ]. B
  577.         Send_Byte(0x03);                         /* read command */; p, y% g0 d7 F: Y7 O
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % L! i) i- A& e: Y  }' X" f
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; D& |6 r0 Z. N
  580.         Send_Byte(Dst & 0xFF);
    . E$ k0 V( V/ O. e& f( P
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */# V4 {! V, ~0 x, B8 g* b
  582.         {
    / Y$ _5 t  D5 B5 g% _- C
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    , A8 i3 v1 z$ @, K+ L
  584.         }+ O5 e- W% }$ D& P8 n
  585.         CE_High();                                        /* disable device */
    0 O6 l+ d/ u' D# Q- x, G
  586. 0 A; t9 _- E" X8 c
  587. }3 a/ Q) Z9 M5 J/ g$ U% b

  588. 5 T2 |3 l/ |+ g0 c# d
  589. /************************************************************************/
      }' G  D' Z% U" {: s& F  C
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    0 a, H, v% Y5 U
  591. /*                                                                                                                                                */               
    2 E. E. ]  K( h0 G, I4 z
  592. /* This procedure reads one address of the device.  It will return the         */1 Y; \( ]& g) _) p; ~: o
  593. /* byte read in variable byte.                                                                                        */1 o9 |5 h9 _* g) M5 S4 c6 r# x) W8 J, o
  594. /*                                                                                                                                                */6 u; s) X. D, x6 k
  595. /*                                                                                                                                                */$ @/ T# w/ i2 }5 j
  596. /*                                                                                                                                                */
    / m' N9 ?% M" l( G6 w# S
  597. /* Input:                                                                                                                                */. F# _# g! g  p) z: }* e( |
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ; M* H4 I2 @  T! w2 f& P* W) C$ x& \
  599. /*                                                                                                                                      */
    ; q3 q1 u: I+ k
  600. /*                                                                                                                                                */
    9 j5 d  t6 X2 x- p. \
  601. /* Returns:                                                                                                                                */  J1 w( Z' S( \% G  |1 g; u
  602. /*                byte                                                                                                                        */
    5 L* G1 O8 t1 o1 P
  603. /*                                                                                                                                                */) K: P: }$ u( q, {  ?& b) F- H
  604. /************************************************************************/
    + D9 Q; Q$ e2 O# M; p7 {* D4 I( Z
  605. unsigned char HighSpeed_Read(unsigned long Dst) % f- b6 _$ e$ u0 ~# h4 A
  606. {  J8 l6 t  G- T9 U# O4 I/ i
  607.         unsigned char byte = 0;       
    . X+ H& s9 F" ^' Y- O. E

  608. # P9 f7 n# E* z# ]% i: o  Y
  609.         CE_Low();                                /* enable device */
    : K* K" v! {. W) d. c4 s2 s
  610.         Send_Byte(0x0B);                 /* read command */# m, m- c% }/ g. D
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */, k/ [6 ^/ q' k! r- t
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & h' K6 o# F- @) Q
  613.         Send_Byte(Dst & 0xFF);$ R" J8 W# d: g3 i4 e& r
  614.         Send_Byte(0xFF);                /*dummy byte*/  x4 t7 a) g, G5 b
  615.         byte = Get_Byte();
    : O0 u/ h8 s; `4 a5 c- ?
  616.         CE_High();                                /* disable device */
    + ~! Z+ x# d4 q  B0 Y6 ?6 S
  617.         return byte;                        /* return one byte read */* M& q; E& G' W0 c; P
  618. }
    # ^9 c$ k7 [, C" s
  619. - [' P) j! r1 O' H9 t4 e
  620. /************************************************************************/
    & f3 {$ v, d% @( T3 g
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    8 k; i# J6 A( ~7 o
  622. /*                                                                                                                                                */                  z% f. O1 _2 D; S0 t! W$ ?
  623. /* This procedure reads multiple addresses of the device and stores                */
    $ H, J& }% J4 [6 F# l3 C1 g
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    , P* `! ~& r% }; C5 v& A
  625. /*                                                                                                                                                */
    : }2 ?% f# L; _* W4 {6 E/ ^/ d0 @: H
  626. /* Input:                                                                                                                                */
    * s4 M( O% i. v; B( }6 U9 ]0 f
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ; C  p+ k" V+ w: h, ]! M
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */* ]3 N0 g1 S8 C2 z
  629. /*                                                                                                                                                */) \4 W. R4 E2 t% {
  630. /* Returns:                                                                                                                                */! G  N$ V) F: @7 J1 X3 s! u  x+ ~
  631. /*                Nothing                                                                                                                        */
    & s' C/ O4 |8 a9 c0 e1 C
  632. /*                                                                                                                                                */" I7 y4 @0 Q" K* [+ E' ~! a
  633. /************************************************************************/' F0 X. g( X) I, _1 Z* s
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes): y! J0 q2 G" T9 X; h$ j8 q  |" t
  635. {
    0 c5 e% A, X( I+ |2 P  g1 O( Z' W" e
  636.         unsigned long i = 0;: u( _, V9 e6 M! v
  637.         CE_Low();                                        /* enable device */4 R+ I9 Z4 R9 i6 v' R
  638.         Send_Byte(0x0B);                         /* read command */5 U" H; h2 N- Y* o% n8 k' A
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 G9 T9 C4 z: p$ {; \
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));9 H5 `2 t4 [. m  d( M! Z& n; M
  641.         Send_Byte(Dst & 0xFF);2 d" y8 `" O9 C$ Z* q
  642.         Send_Byte(0xFF);                        /*dummy byte*/% [  Y  Y+ Y" Y* b
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    + }5 Y  C! i% m( E
  644.         {
    ) o) I5 w# A/ P2 r7 g3 h2 r1 @
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    8 I! n4 T; D9 G( f1 K; }
  646.         }
    2 M7 H* O( m* @
  647.         CE_High();                                /* disable device */$ h( }3 k' A: z
  648. }
    - y! }# L1 |( z, `+ F. p* k

  649. * k+ [, W7 i% J1 Q$ d
  650. /************************************************************************/  X3 C6 B2 t: u; Z- k1 v) E
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    ! u; s9 @, y2 j2 B
  652. /*                                                                                                                                                */
    % p+ J4 _+ T) O0 X/ h4 c4 W: i
  653. /* This procedure programs one address of the device.                                        */  |, M& e0 L' d
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    - f5 S/ e" a8 t% W% I9 `% R
  655. /* block protected.                                                                                                                */( f( A8 P, t  y, @+ r# e
  656. /*                                                                                                                                                */
      s% T  [# [7 ?. T7 f% q" x# ?
  657. /*                                                                                                                                                */! Z2 a/ z9 J/ X) L4 I
  658. /*                                                                                                                                                */
    7 \. {- |1 B3 l( Z; K
  659. /* Input:                                                                                                                                */
    5 e$ o4 ~0 _$ q5 U: X2 _9 M5 u
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & a9 m4 _7 q9 ?7 ]  g! s
  661. /*                byte:                byte to be programmed                                                                */, G* m$ w% h% q/ |
  662. /*                                                                                                                                      */
    1 y% z8 b. w$ `9 X' [1 N, X
  663. /*                                                                                                                                                */) V- u# d+ ?0 {# L. F( l; S
  664. /* Returns:                                                                                                                                */
    $ v6 K5 f. n( k) A1 n/ _% D
  665. /*                Nothing                                                                                                                        */
    / E! r& D+ S  x( R/ B: P% K* j
  666. /*                                                                                                                                                */
    " s' a8 l1 _, x% W. U3 _. Z/ o/ K
  667. /************************************************************************/3 d  d% q, ^2 P9 |& `- I
  668. void Byte_Program(unsigned long Dst, unsigned char byte)- y/ F1 I! f. d( L
  669. {+ z1 k. U% J/ v) M9 ~5 `( ?: V
  670.         CE_Low();                                        /* enable device */, M, l+ w2 o, [( G+ v1 N
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    0 @2 Z2 I$ Q+ X0 g+ @
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    3 r- ]  ?& a+ V. X. V0 F, q7 a
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 \- \) ^; u# F3 |, v* ^- E
  674.         Send_Byte(Dst & 0xFF);: N- w, g. S& Z8 u
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    7 W& u  E0 |% K
  676.         CE_High();                                        /* disable device */( h# C6 u4 h. \* p, |& C) F
  677. }) V7 T( h9 @7 r. ^0 P
  678. ( c5 I( J. h5 g7 ^% i' V% [
  679. /************************************************************************/
    3 [( q& Q* j  ]( D
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */2 A7 n/ f' i/ R  V$ ~8 f
  681. /*                                                                                                                                                *// O% l( u, k8 M7 {( ^5 C5 u5 b
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    1 B2 G' W8 _0 C1 [+ B
  683. /* the device:  1st data byte will be programmed into the initial                 */
    $ `8 `5 Y" C; Z' ^1 V
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    4 r+ d) Y$ M! n6 T( @$ s' o
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    7 H8 t2 T0 y3 C2 B6 I
  686. /* is used to to start the AAI process.  It should be followed by                 */1 N/ @' _6 r1 T5 x5 E) n, b' H0 z
  687. /* Auto_Add_IncB.                                                                                                                */
    . Z3 w2 P: Z1 A( I1 {* _
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    7 p4 @! Y' h% T9 t
  689. /*                                block protected.                                                                                */
    7 O+ {0 n+ o$ z" R% W
  690. /*                                                                                                                                                */
    3 S6 D% ?/ n+ I8 S, ?
  691. /*                                                                                                                                                *// Q' ~$ x# E  P$ r
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    * ^& Z6 y3 |2 n; |9 `; Z
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */! E: V, e" p& `
  694. /*         unless AAI is programming the last address or last address of                */0 z) h0 P; c2 t  f( M0 W
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    / e0 ^6 l9 B; A! m
  696. /*                                                                                                                                                */* N: o4 i; t) |8 Y$ J7 u# L; ~$ \; s
  697. /* Input:                                                                                                                                */
    3 q; l2 R- I6 S1 V; z# T
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 p. O+ F3 L8 J$ q
  699. /*                byte1:                1st byte to be programmed                                                        */
    9 ^# B2 O4 l8 w: g1 i( s
  700. /*      byte1:                2nd byte to be programmed                                                        */# z* r  s( f) ]. p6 _( f- p
  701. /*                                                                                                                                                */
    & l% `( v$ o: D  F
  702. /* Returns:                                                                                                                                */) J' y9 {; A& G, k
  703. /*                Nothing                                                                                                                        */: d2 j) _; F9 _0 k, _1 L& a
  704. /*                                                                                                                                                */3 H; T" D$ T# W- G; q3 x
  705. /************************************************************************/) O6 ]5 [) d! c9 G
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2), Z' r8 ]. L5 ]9 \
  707. {* O: x5 {, `( Y7 K% \$ }
  708.         CE_Low();                                        /* enable device */
    7 a7 l5 W, k/ H. c* d4 ~, T. ~
  709.         Send_Byte(0xAD);                        /* send AAI command */& I% R/ [2 C' x) l
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( ^' ~- L3 V3 h% r
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 q/ I! p1 i: Y! v# O0 K- I
  712.         Send_Byte(Dst & 0xFF);
    0 v5 I, m& m7 g
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    % n( }) j1 g2 R" |+ q- }( X5 ?5 o
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */8 i7 z8 V0 v6 F5 N$ n  w: J
  715.         CE_High();                                        /* disable device */
    + b1 }+ r8 i9 Y2 R
  716. }: E, P0 c, J2 k" t% J, W0 L

  717. - V  Q/ V; y: \0 e. Z" r
  718. /************************************************************************/% U- i6 ~, x5 x9 R9 N7 o$ Z1 Z# O
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ) C2 \/ T% I1 U+ }! _$ n- S
  720. /*                                                                                                                                                */
    8 k, C1 Z5 d9 c6 {* v0 }' g' V
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/4 V8 L, ]; q' f) L+ r
  722. /* the device:  1st data byte will be programmed into the initial                 */- C- m# Y7 n- h) z7 O) e5 n
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    % K, J3 e; I' z
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    1 X0 l+ a# d1 R9 F% @# ]
  725. /* is used after Auto_Address_IncA.                                                                                */: [: g  r6 w! q0 H
  726. /* Assumption:  Address being programmed is already erased and is NOT        */5 C, V" N2 c  h9 ^" Z. k& G
  727. /*                                block protected.                                                                                */- u/ q) Z! A, ^0 D5 C0 o
  728. /*                                                                                                                                                */
    : X1 ^" y& q3 r/ Z7 p9 N* B
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */, i2 h% C2 T0 e* S! q
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */  }4 g  ?* I1 H; x
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    0 {# O) q& J' ^4 o1 U/ G
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    0 ^% y4 z1 k$ B9 X7 H- Q
  733. /*         last address of unprotected block, which automatically exits                 */, ]6 A9 A8 |0 _  L7 J  T" ?
  734. /*         AAI mode.                                                                                                                        */* t% \, |) B: D% G$ Y
  735. /*                                                                                                                                                */5 x& f6 Q$ y$ E! ]1 m8 \; f" G
  736. /* Input:                                                                                                                                */
      |9 g; M: \) [9 R+ m* _9 [* }
  737. /*                                                                                                                                                */4 C$ ^( a1 `1 V8 E4 _2 P
  738. /*                byte1:                1st byte to be programmed                                                        */
    : j& u$ T# K6 `* p- z. r: x
  739. /*                byte2:                2nd byte to be programmed                                                        */0 \0 @1 i, f4 `8 [. B0 ]. ]# q6 E
  740. /*                                                                                                                                      */
    , b! n8 ^4 u: f0 @
  741. /*                                                                                                                                                */+ J( ~- d; G' u4 d& Q
  742. /* Returns:                                                                                                                                */
    ; F* {( v$ p! d  n; B
  743. /*                Nothing                                                                                                                        */7 t' x- t% ]" `; p; G* K
  744. /*                                                                                                                                                */
      a% M9 h" B/ y/ n; t
  745. /************************************************************************/
    . o, `5 Q* f" ^* `0 R8 r4 K& H$ o
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)+ {( t; i$ D, z0 l+ V% A2 N" B! r# T
  747. {3 v1 i, E- j7 \; t8 u0 o. P
  748.         CE_Low();                                        /* enable device */, d% m) T: W4 U
  749.         Send_Byte(0xAD);                        /* send AAI command */
    8 e7 y( M- O7 I- d
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */, \0 y  Q# b+ j
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed *// p. d0 O# ]( W* S5 W* K( K* n
  752.         CE_High();                                        /* disable device */& R3 I% Q9 B7 `1 \8 Q2 s$ [
  753. }) d. V+ L1 \1 C* o1 M5 r8 Q* a

  754. 2 V5 L9 K/ `# E; n2 L" v! E
  755. /************************************************************************/
    ) i+ R% @) A2 h
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    5 j" z, R' R3 n" ]% d3 r
  757. /*                                                                                                                                                */+ V/ a: M! o" C( H$ n0 n1 q
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    ; f" s* N6 v3 s% ?5 D9 t" f
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    : H* v; X& i! |6 c
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */" W) W9 p( q3 n% |% i
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */2 r* d3 w/ z4 p* T# p/ h& S
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */% q6 N' V0 j2 Y5 f
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    5 R$ O5 b8 z2 h4 b5 G
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    : k# P$ }- i* F+ Q
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 P# P6 T4 k! P: t) C2 J, r
  766. /*                                block protected.                                                                                */& a- ?! A8 s3 M( |1 M- p% y6 ]
  767. /*                                                                                                                                                */
    0 Y3 g* W$ n8 {, e- Q
  768. /*                                                                                                                                                */
    0 w- b% j0 G7 ~, {1 n
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */* @. u7 t  @+ j" M5 J  K
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */" E! x5 Z! t' k, @/ c
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    . M) J9 V% ]% y" i
  772. /*          to exit AAI mode unless AAI is programming the last address or                *// ]7 g) c, P5 a( j* g# r
  773. /*         last address of unprotected block, which automatically exits                 */* D0 q6 i: ~" ?/ L; l7 E
  774. /*         AAI mode.                                                                                                                        */
    1 q5 b0 E. M1 z8 c6 O$ u% |; N, R
  775. /*                                                                                                                                                */
    & d: e. l1 I8 p+ e9 L0 k6 w
  776. /* Input:                                                                                                                                */2 f( Z9 A( F# F2 `
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// C. _, ?8 z( ]% O
  778. /*                byte1:                1st byte to be programmed                                                        */
    ( N+ S1 R' B  S+ n
  779. /*      byte1:                2nd byte to be programmed                                                        */" ^4 n1 g' G% o* \
  780. /*                                                                                                                                                */
    ; m# t& e' g& F6 M7 E3 _
  781. /* Returns:                                                                                                                                */
    / Y3 N' V1 L7 Q8 z- _3 V
  782. /*                Nothing                                                                                                                        */; x4 @# i# z9 V! f+ g' p
  783. /*                                                                                                                                                */% m+ h* N  R; n3 s
  784. /************************************************************************/
    3 h% F8 C- ]$ \" p- t8 ?
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)2 m- t& @3 A( G& D& |
  786. {3 e- L1 V5 v# O% `
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    6 s0 f0 M8 q& w* c4 K- j! X

  788. ; ]6 _+ F. ], o. r) N
  789.         CE_Low();                                        /* enable device */
    3 Z( c# i8 ^* f; V! Q/ Z  R
  790.         Send_Byte(0xAD);                        /* send AAI command */
    , U4 Q# {& e1 N9 x+ E. F
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */6 B. ?  F! y. g1 ?8 L
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));, N5 j9 G6 H. e. u# R/ k8 d2 F
  793.         Send_Byte(Dst & 0xFF);+ N7 H3 q. O) e: D
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    2 t) x; I( @( [( Y2 r! ?. b6 w
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    0 n/ p& \, N. M. I
  796.         CE_High();                                        /* disable device */. P3 V% J0 H% u& m" Q' e
  797.         % H) {) ~6 c; r9 i
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */* g5 ^6 y1 O- M5 F* `
  799. 2 i4 f5 @% @: R: C
  800. }
    8 K4 g  N" q: ^$ `, K9 p3 U* Z, [

  801. 7 c& p2 j; d& C
  802. /************************************************************************/
    . i8 T" [9 x" y
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    1 T, T# O# L; [& P
  804. /*                                                                                                                                                */$ t+ q% B8 t2 P6 I+ U+ j/ n+ V- o
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */, c* n8 @" ]  |$ ]. [  n: y6 H
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    " Y" G0 D2 G! A
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ' v9 t* u1 j  T) D! A
  808. /* the device.  The 1st data byte will be programmed into the initial   */. n, I2 {- i% `
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    * i2 u1 u4 g& C1 ^. V9 A$ c
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    5 _1 R4 _, ]2 P7 e1 h
  811. /* used after Auto_Address_IncA.                                                                                */
    . L( w1 e+ M1 M, g- h" [9 B% k" O
  812. /* Assumption:  Address being programmed is already erased and is NOT        *// t6 Z" a$ r) u3 k
  813. /*                                block protected.                                                                                */& S5 m7 M  s2 F. j2 n4 a# `
  814. /*                                                                                                                                                */
    0 U3 b5 @5 g' M
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / V8 J, u+ Z5 x2 b" O1 @" B
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    # I- J6 w' o8 ]( }3 ^" j. a
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */+ W1 w  d6 B' C1 J2 E* V
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    + I  D: U$ c& I; b
  819. /*         last address of unprotected block, which automatically exits                 */. h; D7 h+ {; [( S" W
  820. /*         AAI mode.                                                                                                                        */0 r4 l* a9 M* Z1 H5 [+ D
  821. /*                                                                                                                                                */0 Z& [2 [7 N# b, s9 s/ @7 H6 ^
  822. /* Input:                                                                                                                                *// s) @$ b3 m$ [+ w
  823. /*                                                                                                                                                */7 N& N' g7 E$ D4 W$ l
  824. /*                byte1:                1st byte to be programmed                                                        */
    : B/ p& P8 N8 l
  825. /*                byte2:                2nd byte to be programmed                                                        */- h7 v! E& n6 U& q. _
  826. /*                                                                                                                                      */( R, a3 @# r- E9 {6 ?- N
  827. /*                                                                                                                                                */
    7 S* v. [- i9 T
  828. /* Returns:                                                                                                                                */
    ( p( {3 @9 c, e1 y! h& F
  829. /*                Nothing                                                                                                                        */
      R6 {# y- }( A  T! M6 P' |( O
  830. /*                                                                                                                                                */2 V/ m) @; v5 S; G; ?
  831. /************************************************************************/* e( @4 q5 z5 i6 \) _9 I+ P: m
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)& u9 F1 E( h, O$ w" r( K  }) E: W" v
  833. {6 D3 s  d; o7 j" q: H, o
  834.         CE_Low();                                /* enable device */- }+ |/ g/ o0 [8 N1 ~; z
  835.         Send_Byte(0xAD);                /* send AAI command */1 b& Q" f' b6 P4 y" O$ q0 u
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ) K. x2 }' E" f
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */; a$ I2 D3 K* T! q  \  E
  838.         CE_High();                                /* disable device */
    7 h0 B' a; U' B* O% v

  839. ) J& N/ {0 P+ [0 j3 M3 b5 {
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    ( [7 Z& ?- z( F, k( k" {% q
  841. 6 h8 b% J) @& W/ [6 u, S
  842.         WRDI();                                 /* Exit AAI before executing DBSY */& |  j; c& `4 m9 v5 ~& \. a' [
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */# Z& b) {' N, M5 d2 r* `4 P
  844. }$ |! m' b& d8 j( U/ V9 i% y) @6 F1 E* S
  845. 6 H9 ^. F6 g6 C; h& f. i6 [! @1 s' H
  846. /************************************************************************/: t. R/ R6 y% P1 n) s: o3 o2 Z
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    8 [5 z, f  h. W# u$ _3 i
  848. /*                                                                                                                                                */
    0 o; S0 e  u# `9 t) l; P
  849. /* This procedure erases the entire Chip.                                                                */
    8 H8 a1 `0 E9 `& T4 I" x3 r+ R
  850. /*                                                                                                                                                */
    4 g+ E, A6 a$ b" c" j/ @4 R* z
  851. /* Input:                                                                                                                                */5 Z) s* W& Z* j; T7 [( S% {
  852. /*                None                                                                                                                        */
    5 p1 ]5 e' i$ I3 q
  853. /*                                                                                                                                                */
    % }7 c! d: |( Q5 r: |' z7 P, p; w' Z
  854. /* Returns:                                                                                                                                */
    ( w% s! T2 f4 E7 Q* C
  855. /*                Nothing                                                                                                                        */; @* C* Y0 t6 c& ?
  856. /************************************************************************/( Q6 T0 S) U9 w' P
  857. void Chip_Erase()
    " e# y& w' E) B, T" p& [/ F7 h) J
  858. {                                                7 w* I6 @% _  q/ P: F7 Z7 L8 _- k2 _" Q
  859.         CE_Low();                                /* enable device */
    % R( b% s; I4 d. q7 D9 a  P0 {# c
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    $ l/ ^0 g6 @' e" M: S5 J
  861.         CE_High();                                /* disable device */  c, B  V# z+ Y
  862. }
    ; c, e! x5 Z( O6 {/ D) u! F$ _! d7 W" p* f

  863. 0 L" j$ i4 I7 ?) X5 o7 u5 @0 U, q* \, X
  864. /************************************************************************/: R2 s" z, H# B0 p, q7 K
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    3 M" B3 f3 i& g- _4 e6 B/ p2 f
  866. /*                                                                                                                                                */: [" n5 b% Y7 e# C) r2 ?
  867. /* This procedure Sector Erases the Chip.                                                                */3 T! G3 \4 Q! j8 S, I7 }2 D/ S, z' d
  868. /*                                                                                                                                                */; y) L9 [* _0 C7 ^! {0 X7 t
  869. /* Input:                                                                                                                                */! x5 b9 w6 z2 P1 y
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + J3 q6 U% _* i+ i
  871. /*                                                                                                                                                */2 M9 E- E# F% ?* ]! p- J0 n
  872. /* Returns:                                                                                                                                */
    % K9 [7 P" o! y# ?- A
  873. /*                Nothing                                                                                                                        */
    9 i- t7 c% A# O% i* ~
  874. /************************************************************************/
    . b5 A6 W/ g" _/ l4 G
  875. void Sector_Erase(unsigned long Dst)% Q% g6 @& W; o  R
  876. {# E) i  j4 Z; D; Q
  877. ; `0 U  a) h, ^! Y

  878. # S- v5 [: ^6 z# ]5 @
  879.         CE_Low();                                        /* enable device */9 H9 W( H7 @( `8 u* K
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    : g$ H) C9 e4 x
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , @# G7 Q- W1 ?
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " Y) t5 Y6 Q0 h- \+ S0 B: e
  883.         Send_Byte(Dst & 0xFF);# Y  O: `& W- y* Y' M8 S" U. }& F
  884.         CE_High();                                        /* disable device */
    ; ]3 U7 K* u, D  _2 X3 M. t, d& D
  885. }        % e# l5 j) `1 L- Z

  886. 8 z* {* X) Q5 q2 O. h
  887. /************************************************************************/
    & K& \% O& c3 k: a9 \
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ; E/ p# z& g+ D% B3 ^1 G
  889. /*                                                                                                                                                */6 |8 C7 n3 w/ r  n$ `, m
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        *// e# |6 q8 @. R9 a$ c  ]% m" L# ^) r
  891. /*                                                                                                                                                */' i' t2 P! Y( h: H1 g
  892. /* Input:                                                                                                                                */! W$ p; J6 |: Q% d/ V2 G
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 \7 Y# |6 q: X1 G  ?6 z3 H: N* r
  894. /*                                                                                                                                                */
      Y6 G0 D0 \( F, \
  895. /* Returns:                                                                                                                                */
    . K& I7 q- O3 e5 p* F9 ]
  896. /*                Nothing                                                                                                                        */, A1 Q/ b* G# u0 X0 F3 ?/ U5 ?& t
  897. /************************************************************************/
    8 A+ E+ A$ v7 X! |- ~$ ^
  898. void Block_Erase_32K(unsigned long Dst)- n( M6 x4 E; h6 r
  899. {
    " _5 w8 H0 U, Y; S5 B# E
  900.         CE_Low();                                        /* enable device */
    7 d0 D5 Q0 i# n1 u% f( _
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */! g- U. x* t, }# K) \
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */) Y/ \1 N9 c1 {8 J$ U4 @4 c) Q
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));4 t$ W; m" Y4 w7 G2 J* _
  904.         Send_Byte(Dst & 0xFF);! m$ u7 k1 `! p+ Q
  905.         CE_High();                                        /* disable device */# |% x# e5 n: Q4 O5 E
  906. }# \+ ^: Q7 N, W5 v# l

  907. 4 o5 v+ i# {4 [% P2 w: |' Y, j& H! C
  908. /************************************************************************/: d# v( }" S5 S) s" d
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */! X/ ?! o# r8 d* `- E  G
  910. /*                                                                                                                                                */) q. n* c* ^. v+ ?  G- S8 d. J9 j
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ! e$ H( m% \( {0 W
  912. /*                                                                                                                                                */
    : q9 B5 k% H1 X5 d! k% ^
  913. /* Input:                                                                                                                                */. R* t+ `' F4 a
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 i- b" M2 }3 R5 z- c3 `: x
  915. /*                                                                                                                                                */0 _% w6 o+ l. v; t" a. E
  916. /* Returns:                                                                                                                                */% y5 y9 w! q0 k) m6 n" F/ t- _9 }9 m
  917. /*                Nothing                                                                                                                        */
    % |+ H0 F% C8 f' @* u* U3 {( f- @
  918. /************************************************************************/
    2 y9 _" s  J! r* s6 T( _
  919. void Block_Erase_64K(unsigned long Dst)
    ( ^6 l  k1 V$ I: g' ?3 }; ?
  920. {' Y+ L0 c" G8 `+ R" ^
  921.         CE_Low();                                        /* enable device *// q" I4 N- Y, r
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */' M& o7 j" d/ f" j* O' C
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    0 G3 s$ Z. e9 {  I
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));$ ^/ h: U" f. Q
  925.         Send_Byte(Dst & 0xFF);
    7 O0 j! G7 R6 n( M
  926.         CE_High();                                        /* disable device */! v' R0 ?6 V; v+ [. |
  927. }1 Y' o/ @& n6 N7 e$ B
  928. + |5 z& g; S+ D0 S
  929. /************************************************************************/
    / L. U/ ]# y' k' p* s/ h' M
  930. /* PROCEDURE: Wait_Busy                                                                                                        */: ~& E( T$ B+ w' H, }+ |, T7 E; ~
  931. /*                                                                                                                                                */0 e- o! |: T7 O$ e" _; J  H
  932. /* This procedure waits until device is no longer busy (can be used by        */. P$ o1 N$ G  \* L% R
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    * u$ _+ I- m( j4 [
  934. /*                                                                                                                                                *// K% E9 |6 l3 o
  935. /* Input:                                                                                                                                */  r9 G  l" q1 E5 e% R
  936. /*                None                                                                                                                        */, ~: {: P/ j. _5 N7 U0 v/ l
  937. /*                                                                                                                                                */
      N0 T0 q+ l1 c
  938. /* Returns:                                                                                                                                */
    9 m- L) N% p" N8 Z
  939. /*                Nothing                                                                                                                        */# {8 @! K8 r* I1 J" m/ V6 v
  940. /************************************************************************/9 P0 l, z* u( ^. `- h
  941. void Wait_Busy()
    9 ]! f: l( K. S1 {
  942. {7 Z' N% Z- e/ Q6 K8 ?2 O
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */5 r7 z7 _+ i' F/ }5 W2 P. \
  944.                 Read_Status_Register();$ m! a0 t9 v. B& z1 p* N5 d) U9 M& c7 Y
  945. }- |. o/ y- V- k- R8 E6 j6 r

  946. . o  X' g) Y7 G7 j  W
  947. /************************************************************************/. T: F: q- V& k0 {
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ' I/ A. `7 K( m# F( ?* m% B
  949. /*                                                                                                                                                */( R3 }- _# b- H
  950. /* This procedure waits until device is no longer busy for AAI mode.        */4 p! G  q8 x6 @! |/ z/ I6 V
  951. /*                                                                                                                                                */
    ! M9 x5 |6 E: l! [1 n
  952. /* Input:                                                                                                                                */; ]1 J8 o* ]2 @& h3 T  P
  953. /*                None                                                                                                                        */" V: o3 a- P& [% A. L5 H3 m
  954. /*                                                                                                                                                */
    : ^8 _& v# Q3 f6 y9 Z
  955. /* Returns:                                                                                                                                */$ F9 V# V3 q( z" o9 g
  956. /*                Nothing                                                                                                                        */
    % k! [! i+ V1 w( v9 K2 I
  957. /************************************************************************/
    7 |+ B) C8 C' Z
  958. void Wait_Busy_AAI()
    9 I" `" I+ \* b$ G+ U
  959. {
    * s( k- \0 J# D; n8 s  v
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */% I7 ^& @1 G) B% N
  961.                 Read_Status_Register();6 c7 i- z/ q6 {( Y
  962. }) u! a$ _" {( y, \: V5 Q( k. ?& l

  963. 2 h3 I; f4 n6 X" v0 y
  964. /************************************************************************/3 `9 ~, x7 ?+ j$ c+ `
  965. /* PROCEDURE: WREN_Check                                                                                                */; _7 e! I; m2 I( ]$ g2 S7 N3 @. F
  966. /*                                                                                                                                                */
    ; {3 M$ f- S+ Z4 r( }- x; ?
  967. /* This procedure checks to see if WEL bit set before program/erase.        */" c" w% k7 a0 n# s, V. G3 }$ f! U
  968. /*                                                                                                                                                */6 c: r6 `- U2 i% \  \
  969. /* Input:                                                                                                                                */
    , ^' B6 h/ O! d8 Z4 t3 J
  970. /*                None                                                                                                                        */
    ) n, M  \" x3 _- M3 s
  971. /*                                                                                                                                                */5 M$ F* H7 }  {6 w& r: o8 r$ z( J% O
  972. /* Returns:                                                                                                                                */
    1 `. {' |! w) N4 w* F- S
  973. /*                Nothing                                                                                                                        */- \6 G& p# H! _+ t" H
  974. /************************************************************************/
    " m. Q" W8 u9 l- g: K4 G
  975. void WREN_Check()3 S9 ?: I) _, T! z, e
  976. {1 Q- ~( i5 x& D- ~/ u5 A( q& w+ j
  977.         unsigned char byte;
    9 g0 {  K7 }. U7 _% r; L
  978.         byte = Read_Status_Register();        /* read the status register */# P" K0 z( F/ t: H$ b
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ) P4 M- B4 m3 T$ g8 P3 {
  980.         {
    . L! j, s* _+ Y6 l: u* k
  981.                 while(1)% S, ~* W+ G) s. X3 U, n
  982.                         /* add source code or statements for this file */
    ; P; |# E. c. b
  983.                         /* to compile                                  */
    8 I1 N, \. l! L+ x# n& Z; {9 V4 K
  984.                         /* i.e. option: insert a display to view error on LED? */
    6 [) U  Z4 B* P& [, x6 u
  985.                  
    ' d/ x) u" z' R& O7 R4 ~' _8 {4 d; x
  986.         }# G' g, j/ }9 R7 ]5 x( _* u: b6 u! R. |
  987. }9 L  n0 f5 p5 ~
  988.   n6 k- I; _- p& b
  989. /************************************************************************/
    - S) j( J" _; J
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    % D5 u7 y& t' N7 p0 u2 r
  991. /*                                                                                                                                                */! D$ ]* B( L, a! k" m9 P
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */8 ?: e* P3 O+ C* I" {* _
  993. /*                                                                                                                                                */
    # f1 D3 ^0 q  U$ {# f) T' n
  994. /* Input:                                                                                                                                */
    , ]4 V% x! G5 Z3 }2 ^, H9 H+ }. Y
  995. /*                None                                                                                                                        */
    & D0 ~4 K/ U% b& W
  996. /*                                                                                                                                                */
    " O9 [1 b1 g, w8 U) C
  997. /* Returns:                                                                                                                                */
    5 r! j6 p( t. l3 I+ t7 @% C- F
  998. /*                Nothing                                                                                                                        */
    1 f0 p6 t& B. o3 E! T" V, H$ p: A( ?
  999. /************************************************************************/- |% [$ y/ ~: A0 _" y4 j
  1000. void WREN_AAI_Check()
    4 @6 E% j* M. I) P5 j6 y
  1001. {
      f8 s8 s- ^* _
  1002.         unsigned char byte;2 l9 t$ w+ F8 W4 h3 y, d' Q
  1003.         byte = Read_Status_Register();        /* read the status register */
    1 J9 G$ ^& e6 D; f4 ~' @$ z& V6 k
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    0 n) b" j) d: }/ a) l( d) V) j3 H
  1005.         {
    6 ]% w% v" |6 F/ `
  1006.                 while(1)                6 z6 q' s) ]5 u" C
  1007.                         /* add source code or statements for this file */
    1 _! @( O' u! `& _# c1 |
  1008.                         /* to compile                                  */# ^, S* L% y/ C+ P
  1009.                         /* i.e. option: insert a display to view error on LED? *// ~& h! A1 H4 k6 ?
  1010. , R5 Z* z* }" d1 P$ p
  1011.         }4 y, s4 X0 u' h3 }  u1 f5 d# i# F
  1012. }
    5 F% S7 N% N& G* D" U8 B' P) W
  1013. & k# B# {3 c' r. W8 |& N
  1014. /************************************************************************/
    # S/ \" }9 w' w! [4 R
  1015. /* PROCEDURE: Verify                                                                                                        */
    * W3 c4 Q# f) r/ {* R9 Q
  1016. /*                                                                                                                                                */
      ]! }& ^$ r, ?+ e( t; l! b
  1017. /* This procedure checks to see if the correct byte has be read.                */7 n1 U7 {. k- C& Z
  1018. /*                                                                                                                                                */
    9 F0 B# u' l' R+ T% J3 W
  1019. /* Input:                                                                                                                                */: K. P6 T  ?: G! i/ e" Q2 `
  1020. /*                byte:                byte read                                                                                        */
    $ W/ G3 ^3 q- c- t# m' C. `
  1021. /*                cor_byte:        correct_byte that should be read                                        */: c+ x: k& ~! w* y! H4 W
  1022. /*                                                                                                                                                */
    0 t9 S: W' b4 E! C* e
  1023. /* Returns:                                                                                                                                */& O1 H0 K1 S: }0 v: X& R+ r7 B
  1024. /*                Nothing                                                                                                                        */
    # U; M% m4 Y! W# r* b& C
  1025. /************************************************************************/
    + f) l" x+ f0 b) W
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    , E+ H9 q5 f) S- D
  1027. {: h, ?( T8 D+ i1 J6 U( U4 G
  1028.         if (byte != cor_byte)
    9 B2 q: h6 V$ @' D' u
  1029.         {
    7 v" q. ]1 ^+ [
  1030.                 while(1)
    5 Y0 ?; o, H( @" l% Q
  1031.                         /* add source code or statement for this file */+ ~. y5 e- b6 e# x9 T/ X
  1032.                         /* to compile                                  */
    " z3 u; v5 n( b- ]" F2 A! K8 q
  1033.                         /* i.e. option: insert a display to view error on LED? */
    . j+ v1 [8 Q4 M1 p- e1 x
  1034.                 5 u- R8 R9 [' G/ B
  1035.         }4 Q+ K3 c; ^& K
  1036. }& D8 ^0 [, ?( V6 W
  1037. * ^4 N( l# P" O! B$ P+ ~! Q
  1038. 8 z+ I2 [1 ]* x' H/ v1 J1 J' C% u
  1039. int main()  R# Y( V& ^, ?. _( e4 C: b
  1040. {9 u, U! U6 j# M1 D) W! s3 d
  1041. ( I. }; O. Y2 P
  1042. return 0;$ U, X" T$ B7 s/ k, n: u( B9 `
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
. ?0 c4 j: V6 D2 o   main()
4 \, J. k! Y* _& R" }8 _' H   里面怎么是空的呢?
5 F$ b& s/ `( V( a* \# }5 n   发一份给我吧! F$ `# T" Z# c9 ?
mail:luyijun2005@hotmail.com
) z8 C0 E" r; ^3 T咯。。。。
回复

使用道具 举报

 楼主| 发表于 2007-12-11 19:37:35 | 显示全部楼层
本部分就是如此,它提供的是方法,并不是给你拿来编译的.你要main函数能用来干什么? 为什么不看看 Byte_Program...等函数?
回复

使用道具 举报

发表于 2008-1-8 17:42:00 | 显示全部楼层
如获至宝!请问哪里能找到SPI的官方spec(我不是指flash的datasheet)?网上只能找到些片断...管理员是否可以上传spi spec至本站?
回复

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
$ h; Z  r% ^! l% G( ~! x1 W- K. F8 X0 n8 j3 ]0 S
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。# u/ T0 P3 i$ ?
EC的代码在哪跑,你看DS的说明,每个EC都不同的。: T; V- R# Q5 b8 F5 _: h% ]8 H
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
# m; F5 V& D) F, l上面几个问题是你没看任何东西而白问。
2 {: T  B/ ^7 [6 c3 H8 @% S% O7 q' G( r4 r! E3 r+ }" W  {6 X! U
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。6 G! Z8 L; L6 {' D: a
6 I$ b2 n: u- m
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!% \- ?9 g, o$ m- v

  |- W5 ]* h9 \3 J! r5 o. V关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”4 m) Z+ y+ a0 l  p# \& \4 r

! U$ ?6 V& N; _/ q( o关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
" G7 W( @* K1 r% q7 {, ]; W
. P2 p8 o" c- }8 E6 ?不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
  c8 r1 j6 |6 [7 ]7 ]" q似乎要把SPI能support 到最大,这EC chip应该有好卖点" Y# s1 f4 l, p3 f# d% }% J
BIOS功能要不要强大,也就决定了SPI Flach的大小
4 M2 Y' F( e/ B, h# X1 q我是这么想的~让OEM去决定要挂多大!
/ Z) O6 O* d" s, R4 j如果我司有BIOS工程师就好了~哈+ j. |% c+ ?* A" S" |
WPCE775应该算很新的东西,来看它支持到多大?
2 e( C* ^. ^8 S( h" V5 J% f* G) j( M8 ]! D0 p; u/ E% A
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
5 A% h/ [, I9 T2 i其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
& @' d; ]& }3 u4 m0 t7 ~' ^. E$ A7 l6 {$ L
这份driver收下~希望以后有用到
+ a9 W" ]- R. W8 K+ s" y谢谢bini大大9 s& D* d4 Z9 X' e4 Z

% |" F  [. J( v很新很新的新手,如有错误请指正 (准备看第二家的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()
; s: l  @: j9 ~5 z, D( F! p. {5 k{
5 z2 v9 V. r2 z        unsigned char temp = 0;
- x( X) `, e0 Y        CE_Low();- Y" S; J7 }% b& }! G
    while (temp == 0x00)        /* waste time until not busy */) e' p6 L; o' K: {' E: k, y3 O) q
                temp = SO;
+ @& t, |$ P" {' u1 l* x  H        CE_High();% P, `7 S4 b6 C# J! x7 a
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
) H7 J! N5 ]" V+ ]{
6 U2 G% I, z. M* t% u        
/ w! Y) D+ y2 [        unsigned char i = 0;8 I# D# J9 V! R+ ~7 D
        for (i = 0; i < 8; i++)
- I; t, x& O* Y( A7 ~3 o4 n. L4 N6 \        {
: j0 @- b4 S6 r/ B               
/ r" G$ O- g1 J* b$ b/ }                if ((out & 0x80) == 0x80)        /* check if MSB is high */
9 g) X2 F; S; W% K( f                        SI = 1;6 J/ z5 m7 c0 u+ R$ d
                else
" a! Y: e) x( c                        SI = 0;                                /* if not, set to low */
; ~% B$ n; u4 P$ y! O5 ]- W8 } 问              SCK = 1;                                /* toggle clock high */
1 D6 l9 P& o# |& j- q  I- |   题            out = (out << 1);                /* shift 1 place for next bit */
' y6 |5 Y4 B. w. @0 y                SCK = 0;                                /* toggle clock low */: E& R$ U0 a7 K; X" C
        }
! ?' ~4 Q4 x4 ?5 B; C& y7 f. n, ^}! }7 d: t7 ~6 i* k( Y8 F. ~
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-4 12:43 , Processed in 0.151623 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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