找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55585|回复: 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
    5 i! E& e/ g& ?+ f
  2. ) \. e0 s3 k4 ~* ~
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    3 e, z. T- M. z- X; g* ?$ r
  4. 5 `( c9 h) G; l" r# a1 h. m4 J+ M8 C
  5. November 4th, 2005, Rev. 1.0! Q, j5 S- n6 [" q: o$ g

  6. ) O+ W; u6 N. g0 j) c
  7. ABOUT THE SOFTWARE" o3 v1 G4 T, y" i
  8. This application note provides software driver examples for SST25VF080B,0 Q$ C' V1 Q1 R; {" ~# D
  9. Serial Flash. Extensive comments are included in each routine to describe # |+ J! I& H- T/ P
  10. the function of each routine.  The interface coding uses polling method
    , @& k! X  z6 Q5 p
  11. rather than the SPI protocol to interface with these serial devices.  The
    2 ~. b. l: F8 ]: `4 [* `# o
  12. functions are differentiated below in terms of the communication protocols6 u) i* Q; F0 h. j
  13. (uses Mode 0) and specific device operation instructions. This code has been 4 `) [" K1 B, c2 V" T8 \, D
  14. designed to compile using the Keil compiler.
    2 F$ _) N, m  @+ f

  15. : u# g+ G/ h% B: G+ C$ c; V1 Q4 C
  16. 5 ?; ?( u% ~" E, `$ E( |
  17. ABOUT THE SST25VF080B2 \, p% N8 H% l) \- C  P& a

  18. 8 |1 l5 _0 n2 p% u0 [! \9 W+ ~
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    5 B. l* R  K: T3 y, z" |6 X
  20. conjunction with this application note for a complete understanding
    6 a8 [0 `3 L, ]# u/ }9 Q6 i' W0 o
  21. of the device.
    4 M& v/ `' G5 H1 m' b. ]
  22. 5 G5 t+ ~0 @  A2 o/ R% g

  23. , M5 \5 l0 Q2 l. G
  24. Device Communication Protocol(pinout related) functions:
      U: d. w0 p" ^. f; ]$ f

  25. % f- l% O4 j6 Q" l4 ^) E; X* L
  26. Functions                                    Function
    " l! W, F$ j3 l; K, W
  27. ------------------------------------------------------------------5 d8 G) S! Q% h' H/ `0 G
  28. init                                        Initializes clock to set up mode 0.
    + v0 W. M, x" O- X
  29. Send_Byte                                Sends one byte using SI pin to send and ( e3 A1 ~; D  N3 M& X! x+ j
  30.                                                 shift out 1-bit per clock rising edge/ t* j! ?' n, z
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    2 u: I8 m0 U$ j0 `9 D6 e2 ~
  32.                                                 in 1-bit per clock falling edge4 s" b2 p" U/ C. K  M( d- A& m
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    8 R: W9 U6 e0 b5 g: j; l4 X6 W% t
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high- M+ a  C: g: x6 t1 F: z* a8 Q
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    1 r- N" m* j  C' C$ J' T' b
  36. Hold_Low                                Clears Hold pin to make serial flash hold
      o0 f  Y2 q5 W( a# A
  37. Unhold                                        Unholds the serial flash" V$ D. P4 Z2 m4 h
  38. WP_Low                                        Clears WP pin to make serial flash write protected1 r3 q6 C* H4 r2 w
  39. UnWP                                        Disables write protection pin& Z4 _, C. s6 `$ n3 O6 f: z

  40. . }& s' ^% J: ~8 ~9 m9 ]
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code" Q/ [8 h  n% t+ E3 v& ]
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your. ?* G; Y$ J. J4 Q- I) X
  43. software which should reflect your hardware interfaced.          
    ) q( s6 c' K# v* t! f. u7 t

  44. : X9 D: [: Q$ p* a' J. U

  45. 9 U+ Y' G9 I# D
  46. Device Operation Instruction functions:
    1 U& R2 }- l; [; |% N5 m& f3 i& A
  47. . _2 {( L7 L+ ^
  48. Functions                                    Function
    % J! f7 o+ J. O
  49. ------------------------------------------------------------------1 M8 D) n6 m& z: \; _/ ]7 l
  50. Read_Status_Register        Reads the status register of the serial flash
    3 e' Y- y! G5 [$ G( ?% _
  51. EWSR                                        Enables the Write Status Register
    7 f) l8 l& v% Q: g9 }; Y; n
  52. WRSR                                        Performs a write to the status register6 k/ h1 k$ ?7 k1 p! j1 W
  53. WREN                                        Write enables the serial flash. r2 u, `6 I, N/ q* \! s
  54. WRDI                                        Write disables the serial flash2 [! V9 m5 R8 L- A
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming3 ~8 U. |9 L& F$ L% X
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    5 ]0 M' W$ B' _
  57. Read_ID                                        Reads the manufacturer ID and device ID/ ]9 B, T. _# x9 K6 q
  58. Jedec_ID_Read                        Reads the Jedec ID
    + C1 W8 Z2 `' |& u* a3 M- Z3 W! m
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    / c3 W$ g* i. E3 ^0 \2 Q
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)- A) _: O% S1 s4 @) e! v* P
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)* z$ V) G/ e! ?  P( c+ d1 R
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    0 g  ~3 f  J+ B+ B  v+ G7 ]$ Z
  63. Byte_Program                        Program one byte to the serial flash7 I( f! w, B  n7 c( A3 h' P2 l2 {
  64. Auto_Add_IncA                        Initial Auto Address Increment process( e" x6 y; ?7 o/ q# T$ }  J
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation5 ~" @& Y5 A0 s* M1 N$ ~) R& ^
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY, g; R& H. V- o9 n7 f. F
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY4 [: R0 {, a( P5 _! u! F
  68. Chip_Erase                                Erases entire serial flash
    ( w  e2 V( A5 j8 O) O! c
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash) A" b7 }0 g, M5 K. q
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    ' a) {8 f- S+ w8 s
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash9 d( ~5 |" P" o; b; r
  72. Wait_Busy                                Polls status register until busy bit is low, A$ E7 G6 Y# M& S
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    . M5 v- A( [4 c1 H+ V+ O- h. c( L
  74. WREN_Check                                Checks to see if WEL is set/ ]$ X; M' j" S7 ?( T; C
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    4 a8 H8 V$ s7 c/ T

  76. 5 t8 b' {3 u0 |7 `0 z# t
  77. 9 Z- n# C; X$ J0 ~( E- L

  78. ' f+ |/ n2 C1 @, N$ y# U9 K4 b# p9 v
  79.                                                                      ' t  r0 j- D% @" g
  80. "C" LANGUAGE DRIVERS 7 N9 D- ]+ M& b4 R& M9 h' U9 f

  81. & C* d" g7 c4 l' g. {
  82. /********************************************************************/
    8 R' ^) o( R3 i! _5 C+ B) @* f
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    " ~0 b. l7 B% D1 m( |
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    , Q7 t8 ~- F' X+ `- p* D
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    3 u* B5 `& @. H$ d) ^! ~! K4 X/ L
  86. /*                                                                  */
    6 N0 y2 a5 m- W/ w: c+ W
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    / o1 b0 L+ d. y% R& z( G1 W
  88. /*                                                                  */
    6 M% R1 p$ P8 Q; U
  89. /*                                                                                                                                        */
    . i2 [8 U% Q% z
  90. /********************************************************************/8 D! R' p+ w8 j9 F* r
  91. # Q6 u! @8 E! y" Z
  92. #include <stdio.h>* Q/ m  ]" y3 ^. v+ X  F6 M, x, e
  93. #include <stdlib.h>. [8 l+ g! n  @

  94. - ?  T. u7 t. {% m
  95. /* Function Prototypes */* J& r( q6 z4 s6 l2 `) S, I
  96. / Q  N( X9 _+ y5 ?4 F$ K
  97. void init();8 r2 _* ~7 T$ f/ M/ }1 o' t; `
  98. void Send_Byte(unsigned char out);* {6 L! S6 H) l) h$ C" q
  99. unsigned char Get_Byte();
    9 p# J9 l4 }5 K. z
  100. void Poll_SO();
    & {' B3 E) @) K+ H6 a
  101. void CE_High();
    , @8 h. ~- \8 H/ R. y# [* c
  102. void CE_Low();
    ! i/ o* A* Z; R8 C7 S# J
  103. void Hold_Low();
    1 }/ S4 e. t# a: B! p
  104. void Unhold();" a5 r& I9 S' C& n2 E2 @
  105. void WP_Low();/ K  _* g% E* e2 c  s
  106. void UnWP();
    0 N, ]* p9 W) b
  107. unsigned char Read_Status_Register();
    " q: m( R5 w. n9 Z7 q
  108. void EWSR();/ x6 L( N4 N) I) Q; f+ T; ~/ R
  109. void WRSR(byte);6 ]  ?! u' s, @* w0 E
  110. void WREN();
    0 T8 ?2 c- _3 b( b6 Y! c: D( r
  111. void WRDI();6 D& e8 R( i  D; ^
  112. void EBSY();
    5 V8 \) \5 E6 }) \6 {6 K3 T
  113. void DBSY();
    " m- W. u' ~4 v) g! T0 S
  114. unsigned char Read_ID(ID_addr);
    3 L+ `+ x3 C2 \; p6 E1 k9 `
  115. unsigned long Jedec_ID_Read(); 1 R1 @4 B% z+ O  S+ ^0 @) |
  116. unsigned char Read(unsigned long Dst);
    9 o5 b9 G1 Y8 |2 r/ ]6 S
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);4 O4 n+ L& _5 T6 i
  118. unsigned char HighSpeed_Read(unsigned long Dst); & H' Q% I! J# Z2 q
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
      Q+ {# M0 \+ L  b4 `5 c# q
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    . B  q( C! Z- i( R5 W! \9 m1 @: p9 L
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    0 T: V3 U3 e9 T( a/ R$ D- Q# P; [
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    ; a0 q: L! S+ i! D0 R
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);, o8 q7 P, O1 g" `# a  J2 ^7 D7 s
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);. d8 e* o4 R, _9 _- O- |0 j
  125. void Chip_Erase();! [1 q  R" {1 e; U; J
  126. void Sector_Erase(unsigned long Dst);
    0 I4 r' o+ }, u0 Z
  127. void Block_Erase_32K(unsigned long Dst);
    ) }& ]3 D/ p% E- Y( ~. D5 m
  128. void Block_Erase_64K(unsigned long Dst);
    0 T0 g& Z+ q; t( r
  129. void Wait_Busy();
    , |9 n. ^, |2 p1 W& h# m/ ~( E
  130. void Wait_Busy_AAI();
    0 Z) Z7 l5 v- s
  131. void WREN_Check();& R! O7 x  Z9 ~$ F
  132. void WREN_AAI_Check();8 P, v3 A5 ?% W. K3 t/ _

  133. , k4 L# b; U8 s; w  ?4 {, x
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    6 h4 D% W( I3 i' C% N* h5 R+ Z
  135. * r. H1 L: k" O+ Q. h7 k! }
  136. unsigned char idata upper_128[128];                /* global array to store read data */4 e9 t" X* z! V: \3 Q
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    % `$ {& ]6 R% ^+ _1 Z- k0 {
  138. ; N3 l7 `& F) U8 u6 s) `
  139. /************************************************************************/
    % k/ d/ [6 Y/ M+ R4 D
  140. /* PROCEDURE: init                                                                                                                */4 q7 ~; O( E2 L! a3 N
  141. /*                                                                                                                                                */
    8 x+ |7 ^# ~/ p4 H/ M9 t
  142. /* This procedure initializes the SCK to low. Must be called prior to         */1 b3 u$ G3 w& q0 T
  143. /* setting up mode 0.                                                                                                        */
    % g9 p0 }  B! {7 x
  144. /*                                                                                                                                                */
    & A- _' D  u+ s7 G% L# [
  145. /* Input:                                                                                                                                */
    " J- i4 V' g( j& @* X
  146. /*                None                                                                                                                        */
    , e! m3 u' _/ ]4 o# v0 p
  147. /*                                                                                                                                                */  r3 P) [8 O' T- V
  148. /* Output:                                                                                                                                */
    1 H- W- |4 Y; _9 k: ~* Q/ f' ]; ^8 b- l
  149. /*                SCK                                                                                                                                *// G" l2 w' ]3 E. {6 e9 Y
  150. /************************************************************************/
    9 B  @! L  e" ~3 I( [) N5 k3 }- `
  151. void init()
    % D4 J6 V# U5 a% k5 M: T  S* X. x
  152. {) i: K3 n# T) t  {. @# O- B
  153.         SCK = 0;        /* set clock to low initial state */* }! S$ ?- ^5 ~. i% ]0 O
  154. }
    6 {. t5 j- v- i9 S5 E7 j/ }: K

  155. ) Y9 g3 b; Y/ b) K  i# H  c5 ^' Y
  156. /************************************************************************/
    2 x! s' }; U2 l0 Z- Q
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    ! K2 @' l- b. b8 N. e% \
  158. /*                                                                                                                                                */
    % T& o# s7 A3 w0 E, C
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    + x' G4 S% V- q* g
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    1 I8 I- `$ S- r+ q# G( i4 N
  161. /*                                                                                                                                                */3 j) I: n: b  e: W
  162. /* Input:                                                                                                                                */
    + A- k& s! @$ o- S8 r
  163. /*                out                                                                                                                                */
    $ u& K5 v2 K) n; \) R  y5 v
  164. /*                                                                                                                                                */
      l/ m2 Y& @1 j; E1 m$ k) o! Y* y# |
  165. /* Output:                                                                                                                                */; p( [' Q  G0 N! Q, E
  166. /*                SI                                                                                                                                */
    9 M; T2 ?6 R0 |2 p6 B8 x) U. c
  167. /************************************************************************/
    & F3 n8 S7 L  Q* l8 a
  168. void Send_Byte(unsigned char out)
    , K+ A  Y& T% ^8 u# C7 `
  169. {
    * h; T5 b- @1 E! A0 ]
  170.        
    ' ?% e( y: k! L* ^
  171.         unsigned char i = 0;
    1 t7 n# m# \+ x
  172.         for (i = 0; i < 8; i++)& ^% B; F, g: z: B- ], A6 N* U0 s
  173.         {! i3 P! v$ s* U+ Y
  174.                
    " [$ `; s, V. ~$ O+ \
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */$ q$ e* O+ a$ ~$ r
  176.                         SI = 1;
    6 r9 m/ y0 A7 S- x
  177.                 else
    5 O6 `1 O& [& U, L$ O; m+ }/ }8 S/ f& G
  178.                         SI = 0;                                /* if not, set to low */7 x% i$ z! D2 p$ Q' t& u8 W' `# y
  179.                 SCK = 1;                                /* toggle clock high */
    5 o* H: d! Q! t4 I3 W
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    2 V! i, t2 ^' Z8 f/ Z$ m
  181.                 SCK = 0;                                /* toggle clock low */
    , u8 O$ b& d) r+ s" P
  182.         }
    0 Y+ f4 T) ]; \5 {+ @! }+ ^2 D
  183. }3 S" n: }$ B# E; x

  184. 6 o( ^. G  O9 @
  185. /************************************************************************/( e8 }$ e& f) L5 K& z5 m: s
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    ( q4 u; j0 Y6 Y9 t5 r% r
  187. /*                                                                                                                                                */
    , o# k! _: n! k; p* c4 O# K8 A
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */8 p/ U. c- V: P0 D
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ( i1 q6 B- A/ b' D
  190. /*                                                                                                                                                */! K1 x5 U2 Z9 k$ h
  191. /* Input:                                                                                                                                */4 K& g2 H: X! z2 u& k
  192. /*                SO                                                                                                                                */
    ( ]0 d# W- m  P& v( l
  193. /*                                                                                                                                                */6 e3 @6 F2 c5 o1 Q" r
  194. /* Output:                                                                                                                                */
    " T# r0 S3 b- \3 g
  195. /*                None                                                                                                                        */3 H1 m# x( v+ `; k7 k3 E
  196. /************************************************************************/
    ; m2 q2 D1 ?7 C+ {0 _
  197. unsigned char Get_Byte()8 b- B0 `: O8 D$ r
  198. {4 O6 d- q3 S) W9 W7 B
  199.         unsigned char i = 0, in = 0, temp = 0;' H) S4 O2 k" W. T8 D9 i; W
  200.         for (i = 0; i < 8; i++)" o  z. ?* b$ ]8 @  L
  201.         {: x0 e% ?6 C/ W3 g. h
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    4 x0 b) Q% b  Y
  203.                 temp = SO;                        /* save input */) l4 F5 V# U, K3 y& i
  204.                 SCK = 1;                        /* toggle clock high */$ [7 Z1 Q* B, p4 |4 N+ \5 A, l5 d" B
  205.                 if (temp == 1)                        /* check to see if bit is high */5 X5 v" f8 G1 s2 |" A2 _0 y
  206.                         in = in | 0x01;                /* if high, make bit high */
    & d1 M1 B- N& s: a6 b, m
  207. & O/ ?$ P) X( L1 |7 E
  208.                 SCK = 0;                        /* toggle clock low */
    3 G) S5 ^8 A2 X

  209. . _8 E6 ]8 I: K- W
  210.         }4 q6 N- g4 A* `
  211.         return in;
    & A1 Q8 B9 x" K# s5 M
  212. }  S8 \( C9 d' J. j+ j0 T! c# z
  213. ; p1 X$ m8 y5 o  d# S/ b
  214. /************************************************************************/
    , r3 t7 k& ?4 V* I1 R8 x- D
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    . _* _: F, B; Z: p/ L
  216. /*                                                                                                                                                */
    # p2 d' I4 ^4 W2 e3 ~
  217. /* This procedure polls for the SO line during AAI programming                  */
    1 K; Z) x. _6 m( t# h6 \" ~: f4 F
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ' y3 x/ O$ {- A5 ^- o4 J+ ^: l
  219. /* is completed                                                                                                                        *// {( f- |1 l8 h& [: Y# y) I6 C
  220. /*                                                                                                                                                */
    4 t3 e6 S* q) c. N- f: N+ j+ O% D
  221. /* Input:                                                                                                                                */, [- N7 T: y# E
  222. /*                SO                                                                                                                                */9 E& S% N+ J9 O8 V  Y  O: _7 y
  223. /*                                                                                                                                                */
    $ Y- P/ o8 \4 a3 u
  224. /* Output:                                                                                                                                */6 |* l; l9 L9 F% \
  225. /*                None                                                                                                                        */
    % M4 _0 M+ X+ F3 n$ f; k
  226. /************************************************************************/
    1 S4 N7 d9 S5 W0 I& X5 J$ m
  227. void Poll_SO()
    ) l; @3 W1 V, J: i% H  u( z
  228. {" M; V  Z2 z6 g
  229.         unsigned char temp = 0;
    . a/ ]5 S/ x; Y
  230.         CE_Low();- y( l- Z$ S) y5 Q/ y  ^  t
  231.     while (temp == 0x00)        /* waste time until not busy */
    8 D+ E1 I/ ]: {' n) ^1 b) N$ k
  232.                 temp = SO;
    & W: n, g/ Z9 e) q$ x7 y: k% _/ S/ }
  233.         CE_High();4 c7 q9 l2 I! P+ K# @  x* D& e2 S
  234. }
    % p( ~2 a) J' K- x) A6 A2 c1 W

  235. # M( L! ^* k2 K0 r7 G9 i
  236. /************************************************************************/
    3 s8 `! ~3 w8 b; F
  237. /* PROCEDURE: CE_High                                                                                                        */
    ' e( \, Y# A- Y. Q" @9 y, D
  238. /*                                                                                                                                                */: ]) a8 O& b! M: p; n; r1 j. f
  239. /* This procedure set CE = High.                                                                                */
    ( D+ @; |9 `& A$ Y! E: C- Q
  240. /*                                                                                                                                                */: v( c1 g( q+ e$ ~
  241. /* Input:                                                                                                                                */! U- e% B. C' K, E* I
  242. /*                None                                                                                                                        */
    2 r% ~& P: z  |3 }$ d& R+ R3 n
  243. /*                                                                                                                                                */$ P% ^6 T! o$ E5 x1 w3 u
  244. /* Output:                                                                                                                                */
    ( o% K1 I8 I" O- s8 V
  245. /*                CE                                                                                                                                */
    : d& Q- D2 j% g% ], s. E
  246. /*                                                                                                                                                */
    ' i( w1 S4 P$ [1 L# m4 i
  247. /************************************************************************/  g3 t( I! M- M
  248. void CE_High() 8 n0 u6 q! N7 ~; n; P& N
  249. {. |3 _0 n: J1 W9 S1 ]) S& N
  250.         CE = 1;                                /* set CE high */8 r3 W# L" T& c" @
  251. }
    + r+ i% }3 N2 o0 @; \( t

  252. " _# q! p, G' J; K9 P
  253. /************************************************************************/
    " B" o% W9 `- s4 ?  Y, l) P  [
  254. /* PROCEDURE: CE_Low                                                                                                        */5 F  F* U, O/ M/ w# `5 x( e
  255. /*                                                                                                                                                */7 _2 E) E- o) u% f) ~  B
  256. /* This procedure drives the CE of the device to low.                                          */
    ( A/ _* r9 W9 Y2 v" [' W3 u0 `
  257. /*                                                                                                                                                */3 W# K2 c9 G, T* y/ o
  258. /* Input:                                                                                                                                */
    : A" [* T, |: y  g& G5 `; Z
  259. /*                None                                                                                                                        */1 G- T# C4 Z6 P1 N2 L4 H
  260. /*                                                                                                                                                */
    0 T; m1 y7 c* E8 _, l' p! d& a; r: }
  261. /* Output:                                                                                                                                */! W# }5 Y2 n$ k( P$ G
  262. /*                CE                                                                                                                                */
    1 G. m  F6 f7 |$ ]
  263. /*                                                                                                                                                */1 y# Z: J9 M! a/ ?' v
  264. /************************************************************************/0 I! |/ A9 N" U% S% W; D5 T
  265. void CE_Low()
    * h( r6 i4 F. n
  266. {       
    6 G! {" b- q# i8 @: i  L: ?+ E* h" O
  267.         CE = 0;                                /* clear CE low */
    : X- B. Z% T, p$ _' Z% o& I
  268. }! ~- Y2 w5 [( k9 L# |

  269. " d1 b' D* ?  a7 s$ g
  270. /************************************************************************/8 R+ n  K4 ]5 G- S2 ?# Q
  271. /* PROCEDURE: Hold()                                                                                                        */
    ; y% s0 D8 s- m& w$ N3 ~0 W
  272. /*                                                                                                                                                */& |0 W  A  T% _- _9 L; }
  273. /* This procedure clears the Hold pin to low.                                                        */
    , J1 n# z2 z  ?# t; ?
  274. /*                                                                                                                                                */6 L# q1 A1 W) [& C6 i
  275. /* Input:                                                                                                                                */
    / u' P" Q3 t1 r8 U  k$ X( ]
  276. /*                None                                                                                                                        */" B. s7 ]" j% e% L' y8 c) U
  277. /*                                                                                                                                                */
    ; p4 C: B4 u! C8 H! f( d# B
  278. /* Output:                                                                                                                                */* n6 j1 I5 I0 d4 ^
  279. /*                Hold                                                                                                                        */
    " J+ d# N4 q" Y( k. ^( U6 o8 }
  280. /************************************************************************/% \/ H9 l5 B" W8 e: g# u5 k* p
  281. void Hold_Low()
    & s& z  ^3 I, Q( M  T$ M! C
  282. {: Y  n( K6 L( P% w) p
  283.         Hold = 0;                        /* clear Hold pin */
    : h% z, l9 z% u; X8 E; Z
  284. }
    ) t# j1 v+ U- {
  285. ' C  _- P; f. e* Z
  286. /************************************************************************/: z3 I/ f. Y! P5 }
  287. /* PROCEDURE: Unhold()                                                                                                        */
    9 U3 V" l! q8 o) e* v' N- X- s
  288. /*                                                                                                                                                */! K$ d# b6 u$ E$ o
  289. /* This procedure sets the Hold pin to high.                                                        */
    4 ?5 {7 p4 Y' G
  290. /*                                                                                                                                                */
    9 _" \+ ]" g6 u" V
  291. /* Input:                                                                                                                                */! R  V; Z3 h8 F7 k5 Y' g3 I
  292. /*                None                                                                                                                        */# ?& K9 S& x1 j
  293. /*                                                                                                                                                *// g- H% Z- u4 N- i* p
  294. /* Output:                                                                                                                                */4 ^0 l2 \; b/ x6 D, ^$ w
  295. /*                Hold                                                                                                                        *// S$ E- |. s% ]! D3 I4 \4 H' d
  296. /************************************************************************/
    9 o" `- m, j, O; }3 u
  297. void Unhold()
    % y3 r% N/ p5 J, s( e: e; e
  298. {: Y; O0 I& z. v& s) w( g
  299.         Hold = 1;                        /* set Hold pin */" |# X7 K6 L7 l8 f! Q/ v! m
  300. }$ C8 z+ T$ u- Y5 I2 D4 @

  301. ( Y! D1 g/ z. N
  302. /************************************************************************/. G$ O$ w" d- O0 h
  303. /* PROCEDURE: WP()                                                                                                                */
    / ^* j2 d# u0 ~9 V3 c/ n+ y7 c4 _
  304. /*                                                                                                                                                */
    9 }- j; m+ w: [" m( j3 V, h- @
  305. /* This procedure clears the WP pin to low.                                                                */5 M$ L& O( K# X7 C& a$ j3 q. I
  306. /*                                                                                                                                                */+ _" D! ~0 ~. b1 p0 O+ z8 p% O" I
  307. /* Input:                                                                                                                                */; R; F' ?& |; s! x& X7 B
  308. /*                None                                                                                                                        */
    ' H, w1 r! `6 |3 U
  309. /*                                                                                                                                                */
    & d! v5 v2 _# _+ o( B% |0 r( Y6 Z  M
  310. /* Output:                                                                                                                                */
    # t; g+ |) G# I. T$ G0 _
  311. /*                WP                                                                                                                                */: y) i# R( y* P4 K
  312. /************************************************************************/, a- H! {) S3 w
  313. void WP_Low()
    " _: Q! b0 Y$ r7 V0 `3 E4 a. O
  314. {
    ; z8 ~0 ~5 e# Z6 p7 c
  315.         WP = 0;                                /* clear WP pin */
    : L( C5 H* X6 y/ e  q7 }
  316. }
    + ?/ R1 z* K2 D* E2 y
  317. $ m3 Z/ S9 j) ^- }" G
  318. /************************************************************************/$ o# w. p6 H" a/ B. q* X  h
  319. /* PROCEDURE: UnWP()                                                                                                        */
    8 [6 [5 x" _7 Y
  320. /*                                                                                                                                                */' a4 R4 g: h( z. x2 \6 p
  321. /* This procedure sets the WP pin to high.                                                                */' F4 g- b9 ~# o$ R, \) W
  322. /*                                                                                                                                                */( o! j; }  C* C
  323. /* Input:                                                                                                                                */
    5 ^, w8 B& S% |- y# z6 g7 H
  324. /*                None                                                                                                                        */
    , v- J# y! r2 X
  325. /*                                                                                                                                                */
    ! e+ u9 u$ a0 t2 x
  326. /* Output:                                                                                                                                */( U  `0 j3 M3 m' l+ R5 [0 n  C& G
  327. /*                WP                                                                                                                                */
    2 p6 ^; W9 [( b* ]. N2 A
  328. /************************************************************************/
    * u. k" P' J4 l9 d" i
  329. void UnWP()0 C3 L$ g! L: O1 k
  330. {
    9 E3 w- M. ]5 L  a
  331.         WP = 1;                                /* set WP pin */5 P, v6 M* T8 G% D2 d
  332. }# o' L% k2 r- U* q; Q) m& p5 t' m3 _( n

  333. / P: D6 Y  T  W2 C' I8 f
  334. /************************************************************************/
    : g; ?, F7 C, n& T7 ^
  335. /* PROCEDURE: Read_Status_Register                                                                                */  }2 p9 Q* p' j
  336. /*                                                                                                                                                */
    1 q, {. i3 z4 q3 r% ]- k
  337. /* This procedure read the status register and returns the byte.                */6 ^5 I$ U. N  d8 Q; ~6 ?0 ~
  338. /*                                                                                                                                                */  N8 j. u( ~% e8 ^& @
  339. /* Input:                                                                                                                                */
    2 O; g0 F; ^. z  _$ p; f
  340. /*                None                                                                                                                        */- `$ F! {  o* m# w% _8 P1 e* r2 X
  341. /*                                                                                                                                                */5 r5 g) F3 Q5 p1 n
  342. /* Returns:                                                                                                                                */
    $ X+ z, H/ U" S( n& c0 }3 ~
  343. /*                byte                                                                                                                        */
    9 R2 ?$ y4 Q& r, Q* {
  344. /************************************************************************/
    9 i0 Q' B6 V; C
  345. unsigned char Read_Status_Register()
    6 ]2 D8 S% Q8 r7 d. A, [: {! D
  346. {
    ! y% K) I! ~) \/ q* }, t9 d. G2 j
  347.         unsigned char byte = 0;
    5 m# z, K* j0 a3 r
  348.         CE_Low();                                /* enable device */
    " P1 R# E: _; |) k$ j3 \6 }8 u8 M
  349.         Send_Byte(0x05);                /* send RDSR command */
    1 a7 d6 `; I  D; P3 @& `, N! Z
  350.         byte = Get_Byte();                /* receive byte */
    - E$ |( s4 e) M; ^- v
  351.         CE_High();                                /* disable device */
    ) L" G% v- @$ D* j! N' d3 r
  352.         return byte;
    ' G! |8 Z" L* c4 c7 w
  353. }
    9 Z0 B% S5 X$ }. e' L
  354. 3 r8 G- d" m3 H! W2 [# d
  355. /************************************************************************/. C* _- m2 a5 F5 w& k  b( d& _
  356. /* PROCEDURE: EWSR                                                                                                                */
    & w% T8 r- @5 @5 `) n$ ?/ r
  357. /*                                                                                                                                                */, |/ W4 S- v- U+ Y0 w" ^
  358. /* This procedure Enables Write Status Register.                                                  */* m/ s! P$ D" `& c! X
  359. /*                                                                                                                                                */8 ]: @6 j$ A6 M; R, Q0 k
  360. /* Input:                                                                                                                                */- X4 G( h3 L; N7 {6 h
  361. /*                None                                                                                                                        */
    ( V+ \1 Y  m3 H) t0 m2 P3 I' D; C
  362. /*                                                                                                                                                */
    % X! X5 k3 E1 b, q
  363. /* Returns:                                                                                                                                */
    4 @. ~% w, X. p
  364. /*                Nothing                                                                                                                        */
    % m; m" p) e% W# a* Y
  365. /************************************************************************/
    4 B7 x: Y  H, v( [5 p
  366. void EWSR()
    / M# }8 v1 \  m9 Q2 p& {
  367. {
    9 Q* w  N1 \0 G7 _# [. ^
  368.         CE_Low();                                /* enable device */" b+ l" G1 O/ t; S1 j
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    . b9 p8 _  G( C, p0 I" G
  370.         CE_High();                                /* disable device */& e1 B& S/ D, D1 B
  371. }
    3 n' |# U7 B+ v8 C& `' c

  372. / T$ o& j$ \3 J2 D
  373. /************************************************************************/
    2 C: s* D9 O0 T4 s$ r
  374. /* PROCEDURE: WRSR                                                                                                                */
    ! D& d/ i% q0 i2 h$ [8 C
  375. /*                                                                                                                                                */* }$ q' e/ R" K
  376. /* This procedure writes a byte to the Status Register.                                        */7 R4 k  t7 `- j7 i- _7 ^
  377. /*                                                                                                                                                */# ?4 U; s) g2 _" M
  378. /* Input:                                                                                                                                */  [6 e6 t4 h% @! U! w& |
  379. /*                byte                                                                                                                        */
      B! d1 B2 b4 R( R& Y" @- F2 X
  380. /*                                                                                                                                                */0 u  q1 R& n! m3 ~
  381. /* Returns:                                                                                                                                */
    # W6 v0 N" o1 r
  382. /*                Nothing                                                                                                                        */
      w: o& L+ j' \$ n; h
  383. /************************************************************************/" U7 y9 @+ M) l
  384. void WRSR(byte)
    + ]2 r) n$ l9 V# q
  385. {1 p/ \6 V/ R. y/ L- Y4 c
  386.         CE_Low();                                /* enable device */; [1 S' \, L& w* I
  387.         Send_Byte(0x01);                /* select write to status register */
    ; {# K2 @0 S# @+ K% p
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    - `3 }6 ^1 s' {  t/ g" Z+ P2 X, P- R0 H
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */* j; E# ]6 \0 d* _  _
  390.         CE_High();                                /* disable the device */
    : ]) _$ D8 S, ?0 ]
  391. }) |# c. k+ N6 j% j7 v
  392. ' g; L" z3 b6 N' `! j8 F
  393. /************************************************************************/
    . w- H- k3 m5 g
  394. /* PROCEDURE: WREN                                                                                                                */
    : h$ m2 M/ u$ Z* H5 n, a) e2 m
  395. /*                                                                                                                                                */
    7 J) `* g( T5 v+ V! W
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */; b# F' C1 k& b& m
  397. /* to Enables Write Status Register.                                                                        */
    ' C# `4 Y5 J$ P; s) R* }
  398. /*                                                                                                                                                */  ?5 G: b7 Y( J; U
  399. /* Input:                                                                                                                                */. y$ k" f' G, {
  400. /*                None                                                                                                                        */, v/ J  d! o# W9 H* Y+ _
  401. /*                                                                                                                                                */6 M, W6 I, I; x3 q1 r  q, Z( t
  402. /* Returns:                                                                                                                                */+ a" h% L+ C8 ~* [4 A" W
  403. /*                Nothing                                                                                                                        */
    * V. b; B% [0 Z
  404. /************************************************************************/. A. `- f+ q9 K
  405. void WREN()- C, V; c$ c% l
  406. {" r7 d* e: a) o% U/ D6 L( m' n% l! G& k
  407.         CE_Low();                                /* enable device */' d3 J" O$ W9 o; s+ }$ u2 |7 Z9 p- Q' P
  408.         Send_Byte(0x06);                /* send WREN command */" V+ u  ~  U0 S/ N
  409.         CE_High();                                /* disable device */! Z6 f% D+ n; T
  410. }% Q1 }# S( q6 y" h) ?

  411. & R( K/ j. C6 j4 ~$ d
  412. /************************************************************************/
      R3 Y* e+ x  G+ e  J
  413. /* PROCEDURE: WRDI                                                                                                                */: w3 L! A! o2 F- o8 i) Z% k
  414. /*                                                                                                                                                */$ |; ?! s8 I; |3 Z; X* C
  415. /* This procedure disables the Write Enable Latch.                                                */, U% ^- j5 j" q9 O+ b- m$ c
  416. /*                                                                                                                                                */: {! {4 a& S: j* k) W9 ^2 i
  417. /* Input:                                                                                                                                */6 i, T+ I+ l/ S) Y
  418. /*                None                                                                                                                        */
    2 f3 }- g8 f! j1 M. g: D7 a! I
  419. /*                                                                                                                                                */
    ; N0 N8 o  J3 j4 w; N
  420. /* Returns:                                                                                                                                */$ A9 t8 |% t# H$ r1 ~8 W6 N
  421. /*                Nothing                                                                                                                        */
    / o6 \: Y) f% y- Z! U% b. ^
  422. /************************************************************************/
    . W% A2 Y8 z8 t' t
  423. void WRDI()
    9 I0 O- U7 A0 d- w- a2 q+ y
  424. {
    2 l8 F: @" V) |: s
  425.         CE_Low();                                /* enable device */. P- u5 M5 V6 Y( S7 i6 F/ ^
  426.         Send_Byte(0x04);                /* send WRDI command */, Y6 X7 K  g+ H# [2 a
  427.         CE_High();                                /* disable device */
    # q$ [& _* V5 z9 M0 F( s
  428. }
    $ p/ H. ?6 [6 M8 B

  429. 0 F% ~, ?3 L- d, \7 J3 t8 C3 s
  430. /************************************************************************/- v0 X" }' Z+ u' t# _
  431. /* PROCEDURE: EBSY                                                                                                                */& K; w7 _4 N; t/ X5 i3 J' R
  432. /*                                                                                                                                                */
      u8 \& R0 B+ b  q; M: r
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */2 @( D7 [- c0 N
  434. /* programming.                                                                                                                        */
    9 H% L6 X! Y: W# t! @3 u& A
  435. /*                                                                                                                                                *// S3 w5 \: W! H" U" l- {
  436. /* Input:                                                                                                                                */: O; _; L3 F0 V' A  y6 q
  437. /*                None                                                                                                                        */
      I5 T8 T* `  x0 T8 q
  438. /*                                                                                                                                                */
    0 z( Z  y2 _0 Y
  439. /* Returns:                                                                                                                                */
    % p0 Q  F# v4 h$ l) S7 Q# t2 H
  440. /*                Nothing                                                                                                                        */7 X" ?( `: k3 z' S  {
  441. /************************************************************************/0 Z  [; O0 B+ @8 f' l: n- |
  442. void EBSY(), a9 n) |0 {, b9 A& H- R
  443. {7 a4 N* R  H, Z, @  u3 o3 \
  444.         CE_Low();                                /* enable device */
    + N. ?) r/ c" j- c% ?; H
  445.         Send_Byte(0x70);                /* send EBSY command */
      m* ]0 ^+ O+ o" G7 z
  446.         CE_High();                                /* disable device */1 @$ z  _8 Z/ ?! F6 B
  447. }
    - `( ^7 l) V4 f, K
  448. % X9 o) G( N1 _: a
  449. /************************************************************************/
    1 X5 M8 p$ g( `8 Z
  450. /* PROCEDURE: DBSY                                                                                                                */! p" N" ]; u4 @* z+ y; I( |& d
  451. /*                                                                                                                                                */* W8 m5 |1 e! ^$ g9 z
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */7 f; `7 V$ ]1 H2 T
  453. /* programming.                                                                                                                        */$ L; e$ T- @- Y. C6 G) s  g
  454. /*                                                                                                                                                */" ]1 i# s. P4 W
  455. /* Input:                                                                                                                                */5 w) d: Z' K( j
  456. /*                None                                                                                                                        */
    7 _( B- {& X7 j* ]( U% ?( t
  457. /*                                                                                                                                                */# @- C1 w* B5 p" P5 Y5 M
  458. /* Returns:                                                                                                                                */+ a) o9 k' D  g8 W
  459. /*                Nothing                                                                                                                        */7 [4 o+ l' ?* n4 l; ?: R5 R% G0 A9 K
  460. /************************************************************************/
    9 \5 G' u' V  L& V0 c0 t4 i+ e
  461. void DBSY()% I4 l. B9 G" |* Z
  462. {
    5 U3 j0 |+ ^8 |, o5 @$ |
  463.         CE_Low();                                /* enable device */
    - F# v0 O7 I5 p; ~# B2 \$ B2 v
  464.         Send_Byte(0x80);                /* send DBSY command */& ^/ M/ I0 W" p
  465.         CE_High();                                /* disable device */' a  D  y6 C) F9 g8 \
  466. }
    / b/ i; G" C' O. b
  467. . w; f( Z+ f7 }# X1 m; H$ o! d8 W
  468. /************************************************************************/
    , S# O* r7 ]3 E7 R
  469. /* PROCEDURE: Read_ID                                                                                                        */! y* }& G* l/ W0 ~/ n
  470. /*                                                                                                                                                */
    7 M( I. R" N0 b. r* q6 H8 C
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    1 H# o& m9 }0 g/ w; G" g
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */# H/ r/ c$ P! c- p4 d) s
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    . q) H7 E) y2 b- t. y9 I
  474. /* whether the device outputs manufacturer's ID first, or device ID         */$ K( \) \0 F) J6 c) J: F5 y2 h- Y
  475. /* first.  Please see the product datasheet for details.  Returns ID in */1 j4 \! {. O; Z% k" J
  476. /* variable byte.                                                                                                                */
    0 }, G7 z: u6 Y0 _$ b. {! {
  477. /*                                                                                                                                                */
    . z' r% d3 F, ^0 |: D
  478. /* Input:                                                                                                                                */0 K7 K# w. q: @% S, b
  479. /*                ID_addr                                                                                                                        */
    & G- {' f0 }, s; ~& |
  480. /*                                                                                                                                                */2 u  x+ `: y7 }6 [# J
  481. /* Returns:                                                                                                                                */
    0 x1 t8 M3 T: t$ q
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */6 e2 ^; C# v$ k
  483. /*                                                                                                                                                */
    5 Y" {8 B% v5 a- A  Z# a
  484. /************************************************************************/9 N% X" K- i/ U( y9 @$ y/ d
  485. unsigned char Read_ID(ID_addr)
    * f5 b1 h$ m6 F& x! |% u
  486. {
    " A: `2 E; q2 }3 F
  487.         unsigned char byte;
    8 Y8 }& Z! r. O, U2 t
  488.         CE_Low();                                /* enable device */& Y5 M5 J3 p6 c+ k% g
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    . X4 W& F0 Q) q7 n5 @8 h
  490.     Send_Byte(0x00);                /* send address */. y) ^; u/ m3 p* X4 x, q5 f
  491.         Send_Byte(0x00);                /* send address */% [2 V7 q! {8 r: P
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
      G( ?+ Y* n2 Q' U2 W# ]8 m
  493.         byte = Get_Byte();                /* receive byte */( X' H' s! @4 V
  494.         CE_High();                                /* disable device */
    $ T4 X1 u$ z& w5 J
  495.         return byte;* U9 C1 m9 ?7 P* E+ B7 w! [
  496. }
    / v7 ~1 S: |% w5 r0 _" d2 j2 b8 x
  497. / @* F; R* m  Q- {6 }( a* v1 v" Q
  498. /************************************************************************/
    : `) ]7 T8 L& V& }3 r6 q9 P& C% m" C
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */0 M& y' j0 X: T* A* Q4 b" d. z
  500. /*                                                                                                                                                */
    3 z" W; z  q: u; _
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */6 i- q, I) s1 L
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    2 z) T3 ]  q5 p/ t
  503. /* Please see the product datasheet for details.                                                  */
    8 G! `3 }7 V: ?+ D0 L
  504. /*                                                                                                                                                */
    5 [) J& x' d0 K6 e
  505. /* Input:                                                                                                                                */
    0 n' t: A/ b) m7 u
  506. /*                None                                                                                                                        */
    + H, U' h4 @1 ?& D- }# q
  507. /*                                                                                                                                                */
    9 O7 z2 g. d' ^2 x5 \* {# j* d
  508. /* Returns:                                                                                                                                */
    , D4 |/ I' r8 _7 \) ^+ a- p
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    ' m! n/ O& E' h  q4 A, X3 |
  510. /*                 and Device ID (8Eh)                                                                                        */
    , Y- d" [0 _3 ?, y
  511. /*                                                                                                                                                */
    & M7 Q9 V4 X' o
  512. /************************************************************************/
    % k! U' [5 T+ a, e- L+ [2 Z6 t
  513. unsigned long Jedec_ID_Read() . U( Q% C* L2 H4 B: ~. }' F8 W. g
  514. {
    8 p4 y  _, u) j: Q
  515.         unsigned long temp;
    0 H4 }- Z* @6 ~( U2 t# |- p" ?
  516.         3 G/ x4 z/ X7 [3 Z$ t  v" j
  517.         temp = 0;* a  |4 Q( @( ]. j5 R$ N
  518. 7 G# E! h6 }3 Z. h) y
  519.         CE_Low();                                        /* enable device */
    ! C3 Q# J8 W; j( O7 w9 A2 z
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */) e6 [$ q( u) u& z/ w2 a& h2 [
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */, ?7 c0 V! A& B7 F) Z
  522.         temp = (temp | Get_Byte()) << 8;       
    : A# `/ U' ~% N+ N9 r/ t
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */6 a. M6 u4 F; X0 s
  524.         CE_High();                                                        /* disable device */
    3 ?8 ~! c9 p* q( Z; y  a/ J' r
  525. / m, i4 V/ Y" S# M5 w2 N  x
  526.         return temp;/ E" i& r/ K2 \' N( s; L
  527. }
    ( \) J4 l4 q' C6 i

  528. & X; h9 \8 O* G; l2 O
  529. /************************************************************************/
    / \, [! Q# I7 G8 [
  530. /* PROCEDURE:        Read                                                                                                        */
    5 t: N- l' W; D* ^4 |, E
  531. /*                                                                                                                                                */               
    3 P& w; c  a3 i( }& b
  532. /* This procedure reads one address of the device.  It will return the         */
      w, L# B9 Y$ w8 C' e0 {
  533. /* byte read in variable byte.                                                                                        */
      P% i% U& N# R# _: r
  534. /*                                                                                                                                                */7 P; ]$ u/ r2 M# B! ?
  535. /*                                                                                                                                                */
    . n; Z* ]" E0 G$ M# b! v, @$ M5 o
  536. /*                                                                                                                                                */
    7 H6 R0 ^+ V/ p
  537. /* Input:                                                                                                                                */
    - v! V6 J. G: N
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */' x/ d- y* R) c* X6 t
  539. /*                                                                                                                                      */
    0 H1 g9 S3 `7 q/ |$ P8 F6 V( D( T  }' g
  540. /*                                                                                                                                                */
    4 D5 r/ ^5 a# w. q4 G) ]
  541. /* Returns:                                                                                                                                */
    7 L6 g9 I8 }: L
  542. /*                byte                                                                                                                        */
    * p" W% V# y* Q! F1 p( J3 P- B
  543. /*                                                                                                                                                */
      p8 T* I& i* o7 e, k4 E
  544. /************************************************************************/) B' s2 }# p& }* l9 B2 {
  545. unsigned char Read(unsigned long Dst) " h, g4 ~5 G$ }- y: ^2 I! n3 r
  546. {& v" ^4 P, N0 c
  547.         unsigned char byte = 0;       
    , w8 k: D* O7 Z+ x9 j
  548. / S0 l8 K# E1 A4 p
  549.         CE_Low();                                /* enable device */7 D: {; a, [! p6 K+ Y  J2 P
  550.         Send_Byte(0x03);                 /* read command */
    ! C- ]1 d% T! j2 c! T2 t' F! ^
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ' ?1 i  H7 @5 Y" |
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
      d4 }2 X% C) I( L$ H
  553.         Send_Byte(Dst & 0xFF);1 Y2 f3 L2 T+ A  d! _6 t
  554.         byte = Get_Byte();0 R  |/ f8 y! L3 v% W; q9 u) c1 w
  555.         CE_High();                                /* disable device */
    3 P7 Q6 V) n4 C( _! [
  556.         return byte;                        /* return one byte read */
    $ \3 B, i# g, [- E
  557. }
    5 ]' Y5 i3 ~4 j) y2 Q/ w' Z  x
  558. ( ^- l$ I( e4 Y. B9 j8 O
  559. /************************************************************************/
    9 P: _+ c) O* Y7 y& h( f
  560. /* PROCEDURE:        Read_Cont                                                                                                */' H+ E5 W  Q7 ~4 b" B+ L" }: j9 |9 `
  561. /*                                                                                                                                                */               
    + L3 S2 x% v2 D
  562. /* This procedure reads multiple addresses of the device and stores                */
    ( ~' {+ {" _8 s+ g8 F  z3 {
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    0 S8 f8 {( x9 o1 n
  564. /*                                                                                                                                                */  `9 E) e- ^0 }( [. B
  565. /* Input:                                                                                                                                */: M: w# X1 e5 q
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 I8 a) p, t2 ^' r
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */5 b! R: A. N8 ~& m2 `, {
  568. /*                                                                                                                                                */
    + l* O2 Q: G. u; v
  569. /* Returns:                                                                                                                                */
    1 @9 ]6 |! r' h. _1 Y7 [- N
  570. /*                Nothing                                                                                                                        */# z- d& j# R7 z, B! j' j
  571. /*                                                                                                                                                */6 V, R/ J( Z; V$ N2 B" O! {! g
  572. /************************************************************************/
    ( e8 D7 D4 [7 \3 N' m4 a' h
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)2 h) U0 U; `! p! n4 P( N
  574. {
    6 b- ]" b" J8 d0 {8 K2 Q" t' @2 d
  575.         unsigned long i = 0;
    0 h9 t9 O* w0 W" @2 s
  576.         CE_Low();                                        /* enable device */
    $ Q* _0 }" b' X% u4 h" D6 x' {; d
  577.         Send_Byte(0x03);                         /* read command */
    $ S4 [4 B2 @. E) b; z6 A3 E
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    : H* M: x/ Q6 W
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));# M! u, ?8 {* M( e+ P
  580.         Send_Byte(Dst & 0xFF);
    9 Y5 o0 n# d& A
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */: k  d: I6 x0 d5 S
  582.         {9 Q# k* k. s) a( q# `
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */  ?4 y6 Q# S; G8 C
  584.         }
    / a# i; e$ v2 |5 w; O- Q  v# F
  585.         CE_High();                                        /* disable device */+ z  N7 z% o: [+ h
  586. + r- s$ ?- P+ n3 t4 p5 c* m. g1 F
  587. }% [- q' N1 m% A5 L8 }5 E

  588. 1 f5 V( g+ e" F3 m
  589. /************************************************************************/3 z! L# |: G  W4 A3 U; h0 ]" K& f
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    % @4 K2 x. b, ^0 y
  591. /*                                                                                                                                                */               
    ' e1 r3 }# I: `; F: D
  592. /* This procedure reads one address of the device.  It will return the         */+ R. K+ |% a' X1 y5 j
  593. /* byte read in variable byte.                                                                                        */, j' l. ]& `  s% ^+ w6 k
  594. /*                                                                                                                                                */4 p: d; z/ v; X" ^
  595. /*                                                                                                                                                */6 H9 q+ P4 A, ?7 q; ?$ T2 Y
  596. /*                                                                                                                                                */
    7 W: K$ }# q5 f7 J9 H
  597. /* Input:                                                                                                                                */9 C1 x& }! @" t  g- [2 g* K* G
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        *// s; _: Y. Q- j  y5 l- q3 o* Y
  599. /*                                                                                                                                      */) @9 a; w0 _  G. l
  600. /*                                                                                                                                                */  @% I6 D- G5 y& e
  601. /* Returns:                                                                                                                                */! h7 i0 E9 s1 X# S
  602. /*                byte                                                                                                                        */; Y9 S- C! z* Q3 o4 f( P7 g
  603. /*                                                                                                                                                */' H. X, c5 d! t
  604. /************************************************************************/
    8 i  J  A1 r6 S( s& m& G3 X
  605. unsigned char HighSpeed_Read(unsigned long Dst) ' s& T! a4 q0 _2 i" o
  606. {) X# E" E0 b7 O! \9 f
  607.         unsigned char byte = 0;       
    9 B/ ]4 ^, w3 J6 ^) S
  608. 7 j( K* _" v( j& F. L: }. g
  609.         CE_Low();                                /* enable device */& r" C+ V2 v2 |; J: k2 i  l3 X8 K
  610.         Send_Byte(0x0B);                 /* read command */
    7 J' v8 Z# s9 j) c3 N
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    # w+ Q2 `  H3 w6 J+ _; S
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + g" P2 Z) E; H
  613.         Send_Byte(Dst & 0xFF);
    ( E! o* z- ^' _9 J
  614.         Send_Byte(0xFF);                /*dummy byte*/# ]# A1 p1 z2 j
  615.         byte = Get_Byte();" [* _7 ]2 w$ d, h
  616.         CE_High();                                /* disable device */( D7 N3 n- V; k! ]" n7 C3 P
  617.         return byte;                        /* return one byte read */$ j- J  |; `; Z$ p; a$ ~
  618. }
    0 K& [! o. V* [$ i

  619. 8 ?# C" i2 r( s) i$ f7 Z4 a$ }
  620. /************************************************************************/: ]8 d. p% F& ]: |- d4 `
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */6 B( B; g& q. x4 Z/ e2 `/ l
  622. /*                                                                                                                                                */               
    % G$ _3 e3 Y, f
  623. /* This procedure reads multiple addresses of the device and stores                */
    7 c$ ?9 P$ L- C& ?  o
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ( D( `# Y0 o7 L, k, q# g
  625. /*                                                                                                                                                */- C4 I) n1 y; s
  626. /* Input:                                                                                                                                */" S& j% \- Z! H7 y# O- j: Y  y' z# B
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 Y& u2 u6 ?) q, T5 {& t2 D
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    + c5 H7 i' l' }! ?: v+ I1 N
  629. /*                                                                                                                                                */8 q8 H& r# M) ^3 ~
  630. /* Returns:                                                                                                                                */4 K& o# c2 }5 Z/ ?2 q' s  q
  631. /*                Nothing                                                                                                                        */2 L% p  p( c5 o5 j# h& s3 C; y
  632. /*                                                                                                                                                */
    . S' v! L/ F/ g
  633. /************************************************************************/
    ! H; I% x% |2 {& a5 v$ X. L& q
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)  ]2 [" C( b$ `  e; l6 S
  635. {9 |  T$ q0 j/ _1 {: u) h9 l/ I" c& f
  636.         unsigned long i = 0;
      {2 k; ]0 D% p6 A1 [
  637.         CE_Low();                                        /* enable device */
    ( c5 p* t9 E* Q) @
  638.         Send_Byte(0x0B);                         /* read command */" s* j7 F! ?1 x+ a  e3 |" a* @8 J+ W
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' X7 G! T6 k+ G- T* E
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));- R4 m9 `- B4 E% n5 U
  641.         Send_Byte(Dst & 0xFF);
    ; y) g& Q+ `, u  M
  642.         Send_Byte(0xFF);                        /*dummy byte*/0 n% Q0 N6 m* e9 s9 Q+ T
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */" K0 h3 G$ `1 @; n# L
  644.         {4 I) j; H3 d; W0 N2 n4 n
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    + C  S$ E! B9 V$ ?& ^0 ~  n
  646.         }
      u, {4 C# N2 _: |8 x
  647.         CE_High();                                /* disable device */
    1 T5 I  D" `0 X5 i  x+ L
  648. }, Q4 N" i' K7 N  p7 C. P
  649. 0 a& M3 T+ N7 l/ o: t/ z
  650. /************************************************************************/
    . o1 L) n7 S" m3 K- P3 ^
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    - D' w* L! O" x8 E  i" V
  652. /*                                                                                                                                                */0 z( K  Z1 i2 [# C* `: T0 S5 A" y
  653. /* This procedure programs one address of the device.                                        */! B1 L, G. g: z& z& O" E  B  a, ~
  654. /* Assumption:  Address being programmed is already erased and is NOT        */+ X( }2 s) v* V5 Z; H( u
  655. /* block protected.                                                                                                                */: ~  L7 p' S7 t1 L
  656. /*                                                                                                                                                */5 \" O: o) [; l* d' M+ ]
  657. /*                                                                                                                                                */* S" g; R! ^/ d
  658. /*                                                                                                                                                */
    $ \$ h8 ^4 c3 B. m- P
  659. /* Input:                                                                                                                                */
    $ b% Y( l, `$ ~2 b/ _( h1 e! ?
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    . o2 a8 V2 M0 m5 b3 g. n
  661. /*                byte:                byte to be programmed                                                                */
    8 c7 z5 l& N6 h. Z. N1 ]
  662. /*                                                                                                                                      */
    ; E. b9 Q' P$ @  j: }6 i
  663. /*                                                                                                                                                */6 F. D, d, J) Z1 _" m% h) P: f) Q
  664. /* Returns:                                                                                                                                */
    4 c/ Y- _* t6 W* H/ q6 \/ _
  665. /*                Nothing                                                                                                                        */
    ) x9 A7 J8 N$ N1 D) \; ~- t
  666. /*                                                                                                                                                */' U# ~- v1 C3 ?: O4 X# L
  667. /************************************************************************/
      `' I: ^2 @5 \, I9 `+ R. }
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    & R  m: a; Y$ }) B! m6 V* f
  669. {
    * N" L2 X* j3 Z$ B( i* n1 L
  670.         CE_Low();                                        /* enable device */6 @; G* u5 Z7 o4 H
  671.         Send_Byte(0x02);                         /* send Byte Program command */$ H  V* V* l: N& L8 R$ Y- j
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */8 d% H4 Z, z4 b( H! R, T
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , B/ \2 N/ k/ k# ^% d# z
  674.         Send_Byte(Dst & 0xFF);9 U5 g2 ]1 J' P( g5 K! K$ g
  675.         Send_Byte(byte);                        /* send byte to be programmed */7 r2 |" Y. F3 Y8 g+ ^1 Q
  676.         CE_High();                                        /* disable device */
    1 T. l9 |0 U: K' Q/ q5 R
  677. }
    - G  G7 t. u) O% m  F$ b1 W0 C* T: z
  678. 9 k" a) |% j! d: R+ `
  679. /************************************************************************/* v+ T/ b; r$ ?& l' w" I2 z
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    6 `- s* I6 D) F+ q% k5 l
  681. /*                                                                                                                                                */, t2 d- f, p$ H/ i
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/7 R' R7 I. f8 h3 k! j+ W
  683. /* the device:  1st data byte will be programmed into the initial                 */3 L8 Y" X* K- r1 ~: j/ B, J
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */6 S' `8 R' x4 E9 H, P) X
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */: m8 Y. W- I. P
  686. /* is used to to start the AAI process.  It should be followed by                 */* B; H- _1 H! N+ q
  687. /* Auto_Add_IncB.                                                                                                                */' Q  G: v, N/ O7 z/ H
  688. /* Assumption:  Address being programmed is already erased and is NOT        */1 F8 @/ k, f7 F) e) D& A9 \' X
  689. /*                                block protected.                                                                                */
      q. }" c0 ?  B* ?0 ~
  690. /*                                                                                                                                                */
    6 U5 _# u$ y+ ?9 d! V: h8 ^# h
  691. /*                                                                                                                                                */
    4 L/ ?! ~3 {4 X# g  M- @4 d* |
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */2 X7 i1 k2 k" B9 T& u$ B  P' V8 y
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */  i. n( }" e! ^- Z1 `5 s9 E! ~
  694. /*         unless AAI is programming the last address or last address of                */
    6 D8 q' }8 T1 ~/ P# b6 a0 f
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    / V( K: M" A( k2 I
  696. /*                                                                                                                                                */
    7 Y; K9 v) ^/ C% I% q
  697. /* Input:                                                                                                                                */) g* Q+ c; {/ H- w! {. s
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */$ d+ {5 l6 L7 i$ d# c/ [( |& I
  699. /*                byte1:                1st byte to be programmed                                                        */
    ) y. h/ G/ F4 f2 Q! a
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ! l$ t6 t6 ^. ~
  701. /*                                                                                                                                                */
    ' f9 n8 z" I& P, d# {4 v" C
  702. /* Returns:                                                                                                                                */. A1 z' @; S% J( }
  703. /*                Nothing                                                                                                                        */
    " n9 p( i+ w) q9 {# g& V
  704. /*                                                                                                                                                */
    1 E. Q9 u) A5 [0 P2 L" [+ W  P
  705. /************************************************************************/
    4 Z$ r% l" B6 \- n( N( c
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    / x; @* m/ P6 }/ R) ?0 G/ a+ s3 t. d
  707. {6 H. J* H: \: T$ }4 l7 r- _1 z! P0 @* u" O! H
  708.         CE_Low();                                        /* enable device */
    ' d& E  z3 F4 H) s0 e* @
  709.         Send_Byte(0xAD);                        /* send AAI command */8 |' T, _: [  g5 G2 Y
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */) C/ R+ o) t% f; ]  K2 r+ H% m' S
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));6 {- }- G0 ?; F1 W5 z8 @
  712.         Send_Byte(Dst & 0xFF);$ I3 q  i) S( W8 y& b2 E
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ) f& ^* s& u5 {5 H+ L" i5 n
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */3 }1 J- {; I" p# w! k; a) M
  715.         CE_High();                                        /* disable device */9 {4 b0 l& Q* F- ~+ p- K2 G
  716. }& D9 y% q5 e$ S6 y( I: ?

  717. 8 n* }! U8 D  S
  718. /************************************************************************/
    1 X6 ?% k1 h/ m- w
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */7 X2 v* |/ H0 r
  720. /*                                                                                                                                                */1 R8 a6 d! Y0 y2 g5 C5 }
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/7 Q& F) {6 k! Q& m+ {+ Z
  722. /* the device:  1st data byte will be programmed into the initial                 */$ o  j' ~: u8 l# J1 w
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */* O( b) V- \& l4 C
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */( ~6 z5 O! \0 S4 b4 p) b0 E5 z) H
  725. /* is used after Auto_Address_IncA.                                                                                */
    5 P1 C* g. K: e! M! h. L% o; r$ Y) e' e* G
  726. /* Assumption:  Address being programmed is already erased and is NOT        */; ]8 U8 b9 R3 \7 ^, I
  727. /*                                block protected.                                                                                */" o9 F! Q6 t  W5 u0 F# I
  728. /*                                                                                                                                                */
    7 ?$ l5 |( I- x
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    % N! ~! J1 ~) `+ a
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */# t! c0 [1 F! n5 n8 Z# L) O
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */+ f2 V- S' I% y6 n* u
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    1 F" j" t4 Q1 s5 `* x, M
  733. /*         last address of unprotected block, which automatically exits                 */
    . s5 x) q& t% e. n7 T, \
  734. /*         AAI mode.                                                                                                                        */3 @8 J! u" C9 }+ _7 g9 N) o1 \
  735. /*                                                                                                                                                *// W# i, M' _! }' H3 J- z2 [7 r
  736. /* Input:                                                                                                                                */$ r' a7 F- Z8 @% \6 Y! R' J1 w
  737. /*                                                                                                                                                */
    2 y1 |  B, G0 j. r
  738. /*                byte1:                1st byte to be programmed                                                        */
    ) G6 ?1 A9 K$ ]! O- K- e$ ]" D' ^5 r
  739. /*                byte2:                2nd byte to be programmed                                                        */
    1 l- P' d$ i3 P
  740. /*                                                                                                                                      */
    ! F. ~2 @( ?9 z2 N
  741. /*                                                                                                                                                */- g8 [9 J% K8 s6 @: @* J
  742. /* Returns:                                                                                                                                */
    , ?1 x9 S1 [, e4 }6 W' ]
  743. /*                Nothing                                                                                                                        */
    ( O* f8 l2 m  O5 [7 c% v% y
  744. /*                                                                                                                                                */; P$ o) x( a" J% A; T; z, S
  745. /************************************************************************/
    9 `1 B6 n; A) q, |: z
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
      m8 F- r9 G! v; T6 l0 q" [1 ]
  747. {: U8 i1 N9 V: ?- i% C8 Z
  748.         CE_Low();                                        /* enable device */7 X& W/ x' c* L  B
  749.         Send_Byte(0xAD);                        /* send AAI command */
    $ W# V; I) o6 G0 A& o
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */8 P# @  X* N9 D$ Q
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed *// D! _# l% @" F  D
  752.         CE_High();                                        /* disable device */$ W9 u% p3 D5 f0 v1 F, F
  753. }1 [7 q! s& ]0 W" x
  754. 2 J3 e6 a  g3 K  ~: l/ P; H
  755. /************************************************************************/
    / v4 v+ V5 }) S0 t8 l
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ( w2 h! W. i+ N" V0 d3 g5 r" s
  757. /*                                                                                                                                                */
    2 o+ ?: z- u5 c
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    / h0 p" C4 h; `% I
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    7 o4 O/ U# |# `  {7 p  M$ ~1 n
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    - n5 t  |) [9 A7 N+ K
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ' x1 m+ }$ Q, z7 R1 F
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */+ N& l. d" |' \7 \# e- V; N
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  *// j& Q5 G9 \; Z. l. f
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    9 h5 Z+ ?  k* `( I; T' ?- d( J
  765. /* Assumption:  Address being programmed is already erased and is NOT        */7 A2 O" b- O1 f- D0 k! a
  766. /*                                block protected.                                                                                */
    ( q- ^- H* k) A* \
  767. /*                                                                                                                                                */
    9 R9 w7 C- [9 k& t% P
  768. /*                                                                                                                                                */
    0 p4 ^2 i* S- r7 ?% ]
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    3 \7 J: `& B+ i
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */3 W" Z, }# Q7 i7 q
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    & ~- {2 p  P: f% i
  772. /*          to exit AAI mode unless AAI is programming the last address or                */  ]  [; s3 u+ I* E( m6 y( a& x
  773. /*         last address of unprotected block, which automatically exits                 */0 ]' w2 g, ^% Q8 Q2 d; r7 E$ f
  774. /*         AAI mode.                                                                                                                        */# z- ~8 F; }5 B8 H3 K
  775. /*                                                                                                                                                */
    ' z5 h4 I' f3 n+ M
  776. /* Input:                                                                                                                                */2 e+ p4 D. W# d! Z, F
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// D3 e* c% N2 n0 \7 R
  778. /*                byte1:                1st byte to be programmed                                                        */
    - b  j; [  U7 e$ g+ H+ b2 L% u
  779. /*      byte1:                2nd byte to be programmed                                                        */  h) ?# y* Y  ]: ^5 j6 w9 u
  780. /*                                                                                                                                                */9 M: C$ s: C' J2 C* _1 |
  781. /* Returns:                                                                                                                                */. k( |) V0 G- G4 M$ Z
  782. /*                Nothing                                                                                                                        */
    ) H' j/ y  @$ O! u# W& e! w( Y
  783. /*                                                                                                                                                */7 l+ {# O; U3 i( v
  784. /************************************************************************/" q. f# ^( E. T7 a, _; b
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    : o) U) e4 {" p- }) g5 S* Y7 m
  786. {: s, `, `3 Y5 g) ]* E- N
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    6 k3 ^* a* H' Q  a6 ?
  788. # s# L: v1 @! a# U! \8 O
  789.         CE_Low();                                        /* enable device */+ G# S' R# x. x/ S
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ( E' E9 h! n9 [. i: ~. G- t
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 e* t+ z* c+ q* p3 G* o7 `# e
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));% v9 z& s' r+ o0 l0 H$ r
  793.         Send_Byte(Dst & 0xFF);
    + C* z+ X% f8 ^4 h
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    % i" V- [- M, a+ o! r
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    9 |' X  j3 P, p; \0 j$ W) G5 Y
  796.         CE_High();                                        /* disable device */. L: e! b9 y. n  w  ^8 p
  797.        
    5 Z* J. k$ m7 p* e
  798.         Poll_SO();                                        /* polls RY/BY# using SO line *// d9 n4 K# q8 B+ g
  799. / ^$ @! i; U% s% z& h6 I
  800. }
    6 m9 g* k! r* u* r% G7 i
  801. 5 @, O9 \# f1 Q1 K
  802. /************************************************************************/+ N3 j6 ~! c+ u7 x) b3 Z
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    , w+ D( Z+ B* N
  804. /*                                                                                                                                                */
    7 S  B0 W& ^! r& ~0 i, ?
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */  v, G. o9 L# N1 ~% b; e" I
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */$ [6 U$ U" E7 G& _! Y
  807. /* AAI programmming is completed.  It programs consecutive addresses of */9 w7 p3 J+ g& N" X
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    5 e! N4 l$ V, C
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */& L# Q. o# V& k8 {
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */& j. [; m0 e& M' p  e
  811. /* used after Auto_Address_IncA.                                                                                */
    / y! ^* z! |. @) I$ p
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    + m: h& e5 b3 N
  813. /*                                block protected.                                                                                */
    + g" @: i! ~/ G/ C* E2 ]$ S
  814. /*                                                                                                                                                */) G3 t1 Y0 |3 b( V
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / m. s( a- V  n/ G; |$ R/ L
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */2 @6 P5 |. [$ v* b7 S& ~  G9 \
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    & Y2 I3 H" O( G( J, O
  818. /*          to exit AAI mode unless AAI is programming the last address or                */# U3 ?. @; F* v$ y% T6 [
  819. /*         last address of unprotected block, which automatically exits                 */: i& m( ~( m" S: h: n6 y5 l( G
  820. /*         AAI mode.                                                                                                                        */
    % ^  g! G8 L2 s: x& t: k( ^0 T0 k
  821. /*                                                                                                                                                */+ _' I! o( ~7 B4 Z8 l
  822. /* Input:                                                                                                                                */3 z; b+ ^. H9 F+ e2 v( A
  823. /*                                                                                                                                                */
    , w8 D* N$ y8 r" H: s
  824. /*                byte1:                1st byte to be programmed                                                        */' @( @0 Y9 B! g# H. p! q8 K
  825. /*                byte2:                2nd byte to be programmed                                                        */
    & R9 Q/ M2 P$ o: @# P
  826. /*                                                                                                                                      */
    , g9 M7 h, N. F7 i" ]* H! t% t4 Z
  827. /*                                                                                                                                                */' i3 }9 @% R1 m4 c# s
  828. /* Returns:                                                                                                                                */* Z5 ^3 R, U+ W& p
  829. /*                Nothing                                                                                                                        */; E* o) Y3 A, }5 M/ F3 B) R, q$ G7 @
  830. /*                                                                                                                                                */4 w$ l8 a0 B  s% s- N
  831. /************************************************************************/
    & h1 y; O$ V+ G% e8 z, m
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    5 h4 }; o( C1 M  k+ {! E( c1 Y) o
  833. {
      K1 C9 C4 k/ W/ l5 g- `; c# \
  834.         CE_Low();                                /* enable device */9 ]$ s/ `, t  `* P7 f. t6 N- n$ o
  835.         Send_Byte(0xAD);                /* send AAI command */
    1 Y: W( a5 Z- E% l5 c
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */: n$ b  y/ V" Z: Z% i& E
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    : O5 K& W  R+ b* v# T* }
  838.         CE_High();                                /* disable device */
    9 M. _  J1 C7 b5 \4 [

  839. # P+ k# l0 s  @7 v, `* j1 e
  840.         Poll_SO();                                /* polls RY/BY# using SO line */8 v+ q" R2 J2 V' B9 h2 t
  841. 3 V% S' y! l  Y5 M  A
  842.         WRDI();                                 /* Exit AAI before executing DBSY */1 ^6 ^4 F; `( q% J
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    ; {; O2 \0 e/ {2 J, V) |
  844. }2 M. ~4 r+ u4 M( G+ I( `
  845. 3 h% u! n0 V* ~) l
  846. /************************************************************************/
    " s( O+ X3 V; u  V" D& P
  847. /* PROCEDURE: Chip_Erase                                                                                                */" J* M" |0 k' F: }0 b
  848. /*                                                                                                                                                */
    . ~  y8 r4 I" f: K. T
  849. /* This procedure erases the entire Chip.                                                                */) g# o6 D/ |" M  w
  850. /*                                                                                                                                                */
    : Z' Z) B# z1 h! X4 |$ T
  851. /* Input:                                                                                                                                */! @6 J! H" m3 c3 O
  852. /*                None                                                                                                                        */  z+ Y! s+ Y# h! l/ G: d# F
  853. /*                                                                                                                                                */
    9 z' l0 n4 N4 B; u6 |8 ^0 f+ t
  854. /* Returns:                                                                                                                                */
    0 K. X) G  r1 u, z+ {% N' `
  855. /*                Nothing                                                                                                                        */
    " a4 h$ |, {% f. a9 ^
  856. /************************************************************************/
    . c/ A* e, K% x, R
  857. void Chip_Erase()) X; p/ P5 z8 Q/ l. L
  858. {                                                ' n6 ]% M* N) W* W' t% N
  859.         CE_Low();                                /* enable device */1 q) {6 m% P2 O1 H: f( q
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    / p6 h3 u  S1 G( @7 @
  861.         CE_High();                                /* disable device */
    3 n7 |( q7 \' `" S$ N- |: m# O
  862. }
    4 Q* N% A1 a: U

  863. - C0 x: C4 @7 l+ ?, B
  864. /************************************************************************/. M2 E+ x* P, z2 w9 K8 C. \8 S
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    , Y7 A) G7 r3 W0 @; b2 b+ v* n
  866. /*                                                                                                                                                */
    . E3 I5 _( c9 h, k) X3 u- D+ N6 V. P7 _
  867. /* This procedure Sector Erases the Chip.                                                                */. N% h; j/ |2 b- j
  868. /*                                                                                                                                                */
    ' O' {$ e' r) e- `, l: T
  869. /* Input:                                                                                                                                */
    , V# o. a& V; d
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! z$ ^1 g1 s% h9 r& ~+ ]4 m
  871. /*                                                                                                                                                */
    ; t- t# ?/ [0 M4 R, [$ C+ C7 `+ P3 i
  872. /* Returns:                                                                                                                                */
    , @" e  K4 Q* Y2 H. i
  873. /*                Nothing                                                                                                                        */+ p2 w6 G7 ~% J, y# T) y, q
  874. /************************************************************************/
    2 i5 D- \7 G. t0 Y+ B
  875. void Sector_Erase(unsigned long Dst). w+ B! G  G; f( H4 @+ T
  876. {; z. U5 b+ G; H# n, K

  877. ) M( x& c: ~! B. s4 g

  878. 1 R# y9 S+ w7 I
  879.         CE_Low();                                        /* enable device */2 o2 Y. ?* }1 b% p+ T
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    8 N/ b1 ^' d5 Y
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ) x+ C% g+ K0 N! }
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " o" H+ w  L  `+ k9 x8 s" C  M0 M
  883.         Send_Byte(Dst & 0xFF);% J6 U3 h6 y- O- ^0 ?
  884.         CE_High();                                        /* disable device */- a) C6 R9 v7 Z3 ]9 D
  885. }        2 b6 D- \  W: C. f' O
  886. , W" e' j$ B3 A% J6 L
  887. /************************************************************************/
    3 \! s  {% ^8 s
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */* D1 X% F, @  c; X# @* W6 T' ]( Z
  889. /*                                                                                                                                                */: Z) U. q) c% s) J
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    $ _  Z7 X0 |6 w* e1 z4 p
  891. /*                                                                                                                                                */3 Q4 N4 V/ Q: D
  892. /* Input:                                                                                                                                */
    , E8 m9 @7 T- }7 t% G4 v, C5 z- ~
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 N( t  X1 n/ h( y# p
  894. /*                                                                                                                                                */
    / G$ \0 ~- P4 `
  895. /* Returns:                                                                                                                                */) z5 ?- A3 s$ f( c8 c5 ~
  896. /*                Nothing                                                                                                                        */
    + w5 {1 a" K: h8 M, m
  897. /************************************************************************/
    8 W! x4 O8 N2 f- G% N
  898. void Block_Erase_32K(unsigned long Dst)4 r% W/ D1 @/ g% V! O
  899. {0 V' v1 B6 q, s1 N  n+ n6 l
  900.         CE_Low();                                        /* enable device */( b! c9 n# {# U* M4 H7 X
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */; q% a' M& T- N. g( a2 C7 L' t
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    5 r7 K0 g& J0 h! r" d
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , a( |# \- t5 m
  904.         Send_Byte(Dst & 0xFF);5 y" l8 i, Z# q. K$ h
  905.         CE_High();                                        /* disable device */; g9 \) j  {: l% L! E/ G' Y1 b1 ?7 s
  906. }; K7 v0 r4 J+ ?2 d' s
  907. 9 ]1 S3 ]. r4 G6 F
  908. /************************************************************************/7 K5 Y, _! A+ L
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    ; s; m) V+ A& `9 S  h+ e! q/ E: H
  910. /*                                                                                                                                                */) Q' d- l1 [, X: h; c1 f+ n
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */# Y: J( D  K* L2 e. P$ ]1 a; B
  912. /*                                                                                                                                                */
    + l# m* O5 V# x: ~- h3 B2 f
  913. /* Input:                                                                                                                                */# v- l: h0 ?& ~/ t, z/ E
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 p: ]7 g+ H/ X0 T, l  f
  915. /*                                                                                                                                                */
    ; J8 q, F* a" P% r- l( h
  916. /* Returns:                                                                                                                                */1 b) \  M! [. t% s7 O8 E& N1 V
  917. /*                Nothing                                                                                                                        */+ i: K4 |" |, g4 M
  918. /************************************************************************/
    7 S8 I) n6 @" |$ \' ?# c
  919. void Block_Erase_64K(unsigned long Dst)- z1 V- x, o, G8 ^" O
  920. {1 s. g& F0 X- a" q( w2 q2 L1 s+ N
  921.         CE_Low();                                        /* enable device */0 U2 r/ G" _% I; y1 {' d
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    5 C6 \) `0 t. P: `7 W  }& W9 i6 _
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 I8 W0 L( i) p, G4 [
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));+ W7 n/ e7 L1 y* \* _
  925.         Send_Byte(Dst & 0xFF);& p: D/ d" J; B' j( x
  926.         CE_High();                                        /* disable device */% h* X' q* A& l8 m: q7 n0 q; g! O/ G
  927. }+ I" T2 p2 M" t
  928. % ^. d; g' n$ x# e5 x; M
  929. /************************************************************************/. v2 K9 g& {: _& A0 g' b1 V
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    5 U3 L  G* o5 A  @+ q: h
  931. /*                                                                                                                                                */
    ( E; X* M7 }  L/ r8 P
  932. /* This procedure waits until device is no longer busy (can be used by        */+ ~8 L. G' L4 E7 }$ ^
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    6 Q: N, r5 a+ H& Z+ X' y
  934. /*                                                                                                                                                */
    - X8 \* y# ^. Y& }6 D! ~( S+ [
  935. /* Input:                                                                                                                                */
    1 f, P, l% v3 v) _, ^+ d
  936. /*                None                                                                                                                        */
    0 [7 k2 I. d( c4 H% {$ H
  937. /*                                                                                                                                                */
    $ w3 g, S2 F& F" G
  938. /* Returns:                                                                                                                                */
    6 E& u2 c1 j) U4 a  A& ^
  939. /*                Nothing                                                                                                                        */6 {$ Z3 \. ~- t  K8 L# H
  940. /************************************************************************/( J% e6 q/ ?3 x: s# s5 \3 F3 V: `4 `3 B
  941. void Wait_Busy()9 I2 `; @7 z2 }' N) Z/ U
  942. {
    0 Y, ]1 d6 ?+ d1 d% j' i
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    * I' b2 ?1 z6 x/ u9 P. x3 t
  944.                 Read_Status_Register();
    9 N3 p9 g% J$ B2 s1 @7 C9 q) S) N
  945. }
    7 _( d. E( D: @8 ]) o6 `
  946.   M4 |* w- i, v5 X% ~9 G( Z" \
  947. /************************************************************************/$ {+ X$ i7 e$ A- g3 O# M
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    , E; W& p- F" M# s7 c
  949. /*                                                                                                                                                */
    . x; n; x! C* I  m- O
  950. /* This procedure waits until device is no longer busy for AAI mode.        */7 G" P" A! s/ y( Z6 K0 [8 r
  951. /*                                                                                                                                                */
    / `* ?) A. N& u) S) m+ D! I, s
  952. /* Input:                                                                                                                                */
    7 ?, N1 j6 b: x* q' I) y. X9 t
  953. /*                None                                                                                                                        */7 @( t( {( E: f( F. Y$ R. \' f
  954. /*                                                                                                                                                */
    8 o3 z+ I+ Q  u" c0 z8 ~9 S
  955. /* Returns:                                                                                                                                */
    2 z% K/ T" U; L( _; q3 P( s
  956. /*                Nothing                                                                                                                        */
    6 W: H5 Y0 d$ K
  957. /************************************************************************/0 U! _3 I! A7 _6 q' u  O
  958. void Wait_Busy_AAI()
    ; L/ y' C) D1 c' p, n6 C& @  {
  959. {# J( n. t" K4 V5 x+ T. H
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    # G" T" F6 M# s: h2 C
  961.                 Read_Status_Register();, `$ z/ [0 t" d; k
  962. }; @6 v+ ~) {8 l0 N  b6 L; b8 ~
  963. 4 [. g$ ^9 k5 {6 N! O. i
  964. /************************************************************************/6 |9 u* {% Y' N6 C# Y1 l
  965. /* PROCEDURE: WREN_Check                                                                                                */
    ( [( o5 p7 p# n, w; X9 N- h
  966. /*                                                                                                                                                */
    : ]( `4 |5 ]4 q" Y" a: u
  967. /* This procedure checks to see if WEL bit set before program/erase.        */7 n  t5 P9 ~1 h) M: K
  968. /*                                                                                                                                                */, p+ w0 ^* s- o  V& O8 ^- I
  969. /* Input:                                                                                                                                */( s/ d, \) s$ x6 n3 X0 o6 ?
  970. /*                None                                                                                                                        */
      w4 \9 }0 j! y+ m
  971. /*                                                                                                                                                */
    + G# u9 ^9 Q0 J- x" ]
  972. /* Returns:                                                                                                                                */8 I9 M- Z0 V- U0 Y0 U
  973. /*                Nothing                                                                                                                        */
    # [& |! L& |8 L8 x2 a1 J# W: L6 o0 Z1 ^
  974. /************************************************************************/' m0 N& v/ z& k7 q5 I8 P7 G' z
  975. void WREN_Check()
    # ?9 _+ `. s0 N7 }
  976. {
    , S3 ]8 v% \# D
  977.         unsigned char byte;' V8 a2 k  ?: F6 X$ g
  978.         byte = Read_Status_Register();        /* read the status register */2 C; m* G; k/ N9 b: O
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ! m$ D7 A8 O! n, |
  980.         {
    ; r* H  B" K. d- v; G  S
  981.                 while(1)
    8 S1 _3 P4 C' A5 ]  `1 I6 c$ p
  982.                         /* add source code or statements for this file */$ I- J8 s7 t7 t/ P' x8 j' V
  983.                         /* to compile                                  */
    8 ?, K1 w$ ?. H0 C! V( S
  984.                         /* i.e. option: insert a display to view error on LED? */+ \1 ~* p0 ]0 o
  985.                  
    8 K2 l  D2 z& X  W  ]! _# j
  986.         }
    $ t- N" @# ?: Q0 |
  987. }
    # N  F% i% n$ y9 j- ]$ F2 f; r
  988. 7 \! h9 ~: z- o/ Q% K* N
  989. /************************************************************************/
    . r8 B( T' p/ p+ Z  _5 X6 c
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */! H4 T8 M% x) V( r% I2 E. \' L
  991. /*                                                                                                                                                */
    8 ]# R7 p$ n  g& u* I$ l( i0 d
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */- |, X( @" b3 d& E* F6 N( o
  993. /*                                                                                                                                                */1 P+ \8 M' U6 ?- Y% g
  994. /* Input:                                                                                                                                */
    : F; X( r& f/ l, \& |# |
  995. /*                None                                                                                                                        */1 N( C8 d% W" y
  996. /*                                                                                                                                                */2 B2 K  y3 h" q, p, X
  997. /* Returns:                                                                                                                                */
    % w" j7 V, u% j; y' D1 W- e+ B
  998. /*                Nothing                                                                                                                        */
    ' _. A" v% S; h1 T0 L4 M% Y! E
  999. /************************************************************************/
    * x/ I3 w( E1 c5 I5 b* \  y
  1000. void WREN_AAI_Check()
    , ]1 `0 R6 M& T; @- t+ C3 u
  1001. {# ~5 O0 u( g5 Z  i
  1002.         unsigned char byte;* r* p+ A* W0 D
  1003.         byte = Read_Status_Register();        /* read the status register */6 Y6 ~! t' s2 r& x* o! [
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    - B" X! l* q/ B1 n4 f" k6 n
  1005.         {& O6 B$ d5 \& E3 K' b
  1006.                 while(1)                9 f' t' w" J2 B
  1007.                         /* add source code or statements for this file */6 y( J( Z3 Z9 {+ V4 T* @# v$ D
  1008.                         /* to compile                                  */4 ~' R4 F: w* n9 z) L! x
  1009.                         /* i.e. option: insert a display to view error on LED? */, L  f! z5 _2 ^- e

  1010. 6 v  ~4 p2 }% D9 }7 I- j! L
  1011.         }
    - u0 Y9 Y6 ~4 y; E8 P+ D% A
  1012. }
    2 J! C" j+ G9 O( \0 x+ _0 T
  1013. : V8 M9 k1 s& i/ z( ^" D! U: f
  1014. /************************************************************************/3 {# K  y; ^& P
  1015. /* PROCEDURE: Verify                                                                                                        */
    5 [3 m# d$ P, z6 |$ I0 H
  1016. /*                                                                                                                                                */
    9 a& _# Q/ C4 r, v
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ; J# z& D$ T: W0 k. V
  1018. /*                                                                                                                                                */
    6 [: n; z+ c4 W, u$ N) {
  1019. /* Input:                                                                                                                                */
    $ e5 {, H, g6 V7 n* X8 j
  1020. /*                byte:                byte read                                                                                        */
    2 M% i6 r9 P7 K) [, ], v4 k
  1021. /*                cor_byte:        correct_byte that should be read                                        */2 [# v$ P% O5 e# l
  1022. /*                                                                                                                                                */
    $ y. ^" x+ g; j9 B/ g
  1023. /* Returns:                                                                                                                                */% _; P6 z% G1 g
  1024. /*                Nothing                                                                                                                        */
    6 A4 M4 P8 z5 n* F7 l. o; a
  1025. /************************************************************************/+ Y7 F/ \9 z& q1 R3 Y4 _+ o: G
  1026. void Verify(unsigned char byte, unsigned char cor_byte)9 a6 S! k8 f' q5 N8 a' C' b
  1027. {
    1 l3 \" A+ h  l* ^- i) P
  1028.         if (byte != cor_byte)" D, ~) i0 {# }
  1029.         {" c# \9 l2 [2 b: l: e) E
  1030.                 while(1)( }% }0 m: h7 R: Q3 J
  1031.                         /* add source code or statement for this file */
    & k: o- y- U' n5 j
  1032.                         /* to compile                                  */2 I. R! U. q8 I% w! ]! O7 X. s
  1033.                         /* i.e. option: insert a display to view error on LED? */$ q- b$ l3 C0 r8 {
  1034.                 ; O% C) }- G; Z
  1035.         }
    & ]7 t$ x' @$ P+ r+ e6 d
  1036. }
    ( [2 `# x% P9 V3 i4 u5 i
  1037. " J8 G3 W" [# [$ `

  1038. 6 W* _8 ]% ^4 E2 q# o
  1039. int main(); ?+ [9 U  U9 ~" ]: E
  1040. {' A5 o4 G: Z$ D1 W

  1041. ! L: D; e2 A2 m5 D. n1 b8 T
  1042. return 0;4 M+ M) e  h7 c5 @% D. ]
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
( d* R3 r* @; T, s   main()  e1 E" r( k' @! n8 O
   里面怎么是空的呢?
) Y/ s2 V% {; {$ Y1 k6 h+ c   发一份给我吧3 i" j4 D# b$ M  w5 K$ ~- Q# l) a
mail:luyijun2005@hotmail.com
: r' p4 v5 `( n' c9 _/ A- t咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
5 f  Z! _, r( h+ ]% p# V
" _0 W7 p2 Y+ D0 G" f[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
, u. D9 n4 C3 H. lEC的代码在哪跑,你看DS的说明,每个EC都不同的。
6 n) s3 L" }" i9 U" G9 H) d2 Q6 z: s. AOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?7 I9 |. W/ A: o# z2 T3 N* H
上面几个问题是你没看任何东西而白问。$ B  G* b0 \9 }& L7 U% ]6 k, k  O9 h
- W/ g* N" Y* |0 F& [
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
* _8 Q1 ?6 l8 ~, c1 X$ m# ~: A, m5 {% D- y1 F, b
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!. p; o5 M. l' K( ~/ \8 }
5 h1 ?5 Z, C/ f- z6 n8 {; P
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
9 B2 N: S! x+ `' c/ K
$ {% V1 V; l" }) A% K! h9 v关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...) d6 X" w+ n/ T

# q0 o6 F/ {* @" z, P; Z不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样' R7 H$ q$ k: ^" f* q! |0 o" }; M+ ^7 S
似乎要把SPI能support 到最大,这EC chip应该有好卖点
+ [  v+ v. T  a' eBIOS功能要不要强大,也就决定了SPI Flach的大小
  P2 |" L" }' i  i& m1 `  c我是这么想的~让OEM去决定要挂多大!
7 U5 B( ?4 w9 n- K; E( K5 y如果我司有BIOS工程师就好了~哈1 t$ E( v9 w( S* {
WPCE775应该算很新的东西,来看它支持到多大?+ x+ i8 u7 A0 }' W& }* Z+ T

7 o$ T/ A" V7 y2 D- ]: I另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte  t$ t& ~! f  Y" X# ]+ e+ p! e2 M
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
$ \) i8 N. o- v, f) g# u! k! a/ S: `# M# n% p2 L
这份driver收下~希望以后有用到& V, g: H. d* m4 W7 s2 |% Q
谢谢bini大大2 K; h8 r4 s3 j! |
9 [) d1 G0 |: u* @- Z
很新很新的新手,如有错误请指正 (准备看第二家的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()
7 p& _7 Z: O; s  s4 K{
3 m5 S; O5 r6 H, e8 i: _# A        unsigned char temp = 0;) B* |  \$ ?! m/ l3 v
        CE_Low();
" ?+ e0 f4 X+ \8 Z2 ]8 B8 Q1 R    while (temp == 0x00)        /* waste time until not busy */# u9 u1 G8 K, x8 }/ _
                temp = SO;$ C7 Z2 j7 Y* f- _5 L4 o" w- ]
        CE_High();4 w! v* s0 S% M) J/ E/ `: ]
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
( C" `; b/ d5 G" u5 e{
; a$ B: q% ^$ p, a8 F) `        
/ P. H4 H4 G4 t" Q: d  y  x        unsigned char i = 0;) {- M* K9 T2 l0 A: t+ F1 y$ x
        for (i = 0; i < 8; i++)
' J4 `+ N1 L# a* c) n        {
, M( M3 }% L: n- ]5 N               
" K  I2 V0 P% s! Y3 B3 n                if ((out & 0x80) == 0x80)        /* check if MSB is high */& V% i1 s6 N4 S8 H+ s
                        SI = 1;' e* X2 p7 o. g/ }& T  u
                else" A- n$ K( k7 y/ E$ e& Y# A7 i3 y
                        SI = 0;                                /* if not, set to low */0 J( x0 j; h4 e" d- h
问              SCK = 1;                                /* toggle clock high */
$ a$ I+ G8 g7 g$ \; y   题            out = (out << 1);                /* shift 1 place for next bit */
/ H2 q6 ^/ Y( j                SCK = 0;                                /* toggle clock low */6 d* G" Q# \1 o8 ?
        }' `! m! E2 E3 `; z. X0 y( p
}6 q9 d- H" W* v$ Q9 A+ o, r: F
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-20 07:38 , Processed in 0.130511 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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