找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 53403|回复: 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
    - Q! c: t) f+ v$ m4 n8 l
  2. 7 I# }  f* F; {& s5 q
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    ' ~3 S# x' [; x6 y( h; W
  4. ! b" `' x; z: }8 A% B& {6 \. ?
  5. November 4th, 2005, Rev. 1.0
    - k- e0 L( C$ E6 G* v( N

  6. ! n$ h4 Y  S4 u* I7 f
  7. ABOUT THE SOFTWARE
    - M0 x, [* w; R. P2 E
  8. This application note provides software driver examples for SST25VF080B,- k/ c# v5 P# |( l+ Z$ v% t2 h5 \
  9. Serial Flash. Extensive comments are included in each routine to describe
    4 `) }1 {0 x/ F. n7 V8 c5 g- x. Q
  10. the function of each routine.  The interface coding uses polling method 3 ~. {/ a: `2 }( z: g! W0 V' A  g. ~
  11. rather than the SPI protocol to interface with these serial devices.  The
      l, t2 W& B& q' r- b3 `
  12. functions are differentiated below in terms of the communication protocols
    - Y8 d1 j* L' V, T; v
  13. (uses Mode 0) and specific device operation instructions. This code has been / @8 s7 n% i0 X% e  A
  14. designed to compile using the Keil compiler.
    / F8 i0 v- B9 ?8 l; a& o

  15. " N# ]9 M9 p8 H. J5 T
  16. & l" J3 x) r5 O
  17. ABOUT THE SST25VF080B. }8 `: t6 @1 z* d

  18. # {9 ~. V' q/ O
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    - T% s  d" Q" |9 Y
  20. conjunction with this application note for a complete understanding * w: N9 N# A! F; c$ k( s
  21. of the device.# a3 r7 a2 v* N2 X) U% t
  22. ( j% \3 p( Y5 Y. @; t5 D$ m
  23. 0 U% z- f5 ]* ?
  24. Device Communication Protocol(pinout related) functions:
    ! v# c' I4 M$ @7 w5 _
  25.   o) j/ t2 l: R2 R+ P
  26. Functions                                    Function
    % Z9 R+ G$ d9 p( @
  27. ------------------------------------------------------------------- _# `$ \5 X# ^7 [, e6 ^1 p7 _
  28. init                                        Initializes clock to set up mode 0.
    ' t, h) r5 ]( N* N/ X
  29. Send_Byte                                Sends one byte using SI pin to send and
    7 f' ]$ s: w/ F; e
  30.                                                 shift out 1-bit per clock rising edge
    , C+ K3 A% E5 V; D
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    8 w8 F+ Z4 Y" U& @" y' n
  32.                                                 in 1-bit per clock falling edge
    . R1 I4 R9 q* F/ u( X* Q
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    / P9 S3 R5 C5 `- p9 N! B
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high/ M2 c0 L, U& b$ L7 f# O
  35. CE_Low                                        Clears Chip Enable of the serial flash to low* k  |- y# G4 P/ M1 N5 P. I. c
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    : k, n3 y  G- J( G9 n4 _4 E" P
  37. Unhold                                        Unholds the serial flash
    6 U5 `5 V: p; ?. @: x
  38. WP_Low                                        Clears WP pin to make serial flash write protected' A9 d' D, Z" l" {6 d1 x
  39. UnWP                                        Disables write protection pin
    + M, b+ b% w% l8 [9 _: F7 _7 o
  40. ! [9 j/ e0 z" F9 c( `  l  Q& P
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code$ d# C  `( c0 r. @) K" U- w
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    * ~$ [5 O8 `9 i
  43. software which should reflect your hardware interfaced.          
    1 y' m! |- }2 S

  44. ' @: N8 O" L' I1 ?' e/ E2 k# H

  45. % G& {' {- p9 h5 K- _' L/ i  F
  46. Device Operation Instruction functions:2 N( V9 z/ S) t& B6 D$ x3 }
  47. . Y, i! B/ a7 I# L( r& W  l' X, W
  48. Functions                                    Function# T6 i9 u2 d8 e* ?) F; U
  49. ------------------------------------------------------------------
    ! N( o1 m' i7 P- k! L
  50. Read_Status_Register        Reads the status register of the serial flash4 r+ q& H+ t9 r8 P: a
  51. EWSR                                        Enables the Write Status Register7 Q5 D0 U! p1 Z! Q
  52. WRSR                                        Performs a write to the status register$ O. P( Q6 g* [, I$ _  E* z9 R
  53. WREN                                        Write enables the serial flash2 T* |  u& p: j, X& ]% w
  54. WRDI                                        Write disables the serial flash9 N* n+ Y. P7 t, k
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    , H/ \( \+ d5 k) R
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming$ q; _' Y7 I* K" E# I9 F5 a
  57. Read_ID                                        Reads the manufacturer ID and device ID. ?3 B" I. {+ v" P! `1 Y
  58. Jedec_ID_Read                        Reads the Jedec ID5 N. W. p/ u! ]8 m8 s0 N6 u0 p' H
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)$ L2 [6 }7 n# Y" n! _* Y
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)/ Z; y4 c1 l; g, K
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)7 U3 i8 ~  r. K' o
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    - j. C5 P7 R: E2 j5 }* A3 Z
  63. Byte_Program                        Program one byte to the serial flash- G5 F: h# D9 ^* ~* Z7 o! W8 M
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    9 t. |8 H$ H3 h# q# Z
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation1 f1 _+ Y* Z' A
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ' p. Z+ p1 b' H! U1 D& E
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY/ k; x, A2 j( [" g" }5 ]1 Z
  68. Chip_Erase                                Erases entire serial flash/ ~, ~2 a$ C. C, `9 \
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash4 W0 w9 f3 s2 M: e& U6 z9 L
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash; o( Z# ]( ~: d5 d
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash5 d4 y7 r% ~* A9 m0 ~
  72. Wait_Busy                                Polls status register until busy bit is low; v5 h! M2 L% E1 c1 V: F
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    ; y- \& j# ~, I% ~- ?8 L# ^
  74. WREN_Check                                Checks to see if WEL is set. v3 w, \% l7 V; g2 J+ ^
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set; H4 P% g. H; f0 L. _
  76. : `2 ]# L0 s, l" i8 U  K9 f- Q

  77. % d9 g: S( W* s0 c0 X6 Q4 [& I

  78. % I, l; _3 i( j: Q$ w1 {! l
  79.                                                                      
    - _( O2 J/ G: O  {8 t# P
  80. "C" LANGUAGE DRIVERS 0 t- v2 m" I( _) z
  81. 5 c9 D, @2 r) N% c  ]
  82. /********************************************************************/: v5 [5 w* `2 J
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    6 O2 {9 ~1 {! }5 g! v) W* C$ y
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */' c$ z+ K2 M, D/ q1 Y8 \" x4 @9 h
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */' q" v. l: f% Z7 b$ Y  ^+ H
  86. /*                                                                  */$ q+ Q* ]4 z. h  p' P6 X3 P& H; H
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    2 z# |( L  k! j! g& E% k
  88. /*                                                                  */
    - {* d0 n$ O, F# C
  89. /*                                                                                                                                        */
    : x: n1 `( d" J- \: s
  90. /********************************************************************/. l1 k) v, m: E- R- Q2 o3 H! k
  91. 8 `" P6 q, Q2 k
  92. #include <stdio.h>% S3 [# w( e2 n  ^) ^1 X4 W" h
  93. #include <stdlib.h>; o- s  u! e6 Z% k

  94. . B5 x* d- J; I! Z
  95. /* Function Prototypes */
    : s& `2 A/ B6 l

  96. % C* H$ ?; v- K
  97. void init();
    2 _8 A' h: b# I, @$ [4 p4 y, [1 C
  98. void Send_Byte(unsigned char out);
    $ p- m  L; L* B7 l- e
  99. unsigned char Get_Byte();2 t% ]" h% u* z3 A* u# \
  100. void Poll_SO();' [# L! s% P: Z) `
  101. void CE_High();
    7 Y2 f( p3 `. a) A0 {
  102. void CE_Low();6 ^  n2 t5 R; k& l: q
  103. void Hold_Low();
    8 u* d$ y, D  ~' _* X! O( H6 Z
  104. void Unhold();
    6 B: U, q# q8 [" h7 y
  105. void WP_Low();
    0 }# Z& _6 ?' @
  106. void UnWP();; M: E( B3 u$ m' u; l) k
  107. unsigned char Read_Status_Register();! k, ]; w/ ^: d; f* k) W. h
  108. void EWSR();+ ?9 ^$ k1 w1 M$ H# G8 Q+ O1 \! z
  109. void WRSR(byte);7 d) a- T7 r/ c# n4 }
  110. void WREN();. w5 U2 V: G# k: A0 U
  111. void WRDI();
      y% S- @, Y, ], ~% L2 W
  112. void EBSY();
    7 c: ~3 ~" t% h# B. l
  113. void DBSY();
    " K! `& o9 q6 B
  114. unsigned char Read_ID(ID_addr);  Y3 }& o( p: a
  115. unsigned long Jedec_ID_Read();
    # P( K9 E) o. I( h
  116. unsigned char Read(unsigned long Dst);5 y5 `3 G3 [: l' b
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ( v. w" b# @" f; K7 N: k
  118. unsigned char HighSpeed_Read(unsigned long Dst); ' f( n/ Q- z1 {$ U$ I0 H) K, ~
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);8 C8 R3 f% M& D6 M' k* n6 X  g
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    1 R/ }$ C4 H8 W: b9 P
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);5 {# U3 {9 U" K# U+ Z
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
      w% k- G9 V9 L* E8 I
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);+ |7 g& j/ b+ t/ R5 x! L  `
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    4 {- G9 K% d' T5 H
  125. void Chip_Erase();' D% N9 _- K) K# }; {7 v
  126. void Sector_Erase(unsigned long Dst);
    8 [& N  D- `3 _$ a$ S& m% ~
  127. void Block_Erase_32K(unsigned long Dst);
    8 f1 a' Y: L* S/ }" \4 T! X8 K
  128. void Block_Erase_64K(unsigned long Dst);
    : v5 k3 w" y3 K
  129. void Wait_Busy();1 T* n2 s3 ^! |. h
  130. void Wait_Busy_AAI();
    7 a  U5 ^! E3 g. B; p9 o2 f
  131. void WREN_Check();
    1 M3 b" c) k3 [6 g4 J; n
  132. void WREN_AAI_Check();
    - V+ E" c9 N/ Z2 e) Y6 X
  133. + y8 K* a7 H( k" P  b4 m
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    0 E8 f2 `6 u/ L, p" F9 R, W
  135. ! f- p+ Z9 C7 P' a' ^" ~& ^
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    # u7 n2 ]. A! `( v' r$ j  N! H/ S
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    - E& {* K1 F2 B. k
  138. & Y3 n" y5 E; f6 z7 h7 A
  139. /************************************************************************/7 d" G3 W+ H2 E$ y
  140. /* PROCEDURE: init                                                                                                                */7 v; [* Y3 x- ~
  141. /*                                                                                                                                                */& O7 w3 I6 z- B9 U, }* B, G
  142. /* This procedure initializes the SCK to low. Must be called prior to         */6 Q# h# S4 ]+ R
  143. /* setting up mode 0.                                                                                                        */
    2 h- C- T: k6 X
  144. /*                                                                                                                                                */
    ) l! E, i5 j  Z+ H( e0 l1 p& I
  145. /* Input:                                                                                                                                */
    * @! u$ h- C! B( l" f6 q4 A
  146. /*                None                                                                                                                        */
    1 r4 n' k3 I4 b
  147. /*                                                                                                                                                */! \& r, T1 a' G5 X6 j
  148. /* Output:                                                                                                                                */
    - a4 M- ?* M( c/ K' L
  149. /*                SCK                                                                                                                                *// [/ J8 B# u5 n- T& H' w
  150. /************************************************************************/
    : R5 h  Y: \( B9 e  A9 c' L4 o& G
  151. void init()
    1 s' S3 x" J9 }9 e+ ~8 h
  152. {
    0 A& O. E, ^2 H6 Y
  153.         SCK = 0;        /* set clock to low initial state */
    . i" W7 ^8 n6 Y7 a/ T
  154. }' z3 w) C5 F/ ?7 u- m! f; p7 ?

  155. " [4 C' a2 E- b8 T4 T- p
  156. /************************************************************************/
    + @( {5 m6 ], q/ c' w, h) q
  157. /* PROCEDURE: Send_Byte                                                                                                        */) j& }1 p" g/ V7 W" r4 j
  158. /*                                                                                                                                                */
    ' L! g# X; Q) K
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    - P# e$ S5 W1 `% i
  160. /* edge on the the SI pin(LSB 1st).                                                                                */8 k0 Z$ s5 F2 ^6 {) F
  161. /*                                                                                                                                                */
    8 t# s& T9 H( [) {7 K; K" c
  162. /* Input:                                                                                                                                */4 F0 F7 p2 T  \( M" W! l
  163. /*                out                                                                                                                                */
    " ]; z8 R; o3 q2 F! ~
  164. /*                                                                                                                                                */  r; |- _, ^% Z4 u) ~% _2 _% u
  165. /* Output:                                                                                                                                */: K  I+ U7 G. g8 X0 R6 n
  166. /*                SI                                                                                                                                */, T- d  i; K9 Y; x/ y
  167. /************************************************************************/5 _' a' V& x, c
  168. void Send_Byte(unsigned char out)) S4 G  ?1 R: c* |
  169. {
    6 A0 l1 e$ s! P% `- r  d
  170.        
    2 f+ ^5 Y: Y" V6 g0 W
  171.         unsigned char i = 0;( f) E# N8 [. [  @
  172.         for (i = 0; i < 8; i++); P. ]: Q, \- [/ E
  173.         {4 k- r# _7 A' E( ~1 u2 h- _
  174.                 2 S+ I% n- |3 R# D  I3 T, D$ v
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */9 l7 P0 Q$ U2 Z) S: F4 i! F+ z/ h4 `
  176.                         SI = 1;) l) Y0 d! i; H2 Y5 o
  177.                 else; P' N: U& i7 C
  178.                         SI = 0;                                /* if not, set to low */. S  R# \" ~6 s( v
  179.                 SCK = 1;                                /* toggle clock high */+ d# K) q. c0 D7 Y
  180.                 out = (out << 1);                /* shift 1 place for next bit */6 d. j7 a+ ?4 w" P
  181.                 SCK = 0;                                /* toggle clock low */
    # O1 b+ O* a/ m1 G8 I& O" A
  182.         }
    5 n5 e, l' |. Y2 ~
  183. }
    . V. X% e: a# l5 W& `& T

  184. ' ?( A( D8 v7 B. w( Z. z
  185. /************************************************************************/
    . D1 d9 D# f* R3 _2 x
  186. /* PROCEDURE: Get_Byte                                                                                                        */, b% G6 x" r) G7 W! _. y. Y7 \
  187. /*                                                                                                                                                */# V0 b! {  X/ L* [: O7 }+ R  ^
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */. L# l$ V- ~+ H$ l" {: i- C% o4 D
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ! G1 x3 r  X6 X6 K
  190. /*                                                                                                                                                */1 \* ]/ L+ @4 m/ C, V2 Q9 \8 ?  @* P
  191. /* Input:                                                                                                                                */1 U  [6 B5 B7 {3 R8 m" |# y0 w# i1 M
  192. /*                SO                                                                                                                                */
    6 Y) }! L" X1 |! `$ @$ r/ Z$ ]
  193. /*                                                                                                                                                */+ b, n" t' q, X) T8 {
  194. /* Output:                                                                                                                                */
    4 [6 M+ J4 \% ]+ o  Y
  195. /*                None                                                                                                                        */
    ; b+ K) W3 u" ]. {% n: T! }9 l9 b
  196. /************************************************************************/0 B( X, U8 s2 k7 w
  197. unsigned char Get_Byte()& l7 \  ]. T% w& X3 l
  198. {! P5 l; `3 `8 j6 K
  199.         unsigned char i = 0, in = 0, temp = 0;) M: Q# S' U0 q1 Z3 _' ]0 |$ [
  200.         for (i = 0; i < 8; i++)
    . ~  O: Z8 g) @6 h9 }) p
  201.         {$ ~. t' Y, \9 I8 P5 P+ d
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    $ K/ i- S/ d. x& E# K7 z. U
  203.                 temp = SO;                        /* save input */
    9 @2 j- I" m5 A+ {0 d) n
  204.                 SCK = 1;                        /* toggle clock high */9 h2 }9 @/ ]' S
  205.                 if (temp == 1)                        /* check to see if bit is high */
    $ M6 M5 K, |8 q4 U& W2 s& p
  206.                         in = in | 0x01;                /* if high, make bit high */9 D' }7 W: c" O

  207. 9 g3 Q& h% ]7 Z: r5 \# T4 |
  208.                 SCK = 0;                        /* toggle clock low */
    ! P2 D% j: C* S1 M1 C
  209. ) Z& b; j2 Q/ x! \
  210.         }
    9 \0 t8 m0 a0 @/ ]9 O9 c
  211.         return in;
    $ }" n/ C5 |) x" f# x
  212. }$ w! A# q, G: h, ^, T$ K
  213. ; Y8 U# ?+ a) r$ U  s9 p5 M
  214. /************************************************************************/+ S& g+ a! H5 W
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    8 W6 @8 l( o4 [* A# D# \. F6 m
  216. /*                                                                                                                                                */4 F4 S' Z4 e+ X5 X
  217. /* This procedure polls for the SO line during AAI programming                  */
    4 {9 f  r) }- t/ S
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/  P( }. @4 ~. B& {' ^7 ^
  219. /* is completed                                                                                                                        */
    ( \9 q3 x" t8 }/ z" j
  220. /*                                                                                                                                                */6 Z2 c3 m8 q5 k' C
  221. /* Input:                                                                                                                                */$ ?6 E6 e# a3 X0 i
  222. /*                SO                                                                                                                                */8 A) {6 ?' w3 {4 T( U; h& A# N2 f
  223. /*                                                                                                                                                */& m5 ~2 E* F4 }9 J2 s$ M' y% s
  224. /* Output:                                                                                                                                */
    ( i7 O5 D( B& K- N9 X4 B
  225. /*                None                                                                                                                        */
    : o/ r  c; o" R# X* J
  226. /************************************************************************/
    # D7 n& c% o6 b5 A
  227. void Poll_SO()
    9 K6 M& c' N4 O
  228. {! a+ Z: e- B/ q: y' N
  229.         unsigned char temp = 0;0 G! _" o  w% k  H: d- E8 R8 ^& g
  230.         CE_Low();
    2 ^6 I0 _. L; D/ h4 u1 h
  231.     while (temp == 0x00)        /* waste time until not busy */
    5 M/ o& E! D1 x0 G/ c
  232.                 temp = SO;
    4 u  L( ^2 C% e' e) V
  233.         CE_High();) x" p; e/ c: g
  234. }3 C7 z6 J# m7 D  k0 n

  235. 0 Y% Z6 Y# p  J, Y2 p  r4 m
  236. /************************************************************************/
    ' c# c+ h' R% _3 Y
  237. /* PROCEDURE: CE_High                                                                                                        */
    9 Z1 i* Z# L5 l( K
  238. /*                                                                                                                                                */; i! i+ ^. v/ U- ~
  239. /* This procedure set CE = High.                                                                                */; @- t9 `7 h; Q! `/ F; E7 f7 a
  240. /*                                                                                                                                                */0 ~! Z3 I) q2 R6 t
  241. /* Input:                                                                                                                                */8 r; W( R+ Y5 _4 r3 Q! H, P9 W
  242. /*                None                                                                                                                        */
    ! g; S0 Y7 ~5 x& B* N9 Q6 n
  243. /*                                                                                                                                                */8 A' A7 W5 E5 C) Z
  244. /* Output:                                                                                                                                */4 z! X+ I/ z0 m/ G( ]
  245. /*                CE                                                                                                                                */8 Q5 X2 ?3 Y) G
  246. /*                                                                                                                                                */$ W5 o( F3 Q7 N- p9 |4 j
  247. /************************************************************************/5 V( G" f  O( {0 r  _
  248. void CE_High() / o" c. o" Y/ b& t
  249. {1 ?) u/ ~- t) A' y
  250.         CE = 1;                                /* set CE high */+ \2 @( v5 m$ W6 r/ [
  251. }! }' L. o/ f8 Q& C
  252. 6 Y& d' [0 _" R; I
  253. /************************************************************************/# a* v  i& W3 V2 K' S( L  P9 c
  254. /* PROCEDURE: CE_Low                                                                                                        */( p3 [3 A  |. X. `6 j  w, t2 l9 D9 Q& x8 g
  255. /*                                                                                                                                                */
    ! L0 M! `. X# w
  256. /* This procedure drives the CE of the device to low.                                          */
    5 O5 C$ w3 W+ s8 g9 f
  257. /*                                                                                                                                                */  c0 \% z9 v) z( s' ^
  258. /* Input:                                                                                                                                */1 r8 z1 S8 I% [/ M4 S3 q& M
  259. /*                None                                                                                                                        *// w) j4 m2 S# V: n$ M8 l2 C: ]
  260. /*                                                                                                                                                */
    # k& U1 L7 y  S% b. p
  261. /* Output:                                                                                                                                */9 }7 R6 F5 Y+ ~
  262. /*                CE                                                                                                                                */1 j/ D8 \7 o* d0 R
  263. /*                                                                                                                                                *// A$ w, V- e' V2 s  Y# @
  264. /************************************************************************/
    ) D; @8 r3 w/ r* J
  265. void CE_Low()
    ' ]! @. \9 K4 T% \- l3 {
  266. {        7 p& R4 Y$ \* `: @0 ]: x
  267.         CE = 0;                                /* clear CE low */# M7 w! p$ n* I- e: c( E# Q4 l2 k
  268. }: R: E8 c  f, ?' T% C, e8 c3 |
  269. & r: n6 o# o* ~' A& p2 ?
  270. /************************************************************************/* S! k0 p  u: k! K' ~4 F5 G
  271. /* PROCEDURE: Hold()                                                                                                        */8 ~) z8 x- ]. n
  272. /*                                                                                                                                                */
    ' p2 p/ Q6 c# c. S: N* \7 P
  273. /* This procedure clears the Hold pin to low.                                                        */
    # T# C( C0 t8 D. V* n) f& F% D
  274. /*                                                                                                                                                */% v7 C' k  _) a
  275. /* Input:                                                                                                                                */
    4 S9 S/ z7 M- V" n: W* p
  276. /*                None                                                                                                                        */1 Q- }6 z# U( z' S* ]. p
  277. /*                                                                                                                                                */
    # q  @, H- c6 ]. F. B
  278. /* Output:                                                                                                                                */; k) L0 x0 L% x
  279. /*                Hold                                                                                                                        */' o- t* f/ i; c/ p7 X4 P
  280. /************************************************************************/
    $ y2 a* d( M% w5 g" t$ t
  281. void Hold_Low()
    ( ]( u/ u# G5 ]% X1 ^4 D
  282. {
      \$ v1 |8 E) n! o
  283.         Hold = 0;                        /* clear Hold pin */
    ' x6 m4 g' R) }" X
  284. }7 ^* n, K$ Z2 z- n5 e; T1 b

  285. $ h# A: a$ e! i8 b
  286. /************************************************************************/
    $ N% c: H  a9 p- A, X1 L( p1 C
  287. /* PROCEDURE: Unhold()                                                                                                        */
    3 d) |* R. O, K  J- X- n
  288. /*                                                                                                                                                */
    2 c& l- L9 p9 E. Q; N
  289. /* This procedure sets the Hold pin to high.                                                        */
    2 |3 [+ S" W! y% w& t8 d5 W3 s
  290. /*                                                                                                                                                */
    , z, m* y$ y  [# M" O7 B5 u
  291. /* Input:                                                                                                                                */
    5 h" W% a' X/ b* N3 g" ^+ }2 o
  292. /*                None                                                                                                                        */
    ( O' g* F! ^4 w4 t
  293. /*                                                                                                                                                */
    ; u( o; k' q; i# p% k) R
  294. /* Output:                                                                                                                                */
    8 a9 E' d: g: }3 X! l4 m) M
  295. /*                Hold                                                                                                                        */
    " S9 x2 b& \/ M0 e- B
  296. /************************************************************************/8 _( P, v* [6 F) {
  297. void Unhold()
    , P3 l3 H, g- g6 r$ _, O
  298. {! m* p  d9 ?) S% m8 v
  299.         Hold = 1;                        /* set Hold pin */
    + Y, @8 Z# X! r1 v% ]8 h
  300. }0 Q3 ~6 l* o, s* ]; n% _1 Q/ \
  301. : t# {/ Z. Z7 ]  b4 U6 C
  302. /************************************************************************/9 O7 o3 p: I! @4 V, K. S
  303. /* PROCEDURE: WP()                                                                                                                */+ l$ X! @$ f0 @" i. u9 L/ T  N
  304. /*                                                                                                                                                */
    5 k7 n4 x9 c. ?, |  Q/ W8 P/ i
  305. /* This procedure clears the WP pin to low.                                                                */6 c# }: T7 n' I+ @# j, i
  306. /*                                                                                                                                                */" ~8 ], H4 O" G2 K
  307. /* Input:                                                                                                                                */3 g5 [; g% O  i" n) ?+ D
  308. /*                None                                                                                                                        */# L5 f4 j1 Z& q' w
  309. /*                                                                                                                                                */! O2 C% I/ `$ _+ f0 T2 b3 ]
  310. /* Output:                                                                                                                                */
    # ^6 ~% B' v# J; E5 l9 ]; ^
  311. /*                WP                                                                                                                                */
    ( w' X$ ~( L; n1 f8 @8 M+ S4 [! N
  312. /************************************************************************/& m1 c9 L8 o1 H" v  g
  313. void WP_Low()' M, ~5 Z8 f/ a& f* `$ N4 ~2 d% @2 p
  314. {6 u+ u# x7 F1 h; m3 X
  315.         WP = 0;                                /* clear WP pin */8 u1 s4 y# N# t. U9 f
  316. }7 D# H! i( G7 G- C

  317. ! l. Q! T2 z+ T% i/ ?2 {
  318. /************************************************************************/
    6 `6 D: b0 R( N. V* G' l# H
  319. /* PROCEDURE: UnWP()                                                                                                        */
    6 e" Q- i7 G6 s- N: T$ O  z+ j3 `
  320. /*                                                                                                                                                */
    ) x/ u; @; [; s1 q6 C$ j" D$ Y( k
  321. /* This procedure sets the WP pin to high.                                                                */. u1 D( e; [+ L0 {5 Q& ^! S
  322. /*                                                                                                                                                */
    6 Y) P" o# c- G- [, f4 e$ u% `
  323. /* Input:                                                                                                                                */- l: z7 r3 x* a/ s" ^$ L$ U# ]
  324. /*                None                                                                                                                        */! [9 I1 D9 }  o+ x( v3 m& K
  325. /*                                                                                                                                                */
    ) y" N* `* l% k
  326. /* Output:                                                                                                                                */( E. G! z/ N$ d: Z, u( u5 Q- d
  327. /*                WP                                                                                                                                */
    3 Z" g- s6 n3 o
  328. /************************************************************************/% H, Z* s, N5 `
  329. void UnWP()6 K' I) z6 A7 Q, o
  330. {
    % Z: s: O6 X. I7 @
  331.         WP = 1;                                /* set WP pin */
    & r6 a+ Z- S5 S$ i( r: T
  332. }. r% P) L3 L) e1 U8 _( n. d0 |

  333. : a9 Y. w6 \4 ?  p
  334. /************************************************************************/1 j# {, `1 h& f) M4 @5 V8 a
  335. /* PROCEDURE: Read_Status_Register                                                                                */4 h2 g7 t" h0 B# I) E4 P
  336. /*                                                                                                                                                */  h. w0 q8 l' y) }7 R+ ?! O4 }( W2 l
  337. /* This procedure read the status register and returns the byte.                */
    , |( [* ~5 `6 j( G9 Z
  338. /*                                                                                                                                                */
    # ]6 u1 F/ L' J% s
  339. /* Input:                                                                                                                                */
    ! h1 K: Z* C" A* E) b2 {
  340. /*                None                                                                                                                        */
    - `# [7 a8 }3 _* P  x
  341. /*                                                                                                                                                */! _. D6 n! L7 y
  342. /* Returns:                                                                                                                                */# y! w& p3 ^8 m( V# y& ~
  343. /*                byte                                                                                                                        */% t% @( j: D- @
  344. /************************************************************************/- k7 N6 D- V& V
  345. unsigned char Read_Status_Register()
    ( p2 y6 D8 X0 S  }6 K
  346. {- Z8 n9 y( r. T' c+ Z' Z& z" x' r. l
  347.         unsigned char byte = 0;
    8 M& ~5 K, _7 F* x, w* Y8 N6 Y
  348.         CE_Low();                                /* enable device */
    ' w% V  u( e9 z% x  N0 {$ U) R
  349.         Send_Byte(0x05);                /* send RDSR command */* x( A! d  y, _9 i$ B
  350.         byte = Get_Byte();                /* receive byte */
    # p8 x7 P- A4 p
  351.         CE_High();                                /* disable device */
    ( X9 _9 ?; b1 n$ E3 j! u* N3 y
  352.         return byte;
    4 H; G4 i* m( @9 g" r2 P
  353. }: a/ T3 `/ Z# g0 W

  354. * p1 }5 S! D. k. u1 v& `  W. [* h
  355. /************************************************************************/
      d3 c/ h( u2 h
  356. /* PROCEDURE: EWSR                                                                                                                */: Q$ Z  {% ?! E) X+ `. C* m
  357. /*                                                                                                                                                */
    6 @$ R5 ]% b% h- E7 Q. Z
  358. /* This procedure Enables Write Status Register.                                                  */
    ! g2 ], D7 N4 h) y9 O. O1 Z2 l8 n
  359. /*                                                                                                                                                */
    5 ~; g  W0 b. z  _$ m8 V. V
  360. /* Input:                                                                                                                                */& L9 J3 V- P# i
  361. /*                None                                                                                                                        */, g' B' y, O* K8 @  [  u. D/ L
  362. /*                                                                                                                                                */
    ) ~6 M+ s$ v$ M; d* |4 P- R
  363. /* Returns:                                                                                                                                */
    2 I# N2 c+ b: o
  364. /*                Nothing                                                                                                                        */  l  }+ x, }4 E. U+ n2 D# D  P
  365. /************************************************************************/
    ! U" z7 q: o1 X* H1 M: }
  366. void EWSR()
    : P+ m+ x2 [/ r
  367. {8 v) L2 ?, x% L% ~1 j4 K
  368.         CE_Low();                                /* enable device */. s+ D7 M5 o% s* S9 I$ f
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    ( _) A8 m; x  x
  370.         CE_High();                                /* disable device */
    5 G: T9 w9 K( N) l  d8 N+ X' i
  371. }) J4 v5 n2 {' F
  372. ( d1 H: c& V: F4 R, M; e
  373. /************************************************************************/
    % k, P2 i" H$ @( E* p
  374. /* PROCEDURE: WRSR                                                                                                                */1 C8 N1 d3 K; s5 s! v0 K( c8 D( g0 t* H
  375. /*                                                                                                                                                */
    0 d. |0 j8 c" z5 i8 o7 n
  376. /* This procedure writes a byte to the Status Register.                                        */
    6 @$ ^- H# E$ }# d
  377. /*                                                                                                                                                */
    : W( U) U" p. k
  378. /* Input:                                                                                                                                *// T6 L- s  M+ c+ t8 o7 B
  379. /*                byte                                                                                                                        */; g7 u- [( L" n; p3 D
  380. /*                                                                                                                                                */3 |( ?8 K# \8 k* k& w
  381. /* Returns:                                                                                                                                */# r; e& p0 {" t' y3 }
  382. /*                Nothing                                                                                                                        */# K+ W' s: a( I; ~
  383. /************************************************************************/
    : \' a( x, ~% G0 |; q
  384. void WRSR(byte)
    + y" p* ^2 g% u  l" [2 u
  385. {( C# J, g* ]$ ]8 ]4 h! x: t
  386.         CE_Low();                                /* enable device */9 U5 S7 M8 L+ K! m% E  S
  387.         Send_Byte(0x01);                /* select write to status register *// `/ f% ]' C: X/ `0 [3 d6 i
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ' H! d  {% B% l) ?+ k1 |
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    + s, I) A; z, |2 A5 r; }+ o
  390.         CE_High();                                /* disable the device */
    ! H# g& L7 k. x. w. {, I) u2 R
  391. }
    1 {1 N! u5 W( K( K1 k6 [; n
  392. + l  `( I. r, w/ Y7 ]+ F4 `: L
  393. /************************************************************************/
    0 J; b. _& _/ o# n% w
  394. /* PROCEDURE: WREN                                                                                                                */$ Z$ N/ X2 B! V! |5 T- w
  395. /*                                                                                                                                                */$ P( Q: M: _6 U0 ^% z* k
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    1 I8 a! N4 Y. @" n% G" h1 H
  397. /* to Enables Write Status Register.                                                                        */
    * B0 a/ N. w- J5 ?: T+ E5 c  m
  398. /*                                                                                                                                                */6 d( q( E* s% T$ a* \( V
  399. /* Input:                                                                                                                                */
    & `7 g$ \" Z2 f& Z
  400. /*                None                                                                                                                        */
    # }% B' d2 C. I& T
  401. /*                                                                                                                                                */
    & u+ o3 S. ~- E2 `5 Z% i/ A
  402. /* Returns:                                                                                                                                */
    0 a: ~2 |" s3 u0 {- r
  403. /*                Nothing                                                                                                                        */, x) O! L3 H) h
  404. /************************************************************************/
    5 K: B1 F7 q) F, ~# O
  405. void WREN()' Q9 y& F- V' V& l0 G5 p
  406. {
    ; Z1 X. }. @, e$ E
  407.         CE_Low();                                /* enable device */
    : [1 X9 e4 z( q: s6 q2 o( e9 A, _6 s
  408.         Send_Byte(0x06);                /* send WREN command */
    & _( `, _, a8 {( [* X8 m7 f! H
  409.         CE_High();                                /* disable device */" a0 V4 G; G  _* l3 d& O( m
  410. }
    " A4 a% V! g8 W% E$ I, K

  411. , v4 z" x  A' k) \0 r3 `: }7 A/ F
  412. /************************************************************************/8 c" }$ C2 b: n( N. l/ Z# k
  413. /* PROCEDURE: WRDI                                                                                                                */  ^  D4 d' {( P
  414. /*                                                                                                                                                */
    " `( _2 u6 J5 i$ x6 G+ k5 w
  415. /* This procedure disables the Write Enable Latch.                                                */2 x5 L( X$ ?6 C  f) j
  416. /*                                                                                                                                                */2 p" O4 ~3 ?* j. G4 R
  417. /* Input:                                                                                                                                */
    2 g! m9 x0 Y5 ~, `% z9 P% [
  418. /*                None                                                                                                                        */: D3 C0 ]# u% A2 F0 S, M: z7 x
  419. /*                                                                                                                                                */
    - u6 t/ F: v4 u  s; W
  420. /* Returns:                                                                                                                                */& s" x8 U4 t: _8 I9 R- k
  421. /*                Nothing                                                                                                                        */- F6 ^9 J" n) n# K
  422. /************************************************************************/0 _$ ]8 I" d- e: a: [; ?/ \
  423. void WRDI()' h1 M. K9 W, `+ z% s& b+ V% P7 d
  424. {$ s. L2 \2 e* r6 E" x9 r( e
  425.         CE_Low();                                /* enable device */
    0 I" b3 Y) l- S; J& _
  426.         Send_Byte(0x04);                /* send WRDI command */
    1 L( U1 r, j: L' }
  427.         CE_High();                                /* disable device */
    5 [) p2 p$ R7 {* N+ M! j
  428. }
    & R9 E+ l0 ~6 R* p' |% i$ N
  429. , [( {- N$ w) D# T) p% r/ A
  430. /************************************************************************/
    3 p4 i, ^3 q- Z
  431. /* PROCEDURE: EBSY                                                                                                                */4 P1 L7 c$ m! e9 h8 v6 K
  432. /*                                                                                                                                                */
    * Q2 U* M& U2 ]- N6 B, B
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */, A* u6 p7 T% D1 R2 z6 A
  434. /* programming.                                                                                                                        */2 a( p( i5 B& u3 n) v, c% G
  435. /*                                                                                                                                                */
    3 m) s  q' T  }6 C
  436. /* Input:                                                                                                                                */, m0 z3 O0 `0 c5 m/ S  h0 \
  437. /*                None                                                                                                                        */0 A2 |5 e; B5 F; i$ t5 _
  438. /*                                                                                                                                                */" [) |) J  T' ~
  439. /* Returns:                                                                                                                                */& ?# T& J$ O% ~+ d6 A! @
  440. /*                Nothing                                                                                                                        */
    5 o. v0 \0 e  h0 U9 K
  441. /************************************************************************/
    3 H2 f* I; |9 ~; s' I9 X
  442. void EBSY()
    5 e/ T$ L' [. R1 h7 U, H; x' }
  443. {2 p' X: ], G& `) e* m0 _* C% g
  444.         CE_Low();                                /* enable device */
    9 d, L6 ~, z, r) Y+ s6 [
  445.         Send_Byte(0x70);                /* send EBSY command */
    1 }5 h" d* n) ]
  446.         CE_High();                                /* disable device */! x' L( o8 |- c) x! l1 y
  447. }
    : u4 Y7 X. q; Q" Q7 ]0 d

  448. 2 K* u: l( c. W+ n5 W
  449. /************************************************************************/7 {. ]5 u4 e# c: }4 ?: \/ p
  450. /* PROCEDURE: DBSY                                                                                                                */9 F6 _) |+ w7 s7 E
  451. /*                                                                                                                                                *// y# B9 E( j/ O# I: A# `) x* H* d1 d
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    * N! E$ Q) ]8 |  f) K/ R
  453. /* programming.                                                                                                                        */' `0 N. Y+ P. x
  454. /*                                                                                                                                                */
    4 R$ y7 `# Q8 R! K: |+ q
  455. /* Input:                                                                                                                                *// e( a. ?3 k: `/ i6 Y
  456. /*                None                                                                                                                        */
    " ]/ D' X9 n% o, j3 c' T8 f
  457. /*                                                                                                                                                */
    - p- o6 L4 V. U1 r
  458. /* Returns:                                                                                                                                */
    % o9 C. G, [& {1 D  k
  459. /*                Nothing                                                                                                                        */2 o! }2 _6 u: u0 s6 m$ `
  460. /************************************************************************/
    # N; p. y3 |% h! N) A; i
  461. void DBSY(). i% G% e" H# I5 L# w/ e  [
  462. {
    9 l* B: W8 ~" d/ ~8 }- {
  463.         CE_Low();                                /* enable device */
    ) ]1 f9 \9 `2 F6 C1 v9 t% I
  464.         Send_Byte(0x80);                /* send DBSY command */
    3 c$ a# s" E7 u! |( u; N8 e! n3 K
  465.         CE_High();                                /* disable device */* x3 E. h( @- L5 D2 M4 G! s* G
  466. }- \" P/ a6 ~: x& U/ t; H+ v
  467. ! A* j. K4 M; f# U$ h- C% K
  468. /************************************************************************/
      ^( t& T" M( Q4 z. O
  469. /* PROCEDURE: Read_ID                                                                                                        */0 R, w4 Z2 \" [! ~8 W' X
  470. /*                                                                                                                                                */7 @$ H1 @$ |0 h* I6 ^3 I
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    / B) o9 f8 B! N1 ~3 s
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */! C- h9 e, T+ o; ~
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    / q+ y/ V% p: D7 L) j5 Q
  474. /* whether the device outputs manufacturer's ID first, or device ID         */1 T1 B" \4 s: X; z6 ~. \0 J
  475. /* first.  Please see the product datasheet for details.  Returns ID in */( Z# b) q+ M. h  t
  476. /* variable byte.                                                                                                                */
    8 T/ z9 Q) s" a
  477. /*                                                                                                                                                */) X8 `8 `& x' S5 h
  478. /* Input:                                                                                                                                */
    * e; v" ~) j9 q
  479. /*                ID_addr                                                                                                                        */* W4 H& |' Q* }: S
  480. /*                                                                                                                                                */7 r8 o/ F6 B+ T: ]
  481. /* Returns:                                                                                                                                */
    ' O- b# g% g4 u* T) c
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    8 X6 p/ s1 H4 g2 N
  483. /*                                                                                                                                                */
    5 a2 R2 [; s7 m
  484. /************************************************************************/
    " G6 u  `$ D) z3 N+ R) L5 h
  485. unsigned char Read_ID(ID_addr)
    # Y1 a9 ?- R! d- t4 ~, h! u
  486. {$ \9 _3 {  D0 v" |: x
  487.         unsigned char byte;8 q- Y  r2 s  I$ B6 T) S  t: o0 ^4 A
  488.         CE_Low();                                /* enable device */" w4 z; Y3 p- Y& q
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    2 B) ]4 }9 r: B. M/ J# S
  490.     Send_Byte(0x00);                /* send address */* L3 }) j# S: Y' s# v* R# C
  491.         Send_Byte(0x00);                /* send address */
    4 u0 O4 w  t: C2 f
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    # ]4 h7 D; H6 E6 I' C' X
  493.         byte = Get_Byte();                /* receive byte */7 Z+ e, P% V; K2 s
  494.         CE_High();                                /* disable device */) T3 i1 D1 `- E* |% K
  495.         return byte;: I' [5 k1 f$ q' u* q
  496. }+ {. [; m' J* ~' W+ _

  497. - e, u6 Y4 _# f1 f' A; l
  498. /************************************************************************/
    & d, V: b8 S0 O
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */. ]6 B; A0 X0 o# Y; c6 N6 ~
  500. /*                                                                                                                                                */
    $ _# W* p" ?/ ?; r4 T- D2 t
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */6 k0 O3 V% q9 A/ y; U# j
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    6 H% l' v3 F' `
  503. /* Please see the product datasheet for details.                                                  */7 |2 h, V3 k, F: f# U! X
  504. /*                                                                                                                                                */
    ' z! x* u* T4 z% F
  505. /* Input:                                                                                                                                */
    - X$ X# d6 g5 W* J" e
  506. /*                None                                                                                                                        */2 P) |/ u, Z( S# v5 c% [5 X
  507. /*                                                                                                                                                *// N3 z& A, x$ P+ p* e, T
  508. /* Returns:                                                                                                                                */$ P9 z6 _# f8 J4 {! A8 O9 o
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */+ L' G# F* ?. q* |
  510. /*                 and Device ID (8Eh)                                                                                        */( p( W. \' h2 H% {* i
  511. /*                                                                                                                                                */
    ) o3 |0 D- |! m# A! ]$ o0 \
  512. /************************************************************************/% X3 F8 @( g  `( z9 q; O% G
  513. unsigned long Jedec_ID_Read() # t# t0 x2 U; q7 {6 Q
  514. {& k9 Q, l6 E! Y+ p2 a5 c4 b
  515.         unsigned long temp;- ?& z& K/ {( V/ \& @
  516.        
    : ~, v/ F3 U* d+ g& i/ V$ w
  517.         temp = 0;' ]! A' g- t4 m) F. W- b

  518. , Q: `3 T' |8 d/ J! A7 m5 |
  519.         CE_Low();                                        /* enable device */
    * Z) ?( p; @  s, t
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    " |' v7 ]. i! h
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    , W& G# R8 Z3 w/ D& V
  522.         temp = (temp | Get_Byte()) << 8;        : n. J2 @8 G  W9 `- l- Y/ ?
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    4 `; \' b* ], D7 V' g1 R
  524.         CE_High();                                                        /* disable device */
    , K% ?& M& }7 E+ U
  525. * T" D2 I- t& y
  526.         return temp;* n- ?- g4 [, W6 |  K
  527. }
    8 _: B; {8 t- R  K( ?- p1 l

  528. ! P( ~, t& K, d) w
  529. /************************************************************************/
    ; ^9 s3 A, h6 I
  530. /* PROCEDURE:        Read                                                                                                        */9 ?/ ~  _6 v3 |& T, _5 K- O
  531. /*                                                                                                                                                */               
    & H& k: f* x9 p% ^1 f7 r
  532. /* This procedure reads one address of the device.  It will return the         */$ r: j# N' C- s, m+ |
  533. /* byte read in variable byte.                                                                                        */; B" w4 v4 E4 x- Y
  534. /*                                                                                                                                                */
    & Q8 n) ~! w  A" q- C$ s; X6 H: A
  535. /*                                                                                                                                                */8 T* A- k# P/ Z6 I
  536. /*                                                                                                                                                */, w' K' V' O. \& ]4 W
  537. /* Input:                                                                                                                                */
    4 X: `; g0 ]; m- _! r: g0 R
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */# N4 D( v* V- }8 @5 u% I! B
  539. /*                                                                                                                                      */  |+ v9 B- o% {" r! T2 k
  540. /*                                                                                                                                                */
    . X( _/ P& h: i* P# O4 I' }
  541. /* Returns:                                                                                                                                */5 S! Z5 v! C3 ~. o
  542. /*                byte                                                                                                                        */" R- @; T  H: N
  543. /*                                                                                                                                                */+ N& O3 }! Q4 x
  544. /************************************************************************/0 f( c; y% Q' C8 L& @
  545. unsigned char Read(unsigned long Dst) ) Z( e8 `) q. v3 [2 I8 J1 _
  546. {
    7 E6 j0 X* l( v1 ]9 V
  547.         unsigned char byte = 0;       
    + d/ c) ]/ I8 ~1 _, u! r) ]
  548. ( p) U2 l+ b( A4 b: g
  549.         CE_Low();                                /* enable device */+ K  C. |1 a3 W. {4 t
  550.         Send_Byte(0x03);                 /* read command */
    7 A; |( x. d8 y9 h
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    6 ]- p. J9 R$ a% t/ m
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));8 p/ c& \, k+ A/ y
  553.         Send_Byte(Dst & 0xFF);
    ! s6 _  _; ?  j# Y- @
  554.         byte = Get_Byte();
    " n- A5 |6 J$ v( _
  555.         CE_High();                                /* disable device */
    ' J- r% P. N7 q& E- d4 X
  556.         return byte;                        /* return one byte read */
    9 s0 e4 o+ x( k1 ^4 S6 ^
  557. }& D: U8 F& V' H) N! }) X6 P! }
  558. 4 Y% `% b. O5 Y6 L# j$ Y
  559. /************************************************************************/
    & e9 r; y7 e5 T* o3 {: o1 U
  560. /* PROCEDURE:        Read_Cont                                                                                                */9 N: u7 U; U8 H% j& @+ x
  561. /*                                                                                                                                                */                ( [  c7 ]- E0 j% C
  562. /* This procedure reads multiple addresses of the device and stores                */$ S( X! J% A* \. h% V, ^6 w
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/7 }/ n, n9 [* U5 ~7 G
  564. /*                                                                                                                                                */
    1 y* x4 y; E( l4 t8 g; j
  565. /* Input:                                                                                                                                */: C' s, o1 V! l  A7 U
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 V& `, u; c4 q$ s. y$ f
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    8 `) X! P5 C% }% C- |9 w6 w
  568. /*                                                                                                                                                */- w2 k) L5 D& t- m
  569. /* Returns:                                                                                                                                */
    ; L1 [/ w2 |; N2 [$ T
  570. /*                Nothing                                                                                                                        */7 k# }0 w! c5 f  s) g( m) }( x
  571. /*                                                                                                                                                */, u( F  [- ?1 l- r8 G/ R) D
  572. /************************************************************************/
    . g, _8 c6 Z9 D( M& B# i
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    * ~+ v8 G8 `2 ]& ]+ {% {+ e
  574. {
    ) r+ Z/ h( z7 i) u8 g
  575.         unsigned long i = 0;" }* N9 F  L  Y0 u3 X* x' g* r' B
  576.         CE_Low();                                        /* enable device */' B8 ]( h8 @4 y8 V6 [
  577.         Send_Byte(0x03);                         /* read command */& F$ v# G) {9 b: y
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' p  q# V. O$ J/ y- z
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));4 l4 T0 a2 Z: q  t1 o" `
  580.         Send_Byte(Dst & 0xFF);) z) E. |8 w1 e! r
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    2 b4 x+ O: n' i4 i! X1 ]3 S8 t
  582.         {5 c/ C& @9 P3 S$ ^' c; g
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    $ C2 o9 \: N6 R0 D- }" E: v
  584.         }
    * m3 B! k6 B; ~! J7 G8 l
  585.         CE_High();                                        /* disable device */1 G5 H; F. _# [' X+ v1 d
  586.   V$ g& ^0 P2 H0 c6 O- _- x! f9 K# w
  587. }$ J, W' G+ {3 b) [" @- Y: y

  588. . i$ s& \0 f  r- S1 A' R
  589. /************************************************************************/  l; m+ ]$ f* T! F$ Q
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    ! X- ?; q; c  Y
  591. /*                                                                                                                                                */                  C0 N3 S" q0 \" K, J
  592. /* This procedure reads one address of the device.  It will return the         */3 k$ C: Q4 a% S  Z
  593. /* byte read in variable byte.                                                                                        */
    ! a9 z  B8 q( J! J$ I' z
  594. /*                                                                                                                                                */
    $ E) E( O& \, \$ {( U$ Z
  595. /*                                                                                                                                                */! e" Q) S% Q8 x6 B# o1 V0 p( ]
  596. /*                                                                                                                                                */
    1 V4 |" L' f3 Y! p; B, ?7 G; h
  597. /* Input:                                                                                                                                */% E2 g7 U3 h9 c
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */& t6 L& n# P# \8 |+ X4 Q0 H
  599. /*                                                                                                                                      */
    8 m4 J! y- Z( I. i- v  X7 k
  600. /*                                                                                                                                                */; f' |& y9 o6 C- g; f6 _6 K
  601. /* Returns:                                                                                                                                */
    2 ], U- Y$ Y! I
  602. /*                byte                                                                                                                        */; I  x# X) r' \, J! w$ r/ h
  603. /*                                                                                                                                                */
    ! L$ s! `( J* O
  604. /************************************************************************/8 u  R4 F/ _  a" w: w
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    1 K3 I# \- O! b* R/ m4 g, C
  606. {
    0 ]5 k) n# @2 Z3 R
  607.         unsigned char byte = 0;       
    7 p9 u7 G% g& R* q) n. D3 L0 T
  608. 9 X% V0 t9 s! D0 }
  609.         CE_Low();                                /* enable device */3 X; w1 P: j% B7 R/ a
  610.         Send_Byte(0x0B);                 /* read command */
    ) b. K3 k1 N2 Q  W- s
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 d& n! k) P2 Z! x( Q
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 W4 }) a4 e3 t+ u  n
  613.         Send_Byte(Dst & 0xFF);
    0 P" p' z9 T. T! ?! ]; Y2 F7 y
  614.         Send_Byte(0xFF);                /*dummy byte*/
    6 ?% T% D1 ^' E% N
  615.         byte = Get_Byte();
    ) X+ ~, G  b9 V7 w( a* {& R
  616.         CE_High();                                /* disable device */
    ! \2 b/ w; t3 k! O2 Q0 j1 f) z
  617.         return byte;                        /* return one byte read */
    $ Y$ C2 G& R, ^- R& A
  618. }
    # n" F* a3 f1 K8 o. t
  619. , w9 x# M, ~' P5 i* n7 r
  620. /************************************************************************/
    ; ]: `1 Z! o, O# ?5 w, f
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                *// D# w- c0 ?0 c$ U; o1 Z
  622. /*                                                                                                                                                */               
    2 S' V4 [, v$ D) x
  623. /* This procedure reads multiple addresses of the device and stores                */* i5 T7 Y6 f' _" F4 f7 Y8 a
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/* q! M: b/ q$ r! q9 L  c
  625. /*                                                                                                                                                */2 c$ @' i1 F3 J( [% k* v
  626. /* Input:                                                                                                                                */
    ' H& u' A+ \; V
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) C! ?( O% C& ^$ q/ l/ n/ J
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ! C; T4 q* T. T6 t- K! R
  629. /*                                                                                                                                                */& s0 `7 q: |: D! W3 v
  630. /* Returns:                                                                                                                                */5 y( y* h$ g$ H
  631. /*                Nothing                                                                                                                        */' J$ B+ o( n* H4 W, {8 w
  632. /*                                                                                                                                                */
    - _! \% i4 z+ Y6 G
  633. /************************************************************************/7 S, R* Z6 B, q' R; `& s; F; p
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    6 {4 y& s3 a; [
  635. {
    : Y& Y; c- U$ [% _) J$ x
  636.         unsigned long i = 0;' S! m- j& v  T  v# D2 b
  637.         CE_Low();                                        /* enable device */
    : M! l5 k& t! a
  638.         Send_Byte(0x0B);                         /* read command */: V' H' J1 P& T/ F0 l
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 r% o( K' Q. O$ N
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));# x/ y9 A# n& @$ }1 {. v* K
  641.         Send_Byte(Dst & 0xFF);
    % z- p6 g# D+ t# Z: i
  642.         Send_Byte(0xFF);                        /*dummy byte*/
      h. g3 Z' }2 t3 `
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
      I) d( J9 ?7 e* D
  644.         {
    8 ^  B5 r- d7 p. [1 A
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */3 l/ X' D; j) y! u
  646.         }; M/ d" g4 `5 e, C5 n* I" w
  647.         CE_High();                                /* disable device */0 J. O5 m' A$ b+ I! J9 j" E
  648. }
    / G7 R7 |8 ?$ Y  N0 L+ [
  649. # t5 t! t; Z$ M$ m
  650. /************************************************************************/
    + c- q; z8 a- M; `
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    * I6 C3 f& A& p
  652. /*                                                                                                                                                */, S" l" I- J1 Q) Z+ F3 o% g; E
  653. /* This procedure programs one address of the device.                                        */
    7 E5 n- w1 b$ E* R3 |* C
  654. /* Assumption:  Address being programmed is already erased and is NOT        */+ E) X# V  P5 b/ r/ e3 ?
  655. /* block protected.                                                                                                                */1 U. ?- C; p) ~# g6 A2 [
  656. /*                                                                                                                                                */. c2 |" X. E. N
  657. /*                                                                                                                                                */- |2 i0 v% _' h7 ?2 S& S
  658. /*                                                                                                                                                */) q3 I& U+ j% j
  659. /* Input:                                                                                                                                */) v6 s2 U9 G1 a1 p( \! S# O
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    3 I7 y  Z1 C# r/ ~. @' _
  661. /*                byte:                byte to be programmed                                                                */4 i  F4 ?3 V1 o! B' N8 D
  662. /*                                                                                                                                      */0 r+ a5 m' z* ^+ {1 [5 \
  663. /*                                                                                                                                                */
    : ?& f& o4 ]2 K/ d- K( `
  664. /* Returns:                                                                                                                                */* Y" A7 ^  f0 E
  665. /*                Nothing                                                                                                                        */+ `+ p, t- N* M3 I  R" _
  666. /*                                                                                                                                                */
    9 z  @" t- G0 \! z7 C
  667. /************************************************************************/; G# S2 ~. w& v6 g' d# K
  668. void Byte_Program(unsigned long Dst, unsigned char byte)+ b$ q" V9 x6 j( D, T1 ^
  669. {2 M4 D4 R% N; i  Z
  670.         CE_Low();                                        /* enable device */
    6 l( f# o8 \% X6 n/ Y
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ! [# m; M% d8 l6 [/ J0 g
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */5 s& g/ K4 f! S9 y# o: ]+ U# l
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));( L7 F3 q/ G$ C
  674.         Send_Byte(Dst & 0xFF);
    # v8 k- y; F$ c7 N& P
  675.         Send_Byte(byte);                        /* send byte to be programmed */, ^1 X/ [" k3 k! x
  676.         CE_High();                                        /* disable device */1 v, h8 k, n! I& g3 Z5 ]9 A
  677. }
      P; l3 ^/ {+ B# j- |# |' e
  678. " f" ~& N  ?* Q/ Q% p, M
  679. /************************************************************************/
    * D4 p+ \7 t, r7 y( p
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */# z3 u4 D/ L1 h
  681. /*                                                                                                                                                */
    5 M6 e- E. A6 C* [, ?0 X' Z
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/; U4 G  r* P7 B+ r; @$ e& }
  683. /* the device:  1st data byte will be programmed into the initial                 */( r. h' `9 o1 X% q3 z: D1 ?8 K
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */4 P1 Q6 |  S& k3 l. h) q
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ( g! W4 W/ H" Y1 G! w) J
  686. /* is used to to start the AAI process.  It should be followed by                 */
    $ v. o5 W" A9 h
  687. /* Auto_Add_IncB.                                                                                                                */
    + t$ X! ~+ p& f, y2 _; @/ ?
  688. /* Assumption:  Address being programmed is already erased and is NOT        */6 @) f, a' M0 W
  689. /*                                block protected.                                                                                */  f! a7 b2 J; A1 t
  690. /*                                                                                                                                                */, \! Q# z9 e3 B( M& {/ v
  691. /*                                                                                                                                                */$ T9 s% P. J+ B  ~: c: H
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */. V) E; {- o/ k" Q# D7 h- p8 ]8 v' K# w
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    ' G1 ~+ ?- f" b/ I" T4 K
  694. /*         unless AAI is programming the last address or last address of                */
    # j  l) m* [2 K9 u1 t2 r% k, M) H" p
  695. /*          unprotected block, which automatically exits AAI mode.                                */6 Y$ _+ v) f4 a% p8 z- d, E& x
  696. /*                                                                                                                                                */
    & ~4 E  y; Y# w
  697. /* Input:                                                                                                                                */. ~7 O9 p. d" Z0 t3 w# _+ K& y( h( K
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 F) x& ^$ _" u" n
  699. /*                byte1:                1st byte to be programmed                                                        */. d4 F5 a  y& `4 g9 k1 o) z& x. g
  700. /*      byte1:                2nd byte to be programmed                                                        */
    8 c5 K( E# p" u7 y
  701. /*                                                                                                                                                */5 j1 D& ]( C# Y  x4 n. ]' D
  702. /* Returns:                                                                                                                                */0 w2 J0 z5 p6 Q! h
  703. /*                Nothing                                                                                                                        */- P9 S( }4 O: E" E' N
  704. /*                                                                                                                                                */
    * l! z2 Q4 H- A/ \3 p& X# `
  705. /************************************************************************/) W9 n9 L7 ?: x/ c
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
      p& w* P: l. l: [
  707. {
    2 ?- T8 P+ h7 F/ S- L
  708.         CE_Low();                                        /* enable device */
    1 y6 |" X! t. e2 T8 o7 Y: @# u
  709.         Send_Byte(0xAD);                        /* send AAI command */. v: M% v: i" ?5 T6 K
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( i) W9 V  A0 M% o# I! K/ _
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' w7 M3 c! q0 i! J) a! A
  712.         Send_Byte(Dst & 0xFF);+ x) Q% @0 \3 @
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ) G) ~  V% p7 y  A7 D
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */: r1 u+ X& f3 M" R+ ~8 T& [
  715.         CE_High();                                        /* disable device */3 q# J& P/ C! m: B$ e2 }9 Z
  716. }
    6 m2 i: s+ w! ~1 b" C
  717. + v. T' ^# \/ S0 l" ^0 s
  718. /************************************************************************/: @( U0 f' O0 C1 {, |) k
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */8 R9 s$ O% d; E- ^( {% g+ d
  720. /*                                                                                                                                                */$ A: o0 ^1 c2 T9 D0 A( y; J/ e
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/9 ?, v( r9 R- Z( v: b
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ' M4 ^0 z% \! m$ k( B
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */# A6 ?( z* g9 G7 i  D# O! ]
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */. a% f& @0 ]% [) Y- L* k+ g$ D" L
  725. /* is used after Auto_Address_IncA.                                                                                */
    - G" L1 V" y* a2 c7 N9 p
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! y  D; g: X/ S" x+ [3 h
  727. /*                                block protected.                                                                                */
    : ]8 I$ m9 [7 W4 C( ?1 A
  728. /*                                                                                                                                                */) w8 v" V  Z: j9 S
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */5 Q2 u9 I$ _0 K( w! L
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */- ~* j. a2 V. A! ~* C, M
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    " n6 d( C# Y( u- J+ Y* K
  732. /*          to exit AAI mode unless AAI is programming the last address or                */4 a/ O9 C# Z# y7 ~0 I. x4 H- L3 U
  733. /*         last address of unprotected block, which automatically exits                 */
    . o- d+ L+ |: g
  734. /*         AAI mode.                                                                                                                        */
    + Y, K) F1 h4 z0 q# a. G
  735. /*                                                                                                                                                */
    . s6 D7 }& y' @7 W8 s
  736. /* Input:                                                                                                                                */
    % P" e: g. T3 U! j0 R& V
  737. /*                                                                                                                                                */% {+ X3 |$ x' M8 |( I
  738. /*                byte1:                1st byte to be programmed                                                        */
    7 ~4 @" ~# B& e/ B6 F* Q8 C# p
  739. /*                byte2:                2nd byte to be programmed                                                        */
    % I7 g; C; e0 I8 s$ x! b3 {5 n
  740. /*                                                                                                                                      */* D$ W" z5 A5 ?* u; h+ H# {
  741. /*                                                                                                                                                */' u# ]6 @. ]+ r
  742. /* Returns:                                                                                                                                */3 |% U4 I& {3 r2 Y
  743. /*                Nothing                                                                                                                        */
    : b# h8 J9 e: Q0 m; W! c1 D
  744. /*                                                                                                                                                */1 j9 d' v; i) f2 T* h5 N( }
  745. /************************************************************************/8 p5 v& J% R8 Q
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    + D' `7 `, X  [' m) {/ j8 y& H
  747. {
    ) @2 B& m: R2 V
  748.         CE_Low();                                        /* enable device */& K& p3 z! s& ?8 [6 S' M8 M& q+ k
  749.         Send_Byte(0xAD);                        /* send AAI command */
    3 z: O+ A# P( L& d2 {
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */) G6 C- Y; s+ X! @" v' \
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    % c$ `0 I6 {: }$ t0 h( w
  752.         CE_High();                                        /* disable device */
    * U7 o) `1 b3 u6 q8 K& t
  753. }7 J; S. \$ Y2 J$ i, \/ H

  754. 5 Y% l( ]8 T, s7 N; s" @+ b  ]
  755. /************************************************************************/
    " ^' E/ c1 ~- z5 f  A( e
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ; \) r; [" H* E6 D, o
  757. /*                                                                                                                                                */7 Q: u+ t0 I0 D, J# {# m6 K0 g9 _6 ^9 a' e
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it *// V  E/ s) n# J2 q
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    " `0 T8 v' \* z% L6 P  Q( i* D
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */' h* ~8 J6 ]9 C1 r
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */5 x9 Q; l2 q1 b- }! c
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */; d; v$ `) E9 H
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    0 |6 c# H2 v6 J: z' b/ e
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    + [8 S3 D7 l3 ~+ M
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    # T5 z. d- v+ E9 Q" v
  766. /*                                block protected.                                                                                */
    ! H9 z$ a- T7 D6 l. D' ~
  767. /*                                                                                                                                                */4 k5 P/ O- T2 a3 _8 t' e& b, |' Q
  768. /*                                                                                                                                                */
    * u$ q9 W) O) I( @
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */) @% J" Q: @) d9 l0 {4 Z
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    " d" [8 v8 z) N+ [5 U8 z0 _
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! D) \* y0 Q4 q! f4 X% Q# F* Z
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    # A5 d6 d7 u0 A3 L: |  |
  773. /*         last address of unprotected block, which automatically exits                 */
    & R6 R' b2 Q# u! r$ z! t
  774. /*         AAI mode.                                                                                                                        */4 D: ^5 `' J2 C9 n5 T1 O
  775. /*                                                                                                                                                */
    ! R9 @8 C! i* W1 L9 S7 ?6 n
  776. /* Input:                                                                                                                                */
    % a) K9 O& V: s3 A
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 z! ~6 [) ^% t, R, N
  778. /*                byte1:                1st byte to be programmed                                                        */% B' N* U# f/ p7 R1 a0 G+ C
  779. /*      byte1:                2nd byte to be programmed                                                        */
    5 S( m" r1 B: ]0 O1 m/ Z% P( |
  780. /*                                                                                                                                                */% P- H2 f- o: ^
  781. /* Returns:                                                                                                                                */
    $ O7 N4 p( E- n: Y
  782. /*                Nothing                                                                                                                        */+ Z5 y) ~1 r) Z% v
  783. /*                                                                                                                                                */
    ! E: C- Y7 L* U6 y
  784. /************************************************************************/9 z' |# {$ R3 [9 e/ F" v" g
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)# ]( W: f& y4 Q
  786. {7 W4 c5 e: C# E% K  H: t
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    0 f& D, r" Y1 H: c9 |% [0 i
  788. . _6 ?; V# I" F* g1 f1 ]
  789.         CE_Low();                                        /* enable device */
    % U. w$ b7 }$ r/ o9 j( `
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ( l+ g: C5 [) s2 F+ ~2 o; T
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ I, ?- l9 Y5 `& p. X" v
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));0 ?. U0 a. ~: r) ]2 w( f, f% _- n
  793.         Send_Byte(Dst & 0xFF);2 ^4 O% }  T+ w4 O* t! S
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    9 i# V7 r6 r1 k: }2 b
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 e8 p# D4 b7 y2 B
  796.         CE_High();                                        /* disable device */; K1 w6 d4 s. f, }, ?" ?- ?& i1 v
  797.        
    4 d3 z, [- a( T; g3 @
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */0 E7 w0 [+ n: W+ I! G5 a2 k2 J
  799. + h- y5 e) t- o8 o8 v3 A+ c* k
  800. }* y1 x( P: s8 F& O

  801.   f% l& o1 P/ @* p" h) S& u, ^# B
  802. /************************************************************************/4 ^6 u$ w5 B  f; d4 m3 ~0 ~" s
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    9 v$ a( m& Q- R# r% e
  804. /*                                                                                                                                                */
    / j3 S4 m' i( z7 X% m& r* j4 {
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    0 s, E! V  Z& Y, t
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    ' }5 b2 g- l' ~( [6 H1 Z9 `$ r
  807. /* AAI programmming is completed.  It programs consecutive addresses of */4 L( Z# V$ P  D8 q/ L
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    0 P8 p7 F/ E% {/ z4 }: g
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    3 U! d2 j, w" R- ?0 y
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    . N8 h9 c  B# C: [
  811. /* used after Auto_Address_IncA.                                                                                */4 P( [4 Y# L( x. e1 u
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 S& A1 a/ ?) D/ F
  813. /*                                block protected.                                                                                */# l- U1 _0 n4 J
  814. /*                                                                                                                                                */9 @' q& d# `4 j, B2 @$ `
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */, ^8 k3 g* a( ]! D7 ~
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    * G, ?8 R% D4 I5 l
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! [+ O3 o! m0 q: r
  818. /*          to exit AAI mode unless AAI is programming the last address or                */0 U+ G6 i* Z! x/ j3 v# E8 B
  819. /*         last address of unprotected block, which automatically exits                 */( q0 b3 G2 z9 g' ]% L
  820. /*         AAI mode.                                                                                                                        */  ~6 e3 \% x/ u& C
  821. /*                                                                                                                                                */" H; \: N! J9 w% r9 K3 c3 ^5 R! U
  822. /* Input:                                                                                                                                */" A7 L" Q2 R1 p$ ]" ?: q
  823. /*                                                                                                                                                */  `; Q4 X, a1 ~6 p# Y
  824. /*                byte1:                1st byte to be programmed                                                        */
    2 P/ b( H$ W" ~: F
  825. /*                byte2:                2nd byte to be programmed                                                        */
      \# ]6 F' v5 _
  826. /*                                                                                                                                      */
    # ]$ s" y, d! B& E* R- @
  827. /*                                                                                                                                                */
    , l- r& B8 u4 A$ f$ I: W
  828. /* Returns:                                                                                                                                */' @5 y" d9 g. T. Q( e
  829. /*                Nothing                                                                                                                        */, ?' Q0 Z, f1 v( z( y% d; \
  830. /*                                                                                                                                                */- {7 w$ U% P# K& C
  831. /************************************************************************/5 O! f7 z6 g% p4 a
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
      j' U  m# W# d0 l$ v# a7 f
  833. {$ V& z, u" u( X( ^0 R
  834.         CE_Low();                                /* enable device */- X# o  n- l( z- v0 A" y" \) `
  835.         Send_Byte(0xAD);                /* send AAI command */6 O( J+ x/ Y: w- L
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ) A6 a* @9 G1 [3 Q* i
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */- q- G3 r9 w0 {) L1 ^# g( [
  838.         CE_High();                                /* disable device */9 H$ O' i$ E" F- P0 C7 W

  839. 5 c  {8 a: g+ a2 g) l0 E
  840.         Poll_SO();                                /* polls RY/BY# using SO line */- Y  m  R. d. y% ~. q3 O/ _
  841. / L9 |% z( J( s& b
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    . ^$ a: b  y& Q' T# C5 k, j
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */+ d. x& b' G: u4 L8 K8 i* d
  844. }7 c/ c, A7 B2 o( S
  845. * O* l) z3 w" q/ d) h
  846. /************************************************************************/
    ; T/ G. A' n. C
  847. /* PROCEDURE: Chip_Erase                                                                                                */! R7 Q( x$ r2 J& b, Z8 I
  848. /*                                                                                                                                                */
    ) I1 I9 x7 z1 ^/ E3 O  v* K$ W1 n+ x
  849. /* This procedure erases the entire Chip.                                                                */
    8 i. j( n/ M8 Q# p. Z
  850. /*                                                                                                                                                */' W7 n+ S9 w' E$ J% K9 P: `9 `* c
  851. /* Input:                                                                                                                                */
    ' @* x0 J3 |" Z; Q5 Z: F7 C) y
  852. /*                None                                                                                                                        */
    6 u0 Z% J) [( C1 v% O: A  j0 K
  853. /*                                                                                                                                                */1 S! Y  F; F$ a, G1 s9 \
  854. /* Returns:                                                                                                                                */9 t& t( i! U: }# u4 B0 l( E
  855. /*                Nothing                                                                                                                        */
    ! W. g6 V; ~, X  u9 ?1 K. l
  856. /************************************************************************/1 `* z7 b. q6 Q0 q
  857. void Chip_Erase()  k$ o6 I* z+ M) [' r) J
  858. {                                                2 V8 X1 _7 h6 f: N# N9 X  N
  859.         CE_Low();                                /* enable device */. I- y7 f8 m: u$ @( H
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    " S9 h( T& j; k6 z  k! b
  861.         CE_High();                                /* disable device */. E4 V4 i" b) i9 d
  862. }% \* [" W1 y. Y

  863. 7 ~4 J  d" Y9 o
  864. /************************************************************************/
    ) v3 q+ H( O2 p' a4 {, r
  865. /* PROCEDURE: Sector_Erase                                                                                                */. q1 B) `% t, {
  866. /*                                                                                                                                                */2 Q+ D. J# ^5 T( Y# R, z
  867. /* This procedure Sector Erases the Chip.                                                                */
    3 |& e7 Q5 ]7 Z5 s
  868. /*                                                                                                                                                */
    0 ?$ i' H! l! U1 Q$ z; M1 u( B
  869. /* Input:                                                                                                                                */
    ) I6 Z, j( W& Z; N2 l
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 U& P, x; [' c! `& u9 a
  871. /*                                                                                                                                                */2 n" ^- r) }4 W4 j7 r  [
  872. /* Returns:                                                                                                                                */, M, Y7 C  E) u0 \4 X6 W1 u
  873. /*                Nothing                                                                                                                        */
      I/ y3 o3 m+ @, R3 H, h- Q0 w
  874. /************************************************************************/; h. S2 g# W' n, b3 V' G
  875. void Sector_Erase(unsigned long Dst)3 ?# h* P8 y- X/ |
  876. {
    ; {* o! b. o' F7 o2 p3 I) G

  877. % A5 V5 o  p2 h- d* z- a

  878. , D. ]& A) z. d; R4 v3 C& h
  879.         CE_Low();                                        /* enable device */
      g& ?- G0 j1 ^# j% @7 e6 c/ L  J* I
  880.         Send_Byte(0x20);                        /* send Sector Erase command */7 I: t: b6 P- r# ^& c
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 @; E7 h; L  J+ x' t5 v/ y
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));8 ^2 Q' S! Z7 `( s5 M
  883.         Send_Byte(Dst & 0xFF);
    & j3 ?3 \/ x! W+ q) b4 _. v
  884.         CE_High();                                        /* disable device */+ d' F4 V% T/ W0 o" p! n8 U
  885. }       
    2 t, K: y9 s& p, [2 J

  886. ; h2 P' D, S7 X0 n% J- y
  887. /************************************************************************/4 M, j. \$ Z, A; [) \8 j
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */  U3 ^2 A. J0 y3 e3 g
  889. /*                                                                                                                                                */2 a2 c1 ^9 _: l5 ~9 @
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */# O2 x! b+ h* h
  891. /*                                                                                                                                                */
    # t* r5 F* D; a- y
  892. /* Input:                                                                                                                                */2 ?, U. x5 Y( g* `
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */8 ?9 z5 r" p  u1 j1 @; t# G6 ~( `
  894. /*                                                                                                                                                */
    " h6 k& G" R" q  R( z. z% ]
  895. /* Returns:                                                                                                                                */. m7 s4 Y0 x. h2 I: ~, @) X" d
  896. /*                Nothing                                                                                                                        */
    9 ?7 E" w9 L  Y: ~
  897. /************************************************************************/8 y4 d  w3 p# S6 N. J
  898. void Block_Erase_32K(unsigned long Dst)
    ( J. q' r; W. I
  899. {
    ( D* A6 @3 ^- Q+ P5 m& D3 f
  900.         CE_Low();                                        /* enable device */
    4 j. ~) m( B6 S& P8 b0 f" Y
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
      ]5 A0 {! W$ n$ L1 ~* q7 S
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( D( V4 Z* C! u' |
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));/ P6 c3 p) a- ?- o% w
  904.         Send_Byte(Dst & 0xFF);
    ' l' E; r" G! u, M, ~& L
  905.         CE_High();                                        /* disable device */
    1 N3 o& w1 X, l: k( O9 C8 Q
  906. }
    0 h- e1 q- g; @1 c/ ]. ?2 R' B

  907. ( ^7 ]; Z' i/ q& v0 X) Q- I
  908. /************************************************************************/
    % ]: `; V0 P& g( M/ P
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */4 y0 [) `- \4 I3 H! S
  910. /*                                                                                                                                                */* j- w) N3 d5 y' b( e
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        *// b. |: |5 _( K6 t: K2 e: f
  912. /*                                                                                                                                                */; k6 h. m0 v, P. M
  913. /* Input:                                                                                                                                */
    1 m+ |; d' p5 o, D: w8 N* k7 Z+ a
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% L( q2 @7 N6 y, o' i
  915. /*                                                                                                                                                */
    ; o  r  H4 a1 A; _' t
  916. /* Returns:                                                                                                                                */" H% P- Q+ B/ B5 k- A5 f) d) o
  917. /*                Nothing                                                                                                                        */
    6 j( i1 h' p( k" v3 D. U- _
  918. /************************************************************************/
    ( V, Y! @  I9 V) H0 ^
  919. void Block_Erase_64K(unsigned long Dst)
    ( y+ {+ c# F5 ~2 R( A2 W  K
  920. {
    9 l7 _; Q. ?0 {8 v  D
  921.         CE_Low();                                        /* enable device */
    $ J+ ~- C6 D6 w, K
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    $ k7 }) O3 {  }6 M( X; [
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */. y2 J: k( g/ q  M, w" O+ s
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / G: ]/ M% {0 C
  925.         Send_Byte(Dst & 0xFF);
    / V2 @; f1 O7 K! r$ |
  926.         CE_High();                                        /* disable device */, J: G# c! y' K" b# @
  927. }. p0 A3 J9 U9 z3 m. ]- l

  928. 1 {, @: u7 d& I- ?& M; T( F
  929. /************************************************************************/& M( k0 r; f1 l
  930. /* PROCEDURE: Wait_Busy                                                                                                        */6 l4 I8 G' I( p5 V
  931. /*                                                                                                                                                */
    8 h& L9 g3 m! {4 N* h: O. |  ]
  932. /* This procedure waits until device is no longer busy (can be used by        */
    $ F9 L: R! n( M) |  \
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ' l( ?3 t! @! B2 R1 i
  934. /*                                                                                                                                                */! ~) C% m  s7 V* ~& U
  935. /* Input:                                                                                                                                */
    4 I. J5 c: s- G
  936. /*                None                                                                                                                        */6 U  i/ S- F: F. F* S5 ]
  937. /*                                                                                                                                                */
    7 M4 |/ W) P- @! g4 Z% k
  938. /* Returns:                                                                                                                                */
    / N! n, o' f% T% z+ a/ r' d- P
  939. /*                Nothing                                                                                                                        */
    . b' `; N8 Y7 x; u. h- I; O
  940. /************************************************************************/
    ' E0 y' m% a$ l2 s
  941. void Wait_Busy()
    0 Q6 G% O4 R6 h' K6 Z; H7 |
  942. {
    . Q: F/ j5 z9 R) n" M) Y3 N
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    % Q& f' _% W3 c3 s$ W! E
  944.                 Read_Status_Register();
    " W/ w" Y6 B3 n7 O& M% L' N
  945. }# P" n/ J3 P2 h
  946. ! N  x; m! C2 P7 ?9 p. b, X
  947. /************************************************************************/" z; V+ G" W2 E- w, f5 Y3 `
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */# F$ r+ a8 h  f. p0 k8 v$ J
  949. /*                                                                                                                                                */9 l* |  h1 g6 f9 j$ N
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    # B% V% G8 O5 S2 I) ^
  951. /*                                                                                                                                                */; n3 f3 a* z" I: S. _
  952. /* Input:                                                                                                                                */
    - ]1 Y) \% z2 s! t
  953. /*                None                                                                                                                        */
    3 m! Q. D' v: `# M) u
  954. /*                                                                                                                                                */
    ) [; w5 h, M0 q3 U0 |. ?" ?
  955. /* Returns:                                                                                                                                */; ~: n) u' o& ?
  956. /*                Nothing                                                                                                                        */; f1 R2 N2 i; {) @1 Q
  957. /************************************************************************/
    # n/ I4 o, @' C0 c8 u. _8 w
  958. void Wait_Busy_AAI()
    3 W& D/ I2 H& f
  959. {8 v( D. G3 w* z: z2 x/ p# _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */+ T& I- K( q. l, Y; [& r0 m
  961.                 Read_Status_Register();
    2 x! ]6 F; h! O0 k; f! x) y" P5 H
  962. }
    # v4 J  K% O( h' D

  963. 3 T0 {1 F  w7 q1 _
  964. /************************************************************************/
    5 D; A) E( A& v; G5 m
  965. /* PROCEDURE: WREN_Check                                                                                                */
    . K+ A5 S" l, O; |
  966. /*                                                                                                                                                */3 _& C' \9 c& S* r8 [$ {" p
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    * ?4 e, Q3 q6 H. e: ~
  968. /*                                                                                                                                                */
    # q% I- r7 K* z- m' [( [0 y/ @+ A
  969. /* Input:                                                                                                                                */
    ( o7 \7 h3 @  G$ p: i
  970. /*                None                                                                                                                        */$ c( I/ z& {: R3 D& \7 a
  971. /*                                                                                                                                                */
    & W" L$ J1 P" V) R# W
  972. /* Returns:                                                                                                                                */
      f3 D) Z3 v; j  T8 k" _
  973. /*                Nothing                                                                                                                        */
    0 n* F  W& Z2 a6 T- l5 _0 r  {
  974. /************************************************************************/
    * S# {) h1 `, d/ d' O: w
  975. void WREN_Check()
      z# H$ D  E+ ^7 w! l) j! {# F  I9 r
  976. {
    / n- M/ x" P# x5 f- Z4 [- D. A# n
  977.         unsigned char byte;* P  f8 _: R& K5 C
  978.         byte = Read_Status_Register();        /* read the status register */
    0 X$ [! F3 f6 ]# I$ y* r# z
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ! ?, i+ g* f! C- Z/ o
  980.         {
    & x7 }. ^- d# }/ s0 a2 }5 d4 m3 W
  981.                 while(1)( B, r' Z: K) g: |$ [4 J+ Y0 q
  982.                         /* add source code or statements for this file */
    $ N- E8 L6 l! j+ P/ {' f# G. }( p' O
  983.                         /* to compile                                  */
    : \) o$ d( ~# m) Z' e$ _$ o
  984.                         /* i.e. option: insert a display to view error on LED? */6 G( L: w; \, e! ^, }. @) J& Q
  985.                  
    & x& O9 y, U8 o8 R6 L
  986.         }9 i5 M9 y; _. K5 w  P( ?6 P0 ^
  987. }) E$ ?" g1 W1 [4 k6 N) d
  988. * h5 x: A9 H. Y4 L3 i& o/ {
  989. /************************************************************************/* e9 b* i, Q6 }7 s& H
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */7 o6 U5 E" B9 s- J5 p
  991. /*                                                                                                                                                */6 E( a) l$ u  z
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    , \  I+ P* A" ~7 X; i
  993. /*                                                                                                                                                */
    $ h1 d# n5 `' t
  994. /* Input:                                                                                                                                */5 u! j6 Y& c: X0 l0 D% Q
  995. /*                None                                                                                                                        */
    0 [4 f' H; ]" E9 @: g! F
  996. /*                                                                                                                                                */
    6 P6 H: j4 j+ I2 {. d3 s
  997. /* Returns:                                                                                                                                */1 e6 M9 m2 b- X' x% E' Z4 ]& b$ I
  998. /*                Nothing                                                                                                                        */
    , d0 o0 Y' j0 |0 {9 j, z& c
  999. /************************************************************************/+ e0 x+ ?; A- |1 j: H0 t
  1000. void WREN_AAI_Check()/ _$ Y" ?3 e. w
  1001. {6 r# p( v7 H5 E" q" y. C
  1002.         unsigned char byte;% i) c2 K: s5 `: b* t3 f3 L
  1003.         byte = Read_Status_Register();        /* read the status register */
    ) Y) Y2 D# s7 K! d
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */( x$ P# G1 P* P6 B
  1005.         {. D0 s( G5 A6 L
  1006.                 while(1)               
    2 _5 N% V; Q* T5 v7 a
  1007.                         /* add source code or statements for this file */
    : b+ ?; F6 J1 T
  1008.                         /* to compile                                  */
    1 E( Q% o* U* v+ o
  1009.                         /* i.e. option: insert a display to view error on LED? */
    8 _! y6 g# B! e$ h3 x0 t4 v

  1010. # q9 x/ N" j3 e# M) ~( S
  1011.         }
    7 k$ W2 e7 L1 p/ r5 R! M
  1012. }
    2 c' k; R  R! Q* [+ F9 m
  1013. 7 A6 m0 X" c$ B( W% W
  1014. /************************************************************************/% Q1 B" g* x" p
  1015. /* PROCEDURE: Verify                                                                                                        */
    ( c- _$ c( g' @/ n7 o
  1016. /*                                                                                                                                                */
    ! Y6 V; h) u' I
  1017. /* This procedure checks to see if the correct byte has be read.                */
    $ N* j/ `. H! A$ e  n
  1018. /*                                                                                                                                                */0 E% }6 T! D5 H' V6 G
  1019. /* Input:                                                                                                                                */) U; t. l7 m% W8 {6 l& Y
  1020. /*                byte:                byte read                                                                                        */3 ^' R# D7 R: N% ^4 J- H
  1021. /*                cor_byte:        correct_byte that should be read                                        */  ~7 X) G, Y5 n" U6 b5 R4 v: F' _
  1022. /*                                                                                                                                                */
    : K/ C; y7 G! S/ Z6 M; r) a( s
  1023. /* Returns:                                                                                                                                */8 a+ H( T% ^* u1 S, H
  1024. /*                Nothing                                                                                                                        */' ]' r2 S0 V5 m
  1025. /************************************************************************/
    3 F" z, p5 d& i" f4 G4 A
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    / L9 m+ T. O& o+ e: w0 X
  1027. {
    ) N/ s( b$ C; W0 ~3 X; P
  1028.         if (byte != cor_byte). H; l6 R$ [" f; c2 ?8 z& r! |8 F
  1029.         {1 O: \8 p  ?$ X( U4 E# ^' w
  1030.                 while(1)
    ; k$ b" `0 g0 w) W7 T; K# z
  1031.                         /* add source code or statement for this file */
    * V( n# K. [6 ^" A- I3 A: d2 ~
  1032.                         /* to compile                                  */
    . Y7 ]" V8 [+ d5 j( k. n+ s' N, A
  1033.                         /* i.e. option: insert a display to view error on LED? */
    " r' C7 N$ }% R
  1034.                
    1 _# v  g. V: n8 H' Z* ^
  1035.         }. c- O7 E* x/ ?: i
  1036. }: C8 x  V* A  z& K  ^

  1037. ( d% y" `) D9 V; L5 C6 u$ [

  1038. 1 o; X" p- J& a0 y
  1039. int main()
    $ G8 L/ O( U; m4 H4 _% h
  1040. {% A; T$ B; G! }9 \) B- }! f

  1041. ' \& F/ {4 O  j7 C+ k
  1042. return 0;
    7 E6 b8 C, P& ~
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
; e1 J% }( C& O/ z  A- k   main()
0 a$ q7 p; E* G6 Q. c$ l   里面怎么是空的呢?
% H; c) B2 C# V0 o   发一份给我吧
8 ?$ Q0 r. @( C8 Jmail:luyijun2005@hotmail.com* ^, U2 [- K7 r' n$ r
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。9 Q5 |! u. }8 @3 b, h8 k* ?) Y

" s  J% S2 |# C3 w3 p[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
) r7 l+ s# C3 dEC的代码在哪跑,你看DS的说明,每个EC都不同的。
: ?; G* K) v  ^OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?9 e5 C: o" g: K2 I( n  A, W' e6 v
上面几个问题是你没看任何东西而白问。- {, s( e8 {( @' U

. u8 q7 m" f# M至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
) ]  t( U3 N: `/ b$ k$ t1 ~$ G6 u3 s
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!& Q1 w  `9 }1 P& u% d

- q" ~! y* J6 Z  f7 A* V* {关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
- g5 I: q  H* Q  k) d# F3 c: Q5 a  h. Z9 e7 I7 ^$ e
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...0 I" N$ q+ h6 Y& I) e) k
7 J( g+ ?6 C' {" L7 o# N. w1 K( u
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样; D3 N5 a7 I1 {9 o/ d
似乎要把SPI能support 到最大,这EC chip应该有好卖点
5 C/ p. V9 j0 g6 b% _BIOS功能要不要强大,也就决定了SPI Flach的大小
5 H' q; ^0 g! E# D8 C& W, s. ?我是这么想的~让OEM去决定要挂多大!2 x. J( X' M1 W! T3 `! |% c, {1 r
如果我司有BIOS工程师就好了~哈
, @2 Q; g$ M! ?# b! Z3 gWPCE775应该算很新的东西,来看它支持到多大?  d7 J- y/ V* x* s' e* }  F

6 ^' F* P3 Z, Z! V5 b1 v- \1 b2 @另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte2 p% m; _7 q# E( `& B
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
0 ^* H6 f3 J& X9 F% G: _
) c) \* G/ l9 u4 v  L# A这份driver收下~希望以后有用到
" w! Y$ {& R8 I- F5 w$ ?  m谢谢bini大大" g5 P  ?# E. u! v' Q
) V9 k6 C5 F  W( i9 c
很新很新的新手,如有错误请指正 (准备看第二家的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()
: Q9 y; U- w  o- v& X( W{
) M' V" E2 l$ l        unsigned char temp = 0;
3 [" s( J1 X% f) @; g% N        CE_Low();! t- v: o6 l/ Q5 I& d5 }
    while (temp == 0x00)        /* waste time until not busy */
( Q* p& e, x. C5 P& h9 ]8 y2 |                temp = SO;. h" T! J5 h; u
        CE_High();
: f; z6 g6 p( E! T; [}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
/ C" ]+ N* l1 N8 ^+ J% C5 E! F{6 a$ E0 \9 m# u8 j  k! h
        . I6 o  }* v) ^6 z: w7 H
        unsigned char i = 0;1 |) T+ q4 g) q, U
        for (i = 0; i < 8; i++)
. X& J! H" ^, w1 A  Z' f* ]* ]        {' d1 f5 X$ a, W( U* z1 r3 `2 m
                % H& V) b7 }7 ?. G+ i2 Q9 B
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
2 K0 B3 S, z+ n+ G                        SI = 1;, |3 R) W% P) E) c' H* W3 U
                else! S/ V" k9 b5 v2 @
                        SI = 0;                                /* if not, set to low */
4 @" h3 n; h/ Y 问              SCK = 1;                                /* toggle clock high */
  v6 D7 t% e2 B% g   题            out = (out << 1);                /* shift 1 place for next bit */& v% H' M3 y+ d5 g, B
                SCK = 0;                                /* toggle clock low */) @/ M+ q3 W0 E+ v
        }; h( b) c! }) ~  c3 C' S4 B& S
}/ l; a* y, W, Y0 }$ k5 C" x7 j
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 21:02 , Processed in 0.038703 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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