找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55433|回复: 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
    ' E* w5 v  ~% M( y9 V$ h9 n0 S' \
  2. ! l/ F% x  Y5 E. [, \
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory6 C/ ?2 H0 S. F" l4 d- z. C
  4. + N0 b- O0 t8 P' ]2 }/ M* i
  5. November 4th, 2005, Rev. 1.0) u2 k5 ~- |5 a9 O3 b) g- u  S4 `
  6. $ W" S: I  w, ?! L3 m6 W3 U# E
  7. ABOUT THE SOFTWARE
    ' W- y5 |/ b/ g; y
  8. This application note provides software driver examples for SST25VF080B,+ [8 T% n( C) J+ p$ q: N
  9. Serial Flash. Extensive comments are included in each routine to describe
    , W( O: i  L" b$ E' y
  10. the function of each routine.  The interface coding uses polling method
    - e' J) m( ?2 ~4 A  ?
  11. rather than the SPI protocol to interface with these serial devices.  The
    2 y, T4 p! ]  r( T
  12. functions are differentiated below in terms of the communication protocols, q5 Q. ^, u7 M* l# v( x% Q
  13. (uses Mode 0) and specific device operation instructions. This code has been
    7 m# D9 w0 y# C; K* M" v$ Q$ G
  14. designed to compile using the Keil compiler.
    " d8 O6 U4 d/ p" W1 k- l% b

  15. ) ]0 {; k* A" w

  16. ! j& A% h0 M, L
  17. ABOUT THE SST25VF080B6 d$ Z  Q! u3 i, P

  18. 1 d! f7 ^4 d% Q8 M/ A* g, i, n. d
  19. Companion product datasheets for the SST25VF080B should be reviewed in & W) Y$ p& Q3 [) d, m$ i2 {
  20. conjunction with this application note for a complete understanding 4 N; W) Y# h7 `) S9 W6 z6 o
  21. of the device.9 m  v  i/ w/ G4 y
  22. 1 x4 L1 Y' e) W

  23. ( {7 G+ o. c" J- T
  24. Device Communication Protocol(pinout related) functions:( R, s4 C( o$ v4 V  q9 r) s

  25. 6 L- E: O( w! F$ y  v) {* u
  26. Functions                                    Function
    ; V% }7 P, V% T
  27. ------------------------------------------------------------------
    ) ^+ k% w) G1 ^7 ^* C* \) f. X% i
  28. init                                        Initializes clock to set up mode 0.% n5 P6 ~6 I9 \" H
  29. Send_Byte                                Sends one byte using SI pin to send and
    $ ]5 `( G1 B, N6 M
  30.                                                 shift out 1-bit per clock rising edge8 J+ y1 u6 u* t" e" M
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    7 x+ a2 z* p! U3 V" t
  32.                                                 in 1-bit per clock falling edge9 q! _, L9 B0 v* E
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    ; ^1 U/ @+ R  H
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high- A0 D6 u, ]0 ^
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    # X* z' v# ~* u
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    . b9 k' `  P9 C4 ]
  37. Unhold                                        Unholds the serial flash
    ) M. g; l1 ]6 s( i$ h) L9 I" j
  38. WP_Low                                        Clears WP pin to make serial flash write protected$ _( V+ c/ m! z! ]
  39. UnWP                                        Disables write protection pin8 w- v0 D* l8 i

  40. $ _: \' j+ H9 F9 R0 Y/ C! w
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code: L6 r; M# o# }5 f
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your8 P8 O9 o, I3 d4 `2 t9 Y
  43. software which should reflect your hardware interfaced.          
    % E/ K, K% f. \1 |
  44.   i& X- `( v3 x* y2 y. j

  45. & _# t# B( _7 H+ m3 Z
  46. Device Operation Instruction functions:% v" x: B; v/ S/ S1 t( }/ i4 f
  47. ' j9 }# A; t% ?" n" x; M& S3 E
  48. Functions                                    Function
    & e0 B5 c4 a  T) z. d+ ?3 s2 D& x0 A0 T
  49. ------------------------------------------------------------------
    3 u& n: g; ^6 ~. p/ S) n- d3 Q
  50. Read_Status_Register        Reads the status register of the serial flash- R* e# c# O1 n) U- ]; e8 p
  51. EWSR                                        Enables the Write Status Register
    ; a: E  V. y2 t& ~7 n% r; u7 ?
  52. WRSR                                        Performs a write to the status register( f: [% R3 i* f( x
  53. WREN                                        Write enables the serial flash
    8 Z; Z! o3 H+ Z7 p
  54. WRDI                                        Write disables the serial flash
    . Y, }2 P9 u0 S% F9 r
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    . s3 ?4 N: n/ a' G
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming. [8 S& t5 u6 n
  57. Read_ID                                        Reads the manufacturer ID and device ID
    " c: r& q2 x! l6 C0 M) h  z
  58. Jedec_ID_Read                        Reads the Jedec ID& C# x, I# T# l0 t
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    . h( p5 u) a. U/ c* v5 `
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    ! r% r6 z+ q1 E. ^' J1 K
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency), v6 a  [+ |' y; Z, x9 {" U4 f
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    , D! `  q/ C8 E; J/ |2 w3 l
  63. Byte_Program                        Program one byte to the serial flash
    9 N( D, l: E1 F) Z
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    4 q- r1 d1 D: v: `" K2 S! ]- o
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation% \8 G# f+ Y  I% G
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
      j0 q6 a" Y9 J7 V1 c& E* |
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    * l. i! r6 h1 N+ h0 S& i" e# H
  68. Chip_Erase                                Erases entire serial flash+ l* F5 P, k# ^3 l# k
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash# l9 L! T' c( H3 ~5 n4 p
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash% j3 M8 J5 a9 f% _- G1 F, E( y4 d
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash4 G6 d) S; W; _! L5 q! u
  72. Wait_Busy                                Polls status register until busy bit is low
    1 z. b: _- X, a
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming! b( s5 w' X" T
  74. WREN_Check                                Checks to see if WEL is set  }7 d- g( ?4 a% m% M2 c
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set  v( M' O3 |+ p# O
  76. : I* a1 c: A5 [! V+ X  d

  77. ) z2 G1 O% v' @/ ?
  78. 0 a2 P8 Y' e$ x- T9 h
  79.                                                                      
    7 O9 a& o' _& N& F. o$ I9 ~
  80. "C" LANGUAGE DRIVERS
    " ^+ v: h0 b" O( n" X
  81. % e3 M7 M3 w, J8 |% X, G
  82. /********************************************************************/- @, o8 E* M  W$ @6 p0 f
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */7 C$ Q7 h5 |1 H8 A9 @" s* g
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */1 S) E9 d* K, j0 V0 b3 ]1 r* |/ f
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    " t& b  z+ |- y/ ^7 E
  86. /*                                                                  */
    + C. z/ N. z/ R9 G& U' h( b% H; \9 f6 }
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    ! |& A9 ^) s1 m9 i% H, j) Z  L
  88. /*                                                                  */$ }* W$ Z" s$ Q# V3 m5 _" n6 G
  89. /*                                                                                                                                        */( E: L; J" Q# V9 |- S9 O, ?
  90. /********************************************************************/
    ' `6 W9 h% \# `4 ?1 `
  91. $ @& O2 o- w7 u6 H/ I% p: x
  92. #include <stdio.h>
    7 z9 @( n2 }5 D2 ~& \% {
  93. #include <stdlib.h>
    2 O: a+ J$ G' }1 ?5 t& ^

  94. 0 @. S* u# q7 X
  95. /* Function Prototypes */$ ]" h, u  q  D

  96. 6 S, K, s( @4 {8 i* {( o) H" C- b
  97. void init();
    : `) m( Q4 A$ d. o+ Q4 H. |) Z
  98. void Send_Byte(unsigned char out);+ y$ L! U" R5 v2 Y( F2 k
  99. unsigned char Get_Byte();
    4 J% r8 R5 O0 W$ C) @
  100. void Poll_SO();
    ( R! P0 j' l/ Y* a- ?0 b
  101. void CE_High();, F" F. g# z+ I0 m
  102. void CE_Low();
    , `( k' Q+ s1 G. }7 W' l9 g: }
  103. void Hold_Low();, q; C( V9 c& b: _; t( L
  104. void Unhold();  I- {* ~0 U6 Z  q
  105. void WP_Low();
    0 x3 q! M# b) u) @, g; u
  106. void UnWP();7 n# k: w( R: W" T5 A9 F
  107. unsigned char Read_Status_Register();4 I# z7 v% }) C5 e# [7 P
  108. void EWSR();& i  a  x& ?( B% v* r; a7 ]
  109. void WRSR(byte);
    3 W' D4 a1 ^/ g0 b8 @5 f" ~8 V
  110. void WREN();
    7 X9 p5 p" L5 r. t* M1 @% m4 ^
  111. void WRDI();
    # G# }- s" C( u! Y3 Z2 }
  112. void EBSY();
    " X  \9 a# n! \
  113. void DBSY();' P) t) d" W2 H5 }+ L# J. I/ Q+ _
  114. unsigned char Read_ID(ID_addr);3 `6 L& _6 D) W9 \3 ?- Q# r
  115. unsigned long Jedec_ID_Read();
    ( Y% I+ F' ]$ D) ?$ c7 C
  116. unsigned char Read(unsigned long Dst);
    $ T& Z  t1 K( V' p8 D
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);7 A) ~, p1 `6 G
  118. unsigned char HighSpeed_Read(unsigned long Dst); - w, i( U8 [" E" V
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);! D5 n: C: t$ x4 k4 J- N. X
  120. void Byte_Program(unsigned long Dst, unsigned char byte);- p( G$ Y. Y/ Q* L" D5 V7 H7 O
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);% `3 h4 G, m8 s+ r) s+ G6 w9 ]0 T0 K
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    # Q, a: x* |5 F, U* P, J+ k
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);0 i, _& C" a% I. j, Q3 |" H8 p1 J
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    5 b9 h2 u3 _% K3 b; o3 f
  125. void Chip_Erase();
    7 D, c: m# y0 d) a9 a4 o
  126. void Sector_Erase(unsigned long Dst);
    & l. O& W0 _5 V; h: q" j3 h
  127. void Block_Erase_32K(unsigned long Dst);0 u+ V4 v1 y+ v& S# g% z
  128. void Block_Erase_64K(unsigned long Dst);
    7 A8 t' Z8 o1 m6 Y" p6 b
  129. void Wait_Busy();
    / P. q! K, V- B9 L9 S& m
  130. void Wait_Busy_AAI();, I* Z% N4 W1 G! @9 n0 c
  131. void WREN_Check();
    & Q* ~1 O( _; V
  132. void WREN_AAI_Check();0 I  f% Y" V: Z1 Q2 p
  133. 1 R# c9 {% g3 r6 G( A0 |
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    0 M% J6 f4 @  T* B$ _4 w

  135. , D6 w7 t1 ]* g- C7 q6 F, ^4 g& m
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    , z) N( s2 z+ o6 j$ A9 u
  137.                                                                                 /* to upper RAM area from 80H - FFH */2 B9 f2 j/ ]( d: H9 D5 Q

  138. ! `" u/ g: `- s/ f2 y# C2 w
  139. /************************************************************************/( g. w1 s; [/ L. K, |7 j6 {$ r4 i
  140. /* PROCEDURE: init                                                                                                                */
    ' E3 L/ K5 ]) \
  141. /*                                                                                                                                                */6 E& l- {: ^5 `" A- ?' O
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    ) W  J6 ^7 R% H; ~$ s
  143. /* setting up mode 0.                                                                                                        */
    ( k/ G& K4 T1 S8 @' c$ Z' G
  144. /*                                                                                                                                                */& X1 d+ Y: x8 l4 r7 h' B
  145. /* Input:                                                                                                                                */2 L8 r8 T! d1 X8 e
  146. /*                None                                                                                                                        */2 f3 S+ t! J2 I- Z( f
  147. /*                                                                                                                                                */, U" D4 M7 S; ~5 g* K' c
  148. /* Output:                                                                                                                                */$ k1 I8 y: _7 O; {
  149. /*                SCK                                                                                                                                */$ q- ]: d1 G1 R& V
  150. /************************************************************************/6 I) j* S% [) U) i) u! G: g: Q
  151. void init()6 [0 w6 v1 F; J  I$ J7 O- s
  152. {. c4 a9 i) @/ g- a
  153.         SCK = 0;        /* set clock to low initial state */
    ; d% q: Y" J9 A8 B; H% Z. B# k
  154. }
    9 v- V: x. u9 d7 E6 W. }* n

  155. / x1 V- n* ?0 _1 f( ?8 Y( n
  156. /************************************************************************/
    ' p& F; h; U3 l) y
  157. /* PROCEDURE: Send_Byte                                                                                                        */! i: t2 u& J/ j- t
  158. /*                                                                                                                                                */
    , V! _& [0 p' b1 [7 S( |, N# [
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    / x" X$ s- E* }8 L
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    * m+ G7 Z% A# n2 n7 i; a! X% w* F5 x
  161. /*                                                                                                                                                */
    . Q3 u9 a. a2 }3 ~7 f( O' P
  162. /* Input:                                                                                                                                */
    ( T. Q4 p- b3 _1 d$ G9 C
  163. /*                out                                                                                                                                */
    , g: T3 ~: n& d, K' ]' z! u
  164. /*                                                                                                                                                */; x; r% l4 O! g9 z  V9 U
  165. /* Output:                                                                                                                                */
    3 G7 E# Q4 @) R0 f( m
  166. /*                SI                                                                                                                                */
    + r- R5 n' x* o8 V, ~1 @
  167. /************************************************************************/! P! c7 C; [3 T! u( F* t$ K: ?
  168. void Send_Byte(unsigned char out)& l3 G7 g+ N8 H; l) b
  169. {% C+ O6 I4 Y+ k2 E5 G8 `
  170.         * }4 A' t$ A& y( l. Z. F
  171.         unsigned char i = 0;
    ( y" X* v# O3 q: @7 F
  172.         for (i = 0; i < 8; i++)
    2 m5 t& Y: `- e- ]
  173.         {& p. K/ K" _" J" Q2 r" j
  174.                 9 q9 j- m2 ~- X% r1 q& z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    + s, t- V2 d5 D" [. Z, d, f5 k0 D6 T
  176.                         SI = 1;8 L( e" w8 s# h$ ^
  177.                 else
    + C( y5 p0 u% S- n% _2 Y
  178.                         SI = 0;                                /* if not, set to low */
    ) Q) {7 M/ V. \* p$ b& P( D3 P% _
  179.                 SCK = 1;                                /* toggle clock high */
    + v2 }& W" @* g8 I
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    5 t5 i. Y7 e. G8 x3 N
  181.                 SCK = 0;                                /* toggle clock low */
    ; J* E& i" \1 q( _* S1 }  `
  182.         }
    . e- Z% j: F. C( f' Y6 {4 F
  183. }
    0 M5 B& z9 P+ ]& }3 K7 O, H
  184. 3 s) O, E6 t4 R: F" F- n" k8 M
  185. /************************************************************************/1 j- y) q' s& h! q9 b: p9 X2 |: x
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    $ J  R% F# B- Z1 Q
  187. /*                                                                                                                                                */& p  s9 j. b# M1 p% m
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    2 j) X2 H( d0 v! v( g
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
      G2 I  J5 d  Y
  190. /*                                                                                                                                                */! a6 M( F' k, z( p$ a
  191. /* Input:                                                                                                                                */
    : d4 u, y! a- C
  192. /*                SO                                                                                                                                */, u+ S) g) |( |3 x0 v
  193. /*                                                                                                                                                */5 _, g& x+ A: e8 ^* P' o
  194. /* Output:                                                                                                                                */
    5 Z) R) ~. M+ ?% B4 D9 x
  195. /*                None                                                                                                                        */" d9 y4 C3 X4 U8 c( L
  196. /************************************************************************/" s" W6 Y, X. o4 h7 b
  197. unsigned char Get_Byte()* X0 g- a) P& t2 U. _2 i
  198. {7 w6 u$ i% y" c
  199.         unsigned char i = 0, in = 0, temp = 0;
    : f9 v( ^8 |  u6 g+ Z1 d4 e
  200.         for (i = 0; i < 8; i++)
    1 v+ t* Y$ X+ A/ d3 ]* E- U
  201.         {
    7 P1 p1 J0 Q0 [' b1 n
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */6 z. W$ f; r5 G  x# }" O6 z2 x
  203.                 temp = SO;                        /* save input */
    & x! }! p. L7 I
  204.                 SCK = 1;                        /* toggle clock high */  A8 a. P" i3 r  z
  205.                 if (temp == 1)                        /* check to see if bit is high */
    ) Z* I- J& \- Y9 R
  206.                         in = in | 0x01;                /* if high, make bit high */: r+ I) J% `: ^& e

  207. 6 e/ C, A5 E7 E/ d, |
  208.                 SCK = 0;                        /* toggle clock low */; R; ?1 k5 k! n. @% P( U
  209. " C' f" g) M" S
  210.         }; b% x7 b( r$ ]6 l6 \* {
  211.         return in;. Y) x; A: b* q2 m; f" E
  212. }
    ' B3 k5 A3 j4 }$ c9 \& _3 E- s
  213. 9 k9 ^) g( W# o* C: p  Y! G8 e
  214. /************************************************************************/
    % h2 y  n2 U  E/ B  C6 j
  215. /* PROCEDURE: Poll_SO                                                                                                        */: R; ]1 M4 q  S' k$ y+ N8 R
  216. /*                                                                                                                                                */
    * ^- ]! p8 B+ H2 x4 `: L! |3 h
  217. /* This procedure polls for the SO line during AAI programming                  */: j) @& F2 ~& M. z& ^
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*// _; y" N! F/ ^  y3 d
  219. /* is completed                                                                                                                        */# a4 w7 z; f- o$ I4 O0 @+ V9 I
  220. /*                                                                                                                                                */
    % v; e! L- V+ M6 w1 \2 K
  221. /* Input:                                                                                                                                */. w8 ], t) K( z$ _
  222. /*                SO                                                                                                                                */
    - y8 F0 y+ H9 ^$ R" W) [0 P
  223. /*                                                                                                                                                */# {- X8 k9 T; t/ H/ }
  224. /* Output:                                                                                                                                */
    " P3 r# ?. \- E) D' c: ^) D
  225. /*                None                                                                                                                        */
    ! b; M; c# Z. @+ S
  226. /************************************************************************/9 C' c" \5 j0 s' k) M! ^  j9 W
  227. void Poll_SO()& p$ d+ f4 D7 i/ ]! S2 s$ c) W
  228. {8 `+ _& F2 l* ~2 B8 `
  229.         unsigned char temp = 0;
    ) w- f, j* X2 r6 }) O
  230.         CE_Low();/ j6 a3 b6 u' J
  231.     while (temp == 0x00)        /* waste time until not busy */
    ! i: W, P; ~1 s6 M, x; U$ O
  232.                 temp = SO;! ?3 _: x/ w( c8 J0 ]" ]) Y# u
  233.         CE_High();& W# i& p1 P+ t& r& w" |
  234. }5 q3 z# Z$ q4 M. r( K
  235. ) ^! M0 \& o& {8 L! N* c
  236. /************************************************************************/  s5 u3 s1 p( B
  237. /* PROCEDURE: CE_High                                                                                                        */6 y& T$ G4 P, d2 u2 ^1 W6 l
  238. /*                                                                                                                                                */
    ' w! L+ d% c. f2 H/ y. K
  239. /* This procedure set CE = High.                                                                                */0 n, L) y! _# I- u# r
  240. /*                                                                                                                                                */
    3 Z, W7 w9 c* O! K  T; k
  241. /* Input:                                                                                                                                */' }  t2 l7 c5 g5 F* c9 _- ^2 J6 `8 _
  242. /*                None                                                                                                                        */
    * ~  d% y4 S; l) e
  243. /*                                                                                                                                                */
    ( H: H: G! i) @4 k7 E$ s0 j3 [
  244. /* Output:                                                                                                                                */$ l' F- T* }4 W. E$ N5 T2 K# u
  245. /*                CE                                                                                                                                */. @5 W! }' V' K* Q( G4 U1 E, P
  246. /*                                                                                                                                                */
    # j+ A- q+ l. p5 g$ P
  247. /************************************************************************/3 H4 s) {7 Y, p; X0 F
  248. void CE_High()
    # k2 e* ~* a( k
  249. {* r/ v& h6 o1 Y: X! y$ l
  250.         CE = 1;                                /* set CE high */
    / `9 J9 k6 G4 c4 P6 r( V
  251. }
    4 I& R2 R6 Q" j. {
  252. * p: S* y# J  K  x, C2 E% S
  253. /************************************************************************/
    , T- v8 l( Z" O9 E5 @& j
  254. /* PROCEDURE: CE_Low                                                                                                        */
    0 {( M3 W# q4 p3 H. |$ b8 r
  255. /*                                                                                                                                                */
    % D) j% {/ A* N9 x# P
  256. /* This procedure drives the CE of the device to low.                                          */
    , h2 m" n* \, e& X3 ~2 }" m! p
  257. /*                                                                                                                                                */  e9 D, Z8 A0 g. P6 A9 x$ ~# k
  258. /* Input:                                                                                                                                */* z) l$ ?$ K$ @1 H, ^
  259. /*                None                                                                                                                        */. w3 g8 D  X# }" Z$ j. m5 a! c9 ~- q
  260. /*                                                                                                                                                */
    - P  ~! ?& L! s" Z9 N' L9 s" t
  261. /* Output:                                                                                                                                */
    # x7 ^9 t! `) I" X0 H
  262. /*                CE                                                                                                                                */
    ; c, J9 L6 m  k6 x" f
  263. /*                                                                                                                                                */1 }5 q: I- ], U+ F6 ?
  264. /************************************************************************/% M; T4 }+ k, J$ e
  265. void CE_Low()
    / b- H- |, N+ f0 u, Z) Q
  266. {        ' g( J  Y9 h. p5 U: v4 m
  267.         CE = 0;                                /* clear CE low */
    " q; \; L2 o6 b: L
  268. }% M" w' H6 O2 m7 [& m. R

  269. ; v; p9 }$ F, R# S* B7 m
  270. /************************************************************************/
    8 G, h% g2 V; @4 U+ K3 @( l# S) `0 U
  271. /* PROCEDURE: Hold()                                                                                                        */
    1 q; m1 j2 z+ Y  U; k
  272. /*                                                                                                                                                */
    ' V& w: I0 N! n
  273. /* This procedure clears the Hold pin to low.                                                        */2 [% ]2 I, T' X9 k$ t- Q% J6 t
  274. /*                                                                                                                                                */
    5 J! ]5 c8 @4 Z
  275. /* Input:                                                                                                                                */
    $ f3 x  o: M4 ~9 _& Q6 _$ a4 Y: L3 z
  276. /*                None                                                                                                                        */) c& ]" b3 N5 A( M
  277. /*                                                                                                                                                */& U: K, J5 O& H, ]  r0 p6 \$ k
  278. /* Output:                                                                                                                                */
    $ a3 }; z- ]: `$ S# N
  279. /*                Hold                                                                                                                        */7 o# \7 P" [! K- I% G
  280. /************************************************************************/
    $ d0 {5 m8 C- T( B
  281. void Hold_Low()6 K: ?4 B! Y9 r
  282. {$ A* ~  [: v/ j. t2 U' ~9 Y
  283.         Hold = 0;                        /* clear Hold pin */$ f' g6 w2 U! Z! }
  284. }
    3 r; v. ?4 F3 Y. \, r
  285. ( K: F  e! _+ W- m
  286. /************************************************************************/
    # N% \* {+ s' z. {
  287. /* PROCEDURE: Unhold()                                                                                                        */
    $ H' P0 n- B9 M0 A
  288. /*                                                                                                                                                */; x; H, H7 g* ^: ?- x4 D( Y
  289. /* This procedure sets the Hold pin to high.                                                        */
    7 K9 [# ^5 c' O% n+ ?* e% H
  290. /*                                                                                                                                                */7 W; M  r: q+ p4 ^7 K7 g5 t8 p6 r# ~. H
  291. /* Input:                                                                                                                                */
    % g* j5 Q  X/ y: S% j2 S" i5 g
  292. /*                None                                                                                                                        */
    - v3 H+ y/ w+ \* O9 D8 M
  293. /*                                                                                                                                                */
    ; w% o- ~/ [  d6 B
  294. /* Output:                                                                                                                                */
    ( O& Y7 W* D/ a* _
  295. /*                Hold                                                                                                                        */
      D8 `: i% {8 U2 U) j, @
  296. /************************************************************************/
    0 {+ s1 }- g6 E0 ^3 D! \6 c
  297. void Unhold()
    , P3 r) y: n2 q: _( }4 H4 B/ j4 Z
  298. {
    6 ^4 l. y' e2 a6 [
  299.         Hold = 1;                        /* set Hold pin */( |2 l  k1 H5 F( {: s& N: U
  300. }
    & \+ c6 n0 V! w9 N: E$ E

  301. 9 K' \2 E6 ?( B  N; h7 j/ K( @
  302. /************************************************************************/0 y9 i) f, B1 R. y: C# ]) |
  303. /* PROCEDURE: WP()                                                                                                                */
    5 E& K' A) d/ j
  304. /*                                                                                                                                                */" F* }- }( B  T. u
  305. /* This procedure clears the WP pin to low.                                                                */, }2 ^8 k) Y8 l2 V
  306. /*                                                                                                                                                */4 D4 B3 ?: O, C& V- ~% k
  307. /* Input:                                                                                                                                */
    + D; A! m$ [& z  _' f: Q
  308. /*                None                                                                                                                        */
    " G9 u9 b, Q& C: }
  309. /*                                                                                                                                                */
    5 `2 t! v+ J& S4 ?9 U
  310. /* Output:                                                                                                                                */2 q3 s# w, M- X. |; z8 N( ~
  311. /*                WP                                                                                                                                */- ^$ W- P3 l) n' l3 _8 S! W5 I
  312. /************************************************************************/- j* }* O$ ~; T* n$ W3 I
  313. void WP_Low()) l* p/ _* U$ R) L
  314. {
    2 a; |& b: x. [2 X3 x
  315.         WP = 0;                                /* clear WP pin */
    9 O, S. v! c& u
  316. }
    5 M: i7 K9 h/ T5 x
  317. # e2 k/ Y% D1 M  T3 B" F- \
  318. /************************************************************************/
    , B, c' H( r2 ~2 j
  319. /* PROCEDURE: UnWP()                                                                                                        */
    8 X& u( U& c* t7 O$ O) q8 ]% j
  320. /*                                                                                                                                                */5 O" x, Q# y* k. A& r2 D- A! y  f
  321. /* This procedure sets the WP pin to high.                                                                */
    / H* |; u% F% l, I7 }
  322. /*                                                                                                                                                */$ P$ p2 v5 ~: W+ _! o& h+ w- k2 x% b4 K
  323. /* Input:                                                                                                                                *// w! W, o; `  {8 V& l
  324. /*                None                                                                                                                        */1 w7 [; P8 O+ Z' U1 q7 i, K& S
  325. /*                                                                                                                                                */# F+ {- ^2 f, I) n$ N7 z, _
  326. /* Output:                                                                                                                                */
    : {' a* A" I3 T2 r' p$ N+ |
  327. /*                WP                                                                                                                                */3 j' j/ f3 P! X- J5 Z4 i
  328. /************************************************************************/
    1 F4 A3 E# X6 R3 h) F4 u
  329. void UnWP()* g+ H/ y/ n/ Y! Q
  330. {: y8 O. F* U- B4 ^
  331.         WP = 1;                                /* set WP pin */
    4 @, G- X% A5 o! F8 i
  332. }
    ! ~7 ]  @! a' A) c
  333. 4 k" B- X1 r% I( s* \9 [* x; @
  334. /************************************************************************/
    9 n+ K$ q2 D5 z, h- `- \2 p
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    6 A$ t3 B# U8 c# I  Q' ~
  336. /*                                                                                                                                                */
    ; Z; V+ E' d' ^: c
  337. /* This procedure read the status register and returns the byte.                */6 v0 |" y: x" K
  338. /*                                                                                                                                                */! k8 U; e: b; |7 m& [4 U  {
  339. /* Input:                                                                                                                                */
    $ v  e6 y, u5 X/ b! ?: l, T. Z
  340. /*                None                                                                                                                        */
    0 T& X# r/ g7 l2 y7 S  }# X
  341. /*                                                                                                                                                */
    - k. X& L1 Q$ {5 m$ f+ \; J" m
  342. /* Returns:                                                                                                                                */5 W& J: C% d- ]) A. v! F+ `/ U
  343. /*                byte                                                                                                                        */! F4 Q6 W1 h* t0 j' g. k! n
  344. /************************************************************************/
    ) `) Y3 `9 {7 t* F+ `
  345. unsigned char Read_Status_Register(): x; J+ h( y2 D$ \$ P
  346. {/ t5 d- C! F: _
  347.         unsigned char byte = 0;# W7 \4 t& F# N1 I: ~
  348.         CE_Low();                                /* enable device */
    " M" O  F  L4 l3 K8 J
  349.         Send_Byte(0x05);                /* send RDSR command */: U# k' B! i. ?; y+ ~0 F
  350.         byte = Get_Byte();                /* receive byte */
    2 q# F1 ?; U8 n+ H
  351.         CE_High();                                /* disable device */* U- a3 h/ |' v- M4 W
  352.         return byte;- L0 }" E+ {4 M( e* u1 {7 j) b) K
  353. }% P2 H; n4 H: ^/ d
  354. 9 _+ D- T% J4 n2 v! t
  355. /************************************************************************/# k/ M& `8 s$ \. v7 A
  356. /* PROCEDURE: EWSR                                                                                                                */
    6 Z4 b1 M6 c; J8 p
  357. /*                                                                                                                                                */
    2 c8 S: U6 e7 }- n
  358. /* This procedure Enables Write Status Register.                                                  */
    2 ~& h5 p; J6 T7 D, n0 J& e+ _6 Q; Q& r
  359. /*                                                                                                                                                */5 X' m: e* d/ ?8 c9 I
  360. /* Input:                                                                                                                                */* ^. W; Z; L& i
  361. /*                None                                                                                                                        */2 _9 t% |  M) s5 }/ v+ y
  362. /*                                                                                                                                                */2 Y  h4 A  b1 Q/ ]/ v( o
  363. /* Returns:                                                                                                                                */# r2 v' i. n7 n! N
  364. /*                Nothing                                                                                                                        */
    ; ]' \& D' J4 x& r4 h8 x
  365. /************************************************************************/
    7 G$ k* i+ G- T& j8 K; E
  366. void EWSR()2 n# [3 b! L2 y2 I7 q( v
  367. {
    , R$ c5 l$ t% r
  368.         CE_Low();                                /* enable device */
      ^, G9 J  @7 Q6 N  X- A
  369.         Send_Byte(0x50);                /* enable writing to the status register */, U2 `4 h; i7 U7 {- c, e" m4 Q
  370.         CE_High();                                /* disable device */7 W$ n5 N2 `9 D, z. G
  371. }3 p) t6 q, ~2 I9 D6 g
  372. - O$ H3 U, d3 p- `% k
  373. /************************************************************************/
    % P( s+ @& S, i  U, x. S0 {7 H
  374. /* PROCEDURE: WRSR                                                                                                                */$ `1 w# D( G) I. _2 W( v6 U
  375. /*                                                                                                                                                */1 E* r/ T5 X4 W- G4 _
  376. /* This procedure writes a byte to the Status Register.                                        */4 S0 ~( |% t0 B. ]/ U4 J
  377. /*                                                                                                                                                */' d. c* [$ u7 q$ k& I
  378. /* Input:                                                                                                                                */
    % A1 U2 L) p+ k* Z* R$ s8 n5 u
  379. /*                byte                                                                                                                        */
    * `2 `9 h( p, Q; `, N' R7 q5 u' C1 \
  380. /*                                                                                                                                                */
    + |3 H2 _" i6 o% _' @* L
  381. /* Returns:                                                                                                                                */: b6 S' q8 p- ]7 k, {5 A
  382. /*                Nothing                                                                                                                        */9 H7 l4 x" T5 D) {7 a
  383. /************************************************************************/& l7 z. U8 Y( M, W
  384. void WRSR(byte)+ D$ _/ n9 E; G2 W+ f
  385. {) ^9 ]4 J4 w9 Q  I! [9 t6 r/ l* t* e
  386.         CE_Low();                                /* enable device */( y0 x7 u. y2 s/ v2 q
  387.         Send_Byte(0x01);                /* select write to status register */
    4 I  x7 [! }9 ^$ V
  388.         Send_Byte(byte);                /* data that will change the status of BPx ( U+ q" S' r6 R8 T
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    : m: q6 t- Q! Y& x! w# f
  390.         CE_High();                                /* disable the device */
    + s6 f. E' Z( L' _$ v9 h5 z
  391. }
    6 u  G! z( s$ ^* w3 J7 ?
  392. $ o4 l) N, [' ~; @
  393. /************************************************************************/
    9 ^7 n; [* c# V, c* }$ J2 Z6 e
  394. /* PROCEDURE: WREN                                                                                                                */
    , [/ U: I! `5 |! V  F
  395. /*                                                                                                                                                */1 Q9 k& @: T, U
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ( t6 [5 J/ W2 d: u! X/ l: k
  397. /* to Enables Write Status Register.                                                                        */
    ( I/ |( H: E. O8 z4 z  ~5 I
  398. /*                                                                                                                                                */9 L& `4 C- _) t8 x
  399. /* Input:                                                                                                                                */# [+ D& L1 t. _3 U1 ^1 G) Q; m- h" Q( n
  400. /*                None                                                                                                                        */
    ; t1 @8 M4 k9 m: e* [- q# g2 B
  401. /*                                                                                                                                                */# k  ]' t+ m+ O- j# C' }
  402. /* Returns:                                                                                                                                */; m' s1 O% H3 l2 x3 A! s& u
  403. /*                Nothing                                                                                                                        */
    $ k- y. k2 t, M5 e
  404. /************************************************************************/
    ! s5 O/ t. Z1 G7 E: n+ D
  405. void WREN()0 {& F& y5 Y( R. f* F
  406. {( Y& S% F. E- O
  407.         CE_Low();                                /* enable device */% u) ~0 Q$ w# g
  408.         Send_Byte(0x06);                /* send WREN command */
    7 Y# R) r  C5 y
  409.         CE_High();                                /* disable device */( e7 i: Y0 d; ]/ r# K
  410. }
    5 N4 w1 ]; o/ i) _$ N  M' ^

  411. $ E$ C" j$ @* s% ?1 f. i
  412. /************************************************************************/. {# G. L4 A$ A$ J% j. P  d
  413. /* PROCEDURE: WRDI                                                                                                                */
      T, K3 ~8 h/ m
  414. /*                                                                                                                                                */
    , |# M0 W7 |  L% ^- @
  415. /* This procedure disables the Write Enable Latch.                                                */
    2 r8 n: [0 k2 ?1 @. N; a
  416. /*                                                                                                                                                */
    ' U- |+ p9 F6 \
  417. /* Input:                                                                                                                                */5 R9 {2 m6 y( m! U' r6 Y6 l
  418. /*                None                                                                                                                        */
    2 Q, D* o" Z, O* ^( J
  419. /*                                                                                                                                                */
    & T, B* d3 M3 \4 S# {
  420. /* Returns:                                                                                                                                */
    & `. D) @! `' `* b3 y6 N/ i
  421. /*                Nothing                                                                                                                        */: R6 _5 h% ]: C/ W& o
  422. /************************************************************************/& [6 {3 c) E/ @4 T- y6 [
  423. void WRDI()
    1 z- B0 a4 K- C6 m. U$ ^+ v
  424. {4 T$ V' Y% p2 t8 H3 G( P! U
  425.         CE_Low();                                /* enable device */
    1 x3 n/ X1 q6 L6 d- D
  426.         Send_Byte(0x04);                /* send WRDI command */. q0 D2 @% k4 K5 Y7 @' I9 O! {% ^" e
  427.         CE_High();                                /* disable device */
    9 G/ f& i! ~" ~
  428. }" ?' U1 `2 d. j

  429. ) q8 i* k0 y7 Y8 ~
  430. /************************************************************************/
    5 e$ D( w! u4 e5 M$ L# T3 b
  431. /* PROCEDURE: EBSY                                                                                                                */
    ) O+ M% X9 L7 s/ h9 U
  432. /*                                                                                                                                                */
    1 o& O9 @5 S* z) D# i
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */: [- |! b+ u9 U: t# Y
  434. /* programming.                                                                                                                        */
    2 D6 w! D/ j/ D- @7 R& z5 \2 s
  435. /*                                                                                                                                                */) V# w' w8 k' v7 `7 P8 o
  436. /* Input:                                                                                                                                */5 V  ]" \* u. l2 \  E7 n
  437. /*                None                                                                                                                        */
    ! c% n# l1 ^5 z. e! ^8 Q
  438. /*                                                                                                                                                */
    ! d" H. }8 l; |  s
  439. /* Returns:                                                                                                                                */  g: W3 p$ j9 Q% J9 P% \+ ^  Y
  440. /*                Nothing                                                                                                                        */
      M" ^/ A2 w$ F7 U1 c4 i( o
  441. /************************************************************************/1 N" m" q7 a. {1 e, y% G
  442. void EBSY()) F9 P) S$ ~+ P1 }2 S
  443. {
    7 d- Y0 Y; D5 \  ~- ?
  444.         CE_Low();                                /* enable device */2 u5 z  G( r6 l7 P% A
  445.         Send_Byte(0x70);                /* send EBSY command */
    4 L  G7 U6 P& p
  446.         CE_High();                                /* disable device */
    0 x0 Y7 a5 f& m
  447. }
    0 m1 q/ ?) d1 }( Z" P5 [; Z

  448. & Q! k% S( v5 O5 c$ L4 |* y) u
  449. /************************************************************************/
    / V& W7 i8 i3 B  ~* n0 U2 n1 D
  450. /* PROCEDURE: DBSY                                                                                                                */
    + {1 ^. A( s* S
  451. /*                                                                                                                                                */
    ! @' U$ p" a; W5 F1 A0 ?
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */5 J0 d" t& R9 Y( a: g( D
  453. /* programming.                                                                                                                        */; T) k. H1 [1 E+ b; J0 \
  454. /*                                                                                                                                                */
    - ~7 A) }- N1 _! E* v5 Y2 C
  455. /* Input:                                                                                                                                */  u& M. A9 ?/ i1 g
  456. /*                None                                                                                                                        */
    & T9 ^8 K1 O9 V( J  I* a
  457. /*                                                                                                                                                */
    . S: Z8 k) @6 T( D$ y2 \
  458. /* Returns:                                                                                                                                */& L, X- D) h8 S4 ^$ g
  459. /*                Nothing                                                                                                                        */! M% _- @- O3 B5 A( h' i+ u% @
  460. /************************************************************************// O$ U3 U* a# f, k5 c3 P# s
  461. void DBSY()5 k9 s* f. `" F0 [/ A# k' ^
  462. {& v6 H/ O, T. C, N4 v+ P4 I
  463.         CE_Low();                                /* enable device */
    ) J* e1 I. [! R/ g0 u" F! D  ^  e
  464.         Send_Byte(0x80);                /* send DBSY command */
    0 Z# I- Z' K# V" T& L) w+ p2 w; B( w
  465.         CE_High();                                /* disable device */
    / v7 o  B7 z" v/ ?* M
  466. }
    ) R% t1 c$ H9 ^8 Z8 [$ b0 b2 ]) A
  467. , {% w& i# ?4 e& \7 c! O
  468. /************************************************************************/) T! P& m3 o  g; z5 V1 H6 r3 m
  469. /* PROCEDURE: Read_ID                                                                                                        */
    , |. H# r7 s) t' h
  470. /*                                                                                                                                                */+ z- R: [: y. ~8 |
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    7 Y# D7 a3 v4 f
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    5 B6 W9 Z( c2 O% Z
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    % x6 G. E$ L' q' F1 m( S
  474. /* whether the device outputs manufacturer's ID first, or device ID         */! Q" M0 b/ R; W  W8 V9 j
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    & I3 i  [, k2 J( F' `3 R: X: x2 Z0 A5 U
  476. /* variable byte.                                                                                                                */
    , I( c5 y+ U/ P
  477. /*                                                                                                                                                */
    : S- d( Z( \) n( z: t
  478. /* Input:                                                                                                                                */
    ; y" L! e5 k. J- ?2 T) }! R/ e
  479. /*                ID_addr                                                                                                                        */1 _1 v6 K( u9 C$ F3 ~
  480. /*                                                                                                                                                */5 F% ?; J9 v( j
  481. /* Returns:                                                                                                                                *// Z& O0 O3 H2 r; M3 i0 n1 F. q& d
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */2 y5 m2 z# i7 |
  483. /*                                                                                                                                                */9 Y) C& v" ]" D
  484. /************************************************************************/
    ) G$ V) t* u+ S9 y9 r
  485. unsigned char Read_ID(ID_addr)
    : I  B  R* ?: d$ |! k
  486. {; |& k# @- U, {( V
  487.         unsigned char byte;
    4 Y* w' p* h* V+ P1 N
  488.         CE_Low();                                /* enable device */
    . E/ u7 l5 s! Q& v
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    8 O' u5 i* H8 @% {( z' r4 x
  490.     Send_Byte(0x00);                /* send address */
    6 f9 \7 o! }: R% }. X5 Z5 V
  491.         Send_Byte(0x00);                /* send address */) F# ]0 m' J) M4 i2 Q" @: x
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */: M3 F. z. K* G
  493.         byte = Get_Byte();                /* receive byte */
      k* o. i4 R& H% d
  494.         CE_High();                                /* disable device */
    7 Z8 p, E0 ?2 f7 @6 j
  495.         return byte;
    7 N( f1 `3 R, r6 d9 o9 z0 o
  496. }& m! n; L  P- ^) n; p, }" d

  497. 2 Y$ O- ~, B# X$ ]" _. |, N9 j
  498. /************************************************************************/
    6 [  M! i0 |) j
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    / D( J' R5 q* _* N  b4 l
  500. /*                                                                                                                                                */  P; X/ L* l( A0 ~0 K/ U$ \
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */, H% Q! R% W  Y8 |/ k" Y
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */9 w- Q  u7 {9 Y9 q; N4 ]
  503. /* Please see the product datasheet for details.                                                  */! O' I) e7 s* d
  504. /*                                                                                                                                                */- g3 J( `$ {' a1 W6 o
  505. /* Input:                                                                                                                                */
    ' E7 f: Y/ l. F  U+ G
  506. /*                None                                                                                                                        */" g. z, a& J& {
  507. /*                                                                                                                                                */. n6 U' Y# v8 x1 n( @
  508. /* Returns:                                                                                                                                */
    ; x) s" n0 g" b% @
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */( x  J1 _. r1 E+ u# S1 A
  510. /*                 and Device ID (8Eh)                                                                                        */
    : [+ V% t( J, {* |" m* j; |
  511. /*                                                                                                                                                */! b0 s. n( J7 R: ]3 _$ N8 r
  512. /************************************************************************/
    " M9 \% D, T  @& ~4 H) g) D
  513. unsigned long Jedec_ID_Read()
    , Z5 i" \' t& U& C" c. J
  514. {' T. Z1 d! ]+ z, D
  515.         unsigned long temp;3 i$ Q# l! k5 t) s- ]% g6 T( E
  516.         ! i2 }+ m5 M! r& `3 W) Q9 Q
  517.         temp = 0;
    7 e' s+ l, w0 F5 \. p

  518. , }- E9 K8 @2 F
  519.         CE_Low();                                        /* enable device */% L4 _) y1 |, s' Q* K- Q
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */; m, r2 f. Q+ V
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */5 c! |' A, E2 M7 w' `
  522.         temp = (temp | Get_Byte()) << 8;       
    ' ^1 `( s; I# m/ s8 k* e. m- d: f/ x
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */% \! y' y- Y6 D" v2 d. b$ v' G
  524.         CE_High();                                                        /* disable device */
    # X# ^9 V' a/ @# P

  525. " S, d. h1 k9 R+ }; W# n
  526.         return temp;
    ; I! j0 J- C1 {0 ^6 Z
  527. }- r5 a% l/ n; O' D0 b+ `

  528. & O7 V2 T& ?' E6 n; D8 O3 S1 I: Z
  529. /************************************************************************/
      @: l$ C# ~5 s5 m9 Y5 Y7 o
  530. /* PROCEDURE:        Read                                                                                                        */, l2 D) e- z9 I; }! R
  531. /*                                                                                                                                                */               
    % O8 [. {6 o% ]( ~
  532. /* This procedure reads one address of the device.  It will return the         */* H3 D6 ?6 ]/ @" X
  533. /* byte read in variable byte.                                                                                        */
    4 B# K  {/ L6 p: `7 j0 n
  534. /*                                                                                                                                                */
    & O& {- V" `2 \' W6 l
  535. /*                                                                                                                                                */
    3 `% T: g( W5 R6 X
  536. /*                                                                                                                                                */9 q8 Y8 r' t/ b2 b' E# a3 x
  537. /* Input:                                                                                                                                */# ~# A1 ]6 B) X# q9 O  ]
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        *// S+ E7 d0 A0 r& u9 f4 J/ n4 _9 _
  539. /*                                                                                                                                      */+ l, i9 n3 F, A. ]7 P
  540. /*                                                                                                                                                */3 ]" K7 A  j( [+ ^2 K5 A+ @+ C
  541. /* Returns:                                                                                                                                */+ y: y2 f5 P% \0 z* ?6 F, x- p- C  }
  542. /*                byte                                                                                                                        */# L5 K5 k8 I' ^! G- U2 \* ~" Z
  543. /*                                                                                                                                                */% B. V% ?' V4 Z0 K; |
  544. /************************************************************************/; }1 S  e1 k8 G7 {* q6 P
  545. unsigned char Read(unsigned long Dst) * `$ d# G: J8 j7 F; A
  546. {5 i9 k: t) N' S9 B! O- K
  547.         unsigned char byte = 0;        8 \+ F2 h  G% I. i, _2 B

  548. 6 a5 t4 y' J, q; r9 U$ ~! g
  549.         CE_Low();                                /* enable device */
    1 l% d/ X0 j$ v
  550.         Send_Byte(0x03);                 /* read command */
    0 S6 t6 o# h' w# q3 T3 R* s
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
      O! L, X, Y3 j' w9 i# O
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 F8 V7 j6 N3 g1 ^. [  v9 w
  553.         Send_Byte(Dst & 0xFF);( B+ H, G# S% B! g' v: g& {
  554.         byte = Get_Byte();5 C" S& h  B; p
  555.         CE_High();                                /* disable device */! f1 D5 |- b# h+ ^# H# ^7 @$ O
  556.         return byte;                        /* return one byte read */* E( R/ z( Y2 h: A9 \" F
  557. }
      p9 B8 C  }) B

  558. 5 e( C6 Y  K6 W$ i9 T# q3 {2 C/ b
  559. /************************************************************************/2 ~* d& O9 o2 y( U5 V3 R
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    & T7 u0 l8 K" y+ B2 ]# o7 C$ s
  561. /*                                                                                                                                                */               
    " G" e3 J+ K( O) `) O
  562. /* This procedure reads multiple addresses of the device and stores                */# s7 c' o4 D) u7 d3 G. P
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    1 O( k# h' A+ }/ b% }  a
  564. /*                                                                                                                                                */
    5 S: f: }9 R, N* e1 y
  565. /* Input:                                                                                                                                */2 Z) c8 z4 ?  r9 P* e/ b3 o7 x
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - b: r) H: g$ j+ R9 g
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */: g! W0 T; `$ S) p
  568. /*                                                                                                                                                */
    7 Y3 K7 Q/ Q7 a- a, |1 W/ S: E
  569. /* Returns:                                                                                                                                */# o) X0 y: _% F+ k1 a' e
  570. /*                Nothing                                                                                                                        */
    0 b' \6 T$ I# N
  571. /*                                                                                                                                                */) a! k& \) f5 L9 d' b
  572. /************************************************************************/
    - W, [2 v; ^- N# n$ A
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)3 @) l- z' f$ N% d
  574. {! e  d! p" h7 l  L
  575.         unsigned long i = 0;/ @# b" s, I. ~$ f& C2 k. t
  576.         CE_Low();                                        /* enable device */' S! M: E  R% ]( b8 Y
  577.         Send_Byte(0x03);                         /* read command */
    ) j/ c* b. p- \. m4 T3 X
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 {- b- v4 ~: w& {3 e& e
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));( q, V/ O, N' V) ~, E
  580.         Send_Byte(Dst & 0xFF);0 ]# D* X5 N; b- T3 G7 Z
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    & A* f9 S6 ]+ e2 d( i
  582.         {
    . Y: p+ m# n7 E$ {4 z) K
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */$ Z; m' G: k. @2 e2 x1 w8 R" V
  584.         }* w; |, |$ g0 ?( _2 A! Z
  585.         CE_High();                                        /* disable device */
    " ?$ h4 k$ i$ w7 Q8 T; |1 e4 \

  586. 0 P# U1 z, i+ A& ~: f7 \
  587. }
    4 ?4 P. ?! n$ g  V- |$ u

  588. . o3 H! U8 P! u5 s# h# ]( Q
  589. /************************************************************************/# M8 y# A( ~/ E7 C" Z! a
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    7 N/ Z( F: v' b  n9 u: y
  591. /*                                                                                                                                                */               
    % P5 `( j6 o% ~8 b; q7 ~
  592. /* This procedure reads one address of the device.  It will return the         */( d3 J4 S. ~, T5 W6 o1 P- N
  593. /* byte read in variable byte.                                                                                        */
    ( X3 F* V- ~# a6 _: V4 D# n+ H9 D
  594. /*                                                                                                                                                */# h' y  S. ~9 O3 Q' h* u& w' `1 G# ?
  595. /*                                                                                                                                                */- U3 D/ n/ Q( w  B9 O6 g2 ?
  596. /*                                                                                                                                                *// X5 u6 E7 R* }# e5 P
  597. /* Input:                                                                                                                                */. r  \: k0 i- q8 r$ t( `# q' e7 v
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */. y" h: f! S: K' V! e* }( S
  599. /*                                                                                                                                      */
    + @. t6 I  G8 J2 H- U
  600. /*                                                                                                                                                */. I8 V' u) W# t1 `" `
  601. /* Returns:                                                                                                                                */
      g# e, {3 [  n8 z1 P9 g+ j: `
  602. /*                byte                                                                                                                        */
    $ L# F, e6 R7 P" v: F1 y
  603. /*                                                                                                                                                */
    0 i% W* e( b' }$ w. s  g
  604. /************************************************************************/
    ; R# i) O! H) K( l) s
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    4 L6 T! }0 n% I$ e( {
  606. {
    ! e% q/ |  y, k# X
  607.         unsigned char byte = 0;       
      ?8 _/ q( y4 @! o0 t- ^
  608. ' ?3 z4 T* ^! o' S4 a
  609.         CE_Low();                                /* enable device */1 _3 |  u& a6 t0 E
  610.         Send_Byte(0x0B);                 /* read command */1 l) E* y% Y* I% i6 W
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */4 s+ x1 Q7 x6 o/ L: t# n
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % X# C6 a: K% ]9 V" O
  613.         Send_Byte(Dst & 0xFF);  F! g3 \1 P  w" U5 h
  614.         Send_Byte(0xFF);                /*dummy byte*/
    $ F2 m- }$ R0 j/ R# q# J7 X
  615.         byte = Get_Byte();8 M0 t: t1 G2 g& Y
  616.         CE_High();                                /* disable device */, S& p  W( R/ G5 v
  617.         return byte;                        /* return one byte read */5 ~6 [1 `: `: B9 d- _$ K5 D
  618. }
    * p; Y0 _/ D5 S7 B

  619. % H' Y- Q- u0 Z5 U! @, g
  620. /************************************************************************/' V, I, H8 T# J) @6 A# v$ r/ Q
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    ! b6 \/ z3 _0 ~1 K. G9 Z
  622. /*                                                                                                                                                */               
    , m  l: F3 P! \) c) \; c: Y1 A
  623. /* This procedure reads multiple addresses of the device and stores                */
    ! V) U' e$ I* ?
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/: t: r7 T9 J9 Z8 ]# e2 C- t
  625. /*                                                                                                                                                */
    ; B- m8 C. A0 b% p
  626. /* Input:                                                                                                                                */
    . J5 N2 L4 {8 g
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 ^0 v/ M. y+ Z2 G
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    - Y2 L% K$ ]% Z
  629. /*                                                                                                                                                */8 J# J5 N! U, M  j
  630. /* Returns:                                                                                                                                */- b; s1 A- C7 C: t  _0 ]
  631. /*                Nothing                                                                                                                        */
    , o' X# e1 B# g5 f; l
  632. /*                                                                                                                                                */
    * F/ Z: w4 u* Q
  633. /************************************************************************/
    5 E$ ^, u6 r+ l: h  l, p
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    0 g  P5 G2 b$ r# a
  635. {  D- W4 Z* O; J! `3 P' J$ _: R8 r
  636.         unsigned long i = 0;% V+ g; D0 p7 V( q
  637.         CE_Low();                                        /* enable device */
    / f4 L9 Y' q" F+ f0 L
  638.         Send_Byte(0x0B);                         /* read command */
    6 w  ~3 N, {3 U- A. f3 T; z$ w
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 G8 Q' m$ c9 O. s: \% J4 i
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ Q  K& ?8 N# p' W7 ]6 r8 K5 ?
  641.         Send_Byte(Dst & 0xFF);
    + Z& Q4 I" I1 @) O
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    - G4 r. V" U8 s. H! Y2 U0 M3 v
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    9 }, e% i# g, R3 b
  644.         {; O5 h4 W: |+ r/ W& C/ r5 c! s+ m
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    + ^0 W2 a! t9 m
  646.         }
    & \4 U  x' D8 ~1 h5 n
  647.         CE_High();                                /* disable device */# v7 q8 n4 i9 V+ }! l5 O
  648. }
    - t- }  l5 {. ^4 D; o9 ~

  649. ) p5 ~/ }% T3 b4 Z, z4 }6 t! ^
  650. /************************************************************************/
    * \- S$ u7 o+ R9 a0 R0 \
  651. /* PROCEDURE:        Byte_Program                                                                                        */$ O: s8 W0 \. ~$ S4 ~
  652. /*                                                                                                                                                */
    - q. ]3 {9 s' Z
  653. /* This procedure programs one address of the device.                                        */
    , c6 d7 S7 A2 o) ^! q6 e/ Y
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    " H" A0 t/ l) }# e0 N$ ]" G
  655. /* block protected.                                                                                                                */
    , L2 U( {, a- ?4 P$ X3 h0 R0 p
  656. /*                                                                                                                                                */
    3 P; G/ X- P: j+ X+ @5 o! {% _
  657. /*                                                                                                                                                */
    / Q; A& a6 r% H& V( S
  658. /*                                                                                                                                                */
    1 [! n3 t- l& C1 S' v* v& x
  659. /* Input:                                                                                                                                */3 F: s4 E( i2 Y, o5 C! m; |
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * g. d' q3 v' B
  661. /*                byte:                byte to be programmed                                                                */( v& X1 c3 w! R
  662. /*                                                                                                                                      */
    2 c+ q2 z5 O+ B6 J* |
  663. /*                                                                                                                                                */( M( D* V8 F9 t7 _# |; j
  664. /* Returns:                                                                                                                                */( A) N/ L6 o  c) x7 B$ p
  665. /*                Nothing                                                                                                                        */, p+ k% ~; r. {' L
  666. /*                                                                                                                                                */
    : A# [; |% P2 m: y5 l% X) {* Z' T9 `: ~
  667. /************************************************************************/, \4 e6 O& s: L( X% N" h
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    $ o8 \; \' z0 e
  669. {6 \8 h' l3 {4 P% `8 Z- c
  670.         CE_Low();                                        /* enable device */
    * X' n* Q0 ^: ~3 x
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    $ J) I# ?& a) _/ `4 i& H
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
      q  y* ~0 l7 d# w: G$ F2 R
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));' ~1 t1 H5 G- m! p# {* ~' Q
  674.         Send_Byte(Dst & 0xFF);% p) {) x" J6 H4 q  |+ `
  675.         Send_Byte(byte);                        /* send byte to be programmed */, O4 i6 L7 Z9 i- w& Q3 ^0 U
  676.         CE_High();                                        /* disable device */
    2 ?& P8 L: ~) J6 f5 P( B6 q
  677. }
    ( Q3 L. i0 k9 f9 ~" b
  678. " D4 c3 i- s5 n; j7 {% G
  679. /************************************************************************/
    ) [0 i  Q) K3 j& n
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */0 }" d' S- a. {" D' }7 T% N
  681. /*                                                                                                                                                */
    ! n( [# j5 r# i
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    0 _$ F% d2 x& k: ^
  683. /* the device:  1st data byte will be programmed into the initial                 */
    * p1 q: ?! |( o" y7 f
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */1 m' a6 u5 Q. _  ^
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    - b5 ^$ d3 T$ @  G6 T* a$ A
  686. /* is used to to start the AAI process.  It should be followed by                 */
    ( q- Q" P" o7 c4 |* ^2 G$ L
  687. /* Auto_Add_IncB.                                                                                                                */' x4 [% _; D9 a
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    ; p+ r5 z+ V! X3 K: l$ H( [& x
  689. /*                                block protected.                                                                                */
    & |- `* u- j2 o) |. z; N
  690. /*                                                                                                                                                */6 d$ S5 b) \* @+ K2 g$ X2 R" a' ^
  691. /*                                                                                                                                                */
    % p  \5 ]) l$ V
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    6 {! o9 \7 R, g* f; X
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */" P( \" |/ ~" N, e+ _0 A& D+ Y
  694. /*         unless AAI is programming the last address or last address of                */' D0 {, u# d& r) ~8 l. E
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    6 X6 D! w) f5 E. A3 F& q0 s+ R: ~
  696. /*                                                                                                                                                */
    7 u, n. Q$ x0 \6 Z
  697. /* Input:                                                                                                                                */
    1 A& m$ e  I+ B2 e  U5 `
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 @$ g( ~9 D# }. }. X7 @, d( T) g
  699. /*                byte1:                1st byte to be programmed                                                        */
    9 D5 c1 W; S% D5 Z, q* Z* ^
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ' l+ n& u, g% Q# m  _4 g
  701. /*                                                                                                                                                */1 I1 i: F7 s: B5 ^, ]6 i& e
  702. /* Returns:                                                                                                                                */1 N8 a5 p6 a: f7 `/ m
  703. /*                Nothing                                                                                                                        */
    : W; `5 q8 ~3 @4 |* b$ {
  704. /*                                                                                                                                                */7 T0 k9 L: P' y3 @
  705. /************************************************************************/- w* L+ B* A4 f+ k* o; w
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ( Z. i' n: A& v( N
  707. {1 _. ^: G  k1 X+ y; s" M5 b; d( K
  708.         CE_Low();                                        /* enable device */
    4 {, P8 x0 w, L3 c
  709.         Send_Byte(0xAD);                        /* send AAI command */; V2 v! U5 d  l4 d' X0 b
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ y( I- t) T6 _- d
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & o. I" j  ^% i( P' M
  712.         Send_Byte(Dst & 0xFF);
    & k/ v6 A- e- s0 R3 Q
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + d6 G7 B0 s; z
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */( @9 v- I6 I, v" z! Y& g* {
  715.         CE_High();                                        /* disable device */
    $ L/ ^2 Y- e' C6 L
  716. }1 u7 z' _# ?! M' m. W

  717. 1 O, H3 H3 a& x! u
  718. /************************************************************************/& C; ]+ e5 t+ o  t5 m
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */. B+ a; U% {' {( z' R
  720. /*                                                                                                                                                */5 z* g5 \- t# @* W
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    + o: X1 Y3 p  ~( |2 n9 z
  722. /* the device:  1st data byte will be programmed into the initial                 */
    % H& x2 h# P- u8 [8 |2 T
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */+ v( Q8 l7 X: V. @; j1 K  ]
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */4 I" ^$ }, \2 w0 _! i
  725. /* is used after Auto_Address_IncA.                                                                                */3 J0 J; X5 L. A' {
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 ~( e8 B% N, i" W2 x( O1 }( u9 K
  727. /*                                block protected.                                                                                */& w. ^3 n& b' _
  728. /*                                                                                                                                                */& I; w' w0 H2 E
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    2 h% I, f+ C, S3 s8 R! d* m
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 *// B$ `/ V1 Z" c8 p  h
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */5 ^# n: {8 j7 j9 h' J! x9 _
  732. /*          to exit AAI mode unless AAI is programming the last address or                */0 }$ u5 }  P5 u4 S% n. K* }
  733. /*         last address of unprotected block, which automatically exits                 */
    0 r3 J- [  ^  M% ]4 n) S: M1 N
  734. /*         AAI mode.                                                                                                                        */4 e2 U. o: t# a4 ?
  735. /*                                                                                                                                                */3 t0 o1 F* n2 w1 Z0 Z/ b
  736. /* Input:                                                                                                                                */! J! X, `2 }; D9 q* i
  737. /*                                                                                                                                                */2 K; ~5 L  Z/ X2 y
  738. /*                byte1:                1st byte to be programmed                                                        */7 X  \, M8 d+ {, Y7 F
  739. /*                byte2:                2nd byte to be programmed                                                        */9 W! K% N# S8 ]' b. Z
  740. /*                                                                                                                                      */* i+ X7 t% P' P
  741. /*                                                                                                                                                */# i( w2 J( a2 x, D: p7 F. D9 E
  742. /* Returns:                                                                                                                                */; E6 B& [! `3 K: B" z; ^1 |
  743. /*                Nothing                                                                                                                        */. i# U3 J) k0 M" [& y; u- s
  744. /*                                                                                                                                                */. H6 D; Q6 q; K' I, Q. y" ]' Z
  745. /************************************************************************/
    - G8 y! H+ n: ^: H" R8 f, w9 R
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)) t3 i' Z! z  w$ u; L- b
  747. {6 p! }& V; @) g6 |3 ^% C
  748.         CE_Low();                                        /* enable device */( N3 K" _  I& ]- J. T! d+ K
  749.         Send_Byte(0xAD);                        /* send AAI command */
    0 a# V$ U/ X  z9 t" b1 p' w0 |8 u
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    7 W7 O  O  U9 G5 M6 s9 [; ?+ I
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( m: v" _6 n2 u! g9 C0 P7 \
  752.         CE_High();                                        /* disable device */
    ' M8 x9 q- _  G4 l
  753. }( j) Q6 o& P( J1 w$ I2 G( M2 X
  754. 5 Q' `7 p/ {" }/ e3 D
  755. /************************************************************************/7 b) N0 ~! q* ^- c2 r/ m/ T. F; r
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    8 _1 p* p' w  y( n, m  @
  757. /*                                                                                                                                                */
    9 o! K* T7 M! U- R8 y& i
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */1 D2 j/ k2 z+ A" b
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */1 C0 X+ L% [1 s2 X5 L, m7 \& @
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    7 u6 h2 C$ z6 h4 C3 K$ s
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    / d  {! e$ u0 p" g( w6 @" K
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */* B1 F$ U$ g6 b( P8 N% h+ x" U
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ' M  ~( g2 L9 a" E# s" w8 Y
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; H5 R! M; t; j5 ]  I. Y8 ~7 B
  765. /* Assumption:  Address being programmed is already erased and is NOT        */, ~. N. ]' \2 q1 [; S- ]( B' d0 L
  766. /*                                block protected.                                                                                */  }' Z! E6 T1 W$ w7 e
  767. /*                                                                                                                                                */
    5 ^) G. ]) y5 d. U; ^: o; W
  768. /*                                                                                                                                                */
    / j8 j/ `) K- ?
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    8 o# X& P8 @# X, p2 a
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */+ E) A' F( S, m3 N  |2 S; M
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. P3 S. m% Z6 K) g* J5 R9 w
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    : y# c  v. z0 G% N4 P! O
  773. /*         last address of unprotected block, which automatically exits                 */
    - W. w) ?+ K9 e: \$ N/ Z/ Z, B: w
  774. /*         AAI mode.                                                                                                                        */+ I! f; N* B% ]" T3 H/ i
  775. /*                                                                                                                                                */
    6 Z* a" n( J$ P! w, M7 M  ^, s
  776. /* Input:                                                                                                                                */: o$ W3 a/ p- H. c) _7 z- P
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 g4 |/ x! B. h+ c( U
  778. /*                byte1:                1st byte to be programmed                                                        */
    7 c& H7 l* H: c! h# p( z0 V3 [: Z
  779. /*      byte1:                2nd byte to be programmed                                                        */0 O% V: \1 l7 Z3 E# l% l7 ]
  780. /*                                                                                                                                                */. o: P' s. N" ]0 M* c8 Q
  781. /* Returns:                                                                                                                                */# O, c, Q7 S# k( j7 x4 I
  782. /*                Nothing                                                                                                                        */
    2 H, K8 |, A, f
  783. /*                                                                                                                                                */4 V" S8 p  i# g4 t, Y
  784. /************************************************************************/
    8 m: {; j& I& N+ N" h+ \
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)0 R" p* ^6 \! }" G0 i
  786. {. {' g2 r! }/ X
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    8 K" @9 s% O2 G0 C% N- }" U0 c
  788. 9 D/ u, d; N# Q' M' W: a! Q4 `
  789.         CE_Low();                                        /* enable device */
    1 V7 o* H! k/ g# J
  790.         Send_Byte(0xAD);                        /* send AAI command */, {0 q" p2 \" x: _+ b
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# \0 s; t* z5 [# k$ m/ N
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));* K" f: B! R$ ~( |/ f$ U' D
  793.         Send_Byte(Dst & 0xFF);* @. r# P% s8 l5 }" F
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ( W  d% X2 |0 g6 Y
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    4 F& H3 k: k7 s0 e8 C# }7 m
  796.         CE_High();                                        /* disable device */0 Z5 e* ~' y1 j: \
  797.        
    ' ^0 C4 E, Z0 ]" k
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */, X- X" }8 }$ A, e
  799.   K1 S, s) M, `
  800. }
    2 D) W$ n( @3 ^3 w! ~2 e
  801. - s7 l3 P' ^* S
  802. /************************************************************************/! l3 c4 Z; f. S, _3 i  l! ^& ~
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */$ P/ \" @: ?/ b/ V3 n0 n
  804. /*                                                                                                                                                */' K& O  G5 S% L2 x
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    + Z' S! y5 l4 H# L) {: o: c6 y  Z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    2 D3 t# h- w5 [2 C) o; D6 N
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    4 |, F4 C% O9 r0 t/ p2 X
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    0 D8 N. e1 F  {8 m9 }' z- }7 U
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    ; ~! C3 t7 d9 J( w) ?' O  I& t6 V$ b
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    ) I# _1 q8 Q; ?! c, k, `6 J
  811. /* used after Auto_Address_IncA.                                                                                */7 j5 R. [+ @4 S1 t5 |& X& B
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' C, j. F2 Y3 y# ~; g. ^- I% I9 G$ W
  813. /*                                block protected.                                                                                */
    ; B- t2 o  x: ~0 p# q- x
  814. /*                                                                                                                                                */% C3 S$ v  B$ R# V( n8 M3 K' a
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    % a  F! I& B/ c2 E- N! J
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */1 q3 N/ _1 |6 S, s5 V
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ; Q- ^  ]5 E' a; \  j
  818. /*          to exit AAI mode unless AAI is programming the last address or                *// `0 q. }8 n+ W8 a0 f& i
  819. /*         last address of unprotected block, which automatically exits                 */8 M2 n" {5 F% J" a
  820. /*         AAI mode.                                                                                                                        */
    # D( s9 y, b" N* r* V$ X& @# V
  821. /*                                                                                                                                                */1 d5 y' |5 f& T. I
  822. /* Input:                                                                                                                                */
    4 L; R! W0 N2 e/ n; e) w
  823. /*                                                                                                                                                */
    ( V  b; @7 v- |- W# a0 A
  824. /*                byte1:                1st byte to be programmed                                                        */
    " [* }* `$ }- X; w: e- f; |
  825. /*                byte2:                2nd byte to be programmed                                                        */2 e( G, t' T% ~% m. ^( t; {
  826. /*                                                                                                                                      */
    ' ]; Y& O2 g! v$ }5 o. B) _$ V* e4 l
  827. /*                                                                                                                                                */! Q! G4 J7 t7 Z: v1 @( Z: h- L
  828. /* Returns:                                                                                                                                */; O  I, f' a5 W0 ]2 l
  829. /*                Nothing                                                                                                                        */
    - T. M; W0 y- Q. ~3 f
  830. /*                                                                                                                                                */+ R% a4 C% B6 ~3 B# D0 ^2 b0 o
  831. /************************************************************************/
    . a6 C# z; r0 Q& C( B
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    $ h/ O7 s6 [; A4 ~" ~
  833. {
    ) F" Z8 C/ _1 \, D
  834.         CE_Low();                                /* enable device */
    ! l* s2 {: e0 [; Q
  835.         Send_Byte(0xAD);                /* send AAI command */
    ' S0 w& y7 ^7 Z
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */- o& M' X+ q8 L5 h
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */- W; o" k7 N0 b/ ?
  838.         CE_High();                                /* disable device */
    ; G1 o5 d4 \' T
  839. $ j1 h$ v+ _2 b, `0 G3 }9 `) x
  840.         Poll_SO();                                /* polls RY/BY# using SO line */: g8 W4 {! ^  u2 a: v  `8 m  h
  841. / Y0 S3 l- E! q/ i: D- T
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    ; G& `1 q7 H- e, u/ S) ?. t
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    , `7 R: p- p+ A7 y
  844. }
    , o$ X1 [# e. m8 V

  845. 7 J, V# ]  l3 h  o7 _
  846. /************************************************************************/1 [6 S- A3 v% i$ k, w) N5 g
  847. /* PROCEDURE: Chip_Erase                                                                                                */) y  E4 x/ h) j+ o$ j6 [  u
  848. /*                                                                                                                                                */& l0 S! {6 }0 I3 R
  849. /* This procedure erases the entire Chip.                                                                */3 n9 z* v* [+ P
  850. /*                                                                                                                                                */
    ; G2 O% J( P/ a" d4 }6 t
  851. /* Input:                                                                                                                                */' l6 ~+ n1 p5 b8 v* R" E- ^& x' k
  852. /*                None                                                                                                                        */0 A& U) Z7 @7 M+ [* `6 Z
  853. /*                                                                                                                                                */
    ! g" U# i" j+ R% M/ p0 \
  854. /* Returns:                                                                                                                                */% g/ s) @/ U) g5 `- ~' ]5 Q$ r
  855. /*                Nothing                                                                                                                        */
    0 g6 Y  G7 P$ k' c7 Q9 ]; c9 C
  856. /************************************************************************/
    9 h0 G" ?6 P  i9 J6 u# `6 J
  857. void Chip_Erase()
    8 G; S* G9 U5 `) i
  858. {                                               
    ' x5 o- ]2 i, w4 m' p
  859.         CE_Low();                                /* enable device */# P" @* N1 {% G. M9 z8 B
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */+ h& `% h: L/ x
  861.         CE_High();                                /* disable device */& H- t; U# z; x+ i9 J
  862. }; H3 o. E3 K6 m/ G4 `# C4 m- ~6 h
  863. - k2 b' B- L0 z" `# d* E5 J
  864. /************************************************************************/
    , c" r8 K  W  t0 Q* ]  i
  865. /* PROCEDURE: Sector_Erase                                                                                                */4 S4 ~8 T# w7 C0 ~1 O) u
  866. /*                                                                                                                                                */5 L& A  I  }* Y, c( a3 D5 @
  867. /* This procedure Sector Erases the Chip.                                                                */: l7 R  }$ n/ i2 l! Y0 j7 a
  868. /*                                                                                                                                                */* M* m. d# f+ Y* ]; K% B
  869. /* Input:                                                                                                                                */
    & X7 k  K$ w" ]7 l. B3 p5 L
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 x. A; i! r- d5 R  Q& s
  871. /*                                                                                                                                                */  z; }, \2 M$ c) B5 }9 M
  872. /* Returns:                                                                                                                                */
    ; n* a! T9 |8 d' f
  873. /*                Nothing                                                                                                                        */
    0 k' v; G$ u1 }1 g
  874. /************************************************************************/2 p# T6 g  G1 V
  875. void Sector_Erase(unsigned long Dst)
    & ~, o; j4 y; S8 H4 |
  876. {: {8 t1 _2 o9 }* o; y1 n5 A$ Q* |" Q
  877. 8 p8 `) P$ @, u
  878. 0 e2 Q  h. D' {8 S
  879.         CE_Low();                                        /* enable device */
      ]( R) i5 l3 ^& N7 U: s- a* Q
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    . n- k4 M) M: Y3 C3 v4 a. d
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    : G- Y; u! s- G0 s/ k
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + E0 V8 Z: P1 ?9 \
  883.         Send_Byte(Dst & 0xFF);/ Z: C* P% ^3 G$ ]
  884.         CE_High();                                        /* disable device */# Q5 u( B% X) |  O
  885. }       
    . G! n" W5 s" g7 \' j1 `. X! f
  886. 7 O1 t5 R( j6 w- J  U. D
  887. /************************************************************************/, K, O2 t$ {/ }* S6 {
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    : t" V9 T; }; h# h0 n1 A! ?. R
  889. /*                                                                                                                                                */# L# Z& j0 L) T; {! `) @
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    9 W+ M* r. |& f9 i- z( d5 @. f( p
  891. /*                                                                                                                                                */
    5 O& d+ [4 H1 Q3 a8 f( k
  892. /* Input:                                                                                                                                */
    % Q- y, c; Q% f1 _' k) p8 U5 F
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ `8 t" E$ E: H( n+ {
  894. /*                                                                                                                                                */
    0 j7 q) D4 @3 A( Z
  895. /* Returns:                                                                                                                                */
    ( l8 q2 c) U" J2 a6 k$ P
  896. /*                Nothing                                                                                                                        */9 ~* t# ?7 d5 l; H+ S4 {) z: l+ t
  897. /************************************************************************/! J$ u& y- y& m0 m! j
  898. void Block_Erase_32K(unsigned long Dst)0 m8 \/ u! K) w2 {6 x
  899. {
    2 o' E; |. D) K6 k1 S$ y3 u4 X8 y
  900.         CE_Low();                                        /* enable device */) \7 ~' B( x; V7 t- `: Y
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */5 ~1 }, ^" V) `$ R1 g
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, |4 P3 f( e% B4 T  h: |
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 t* q, l  b, ^
  904.         Send_Byte(Dst & 0xFF);6 F/ ~6 V6 r, d
  905.         CE_High();                                        /* disable device */
    & L) i1 ^8 S4 W8 w" k9 W( h
  906. }
    - \/ t0 ~/ q5 K7 R5 E) V. O$ a6 s

  907. 1 P& B$ v0 d- N
  908. /************************************************************************/& w' p: A6 B/ ~: o$ Z
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    : _& n6 o2 @0 M. T6 u
  910. /*                                                                                                                                                */7 k2 V( y# x$ ?* h
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    : C8 G3 i" D1 G/ u: a
  912. /*                                                                                                                                                */) W4 u; y# [8 i; }' b0 p
  913. /* Input:                                                                                                                                */
    + `" o  I, o4 w5 p5 i, w
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& H" m$ j$ l. X" Y/ N0 V) Q
  915. /*                                                                                                                                                */, e& |+ Z% Q* x7 z) j  d
  916. /* Returns:                                                                                                                                */5 B& [- O4 v6 Z4 d0 O/ G+ Y
  917. /*                Nothing                                                                                                                        */3 q1 U9 p  n$ f' }7 q
  918. /************************************************************************/
    ; N, s5 X/ L; O
  919. void Block_Erase_64K(unsigned long Dst)0 ^  W' a+ {  L$ O1 ~- O: U
  920. {
    ( V0 e/ C* z* ]8 N
  921.         CE_Low();                                        /* enable device */
    + b8 z/ w7 \3 A; a5 y* U# u& B
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */* f" |% g1 `; d: E9 S- I
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */; W7 A. W6 A6 Y; E/ a8 T  f( U
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));* K9 s* c" C: h# M# o, \
  925.         Send_Byte(Dst & 0xFF);* P' S; _8 b# x% v
  926.         CE_High();                                        /* disable device */$ \6 K2 D% e, Q2 G
  927. }. O  w1 |7 n8 q; K7 S9 e) C
  928. ' L: T5 g) N* }' z2 T* }* N2 @
  929. /************************************************************************/5 [8 w% p) c+ R' P! b- n" M1 w
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    4 a1 f5 G6 t! j2 ^0 [9 h0 o3 k
  931. /*                                                                                                                                                */' [6 g+ U9 y7 W9 g6 R
  932. /* This procedure waits until device is no longer busy (can be used by        */! Y1 x( A1 J; C! b7 `
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ( a, _! x% |# H0 v7 d- M+ s% m! G
  934. /*                                                                                                                                                */, N: V! L4 t- |6 D' Y0 j' y
  935. /* Input:                                                                                                                                */6 b! q9 v( w( V- O1 Y# O7 t) g
  936. /*                None                                                                                                                        */& w2 g" c; o, X) ^& t1 R1 \
  937. /*                                                                                                                                                */
    2 u' L# I5 j! R* B& }
  938. /* Returns:                                                                                                                                */
    9 U/ c2 \4 m5 |  d) _. ~
  939. /*                Nothing                                                                                                                        */9 O4 {% T! }; W# E
  940. /************************************************************************/& Z4 G4 T+ `! c7 m. Y* z
  941. void Wait_Busy()
    2 Y3 a* S9 q! w. I8 |' ?
  942. {
    % \" @: c( ?$ n; p
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    2 f. r: H% R$ [! C/ X: V
  944.                 Read_Status_Register();
    9 U) ^% O# u, ]1 I% }# A5 |
  945. }
    # I" S% [- Z6 ]5 H) @" K% i: Q
  946. 1 z1 O( t/ P% S- b+ e; M: x$ K
  947. /************************************************************************/& v1 ~4 D7 z! C( R3 c
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    / G1 O9 S; Q( L0 t( j6 A2 \9 [
  949. /*                                                                                                                                                */
    ) {# s6 I4 d) ^2 E+ L  r5 q( d4 k2 M, N
  950. /* This procedure waits until device is no longer busy for AAI mode.        */' \1 R! p8 u4 l* A- m
  951. /*                                                                                                                                                */* B, m9 s: d5 j. [% l
  952. /* Input:                                                                                                                                */% Q% R; J3 A% V/ ]9 S8 A
  953. /*                None                                                                                                                        */
    ! c$ f; `' W% W3 F9 l
  954. /*                                                                                                                                                */, \7 M9 N, v" [
  955. /* Returns:                                                                                                                                */5 O9 q# h/ u" ]7 S' a! j
  956. /*                Nothing                                                                                                                        */
    , |" N- A3 b& v  H# P5 c
  957. /************************************************************************// e3 G' J( t' ^8 J" V9 Q6 _
  958. void Wait_Busy_AAI()
    + o' y! }1 o* k
  959. {
    / l( a0 S3 ^0 [& X  i
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */% L  s+ l# C9 ]6 l$ P2 c  I
  961.                 Read_Status_Register();
    : N& X0 G  F; ]( F& y0 @
  962. }8 h/ e! b+ H2 |) Q
  963. ; ?) f  ~/ E  z; j2 i
  964. /************************************************************************/0 Y1 z- J- S/ c. k9 _  k) X
  965. /* PROCEDURE: WREN_Check                                                                                                */3 |1 G2 I- G/ r. L7 `% ?0 y5 |0 H
  966. /*                                                                                                                                                */
    8 w" h- K; g3 Q# [* _8 y* }2 g
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    / h% v* O. I. e+ m7 v- W
  968. /*                                                                                                                                                */
      a6 A3 D6 C" J; S+ ~, q8 \/ L1 Z
  969. /* Input:                                                                                                                                */+ x6 H- z! d! E" Y; S
  970. /*                None                                                                                                                        */( D4 T( h- R% R" [& L' E
  971. /*                                                                                                                                                */  y2 p- k3 l! C5 k* ~/ [
  972. /* Returns:                                                                                                                                */6 u; b0 f3 s' K
  973. /*                Nothing                                                                                                                        */
    1 k# X" E6 B: H# @+ n# p" M
  974. /************************************************************************/
    ' W3 X9 X( ^7 e. |* b+ P' w1 i# t: M% z
  975. void WREN_Check()6 p, k/ J/ C+ ?+ I1 X
  976. {
    3 d( _; t: O  W$ u! A+ }
  977.         unsigned char byte;
    9 ?! [' X& B! q( P8 o# b+ w3 I2 L: h. G# z
  978.         byte = Read_Status_Register();        /* read the status register */
      z9 \& ^5 D9 R/ o3 _- w9 i
  979.         if (byte != 0x02)                /* verify that WEL bit is set */1 {  I- m8 U3 C6 f8 P6 U) m1 {
  980.         {
    0 t- J% g2 W1 {7 n4 G
  981.                 while(1)" H$ k) v5 D2 [. C" _
  982.                         /* add source code or statements for this file */
    / H' u; ^4 ]; R% Y
  983.                         /* to compile                                  */! r7 ]+ ?0 q6 B8 W
  984.                         /* i.e. option: insert a display to view error on LED? */
    " ]4 z" I9 n7 m- \- u; U
  985.                  % i+ _4 j" K: J2 _4 d5 l
  986.         }
    9 ~3 w& t( s, I  e8 ?. Y; R
  987. }
    2 y6 O3 M& k/ ~/ z/ _! G' u

  988. $ Q6 ~+ Z5 m- q# A- ~; k
  989. /************************************************************************/
      D* C1 n, \( f" f) Y
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    4 o( Q9 A6 X3 F; S4 T% E
  991. /*                                                                                                                                                */
    ! k. j6 g- V# a6 b; b
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        *// D0 V# c# L) Y, l/ `& d  M+ D
  993. /*                                                                                                                                                */
    7 `, W7 s, ^9 ~% X3 f2 x! H
  994. /* Input:                                                                                                                                */
    2 X/ t% y4 F) z! a/ H$ D8 X
  995. /*                None                                                                                                                        */5 l( Y; C' s* C1 _6 j$ L/ i% ~
  996. /*                                                                                                                                                */
    8 X- z) {  l" n( |4 {: @
  997. /* Returns:                                                                                                                                */6 x( F2 P8 m& C
  998. /*                Nothing                                                                                                                        */
    1 [& ?1 S3 r; P  n% |8 e
  999. /************************************************************************/
    : s) {' r5 r+ K
  1000. void WREN_AAI_Check()
    5 X: q2 a  ?3 k1 x" ^& k, r8 _
  1001. {2 _5 L4 F9 [  \9 M! _4 }9 s
  1002.         unsigned char byte;; f# \$ f: K! D& @: c
  1003.         byte = Read_Status_Register();        /* read the status register */
    2 q6 v) g5 B0 I' F3 q4 }
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    8 M" k) ^% [% U
  1005.         {
    % D% f3 o( g+ ?: z7 U* c! O! c
  1006.                 while(1)                6 _6 C/ L; r! W$ I' c% I
  1007.                         /* add source code or statements for this file *// x( \( }" z6 `- k, d  o
  1008.                         /* to compile                                  */
    8 ]) |) f9 e4 n% v  R* u
  1009.                         /* i.e. option: insert a display to view error on LED? */
    # T( n1 O# w7 H
  1010. 6 d& t4 C+ s' ~/ i, {% J- }( |* T
  1011.         }, ?/ d/ B1 l( Y# s6 W% X4 z( e
  1012. }# i$ i3 `4 F( N- Q4 g
  1013. ( t3 B2 @, I' a
  1014. /************************************************************************/3 [6 A" f$ ]7 @9 N
  1015. /* PROCEDURE: Verify                                                                                                        */% v( U4 r  ^7 w; n0 G: |" ^
  1016. /*                                                                                                                                                */6 |) K$ v. Y+ g/ {
  1017. /* This procedure checks to see if the correct byte has be read.                */
    2 l, @6 L, S& r3 `
  1018. /*                                                                                                                                                */
    $ ~3 U0 R9 I1 p
  1019. /* Input:                                                                                                                                */
    ! `& l5 m' I: J* L' H# m& p5 y
  1020. /*                byte:                byte read                                                                                        */
    5 P, G  J3 q9 r# Z) @+ ~
  1021. /*                cor_byte:        correct_byte that should be read                                        */( K9 d: z1 W4 B( o0 K: w
  1022. /*                                                                                                                                                */9 i" J1 O: p% w9 W& N
  1023. /* Returns:                                                                                                                                */
    # {" }# r( ]; p: R0 v
  1024. /*                Nothing                                                                                                                        */7 w) B! R  J, ~0 [
  1025. /************************************************************************/
    % a  P& D3 p2 W4 {4 C" ^
  1026. void Verify(unsigned char byte, unsigned char cor_byte)" g$ p5 K. b" W. j
  1027. {9 L4 I( g9 m1 c+ s# Y
  1028.         if (byte != cor_byte)
    ) D' L8 O2 q% s- P3 h* w- D
  1029.         {
    ! R2 \1 a/ e0 s+ x
  1030.                 while(1)6 j# t% C+ @0 ^9 c4 b
  1031.                         /* add source code or statement for this file */0 [. k1 C* D, W7 s. l# I' h5 W/ u1 z
  1032.                         /* to compile                                  */0 w# K; y5 {) c# N6 c; T( m3 Z! D7 S
  1033.                         /* i.e. option: insert a display to view error on LED? */3 h) M; v( m4 y
  1034.                 ) J; ?( x  N" t
  1035.         }
    7 u/ m$ \: H  i' q$ Q
  1036. }3 v- \. Q& c: i2 O$ \1 A
  1037. * p( Y" p( R- {- ]
  1038. ( r0 d& D9 b' z0 z
  1039. int main()
    + W2 D9 V9 _) ^
  1040. {+ L+ l2 T, _( n8 p6 ]

  1041. 5 Y& T, j4 E1 i% T% q
  1042. return 0;
    + k# z4 {4 @$ P/ Q9 |, V- C
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:) V* g+ B3 `0 O& n) ]
   main()
, a# y: i  q+ a8 i* K   里面怎么是空的呢?
  z: K) L# V6 E- r, j* ?1 \   发一份给我吧9 A1 e* w1 ]" t; B. o9 h+ \
mail:luyijun2005@hotmail.com' @* B6 K( @# o0 u% o5 A; s) W
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
; D- _, O; N7 F7 o# Z# m6 R) @) _
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。3 p: l* U/ D, ]: m" E$ f
EC的代码在哪跑,你看DS的说明,每个EC都不同的。  e' t4 L- _' w1 H9 k3 D5 A3 c
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
: h( [% m; Z# b6 [" g上面几个问题是你没看任何东西而白问。
" X0 r( F8 r) s9 A& O! C9 Z1 \9 T- M! h6 M9 g6 B. c: i; f& _
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样$ h% Z! q6 ]& Q
似乎要把SPI能support 到最大,这EC chip应该有好卖点
4 `, a) }, O( w) |' l: j+ dBIOS功能要不要强大,也就决定了SPI Flach的大小! [/ F1 d7 `, X- `( R7 W" b
我是这么想的~让OEM去决定要挂多大!2 f" r4 _, {# x3 o+ |6 T  M
如果我司有BIOS工程师就好了~哈
% f! s* Z; a0 d& \WPCE775应该算很新的东西,来看它支持到多大?  ~& n5 G) V0 L- S3 ~9 w  r
( Q" F  P+ s& o
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
& e/ r( g6 x% H其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
& y- o7 ~/ d$ g# k" V3 r2 D* l; J
这份driver收下~希望以后有用到
- b# [+ }. g. Y% Q- \9 w谢谢bini大大" c. ]6 N1 n8 C3 I# D) Q' ^+ p

4 ?2 o- z' t( c# h0 }很新很新的新手,如有错误请指正 (准备看第二家的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()4 ~' }/ j7 g, u0 W$ `5 }7 h
{7 Q0 v( d0 ?, F. M
        unsigned char temp = 0;
  D& {) {, ?, C4 T/ Q1 `        CE_Low();
8 M1 _! V+ a$ C; M    while (temp == 0x00)        /* waste time until not busy */
# K& G' u5 s+ p1 f' o' W& b                temp = SO;
* k  t4 o" {' K& S  T: y( A2 [9 \        CE_High();6 c6 A7 F9 Z: {& i8 [, E5 q
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
" f9 J: c! A: N& ]{4 N- Z& L, s- {) V  B+ x
        
1 \/ e/ g7 S, L4 ?! |  c$ c        unsigned char i = 0;! y9 C" h) A- G
        for (i = 0; i < 8; i++)
5 G' X3 Q; Q$ |* Q  c3 g: }        {
" N) o& s. F( E! l! V) R               
, I/ c9 S7 B; n6 e/ ]# u% c                if ((out & 0x80) == 0x80)        /* check if MSB is high */# e% {/ Y, t) ], h7 c& `5 W
                        SI = 1;
/ e' Q) r; G! F                else. b0 A7 K7 ?, N- v$ E: D1 g* C% o
                        SI = 0;                                /* if not, set to low */
$ s, J: f3 @, H/ L 问              SCK = 1;                                /* toggle clock high */2 [1 U1 u8 Q1 V6 [% O
   题            out = (out << 1);                /* shift 1 place for next bit */
8 |3 p9 B* L( i! H                SCK = 0;                                /* toggle clock low */
7 N( b& ^& r- ^$ I1 E        }: G) ]: p' }) L" s
}
7 I  \- z1 K( k9 g 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-1 16:56 , Processed in 5.496028 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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