找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 53247|回复: 13

[Software Driver]SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver
    : M- k1 S- d# E. M4 n( K5 g

  2. ) a% L! s" M* Y. Q: M% A2 u( D
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    4 M( U& K, o! p. U2 e7 d$ x
  4. % v1 U2 W: H& @
  5. November 4th, 2005, Rev. 1.08 @7 q, r- C9 |' s9 u+ Z
  6. 0 u, n# Z* u% O- o6 n
  7. ABOUT THE SOFTWARE0 i- M# q5 m, ~6 q- j; s
  8. This application note provides software driver examples for SST25VF080B,
    : h5 v) I: {$ |: ?# E; y! X
  9. Serial Flash. Extensive comments are included in each routine to describe
    ) v  y! X- B% Z
  10. the function of each routine.  The interface coding uses polling method
    4 k% R6 r, Y' a" j9 W3 }3 t4 }& v
  11. rather than the SPI protocol to interface with these serial devices.  The8 I" Y% a* z# {# B
  12. functions are differentiated below in terms of the communication protocols* ?% M' j) d' u9 q$ ^, Q# y
  13. (uses Mode 0) and specific device operation instructions. This code has been ( r' j1 R2 j0 v. v! x: [
  14. designed to compile using the Keil compiler.$ b; R; h: u3 I5 V

  15. 5 m+ r+ f8 _) |/ L1 a8 S
  16. 3 e9 O  K0 r/ y4 h0 X" ]5 i
  17. ABOUT THE SST25VF080B6 o! ?1 x' ?( \4 }5 c* m

  18. 2 b0 A5 u0 v+ N- }" N" O
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    7 `3 @0 s  s3 ~7 @& n, p0 K, X$ G
  20. conjunction with this application note for a complete understanding ) l0 @$ J  L* Z: H1 L, _9 C1 B
  21. of the device.
    , O# \3 H3 G6 M
  22. 7 v" i: e9 o7 N8 {: e0 y
  23. ( @. i% o. h5 V/ L
  24. Device Communication Protocol(pinout related) functions:$ ~- Q. o. U8 [3 Z

  25. 5 `  B0 y$ p0 @. z! A
  26. Functions                                    Function
    8 B9 a# k; S7 c: a' {: _6 U5 Q
  27. ------------------------------------------------------------------7 W% z* H) Q  N: R6 }
  28. init                                        Initializes clock to set up mode 0.4 p5 @7 ~; c( Y# {- m) e
  29. Send_Byte                                Sends one byte using SI pin to send and ! H: k0 |! x  p6 I( n
  30.                                                 shift out 1-bit per clock rising edge" {' q1 r7 _- s5 {$ o# X, h4 j
  31. Get_Byte                                Receives one byte using SO pin to receive and shift , v* A: o  Z+ y; `/ t9 C8 H
  32.                                                 in 1-bit per clock falling edge
    7 A' U% @3 q+ r$ U) J) P! R
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming: ?6 ?% Q* r* e4 F# g9 U  a. Z  `) P
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    $ g: m- t. r/ n1 R
  35. CE_Low                                        Clears Chip Enable of the serial flash to low" a  d1 u' W1 X/ R
  36. Hold_Low                                Clears Hold pin to make serial flash hold' M# `7 q4 k- R: F, u4 H
  37. Unhold                                        Unholds the serial flash, m/ c# w& }) O$ c8 D3 O! Q
  38. WP_Low                                        Clears WP pin to make serial flash write protected# y! X9 r2 \4 s" ?. P1 ~# U4 `4 `
  39. UnWP                                        Disables write protection pin
    # {) o* u' x" h4 S  G/ B
  40. 5 ^4 m& h+ D7 K  E
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
      E% z! f6 L9 w7 x( N
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your9 ^( p. f! ?0 p" q
  43. software which should reflect your hardware interfaced.          
    4 }7 o1 b# `8 @
  44. - Z% J7 N. A! z) O3 G6 k

  45. 4 V& J, Z' K4 k3 G1 w. c
  46. Device Operation Instruction functions:! v2 E% \2 E* N3 {

  47. : s, j8 H  t9 U" L- U
  48. Functions                                    Function1 J: R) {5 e' }' Q% s) _
  49. ------------------------------------------------------------------
    ) W! u& H8 ]: m, P* d. i$ z
  50. Read_Status_Register        Reads the status register of the serial flash  _: M# W6 }  C5 w
  51. EWSR                                        Enables the Write Status Register
    / y( m# _3 E9 r5 u3 G! }5 R6 Q
  52. WRSR                                        Performs a write to the status register% ?* s* y7 @; E- R/ M
  53. WREN                                        Write enables the serial flash
    $ j- M2 Z' j2 R  r
  54. WRDI                                        Write disables the serial flash
    & Q/ `$ ?! h  i) m. ^$ r
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    + j, A0 i: d. k' j/ x9 M: B9 Z
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming" {  S4 H' Y; t! F4 j
  57. Read_ID                                        Reads the manufacturer ID and device ID
    9 B* R6 l3 Z5 l7 d
  58. Jedec_ID_Read                        Reads the Jedec ID
    ; c- j" D: h- p$ e- {& e
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)0 {+ F* A: S& S, d8 b
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)1 d7 J$ C0 k+ Z) ^5 B( }0 @, _
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)" f7 J6 f% o" y8 S! o+ ]
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    4 X$ e4 Q) ~# M: t6 z( I
  63. Byte_Program                        Program one byte to the serial flash
    8 ?- m+ {7 S3 V" p0 q
  64. Auto_Add_IncA                        Initial Auto Address Increment process8 N) V: J, F! e+ a/ K2 T
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    $ `* y( W+ @) \3 e  C7 P+ B& w3 B1 o
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY& N! a$ i- ^9 p  {
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY- D% [& \; \1 S' M, I
  68. Chip_Erase                                Erases entire serial flash; V; J2 m7 n) S" D, W! e2 r
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    2 U) E; I9 L, C. M4 Q$ M. b4 v
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash9 s8 ^6 z- v2 ?  w
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash2 u+ `) o8 Q( m$ @; ~% O
  72. Wait_Busy                                Polls status register until busy bit is low  q" N3 X9 Q8 v3 c
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming9 J9 G9 h1 B  w/ k
  74. WREN_Check                                Checks to see if WEL is set2 q6 J3 E* x1 {+ Q6 K/ |  W
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set. U# q6 u9 V7 k: U. g
  76. ! \% L5 I2 G- s' N
  77. " v" ^/ A8 o6 ]% o* d' g
  78. & E) ?5 w$ X; t, `; X% A. w$ F
  79.                                                                      
    $ ?* {* _' y; j
  80. "C" LANGUAGE DRIVERS ) Z- ~) d, o, [, i% l9 i

  81. 5 e* C2 r8 K* y5 |4 _2 o% ?
  82. /********************************************************************/, W5 K7 ?2 w2 n3 X
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    * {; B; H9 v1 V  T
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */6 }, P+ T1 Y9 L2 z. V( s" M2 e
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    . x4 J: I1 r) \& z
  86. /*                                                                  */; K2 I! w, t. m# x, V! w$ p, I
  87. /* Revision 1.0, November 4th, 2005                                                                          */   $ h* c7 I. T3 [& y7 F
  88. /*                                                                  */& {% x8 v0 o4 ?: ~
  89. /*                                                                                                                                        */
    8 V# \+ `( @2 c9 y9 {# v; l& t
  90. /********************************************************************/
    $ W& ~# A/ H9 d; M( ?

  91. / n8 X; C5 o  A
  92. #include <stdio.h>
    # E) ^& W- `$ R0 H, L
  93. #include <stdlib.h>
    ( X( t) f- ~8 O5 F; k6 y

  94. 6 s6 \  Q: T, G+ M% p$ o" }
  95. /* Function Prototypes */6 |1 q- o9 t  D# @

  96. 4 ~. y% |# _# Q$ C1 W$ t
  97. void init();
    8 I: t$ M% O7 G- k3 z
  98. void Send_Byte(unsigned char out);
    % L5 S6 U1 u" @% f, c! G( M
  99. unsigned char Get_Byte();! y8 n7 |4 y' a9 T3 \
  100. void Poll_SO();# a) T' i1 l4 k5 z* P1 c5 T$ @
  101. void CE_High();8 F- C% C( B7 G
  102. void CE_Low();
    ' t0 Y  ~" o6 T" T, S* _
  103. void Hold_Low();" O7 P- d* \* Y9 E5 Q* n/ Q
  104. void Unhold();0 i/ e. O1 o: i0 t, V( k
  105. void WP_Low();
    ' O6 \, A4 h: W2 f$ [, s- h+ N% k
  106. void UnWP();5 i+ T7 _( X, l6 c4 K0 ^
  107. unsigned char Read_Status_Register();5 C! p- F% k- Y, A/ Q5 g
  108. void EWSR();0 l5 C# L2 ~1 S* Y/ o5 R
  109. void WRSR(byte);; d, W% j( l3 e1 O( H$ a3 }. ]
  110. void WREN();' u2 X' I  y9 s6 C( `' t5 H
  111. void WRDI();
    5 n. f$ u" ]/ D" U
  112. void EBSY();
    " }1 e9 S3 x1 G5 ?# [: f
  113. void DBSY();
    0 |' |0 ~3 j5 x* U% C! N
  114. unsigned char Read_ID(ID_addr);
    + o! l" s, O4 @: f7 z* ^
  115. unsigned long Jedec_ID_Read();
    ! G( B- p" Y1 U, U5 K
  116. unsigned char Read(unsigned long Dst);
    ! _1 w2 j" D: \& I' U% q
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    , y, a# a  T2 a; D! G' {
  118. unsigned char HighSpeed_Read(unsigned long Dst); 8 X6 e7 q+ d/ f
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ' b& [- Q! j4 l# F8 D
  120. void Byte_Program(unsigned long Dst, unsigned char byte);; Y/ }) c' T3 X3 i6 |( O& ]
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);9 a1 p$ w/ d+ S
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    0 M6 b% U$ S4 m. m) x5 H( P6 }
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);! t! h2 ^+ l7 R
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    & G6 l7 G" J; [$ n- a0 j; G. V5 s
  125. void Chip_Erase();# m6 V9 W& o+ H% v- q9 c, M
  126. void Sector_Erase(unsigned long Dst);9 T) X, h& l& ?1 Q. R5 F5 O; T2 e
  127. void Block_Erase_32K(unsigned long Dst);0 A, l' C/ }) F$ n4 ^
  128. void Block_Erase_64K(unsigned long Dst);
    0 U" C, {- B0 O9 A4 j4 _
  129. void Wait_Busy();% i6 F8 E3 b- X! I, Z$ m" `
  130. void Wait_Busy_AAI();
    - q2 M9 J6 s- |. a+ R) }
  131. void WREN_Check();3 m' X; A2 |! J% p
  132. void WREN_AAI_Check();
    5 k% d" N3 k4 V/ ]( W& N; Y0 v

  133. & d! |) C/ A* I. b6 f3 [1 u+ j4 z
  134. void Verify(unsigned char byte, unsigned char cor_byte);8 M' |4 y  s( X! O: L2 G. t: x

  135. 4 O5 |. w5 ?: I- I0 y% Q& G  K
  136. unsigned char idata upper_128[128];                /* global array to store read data */4 o! X) L3 p0 i% l! U; g
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    , s4 n2 r7 `: ?/ A9 j

  138. 2 I$ S3 P7 h2 U9 i
  139. /************************************************************************/
    ! p# o9 g. {) z. \7 E, k& ]
  140. /* PROCEDURE: init                                                                                                                */
    9 J" N4 X( W6 k) s9 F) C+ ^, ^- Q
  141. /*                                                                                                                                                */# l' P# z" P2 ?# k( }5 e$ {
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    9 @; {- w" F9 d9 t' [3 ~
  143. /* setting up mode 0.                                                                                                        */+ u; l  x' v& Y2 w" Y1 c
  144. /*                                                                                                                                                */
    6 D; ]7 e5 M; ]; k8 r3 C
  145. /* Input:                                                                                                                                */8 }- u- u( @6 m9 W' d2 }  P: f
  146. /*                None                                                                                                                        */
    8 \) r" ]  ^3 i* v8 t
  147. /*                                                                                                                                                */# p0 y$ M7 @9 u  m* d+ j! l
  148. /* Output:                                                                                                                                */
    6 {3 d* }$ S4 T0 n! V2 \3 S. e5 M
  149. /*                SCK                                                                                                                                */% x( l# R9 r# K) @0 H
  150. /************************************************************************/6 }! u! b; y0 Q* N' C
  151. void init()
    , w8 ?$ k5 g8 ]% F" X8 l
  152. {
    8 X4 A7 J, ~1 H5 m( i9 C0 X
  153.         SCK = 0;        /* set clock to low initial state */' ~  z& }4 T5 \1 k# l
  154. }9 w7 `; p) b8 u! H0 k! B
  155. ) [, `* z4 O, a- s" H
  156. /************************************************************************/) m9 `9 b' V9 B, n+ A" @% b2 U1 Q
  157. /* PROCEDURE: Send_Byte                                                                                                        */* d  [" w' D7 X' F( w6 p
  158. /*                                                                                                                                                */3 B' O- F. c1 K
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */0 K- U5 O* Q4 i4 l" ~3 p- J
  160. /* edge on the the SI pin(LSB 1st).                                                                                */5 M& n3 O" @4 T" R
  161. /*                                                                                                                                                */# F9 {2 n3 ~! p" w, M2 _% {; U
  162. /* Input:                                                                                                                                */
    ) e8 ^4 {5 k' X# J; |/ O
  163. /*                out                                                                                                                                */5 ^) b0 o5 `1 F
  164. /*                                                                                                                                                */
    4 {, |" C% n$ t( o1 i. m; Y! |0 }
  165. /* Output:                                                                                                                                */9 _/ c( k3 w+ b+ W1 I3 `3 B, N
  166. /*                SI                                                                                                                                */! \8 {2 t/ K6 X- p( j
  167. /************************************************************************/+ z2 ], ^) f; p! I: c( i2 f
  168. void Send_Byte(unsigned char out)3 w0 i3 `# f" l
  169. {
    . g) z5 q+ A! u  V
  170.        
    ( F' }2 z& v. ]
  171.         unsigned char i = 0;
    ) }. f8 n4 I9 g! c1 V9 ?9 Q! y4 T, f
  172.         for (i = 0; i < 8; i++)
    ' V4 O. R9 l* Z( E
  173.         {
    & J0 p+ p  F5 h2 w& u4 X3 W& L( Q
  174.                
    5 _2 Q" |; r$ Q' `) S
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    1 ?$ G. @3 K# P# d
  176.                         SI = 1;% {. _; c2 x3 s; b$ `8 ?5 J
  177.                 else
    + @, g6 n7 W4 n: \
  178.                         SI = 0;                                /* if not, set to low */7 d& e: v0 t. a- S
  179.                 SCK = 1;                                /* toggle clock high */
    2 i+ O* r9 A6 k& k0 }
  180.                 out = (out << 1);                /* shift 1 place for next bit */( @; B8 {, n: Q  H+ B9 i
  181.                 SCK = 0;                                /* toggle clock low */, O/ V! X6 v9 Q. {
  182.         }
    ) @7 d# Y1 t8 c' L) I  k/ n
  183. }  F& q, H* f7 s0 f

  184. ! o$ @- y  m0 f8 c- _
  185. /************************************************************************/9 Q2 N: X- b2 ?; D' ?; U
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    ) a$ w5 O- ^, m2 |7 R
  187. /*                                                                                                                                                */
    - _# @' M7 U0 N3 z
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    1 [8 y9 c! e% K& g3 c5 }7 I
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ; i8 }/ ^+ x/ j+ I' R# U+ m6 d5 x: z
  190. /*                                                                                                                                                */6 G7 t# `! f- v& T; y3 q, T
  191. /* Input:                                                                                                                                */+ M$ Q& {0 X9 \! X- x/ X
  192. /*                SO                                                                                                                                */  t+ ^0 H( j: l  `
  193. /*                                                                                                                                                */
    * C5 o( k6 r  {2 ]( _( @
  194. /* Output:                                                                                                                                */
    2 R6 o% S" L- V$ E
  195. /*                None                                                                                                                        */# Y) r3 `( n. r, G; l' `& ^
  196. /************************************************************************/
    2 ]; E2 V/ e, _) D; d- Z  s1 N
  197. unsigned char Get_Byte()& s+ u6 e4 C' T( f! ^# I
  198. {( b  f% p5 d( L$ R7 D( M" S
  199.         unsigned char i = 0, in = 0, temp = 0;- Z( C$ v9 y4 E8 w
  200.         for (i = 0; i < 8; i++)# G: p0 t  C  a2 }
  201.         {& X( n1 w0 @3 Y1 q% w( S
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */; F/ c7 L9 v! `- A+ [9 n
  203.                 temp = SO;                        /* save input */# C' R/ t3 f& h
  204.                 SCK = 1;                        /* toggle clock high */2 I( F2 l3 L8 R; }/ ?  z
  205.                 if (temp == 1)                        /* check to see if bit is high */
    ( X8 ~$ S$ r, j+ Y7 r* m+ P
  206.                         in = in | 0x01;                /* if high, make bit high */
    3 K# u% ?2 A4 W+ I
  207. + ?( j/ q1 z6 E6 I
  208.                 SCK = 0;                        /* toggle clock low */
    5 `6 d7 `% u6 x1 `& X6 l' m/ n
  209. / V3 Q  s1 g% j( {& o* R, e
  210.         }7 `' k0 n& g) Z% A
  211.         return in;0 h" H2 h# [3 v/ x
  212. }) Z  R, ]3 b' }; z

  213. % Z0 `5 k0 M( M. c9 Y
  214. /************************************************************************/
    3 [) B- [7 n1 O/ C8 v" P
  215. /* PROCEDURE: Poll_SO                                                                                                        */9 h$ j. U- h  {* L0 c
  216. /*                                                                                                                                                */# r6 H/ l: U1 C) w5 W* Q1 q
  217. /* This procedure polls for the SO line during AAI programming                  */  Y1 H6 r# z$ j( ]$ f7 x2 \7 S
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    # d* H$ s3 E/ F
  219. /* is completed                                                                                                                        */
    8 a" M! N; f; Y+ _  b. D  a. H
  220. /*                                                                                                                                                */# L3 U1 j& a2 Q# o2 J/ W5 q) o
  221. /* Input:                                                                                                                                */
    8 K/ z; ^6 m+ r" ]
  222. /*                SO                                                                                                                                */
      Z0 S! k( k) }' G
  223. /*                                                                                                                                                */$ }/ x5 D2 d: Q
  224. /* Output:                                                                                                                                */! y4 K( g9 x6 R  `! ~1 ~8 D0 n  ?
  225. /*                None                                                                                                                        */1 m* D+ t0 N. G! g
  226. /************************************************************************/! E) W2 P2 M4 ]  F
  227. void Poll_SO()8 I* L4 w& \1 ~) B7 B4 F( W  n+ }
  228. {' g6 x% O% r& f
  229.         unsigned char temp = 0;/ W' |- P/ X6 k9 A9 Z8 i$ D
  230.         CE_Low();
    ) v6 w+ k) U/ [6 C& {* }& M, S
  231.     while (temp == 0x00)        /* waste time until not busy *// l% C% [4 [# j' X
  232.                 temp = SO;4 L  _5 u" B& G9 [2 u. G) }
  233.         CE_High();$ q) H* O  c7 P$ C' _8 p$ J  n9 z
  234. }1 r. c7 n! O1 c$ L0 o- S

  235. 7 p2 Y5 @6 b! E' N! L9 ~
  236. /************************************************************************/+ @" X- X* v+ U4 G5 \( W
  237. /* PROCEDURE: CE_High                                                                                                        */$ t' v* X) C3 ~  p
  238. /*                                                                                                                                                */1 g2 s5 `/ S3 A+ c) R: O
  239. /* This procedure set CE = High.                                                                                */
    0 {5 D% l& x, P4 g
  240. /*                                                                                                                                                */
    5 l& M( X9 p0 d4 ?# ?/ c$ N
  241. /* Input:                                                                                                                                */- |4 Q0 w6 S. H
  242. /*                None                                                                                                                        */7 l- n# b" |# z
  243. /*                                                                                                                                                */
    * s  V( L: r- w; Q2 P" p3 C
  244. /* Output:                                                                                                                                */& q* c0 B2 T+ x) X. r; {, D* F
  245. /*                CE                                                                                                                                */$ O# Q; a& k5 N" G# F) B6 h% ?4 t
  246. /*                                                                                                                                                */
    3 g- s( |2 h9 w1 r* f7 m5 @
  247. /************************************************************************/
    $ s& V# V3 T: n$ D# _# Z, ^
  248. void CE_High()
    ! r# B( |( Z6 J: O- _) R( s: _
  249. {
    6 x% X! G* B: f& k
  250.         CE = 1;                                /* set CE high */7 K/ K3 x+ l7 R3 r
  251. }9 b  I% Z# V' L4 k& @- N1 [
  252. : c5 z: |' V! \+ |
  253. /************************************************************************/$ @/ K1 k/ }8 I+ c: h7 B. [6 M
  254. /* PROCEDURE: CE_Low                                                                                                        */6 q) x  d4 i. F# z7 t6 g0 o
  255. /*                                                                                                                                                */% m: ?' [5 {  I, o* M- {, ?* ?
  256. /* This procedure drives the CE of the device to low.                                          */6 z2 J1 @5 W0 Z6 Q* C! }" v
  257. /*                                                                                                                                                */5 B7 d! S. R8 a  S# Y3 M; q* b1 O, a
  258. /* Input:                                                                                                                                */
    - t1 |" P/ @5 f! \
  259. /*                None                                                                                                                        */' ~9 b" q# k/ [" _: }$ c# x- _/ k7 B
  260. /*                                                                                                                                                */
    $ F8 w# v) p- x4 Y9 K2 o# [
  261. /* Output:                                                                                                                                */
    3 K# R) m1 g# n0 U2 \9 S0 F: Q
  262. /*                CE                                                                                                                                */
    8 ^+ @( S9 _7 n) ^; M9 ?9 H+ l* U
  263. /*                                                                                                                                                */
    ; u0 a+ B' |* B- f
  264. /************************************************************************/
    : g/ q! w% R1 i& O: b) Z8 n, X4 N
  265. void CE_Low()
    $ m5 L7 P2 ?8 w+ I  ~: ~8 p+ S
  266. {        & \3 t, I  m& C% M5 O4 M% N
  267.         CE = 0;                                /* clear CE low */5 I" F7 k4 H! }
  268. }
    ! r" u1 J6 @9 R! P1 w: Z# d5 r. e! G: e

  269. % D5 W& N! Q0 H# h: ]6 e; }, ]
  270. /************************************************************************/
    8 L1 V) }: `2 @8 T- J$ [
  271. /* PROCEDURE: Hold()                                                                                                        */& b* L+ y7 u& W, V
  272. /*                                                                                                                                                */
    4 ]) ^8 E6 U+ T4 _/ Y) V
  273. /* This procedure clears the Hold pin to low.                                                        */' T* j) f: P' I. k
  274. /*                                                                                                                                                */" P( [4 {+ V7 ]7 O0 D. b$ E& @. n
  275. /* Input:                                                                                                                                *// g8 Y5 g! \3 O( C2 F. l- t
  276. /*                None                                                                                                                        */  n( b% S& z7 U: o8 R
  277. /*                                                                                                                                                */2 K5 \0 ~7 s& |" t1 J8 P& E& r
  278. /* Output:                                                                                                                                */
    " b1 k& Y% R0 `  k" {
  279. /*                Hold                                                                                                                        */
    , k/ w( P/ q# P# W& l/ T. N
  280. /************************************************************************/
    % K4 |2 `4 e; s* A& |
  281. void Hold_Low(); ~; `. z8 M2 [$ p# d- W4 k! y
  282. {7 ]* Q! f# f) T8 w! {8 R
  283.         Hold = 0;                        /* clear Hold pin */+ z# a% C7 T9 O1 x$ j/ W" K  y, G
  284. }' h9 ~1 ^/ q9 ~- B! @" P7 ?
  285. ) o8 p, F% E$ w& _2 `
  286. /************************************************************************/
    8 @  |; Z! m$ i2 X6 X8 S
  287. /* PROCEDURE: Unhold()                                                                                                        */( u- }4 }1 g$ p* x5 ?: Z# b0 p6 F
  288. /*                                                                                                                                                */& u  {$ L, l$ u4 \3 U6 J" J7 ?
  289. /* This procedure sets the Hold pin to high.                                                        */# U: m3 o. q0 c% B. s9 N8 o. L% \
  290. /*                                                                                                                                                */
    9 g6 m4 K) {( \' `; x
  291. /* Input:                                                                                                                                */  V& A% R- X1 e' G' p" F
  292. /*                None                                                                                                                        */
    + c: [) D1 j( |9 Y6 a" c
  293. /*                                                                                                                                                */7 h6 P$ Z! a$ C2 v! V
  294. /* Output:                                                                                                                                */
    & {1 d8 I+ J3 M3 y" {
  295. /*                Hold                                                                                                                        */) Q" ~' @; @9 ?2 Q( J
  296. /************************************************************************/
    6 |4 E8 {/ ]3 k0 X
  297. void Unhold()
    " \; O4 I. ?  ^' a- K+ g$ q
  298. {+ R8 K- Q) ^3 m7 _* M
  299.         Hold = 1;                        /* set Hold pin */
    & R/ B1 E+ V) l& t) E' ?7 b; K
  300. }
    ! W, [" U$ q  n3 q7 k

  301. # Y. [0 ~5 n6 d. k7 S
  302. /************************************************************************/- G8 L. P4 u5 |
  303. /* PROCEDURE: WP()                                                                                                                */; ^4 F; P4 I! b& b# u6 L
  304. /*                                                                                                                                                */& `7 u9 \  _5 h! D! t3 @8 v
  305. /* This procedure clears the WP pin to low.                                                                */
    + y8 G! H# K4 K5 h; s# y4 O
  306. /*                                                                                                                                                */  W  G5 j; `; F; ~/ k+ c- R: H
  307. /* Input:                                                                                                                                */
    ! K0 a% Y% Y) T' x7 h  ^
  308. /*                None                                                                                                                        */
    - L7 i( `, P* f9 A4 b7 m; _: ~; U
  309. /*                                                                                                                                                */3 t" ~, N2 F8 l" A
  310. /* Output:                                                                                                                                */
    ; S7 J, j8 \  F  T4 A
  311. /*                WP                                                                                                                                */9 H) \* Q, g3 n/ g# k# f2 h
  312. /************************************************************************/1 n. Y% \, P8 T) r' ~
  313. void WP_Low()9 q/ F3 J" _2 A5 q4 I' M  C
  314. {
    / I: ~& P# q% \( M% ^. G; O! x# f, w
  315.         WP = 0;                                /* clear WP pin */
    6 b! `/ c- Y7 o, c! s4 T0 ?! s
  316. }
    # z4 F% J0 B( ~7 ]/ x, \! W( P
  317. 9 e7 c- Z$ b9 E
  318. /************************************************************************/- s1 ~/ J- N8 O4 v
  319. /* PROCEDURE: UnWP()                                                                                                        */( a7 E$ m0 ]% k+ w2 n, G
  320. /*                                                                                                                                                */6 s, B  {. y& A7 Z  z# q
  321. /* This procedure sets the WP pin to high.                                                                */0 D  R$ N; \: X1 }. `
  322. /*                                                                                                                                                */8 Y0 r+ s/ d/ N; m0 K" J: }4 e& ?
  323. /* Input:                                                                                                                                */
    3 A+ l5 G, v4 t6 r8 F& r
  324. /*                None                                                                                                                        */
    ' K& t" z8 L; P1 V5 v6 x/ R9 j  }8 j, o
  325. /*                                                                                                                                                *// o; {" _" b. V; u; X! G+ k4 x" R0 m
  326. /* Output:                                                                                                                                *// n0 A, ]3 B1 D# g+ ^1 N
  327. /*                WP                                                                                                                                */, D4 K9 Y+ q0 R
  328. /************************************************************************/
    $ v3 E4 Z6 R2 h
  329. void UnWP()
    ( K+ E3 }# c6 k/ e6 R
  330. {, W) Y7 ^. k. k3 m' g; k8 {
  331.         WP = 1;                                /* set WP pin */
    9 M- X; ~3 T# k
  332. }, @- `8 u. i4 C, ?$ j

  333. $ h4 U# ~8 n3 q
  334. /************************************************************************/
    6 \" s7 k  S) m" O$ N2 h2 ~
  335. /* PROCEDURE: Read_Status_Register                                                                                */6 ^; Y3 b' R& f9 \$ v* G
  336. /*                                                                                                                                                */
      n6 \) O2 ], e0 c% u8 B0 g
  337. /* This procedure read the status register and returns the byte.                */6 {6 ?% |5 G' R  O* J+ o
  338. /*                                                                                                                                                */
    6 _7 e8 b4 h6 g3 o) V
  339. /* Input:                                                                                                                                */
    0 V6 J: ~2 e5 N2 u
  340. /*                None                                                                                                                        */
      B- ?8 O% J1 a  Z
  341. /*                                                                                                                                                */
    ! q0 |1 i/ A  ?- a
  342. /* Returns:                                                                                                                                */- P* n9 j$ u5 @+ V9 a7 t% r3 a
  343. /*                byte                                                                                                                        */
    ! C3 A7 Q  J/ }. _
  344. /************************************************************************/* i* P2 ~8 Z  H% z( u1 P7 l! U
  345. unsigned char Read_Status_Register()  C) R7 P) `( J/ U9 ?4 e
  346. {/ b9 Y! u% k8 S. \% J9 w3 U( m
  347.         unsigned char byte = 0;
    / z$ w  |( e. b& ^+ `$ a
  348.         CE_Low();                                /* enable device */
    . D& k) M3 Q1 @2 V
  349.         Send_Byte(0x05);                /* send RDSR command */8 a. A9 r/ f/ W6 N7 p5 ]7 J/ M
  350.         byte = Get_Byte();                /* receive byte */
    : ^+ f1 j- \7 c' N4 c. O
  351.         CE_High();                                /* disable device */* W% t& x7 G5 n8 ?6 r, B
  352.         return byte;" c6 g& g$ D8 S4 c+ U# [1 `, H# D
  353. }
    % Q! h, w* Y7 e. z

  354. 2 o- X( s' I2 m
  355. /************************************************************************/
    % y: I( Z+ m" b' \) r$ E
  356. /* PROCEDURE: EWSR                                                                                                                */) w4 a% Q" i& s4 o+ _" V
  357. /*                                                                                                                                                */1 J- @. |; E8 _! I2 @- l/ Y
  358. /* This procedure Enables Write Status Register.                                                  */- s3 x8 W9 v' ]! e! h
  359. /*                                                                                                                                                */1 R4 G5 W5 h4 g0 L& |5 k
  360. /* Input:                                                                                                                                */
    ; A7 w" A1 A! w+ }: P
  361. /*                None                                                                                                                        */+ x# q+ ]0 Q" F- J
  362. /*                                                                                                                                                */5 W* m) N) p% P: u" @, x$ t
  363. /* Returns:                                                                                                                                */
    3 V# W6 Z0 D6 Y# y0 o" g1 o2 f6 G+ Y
  364. /*                Nothing                                                                                                                        */- a3 t9 T0 x' M5 q' l
  365. /************************************************************************/
    5 G0 w/ D* Y6 ]( d7 d
  366. void EWSR()
    ; I% W/ E& s- n7 B7 t
  367. {
    9 ^5 d6 W! |) f( w: v
  368.         CE_Low();                                /* enable device */
      E8 @/ L8 a+ M3 B9 V$ `
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    / r; P1 F. ^1 D' I7 L  C
  370.         CE_High();                                /* disable device */$ F1 S8 O. u3 W" z# X
  371. }- R' L5 G6 v- N5 I9 ?8 T, v
  372. 5 r" D8 f, K' F2 a
  373. /************************************************************************/
    . K; \8 e9 l+ L  |5 Z! u8 m
  374. /* PROCEDURE: WRSR                                                                                                                */# s4 u/ n# b2 G
  375. /*                                                                                                                                                */3 X% q3 V4 I$ W9 n$ z% {
  376. /* This procedure writes a byte to the Status Register.                                        */
    0 I; S' e! I+ E0 V3 H
  377. /*                                                                                                                                                */
    * Q7 f: e* K! Y1 B8 e( a$ l
  378. /* Input:                                                                                                                                */3 J. H6 a  X8 ]. j$ B7 y5 I
  379. /*                byte                                                                                                                        */! y) G4 c, d/ P+ o" q
  380. /*                                                                                                                                                */0 y4 {9 {0 X; L3 n# h" N6 C' S: P
  381. /* Returns:                                                                                                                                */- I% i4 _7 }: p" ?4 k6 Q4 q9 p
  382. /*                Nothing                                                                                                                        */
    ! N: u- D; {# l9 {5 }5 A* T
  383. /************************************************************************/
    / h4 C  x2 Z# H- Z; W2 T
  384. void WRSR(byte)4 z- Y+ E3 ?* ]$ I  o2 s- S8 L
  385. {: X# R$ [9 f4 v  q
  386.         CE_Low();                                /* enable device */. w: j0 w7 P; c6 C+ f( c9 d3 i
  387.         Send_Byte(0x01);                /* select write to status register */# E( O; A6 y# _' ?1 J
  388.         Send_Byte(byte);                /* data that will change the status of BPx " s* c( z5 i4 d& _: i
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ! F  G- P. N$ T; T$ k% X
  390.         CE_High();                                /* disable the device */1 F2 n; K) \) J+ Q- H6 @4 w
  391. }8 v  Q5 `$ I  d) s- E3 d; U
  392. & a2 C9 U3 q6 L# i7 {; ^
  393. /************************************************************************/, N" |  ?# l/ i/ _1 j7 U. F
  394. /* PROCEDURE: WREN                                                                                                                */; R& \. U  D* C- ^; N" ^1 g+ O5 ~% u# O( m
  395. /*                                                                                                                                                */
    : r/ C* t) }1 `6 Q/ M: r, L
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */. [" E' _+ F- |  X% a1 m
  397. /* to Enables Write Status Register.                                                                        */( N6 K$ a) b4 }, V
  398. /*                                                                                                                                                */% z- h& X. M: r. n4 W# n- L  `
  399. /* Input:                                                                                                                                */& `0 L+ ~9 v$ x* S+ \' F1 K+ u% L
  400. /*                None                                                                                                                        */
    9 C: N$ p" r* r0 v
  401. /*                                                                                                                                                */5 z; `2 `7 W! Q7 @0 B& w
  402. /* Returns:                                                                                                                                */
    3 m& c/ S. M$ q! L3 \  }! b+ O
  403. /*                Nothing                                                                                                                        */. A4 ?+ }# C; m. _
  404. /************************************************************************/
    0 [. r" N$ @: v2 J) r! ~
  405. void WREN()
    - x- D" n& R0 ~, d# D" J! |; x
  406. {2 I2 p/ B* r$ p+ z6 f2 S: |- L( u
  407.         CE_Low();                                /* enable device */: H& t5 ]" _3 s5 r2 L) p9 L; o9 Y
  408.         Send_Byte(0x06);                /* send WREN command */- _- S! a4 z, ]7 |# b9 C$ y( |
  409.         CE_High();                                /* disable device */4 ^' g. p# |2 x0 C  J- U
  410. }
    " ~9 d% l) s) I3 a  u( M* |# j
  411. 5 L$ d8 W1 [# J/ Y
  412. /************************************************************************/% ^6 z! {9 o, r1 _" ~+ u
  413. /* PROCEDURE: WRDI                                                                                                                */) P$ [3 J+ Z; Y* [0 [3 [- a
  414. /*                                                                                                                                                */
    ( F$ |. v) W1 z% q( ]3 `% D0 n5 h* z
  415. /* This procedure disables the Write Enable Latch.                                                */
    " P4 z: ^% }6 k9 b5 s
  416. /*                                                                                                                                                */' F9 X/ v: d# B
  417. /* Input:                                                                                                                                */, w2 i5 B2 r7 k6 B  ^/ @: P7 M
  418. /*                None                                                                                                                        */
    , M7 ?% [6 k$ u/ ~! Y9 d3 N
  419. /*                                                                                                                                                */& ~6 e1 e! f$ d7 [7 x1 ^
  420. /* Returns:                                                                                                                                */  ]) @4 J  s+ x, W3 t( @( z
  421. /*                Nothing                                                                                                                        */
    . w4 I  ?+ T0 t* x0 b. Z( H" Y
  422. /************************************************************************/  Y. t  e- k/ u3 j& e# W8 b
  423. void WRDI()4 ~3 I0 T+ c- D2 I0 P
  424. {8 D/ N& \6 Y" a, F: R, Z
  425.         CE_Low();                                /* enable device */) x/ _2 ?; O' y
  426.         Send_Byte(0x04);                /* send WRDI command */
    3 W3 ]& g9 W: y8 f2 P# Q
  427.         CE_High();                                /* disable device */! k. T6 Q4 H1 K; x% w& m
  428. }
    * U& s# E4 \" u( @6 [' k" l1 H
  429. : F7 o& W  V+ u5 ]- N
  430. /************************************************************************/
    . |/ `- E# L1 q& ]" ?3 J/ @
  431. /* PROCEDURE: EBSY                                                                                                                */4 J2 S& ?' j4 u5 v5 J
  432. /*                                                                                                                                                */5 Q- y% w. Q3 @, ^
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */4 u" w7 I: G! V7 j- p* F, O
  434. /* programming.                                                                                                                        */2 X3 V- y/ q4 k  b
  435. /*                                                                                                                                                */
    " W& H" |  @5 a8 `+ W
  436. /* Input:                                                                                                                                */
    : k) E% a. f" `$ c
  437. /*                None                                                                                                                        */
    6 C1 H  }9 `8 c
  438. /*                                                                                                                                                */2 c" d" U$ q' t
  439. /* Returns:                                                                                                                                */& A! Q0 t- r% [7 m. O7 w6 b* t
  440. /*                Nothing                                                                                                                        */1 p/ O$ P! f; k9 p" n
  441. /************************************************************************/
    ' B5 d- x" a2 {3 P$ }4 X/ X. ~
  442. void EBSY(). W7 }( U  i# L! [2 G
  443. {, v# s" h9 [7 \7 P
  444.         CE_Low();                                /* enable device */
    " q& W1 L' W" K( }6 T* E
  445.         Send_Byte(0x70);                /* send EBSY command */
    % B, _+ i. O% Q0 X
  446.         CE_High();                                /* disable device */
    * `6 @5 j! K- y! a: N
  447. }& u$ y5 L  D% y- ^% u) R

  448. 5 p2 |: Q( [3 L
  449. /************************************************************************/
    8 g# n; ~7 E, b1 b7 d& S4 I
  450. /* PROCEDURE: DBSY                                                                                                                */- a4 d+ Z+ M/ `6 Y2 h
  451. /*                                                                                                                                                */  ?# Z7 G5 s7 K
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */# x  A& L+ B9 \9 V
  453. /* programming.                                                                                                                        */( e; p1 p6 M' a' G
  454. /*                                                                                                                                                */
    & T, B9 G& M3 K  X; ^/ Z
  455. /* Input:                                                                                                                                */9 P, O$ b# E& M
  456. /*                None                                                                                                                        */1 Z( i6 `  [: v; X  n, P& p
  457. /*                                                                                                                                                */$ M# Z% [! H% z( Q! f$ ]0 e
  458. /* Returns:                                                                                                                                */
    " [0 Z" W9 {  Q" b& \
  459. /*                Nothing                                                                                                                        */
    ! H  B8 a4 C, z* A( Q( ^/ T3 u  {
  460. /************************************************************************/
    & o) j0 _& ^. m" D, e0 Z2 U* q
  461. void DBSY()
    * m% M+ ]" {. v1 q. r5 W3 w
  462. {
    5 [  ]. t9 k$ _8 k& l
  463.         CE_Low();                                /* enable device */0 J  z. F. Y5 Y6 C3 A
  464.         Send_Byte(0x80);                /* send DBSY command */
    2 q; F# t% j9 ]+ }6 u. o
  465.         CE_High();                                /* disable device */
    7 m. M) j( X: S$ {3 i
  466. }
    ( [% g( j2 R) T$ D/ i  D
  467. $ B# n% |/ c+ q$ K* y6 O( `
  468. /************************************************************************/3 f9 x; Q8 t+ z; u. B
  469. /* PROCEDURE: Read_ID                                                                                                        */5 [" t; m* S0 o
  470. /*                                                                                                                                                */" W2 p( ~$ H7 z( U+ b; C/ X
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    # ]; s' D( B, Y2 c4 o0 k3 S, V
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    , ]) v' V8 ]& v/ S
  473. /* It is up to the user to give the last byte ID_addr to determine      */8 d7 e/ I7 V6 Z3 B8 @$ ~9 F
  474. /* whether the device outputs manufacturer's ID first, or device ID         */; Y; @( a1 D# s% Q# m0 K
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    $ ^' H% U" \# e
  476. /* variable byte.                                                                                                                */
    / m5 ?/ F6 Q) s: [& u9 ^. h
  477. /*                                                                                                                                                */, t5 _0 X# u5 M, v
  478. /* Input:                                                                                                                                */
    , V/ C+ i0 O" Q8 d5 Z7 r( _) Q
  479. /*                ID_addr                                                                                                                        */% Q5 z- t+ f5 V8 X: @
  480. /*                                                                                                                                                */* m  `+ ?9 k. ~) l7 B
  481. /* Returns:                                                                                                                                */
    ! }/ C! t0 l, V
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */  O( n! y+ P# S8 X9 V* K% H0 l
  483. /*                                                                                                                                                */( z0 a% f8 A, r! x/ a/ j
  484. /************************************************************************/$ C5 o1 Q- f+ ?
  485. unsigned char Read_ID(ID_addr)
    - {* X4 o, P" `5 {
  486. {
    : a" {* F  T, t2 J! C7 a9 T
  487.         unsigned char byte;
    # D& F" u  d  D
  488.         CE_Low();                                /* enable device */
    , G. Y; s+ R$ C6 x
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */& [, P5 \. h: w* x9 C7 k0 K
  490.     Send_Byte(0x00);                /* send address */* d& \3 S" p3 n4 X4 x! P
  491.         Send_Byte(0x00);                /* send address */# P8 ]* T5 @9 W+ h
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    + ^% G% J& c5 B) Z
  493.         byte = Get_Byte();                /* receive byte */
    # j7 C- z- `* }9 `6 k9 y
  494.         CE_High();                                /* disable device */
    7 p- x* s, x$ j* y8 N3 Z/ C8 W" F. p
  495.         return byte;
    # H" C# [2 ~, V9 e
  496. }4 c% l: C$ {( J$ W" R' w* o. S+ }

  497. 3 x$ H% |* z: {5 e
  498. /************************************************************************/
    ! t9 |- o5 ^& u" p% E( R9 C2 a
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    $ U6 P$ `) L0 E4 s
  500. /*                                                                                                                                                */
    0 U& d+ H+ U" J! J0 U
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */$ d+ y/ b: R- L- C
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    : g; E& ]+ O, Z8 P1 b0 J$ Z
  503. /* Please see the product datasheet for details.                                                  */. d" V# @; ~$ }
  504. /*                                                                                                                                                */. b2 h0 p/ U5 z& i/ b7 j
  505. /* Input:                                                                                                                                */
    8 r4 ]3 @7 m( N/ ~' ?9 p, J
  506. /*                None                                                                                                                        */0 T4 I- R" g8 ^2 ?5 r9 p
  507. /*                                                                                                                                                */
    - v: c5 @$ m, C/ J& m! f
  508. /* Returns:                                                                                                                                */$ n: }& r* k( Y5 ~) s% i& n
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */8 o" F3 n4 j9 f* q' a' b& {
  510. /*                 and Device ID (8Eh)                                                                                        */% X: C7 T7 t, l7 _$ T0 H( d4 {
  511. /*                                                                                                                                                */  {& q* u* \  ]
  512. /************************************************************************/
    4 b" R% I, I6 a$ L! j
  513. unsigned long Jedec_ID_Read() 5 I) i6 C/ ~/ }, c3 C: R
  514. {9 g/ j8 d8 j+ r* D2 ?6 [8 [5 D
  515.         unsigned long temp;8 t3 D& l4 x! G7 g
  516.        
    6 n8 |, C& d" O# ^
  517.         temp = 0;
    5 k* Y" N& b0 T* \; h# U, ~7 [: F
  518. 7 b. j3 s* i! T* \  Z
  519.         CE_Low();                                        /* enable device */9 j" p. _% _) R% B& X
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    - N& p/ ]: J* @. {, K& T4 I! ]
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */! s( g! C; H0 H% f' y5 L! K; D8 m" J
  522.         temp = (temp | Get_Byte()) << 8;       
    . T% c3 M) S9 f: l; D( Y: K
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    5 g0 F" d. E8 w5 @+ O$ R
  524.         CE_High();                                                        /* disable device */; s# R/ F& \# s

  525. ; z$ C! r5 I1 s& C, `; D6 g  a: y
  526.         return temp;5 p6 A3 L1 v) k
  527. }
    # g3 T3 \1 H, i: T8 C8 X2 D

  528. $ ]' C2 B' m; }; P
  529. /************************************************************************/7 k1 S8 N3 D- r" T. @4 f+ q
  530. /* PROCEDURE:        Read                                                                                                        */
    . P, f! C. U4 \7 j2 h
  531. /*                                                                                                                                                */               
      E- i1 E7 v2 U& J
  532. /* This procedure reads one address of the device.  It will return the         */
    / K8 x; w; u: r7 [  @9 |0 x# j; v) X
  533. /* byte read in variable byte.                                                                                        *// z! K) o4 T, {7 V0 R
  534. /*                                                                                                                                                */; H4 z4 _1 [6 B4 L$ q
  535. /*                                                                                                                                                */* K# T( `7 ^2 z# A
  536. /*                                                                                                                                                */4 ~/ I/ Q5 @3 d/ x
  537. /* Input:                                                                                                                                */% H; R# X7 p" c' x0 ]! ]
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    0 ?  T: h/ f0 B" n( J. a( R
  539. /*                                                                                                                                      */
    : T* y* b, _: e
  540. /*                                                                                                                                                */
    ( k: j3 U& N  o. j
  541. /* Returns:                                                                                                                                */
    7 f  m. t7 C) Q' ?' h# d
  542. /*                byte                                                                                                                        */
    + O5 X) n* {6 y6 e9 E' }5 P
  543. /*                                                                                                                                                */
    ! V9 i3 F" E; B# ]1 m0 ?% M
  544. /************************************************************************/: O2 x; R' N6 U  w, w
  545. unsigned char Read(unsigned long Dst) - s5 e9 C3 _9 N/ o" s
  546. {
    : U# q/ y  j3 S2 {; p
  547.         unsigned char byte = 0;       
    # A8 k- X; G: d# z) q% @+ f# |* ^8 N
  548. % o: D1 q' y& g2 K4 T9 P
  549.         CE_Low();                                /* enable device */* `* |3 l& U: i8 k% P* F" J: j1 t0 H
  550.         Send_Byte(0x03);                 /* read command */3 m5 L/ ]& A  m& E
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */6 I0 n3 {- v2 p6 h) M8 u
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & N3 k3 O2 a# R0 P
  553.         Send_Byte(Dst & 0xFF);
    1 B% O( e  n+ m, b
  554.         byte = Get_Byte();. g; c0 Z0 g5 N9 C0 G! D
  555.         CE_High();                                /* disable device */& G3 W" f& R: e: K3 \
  556.         return byte;                        /* return one byte read */7 M& j7 K' {5 L. h- O: @
  557. }
    : O' x* Q1 W$ E& _

  558. * {3 n" [/ E* X& {
  559. /************************************************************************/
      ~) _" h) y1 T' `, {. H
  560. /* PROCEDURE:        Read_Cont                                                                                                */
      }) _+ z5 N9 o. t( u- L$ Q# ]. J+ X
  561. /*                                                                                                                                                */               
    ( b5 w) b; J3 r3 F' ^$ N/ s
  562. /* This procedure reads multiple addresses of the device and stores                */
    8 X+ S- {/ c3 B) D8 J
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*// I. x( `3 D) k, m( H! E6 K% H7 U
  564. /*                                                                                                                                                */
    . m0 E* [, W8 @
  565. /* Input:                                                                                                                                */
    - W: f2 Z; I0 E4 l
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */" G5 [( I5 |$ W# P: D+ A' P
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */* m4 g. H( Y4 }* l4 Y2 G, k
  568. /*                                                                                                                                                */
    + C8 f  k/ p# Z$ ^: J
  569. /* Returns:                                                                                                                                */5 i3 {( o- a, ^' ~( F& F
  570. /*                Nothing                                                                                                                        */
    ! l; c' B4 c2 l* l
  571. /*                                                                                                                                                */' x9 |: q  L$ U. H* H) m6 ]
  572. /************************************************************************/
    * o0 S6 M' Y) \. |
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)" C/ z, L  K6 ^; w
  574. {" Z9 l! J+ v1 N+ A& |9 h9 p
  575.         unsigned long i = 0;
    0 ?3 b) a/ K6 q* s
  576.         CE_Low();                                        /* enable device */" w8 k( d' ?, t0 L  P+ f* ~
  577.         Send_Byte(0x03);                         /* read command */2 r: z; t9 \9 z
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' \" Z5 R/ r* r- s! h
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));( u( G+ T1 W- r6 D/ T
  580.         Send_Byte(Dst & 0xFF);
      B# ?/ F5 X+ s9 M7 j, N/ q/ v
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */# N' N+ `% J& r: M4 Z/ d( K
  582.         {
    7 k5 q* W: P7 ]# |5 R
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    3 {. E" V: f5 i; ^  n; s0 B
  584.         }8 b. P# a, S( X7 C3 u$ }$ h
  585.         CE_High();                                        /* disable device */
    0 v9 b. y8 @( j
  586. & p! @% p, |7 U& d4 E
  587. }4 [/ {) h, L$ [/ T4 \) W4 p. _7 m

  588. ) {5 y: @; I& b/ W$ R0 a3 O# E
  589. /************************************************************************/
    1 A7 ]' j  ]% `  u4 |) \) M
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    9 _9 n+ y) a3 P
  591. /*                                                                                                                                                */               
    0 r" ]0 ^, z9 C4 _* }/ K' n1 V
  592. /* This procedure reads one address of the device.  It will return the         */
    8 A, y  u+ F, s$ W
  593. /* byte read in variable byte.                                                                                        */
    # G9 O$ Y) E" Q2 n/ g
  594. /*                                                                                                                                                */1 e$ U" E5 |* M, ?1 B+ H
  595. /*                                                                                                                                                */
    3 }: i0 F4 s/ C# F+ b6 j
  596. /*                                                                                                                                                */
    , j) D6 H) l! |! {. a8 G4 F4 y! a
  597. /* Input:                                                                                                                                */+ p+ ]/ i7 @& o, g- }! P; {
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */: f0 \* `6 i: k& `
  599. /*                                                                                                                                      */
    : l9 G  ^: D% L- k4 G7 Q
  600. /*                                                                                                                                                */
    ; N# _% D) y$ o
  601. /* Returns:                                                                                                                                */0 K5 g% L( T. [
  602. /*                byte                                                                                                                        */
    7 k8 }+ i5 j6 |5 j) d5 [8 d
  603. /*                                                                                                                                                */
    1 |9 f% I: v; C; q" H. g. d1 Q5 K( g
  604. /************************************************************************/% z' H2 L$ y7 L4 f6 h4 b
  605. unsigned char HighSpeed_Read(unsigned long Dst) 7 g) l# F  n! w# b# j6 q
  606. {2 ?* M/ i& K$ n* l8 l' ~- e
  607.         unsigned char byte = 0;       
    , e1 Q; A" x4 ?- S0 K( B* A+ m

  608. ' |& x; d+ `# ]
  609.         CE_Low();                                /* enable device */
      H5 ^3 K2 P4 J6 g+ a* B
  610.         Send_Byte(0x0B);                 /* read command */
    ( D( a0 d- L0 p: P, A+ G
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ( g% o" k" M9 Y, @& U
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));6 R: o& d6 _. L
  613.         Send_Byte(Dst & 0xFF);
    % T4 g5 H6 d1 ^7 }/ z3 `3 O, ]
  614.         Send_Byte(0xFF);                /*dummy byte*/
    : E9 U( A- F: ^, ]
  615.         byte = Get_Byte();, M  x/ y( C6 U( I
  616.         CE_High();                                /* disable device */
    1 L. O( m+ [* O2 h! I: a
  617.         return byte;                        /* return one byte read */$ v* i# ?% r8 m8 Q/ I. \! h! U
  618. }3 C* Z( E6 `" p$ Z& Y

  619. ' g) r- P' l- k; a0 S, J! d
  620. /************************************************************************/1 o, a2 {! b  e5 j
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                *// W% K9 H9 n* v5 C% f: t
  622. /*                                                                                                                                                */                6 y7 A$ B- o& S! E: [" ]! F/ `5 ^
  623. /* This procedure reads multiple addresses of the device and stores                */6 \/ ]) U/ C. `& u, m% H8 ^" X4 F
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/# u( v6 i! N4 r9 Y
  625. /*                                                                                                                                                */1 u; J/ h/ D2 q1 g8 C
  626. /* Input:                                                                                                                                */
    7 M8 B+ l; m4 \9 J( t
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    . j5 c% f. x* U2 m' L! o# }5 E- o
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    2 M7 T4 ~! l0 C, F# g- h/ U/ g
  629. /*                                                                                                                                                */
    + ^% }- M: v; T) T" N
  630. /* Returns:                                                                                                                                */
    6 J1 e2 P1 l+ a/ _
  631. /*                Nothing                                                                                                                        */
    0 v; Z, D0 p7 k" B/ d2 E
  632. /*                                                                                                                                                */2 t3 [7 e8 [/ d
  633. /************************************************************************/
    1 H7 l9 h( a& m
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)7 U3 C; N' C7 Y
  635. {6 q# l7 S- t7 n
  636.         unsigned long i = 0;
    . p" ?' [2 p2 |+ j% e9 `
  637.         CE_Low();                                        /* enable device */
    : w: Y9 k) R- H1 d" [/ l
  638.         Send_Byte(0x0B);                         /* read command */
    1 z! }2 q  m7 R) m+ V
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ C' y! C, F4 D, T* c' D) W
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 K( P1 }4 }; b, J7 ^
  641.         Send_Byte(Dst & 0xFF);
    % O  J: U# I. C% q- v; z
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    $ C, c/ Y4 ^1 u2 o
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */4 J: I4 ]( c) Q
  644.         {
    $ T3 _$ S& [+ H
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    3 Q: _, {) n/ o2 G. R
  646.         }6 ^- D) E$ r6 o, q  ]& }7 f; C
  647.         CE_High();                                /* disable device */' d6 x: y) m, V3 d2 G
  648. }
    2 r- b. H: j1 E/ r& Q

  649.   Z6 H* |2 }# }3 e* f- H2 J
  650. /************************************************************************/
    # b3 x9 r: d5 j4 e% p
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    3 P) K' J; @& D" O1 z
  652. /*                                                                                                                                                */
    - T+ T- l9 ~7 D1 H, p* I% m, j
  653. /* This procedure programs one address of the device.                                        */; W& i5 [2 J# ~% N- K$ ~, I& e% p
  654. /* Assumption:  Address being programmed is already erased and is NOT        */9 [# K" s" g0 x! Z
  655. /* block protected.                                                                                                                */9 m+ m8 N* z2 ]- b
  656. /*                                                                                                                                                */
    4 V; ^- b8 I4 b$ |
  657. /*                                                                                                                                                */6 j  N5 H$ p! A/ r; Q7 V
  658. /*                                                                                                                                                */
    % v+ x# a" I& X5 L+ e
  659. /* Input:                                                                                                                                */1 e) r5 b8 ]. z
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 C/ |% F0 x1 b) S& ]6 F0 f
  661. /*                byte:                byte to be programmed                                                                */
    9 M0 Q' {4 A  i- y+ S# W4 {
  662. /*                                                                                                                                      */* E+ y( }0 }* k
  663. /*                                                                                                                                                */- v! |) `" ]2 w) p4 \0 }
  664. /* Returns:                                                                                                                                */
    7 `: n9 B+ Y# z. M! \9 _
  665. /*                Nothing                                                                                                                        */
    0 [8 ]& h. t  c6 O
  666. /*                                                                                                                                                */
    / r) _7 `9 Z3 ~0 d% a! a
  667. /************************************************************************/$ v" w  ~6 O4 {/ Y; z' m! s
  668. void Byte_Program(unsigned long Dst, unsigned char byte); \& s  {2 T9 a' V- J) y9 D! w
  669. {4 F0 W5 r5 N9 H
  670.         CE_Low();                                        /* enable device */
    / z. N9 ]( w9 i) y/ I
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    # u1 b* Y6 |5 ^7 U4 A# a: h$ ~
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 C) g) E; i/ Y, S5 A: J" J: s
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 F8 P2 w: d" l8 `* I3 `
  674.         Send_Byte(Dst & 0xFF);/ _4 I5 C# m5 ?2 b8 y" }
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    - s4 F1 F; I3 z2 ]0 W8 }" `: g" I; B
  676.         CE_High();                                        /* disable device */
    ) V  s" S6 v, `% ^  L  v
  677. }( G, J8 k0 ^4 W3 R! L$ r

  678. ' P& v, _5 _8 S4 e- B/ l3 ~
  679. /************************************************************************/; L2 U' ]2 U% e
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ; [1 J& o3 E7 {- n/ I; L" @
  681. /*                                                                                                                                                */
    ! x6 r  l$ I, I9 H: y, |
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    / N  w' h. G% a( x5 ]# F, u: C
  683. /* the device:  1st data byte will be programmed into the initial                 */. q" ^. P1 T1 N3 s
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    0 B) I& v" f/ ^) b
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */. p; L) D: K6 ?
  686. /* is used to to start the AAI process.  It should be followed by                 */- t% m" o7 i$ D9 }4 o8 L2 }
  687. /* Auto_Add_IncB.                                                                                                                */3 l2 J3 D7 S9 x4 Q" \
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 O8 E5 M9 \" e" W
  689. /*                                block protected.                                                                                */
    4 l- K: C# q4 W- J) _( O- M
  690. /*                                                                                                                                                */9 {1 p3 `( K3 T8 N$ I: C7 D# s
  691. /*                                                                                                                                                */- ^0 e1 _  s$ m; m5 @, W
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    8 b( D& c. d9 x* J$ [! U# O
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */2 @+ \# S; _8 P3 U
  694. /*         unless AAI is programming the last address or last address of                */
    ) H. `+ o' l2 X. I9 S. A  I
  695. /*          unprotected block, which automatically exits AAI mode.                                */. j& _6 V% F: j: G# v/ R* o
  696. /*                                                                                                                                                */
    # e4 a8 k; Z: `7 q6 G7 K$ C) B
  697. /* Input:                                                                                                                                */
    ; X, d. E; J* m( f1 d# @% f/ D
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. y6 l% \# X% c+ e+ k
  699. /*                byte1:                1st byte to be programmed                                                        */
    6 o9 h4 X$ Y. J4 m5 X8 X3 L
  700. /*      byte1:                2nd byte to be programmed                                                        */
    # e) L3 p! C0 S2 A
  701. /*                                                                                                                                                */
    : A" E# ^, X- I& F
  702. /* Returns:                                                                                                                                */& M& e* J- H$ P
  703. /*                Nothing                                                                                                                        */
    . \$ `1 v( H- _& \5 A: F" F- T
  704. /*                                                                                                                                                */. A6 |0 S: F) H1 h. ?0 E% ?1 p/ Q
  705. /************************************************************************/
    , q  Y+ P1 x* v# d3 C
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ; n; V) {" ]4 T; C
  707. {* V9 p: P5 F( H! W$ S( \
  708.         CE_Low();                                        /* enable device */& z5 ^6 k; n0 e# u6 c' O; J$ V7 Z
  709.         Send_Byte(0xAD);                        /* send AAI command */
    $ v4 \% _9 k. c: K
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* _2 l- q; k8 ~
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));( F* q  P" S3 b0 z7 E6 X# f! \0 b
  712.         Send_Byte(Dst & 0xFF);
    : ^( ~; O( u; l4 b8 H, s% R) m
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    $ A5 P0 X0 D+ z- G
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( @  {/ x. I( k' C4 m: I9 B
  715.         CE_High();                                        /* disable device */
    ( ]$ W7 f2 g8 }# a: t
  716. }- X) b- {1 K/ E7 ^' e2 r% S0 b7 x

  717. 3 ?7 M8 h4 `- p% j2 m. W" d5 C( L$ k
  718. /************************************************************************/" X/ U: Q+ g) G# P  f: D
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    6 }7 z2 m/ K8 `
  720. /*                                                                                                                                                */  o) F1 l$ e  _3 X* ~& n
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/; a% M  E; r% y
  722. /* the device:  1st data byte will be programmed into the initial                 */
    6 N# f! k* \0 T3 t/ O& I& |5 c+ I
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    3 s8 |+ N! [4 g) ]1 [: R
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */% v0 r7 d3 ^) ~1 s! G5 ~& ?, k
  725. /* is used after Auto_Address_IncA.                                                                                */1 ?% O. T4 ]; s* K/ ~7 F6 X8 I& ~
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    , N1 u! m( j! y1 a5 c( X4 t
  727. /*                                block protected.                                                                                */; x6 a% R4 ^1 m, l* y) ^: i. `
  728. /*                                                                                                                                                */
    , G$ ^- u0 |; |* Z" Y7 t: x" W
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    5 ~4 M" p. c" B$ L+ G! H
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    0 M% s) E6 j& B* k% x0 Z0 k
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */* a4 @* ~( ^0 u/ u9 N: I
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    : x3 b, e; |. Q/ D  C7 s
  733. /*         last address of unprotected block, which automatically exits                 */
    $ E- W6 ]* N! \( d+ P4 W
  734. /*         AAI mode.                                                                                                                        */& V6 w3 h! ^) i
  735. /*                                                                                                                                                */
    . u8 ~9 c; M  \' ~2 q
  736. /* Input:                                                                                                                                */! u$ n. a9 n+ q: }% F1 [4 U# d
  737. /*                                                                                                                                                */
    ) q; w6 c2 a" g. Q6 x' }. U  L
  738. /*                byte1:                1st byte to be programmed                                                        */" w) ^8 P; ?4 O' r  L
  739. /*                byte2:                2nd byte to be programmed                                                        *// }3 c/ Y( c, U
  740. /*                                                                                                                                      */
    / Z9 ]* r, j; y. l0 h+ G1 U+ x7 J# W
  741. /*                                                                                                                                                */
    ' Q) l( f9 u8 G. Q/ I# }, G, W
  742. /* Returns:                                                                                                                                */
    ( W1 s  D7 Q7 _- ~, D
  743. /*                Nothing                                                                                                                        */! _* e9 Z% `" E
  744. /*                                                                                                                                                */7 Q6 j  z9 X( ^- v8 B1 J
  745. /************************************************************************/$ b: [% E/ j* g
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)* p" J% ^3 c& n: _
  747. {% c& Z; _; L& A
  748.         CE_Low();                                        /* enable device */; @. y/ A' G2 w5 r: t& J
  749.         Send_Byte(0xAD);                        /* send AAI command */
    : f4 G1 v; a1 s
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    . b0 ]) n4 }' Q. H, T) r# q' N
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 U; x, o; X& e" h+ a- d; V
  752.         CE_High();                                        /* disable device */! ?! t# f  p/ Q. |9 S
  753. }
    ( K* G! u0 G4 |2 d# ]) a  N
  754. * T, m+ u! r% K8 c- Z
  755. /************************************************************************/
    * V3 N/ D% x! ~
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    3 Y# w* E+ z' q! t% a; z
  757. /*                                                                                                                                                */
      f5 M. T3 c. f: d2 f1 _
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    1 W& W/ ?4 o, G$ h3 [- J& e
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */2 x( s) u: B3 |1 v/ D
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    4 w% D0 \: }& `8 R1 e# Z' p  ~2 {+ U9 X  |
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */% v$ u  I* L- P
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */( @3 S4 T3 ]& u- v9 ~; ]0 A9 S! T
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */+ F. Y3 `1 [6 ^* O
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    3 n6 X9 k/ v8 R% A# Z
  765. /* Assumption:  Address being programmed is already erased and is NOT        */$ h# V$ t8 R7 e3 }
  766. /*                                block protected.                                                                                */
    1 G. r5 F( A& [: M$ u- D% @
  767. /*                                                                                                                                                */
    $ L+ y5 [8 U( _$ h4 e
  768. /*                                                                                                                                                */
    0 s& L) ^- H+ f$ P
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 d! o0 P& |6 z
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */% Z) I5 a/ V# E. H* k, J. Z; c- B
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    . n# t+ J4 n! x) W
  772. /*          to exit AAI mode unless AAI is programming the last address or                */3 X  ^- O; ~- v
  773. /*         last address of unprotected block, which automatically exits                 */
    8 |2 [% U0 |/ I# g! ^
  774. /*         AAI mode.                                                                                                                        *// [' h* p3 @. u
  775. /*                                                                                                                                                */
    2 M% H, q- _/ m, }3 `
  776. /* Input:                                                                                                                                */' G& r  w, t; g/ R% A
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 u* l- C; Y" X' ^/ _, _
  778. /*                byte1:                1st byte to be programmed                                                        */
    % p! q" [  K- c( w  d9 J: Q6 Y
  779. /*      byte1:                2nd byte to be programmed                                                        */
    2 V5 i7 m0 |& r, D& X
  780. /*                                                                                                                                                */- |$ G  A( o+ x
  781. /* Returns:                                                                                                                                *// j5 C: e: P' ?/ m+ R
  782. /*                Nothing                                                                                                                        */5 e& G9 m/ q# s. ]/ K
  783. /*                                                                                                                                                */4 S7 ~& ]/ @# {% Q& t: d
  784. /************************************************************************/& P9 A# B8 H5 }- V
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)8 r+ }# o3 y% t% Z1 w
  786. {3 y0 j9 o0 T) O5 v
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ( a% ]% I/ T& M

  788. % C7 T. M. V7 n/ i$ O
  789.         CE_Low();                                        /* enable device */
    $ N# D4 E( z! H8 i3 s; ?9 b
  790.         Send_Byte(0xAD);                        /* send AAI command */
    1 V/ d! u! p/ v: [( s3 T) O3 Z% M
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 T- Y* H" e0 ]7 o7 a1 ^# L
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));+ b$ r: y8 r- i# l- C
  793.         Send_Byte(Dst & 0xFF);
    ! O: c5 `( [2 B- r7 \% B) n
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        6 g* r, B2 J8 i) q) P) U
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */4 u0 a2 F& C( _8 J! {' `
  796.         CE_High();                                        /* disable device */+ [0 U/ C' o( u6 p# P, \) @1 Z
  797.        
    ; H  C. i4 o$ p7 h# E% L2 a
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */5 r; E; _- i$ e# [2 F9 h4 B8 s$ g) z9 l

  799. & T! d# r; m+ k1 W9 M, G
  800. }
    9 `( ]9 Z% k# L, j# k1 b$ H0 l

  801. , h2 `# I6 G% y! Q
  802. /************************************************************************/( |6 K8 U/ ~. e1 W3 @- p3 A$ {* D
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */( }  D$ w3 l9 K% Q0 R
  804. /*                                                                                                                                                */
    ' S$ h  [8 o% p2 H
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    1 g9 S' v% `* h5 @8 G
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    9 c: k0 K9 [0 P7 i3 k, d  w4 \' h
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    - f7 \7 E# ]3 V- G5 n
  808. /* the device.  The 1st data byte will be programmed into the initial   */0 n! S) r9 ?' @4 V
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */* z9 |& c( r% w$ j! g2 J" G. L5 e
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */- z& `  K7 x  K  n  s6 j
  811. /* used after Auto_Address_IncA.                                                                                */8 }$ _5 g! h% e" S+ J
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    - Z9 X2 X0 @0 K2 H* c# A
  813. /*                                block protected.                                                                                */
    1 {4 i0 w; Y. m0 V
  814. /*                                                                                                                                                */
    $ v% F- ]/ F. n' A2 m8 D+ e
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
      Z+ V! g0 U" w' H* {. I- h
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    . `6 z/ v( e% `# H8 i1 z0 f
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    . q' a5 s3 a& |
  818. /*          to exit AAI mode unless AAI is programming the last address or                */  o4 {' M# ]1 w3 Q5 z3 S
  819. /*         last address of unprotected block, which automatically exits                 */. h; d& T7 w# L. m9 |. v/ c3 L- P
  820. /*         AAI mode.                                                                                                                        */
    0 x, j$ o7 f) d; B* w/ u4 N
  821. /*                                                                                                                                                */" M5 u9 e2 Y! P& k
  822. /* Input:                                                                                                                                */
    0 \3 }8 s# `$ ?- f
  823. /*                                                                                                                                                */" z. `& b/ L5 ], |2 n
  824. /*                byte1:                1st byte to be programmed                                                        */) w; D* m' f  C3 W
  825. /*                byte2:                2nd byte to be programmed                                                        */
    % m: {1 ~5 a; V  T8 J9 r
  826. /*                                                                                                                                      */
    . e$ @/ W' }0 m5 Z
  827. /*                                                                                                                                                */, R8 I; i, @  m; u8 ~5 ?
  828. /* Returns:                                                                                                                                */
    , b% D4 X) N  Q0 B- R4 \1 |. v  Z
  829. /*                Nothing                                                                                                                        */) `4 |( u, t0 f4 o" m5 c6 k/ F
  830. /*                                                                                                                                                */
    & P# X8 G, O3 J- F5 A# c
  831. /************************************************************************/
    1 l! j  ~$ U3 x" Z3 T$ M
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    $ A- Y6 B( ^" C) z2 f
  833. {; d; L9 M0 X3 e8 V- _5 R, z
  834.         CE_Low();                                /* enable device */
    6 t  s. X2 F! Y3 l3 H8 U' g! y$ f3 z
  835.         Send_Byte(0xAD);                /* send AAI command */
    ) O, s6 u1 Q& O, u7 o  M
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */7 _' P5 k) z8 w0 b7 c0 |, C8 T! G
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    # {  }! I$ J- _2 L& @
  838.         CE_High();                                /* disable device */! H! r8 g2 V  ~/ r, e. u8 N8 q
  839. # K, I; U  B* c& G, N( T6 w) v
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    * B9 O  s/ @# }* a7 m  l

  841. 1 S, J) |0 G" v5 i% n+ p/ m1 Z
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    3 M. Z2 f$ O, Q; u% ]
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    8 y+ M+ ?2 G) f8 f
  844. }
    . S3 j0 ]& P% V( \5 ]1 K1 _0 N

  845. + \- C0 s. J* E$ ^1 i
  846. /************************************************************************/! ?5 n! m4 s9 o3 r# W! k
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    + m& ^6 `; @& N! b
  848. /*                                                                                                                                                */8 Z# ?3 ?% r2 P7 `; B( e2 {
  849. /* This procedure erases the entire Chip.                                                                */0 C# C9 ]1 ?2 d
  850. /*                                                                                                                                                */9 F) J, @  |" p- h5 R
  851. /* Input:                                                                                                                                */
    * ]* w) p4 n# q# r
  852. /*                None                                                                                                                        */* V: j4 ?$ R' Y8 D: l
  853. /*                                                                                                                                                */
    * j9 ~6 e( ~( v  u0 O% F  F
  854. /* Returns:                                                                                                                                */
    ' x5 V7 F% j1 Q. G6 [
  855. /*                Nothing                                                                                                                        */
    + \6 T0 y$ Q; L' H
  856. /************************************************************************/
    - |4 ^5 D* M1 e. g( P+ q- O
  857. void Chip_Erase()
    , F1 g( f# z5 A+ ~" f# v; [
  858. {                                                  `/ c" x' x2 m, c# _- T
  859.         CE_Low();                                /* enable device */- A2 u: p+ r/ h; S: n
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    9 B9 x8 E9 f, K" h& ^, k  [+ F7 V
  861.         CE_High();                                /* disable device */; U( k5 X5 |8 P8 G( T
  862. }2 z5 e, _" p, u* G
  863. 8 S2 L5 o; y: {+ E  y' {8 Q; B
  864. /************************************************************************/; k- d! k0 M) ^: Z: c
  865. /* PROCEDURE: Sector_Erase                                                                                                */  X; r& V' k4 {5 Q# M
  866. /*                                                                                                                                                */2 O( N8 e! Z) _, M! ]9 o$ K$ f
  867. /* This procedure Sector Erases the Chip.                                                                */0 Z2 O& J3 L# L
  868. /*                                                                                                                                                */
    ( E5 ^, I5 D" Z) ~
  869. /* Input:                                                                                                                                */  z) w4 M* [% [/ K0 ?4 l
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - E# L3 R# V* Z2 q
  871. /*                                                                                                                                                */
    * U, t! {# ?% I* b& p
  872. /* Returns:                                                                                                                                */5 U0 |6 ~! j# ^' Y2 z7 x
  873. /*                Nothing                                                                                                                        */
    + t' u$ q. H+ G! r' B
  874. /************************************************************************/* s+ q( g# J6 ]! y0 b
  875. void Sector_Erase(unsigned long Dst)6 [& Y$ g2 L# ^  f3 U  |
  876. {& W* ?+ e2 b' u, B4 S! Y  H; f
  877. " q2 o- i; j9 [' ]( R/ E
  878. 1 |  ^5 X4 F7 l. F/ h/ ]
  879.         CE_Low();                                        /* enable device */) X5 P) y1 N+ B! Q7 x- C$ o3 B
  880.         Send_Byte(0x20);                        /* send Sector Erase command */( @5 e8 l* Y! X/ b' ?) Q
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    / [8 v, Z3 d. ]: e8 a' L; y
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));3 J% r- M: o% `; T) B1 j8 x
  883.         Send_Byte(Dst & 0xFF);
    - A% M' q6 q8 \: |+ `; j- G* W
  884.         CE_High();                                        /* disable device */
    , _1 ]: Z/ v+ I5 B8 Y
  885. }       
    $ `. d( d' `6 Z. ^. ]

  886. ( G: Z- u5 F1 E- k( J! R8 A
  887. /************************************************************************/
    $ e& r3 a; u4 E! b! K6 ^8 l8 v2 S
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    / r" ~# f9 k  J" e$ T7 _. ]$ T
  889. /*                                                                                                                                                */( ]- B& c- \# @/ y2 h; |4 [
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    + L  c3 A% |# z+ y/ T8 q/ j
  891. /*                                                                                                                                                */' T; \5 K0 q% R" G9 a. H& K# j
  892. /* Input:                                                                                                                                */, m0 i, f/ @  p" f. u, T
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      S7 e6 T) ^' n3 Y
  894. /*                                                                                                                                                */! ]! l7 f/ M- F5 H1 ^% H! L6 i
  895. /* Returns:                                                                                                                                */+ W& R5 a! y% w: q+ t) a- C
  896. /*                Nothing                                                                                                                        */
    / {7 t* k2 h& |" B
  897. /************************************************************************/- [0 o8 n3 o  X! i  K( ^
  898. void Block_Erase_32K(unsigned long Dst)
    ! j1 K$ h* g2 m$ x
  899. {
    4 B2 J; L5 a+ }3 H( \; P0 u- l
  900.         CE_Low();                                        /* enable device */1 ~+ d$ w- v( \1 J0 n% h8 h
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */% J) p4 @( p; D1 g; S8 [
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( J; Y( i8 c4 m; m" P  ~1 a
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));" q4 W9 w: K" X% s
  904.         Send_Byte(Dst & 0xFF);
    * R# r; z) k& t" t
  905.         CE_High();                                        /* disable device */
    4 n) ~& a: h- L% t* T& d
  906. }% [: Q# `) v, d0 r  q

  907. ; W. {' i5 O: A6 z  {0 h
  908. /************************************************************************/
    % C" M/ _" P; l2 `9 Q
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    + n2 r: p! g+ m, Q" ~; m7 a5 p
  910. /*                                                                                                                                                */+ ~% k6 \: }8 s+ O
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ' Q5 L* Q1 O5 \/ T& o" S
  912. /*                                                                                                                                                */
    6 Y! R. n# ]8 J6 J
  913. /* Input:                                                                                                                                *// x! X$ V4 y% ?' X& Z
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : I- p9 O* S. X1 I
  915. /*                                                                                                                                                */6 f, t3 t" B: f6 r- G
  916. /* Returns:                                                                                                                                */
    7 v. n+ U6 E% V+ G% a& l
  917. /*                Nothing                                                                                                                        */
    2 d/ @8 D' t. t$ ]1 W0 r
  918. /************************************************************************/
    2 Z$ O3 ~- e  }' }/ x6 f
  919. void Block_Erase_64K(unsigned long Dst)
    : ?% n- c0 N' o' m
  920. {$ @$ B: f4 O" a
  921.         CE_Low();                                        /* enable device */+ c, e2 ^! p; ~" c# e( m( p1 x
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    6 |% x7 T: d. K" q+ ^! z
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 a8 v5 S/ v" q/ k
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + d" l# w0 w" H* C. o5 z
  925.         Send_Byte(Dst & 0xFF);
    7 a2 d( c2 j0 h% K6 }
  926.         CE_High();                                        /* disable device */
    5 u! X: |9 p3 g5 U
  927. }) `. s/ z6 o, Q: D
  928. 7 ~% A( k# R9 N, ]6 O" A
  929. /************************************************************************/
    ' c; H7 S4 N2 Q- y
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    , }) X3 [2 N4 Z  \
  931. /*                                                                                                                                                */( D7 r# M' k  t7 F# T* b2 h5 Q
  932. /* This procedure waits until device is no longer busy (can be used by        */$ }/ W  M+ p& P3 Q
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    - f$ T4 P- y! P% D; [( D+ \! T
  934. /*                                                                                                                                                */
    1 O4 D. p) Q7 O( [4 ?
  935. /* Input:                                                                                                                                */  t1 g/ ]( W' Q+ m
  936. /*                None                                                                                                                        */7 A+ e5 x- O* j  I; u5 D8 E
  937. /*                                                                                                                                                */
    & H' B, k; x( Z/ K
  938. /* Returns:                                                                                                                                */
    ' P# C! E9 L/ b* _, P- K% y
  939. /*                Nothing                                                                                                                        */
    ! ?; O& `- |0 W$ a6 K
  940. /************************************************************************/3 d! l+ V8 C' e( k  v* d4 \
  941. void Wait_Busy()3 H  @9 x2 _: H
  942. {
    4 a, s$ }$ _/ o% z0 S
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */, J) ~; K, a8 V. N0 t
  944.                 Read_Status_Register();# f' \3 ?% C! |* F
  945. }
    $ z# Z% q# U: y2 ^6 t

  946. " m* c: E3 s9 c1 [7 T. K2 Q
  947. /************************************************************************/
    1 J0 b7 b: ?* B& e( S8 D
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    " r7 {( w; ^0 t* U: t' a9 O6 @* E
  949. /*                                                                                                                                                */, S& \" _5 P) G4 T
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
      d0 W1 b7 I% R9 `# g( E
  951. /*                                                                                                                                                */
    7 W6 ^  k0 n. E* i! R
  952. /* Input:                                                                                                                                */
    0 n- Q9 c" ]) s$ `$ F. |( J6 M  V
  953. /*                None                                                                                                                        */8 L$ k7 c# q8 c7 z2 ?0 d! w
  954. /*                                                                                                                                                */
    " |5 v6 ~1 T, V" \6 X
  955. /* Returns:                                                                                                                                */) w" B* `. t6 w' s5 q& P8 v
  956. /*                Nothing                                                                                                                        */3 ~/ @" R2 o1 q& C+ v  r( c
  957. /************************************************************************/1 i' S6 |  l5 }+ p
  958. void Wait_Busy_AAI()
    ! }, d4 u# i4 z2 Q: l, d
  959. {3 z) ~7 w3 @, C$ |" a5 W/ u
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */: p) Z$ P3 H  x6 }6 O! `5 V  K2 t
  961.                 Read_Status_Register();
    8 H" A0 p! w: y% o
  962. }" p/ m  m$ E6 R& o3 g  Y) K9 r

  963. $ W/ F% _- Q( Z/ k+ Z! x2 k
  964. /************************************************************************/& r9 r0 U5 W) j+ F
  965. /* PROCEDURE: WREN_Check                                                                                                */* ~# h* N& j' F4 t
  966. /*                                                                                                                                                */5 s7 N( g7 s1 F4 ?/ J
  967. /* This procedure checks to see if WEL bit set before program/erase.        */  G: [2 L0 t' G+ j
  968. /*                                                                                                                                                */. ^7 b% J) x. W3 ~  t$ B
  969. /* Input:                                                                                                                                */% X& F" E# }: H3 z
  970. /*                None                                                                                                                        */9 T9 Q  }7 P* {; I
  971. /*                                                                                                                                                */
    * H; N8 \" n( |' k
  972. /* Returns:                                                                                                                                */
    3 V! @0 }8 [& X% R# m
  973. /*                Nothing                                                                                                                        */6 |7 o8 k5 g0 \" z* k4 s0 u8 d, H
  974. /************************************************************************/
    3 O3 w; O, W; Z
  975. void WREN_Check()1 I3 C; J% D# ], N' d3 D: d
  976. {8 p1 q( [8 U7 u9 Y- Y' R
  977.         unsigned char byte;
    6 F0 O; V( V) R; s. E/ X" d8 v
  978.         byte = Read_Status_Register();        /* read the status register */; r5 v# \; Y, K' S& R  g' Y) i1 p
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    / ?* l- E% n% r; o: O) {- f+ y$ s
  980.         {
    % x9 N+ R& z, o. o
  981.                 while(1)8 c% b! L# r) L1 z
  982.                         /* add source code or statements for this file */
    / H7 V) p  s, ~' [
  983.                         /* to compile                                  */
    / {  W* L" Q  |9 c
  984.                         /* i.e. option: insert a display to view error on LED? */
    / x$ Z" R* q" K: W+ i" P) F
  985.                  
    / m4 U1 ^; P# j" u
  986.         }
    ( w( s$ @7 `6 K; v6 |+ b0 g
  987. }
    # i0 T2 ?* j# F& P8 a. Y$ P! E" |, T! }

  988.   l/ |) d* ?2 C- `9 |1 P
  989. /************************************************************************/
    5 h$ }2 B0 V* Q# g9 |: A
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */% ^, a/ d1 L& E3 j7 d5 b
  991. /*                                                                                                                                                */
    ( S9 }, [" E4 E( `$ t: a
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */1 y  J, _3 X: y; g9 V. q3 w
  993. /*                                                                                                                                                */. v9 ~9 g  T" n- c& p1 d: ~
  994. /* Input:                                                                                                                                */" g: T# {1 P8 ~5 Q% A" q" Q. d
  995. /*                None                                                                                                                        */1 W( K# o$ ]- @5 A# q4 X. T* t8 z- E0 l
  996. /*                                                                                                                                                */
    : \  Z4 f9 V1 p' c% L
  997. /* Returns:                                                                                                                                */
    # E2 x4 |3 N1 y) V7 f( f# ?
  998. /*                Nothing                                                                                                                        */$ ^% g& |$ U4 N- T& p5 w# U. D
  999. /************************************************************************/  j) m9 V1 ]" G! k6 D* I$ r
  1000. void WREN_AAI_Check()8 e# u5 ~) M4 b2 Q
  1001. {" D- D  D- n. n
  1002.         unsigned char byte;
    8 m% ]: k5 M# T) B; N  U* h
  1003.         byte = Read_Status_Register();        /* read the status register */
    & {+ V- f4 z& G# l' R
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */  K( ^5 E" B3 @4 b; I1 n: S( x
  1005.         {/ u8 S2 g1 H; b. K( {  r9 f
  1006.                 while(1)                - n6 k5 u8 [# M' p
  1007.                         /* add source code or statements for this file */
    - f' i. P- k+ h( f6 a- E
  1008.                         /* to compile                                  */% c, C2 u+ k7 J
  1009.                         /* i.e. option: insert a display to view error on LED? */: w* R0 l" j  z
  1010. % E0 h2 t: Z1 w+ O
  1011.         }
    % B, V* d( u! K- A. k. c8 n- b
  1012. }$ e1 w$ B: U$ x6 ^: N4 E, ^

  1013. 4 B2 `& I3 g( L" t
  1014. /************************************************************************/
    % ^( G. O( m; ~4 t+ V5 M7 z+ P
  1015. /* PROCEDURE: Verify                                                                                                        */
    - `) N, f9 G) _0 p. s. p
  1016. /*                                                                                                                                                */' Y4 x" f* C8 ~/ l: Q3 g4 t: n3 I+ n
  1017. /* This procedure checks to see if the correct byte has be read.                */* i/ x6 O* g9 h
  1018. /*                                                                                                                                                */* o$ s* D$ E7 {% i: k7 o
  1019. /* Input:                                                                                                                                */, Z3 G; Q, Q+ H
  1020. /*                byte:                byte read                                                                                        */2 U7 s1 o  W$ i! @
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ' _* k/ F1 u. i
  1022. /*                                                                                                                                                */
    - Z, G1 z" M: ^& j; T' @
  1023. /* Returns:                                                                                                                                */
    % q, u. ?0 E3 N  q, H
  1024. /*                Nothing                                                                                                                        */
    " ]5 |$ t7 R) u& E
  1025. /************************************************************************/
    ) \3 t  @* \5 r  B5 R  c
  1026. void Verify(unsigned char byte, unsigned char cor_byte)+ L: c0 Y+ q1 H8 _- B1 j
  1027. {
    / ?4 G2 |2 @9 J: }$ B# Z
  1028.         if (byte != cor_byte); T* d3 I2 o4 C& E; G8 j/ d/ o: `
  1029.         {" B5 U" Z6 i  Z$ d4 g$ A3 n: J) u
  1030.                 while(1)) H  C! X4 j) s4 d6 W& @7 X. t; P
  1031.                         /* add source code or statement for this file */1 Z' @1 L3 v+ d& d
  1032.                         /* to compile                                  */+ I9 R$ `1 U1 Y5 S* q
  1033.                         /* i.e. option: insert a display to view error on LED? */8 f$ T2 A: I& h; C) z
  1034.                
    2 H, M. y- k: _
  1035.         }$ l9 N& l* `, r0 J$ l. s
  1036. }
    & m) z' z8 L, B0 D, N$ h, m

  1037. + m6 v- H$ |4 {* Q& |2 s
  1038. ; x$ w& C3 u( ~
  1039. int main()) g6 S8 Q2 K% k+ `& W
  1040. {
    3 T' s  F% x8 N, S* d* p' P

  1041. + |7 V! T, |4 V9 N/ J. d" F* t
  1042. return 0;
    / L6 {/ V7 |% q) e
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:/ e3 w2 n2 I: ~& v
   main()4 `- p2 D! {  f  A
   里面怎么是空的呢?, ^9 t/ R+ P+ ~1 w& h
   发一份给我吧4 u$ n0 Z' ~# B! ~* ^
mail:luyijun2005@hotmail.com
8 f3 q+ R6 N$ O咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。+ s8 y" l6 x' K3 U

% Y+ a+ D8 C/ a7 j1 x7 y. g[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
" W0 m- {9 @0 K& B1 T! g- yEC的代码在哪跑,你看DS的说明,每个EC都不同的。
& u& ^7 R) B( A5 A7 N. H* X/ KOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
- z+ c! @- q- P6 Q7 h上面几个问题是你没看任何东西而白问。
: y* z$ O9 T$ V& |6 t+ x4 E* V' I+ Z& Z' v4 b+ S2 V
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

; v! e9 @+ W0 U: V关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
' B3 R2 M# ?4 o3 T. c+ A! t# \  O) h
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”! i1 n2 M, {7 E0 H# a7 l
& S( _9 ^, L0 [/ [  Z
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
" E+ ~  S) J6 b# Q3 _! s5 G5 a0 M( M( H
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样% F+ B8 X( b5 V4 s4 h  G8 I3 X4 t
似乎要把SPI能support 到最大,这EC chip应该有好卖点  `  G+ n# e( r8 g& H* S( _
BIOS功能要不要强大,也就决定了SPI Flach的大小7 _; s% ^5 j3 `, b$ y
我是这么想的~让OEM去决定要挂多大!
* L0 H. p. c1 m1 P如果我司有BIOS工程师就好了~哈
7 C8 A: \5 {  H! mWPCE775应该算很新的东西,来看它支持到多大?  w* Z- O, i( w- \2 \& @
' V. g* l9 b8 x. J+ X) V
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte2 k; `& i0 B* C0 d+ y9 U% H) A
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.; N% ]' U, o: T' c7 U/ b- X, L" j
+ s& e& L$ D0 k: e
这份driver收下~希望以后有用到% [! Y: W3 E! T- g7 T  B# p! W
谢谢bini大大
/ J0 ^/ z" U# Z- B5 l4 T1 X3 e9 |; ?  X2 p6 I/ E9 q
很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

发表于 2009-7-18 15:16:34 | 显示全部楼层
我也有份汇编的DOS下的烧写代码,SST 1MB的 flash可以用。我不知道为什么AFUDOS为什么不能工作,AMI好象没有发送94 CMD下来,AFUDOS直接就说不支持。搞的下BIOS非要自己写个程序,烦的很啊。
回复

使用道具 举报

发表于 2009-8-13 10:59:30 | 显示全部楼层
前端时间小弟也在windows系统下写了一个并口到SST25VF080B的烧写程序......
回复

使用道具 举报

发表于 2009-8-17 16:47:36 | 显示全部楼层

这个函数看不懂Poll_SO()

void Poll_SO()
5 O1 o: E* p7 I9 p{7 _/ Q+ c5 ], Y
        unsigned char temp = 0;: I. p3 a3 }" i7 {% g5 v
        CE_Low();! x: F% P8 u! A# z2 O
    while (temp == 0x00)        /* waste time until not busy */# w8 w7 o7 F* c4 U) h
                temp = SO;. k3 N0 ~. K; k, U8 ?1 i* A
        CE_High();
% N  l" U6 p' O}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
3 r' {, S/ U1 {3 K% k4 K{9 @" w0 J; c& y6 [" e' K: D
          O8 g9 O# I) F+ U: f
        unsigned char i = 0;
% Z3 S  ]1 O' I6 V( x! V        for (i = 0; i < 8; i++)
% k9 R$ k9 I. ~0 D/ x        {2 L9 w' y; b9 g: ~8 i
               
7 R7 E: u% v* z                if ((out & 0x80) == 0x80)        /* check if MSB is high */
  f. @# _0 P4 C0 H. [                        SI = 1;
- v- Z3 ]( s* \7 E' U                else
. g" O1 A, g& m8 i1 n                        SI = 0;                                /* if not, set to low */1 q. |  q9 Z; E* O. E
问              SCK = 1;                                /* toggle clock high */  N5 _$ V) }1 x
   题            out = (out << 1);                /* shift 1 place for next bit */
" W. e# k  N" T                SCK = 0;                                /* toggle clock low */
9 v+ L' j  r2 b, z0 h. j: e- w        }
' s# E2 s# N/ b: |% a; k9 e1 s}
: q/ [: R1 f+ }6 p# Q 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 18:28 , Processed in 0.053164 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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