找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55499|回复: 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
    * m, K6 r2 _0 a+ Q$ Z  E

  2. 7 Y4 N  ~9 G3 h$ e  R9 a
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    8 j4 a3 Y  T8 H' j2 r

  4. 6 m' }* g+ N0 l* L+ z  }9 ^7 N
  5. November 4th, 2005, Rev. 1.0
    : u7 {  @# n- u3 s( n

  6. ) o1 d1 h8 H4 a) W
  7. ABOUT THE SOFTWARE6 W) ]1 U6 O! B. Q7 G0 `+ `% u
  8. This application note provides software driver examples for SST25VF080B,  J* V, V: j. i8 h
  9. Serial Flash. Extensive comments are included in each routine to describe ) j9 X, ~- |  r( L
  10. the function of each routine.  The interface coding uses polling method - _7 Y1 r7 U% x, Q9 A9 X
  11. rather than the SPI protocol to interface with these serial devices.  The6 H; K1 I: O+ c" p6 c: M
  12. functions are differentiated below in terms of the communication protocols
    6 Y- K" e$ u/ G8 p# n
  13. (uses Mode 0) and specific device operation instructions. This code has been . I& ]/ O  M; V4 q0 Y. P3 l6 Y* X
  14. designed to compile using the Keil compiler.( O) m( u2 a% O3 D; @2 i
  15. 4 N4 k9 y4 o# K7 S
  16. ' L5 G. c) p, F* X: r8 H4 H
  17. ABOUT THE SST25VF080B0 i' B0 O1 z7 G# J% I
  18. # b2 O4 u3 A: M
  19. Companion product datasheets for the SST25VF080B should be reviewed in * H) ?1 Q: d! K
  20. conjunction with this application note for a complete understanding , v/ }! R/ G9 I
  21. of the device.
    ! H8 {2 W2 W2 m
  22. , m5 E" j/ Y7 L* i1 ]

  23. : l" i. @8 s3 U% v( o
  24. Device Communication Protocol(pinout related) functions:/ E  k& I; }' m7 c  b( A

  25.   X6 w! i8 A8 F  w- [6 k
  26. Functions                                    Function! G' y3 |. F+ Q$ ?% r" ~
  27. ------------------------------------------------------------------' j/ i$ @1 A3 m0 P
  28. init                                        Initializes clock to set up mode 0.5 o# a- _" ^. ^9 ~
  29. Send_Byte                                Sends one byte using SI pin to send and ) x) w- p( P* A" x
  30.                                                 shift out 1-bit per clock rising edge: c. a4 e$ S4 _( `) H" u7 v1 o
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 4 i: V. K' y, w" Y4 w5 N( z# N
  32.                                                 in 1-bit per clock falling edge
    $ I' S$ u8 [- y
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    0 G3 e" \  `6 C, k  W
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    - A/ u" W6 t: v7 S3 t" m9 Z! _1 K
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    ' a( ?3 L, h; I! u. Z
  36. Hold_Low                                Clears Hold pin to make serial flash hold+ t% |* j8 O9 h9 L: h. W9 \
  37. Unhold                                        Unholds the serial flash/ Q+ c! h" q+ E$ v" D
  38. WP_Low                                        Clears WP pin to make serial flash write protected+ b. {) S1 `) }! W, N
  39. UnWP                                        Disables write protection pin
    ! p# H3 ^# O3 `/ f' w

  40. / c6 b3 l2 A- \
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code. D$ o3 m* W: i/ f
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    : Q. ^3 l% {7 U& g- _
  43. software which should reflect your hardware interfaced.          
    # ^' W% t; x! Y0 O/ t# b; |

  44. 5 p. ~4 ], }) D
  45. 9 K( P$ U1 l, y9 y
  46. Device Operation Instruction functions:& l! i6 _- v: F3 Q1 e6 L
  47. 4 W9 P8 s. d5 @5 S0 ]- D
  48. Functions                                    Function: A* v: V1 ]0 U7 f9 A1 x7 `  {& j
  49. ------------------------------------------------------------------
    ! Q& n& i1 M+ m+ u, ~' N9 ?/ V
  50. Read_Status_Register        Reads the status register of the serial flash
    - p4 D% `( y0 O3 b5 ~
  51. EWSR                                        Enables the Write Status Register
    % x1 X0 q! Z! ~! }4 C: h
  52. WRSR                                        Performs a write to the status register
    - i: Y1 ~$ `9 F, k" |
  53. WREN                                        Write enables the serial flash
    ! H" W; V5 @# l0 H. h( a5 v
  54. WRDI                                        Write disables the serial flash" @) \1 {( @: @) T
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    - f3 R3 T' g# B1 _5 a  m
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming4 R/ r/ v/ D; A0 H8 G" l; y
  57. Read_ID                                        Reads the manufacturer ID and device ID+ ^1 u  X4 V! p: t* p  Q
  58. Jedec_ID_Read                        Reads the Jedec ID
    , `" \; t# ^1 T: g7 h1 ~4 p) g
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency). q* _0 z1 [6 y9 y4 m4 a
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    / m3 e0 ?3 p, _( F' H0 `9 ^- w% ~
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)! e) [  f2 C3 h* T7 \  |
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    ) f) e3 v1 l; B+ B
  63. Byte_Program                        Program one byte to the serial flash
    - Q: {/ \: n( s+ Z# F
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    4 V, J. K6 i: _/ k3 ~
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation8 `! [! F8 v, ^& _0 L
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY% T$ ]. z0 z3 f8 ]
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    9 ?; i$ w6 X( g( g
  68. Chip_Erase                                Erases entire serial flash. m; q4 n% V0 ~# a. m5 I6 t7 {7 g
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    8 P% t8 U% K/ t! t
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    9 i" x* C: a2 j) T
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    2 p+ w$ |- T1 b! E
  72. Wait_Busy                                Polls status register until busy bit is low
    2 H8 _, q2 D  i' }" I- R
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming! @9 w8 I8 ]! O# Z" y( U
  74. WREN_Check                                Checks to see if WEL is set
    9 j0 k# r  E9 q3 W$ E
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    % k, `3 ^/ x/ i/ P8 p
  76. * P- S$ X* H( @' G# g& X
  77. 4 C2 X( z# q8 @7 y

  78. " H& I/ I2 ?! i1 N
  79.                                                                      
    ) ?8 @! G8 ]! D  c  {. }0 L2 Q
  80. "C" LANGUAGE DRIVERS $ o3 c% f4 C. _' C6 ^
  81. " t  n& U) w: ?6 ~" o
  82. /********************************************************************/
    % }2 q( ?: x9 Z% |* K( }
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */& m/ k2 l1 S: U$ L+ M
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */2 U, t, ]. I% p: U" _6 i) P; g; n
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    : r; L/ j! }( |5 R
  86. /*                                                                  */
    0 p% o6 J1 n$ t0 A  X
  87. /* Revision 1.0, November 4th, 2005                                                                          */   + n! D9 h3 R* H7 A! @+ i) Z
  88. /*                                                                  */
    ! Y0 d3 a9 R. F7 D. i! c% z
  89. /*                                                                                                                                        */
    . y& v3 E) T: q5 ?+ A1 g4 L
  90. /********************************************************************/7 L  _2 t2 o/ ~
  91. 5 u, D) y. Y8 l1 r2 h" j
  92. #include <stdio.h>
    7 [' o* `  k  G1 R- k
  93. #include <stdlib.h>
    ; I3 P2 v2 \3 O# E* M

  94. 6 p8 `# `( P$ ^( v: R, P2 V( ~
  95. /* Function Prototypes */8 B/ ^" m/ d- f# _

  96. 7 `  J8 J+ q% V
  97. void init();
    ; t5 J' G9 W2 z* R
  98. void Send_Byte(unsigned char out);! ]: Y- X$ |% \$ i$ X) w. E
  99. unsigned char Get_Byte();; v9 c. ~" n7 t9 J7 H, o
  100. void Poll_SO();3 L$ N- I' e( R7 ]  X0 y1 K
  101. void CE_High();! ?* m3 ^# L( l. w2 X% a
  102. void CE_Low();% P$ s, H  P) t/ p) I. d8 N$ X
  103. void Hold_Low();
    ! h; c) G$ S* H. S
  104. void Unhold();5 T" q8 L) p/ S" A' R8 S2 a6 _- p5 y
  105. void WP_Low();2 ~) `! r+ ^$ L, a1 Y; m
  106. void UnWP();. c5 j& ?8 l$ c5 c( w# T& ~6 m
  107. unsigned char Read_Status_Register();
    7 q, i0 r1 S3 ^! j% \4 T8 P/ `, {3 a
  108. void EWSR();
    9 t, l$ z1 q( s. F" k( h4 ], f
  109. void WRSR(byte);  ~% w- G* E* o$ u# |
  110. void WREN();/ W' X' d2 a/ P3 B# k% E
  111. void WRDI();% ~% x" V7 j/ \" t" ^
  112. void EBSY();
    ! e8 Z7 |  n' H, F: ?& Q7 `) p
  113. void DBSY();
    ; Q0 H7 H0 K' I# M4 T3 A
  114. unsigned char Read_ID(ID_addr);& E8 w  H: M: v( {" {
  115. unsigned long Jedec_ID_Read(); - |! W+ Q* Z9 ~: a( e8 _
  116. unsigned char Read(unsigned long Dst);
    4 n9 _: V0 V0 N: l7 Y3 a( S0 f8 Y
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    & q5 S$ c, H2 r; H: l- ~+ d2 v
  118. unsigned char HighSpeed_Read(unsigned long Dst); : D% o) \7 ]) a2 t
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);* F1 `1 W- f* _! L1 `
  120. void Byte_Program(unsigned long Dst, unsigned char byte);" Q6 n* S7 ?  Z" u: N; G7 P
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    + y3 ]4 W9 Q" l# G# U) ?! J
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);* y7 w& \$ D: z* x4 t: g: U  B
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);/ y; n7 Y9 S9 Y$ ^3 c' B3 N. r
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);. `; W7 Y3 y8 t3 T8 l: e
  125. void Chip_Erase();
    4 h2 O* `% F& }; ?- ~) ?
  126. void Sector_Erase(unsigned long Dst);
    / J* K% d! a9 U
  127. void Block_Erase_32K(unsigned long Dst);* T, B" ]! L  G. p
  128. void Block_Erase_64K(unsigned long Dst);
    3 W9 A( j! z8 K: O; `1 I* S
  129. void Wait_Busy();7 z4 p8 v. D' S& U
  130. void Wait_Busy_AAI();& T* ?+ m$ c- z
  131. void WREN_Check();
    / f) P- ]/ x4 s2 \4 ~  D, N  ]) p/ N
  132. void WREN_AAI_Check();
    ' R; ?  u( c- V$ t0 l% C" T7 T4 g

  133. / j( l3 v) k  B, b* E, g' S9 E
  134. void Verify(unsigned char byte, unsigned char cor_byte);+ z# b0 g. e7 a- q5 U* J  D
  135. 8 w0 Q8 s1 x" h
  136. unsigned char idata upper_128[128];                /* global array to store read data */1 x% _4 }6 c6 h7 \1 b$ L* g& y
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    . p$ |6 A6 g& \2 K3 O' N# p: B
  138. 3 q$ D/ W% r: D; n' M+ h
  139. /************************************************************************/
      W' G, r* r' [; R2 j# ]
  140. /* PROCEDURE: init                                                                                                                */9 a- Y& d; q. B. K: I
  141. /*                                                                                                                                                */
    2 j# e+ a& a2 i3 A& k& E
  142. /* This procedure initializes the SCK to low. Must be called prior to         */. d- Y9 d+ P/ F
  143. /* setting up mode 0.                                                                                                        */
    8 x; j. i' S( i& s
  144. /*                                                                                                                                                */
    ! ^" @6 A7 J% a6 K* {
  145. /* Input:                                                                                                                                */
    9 h1 c/ s  B- y- h+ [
  146. /*                None                                                                                                                        */! X, ^9 U7 L/ @! i
  147. /*                                                                                                                                                */
    8 [$ Q7 r; h4 @4 l2 N7 J
  148. /* Output:                                                                                                                                */
    ; ^1 _6 ~! `" l( l" d3 w; j
  149. /*                SCK                                                                                                                                */0 _; G2 ]' b9 _
  150. /************************************************************************/) U: r; M" E, I% w! c% h
  151. void init()
    6 W& r$ g6 H$ J- \' y1 u7 y
  152. {
    , t/ e5 @+ J  M" @" {$ w$ ~
  153.         SCK = 0;        /* set clock to low initial state */( r& c, r* G) @
  154. }7 o8 z" s  d$ k& |5 U

  155. 6 l8 ?- ~& ^3 B; e" C2 a* G$ U
  156. /************************************************************************/
    0 a% Y1 U: i) U# w& o+ Z& h! ?1 n
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    4 `' `$ s7 c) {7 Q1 N
  158. /*                                                                                                                                                */
    / L+ n  t1 F2 p0 ~
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    % R1 r4 P; g' p* w& h) D. a* T
  160. /* edge on the the SI pin(LSB 1st).                                                                                *// J: G* y9 O5 D# U" w  n; \' T& C9 i
  161. /*                                                                                                                                                */" o1 Z, f" }/ R$ l2 T$ W( Q1 k
  162. /* Input:                                                                                                                                */
    8 Z, n$ c' l0 L7 O
  163. /*                out                                                                                                                                */0 W, ?( s0 z% }( [
  164. /*                                                                                                                                                */
    & B4 Q2 U, A' m  H
  165. /* Output:                                                                                                                                */
    4 b+ J5 ?! K+ x+ v
  166. /*                SI                                                                                                                                */
      R, r  ~; y1 x! ?
  167. /************************************************************************/
    4 A% f) z5 w& [( s% T
  168. void Send_Byte(unsigned char out)& M+ m3 P8 e6 S8 c5 x) L9 S" M
  169. {
    4 y! ^7 T4 v8 D% C2 y5 }3 u
  170.        
    $ [! q2 a: n1 w0 G- C' {' z
  171.         unsigned char i = 0;
    3 ~. Q  ]) m# V& W% A: Q
  172.         for (i = 0; i < 8; i++)$ o9 ?" `1 P# I" q& R
  173.         {# M; Q( U; l9 L
  174.                 4 V( S4 J9 M% r. D: B" Z2 k
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */1 U7 R9 a5 F1 p( O* C" @5 n
  176.                         SI = 1;
    / p+ V  p. d* f7 R! s
  177.                 else1 A& y8 x6 Z+ D/ c0 d" n0 a9 p
  178.                         SI = 0;                                /* if not, set to low */; m% u+ |) [/ x! ]
  179.                 SCK = 1;                                /* toggle clock high */3 P3 S! |+ b& Y5 d! g* a
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    1 v9 F, U" H% @
  181.                 SCK = 0;                                /* toggle clock low */
    4 y/ f# G  w+ y2 l) e# Z) z
  182.         }
    7 E8 ^) w0 E1 b6 ?# \+ q% W! t
  183. }6 S) `3 ]4 \& m1 Y! b

  184. ) n2 v) q5 ^  Z% o
  185. /************************************************************************/
    ) S" g# @$ u  `
  186. /* PROCEDURE: Get_Byte                                                                                                        */8 H5 F6 W" s, R" e9 c& N
  187. /*                                                                                                                                                */
    - m& d  g- r+ w. O+ p( m/ Z
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ' s$ |8 A+ R$ ^
  189. /* edge on the SO pin(LSB 1st).                                                                                        */9 h+ [+ C# b+ ?8 X, f' S& n1 u  y
  190. /*                                                                                                                                                */
    : f) S5 m: A: g9 E" M& k% }0 l
  191. /* Input:                                                                                                                                */5 A' W9 x7 m: }; }
  192. /*                SO                                                                                                                                */
    - b- d* y/ }8 x2 r! M0 n
  193. /*                                                                                                                                                */
    ) n! D3 u1 t/ V, x/ |. ?) d- v2 s
  194. /* Output:                                                                                                                                */: ^* G' A/ R5 j3 k6 J# [
  195. /*                None                                                                                                                        */
    8 f) ]0 j* r" l( ?& t
  196. /************************************************************************/
    ( M# M9 }+ h, d/ d+ p1 c
  197. unsigned char Get_Byte()
    * @3 x0 o" D7 J6 J3 x9 H# H- B
  198. {
    # l# ]. ^$ ~. J, R$ p% V9 s8 b
  199.         unsigned char i = 0, in = 0, temp = 0;
    1 O+ K/ c4 o/ O$ c' j
  200.         for (i = 0; i < 8; i++)
    $ E5 W1 f  a  m+ I1 p; R4 t
  201.         {
    - @. j/ B$ m# ?
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */5 c. H% t: ~4 q/ r
  203.                 temp = SO;                        /* save input */
    3 B. F8 y9 K$ m! j  z8 z: G
  204.                 SCK = 1;                        /* toggle clock high */- v! F: m5 d& _8 ~6 r
  205.                 if (temp == 1)                        /* check to see if bit is high */
    : y  Q% g: l* o% D7 Y: D* P) k' L1 _
  206.                         in = in | 0x01;                /* if high, make bit high */+ C" R; U7 Z% [

  207. , s2 {- Y/ O3 ]
  208.                 SCK = 0;                        /* toggle clock low */3 Q( f" y& l% ~8 d6 z
  209. 2 q: y" ~# y. g  Z: O
  210.         }
    1 [# d/ Z% {0 ?% g) L: S2 ^9 U
  211.         return in;" `; ]  _& P) r# D% ?3 E
  212. }! {* ]& K3 S! u0 i9 n, L
  213. 5 o5 q/ \6 W2 C
  214. /************************************************************************/
    . i7 k9 ~: L1 `2 m7 k. L- |+ D4 P
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    % ^6 e$ B6 z* `$ f8 d( P# ^
  216. /*                                                                                                                                                */
    # i& r5 B! i5 i9 K# j$ I
  217. /* This procedure polls for the SO line during AAI programming                  */
    6 \4 [1 k3 A/ m+ e
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ' @! U2 M% g! T) O  P
  219. /* is completed                                                                                                                        */
    : U+ T9 E, H, Z( t3 }
  220. /*                                                                                                                                                */
    9 z% A7 ?" K0 m0 V" F, Q
  221. /* Input:                                                                                                                                */. r+ C2 `$ w3 e6 c& d
  222. /*                SO                                                                                                                                */) p& C9 k5 w1 w* r/ M+ z
  223. /*                                                                                                                                                */
    $ l/ a5 ?- {! g: e& p5 c7 c
  224. /* Output:                                                                                                                                */
      [9 ~# Q! P: f2 T( d" a! m
  225. /*                None                                                                                                                        */% Q5 F. ]( c2 g! `
  226. /************************************************************************/
    ! M+ a& V% j" g$ Q# T, `7 m1 G! M
  227. void Poll_SO()
    " G  J/ F  N, e! e6 p- r- s, N
  228. {
    6 a) t0 G3 ~, ~1 E+ z
  229.         unsigned char temp = 0;
    5 _  J3 h4 V  J3 E3 B
  230.         CE_Low();
    - r* m' a2 K' ?, b$ W7 e
  231.     while (temp == 0x00)        /* waste time until not busy *// k, u6 H: j  C+ n! ]
  232.                 temp = SO;
    0 X8 a( N0 V; B0 f
  233.         CE_High();7 T3 z( y5 n! T/ U; I' o
  234. }/ P! Z, j! [( _" l
  235. & Y- R7 p; Q. u7 K2 Q# W6 B
  236. /************************************************************************/" i4 P6 N) k) v  B7 o1 k6 s( B
  237. /* PROCEDURE: CE_High                                                                                                        */4 v* `& |4 O6 O4 F9 W) F9 ]
  238. /*                                                                                                                                                */
    - ~. Q( A9 S- F
  239. /* This procedure set CE = High.                                                                                */# d, W8 o8 x% d3 P2 u
  240. /*                                                                                                                                                */
    ; ]4 k4 L( K2 n2 Z9 A( S
  241. /* Input:                                                                                                                                */
    " I! H3 j- F8 z6 B  S$ I1 E
  242. /*                None                                                                                                                        */
    3 z; R& @# P1 W% @5 l
  243. /*                                                                                                                                                */  {6 p4 B) w, H. T. n7 l4 ]7 o
  244. /* Output:                                                                                                                                */7 S) U7 R! _% }, {4 c0 n) K% }
  245. /*                CE                                                                                                                                */9 {- m% y# c% n, R0 t5 p
  246. /*                                                                                                                                                */5 _* m! H2 m4 q/ c, r
  247. /************************************************************************/
    6 P- V! Y  B' L+ U$ C
  248. void CE_High()
    3 ~# S' V; O7 V
  249. {) a" j/ A( T$ {3 S' k
  250.         CE = 1;                                /* set CE high */$ G8 B' Q/ m' J/ h
  251. }3 `" B( n3 Y2 `1 s

  252. : ~6 ^( I0 i7 R- ^4 {6 l9 P
  253. /************************************************************************/
    1 ~9 {9 g: z; z4 ~! ?+ x# F( H9 k+ M
  254. /* PROCEDURE: CE_Low                                                                                                        */0 O0 ~: h. Y2 T8 A
  255. /*                                                                                                                                                */# K* P: H& [0 Q- o$ x
  256. /* This procedure drives the CE of the device to low.                                          */
    - I+ h, d1 G5 v4 d0 y8 Q
  257. /*                                                                                                                                                */
    9 h9 K* f* s9 a2 q& c5 ^
  258. /* Input:                                                                                                                                */
    ) h6 \1 I# r) _8 V  E7 V; X
  259. /*                None                                                                                                                        */" P0 D3 p" s" V" s/ L" H
  260. /*                                                                                                                                                */' a% I( \5 V- l. W3 ^
  261. /* Output:                                                                                                                                */
    ! ^  j' b* ?" @) x# @/ Y; @2 Q
  262. /*                CE                                                                                                                                */
    . k% ]2 r, j- T$ q' J! C/ P
  263. /*                                                                                                                                                */( U1 O( X; Z7 Z: E& }
  264. /************************************************************************/
    ! l. `/ i8 M/ J' t6 C. b9 k* h
  265. void CE_Low()
    & K' N) q. q" I# g; X+ y3 N( ]
  266. {       
    : H8 R/ S  }: W
  267.         CE = 0;                                /* clear CE low */
    ; P, K+ E: c( d  A) S' I" p, ?
  268. }2 ?+ ~. X! ?5 E/ V  l/ k8 v7 x

  269. 3 y% s  s, I/ Z( y5 W9 E; H
  270. /************************************************************************/
    % `# t+ G6 S# \: u
  271. /* PROCEDURE: Hold()                                                                                                        */2 b! z, v, @$ ]2 U! B) f
  272. /*                                                                                                                                                */' Q  N- {" s. E
  273. /* This procedure clears the Hold pin to low.                                                        */
    , a; t/ g# N2 ?. _! C
  274. /*                                                                                                                                                */6 R0 l  k" P/ ]- J: h: n
  275. /* Input:                                                                                                                                */" n5 S3 e$ o5 V; U& J
  276. /*                None                                                                                                                        */4 I+ u, {" X& H3 ^- a, D; V" Y
  277. /*                                                                                                                                                */
    $ N  {9 t0 V! t$ @2 `
  278. /* Output:                                                                                                                                */
    , F) \% R: n) ^- k' @3 l
  279. /*                Hold                                                                                                                        */" @# D* Y1 K+ o) F
  280. /************************************************************************/2 V" H% K, V8 I$ ~0 ]% R7 Q+ A) d
  281. void Hold_Low()
    2 m' V9 j5 s4 R6 ^; X: f( Z8 Z2 O& {
  282. {
    2 ^# F9 p& |: {" h' F1 D
  283.         Hold = 0;                        /* clear Hold pin */  O* Z6 g9 Z3 a' V3 z# T& v
  284. }9 T* F, l1 o  Z
  285. 8 b3 D  x9 F, l0 J+ o
  286. /************************************************************************/
    6 E4 Y0 p& Q5 U" \& }* _
  287. /* PROCEDURE: Unhold()                                                                                                        */
    3 \  O* ^4 N( j# e6 e9 V, Q
  288. /*                                                                                                                                                */
    . h, |- d5 r" N8 z6 Z
  289. /* This procedure sets the Hold pin to high.                                                        */
    ' E; `6 _4 Q: J3 l, u. M  l. ]
  290. /*                                                                                                                                                */% X% k: Y% a6 G0 P. o) }1 Z" z
  291. /* Input:                                                                                                                                */) Y3 K6 s) X5 t1 w' g2 l3 `4 I
  292. /*                None                                                                                                                        */! z( P9 t* w5 ~. i
  293. /*                                                                                                                                                */
    ' V9 A% I  N5 @' ?
  294. /* Output:                                                                                                                                */
    0 T$ |! p5 K! E: A, |" D2 g" ^: y
  295. /*                Hold                                                                                                                        */
    ; z3 ~, x2 f. S. N2 [
  296. /************************************************************************/
    0 W3 j( Y# }, R1 u6 p
  297. void Unhold()
    - @! N  m/ N0 V: J7 `+ ~" k' ^
  298. {
    2 q9 Q/ ]# ]& m. ~% ?4 B) [. X% C
  299.         Hold = 1;                        /* set Hold pin */3 V' A* h' H! R- T
  300. }
    : c$ c+ I  L2 N2 ~3 `
  301. 8 V* J4 X4 O& v
  302. /************************************************************************/
    / L$ s! X/ w* w& ?
  303. /* PROCEDURE: WP()                                                                                                                */5 z2 m* ]3 r6 ]. g- T0 f
  304. /*                                                                                                                                                */% o3 t; L: B/ U, Y3 o* A5 N0 c  P
  305. /* This procedure clears the WP pin to low.                                                                */4 J) }$ X/ n! g" U
  306. /*                                                                                                                                                */: T3 ^( `6 O2 F% F) G* n. B
  307. /* Input:                                                                                                                                */
    % A0 _- o# @4 \0 [9 \, o
  308. /*                None                                                                                                                        */$ c8 a9 Q7 m' w2 w; {  P3 j
  309. /*                                                                                                                                                */
    ) C$ o/ \; ^" R- ]  k5 e
  310. /* Output:                                                                                                                                */! i0 M$ _! w5 }  a
  311. /*                WP                                                                                                                                */$ a( G" S; O  D- B" U0 k2 F
  312. /************************************************************************/
    4 v' S" l. [: @1 p/ n' P( r! L" _
  313. void WP_Low()
    7 Z: F+ A7 @6 ^9 H: j4 S+ G6 Q: |
  314. {. ?1 P6 E7 V% w( B- Q
  315.         WP = 0;                                /* clear WP pin */
    # }, c+ @% Z8 b; B& L7 y# G. [
  316. }2 Y) ]# z, O* x3 m4 J

  317. 2 b$ d' I2 C- ?3 ^
  318. /************************************************************************/
    ( Q1 P$ W: J: E" G" X9 S* F
  319. /* PROCEDURE: UnWP()                                                                                                        */
    4 o; v4 H6 D0 C8 F6 ~: k! ~
  320. /*                                                                                                                                                */; J- U+ ~" V4 T' ?0 J% h8 }0 s
  321. /* This procedure sets the WP pin to high.                                                                */
    , E  M$ p- K- |1 e$ o8 A- J" d, ]
  322. /*                                                                                                                                                */( G; a% I) E9 Q9 C( ?3 D& F
  323. /* Input:                                                                                                                                */
      M: W# P$ J: d6 l! u% C
  324. /*                None                                                                                                                        */
    ' R2 `1 _5 p& K; c. {" }
  325. /*                                                                                                                                                */
    , f5 A0 Y& X8 T) X1 p
  326. /* Output:                                                                                                                                */0 [- \4 I; o* m4 P
  327. /*                WP                                                                                                                                */
    # `6 Q! j; ^  H+ N) v/ d
  328. /************************************************************************/9 d; G, n0 J; i" Z9 u4 M, c
  329. void UnWP()
    1 }5 n' p. [$ \, M7 W
  330. {' i! v) W7 x* I1 @$ y
  331.         WP = 1;                                /* set WP pin */
    7 v' S# {1 M2 e: K
  332. }3 {% I+ k4 U' l7 }+ `$ I
  333. / q* k( [# E( c! V& J+ f5 O
  334. /************************************************************************/4 n; {( M' w4 I6 p6 Z2 V2 S2 D5 t
  335. /* PROCEDURE: Read_Status_Register                                                                                */& f6 i  D4 f5 v' D, ~" o
  336. /*                                                                                                                                                */8 [4 z1 l% z8 ~3 [+ `3 e% \
  337. /* This procedure read the status register and returns the byte.                */
    & m; X4 N: O: X1 @# E' J
  338. /*                                                                                                                                                */
    * c  S5 l" F7 I7 ~6 A
  339. /* Input:                                                                                                                                */
    & n4 }- h9 R0 u
  340. /*                None                                                                                                                        */
    7 E$ L, Q- q& U6 y, E0 w
  341. /*                                                                                                                                                */
    - m% h9 ^7 q1 `2 n/ e
  342. /* Returns:                                                                                                                                */
    4 ~7 M) b* Z  |' ?9 w; v
  343. /*                byte                                                                                                                        */; p9 ?6 \- ~* R3 [" O0 k
  344. /************************************************************************/5 D1 k' P$ v+ z. l+ Z
  345. unsigned char Read_Status_Register()
    4 e/ U4 x$ [- ]
  346. {
      N" K7 I" d) H& D5 |: q
  347.         unsigned char byte = 0;
    $ Q, O# {2 c4 y. a5 f$ h
  348.         CE_Low();                                /* enable device *// B  Z& z; V8 J& u
  349.         Send_Byte(0x05);                /* send RDSR command */9 Q9 l7 n/ C7 G6 h6 ^; M
  350.         byte = Get_Byte();                /* receive byte */
    " D% R2 G" h+ G( n: t/ p5 V
  351.         CE_High();                                /* disable device */
    . ^$ z  D9 s3 h
  352.         return byte;) S& S5 u$ ~  M# t3 U8 g
  353. }! W6 V: @9 K) g/ c  i( g
  354. , `  ^" Y' v( o  g& g) e
  355. /************************************************************************/- ?2 g9 z" U/ u* p
  356. /* PROCEDURE: EWSR                                                                                                                */
    % V; f& |/ P( e
  357. /*                                                                                                                                                */
    , {) a5 a* F% F& q
  358. /* This procedure Enables Write Status Register.                                                  */
    3 S% z* A1 s8 `0 S
  359. /*                                                                                                                                                */
    , s8 L/ ~" N* p* p) M& M8 U; e+ \& D
  360. /* Input:                                                                                                                                */+ M- j1 a/ D4 r  g6 |! `
  361. /*                None                                                                                                                        */
    4 ]& J' O4 t$ O& D3 I# e8 g
  362. /*                                                                                                                                                */" l2 o$ u/ z! y* t
  363. /* Returns:                                                                                                                                */
    2 j$ R( @% t) {
  364. /*                Nothing                                                                                                                        */
    & F1 w8 a! [0 V, x6 R, F
  365. /************************************************************************/; M  [" K2 A. A& X- |/ H  @0 G
  366. void EWSR()- @4 A; X; ~% |% h& M
  367. {7 w6 S7 L5 X# t2 F9 U
  368.         CE_Low();                                /* enable device */3 h8 A- N7 F0 }( m
  369.         Send_Byte(0x50);                /* enable writing to the status register */. c. j) i( I; i' d, n2 n
  370.         CE_High();                                /* disable device */1 u, I0 x8 y5 r* r2 a6 T% H. y
  371. }/ o: E; m3 I$ B; g$ v

  372. ; }3 x/ V: I8 L; G! z; u; J
  373. /************************************************************************/; x# |& I7 i9 I: X- v
  374. /* PROCEDURE: WRSR                                                                                                                */
    9 K: {% L# u# e" V
  375. /*                                                                                                                                                */
    # e/ ?) O7 s- l# B3 l2 j, t1 X# A
  376. /* This procedure writes a byte to the Status Register.                                        */
    3 h8 ?% ?( T1 O# N0 B- K' y( y- x
  377. /*                                                                                                                                                */
    7 f9 C, Y' `9 i8 {# ?4 c9 ]# C
  378. /* Input:                                                                                                                                */% @' e& t. {. T3 c
  379. /*                byte                                                                                                                        */. Z' Q0 o1 u9 D( c! b: D" o
  380. /*                                                                                                                                                */  F& S" c$ C( x2 |% L' [2 \
  381. /* Returns:                                                                                                                                */; k5 v# J( k% [1 d* I7 Y& r3 F9 H
  382. /*                Nothing                                                                                                                        */. [+ I( o% h) t7 {. Q
  383. /************************************************************************/
    4 ]. I0 x6 C" P4 [6 r6 v% S
  384. void WRSR(byte), g& [' m' l& x0 z4 e6 p6 ^, g
  385. {/ ?6 }+ h/ l  g* i8 n8 B& E
  386.         CE_Low();                                /* enable device */8 I, @$ l( c0 ?$ g, \% M" o
  387.         Send_Byte(0x01);                /* select write to status register */# W1 s7 m0 q- {( e2 t
  388.         Send_Byte(byte);                /* data that will change the status of BPx 2 F; O6 h/ F' C) A! M
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ; q/ Z* ?3 f0 W( e6 L: X! z
  390.         CE_High();                                /* disable the device */8 T2 W. _$ q& u( M5 K1 w
  391. }
    * K" ^; F: j! A  w1 `% s

  392. ( K* ^6 a' o8 `" q, A9 [4 `9 |5 [
  393. /************************************************************************/9 @* ^( w6 E$ ]0 N* {! x% h4 `
  394. /* PROCEDURE: WREN                                                                                                                */# S( A- ^" k$ `4 l1 t' D
  395. /*                                                                                                                                                */
    9 L8 b% \2 s7 F  u
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    7 ?; `3 M0 r+ G
  397. /* to Enables Write Status Register.                                                                        */( Y3 Y# Q1 d! ?- x& O2 l
  398. /*                                                                                                                                                */+ D0 O. }" D5 R
  399. /* Input:                                                                                                                                */5 o9 P2 c6 |" P( J( g- Z, Z6 @) `
  400. /*                None                                                                                                                        */% G$ H; n$ X* D. `
  401. /*                                                                                                                                                */
    8 [, m: t  ]9 ^  _$ `
  402. /* Returns:                                                                                                                                */! i% Q, d- p7 |* `
  403. /*                Nothing                                                                                                                        */. J, p  o; w, O9 A. e
  404. /************************************************************************/
    ' |1 a! a/ z! V! K& U
  405. void WREN()6 a) v4 n( g/ G0 |
  406. {( Y* s( p8 H; a/ W, F  Q$ L8 J
  407.         CE_Low();                                /* enable device */
    , g$ W" _+ `+ X5 i
  408.         Send_Byte(0x06);                /* send WREN command */
    7 D2 r' }. o* ^/ }1 H" a0 G
  409.         CE_High();                                /* disable device */
    ; l! J6 B/ E6 f/ j! c2 n. o4 G
  410. }8 Y4 w6 H" o' R* q
  411. + N3 C9 j* |9 V$ ~0 E6 _8 D  @1 Q
  412. /************************************************************************/" b1 D2 Y3 E- D* W* a5 x) J2 \
  413. /* PROCEDURE: WRDI                                                                                                                */0 I! Q/ e# E* j4 P6 d6 W
  414. /*                                                                                                                                                */% e6 ~& T0 G3 d( i- J
  415. /* This procedure disables the Write Enable Latch.                                                */
    1 N1 ?7 {& c' o# z+ ^0 v6 l
  416. /*                                                                                                                                                */
    0 M* h% Y; n9 o6 U
  417. /* Input:                                                                                                                                */
    + C1 W5 d" d" t& r
  418. /*                None                                                                                                                        */8 k9 v0 ~5 r5 x# A; m% x* e
  419. /*                                                                                                                                                */
    $ F  @0 p7 e% S1 [( I) r
  420. /* Returns:                                                                                                                                */" |# w* ]) o6 _+ r3 I7 k9 i$ f
  421. /*                Nothing                                                                                                                        */' ]0 |8 C  n, Q5 \* @
  422. /************************************************************************/
    * i  v$ ?# r  }1 t% J$ A; h! W, \) d
  423. void WRDI()
    # s' e# L( [& S
  424. {
    " E  x- F* P6 H3 u) i% {1 w
  425.         CE_Low();                                /* enable device */
    1 W: ?. `; [8 H, @
  426.         Send_Byte(0x04);                /* send WRDI command */& K5 A8 O& ^4 ?4 S( r( A, ^( S
  427.         CE_High();                                /* disable device */6 [" B8 X$ ^9 F# f. {; s
  428. }' {  B0 b& R# d# Y
  429. 7 j/ p1 d; N% c2 T7 B  R
  430. /************************************************************************/( j- ~6 M# w: M% \
  431. /* PROCEDURE: EBSY                                                                                                                */
    9 o3 W4 U5 G$ z) |) n
  432. /*                                                                                                                                                */
    2 e/ l7 Q5 L7 }# \
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */- ?7 [0 z. {: ?3 _( x1 u
  434. /* programming.                                                                                                                        */6 T' j0 _: q" a) R
  435. /*                                                                                                                                                */
    5 n5 e/ }+ Y! d( Y1 ]; d8 E5 r
  436. /* Input:                                                                                                                                */
    , U2 \+ i6 \" k6 P) E$ ]
  437. /*                None                                                                                                                        */
    # v" q3 k$ O5 W% o* ]0 ?- O
  438. /*                                                                                                                                                */
    ) m/ d! u9 f" |$ x! [
  439. /* Returns:                                                                                                                                */" R& u' v; T' V6 v1 s  {) J
  440. /*                Nothing                                                                                                                        */, w1 P* L2 E  X' d) U1 O. ?7 J9 l
  441. /************************************************************************/
    * b9 N" k+ O! n5 P: O
  442. void EBSY()
    ; b1 f" Y2 s0 Q# a$ N
  443. {
    , a; l# D  e& {4 F* |
  444.         CE_Low();                                /* enable device */( ~/ z  g0 l7 z
  445.         Send_Byte(0x70);                /* send EBSY command */
    $ n4 W" C, l  c- J1 F% ~
  446.         CE_High();                                /* disable device */- v% {* e- E0 Y4 L
  447. }/ T/ ~2 O$ r4 o: ?7 S) G

  448. : D" G, i0 _" `6 a2 m) A  t
  449. /************************************************************************/
    5 y  A/ `! Z5 j5 `3 o) G: C
  450. /* PROCEDURE: DBSY                                                                                                                */
    8 G( _1 L, x# L# s
  451. /*                                                                                                                                                */
    " n$ S* k# w! n6 R
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */* g: f6 {4 S( x& L7 P! x
  453. /* programming.                                                                                                                        */
    # l; D( T: W( H8 U! ~: v7 w' ]
  454. /*                                                                                                                                                */
    ; A, y+ s- |9 I# j7 F2 k
  455. /* Input:                                                                                                                                */2 w  X2 D9 [/ c; t, [5 ~5 C
  456. /*                None                                                                                                                        */7 Q  t2 s, S- o5 X
  457. /*                                                                                                                                                */# g$ P" y- c% v7 O7 P
  458. /* Returns:                                                                                                                                */
    7 G; b: n/ n0 j7 z: W" {
  459. /*                Nothing                                                                                                                        */
    3 q" F1 J& M) o4 ?% Y, r# N
  460. /************************************************************************/
    2 A; l" X# i  R) @
  461. void DBSY(): S5 q  h5 O( B  g9 q7 f- H  x& C
  462. {
    " k& M# H1 e8 v- Z; v" p
  463.         CE_Low();                                /* enable device */3 K& j9 Y; S- q+ |/ N# y: ?- \- Q
  464.         Send_Byte(0x80);                /* send DBSY command */; _% E9 m. v: Z4 G6 l( G
  465.         CE_High();                                /* disable device */
    0 K8 @; z+ n% R5 `- g4 D$ I
  466. }6 l( p' @4 C; X+ v" J( e
  467. % a; E  M% W" Z" x; C( Q
  468. /************************************************************************/3 j; E5 m5 x6 q( \$ B5 D5 O
  469. /* PROCEDURE: Read_ID                                                                                                        */. [# [: A# {; _
  470. /*                                                                                                                                                */* {4 U; L# D# K; f) t/ h8 R5 e4 W
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         *// D1 \9 ], ~5 |
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */1 E0 v6 y9 e) c* d( q
  473. /* It is up to the user to give the last byte ID_addr to determine      */' B7 v% C9 s/ t
  474. /* whether the device outputs manufacturer's ID first, or device ID         */' q, x5 I  d( M8 `+ Z3 H
  475. /* first.  Please see the product datasheet for details.  Returns ID in */, Q" i5 u; m" N! c
  476. /* variable byte.                                                                                                                */
    7 `$ A( q2 X& N
  477. /*                                                                                                                                                */9 h8 U; D; }# m# r
  478. /* Input:                                                                                                                                */, W+ ]; Y% U8 B6 x$ J; T6 u
  479. /*                ID_addr                                                                                                                        */: y% Z' J- T) V/ W8 Q" Q+ H
  480. /*                                                                                                                                                */+ {- A1 D- B" h4 W, J! l" H
  481. /* Returns:                                                                                                                                */
      j# C1 H2 v( t- V# F8 N
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    : i7 [0 a$ k1 `+ s. I: J; k
  483. /*                                                                                                                                                */
    / k- r6 E; W. U  \2 V$ S+ M
  484. /************************************************************************/! @  j" t8 Q8 p
  485. unsigned char Read_ID(ID_addr)! H& j0 E; c2 `. S0 N5 k  V+ U
  486. {
    8 z8 Z7 y4 ?' U0 P: i2 U3 _
  487.         unsigned char byte;& o0 |; l+ e! _0 V; N
  488.         CE_Low();                                /* enable device */9 d" f& M7 s" r' Y3 _
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    1 |( `; ?2 }$ N* U+ ~/ \( m# ]1 k
  490.     Send_Byte(0x00);                /* send address */
    - O6 m5 {) _4 n# L( G' N3 ?
  491.         Send_Byte(0x00);                /* send address */
    . r# U; i! C5 h7 m
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */1 `( D1 T$ [7 s1 G" ?, f% E  N9 }1 }
  493.         byte = Get_Byte();                /* receive byte */0 S) l; b6 C) v5 }6 ]
  494.         CE_High();                                /* disable device */1 E0 ?" ?7 J0 {
  495.         return byte;" X3 Q9 U3 A  |) M# _
  496. }3 g4 Y; h0 E' k, E: v
  497. 9 d. `! _" ]7 e
  498. /************************************************************************/1 _  K. b- {6 g& Y1 U
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    1 U+ V6 r/ F& n
  500. /*                                                                                                                                                */
    ' r- J, \" _' X3 v
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */) ~5 r0 [+ t( q
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */4 J$ r/ u+ j; w/ F( x
  503. /* Please see the product datasheet for details.                                                  */# n  X( i7 U! ^% P# v6 d
  504. /*                                                                                                                                                */6 M! L4 B$ D  ?! |) i
  505. /* Input:                                                                                                                                */" S. Z* u" Q5 u9 W0 M& ^: {
  506. /*                None                                                                                                                        */
    9 N  H/ X$ S" [( C  K3 Q0 R
  507. /*                                                                                                                                                */5 v, M3 g1 z6 c; z  A/ l, `) q; e
  508. /* Returns:                                                                                                                                */
    ; }4 i; a5 g+ D- q/ c, k
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */$ x/ w4 l! P! @6 O0 q; o
  510. /*                 and Device ID (8Eh)                                                                                        */
    ( S- z- Y( [# V4 B7 W
  511. /*                                                                                                                                                */' h4 T% A' r! {
  512. /************************************************************************/
    1 O9 M& L( y( L( r5 w. x9 w# h* h
  513. unsigned long Jedec_ID_Read() ' Q2 n+ e- B/ B
  514. {- T$ {+ q* ^4 Z" L. S
  515.         unsigned long temp;
    , k2 c8 w0 t/ n$ }3 V$ U1 O' l, ~
  516.        
    2 H  E2 C2 ^% Y
  517.         temp = 0;2 @* l$ L) h, ?) O; j* J0 ]& b
  518. # [* W- K) G  y0 g) Y
  519.         CE_Low();                                        /* enable device */
      i% n6 f  D" K$ b' i3 c  D
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) *// B. D8 ~8 R: q
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */6 Q2 g) C. i" z; \4 P7 o
  522.         temp = (temp | Get_Byte()) << 8;       
    ) w  }' ]* X6 m! O0 z4 R& q! `7 B
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    , M7 M5 c; V7 F: P5 s" t( C$ m
  524.         CE_High();                                                        /* disable device */
      E1 X# q8 B! M( d
  525. 7 X8 O9 ?# s- W9 c
  526.         return temp;; H  |- S9 D) o8 Z& Q$ K
  527. }1 j6 i6 Y& k6 W8 y

  528. ) s% I- f2 v1 h3 \) Y+ f0 ~
  529. /************************************************************************/2 d# }5 v/ R8 I2 o4 Z7 y
  530. /* PROCEDURE:        Read                                                                                                        */% R7 o) ?6 ?9 Z" Y& q4 j' x
  531. /*                                                                                                                                                */               
    1 p4 p% @- b  C
  532. /* This procedure reads one address of the device.  It will return the         */
    ! w1 ], A, J/ Y$ X: b
  533. /* byte read in variable byte.                                                                                        */
    & Z: @& Q( A  }; Y& y  J# r% r
  534. /*                                                                                                                                                */+ {  G% _: G3 ]0 S+ r% c
  535. /*                                                                                                                                                */4 f( h5 W0 p' A/ {! [
  536. /*                                                                                                                                                */7 i2 r+ _! v4 f/ F; s# ?% X& V( L3 @3 P
  537. /* Input:                                                                                                                                */) }: l$ e5 C  v, Y+ `( d- ]& R
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */2 \1 j0 [4 W: @6 e1 f$ T# A
  539. /*                                                                                                                                      */( r+ |. ?8 Q( ]% g" e, f' n: a
  540. /*                                                                                                                                                */" d( X0 T2 U+ p- ]1 H& K
  541. /* Returns:                                                                                                                                */
    ' M0 d  J. G$ F  J( P* M; J+ N. ^
  542. /*                byte                                                                                                                        */
    3 \" i- @0 e! s2 j  R
  543. /*                                                                                                                                                */
    3 M+ y. K! G1 H" K  x
  544. /************************************************************************/
    " N5 C2 a; w7 Z' W
  545. unsigned char Read(unsigned long Dst) : k  }7 D5 [$ @; y' I
  546. {
    5 P* d( W) b7 D* I4 ]
  547.         unsigned char byte = 0;       
    " _% c8 u: f* j" t* b

  548.   e# n: Q0 Z" s3 t8 V4 W
  549.         CE_Low();                                /* enable device */
    7 k' x% ?3 O/ e- I* W/ p5 l
  550.         Send_Byte(0x03);                 /* read command */
    # I% J% }0 g: M7 l
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    : D. X5 O3 F: }, |
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " z. t2 u# y* p: e+ j0 I
  553.         Send_Byte(Dst & 0xFF);9 K& y, m" x$ G; ~8 W$ O4 n, E
  554.         byte = Get_Byte();
    2 b; q6 j( Q1 c) @& f) P. |3 |( c# z* _
  555.         CE_High();                                /* disable device */, n! k3 u2 J4 @7 E; B1 g
  556.         return byte;                        /* return one byte read */
    5 h7 P6 f2 ^( |4 O3 f3 }% n
  557. }
    ) O3 w' O9 W' B/ s- ]& x6 R, A

  558. + {% m" b" r/ K7 U1 N
  559. /************************************************************************/
      b4 v! s- i" q4 P1 r1 J' h# K
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    % j0 W/ U4 Y* _
  561. /*                                                                                                                                                */                % F" a  j) i4 \
  562. /* This procedure reads multiple addresses of the device and stores                */' ~$ C7 p  s4 E6 M+ X
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    + ~$ [! `! R0 ]( S
  564. /*                                                                                                                                                */- j% w/ V# |3 ]1 l
  565. /* Input:                                                                                                                                */
    ) }5 c  n+ Z. @3 i" z8 Z( Q
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ s3 n. E, s! y' M: F5 i
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */5 t9 h9 d7 l. ^6 U
  568. /*                                                                                                                                                */
    # Q4 c  r; ]4 ]( ~9 M
  569. /* Returns:                                                                                                                                */
    6 F, {- M8 q! ?6 Y: i, d
  570. /*                Nothing                                                                                                                        */) u/ `# e9 b0 W
  571. /*                                                                                                                                                */  k1 k4 f0 H- y: Q3 Y8 `) ^
  572. /************************************************************************/
    7 T' ?. X" z( x
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)/ R$ z2 V' N( f! u7 [
  574. {
    / P; {- z! o7 M& A8 I+ {0 `
  575.         unsigned long i = 0;  c) A6 T  W* S5 T& G, M+ F* {
  576.         CE_Low();                                        /* enable device */  E* L* L5 N- G! S
  577.         Send_Byte(0x03);                         /* read command */2 L  J  v% i1 ?% C. ^% x) t- G) v
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * T; U" k) r* ?' j9 s
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));& C. b: d/ k$ ?2 D
  580.         Send_Byte(Dst & 0xFF);
    5 H  ^$ j$ r1 b# r" V6 v5 J1 V
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */, [8 O# _& f0 B, Y# P7 r6 L
  582.         {* m! \" z7 s' Z8 k4 G
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    . ^& `' M/ G3 r% J8 s! t$ i1 R1 F4 s
  584.         }# r  @4 a3 J# I. I) t8 Z4 a" p
  585.         CE_High();                                        /* disable device */
    $ ?9 J4 y% L( C: W4 h9 X1 F
  586. 1 T# n) A% k0 T( u$ I
  587. }
    ' S4 @8 d3 E5 ^5 L2 F" J$ q

  588. ' t/ o9 s9 z9 p+ ~( n4 ^* a
  589. /************************************************************************/
    . v4 n3 e( \9 k" U% f
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    . Y& s8 b' P1 o7 ?! P
  591. /*                                                                                                                                                */               
    & s) F; \. ~& N
  592. /* This procedure reads one address of the device.  It will return the         */: n5 \; H& g, h
  593. /* byte read in variable byte.                                                                                        */
    4 z' n1 y' _, p& K" t8 M
  594. /*                                                                                                                                                */
    7 d( G3 E1 U6 m* `
  595. /*                                                                                                                                                */+ E# b- y. P4 K4 I  T
  596. /*                                                                                                                                                */' }8 ?2 E& x1 F( B
  597. /* Input:                                                                                                                                */( S) [# U5 |% u/ o2 K6 l8 ?( f
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ; W- \. q. P3 @5 W( h: K( {
  599. /*                                                                                                                                      */
    $ L3 O# b, x- x0 n" W
  600. /*                                                                                                                                                */
    . I8 C1 l7 P0 x; h& v1 T$ f1 \( T5 a# l' w
  601. /* Returns:                                                                                                                                */
    ; u) a. D9 E4 r
  602. /*                byte                                                                                                                        */& e0 G+ Y5 @. O, `" }
  603. /*                                                                                                                                                */, r/ w( W% S3 Z# Q- s3 U
  604. /************************************************************************/5 h6 {) b& K1 S
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    * R* L" N4 d( m/ A7 [
  606. {
    / [3 G6 Y8 M0 F% i4 m# A, Q) I+ z
  607.         unsigned char byte = 0;        ; c) a( @5 D* B" G8 J( v3 h! M0 I+ c
  608. " ~9 P% v2 u, t
  609.         CE_Low();                                /* enable device */
    + q7 T9 d# A2 Z% d' u9 V6 x; W* c
  610.         Send_Byte(0x0B);                 /* read command */
      o5 F# }. Q2 H6 _% ^$ O
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ( j( L& e* Z; ~" O7 c) u0 z
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 |( A- C2 F% T0 s/ H: y. S
  613.         Send_Byte(Dst & 0xFF);5 G! m$ a0 r; W  }
  614.         Send_Byte(0xFF);                /*dummy byte*/! T/ X  P4 w( O" a0 z! L
  615.         byte = Get_Byte();
    5 {6 h/ E& }0 Y2 z) h' h, ]5 I# ?8 B
  616.         CE_High();                                /* disable device */8 U/ F; c% F! H5 ^6 V) B/ Q0 G, w
  617.         return byte;                        /* return one byte read */
      w" J' o6 o2 P' s7 R8 K6 B
  618. }( n4 i5 A* F. O5 A* U" Q, k6 P
  619. 0 u- @) N, F1 h+ W, d9 u1 H
  620. /************************************************************************/6 o3 r1 V# Z) K" V$ X* v
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */- j3 l+ N& l# L! {+ {2 x& X# P, p# D
  622. /*                                                                                                                                                */                * e. ~. F8 U0 I- O- f& a& F
  623. /* This procedure reads multiple addresses of the device and stores                */! k7 H5 ~, h/ H% w
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/; C1 Q9 `, W" t! B/ M; \
  625. /*                                                                                                                                                */
    3 S' ]% H' J( c9 {
  626. /* Input:                                                                                                                                */
    $ M7 w2 g7 Z5 ?3 n
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( t- t, U3 w* p
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */4 i: m8 @, N$ E7 N- }4 i
  629. /*                                                                                                                                                */" f! h- z9 x5 L& l
  630. /* Returns:                                                                                                                                */
    ! g& e# J! q# c9 w! P7 b
  631. /*                Nothing                                                                                                                        */
    7 G0 z  I7 A" j& ]. [
  632. /*                                                                                                                                                */$ v: N& ?/ Y/ ^5 g) n7 i( K
  633. /************************************************************************/3 o5 M( m+ z) Y4 i8 V+ H& I8 E
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    * n. s8 g! Q. ^" q: Z, Q
  635. {
    & Z& x( W0 H- ?0 Q# M. u" ~9 B
  636.         unsigned long i = 0;' f& K9 K/ p$ J9 `# J. A0 x
  637.         CE_Low();                                        /* enable device */; Z4 e) C1 r! i" ^2 H- }9 s
  638.         Send_Byte(0x0B);                         /* read command */
    , B: X! \/ [6 R( D* {
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 I0 x3 m' J5 D' _3 W
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - W0 Z4 j8 v. q
  641.         Send_Byte(Dst & 0xFF);
    ( C& |5 L* y: m- O8 d) W  k
  642.         Send_Byte(0xFF);                        /*dummy byte*/
      E& p8 n* n1 y+ N
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 |- i" A& u% K5 O( l; v
  644.         {$ x$ ^2 p3 _. M7 E! t3 ~
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    1 C6 V" [, D( \! W* c9 b
  646.         }) Y5 m/ a: v- }: f# e5 e4 ~* R( |, o; e
  647.         CE_High();                                /* disable device */
    6 H% m% \0 Z; e/ C
  648. }
    1 r9 B) Y1 t1 T- s% ^3 U

  649. & ^2 d& M! P& i( r' S' R0 R
  650. /************************************************************************/
    : \# y' |; E& Q% D
  651. /* PROCEDURE:        Byte_Program                                                                                        */+ x0 j) P1 Q7 z( b# ^; n( B3 Q
  652. /*                                                                                                                                                */. \% C" x$ j1 J/ b$ J0 O
  653. /* This procedure programs one address of the device.                                        */1 D5 ]1 w2 u1 Y& e1 F
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) t1 ?9 f% r3 U( C7 E
  655. /* block protected.                                                                                                                */
    $ K# u$ x2 H- F1 h7 y
  656. /*                                                                                                                                                */
    ; x& M( |7 O6 \0 L7 E6 f4 h
  657. /*                                                                                                                                                */& G; v; R! T( b, A: X8 W
  658. /*                                                                                                                                                */
    2 l3 Y% i+ O" t" Q5 {" b
  659. /* Input:                                                                                                                                */0 |) Z. l4 p. Z- X& T
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      ^4 ~2 u5 J5 ?7 M% t
  661. /*                byte:                byte to be programmed                                                                */5 g" _( C6 l8 N; F' l
  662. /*                                                                                                                                      */: j$ \  i) E4 G  \- l/ G6 L: d
  663. /*                                                                                                                                                */) w( g$ c. Y; V/ b7 j4 e8 M4 H
  664. /* Returns:                                                                                                                                */
    % v7 X+ f+ S2 B. Z2 @* s* l' |
  665. /*                Nothing                                                                                                                        */
    4 E3 ^9 q/ u  q
  666. /*                                                                                                                                                */
    ' }, O/ \4 i; O0 k. w! h7 T0 K
  667. /************************************************************************/$ Q# }: F4 K% F; U; b1 ]
  668. void Byte_Program(unsigned long Dst, unsigned char byte)' I9 V1 K6 {5 d+ @, G: u
  669. {
    # E4 x) `& Z! @6 Z! d* B
  670.         CE_Low();                                        /* enable device */
    4 {5 d4 u/ @% ?4 [7 Q
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    # U  f# l2 e- i$ j
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    + J% l! q8 i+ Z& A
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));  s5 V3 f) ]& R/ V' D: U
  674.         Send_Byte(Dst & 0xFF);2 E& K$ N1 g& K
  675.         Send_Byte(byte);                        /* send byte to be programmed */' b( q4 s% x1 V" v+ t! d) ]! P* S5 n+ m
  676.         CE_High();                                        /* disable device *// ]+ V- d( t2 z% o! Y" r
  677. }- w$ O6 T( x# c$ ^
  678. . c- W0 }. W4 D9 N' e. U
  679. /************************************************************************/" K7 L0 y+ c' W  N4 J
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */  A& ?1 {, _4 z
  681. /*                                                                                                                                                */: f6 b2 ~8 ]/ P& [
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/) @9 @( j# V) K4 X' c) L2 V
  683. /* the device:  1st data byte will be programmed into the initial                 */5 e3 r6 g) A8 O" i- }+ _7 b
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    1 p+ U& P2 J, K
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ' W2 y3 P. f# J/ T; i3 D* I% M' V
  686. /* is used to to start the AAI process.  It should be followed by                 */
    4 G- l7 D6 F: L9 {5 k
  687. /* Auto_Add_IncB.                                                                                                                */
    ! {2 s; }/ q  h& @1 U* S  z$ r+ W- v+ J
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    ; @4 \( f7 Q$ w- T+ c) A& J: f& E
  689. /*                                block protected.                                                                                *// k, ]3 M( [& j% r' L
  690. /*                                                                                                                                                */
      K7 T# {3 f0 i6 a) }. Y5 S* {
  691. /*                                                                                                                                                */) e! [- u/ J0 E7 ?- d
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    + ]9 [4 L2 o4 Y" Y
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */) p; C$ f, ~$ V; N6 i: m
  694. /*         unless AAI is programming the last address or last address of                */  D/ g; `9 ~( z% b7 v" J  O$ @
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    6 O8 z) o4 p/ o, v
  696. /*                                                                                                                                                */1 u- ^8 G8 _! g  @( Q- m1 b" ]
  697. /* Input:                                                                                                                                */+ M8 R3 f# A, h3 Q5 F* T
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 v- S1 u# u6 X* ?" Q- d
  699. /*                byte1:                1st byte to be programmed                                                        */
    ' M- _" h+ z) J
  700. /*      byte1:                2nd byte to be programmed                                                        */
    * G; q0 ~  R+ K* D* \% v& j
  701. /*                                                                                                                                                */
    5 U2 y* C  x* D; {8 {( j1 U
  702. /* Returns:                                                                                                                                */
    : c5 ]) x& E3 K* C' i
  703. /*                Nothing                                                                                                                        */
    * z. A0 i4 Y- s1 j6 y% S
  704. /*                                                                                                                                                */
    # f6 L  ?7 P; g$ u8 n" z3 i
  705. /************************************************************************/
    & s8 k9 S( W7 m0 N
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    . a+ u6 ?0 f/ B) X! [$ {9 |- b
  707. {
    + v  S0 r2 h( Y7 k3 [6 j
  708.         CE_Low();                                        /* enable device */: Z% e2 r+ U2 N8 n5 ]/ ?1 a6 n
  709.         Send_Byte(0xAD);                        /* send AAI command */
    % [, h2 `# T# b% U5 \6 O* @' ?4 l
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 w# o6 r. H- b5 T% D9 g
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % w4 \0 h* E' c- o' j# [2 ^
  712.         Send_Byte(Dst & 0xFF);5 t% `7 U8 O! R- [! j
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        7 Y7 d& `+ T2 y  P, v
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
      h8 D( \" Q5 ^3 Y9 C& J8 _% o
  715.         CE_High();                                        /* disable device */; _+ k+ Q8 E9 W6 t  t, J: k: D
  716. }" D* B" @$ }+ r, Q1 |/ J

  717. 2 J$ _  T4 B! z
  718. /************************************************************************/
    2 J' U) ?# e" Y' i& }
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    " Z$ G# ?. V* p
  720. /*                                                                                                                                                */; m4 e. {" p! i* L- {2 [3 K
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/2 J# Y' s; _( W% X2 E+ a1 a9 N
  722. /* the device:  1st data byte will be programmed into the initial                 */9 p+ j( ?* b& r
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */. p4 Q, L1 z: G# J8 ^1 B
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    " i  _7 H5 _  W. d, }
  725. /* is used after Auto_Address_IncA.                                                                                */
    $ M" l+ E1 [( @" V1 m! B) }# G
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ( J& I9 [: k2 g  l* G
  727. /*                                block protected.                                                                                */) g" }. k, U6 l; z3 e, `: m
  728. /*                                                                                                                                                */7 |1 d9 {/ S4 R. p
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */& s2 l3 p2 B' b+ s2 w" J. [
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */9 v* R+ I' }: [/ {
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */, N( H$ O# C$ Y/ M. u9 h
  732. /*          to exit AAI mode unless AAI is programming the last address or                */5 A7 m7 @& T  ?: `' A# i% f
  733. /*         last address of unprotected block, which automatically exits                 */
    ( c8 d# q( Q+ S7 n8 K& r& K2 T) A
  734. /*         AAI mode.                                                                                                                        */1 C! {5 l. s  U& ^, u
  735. /*                                                                                                                                                */
    : |" [  F1 L' X5 c: e
  736. /* Input:                                                                                                                                */6 i4 v" f  C- X- m  L9 G: ]
  737. /*                                                                                                                                                */. {. m# m% ?/ _9 i7 L
  738. /*                byte1:                1st byte to be programmed                                                        */1 ^& f6 J5 ~, C: e
  739. /*                byte2:                2nd byte to be programmed                                                        */
    5 ?2 h. o* C) n4 }3 v
  740. /*                                                                                                                                      */
    8 x) d8 v& S% L+ j  R
  741. /*                                                                                                                                                */2 G5 R: E$ A' ^" h' X# k
  742. /* Returns:                                                                                                                                */, K- g8 z" O/ I% M9 X
  743. /*                Nothing                                                                                                                        */2 X  J* r. N- U( I/ T
  744. /*                                                                                                                                                */4 ]! Z$ I' P# i. q% n7 S
  745. /************************************************************************/
      V& R6 U+ G7 O2 m" b/ J
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)) l, X. c( ?3 r0 }
  747. {
    - m7 \: d& Z9 J0 b" c& ^8 P; Q; C
  748.         CE_Low();                                        /* enable device */
    * l0 J, V5 k  B' y$ j6 U
  749.         Send_Byte(0xAD);                        /* send AAI command */, U4 o" a9 V; G8 {: M' E
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    1 e) ?; \+ C* |: l+ A9 r7 v
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */$ l5 q# _/ ]9 l  Z" O" B
  752.         CE_High();                                        /* disable device */1 ^7 m4 [) g5 Z+ g: W. I
  753. }
    . ^: `1 r0 e5 i; A0 x
  754. ' B3 \, \/ \' ^  e" C. [
  755. /************************************************************************/
    3 Q" X) i6 p/ ^. O( N6 [" b
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    * }! D! a) K7 Z
  757. /*                                                                                                                                                */
    / Y: \& k! q- g8 h
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */+ L$ H& b1 `" z- a
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */7 h7 J0 |/ x( I$ @4 K
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    + G! j/ P' T! T0 v
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    . Y5 C7 }) T. }& K3 E1 j- `- D
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    8 Q+ g: {+ S! [8 y4 w
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */  M* b6 z# H' P- S2 \* I* O  m8 i
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */. i4 R; ~+ e3 x9 }8 x
  765. /* Assumption:  Address being programmed is already erased and is NOT        */! D1 D* _- r7 c
  766. /*                                block protected.                                                                                */
    + k! L' k! {$ j! B6 P
  767. /*                                                                                                                                                */$ }0 s: W1 g$ b; o' u
  768. /*                                                                                                                                                */
    ! [+ u, A) L+ I, N0 }
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ! H2 H2 F! H) h
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    % C( B: ]* G, p7 N6 i" q  Q. _: x
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */  ]9 v' p% R/ E$ K" c
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    9 ^+ f$ p2 A6 F% \$ O. e  V
  773. /*         last address of unprotected block, which automatically exits                 */
    , k  Y; p+ y# m% S3 M
  774. /*         AAI mode.                                                                                                                        */
    . ?6 ?, M8 R% t8 \. A4 H+ l2 p" p
  775. /*                                                                                                                                                */
    4 X0 S4 U4 T. n" j" p
  776. /* Input:                                                                                                                                */0 w1 x9 S" V5 b4 }9 g) n/ u
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; g  ?$ i/ R$ T1 |# w
  778. /*                byte1:                1st byte to be programmed                                                        */
    - {. f. X  G# F/ ~+ d
  779. /*      byte1:                2nd byte to be programmed                                                        */
    " d. \9 G3 ?3 m. C/ ]" N
  780. /*                                                                                                                                                */5 K) Z  c9 ?5 o" f$ [/ H6 V/ s
  781. /* Returns:                                                                                                                                */. \9 n* Y. T7 `6 w! \
  782. /*                Nothing                                                                                                                        */0 Q0 U0 j2 W1 M9 @8 N! o& U  [2 }
  783. /*                                                                                                                                                */
    8 o  f- r/ n; M3 Q( _! B
  784. /************************************************************************/3 J0 F5 S2 {* [
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)7 p' t! U, O0 P% i
  786. {$ Q* W! f. @; W/ j5 y- J7 N
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        - e: E5 l1 H$ ]7 ~! f; s" N

  788. 5 V; R8 {! |) y- ?  c& k; ^' d
  789.         CE_Low();                                        /* enable device */' }  n# m4 ]. O& }) b
  790.         Send_Byte(0xAD);                        /* send AAI command */
    & `$ q: o/ Z) E. D" K
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ X$ q5 M4 d* d( Q5 q
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 I( I% I8 j/ R6 F( X. _/ r
  793.         Send_Byte(Dst & 0xFF);9 |3 @! Z& d8 j+ }8 m2 Y3 z
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    * `* M' R$ Z8 E2 e& C
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */# \6 W7 t5 p4 j4 N
  796.         CE_High();                                        /* disable device */
    1 o2 S  M3 M7 W/ R# ?! V
  797.         & F+ l* s: O" M3 ]! c1 P' J
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    7 y7 Y& v0 M- m) g* s$ X" Z7 n

  799. - W( k& _& B- t$ I8 i9 N
  800. }+ y/ Y! q: Z; w; N) t
  801. 2 P$ C& k# S  l; _' c
  802. /************************************************************************/
    & I2 \) \9 r. Y/ m' X- L
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    # ?5 ^7 [! N' U0 y
  804. /*                                                                                                                                                */2 p* [! K  ~- c( F
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ' j9 q" }% o; w7 I$ C$ O4 N
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    6 I! W: D" b) m( L
  807. /* AAI programmming is completed.  It programs consecutive addresses of */  T% ^: l4 t& d$ `
  808. /* the device.  The 1st data byte will be programmed into the initial   */  Z/ ]0 Z, @/ @
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */( b. l+ Z, p- @
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */6 l. `% N0 h& K8 O4 }
  811. /* used after Auto_Address_IncA.                                                                                */* W1 A2 S0 h! q& w
  812. /* Assumption:  Address being programmed is already erased and is NOT        */% [% U" B( a+ s0 k$ F
  813. /*                                block protected.                                                                                */
    . i& I/ \* _; }5 h9 Q5 {9 z
  814. /*                                                                                                                                                */5 l$ K' e; o& `; G+ q' ]
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */+ ~+ b0 ^( _; k5 n" F; ?& h  d
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */# [- N" Y7 ]  F8 r$ t. q
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ ]% Z: Q# N+ k! H# ]9 o# G
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    $ v; w! c) A+ Z- }' Q. x
  819. /*         last address of unprotected block, which automatically exits                 */! W# E: w  Q: {1 E5 Z
  820. /*         AAI mode.                                                                                                                        */
    3 _4 X+ k8 p- M5 Y8 F1 K( A. Q
  821. /*                                                                                                                                                */" s; n% h) D2 g
  822. /* Input:                                                                                                                                */. X; {/ O  C7 f7 }$ W1 ^9 k
  823. /*                                                                                                                                                */) q* J! z( N+ {0 ~8 a) y
  824. /*                byte1:                1st byte to be programmed                                                        */* B1 j! V( J2 S4 t' [* c2 [" D
  825. /*                byte2:                2nd byte to be programmed                                                        */
    0 ]$ H' W; `) x& h# H
  826. /*                                                                                                                                      */: `  q, J5 b4 S' z( O5 _
  827. /*                                                                                                                                                */4 x/ q; X& c$ g) r! v
  828. /* Returns:                                                                                                                                */' L0 J+ n/ E" y* q8 X7 b
  829. /*                Nothing                                                                                                                        */
    $ g' O8 @& P1 l4 z# B
  830. /*                                                                                                                                                */, G& ~9 H6 I) V3 q+ y/ B. {7 R
  831. /************************************************************************/
    $ ~+ S) @' B' B  H
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)4 l3 H7 ]) x) c6 I4 ^7 F
  833. {. e; Q. r# I) T8 t; f; ^
  834.         CE_Low();                                /* enable device */
    , l& H; u- r. |* m/ {
  835.         Send_Byte(0xAD);                /* send AAI command */" u& \2 s0 k" g6 M
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */3 z* L8 {6 q% C
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    6 _$ B3 i% g: ?, t5 \
  838.         CE_High();                                /* disable device *// ?: ~- Y0 C/ \- `/ e- {9 o
  839. 9 D) F8 H: H* Q& C# l
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    ) \1 Y, |7 y5 q* W! O% M9 n( w" t2 J

  841. 7 |" E4 ?0 \- f
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    8 }( M. U0 W! h2 ~3 c" M1 \+ B3 P
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */8 d, n# y2 X: t  d% I0 F) ]
  844. }. z7 W  ]* m2 Q% {5 W
  845. $ R7 ]) p/ q. E! G+ o- ~
  846. /************************************************************************/
    0 ~2 o) X7 N' A5 T
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    . M8 s  H8 K$ q8 J: a: A
  848. /*                                                                                                                                                */
    . Y) g8 C9 X2 A* O& B5 r" a
  849. /* This procedure erases the entire Chip.                                                                */
    , c! ]( \, O9 I1 i. O: V
  850. /*                                                                                                                                                */5 E+ ^1 l$ c' O
  851. /* Input:                                                                                                                                */
    ! H: E5 K- _7 Z  f0 b5 r, G
  852. /*                None                                                                                                                        */4 b5 Y" ]1 M* U. k) M2 {, d% i
  853. /*                                                                                                                                                */. J  X$ G* C/ w+ v
  854. /* Returns:                                                                                                                                */5 X9 P! h; N& U$ U- B! c
  855. /*                Nothing                                                                                                                        */5 A! [* g+ Q0 Z5 ]) f* T
  856. /************************************************************************/9 m* Z6 U. y4 w) r. r* h
  857. void Chip_Erase()
    * X7 i& Z" b! _/ o8 Z
  858. {                                                6 S5 T/ c5 A  B# i& ]- E2 {5 X+ ]
  859.         CE_Low();                                /* enable device */
    5 n3 \. H0 g, s
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    - p4 N: D' L, c1 J- B: Y
  861.         CE_High();                                /* disable device */' n7 N4 y1 C1 I( [+ w* f( Z
  862. }
    9 n$ N! t4 I# L* E

  863. : p( P0 c  q9 p$ f0 j
  864. /************************************************************************/
    ' w# P5 y) n) d1 ?  X
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    : {0 p% ^0 B5 h. p1 e" g/ W1 Z, i
  866. /*                                                                                                                                                */
    6 U& s' l1 ]* ?& U/ I/ a' r- C
  867. /* This procedure Sector Erases the Chip.                                                                */# A( H& @  ?' [7 ?, Q
  868. /*                                                                                                                                                */
    9 R( j* Q1 G& t( x- m' \. P# v2 d6 h$ y
  869. /* Input:                                                                                                                                */
    0 x2 X7 x' a  G3 o4 \) t
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 ^2 F8 U& |4 b3 [- C0 V7 i
  871. /*                                                                                                                                                */3 h! c3 I1 e- m) ]8 x: H9 B
  872. /* Returns:                                                                                                                                */; y* D7 g/ ?5 I: c7 _3 [: n
  873. /*                Nothing                                                                                                                        */& ~* }: D# N2 K& u( f
  874. /************************************************************************/
    ) V( V4 l6 @) `1 V9 {
  875. void Sector_Erase(unsigned long Dst)! H# N4 d: ]" H( z+ _3 c
  876. {0 n# {; j0 [3 e& D

  877. ( V( |9 [2 W( Z0 ^4 q
  878. * Y8 d6 j( s9 W2 L+ j4 j! G
  879.         CE_Low();                                        /* enable device */
    9 ~( n9 h( F5 T7 O8 Y# N' |+ {3 r
  880.         Send_Byte(0x20);                        /* send Sector Erase command */% _- k8 ^# Y. D$ A. s
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 v6 [, l5 L5 ~1 z- s5 ?
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 D$ ~" U$ P  Q
  883.         Send_Byte(Dst & 0xFF);
    0 ~: C, w7 V! j/ X, L, T1 \
  884.         CE_High();                                        /* disable device */6 f# }5 N' r3 J' D7 R" L
  885. }       
    : q# P1 F" A8 t/ o( s9 L
  886. , G  n% a- G) ~; h2 M2 c- `
  887. /************************************************************************/
    + [  N; F9 z% {% b) `/ K$ |+ P
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    . e) p. i7 u) G8 U1 y
  889. /*                                                                                                                                                */
    - G. n2 r7 {5 z+ z) v
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */) j( b7 p9 q7 K+ H  w- \! D
  891. /*                                                                                                                                                */
    & K* a4 f9 J* e. N( R
  892. /* Input:                                                                                                                                */- p1 F: T- X" T# }
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 t+ @/ O) E: x, \" Y. b
  894. /*                                                                                                                                                */4 b# W8 W  x& F+ ]
  895. /* Returns:                                                                                                                                */( P/ k* O* Y( n. R
  896. /*                Nothing                                                                                                                        *// o. v5 |* k, X, d$ J
  897. /************************************************************************/1 X$ A2 e# q, L2 E" b/ k# s7 o( g
  898. void Block_Erase_32K(unsigned long Dst)
    ' S+ o# C; L) E# P7 v2 V. d# \
  899. {
    6 i, c, G9 Q. I: W  H
  900.         CE_Low();                                        /* enable device */8 P# z' U( S, a. R: Z0 b- I
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    , b0 j; n2 Q  [. j5 A, l
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + w) S7 C4 I. ~7 L- S7 K
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & _5 m3 o* Z; r. i: G% T! Y
  904.         Send_Byte(Dst & 0xFF);
    . J% _4 i6 d1 L- p5 a/ @* k
  905.         CE_High();                                        /* disable device */
    . z: f, n; N# s2 G" T, m1 [' h
  906. }* R  M1 b- Q3 l* y% a

  907. . F9 M: }+ y' ~5 d* c. p
  908. /************************************************************************/" U, P7 b0 j7 U4 a
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */$ @' Y/ e3 W! f2 |
  910. /*                                                                                                                                                *// T4 K* R9 e6 O# |; z+ B
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ( i& A1 t5 i- i
  912. /*                                                                                                                                                */
    2 f- j- R2 ^4 N" B
  913. /* Input:                                                                                                                                */; I7 o9 ~! \4 e) o& e. Q0 t
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 U/ {7 N0 e5 H( k0 J3 R, ]% W! g
  915. /*                                                                                                                                                */- N: W2 t6 V) d% m' q6 _
  916. /* Returns:                                                                                                                                */
    8 S$ H6 d' t8 o3 K
  917. /*                Nothing                                                                                                                        */1 e4 X& ?' n5 V' V0 J4 v) ]3 l
  918. /************************************************************************/  `6 ^( k) q: }4 k- k
  919. void Block_Erase_64K(unsigned long Dst)
    9 v4 x0 T4 t" A3 c0 K1 s
  920. {/ p/ b6 `, _- e8 G6 T! V
  921.         CE_Low();                                        /* enable device */
      x' p6 N$ B; k% @
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    ; q5 w2 q$ |" i0 H
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    - j9 |- q9 w" X; _
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - |6 @# @% W0 q2 I' |! m+ f2 X
  925.         Send_Byte(Dst & 0xFF);; t  b. B% s, R: n! z1 r3 R4 C
  926.         CE_High();                                        /* disable device */
    # H' W1 k: Y4 C1 o! |4 r3 n
  927. }
    2 p+ N( h$ T( J  r0 r6 }$ `5 M5 q

  928. * t/ O' s9 G6 n6 d: ]
  929. /************************************************************************/
    ) r. M- x. S8 v* v% g" R
  930. /* PROCEDURE: Wait_Busy                                                                                                        */  S$ c2 O4 p) O6 ~* |/ ]9 O
  931. /*                                                                                                                                                */: x7 M/ m  S5 Y2 [1 I" {, X
  932. /* This procedure waits until device is no longer busy (can be used by        */
    7 [( ~" |& C8 Q. b' z% D- H
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    * e. K. ?1 V9 y. y2 x# J! u3 |
  934. /*                                                                                                                                                */
    6 F0 N: s( Y& x
  935. /* Input:                                                                                                                                */
    0 ?; k: ~+ p: _8 e; k! L9 U
  936. /*                None                                                                                                                        */! m3 S; R. o# w- p
  937. /*                                                                                                                                                */8 S" N; L' l9 D2 j  u% c
  938. /* Returns:                                                                                                                                */' e, S! v1 ^' S- G" j
  939. /*                Nothing                                                                                                                        */
    " R# K  C7 D+ ], B5 r
  940. /************************************************************************/
      p; [' K, t& y: r% d
  941. void Wait_Busy()& k' y3 ~3 l0 Z+ T# f
  942. {
    2 k, A0 L1 Z% h
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    6 \/ E5 ], n- k; g
  944.                 Read_Status_Register();
    8 X9 S1 y5 C$ E3 H/ k# H
  945. }8 P) _% o; Z: c6 ~

  946. 3 H! I$ p- i1 J5 O
  947. /************************************************************************/
    ( c. S& X& d. |1 p9 `: @# h
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    . V2 B. H, s7 \6 ~4 n
  949. /*                                                                                                                                                */
    5 j! C: ], r& u' H
  950. /* This procedure waits until device is no longer busy for AAI mode.        */' Y- ?" q8 G# z: w5 E: g7 q
  951. /*                                                                                                                                                */
    ) U% {( x, X8 e5 u; _: Y
  952. /* Input:                                                                                                                                */
      s! Z" X" P+ j
  953. /*                None                                                                                                                        */
    + y( N4 @4 m) B; ]" V, Z% |
  954. /*                                                                                                                                                */# ~+ d* O2 Z! d8 i( Z" ~/ u" Q# p
  955. /* Returns:                                                                                                                                */
    " ~& y5 ]- d! Y0 |! y: t) D
  956. /*                Nothing                                                                                                                        */
    9 d% C3 H6 d8 ?, E, u% W+ B
  957. /************************************************************************/
    0 o5 Z+ {. f$ W' G1 n- `5 O
  958. void Wait_Busy_AAI(), u" m2 |4 {( ^
  959. {+ N% X0 X' m6 ]+ J- W) q/ v- o
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    * L. l" {" @! A$ U( s" r; b$ F  c9 s
  961.                 Read_Status_Register();
    * \/ B( X* ]' v$ F8 V+ X/ W
  962. }
    : d  B" E2 t; e# e

  963. " o, n) S: u$ k! I/ V2 s7 Z+ x& o
  964. /************************************************************************/
    - c! s! \8 P3 h) K9 ]3 F
  965. /* PROCEDURE: WREN_Check                                                                                                */1 Q( {9 \% g7 Y0 x
  966. /*                                                                                                                                                */6 F8 m$ U2 a7 v
  967. /* This procedure checks to see if WEL bit set before program/erase.        */  I; z7 E3 s4 T" p1 |0 p
  968. /*                                                                                                                                                */
    ( Y8 g% q; K- E; T1 d' n
  969. /* Input:                                                                                                                                */
    * \% |$ f+ S9 V" k
  970. /*                None                                                                                                                        */
    6 j7 i: y% C0 [3 ~' E- g& Y. E
  971. /*                                                                                                                                                */
    " F% q6 c: Z" m  i
  972. /* Returns:                                                                                                                                */
    " x7 @3 l. e' @6 R
  973. /*                Nothing                                                                                                                        */
    3 _! R" I3 w2 P
  974. /************************************************************************/' i1 J: M7 F/ z" `
  975. void WREN_Check(), ?/ Q7 G8 [- G+ `: _
  976. {
    3 @1 f6 @/ ^# e
  977.         unsigned char byte;
    # F2 l' n1 K3 B  \9 B! T$ F
  978.         byte = Read_Status_Register();        /* read the status register */$ W5 }" g# E) k* _1 d1 j# ]' q
  979.         if (byte != 0x02)                /* verify that WEL bit is set */2 Y4 k& k' ^8 q6 y
  980.         {
    , k5 x. s' [3 U# g
  981.                 while(1)5 \5 T* a$ y) t+ `
  982.                         /* add source code or statements for this file */
    2 V/ m8 h& ]2 f7 r5 f9 Q0 K
  983.                         /* to compile                                  */+ K5 F  m8 z7 V$ f/ Q
  984.                         /* i.e. option: insert a display to view error on LED? */0 a  K. }- g) x, A5 t
  985.                  
    ' t5 c0 a# {9 H
  986.         }+ h8 I% Q1 ~) H) T: d* X
  987. }# t, {% E8 T! g8 [/ y: f5 _
  988. 3 ]+ C2 Z$ s. U- k4 |
  989. /************************************************************************/
    ' T4 k0 f( r- H  v! a2 p8 k3 D$ v
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ! j# r& A, ~$ E1 r1 k7 h, W& p$ [
  991. /*                                                                                                                                                */$ E5 h0 j/ @: F' _
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    7 C8 |  a3 K! h( ?! l5 u% q! z( `0 U/ R
  993. /*                                                                                                                                                */
    9 I5 R& b3 }: k. M
  994. /* Input:                                                                                                                                *// x) a( ]. o4 w3 m0 H
  995. /*                None                                                                                                                        */
    6 ^! m& e8 R3 S0 ^. i  ~& U8 `# g
  996. /*                                                                                                                                                */
    ; T. w9 e, ~7 s
  997. /* Returns:                                                                                                                                */) U* u: E* q8 L: _$ U* d% F* J
  998. /*                Nothing                                                                                                                        */
    - v# t! C4 J) d+ A$ l9 Z
  999. /************************************************************************/
    3 U; G3 q& \& U7 T% ~
  1000. void WREN_AAI_Check()
    # Z$ I6 S/ k2 e" C, ^
  1001. {
    ! V* ?' t. G% D) w6 D8 d! }" n
  1002.         unsigned char byte;. E$ Y  s! M4 R2 `9 V5 c4 B
  1003.         byte = Read_Status_Register();        /* read the status register */
    , n/ K- L- v( b; t" h
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */% k: g+ E6 I: B+ r) o# u
  1005.         {+ l. D  x  Y% X2 @
  1006.                 while(1)                . r5 t2 ?6 S3 D0 j# f7 K
  1007.                         /* add source code or statements for this file */
    ! P+ z$ X) h. h. F; t  t) @" a/ i* g! U
  1008.                         /* to compile                                  */, S6 Y* A) w7 m; r* d. d
  1009.                         /* i.e. option: insert a display to view error on LED? */# |  p6 y& m) s

  1010. 7 {; W& b' H0 A: q4 c6 ]% v
  1011.         }; t# `. W; N0 @9 m0 h) s' A
  1012. }# U: F4 u+ ^& g- w6 d/ x8 S% X  p
  1013. 3 f9 Q, P( N2 G' j" z2 y& I' K
  1014. /************************************************************************/5 j9 X  R+ t0 u" {1 n3 H  u: W( t
  1015. /* PROCEDURE: Verify                                                                                                        */, ~$ u1 V3 x! M# A% _  _1 l7 p
  1016. /*                                                                                                                                                */
    & z9 N1 N3 Y1 a( m8 p: K3 B" ?
  1017. /* This procedure checks to see if the correct byte has be read.                */
    % p/ `0 {: I0 P3 S  s, |
  1018. /*                                                                                                                                                */
    . c; [3 s. t4 }: t; F5 ]
  1019. /* Input:                                                                                                                                */
    * k1 b) O- X$ [
  1020. /*                byte:                byte read                                                                                        */
    ) A2 B) ]7 N% o! b  j" V# s
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    $ N, a, C# @: u% w- q0 l
  1022. /*                                                                                                                                                */
    5 e* Q" N' \8 J3 f. O/ e* a
  1023. /* Returns:                                                                                                                                */
    : s) m6 Q* ^+ G
  1024. /*                Nothing                                                                                                                        */
    8 s; `, H2 a$ N5 _
  1025. /************************************************************************/  n) u6 X, i% ^5 b6 f) |
  1026. void Verify(unsigned char byte, unsigned char cor_byte). \$ ^: }; l2 x* [
  1027. {
    3 e, M6 U4 r4 _' {9 S7 x2 k  N
  1028.         if (byte != cor_byte)+ j5 `6 h2 ?/ K2 L/ B, X, n
  1029.         {
    + s" z; Y4 e3 G, p3 Q, M
  1030.                 while(1)
    * i8 f) L+ B$ P: D! F* n
  1031.                         /* add source code or statement for this file *// h3 i: Y( t  ?! b, F& s
  1032.                         /* to compile                                  */
      Z! {' Y! Y0 l0 W4 H& B
  1033.                         /* i.e. option: insert a display to view error on LED? */% u6 q* D, L$ L5 K# k& t5 r# r( U+ `
  1034.                
    9 |' v, I# g% z5 v, P
  1035.         }
    ! {* a0 g8 C. l$ S6 V0 v
  1036. }
    7 B8 I) D& s2 v% Q
  1037. 7 r' e& ^4 i5 w4 Y& V5 h

  1038. ; }) J# ^6 x( `5 K! Q( O3 N
  1039. int main()
    7 S, [' I+ }3 z) c. ]
  1040. {
    3 F& j# L5 K  }! A! N7 |1 ?' o8 J" _
  1041. : @0 y, K+ D4 q
  1042. return 0;
    ) E2 V" I. [4 k% f- S
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
0 n( _% z0 x, a) A; [0 b  z   main()
) V! r+ F* ?: T: B! [   里面怎么是空的呢?$ |6 Z6 B3 ?# F2 @
   发一份给我吧3 p2 k- ?9 `* @
mail:luyijun2005@hotmail.com
" V4 T& L3 v% H# r8 ?; Q咯。。。。
回复

使用道具 举报

 楼主| 发表于 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% ^9 E  ^0 W! J2 m
2 i3 l# _. b- z[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。" ]$ N' d: `: [" Y: D6 v) A0 }
EC的代码在哪跑,你看DS的说明,每个EC都不同的。; G$ }# [) i6 `2 X
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
' ?4 u# z. {/ N% N: h  j上面几个问题是你没看任何东西而白问。
  l( b- ]; E: l6 F3 k9 {' ]
. ?* ~. y+ W, c; D& n, L" n& E至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
7 K& J" }7 K( F  W) s# G9 L8 B( C* a* I4 y( s
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!/ p# s8 V3 t# G4 w
% d: X% R$ T' r  p3 x
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
0 ~0 ]3 n+ C8 }0 M& l  o" h& Z2 k% }$ q& h- p  B5 G6 w
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...9 g' ]( C! }) H7 S  p2 e" O' V
' @, K' x3 f6 l$ o
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样" f) j0 S; L9 Z5 a( M
似乎要把SPI能support 到最大,这EC chip应该有好卖点7 v" Q" E' U9 @3 o  h7 p* d
BIOS功能要不要强大,也就决定了SPI Flach的大小
$ c$ S* d# O8 E我是这么想的~让OEM去决定要挂多大!
% p1 U% U1 _8 ^4 \. Q如果我司有BIOS工程师就好了~哈& ^* G! ~. W7 _( p5 f
WPCE775应该算很新的东西,来看它支持到多大?. [* B  Y; N/ u, Z! _; z

7 F# A5 X2 `2 @5 ]. I另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
8 P1 Q1 ^8 I: t' l$ C1 v其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
  b4 X7 R) b+ i' A, V2 k* J9 @8 y( ^3 y% j% Y! B" j
这份driver收下~希望以后有用到7 I- p  n$ f! L
谢谢bini大大
/ y, J5 v$ B! V4 Z' c5 m
1 x/ f# S5 N9 ?8 K  C, o很新很新的新手,如有错误请指正 (准备看第二家的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()1 }' F. o- r- r1 X. N6 Y
{% v3 j8 H; \! H+ q# l
        unsigned char temp = 0;% v* q6 @+ j6 A
        CE_Low();
+ T9 D# N4 }& @; D    while (temp == 0x00)        /* waste time until not busy */% O# @/ S4 c) ?& T4 G
                temp = SO;3 y* P& `2 t; X6 ]# P
        CE_High();
7 }1 M' I+ f. H% v% ^% \}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)) t# T3 G/ G$ u/ K5 I
{0 ]5 T: o/ R2 P6 n% J9 Z
        
  X' e! E0 l/ ^& H; J        unsigned char i = 0;
; T) K" T8 N: Y) o, a" e        for (i = 0; i < 8; i++)8 d) ^( H! E; |9 k3 Z! f
        {
: p' d- {- O; N+ V3 `& B& t               
4 u7 K. y1 \1 w4 V7 q5 ^9 q; g                if ((out & 0x80) == 0x80)        /* check if MSB is high */
4 B6 Q$ F' `% ?+ e; F% |# s( |# ?                        SI = 1;
* V: u" |: k8 U# @' U3 y                else5 Z, R: |7 e( p
                        SI = 0;                                /* if not, set to low */
- z! H; Z2 q1 `1 |; u: P& B1 _ 问              SCK = 1;                                /* toggle clock high */
" x5 s0 O$ f$ @: z- y1 b# D   题            out = (out << 1);                /* shift 1 place for next bit */
/ G( V' i1 }* k3 R  c3 B0 [1 q& o                SCK = 0;                                /* toggle clock low */; {4 i/ g1 w6 \- i3 _
        }
$ D* V; x5 R4 l) V1 q4 p}2 r/ s# r5 A4 T1 O$ O6 H
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-22 01:11 , Processed in 0.115668 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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