找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54337|回复: 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& Z& P) i  X$ e4 o9 w

  2. $ Z: U) Q  R5 T: [/ I9 \
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory7 z- M- e4 s# X; V  j  J

  4. % \% Q3 F4 d/ ^2 L/ |
  5. November 4th, 2005, Rev. 1.0
    " c5 q, C. e/ z* o6 B# h5 Z# d. V

  6. . e/ N; m/ F! L: `7 O! p& Y- S
  7. ABOUT THE SOFTWARE+ U2 [" S0 N& W9 ~* g( H* X
  8. This application note provides software driver examples for SST25VF080B,
    * w$ [) g3 _* d
  9. Serial Flash. Extensive comments are included in each routine to describe
    4 G- v  G8 H* h- e! U; C! ^
  10. the function of each routine.  The interface coding uses polling method 9 N9 i" a5 q6 [/ ~
  11. rather than the SPI protocol to interface with these serial devices.  The6 }1 Z- R% A9 u( o4 S5 D3 c: R  ~
  12. functions are differentiated below in terms of the communication protocols
    / E3 ]% I: h# F9 Z5 _* C9 m, N- L. N
  13. (uses Mode 0) and specific device operation instructions. This code has been
    9 p! T* F' C3 e
  14. designed to compile using the Keil compiler.. q7 R( b1 g$ o/ L" O/ P$ A- Q6 D
  15. ( U/ n7 \7 S. h, A. Q  S* Q, _
  16. ) Q$ X  i, q+ x, x: n$ V& T
  17. ABOUT THE SST25VF080B: Z: p+ ~9 e; M! a" K5 ?

  18. 5 J. d8 o4 m7 D- N9 C6 l- B
  19. Companion product datasheets for the SST25VF080B should be reviewed in 5 I; V% F8 |# F& K) S: T
  20. conjunction with this application note for a complete understanding
    + ]' Z* p' r9 d6 u
  21. of the device.
    2 g& {: C2 a; P& @# i6 |

  22. , a* y7 {# C/ J6 i7 f1 P% y- H% A2 V7 z
  23. 2 r# e& T# s! o$ Z0 c
  24. Device Communication Protocol(pinout related) functions:
    1 L$ V  D2 V# u7 {6 I4 N

  25. * x3 B& ~+ ]& b/ g% r% r7 o
  26. Functions                                    Function& V6 ~4 b/ ?4 i0 U* c( {6 J# `  S
  27. ------------------------------------------------------------------* F- H3 D. E- Y3 b
  28. init                                        Initializes clock to set up mode 0.
    ' s! p+ e& u1 y1 @9 A7 C" a) `8 M2 R
  29. Send_Byte                                Sends one byte using SI pin to send and
    9 v+ {& [* z, }: f; h$ x
  30.                                                 shift out 1-bit per clock rising edge
    8 m0 Z7 }1 b- `/ g0 ~+ S* ]
  31. Get_Byte                                Receives one byte using SO pin to receive and shift ' d& D. W; r- T% Z
  32.                                                 in 1-bit per clock falling edge6 B' f" F. c! B$ F2 w6 _
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    & G6 ]+ J- d& Y7 N! r% u" V4 q
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high, F% c0 [3 w0 w  a/ i. I! a+ U7 O
  35. CE_Low                                        Clears Chip Enable of the serial flash to low# ~( y/ z4 C) g7 i4 H0 g( \6 H: h
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    3 X: p5 {. U6 k3 M  V+ j- q( X
  37. Unhold                                        Unholds the serial flash; @3 v+ b7 ~6 ], s
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    2 x& H" |7 k: w3 t8 {- ?
  39. UnWP                                        Disables write protection pin
    7 V: v( i! z% Q

  40.   ?8 h% O( w  s2 P# G
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code$ S4 ?9 J- t) t+ O; ~% z4 N( |
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    + b% R0 b/ Z7 r8 m  ~" J+ [( m
  43. software which should reflect your hardware interfaced.          
    " h* c" H$ B7 `

  44. & W+ g( a& k$ v3 O- p' S; o( K

  45. 0 L- i1 H& D- B% A
  46. Device Operation Instruction functions:6 C& u4 V* W; U% ?8 l
  47. ; m1 m6 q. i% I( x! m% X: S
  48. Functions                                    Function
    / A  I( q: q" R
  49. ------------------------------------------------------------------" \0 M2 O8 w! Y3 E8 o
  50. Read_Status_Register        Reads the status register of the serial flash( C6 \3 b- S) [+ w+ F$ R- Q3 b# `& h
  51. EWSR                                        Enables the Write Status Register
    & ~3 h6 y% J0 P" g4 e' Y
  52. WRSR                                        Performs a write to the status register
    * }. O, |& V, j% V
  53. WREN                                        Write enables the serial flash
    . Z# P. b& s+ e8 |& X  O* k& H2 l, x
  54. WRDI                                        Write disables the serial flash1 K) S% `7 `- g2 G# y" t% O
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    2 ~6 B2 B: u3 ?3 X
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    ' F" D6 `8 O( L# Z; U: z- L! E. S  j
  57. Read_ID                                        Reads the manufacturer ID and device ID: S3 t6 s. G7 Q  e/ v
  58. Jedec_ID_Read                        Reads the Jedec ID
    2 [6 ]! N. z' i% m  ?2 j
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    % o; W& ?: J0 S5 ^1 D+ D
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)4 b6 v: t6 N/ I  n0 \, k7 a9 [
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    & `) T, v" k& X/ a
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)4 @) z6 R* P2 B$ R& |$ I0 n5 o
  63. Byte_Program                        Program one byte to the serial flash2 s) ]' w- x4 n( d4 f
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    8 @. t  {( o0 ?) {( }
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation8 ^; ^9 T7 Y; x/ f- o
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    4 `6 y! X  s$ A1 t& a3 N) ?, W1 J. A
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY9 ~# t) \( E+ S" k' f
  68. Chip_Erase                                Erases entire serial flash7 D, z# ^3 ~. M7 V
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash( f: A6 D; z. q! R3 m
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash6 t0 O6 v( T6 A5 K) n6 Q! s0 p
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash' W9 s( e' m# b; o6 _
  72. Wait_Busy                                Polls status register until busy bit is low) P+ U% M6 q7 s+ x8 I: h, h
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming% U8 `5 L" C4 i( }6 \# Y
  74. WREN_Check                                Checks to see if WEL is set3 Z# b* m# Y* ~. W6 t2 f
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set2 F. Y6 V! |' q. g

  76. 1 r. }+ w/ J- K5 l8 q* ~  I3 G

  77. ) v0 c9 J/ C' g

  78. ' q$ Q. G  z6 P0 |7 X4 q
  79.                                                                      
    . s% H' j: A2 J- n$ ~( U% |; a
  80. "C" LANGUAGE DRIVERS
    9 f( a2 S$ T# I3 _; I* J
  81. : @) e' h+ v1 F, d3 J" S
  82. /********************************************************************/
    3 o  @7 t: h+ ~) u/ B! g
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */6 q; D/ S" F6 w' p, i# v8 X
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    7 }, b, J+ p6 m- u& N" l
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    0 j8 [# _; o( S8 s# }+ e9 S$ J
  86. /*                                                                  */
    5 ^" B. W8 x  l, p
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    8 j# ^& v+ C( k. U. E. d
  88. /*                                                                  */1 J) Q$ e! h4 r
  89. /*                                                                                                                                        */
    ( d- p4 X- E! m0 d& P' M* M9 x2 [
  90. /********************************************************************/
    & Z$ P; G- }0 Y+ M9 W6 W

  91. 4 h5 j# z9 [/ S* }! i$ j, a# j
  92. #include <stdio.h>
    4 D' N8 h8 c) C! N
  93. #include <stdlib.h>" M2 U7 k" }& V. b
  94. 7 r+ v: \3 b7 n; z4 I% V
  95. /* Function Prototypes */
    9 h" D2 m" |+ T: V  B$ Y4 n. ^; v
  96. * o9 Q# ]4 x* L3 f" Y2 f
  97. void init();  m2 J* n- a; J9 O
  98. void Send_Byte(unsigned char out);
    ) V7 ]8 `9 K% Z3 i2 H, r+ W; y
  99. unsigned char Get_Byte();
    - v8 [, z9 G; |
  100. void Poll_SO();
    7 r0 A, g* S- q
  101. void CE_High();- ~+ ~8 R) b# @; x( l' m7 \
  102. void CE_Low();
    0 y* v8 {8 R- h( {
  103. void Hold_Low();8 {& o& x, G. Q3 s5 j3 p1 G% r
  104. void Unhold();
    $ b5 W  Z9 y( }' A
  105. void WP_Low();" Y& I4 @$ j4 F/ I. O
  106. void UnWP();) t7 S) y, h  T5 \+ O
  107. unsigned char Read_Status_Register();1 {6 j& G% E; a; ~2 ^' O8 Z6 P$ {
  108. void EWSR();% s! q# j7 W3 L5 b9 k/ O, f4 M5 i
  109. void WRSR(byte);) M9 Z, g' e0 k$ u' J& G
  110. void WREN();. L7 |0 B0 v/ Q. m
  111. void WRDI();- b) W4 k" L- b4 L
  112. void EBSY();
    4 ?/ l! ]" S5 b- F
  113. void DBSY();
    * h# a/ L8 d7 ^# d  v; U0 b
  114. unsigned char Read_ID(ID_addr);
    / z3 Z! G8 M; @
  115. unsigned long Jedec_ID_Read(); " O3 t5 A5 f/ q( f
  116. unsigned char Read(unsigned long Dst);
    ( l% @! f' Z# w$ f
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);( e( `$ e$ u" n5 P
  118. unsigned char HighSpeed_Read(unsigned long Dst); . s1 h; h& o4 k5 H# O- q$ W5 U! {
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    3 f/ Y" m$ m* W. q. T7 j/ o2 [- x$ Y
  120. void Byte_Program(unsigned long Dst, unsigned char byte);/ V; w3 B8 O/ l- Q4 z
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);9 ^8 ]0 L) F% ?  R' c: g4 p. L& R
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    7 F* E3 P3 c; {( E1 z) A+ G
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    1 ^5 [4 d9 N5 D6 o, j
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    . l4 g+ }5 d: l+ c
  125. void Chip_Erase();
    0 w6 O: `# r$ p9 W
  126. void Sector_Erase(unsigned long Dst);
    9 H6 l; g* W: ]: `
  127. void Block_Erase_32K(unsigned long Dst);
    & b7 H: ~1 {4 I: x4 r4 T
  128. void Block_Erase_64K(unsigned long Dst);; ]( G- z% p, j- e/ z$ H9 O& U( P& l
  129. void Wait_Busy();3 g2 o: I: [; Y  |
  130. void Wait_Busy_AAI();5 t0 f  Y# G1 Z7 a
  131. void WREN_Check();
    % f9 [: }4 ~7 w
  132. void WREN_AAI_Check();( g- w, t( h+ }/ s/ i

  133. ! g+ f' G# x9 t5 x3 Y2 ]! [% s
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    & X; _% K2 P, M7 ]
  135. 5 L# C  R( N' K
  136. unsigned char idata upper_128[128];                /* global array to store read data */2 I- |8 A  r+ F- g4 g: K
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    " r& g/ B; x; ?1 A* s8 b2 W
  138. - o7 }/ Z. J* W8 }- p3 R5 u0 x
  139. /************************************************************************/$ U2 ]9 @: ?# l, ?5 Z
  140. /* PROCEDURE: init                                                                                                                */
    4 v' j# u/ Y- Y2 V2 l
  141. /*                                                                                                                                                */- K+ l% T7 q6 z& S; f; R) i& |) A* `
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    4 e+ n! e# \6 ~; W" j& l
  143. /* setting up mode 0.                                                                                                        */
    9 x3 Y+ p) x$ T4 J: b
  144. /*                                                                                                                                                */# v# E; v' P1 u+ ^
  145. /* Input:                                                                                                                                */) w) w/ \0 r7 j2 _+ r3 w& W+ x6 ~5 Y
  146. /*                None                                                                                                                        */
      `# s6 p8 Q" h% t( a
  147. /*                                                                                                                                                */
    ) q4 n  H- M* k2 a
  148. /* Output:                                                                                                                                */
    * J$ @8 _+ g) d. {3 @0 D
  149. /*                SCK                                                                                                                                */
    + d1 }+ W- o9 L+ d
  150. /************************************************************************/8 H) M' w# x5 d6 w% `
  151. void init()4 M! |. V6 I0 b: u$ n2 V
  152. {& c9 C+ g/ f: G5 u
  153.         SCK = 0;        /* set clock to low initial state */
    * N4 b- {1 q8 e! S2 v9 R
  154. }. Z! Y$ I% T( ], x) Q4 ?$ m) ~

  155. " m8 \: n) m0 r* z+ ~  V
  156. /************************************************************************/
    $ H2 u0 V% P+ ^/ i. w
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    : \. s8 a# F( x6 F) d" a
  158. /*                                                                                                                                                */3 |& n  P3 n0 [4 D' p
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ; ]4 [$ r& ]/ Q4 w% v
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    $ C. z* \/ g0 |3 W! D+ o
  161. /*                                                                                                                                                *// S% D3 w2 e) r
  162. /* Input:                                                                                                                                */9 `+ [5 C# a2 M5 n+ b7 P: O+ y6 ^! [$ p
  163. /*                out                                                                                                                                */. W9 U. O5 G6 e  z
  164. /*                                                                                                                                                */; ]" @. ^( i: D/ B; [3 q/ ^
  165. /* Output:                                                                                                                                */6 c: F: {( M4 ~7 v8 ?! c2 u
  166. /*                SI                                                                                                                                */9 b- O' w" P; ~9 V) P+ {0 {0 k
  167. /************************************************************************/$ z: K( v* J3 `5 h" e6 H9 d/ Z
  168. void Send_Byte(unsigned char out)/ I/ i( y7 m& z
  169. {9 E: `( O* Z& n# ^: u  }% e
  170.        
    % Q& t: [3 O; T: |2 ~' u/ w
  171.         unsigned char i = 0;
    : k  u9 P9 b8 V
  172.         for (i = 0; i < 8; i++)
    ; g% x" J2 k* |; x1 q2 E
  173.         {
    % M- A% V! R% n! o
  174.                
    * N- x% G6 Q7 c0 v, `# }
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    $ ]2 H% A8 ]7 f" Q$ G
  176.                         SI = 1;
    8 u- W3 X/ v9 b7 U5 s
  177.                 else* @, x9 a3 ~6 _8 s" `1 z+ U4 @
  178.                         SI = 0;                                /* if not, set to low */
    2 r4 X- V" q/ D, N7 l
  179.                 SCK = 1;                                /* toggle clock high */
    9 P, I# T- g: @& F) v! M# C
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    # e) O" ~5 y& k: n" K
  181.                 SCK = 0;                                /* toggle clock low */+ K' ?1 g2 \+ s
  182.         }5 b5 V# F/ t7 X: r
  183. }
    ( k2 ^4 m: |" k& s

  184. 4 s! T- m( Z2 \+ W
  185. /************************************************************************/
    & M4 j1 U% K4 X  ~7 a/ A
  186. /* PROCEDURE: Get_Byte                                                                                                        */
      J1 W" }1 V& D$ K  y# E& }) r  j
  187. /*                                                                                                                                                */% l' `/ [- Q* j/ N7 P# ~4 ^2 H9 Q$ I
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */- l) |& m4 u/ M. ]  i5 U
  189. /* edge on the SO pin(LSB 1st).                                                                                        */& \; u& {) d: L7 a$ o1 D+ l- i9 v
  190. /*                                                                                                                                                */& F* g7 b6 g' ?5 V
  191. /* Input:                                                                                                                                */1 ]) t; E- x( g% l' B2 V# l
  192. /*                SO                                                                                                                                */& Z( c, |6 `, ]) ?9 y: P
  193. /*                                                                                                                                                */) D2 O7 J% M5 U2 S7 j
  194. /* Output:                                                                                                                                */
      F3 }/ c+ F% F, M7 s. p) p1 T
  195. /*                None                                                                                                                        */7 T* h- Y6 x& c# @
  196. /************************************************************************/
    - i0 b: u9 e4 D. J4 V
  197. unsigned char Get_Byte()# }6 k' p0 {0 ?) S2 }& M3 U! p
  198. {. F6 H& {: o  [; b
  199.         unsigned char i = 0, in = 0, temp = 0;8 N: B5 a% _# j# }# b2 ?2 w# `3 M
  200.         for (i = 0; i < 8; i++)
    ; U. x) a. o- N) U
  201.         {, M& T( D5 T0 {/ U0 D
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */3 W+ K9 w1 m# w; e" k
  203.                 temp = SO;                        /* save input */
      n0 I6 A" j' t
  204.                 SCK = 1;                        /* toggle clock high */
    8 j; I1 l, W+ G: _/ ^( R$ l
  205.                 if (temp == 1)                        /* check to see if bit is high */0 C0 O+ _  i" n: f2 u" P1 `0 b
  206.                         in = in | 0x01;                /* if high, make bit high */( b% ]/ J+ a$ s- Q/ u, u

  207. $ q  G- e  U. W# ]
  208.                 SCK = 0;                        /* toggle clock low */
    % k/ O4 y/ L& B2 u1 d0 [$ z
  209. 1 p; @& o+ ?- O: N* w
  210.         }( c# p; Z2 m( j. G
  211.         return in;! O+ K9 I$ C9 A+ e
  212. }+ w! ~  O% a8 ^# Y) Q/ s" w- {

  213. - N6 x  @+ C9 G9 H
  214. /************************************************************************/6 d* L- H& K% V% ?* w
  215. /* PROCEDURE: Poll_SO                                                                                                        */2 H8 J8 Y6 q; Z$ x
  216. /*                                                                                                                                                */
    # P# v9 P  I% T# e7 ~4 t
  217. /* This procedure polls for the SO line during AAI programming                  */
    1 x! {7 ?8 f: T6 r% N
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    % y# y2 i* z! x$ Z2 s6 c- K& n
  219. /* is completed                                                                                                                        */+ Y) m$ k2 F, j$ Y( B. O' i+ Z( y
  220. /*                                                                                                                                                */
    , L- J9 s* C5 G' R/ V: }" ]# n- x; E
  221. /* Input:                                                                                                                                */
    ; f. S3 R8 o2 e
  222. /*                SO                                                                                                                                */
    " k" }- b/ Q/ P3 \2 J8 T
  223. /*                                                                                                                                                *// k) I6 Y9 W6 g+ L
  224. /* Output:                                                                                                                                */
    $ E  t0 r& ~1 Y# W( Q
  225. /*                None                                                                                                                        */
    2 [6 z& o5 A; e1 W1 N
  226. /************************************************************************/
    - E0 |& O% \6 v
  227. void Poll_SO()" r9 G; z% W6 \5 m4 b3 a" L; N1 a
  228. {2 w$ r- M7 m% `5 G3 Y+ s8 E- T
  229.         unsigned char temp = 0;
    ; C: w" }5 {% {3 g% W7 W7 `  S" {
  230.         CE_Low();& o! T/ e' p$ j8 j: X) ?" G: d/ C
  231.     while (temp == 0x00)        /* waste time until not busy */
    ; J. a+ f( p. X7 K
  232.                 temp = SO;. l( s  x" m, p
  233.         CE_High();
    8 y7 v- p, p9 w9 {) {/ v1 b; W1 R
  234. }
    $ M  B* I9 g% O- a8 w/ Y) [
  235. 1 Z2 u+ \5 ~% x9 O% j+ _
  236. /************************************************************************// y: b2 J4 h2 g9 q/ i
  237. /* PROCEDURE: CE_High                                                                                                        */; {9 k# _3 Q. r# j( g
  238. /*                                                                                                                                                */) Z- A% m, R) L/ Q0 q
  239. /* This procedure set CE = High.                                                                                */
    . k. X6 B; r% ^' X1 P
  240. /*                                                                                                                                                */
    % z# k8 P- x6 R/ n  t7 h+ t0 j
  241. /* Input:                                                                                                                                */: C) y0 H; t& J3 _
  242. /*                None                                                                                                                        */
      J  b1 n, H/ d- T
  243. /*                                                                                                                                                */
    8 p9 X: a. L( W  r: H2 T: |# {
  244. /* Output:                                                                                                                                */
    2 q/ L+ p8 D3 a, Q! i+ M
  245. /*                CE                                                                                                                                */
    # f& g' j+ n, v+ u7 n
  246. /*                                                                                                                                                */
    / T, _8 m  ]; g# K0 C2 M  a( y/ d
  247. /************************************************************************/
    ( ?3 n! n! Y$ ^. R
  248. void CE_High() ) Y! r6 x- d$ |2 @- g3 D. T- u
  249. {& ~' t' [# x4 }# P) |
  250.         CE = 1;                                /* set CE high */) u% Q! v, @( F  `
  251. }
    * V. i( ~8 L' _2 @% g4 c) R

  252. 2 n' D5 q" j  ?; O  ]
  253. /************************************************************************/+ v5 z  A. n( M6 M# ?% n. ~
  254. /* PROCEDURE: CE_Low                                                                                                        */
    " t- L9 A& I8 ]1 X* r. d. K1 c6 W
  255. /*                                                                                                                                                */3 ?# Z6 |  y# [1 b& d
  256. /* This procedure drives the CE of the device to low.                                          */) \0 w# ~0 `. [' O7 H
  257. /*                                                                                                                                                */& G; L) B0 k' k7 L
  258. /* Input:                                                                                                                                */
    . B+ O3 q% N* c7 s9 s0 b
  259. /*                None                                                                                                                        */
    % x+ k9 }+ f3 P3 y8 o% l
  260. /*                                                                                                                                                */! D. y8 L2 G7 O- E, _5 w( W
  261. /* Output:                                                                                                                                */
    ' T5 v% G* Q* M3 s- S8 x3 g6 k+ l
  262. /*                CE                                                                                                                                */
    * h- Y) X2 i- n2 V" U: F3 f: v1 G
  263. /*                                                                                                                                                */7 x/ `; O8 v- ^4 Z6 O6 P8 d, B
  264. /************************************************************************/0 R; i* R$ Y- m4 }- D& E: d3 N9 ~
  265. void CE_Low() " R. j0 J/ |, B, e2 t( T* r
  266. {        ' X% `2 R% l* T( p
  267.         CE = 0;                                /* clear CE low */
    1 s: l7 i# u5 s0 z
  268. }' o7 }& i& l/ L9 e4 c
  269. , h: {8 P$ Z. o1 ]! i# d8 j
  270. /************************************************************************/
    " x+ |1 R) G% @: c1 O$ b
  271. /* PROCEDURE: Hold()                                                                                                        */6 d7 a0 D( z& m3 j& r$ u0 I
  272. /*                                                                                                                                                */& k* W+ F2 T* E1 r+ `' c. x, t* m
  273. /* This procedure clears the Hold pin to low.                                                        */
    ) L2 g; `/ A* |  {& \$ E- S
  274. /*                                                                                                                                                */# _2 f: @+ }, m# Z  B  K/ L
  275. /* Input:                                                                                                                                */6 n) [: `1 K2 m
  276. /*                None                                                                                                                        */3 ?9 ?5 ^& K3 }  {; c" F
  277. /*                                                                                                                                                */
    9 s9 N0 m: _$ U3 @/ K
  278. /* Output:                                                                                                                                */
    1 q; q1 T$ q* K7 q% c7 w. h
  279. /*                Hold                                                                                                                        *// y9 H. R1 e- u/ p7 Q0 x& a! H
  280. /************************************************************************/
    % B: I0 b* J. L  }
  281. void Hold_Low()
    % ~3 R. U6 c- d$ m" f- C
  282. {
    ; i8 @5 W# Y. {& T+ I0 r2 u" T) Y
  283.         Hold = 0;                        /* clear Hold pin */  B' S( a# F6 g
  284. }
    & G" I9 D' X% @# F
  285. 1 R- h) U4 c+ @* @
  286. /************************************************************************/6 N6 c% A' N( f+ V: l
  287. /* PROCEDURE: Unhold()                                                                                                        */; @0 P" z0 D, j
  288. /*                                                                                                                                                */$ w) i0 v# h) r- v5 p9 }8 ]
  289. /* This procedure sets the Hold pin to high.                                                        */
    ) }6 n/ R8 G/ s6 l( i
  290. /*                                                                                                                                                */  Q8 r* Q; ~3 A: _0 c% c
  291. /* Input:                                                                                                                                */* M$ \! b- j+ Q3 |$ Y
  292. /*                None                                                                                                                        */: [8 J( y: H" Y4 _/ ?
  293. /*                                                                                                                                                */
    1 z0 W' l% a4 u+ A6 K
  294. /* Output:                                                                                                                                */3 s$ T4 K& @7 u( c% S3 O2 D3 O6 v
  295. /*                Hold                                                                                                                        */
    7 M' S% W0 u' H5 V- F
  296. /************************************************************************/" Z& m( \5 p& {* Z) b; n
  297. void Unhold()
    / J: b" m  x: J  T
  298. {
    $ b' d# o7 C6 S" _. o0 Y
  299.         Hold = 1;                        /* set Hold pin */
    2 C* S6 \$ Z9 b) Z1 ]5 u$ g
  300. }+ H% v9 Y- |* Q8 q/ H

  301. ) o% h7 z& U. a7 Y' t; G8 h, N  B
  302. /************************************************************************/8 v* m- s0 ?# Q& W
  303. /* PROCEDURE: WP()                                                                                                                */$ P' r" t/ A, ]$ P$ s# z
  304. /*                                                                                                                                                */0 s4 P5 t8 m# b2 t4 c4 `' i5 o
  305. /* This procedure clears the WP pin to low.                                                                */* ?+ h% U( |  i/ a  B4 ^
  306. /*                                                                                                                                                */
    4 Q4 U, L/ ^5 x5 R: l" H$ z# a' `
  307. /* Input:                                                                                                                                */
    " p! k% S1 M+ X4 C1 p: g* u
  308. /*                None                                                                                                                        */; ^3 W# n' e4 R+ c! p( W0 \7 `
  309. /*                                                                                                                                                */: w5 i! l6 _8 @2 x2 V
  310. /* Output:                                                                                                                                */6 ?( ^3 c2 X( V: {% ~2 w6 w
  311. /*                WP                                                                                                                                */
    + r. _8 y) l3 t0 `- `% y- g! j
  312. /************************************************************************/* u3 q5 D; ~( l& [
  313. void WP_Low()
    . _0 e8 ?$ H% T8 I0 Y
  314. {/ B% I$ ~. |4 V# P0 U. G2 D
  315.         WP = 0;                                /* clear WP pin */4 _. o9 H, v. N$ Q7 N1 q8 I  }' D% K) _
  316. }
    ! b1 ^( S; P4 Z( [

  317. 6 M0 R& ]9 ]" \. S, r) I
  318. /************************************************************************/* U, C7 y& b* `" z2 U
  319. /* PROCEDURE: UnWP()                                                                                                        */
    ( D/ L% x" k4 l' w
  320. /*                                                                                                                                                */
    3 R) M4 c( Y7 @/ n+ K+ V- G. t# T
  321. /* This procedure sets the WP pin to high.                                                                */
    , s  H- d# Z2 c+ ?8 P7 }0 Y8 M. @
  322. /*                                                                                                                                                */1 O" X3 E; o/ t
  323. /* Input:                                                                                                                                */
    . \6 r6 [! [& A, l0 s
  324. /*                None                                                                                                                        */. U) ], [9 p7 h! r% n5 E
  325. /*                                                                                                                                                */
    5 M: I2 g; k3 U  X7 j1 g8 ^7 z
  326. /* Output:                                                                                                                                */, z( H. l) j% u2 O6 c( |
  327. /*                WP                                                                                                                                */
    6 n1 K! X! N+ u0 \* t, Q6 K
  328. /************************************************************************/# O  \, I1 u$ u: W
  329. void UnWP()8 Z8 [3 m8 S% M
  330. {
    0 T2 h9 e7 K3 Z- U! X
  331.         WP = 1;                                /* set WP pin */- y7 B; N6 @3 K
  332. }3 [4 h7 b. m0 {, r2 s" @$ A! i

  333. + x; \1 q" C1 D3 C* H
  334. /************************************************************************/
    8 I3 E) O  p1 x( \, O6 V. T7 |
  335. /* PROCEDURE: Read_Status_Register                                                                                */* d6 N- z7 {0 O* x
  336. /*                                                                                                                                                */* @' h( M1 B: x* k" w! M& [
  337. /* This procedure read the status register and returns the byte.                */8 z& F7 `4 R+ [
  338. /*                                                                                                                                                */0 M- \+ y4 k. K: X% `9 u
  339. /* Input:                                                                                                                                */
    6 |) h  V2 F* x7 I$ W
  340. /*                None                                                                                                                        */" e- R& Y! u' \
  341. /*                                                                                                                                                */$ Z! w4 w, }& e* v% _# X
  342. /* Returns:                                                                                                                                */
    4 x; t1 v( R1 q0 v, }) S; t# u  k+ V
  343. /*                byte                                                                                                                        */$ Q0 T/ Y0 w. T7 i
  344. /************************************************************************/
    - \, g; q+ ^# R
  345. unsigned char Read_Status_Register()
    2 r8 z$ {; E" }, l7 B' \
  346. {: g) g& S) K! C. H3 k+ P
  347.         unsigned char byte = 0;
    - V1 Z& ~% T% x& v' e1 o/ b
  348.         CE_Low();                                /* enable device */3 _1 b$ w5 A$ X6 ]( V; D
  349.         Send_Byte(0x05);                /* send RDSR command */
    % s. n: H' ~9 \/ T' I, i
  350.         byte = Get_Byte();                /* receive byte */
    . D% Z& Z! O! u  j
  351.         CE_High();                                /* disable device */
      X% p6 \" ^+ a- u4 T$ \* \& h
  352.         return byte;
    5 u8 A& `( W7 A& y; }4 C
  353. }3 N! l! @0 Q  C6 \
  354. 4 `9 H1 V) O3 n  B2 w+ g
  355. /************************************************************************/+ J2 ^" l. t8 Z6 W2 k8 V* l5 b
  356. /* PROCEDURE: EWSR                                                                                                                */
    / \8 \; R" D4 |1 l- r+ q) s4 O
  357. /*                                                                                                                                                */
    $ K) B. e% N; U) B* h
  358. /* This procedure Enables Write Status Register.                                                  */& N" J5 H- t- P9 L) D5 u
  359. /*                                                                                                                                                */6 _& Z( N0 S8 X( B4 ~% D, N
  360. /* Input:                                                                                                                                */
    3 F* X6 T! D6 O1 E, B. f: ?
  361. /*                None                                                                                                                        */
    + R1 k8 r+ k$ G! i- ]
  362. /*                                                                                                                                                */( M! ]- w) K! m0 Z3 r5 [2 L
  363. /* Returns:                                                                                                                                */. [. l! g' I. o4 ?4 I  W; i
  364. /*                Nothing                                                                                                                        */; ^8 _, n* G) Y
  365. /************************************************************************/
    ) h, p; ~" B; h0 v8 `
  366. void EWSR()
    ( N/ o/ W7 V0 d) n% q9 j* U- g" e
  367. {
    5 [; m9 s# Z7 L2 N. H
  368.         CE_Low();                                /* enable device */# c+ a/ A+ g# b! L
  369.         Send_Byte(0x50);                /* enable writing to the status register */# Y8 G- K% l0 n* M
  370.         CE_High();                                /* disable device */
    4 p; d9 _5 W' Z0 x% V
  371. }
    1 j. V; A& K" g9 G1 c5 ^! a: D  k

  372. 8 d- L# g% N' O) {
  373. /************************************************************************/% V' _" ^0 F6 c8 `" @5 c, D7 q
  374. /* PROCEDURE: WRSR                                                                                                                */
    3 z& @0 A+ v, G( o
  375. /*                                                                                                                                                */
    : B* E1 V+ o( r' D3 f/ F6 P0 H: D
  376. /* This procedure writes a byte to the Status Register.                                        */* ~4 ^, m4 w5 H2 K, Q' [
  377. /*                                                                                                                                                */
    " y0 h4 L3 G7 ^" S
  378. /* Input:                                                                                                                                */
      [1 z: i( o$ z" H$ y
  379. /*                byte                                                                                                                        */
    ' g$ `' l' M+ o4 d+ [3 h/ I) o
  380. /*                                                                                                                                                */
    1 ^/ i: \  ?; z' ?- A  s- y$ h; T
  381. /* Returns:                                                                                                                                */
    5 b; b8 z  Z; P' M0 Q' D& F
  382. /*                Nothing                                                                                                                        */3 ]6 J# ?" I; d- E4 B  {
  383. /************************************************************************/3 B+ v0 W8 j1 Y5 B7 X
  384. void WRSR(byte)+ }, Q, x" E; X' d5 @9 O1 G
  385. {; q) S: Y0 L! l
  386.         CE_Low();                                /* enable device */
    ; k1 \* |. d+ a# {
  387.         Send_Byte(0x01);                /* select write to status register */
    7 a) e8 G& }/ S6 M% ?0 X( Z
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ! s9 l7 {7 f; S8 m; E+ m
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    / O% f' I' @8 O, f0 P
  390.         CE_High();                                /* disable the device */
    , Z4 U1 F/ m$ W6 Z$ c
  391. }
    7 r4 n, O9 y. f9 s1 U3 L- r

  392. ) H7 v  X# ?8 M; L% s6 R5 z( r; D$ O
  393. /************************************************************************/
    " ^3 F0 a9 h1 U( D% H  M% G
  394. /* PROCEDURE: WREN                                                                                                                */
    ) T" D$ i: g! S+ \  O2 U( l
  395. /*                                                                                                                                                */
    5 [6 b6 g2 X; o6 s+ V; ~
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    # A9 W  ?1 C- H7 e* A4 ^
  397. /* to Enables Write Status Register.                                                                        */0 K' S0 B) v7 J4 W6 p0 x
  398. /*                                                                                                                                                */- s5 j8 z" `5 v; Q3 W, h+ P
  399. /* Input:                                                                                                                                */
    1 ]- T% G5 T" \8 ]
  400. /*                None                                                                                                                        */! @* m! b2 S) n7 f( x; m
  401. /*                                                                                                                                                */! G1 @6 J4 D  Y0 @" h# u6 ~
  402. /* Returns:                                                                                                                                */7 o; O) Z% i6 v
  403. /*                Nothing                                                                                                                        */" D/ P5 k7 a5 d
  404. /************************************************************************/
    " B0 ?/ {$ r' j
  405. void WREN()
    % t) p8 u4 h9 o8 f! `4 |
  406. {
    3 ^1 ~6 a. Y8 ~, g5 ]
  407.         CE_Low();                                /* enable device */6 v" Y; ]' k+ d7 ^+ T0 s
  408.         Send_Byte(0x06);                /* send WREN command */% p' U9 C  s* }! w
  409.         CE_High();                                /* disable device */7 M. v" X' [2 E, q/ O3 y! U' z* ^
  410. }; m# O4 @& d, Z& e+ g/ G
  411.   Q% O  L/ D% Z
  412. /************************************************************************/
    3 Q3 o" Y. ?# x$ }! B
  413. /* PROCEDURE: WRDI                                                                                                                */
    / {, T+ |# ]) y9 Y/ }6 o% Z
  414. /*                                                                                                                                                */' o( y/ [$ h  w( k9 y/ B# t8 W
  415. /* This procedure disables the Write Enable Latch.                                                */
    * T4 z8 m1 G( E
  416. /*                                                                                                                                                */
    1 o, O/ Y" k* u
  417. /* Input:                                                                                                                                */
    - L) F0 y3 v/ ]0 _; z$ K
  418. /*                None                                                                                                                        */0 a5 a/ K% _5 l, U# o% f' w
  419. /*                                                                                                                                                */, h+ H) m/ t. G! ^+ w1 v
  420. /* Returns:                                                                                                                                */
    . r  I# u6 I& ^: F
  421. /*                Nothing                                                                                                                        */
    / X. l; Q5 S3 n& ^1 D
  422. /************************************************************************/) T) _6 m$ n9 W" n
  423. void WRDI()+ J( `! k' u3 j3 \. i0 |8 `
  424. {
    : ]4 f& p% _" E. p) p* Z4 Y
  425.         CE_Low();                                /* enable device */
    4 E' d+ g) O/ X) I! {
  426.         Send_Byte(0x04);                /* send WRDI command */
    % y3 U4 ~/ e9 i) K
  427.         CE_High();                                /* disable device */
    8 \7 z) W1 Y, A* p; A* R
  428. }
    ) b* O/ n. h2 d0 r$ J

  429. $ E; P. n/ ~3 o% S0 i. U; i! |6 J/ J! A
  430. /************************************************************************/$ B, k/ ^2 k- p. s, F
  431. /* PROCEDURE: EBSY                                                                                                                */
    5 c0 _( i: z# w: f! I8 l
  432. /*                                                                                                                                                */
    : Y4 ~0 x# `3 i
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */# F% x7 l4 V. s; F  J* o
  434. /* programming.                                                                                                                        */" o/ Z; w: Y1 Z6 W0 y- m& Z8 Z
  435. /*                                                                                                                                                */
    , n- H& x% [6 j7 l2 r% {
  436. /* Input:                                                                                                                                */% @) H2 f" V( y9 I) K0 p. X  r; z
  437. /*                None                                                                                                                        */
    ! ^  N; U4 e% @" K5 j# V
  438. /*                                                                                                                                                */1 m- ~1 L% y* C" Y& s1 [2 U
  439. /* Returns:                                                                                                                                */3 ^7 M7 r6 Z. f- E2 _* P6 ]
  440. /*                Nothing                                                                                                                        */
    # l7 y0 b- F+ p; r6 c: ^. n
  441. /************************************************************************/
    2 l9 f; p4 M' F- A& t3 F, n
  442. void EBSY()
    & I* K+ h5 W" U+ I  U& Z0 I
  443. {
    8 U$ ^2 v, Q: e. X: Y. k0 ^
  444.         CE_Low();                                /* enable device */9 Q$ s9 ?1 v3 f- x
  445.         Send_Byte(0x70);                /* send EBSY command */$ R7 T0 A5 r" t2 ~/ \* H8 R$ f* k  T
  446.         CE_High();                                /* disable device */
    . d4 I$ a5 \( a+ B
  447. }
    7 Z9 W9 K, b& v& B% I, p

  448. 0 Z; x6 S. _% ?) v
  449. /************************************************************************/6 E- x: \: O+ r* i
  450. /* PROCEDURE: DBSY                                                                                                                */: F2 ?( b! {' Z# m8 N2 e8 L) H
  451. /*                                                                                                                                                */
    ! Y3 I' `7 ]" N, U$ g" c* J
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */1 X- R2 e8 y  }: t$ G* b9 v  W. x
  453. /* programming.                                                                                                                        */9 t4 p2 q8 |8 c$ e. `
  454. /*                                                                                                                                                */( I5 ^' b- t5 y/ y6 E- }6 A' k
  455. /* Input:                                                                                                                                */
    2 k$ @; R' m$ b& |) R
  456. /*                None                                                                                                                        */
    - z8 ~% h+ ?- l3 Q6 v
  457. /*                                                                                                                                                */
    ( e! l8 e. R+ W
  458. /* Returns:                                                                                                                                */3 k5 u( ]2 x- ?- P
  459. /*                Nothing                                                                                                                        */
    3 K* O: j" n+ p3 E7 c- b
  460. /************************************************************************/
    7 P! n! y5 k) F0 s; e
  461. void DBSY()3 N1 Y8 }+ q5 a& K# @+ K3 u' n
  462. {& D9 F3 \+ r7 J# J0 z
  463.         CE_Low();                                /* enable device */* s3 j" r; R: S) g+ k/ K" }/ s
  464.         Send_Byte(0x80);                /* send DBSY command */8 S+ `; S9 m- G4 Z8 \
  465.         CE_High();                                /* disable device */* S# b6 H- ]5 r) O/ N& ^$ n: E' h
  466. }0 X6 X9 m* `  j3 z5 j

  467. & Z  r& D) j& f) s1 ]- {% w. j
  468. /************************************************************************/( w$ C9 ]; x# @+ b
  469. /* PROCEDURE: Read_ID                                                                                                        */3 m3 M4 l- j9 N5 e
  470. /*                                                                                                                                                */
    ; C/ r& r, \+ u
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    7 P5 |. t4 F; M/ M# D
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    4 G( ]# s/ ]8 Q- `
  473. /* It is up to the user to give the last byte ID_addr to determine      */" a9 i# M3 U" H! k
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
      V( D. S! D! T
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ( z. P5 {4 s) n- m
  476. /* variable byte.                                                                                                                */6 x( H0 O8 \! l% A4 }
  477. /*                                                                                                                                                */9 }: M. C# m( i  X; F* q+ O& W* [
  478. /* Input:                                                                                                                                */
    * j, m$ a7 a$ W8 _- x2 L: U4 r5 i
  479. /*                ID_addr                                                                                                                        */
    ' D! ~8 n# q; U, u
  480. /*                                                                                                                                                */- O: X) f# \" C6 o
  481. /* Returns:                                                                                                                                */& @* \+ S) F5 Q! i6 L
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    0 @0 o! ^6 O1 S0 p0 A3 M
  483. /*                                                                                                                                                */
    9 w% p; E8 i2 {
  484. /************************************************************************/3 C; T1 ?6 N5 V& W4 s+ c6 ^  [
  485. unsigned char Read_ID(ID_addr): R" j7 x8 L  t6 w, |2 v
  486. {
    6 X1 x. v& \: Y
  487.         unsigned char byte;
      G7 I' ~, l* m
  488.         CE_Low();                                /* enable device */4 {/ g" t8 |% ?, d
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    ( M7 K, o* W" t
  490.     Send_Byte(0x00);                /* send address */
    + C  y8 D4 p3 J( P4 S. w& X4 _4 l/ I
  491.         Send_Byte(0x00);                /* send address */
    & R! o8 D3 p/ P6 k$ g1 G
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */( Z. r: E) h3 f5 G4 ?
  493.         byte = Get_Byte();                /* receive byte */! R8 K3 W7 ~3 |
  494.         CE_High();                                /* disable device */# U8 J* g: [8 Q3 F; u* s/ y
  495.         return byte;
    - x# Y+ v' r% j4 [; k; q5 h  Y. L
  496. }- q, R6 {  h3 d  Y

  497. " R5 k$ o7 H0 E6 J; X
  498. /************************************************************************/$ n3 \. k) [1 I4 r4 H7 p; m
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ; D: f5 ~8 ?/ H7 z( N0 M$ l
  500. /*                                                                                                                                                */7 h* @; ^6 m) C8 W8 r
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    % }9 f6 }$ m' @# t
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */3 G% d5 J2 [0 i- K# P) T
  503. /* Please see the product datasheet for details.                                                  */! S  R7 m7 \& f: c* O
  504. /*                                                                                                                                                */; G1 G' ~' k) ]! O5 ?4 K
  505. /* Input:                                                                                                                                */
    - B1 W! ?! U( B3 |
  506. /*                None                                                                                                                        */. q# `4 G4 s1 B' k2 n; I
  507. /*                                                                                                                                                */
    2 |6 v2 M' F4 a  I7 \
  508. /* Returns:                                                                                                                                */
    % ]* \$ y- `! u4 c0 y" U  R
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */# V5 }9 X! n; \  `
  510. /*                 and Device ID (8Eh)                                                                                        */1 `5 F0 k) T4 d) e
  511. /*                                                                                                                                                */
    - k0 |8 U7 Q  @$ t/ M4 g& o1 F
  512. /************************************************************************/
    - b4 U& I0 v( l: g7 _% q
  513. unsigned long Jedec_ID_Read() 8 T# @7 f1 [1 O* j; o- G
  514. {
    ; b/ g6 T, N# D/ [: J  a
  515.         unsigned long temp;+ v& i( I2 m: f0 {4 J+ ^# L3 e
  516.        
    ' e' K5 `: x5 L5 S4 P2 v
  517.         temp = 0;
    ! ^- c5 p7 u/ T

  518. 6 p; Z% m# o: \6 A& r9 _
  519.         CE_Low();                                        /* enable device */4 ?4 ~5 f4 q* ?2 s
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */2 E" h9 k) E: K4 I# z( S$ R2 w
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */0 A" ~5 F$ P6 e1 G6 R3 R6 W
  522.         temp = (temp | Get_Byte()) << 8;       
    * j7 e/ c1 K7 x9 L1 l! V' W
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */0 J6 G, A1 o" ^* [" H/ J+ v5 U  n1 k
  524.         CE_High();                                                        /* disable device */1 t+ J1 x: {/ h* f% a+ d; [: @

  525. " h/ n3 T; b2 r* |
  526.         return temp;
    8 u& m7 @  W& `7 |
  527. }+ D. |6 W4 Z) e, z# _, S

  528. % i; r/ G  z/ g6 }/ Q
  529. /************************************************************************/0 ?. D1 Y0 l  `, t! T2 `( `, {7 q
  530. /* PROCEDURE:        Read                                                                                                        */
    ( @! e' [; X( h- o& A5 u8 s
  531. /*                                                                                                                                                */               
    # ^, j  s5 ^! Z$ Q- f, O8 y4 G' D
  532. /* This procedure reads one address of the device.  It will return the         */
    ; v6 }: C1 \; y- d" b' ~
  533. /* byte read in variable byte.                                                                                        */
    % d% S( ^7 A8 Y/ k8 j7 W+ [% m4 D% @- ^0 Z
  534. /*                                                                                                                                                */' X0 [1 }6 t3 ~# |9 m3 T
  535. /*                                                                                                                                                */: w' q9 F; c& s" s
  536. /*                                                                                                                                                */
    # K5 c/ R& l. W2 P. m5 G/ S& h& e
  537. /* Input:                                                                                                                                */
    5 a& g$ C- F) r! u5 X; [! K
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
      J) C9 t7 m4 Z! M. q  K
  539. /*                                                                                                                                      */
    # Q) y+ |* z; G/ {. p% t
  540. /*                                                                                                                                                */1 X3 O6 h$ F9 w% }5 U
  541. /* Returns:                                                                                                                                */
    " @" g* l  c+ T4 M0 w5 `. ~# B
  542. /*                byte                                                                                                                        */
    ( B# U0 G# n8 b
  543. /*                                                                                                                                                */
    " {# C( H1 k5 n/ x2 f
  544. /************************************************************************/
    & p$ ?, [1 ?9 F
  545. unsigned char Read(unsigned long Dst) ! d1 c( b) {8 a  Q
  546. {
    ) h/ W$ W1 Q; H( l# c4 \5 \$ d
  547.         unsigned char byte = 0;        8 X1 {+ J- e; w' |' R! n6 Q

  548. / ~* J7 b, ]' a# J
  549.         CE_Low();                                /* enable device */* H/ ?, g; @9 _7 S/ O& A7 ~$ f" X, W
  550.         Send_Byte(0x03);                 /* read command */
    & {8 C) O2 Z) q9 r3 d3 I
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */& h. i5 R9 I. M0 i* w- G1 Z& k
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 R8 u; s6 N. {: |3 H! Y
  553.         Send_Byte(Dst & 0xFF);
    0 Q0 g+ G& D$ N! S& d
  554.         byte = Get_Byte();
    1 b( n& X7 E. J# j* L. d8 Y0 e
  555.         CE_High();                                /* disable device */
    7 }' u! o. O$ l
  556.         return byte;                        /* return one byte read */2 h8 V! f/ r% [0 V4 M
  557. }
    2 r% H" `3 k3 e4 K! E
  558. 6 \7 j/ B( R2 P" Y( v
  559. /************************************************************************/* s% P( U# o: C! S5 l# d# |' M  |
  560. /* PROCEDURE:        Read_Cont                                                                                                */! x8 h- i+ }/ V- O* U1 w
  561. /*                                                                                                                                                */                ' L: H( o" [8 z
  562. /* This procedure reads multiple addresses of the device and stores                */$ E3 A+ i& x* W$ u6 c
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    . ~4 T) ]# F( W  x; ^# Q
  564. /*                                                                                                                                                */
    + d( i# R8 W+ R$ B
  565. /* Input:                                                                                                                                */4 b+ ~1 m1 l" I$ {7 j/ B
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* N7 W+ Y% _" f0 E0 T6 @7 c
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */$ E( K" W# _( A% B' ~
  568. /*                                                                                                                                                */
    - d/ ]* A2 F( ^% }
  569. /* Returns:                                                                                                                                */
    ' U1 y2 y& ?* A8 p
  570. /*                Nothing                                                                                                                        */
    # z( G" m5 W) a; [% k
  571. /*                                                                                                                                                *// O' j) i+ ~6 {4 ]; z4 Q
  572. /************************************************************************/
    . i6 k% [7 b1 j% @# w: q/ z
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)( {9 j. `( S: r, _7 m% j) @% M
  574. {+ A" H/ f; A9 ^' T' W" X  ^
  575.         unsigned long i = 0;
    8 ~, h. H% G; E1 V& |8 _. a9 }
  576.         CE_Low();                                        /* enable device */! a* S3 r; W1 Y1 x
  577.         Send_Byte(0x03);                         /* read command */
      g4 t, `7 m9 U8 ~: @/ ^7 g$ ]. s
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    5 D. a4 d  y& @5 E
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    9 h6 `* z, ]3 Y4 C$ e
  580.         Send_Byte(Dst & 0xFF);# Y9 T4 X: J5 c2 c8 z. l2 f" m
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    - B; ?( p/ X3 F( R; b: N
  582.         {; S" r4 [) z$ F) c8 u4 i+ Z( z& D& b
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    9 a, y7 ?9 c- W6 ?0 J' d
  584.         }
    / g$ v: q8 s6 w& w  W6 j4 ?
  585.         CE_High();                                        /* disable device */
    % Z; p7 }9 r& Z
  586. + x2 h+ w# o0 r. b2 l% D6 k0 G
  587. }; ?; Y$ b1 E4 ~: h* H
  588. 1 Z3 w* G* T3 C% y
  589. /************************************************************************// F. j( m) j3 _( p: c+ w+ }% k
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    8 D( p) q8 L" u
  591. /*                                                                                                                                                */               
    1 m# a' i9 U$ I- t( ?
  592. /* This procedure reads one address of the device.  It will return the         */0 a% A: f, p8 @: Y
  593. /* byte read in variable byte.                                                                                        */- ^! E& o7 h2 U2 P9 |2 k4 k
  594. /*                                                                                                                                                */
    ! O) m, q6 t( [
  595. /*                                                                                                                                                */# D" G* t5 W# R% e) [) s
  596. /*                                                                                                                                                */
    4 s1 L5 S! h+ r5 F! j- Y! }$ q
  597. /* Input:                                                                                                                                */. }9 c) W! V3 s4 P4 X6 _$ H; `( I
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% J6 L$ e" t$ Q$ B& l
  599. /*                                                                                                                                      */
    , C- |1 s4 Z3 |3 a+ s
  600. /*                                                                                                                                                */
    4 ]0 q( M  h, @
  601. /* Returns:                                                                                                                                */+ G  y' _' ^4 E3 H
  602. /*                byte                                                                                                                        */0 a% i, C; ^0 l/ N" Q2 @
  603. /*                                                                                                                                                */
    ( A; x+ O$ ?$ `9 O& B% F, {* Z3 `
  604. /************************************************************************/7 I0 _! c$ o& {, J
  605. unsigned char HighSpeed_Read(unsigned long Dst) / O" w% K  J, z* m) t% ~- t
  606. {$ P2 C; H( J- p! k& f8 j/ g9 G8 ~4 ]
  607.         unsigned char byte = 0;        3 F$ C9 {' Y2 k/ U' _+ r! Y; T6 t5 V
  608. # i1 |/ ?% a7 h" p8 ~
  609.         CE_Low();                                /* enable device */4 [0 j$ O7 a7 @# o
  610.         Send_Byte(0x0B);                 /* read command */- O. V: f" a) U6 z
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ) Y/ N- N" i- f( e8 T! L, U4 m
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
      \0 H  j( q4 _  P
  613.         Send_Byte(Dst & 0xFF);5 C1 s% k0 l7 g1 D+ f3 S9 _4 u
  614.         Send_Byte(0xFF);                /*dummy byte*/
    ! `- S$ S( O1 o* @6 o3 o
  615.         byte = Get_Byte();
    # e% S+ ~2 E  y; j. O0 \
  616.         CE_High();                                /* disable device */: R( k; `+ _$ d/ p; u* [
  617.         return byte;                        /* return one byte read */; Z; N3 n: d6 b+ V: P
  618. }$ O' \  t) s6 n* c& v

  619.   ^" g1 G! _' f  a7 A
  620. /************************************************************************/9 G9 o; g* h* L* `
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    $ B6 v0 h5 k7 t: a; M0 I
  622. /*                                                                                                                                                */                " z# ~1 M. m% m! h6 r& Y" P0 r
  623. /* This procedure reads multiple addresses of the device and stores                */
    0 n% p4 i( C( C' l) p- G
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ( F0 l  ?$ A& @) A& _
  625. /*                                                                                                                                                */4 V& U3 X# Y# s* T
  626. /* Input:                                                                                                                                */
    2 i$ E' m$ V/ V- B# |4 K
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 l' d; G) L" `
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    9 U) ^4 E# s8 b- F5 i
  629. /*                                                                                                                                                */$ A9 k. z! Y  m3 o2 q
  630. /* Returns:                                                                                                                                */
    8 [+ Q4 n( x) F
  631. /*                Nothing                                                                                                                        */
    ) K! T8 I$ J2 r" V+ \  ?
  632. /*                                                                                                                                                */
    ) L: e' L- F8 [0 W. X6 Q# t
  633. /************************************************************************/% {! k, Z/ m) e8 i, `: {3 j
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    . n. s( F3 \' J' v1 E
  635. {" |1 |9 h: w! U. k. Z2 f0 [% s. G
  636.         unsigned long i = 0;% y/ L' b/ p6 k
  637.         CE_Low();                                        /* enable device */
    % {  C7 n' o6 C0 c% g" w
  638.         Send_Byte(0x0B);                         /* read command */5 W. U6 e! s* Q; g# N$ ?8 t* I
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 m" A0 I" V$ |  e+ f  R
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 r* j1 ]- Q2 o' W; U
  641.         Send_Byte(Dst & 0xFF);
    0 _6 ^. w# u5 ~* j3 i3 A
  642.         Send_Byte(0xFF);                        /*dummy byte*/2 }; |/ M% p7 z; K
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */4 }4 }0 ^) b9 g0 `. R
  644.         {" [- U4 E2 }6 [
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ) y- ]$ p% G- _1 L1 }
  646.         }
    . R7 m* O+ u' E) S( `+ G- j
  647.         CE_High();                                /* disable device */
    * I. B# u( o( g3 r, A, n5 R" U; [
  648. }
    $ u  ]: @8 ], K9 L+ {* g# I

  649. ; O/ t9 m7 m! k* l3 X$ q; A2 H
  650. /************************************************************************/: n' N" U6 x- s- K! B0 k
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    6 }5 \. v' x) l6 f7 W& M. h8 U
  652. /*                                                                                                                                                */# {; y/ s8 M4 d
  653. /* This procedure programs one address of the device.                                        */
    ( z1 }4 G* \! X- |
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 `$ Y$ {! i! n: Y* e$ V' x% a
  655. /* block protected.                                                                                                                */
    ) V& r  r) j/ m( D- g2 J# P' j+ i
  656. /*                                                                                                                                                */
    1 B- D* {* M- z1 B
  657. /*                                                                                                                                                */; }4 H* `: [6 N" o& X
  658. /*                                                                                                                                                */
      ?- g; ^, J  ]* M1 k
  659. /* Input:                                                                                                                                */
    0 m  g1 i# O' {1 L' e
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 D6 ]" k* q$ |0 x) j8 N& a
  661. /*                byte:                byte to be programmed                                                                */
    2 c  {* ^8 E8 o) @
  662. /*                                                                                                                                      */5 e" W# a! B* l7 c" p. }& Q
  663. /*                                                                                                                                                */* j( I1 j, X6 S9 r
  664. /* Returns:                                                                                                                                */
    5 Y( [! s3 c. u, I
  665. /*                Nothing                                                                                                                        */5 l4 ?) C% ?/ Y' t" Z
  666. /*                                                                                                                                                */
    3 j2 A$ g+ M, s6 u, C! N
  667. /************************************************************************/) [- t8 x3 ~% h" ^6 e; b1 c; A1 t
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    : s/ T4 u0 K6 A
  669. {
    ( K' E0 ^$ x1 j% S+ J8 P
  670.         CE_Low();                                        /* enable device */5 C9 k0 Y: X6 P: n7 L
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    , V3 Z+ u# ?5 B) A0 d
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */0 G& K" Z' a5 J3 j, H1 g2 N( o5 t7 y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));; o: s6 J0 s8 b3 b
  674.         Send_Byte(Dst & 0xFF);
    6 H8 \1 i. t: r( @
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    . o: u3 F. l  n- t
  676.         CE_High();                                        /* disable device */
    1 y% C/ m1 @, |$ F' }
  677. }
    4 [! D& k# j! K! H& p. I
  678. # U: _# P6 _) ^' P( s
  679. /************************************************************************/! _3 \# S, A- B: o9 `
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */" F$ [5 c4 M8 X7 R8 K
  681. /*                                                                                                                                                */
    ) p5 d: k% C2 j$ m; s' j
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/6 U4 |) J9 j; p5 d
  683. /* the device:  1st data byte will be programmed into the initial                 */
    : F' G/ V1 i% ~9 S- j
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */) V; A9 W6 z# q& ?# w* S& x
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    - w0 A% y0 ?, T6 H' E* u
  686. /* is used to to start the AAI process.  It should be followed by                 */4 j/ g0 e) n. T, c& U0 |
  687. /* Auto_Add_IncB.                                                                                                                */9 R4 o( {- \* M8 O2 F% {' {0 _4 j
  688. /* Assumption:  Address being programmed is already erased and is NOT        */) v) |3 a3 D. \" e* x
  689. /*                                block protected.                                                                                */
    2 h/ m; l2 `/ i0 e/ _
  690. /*                                                                                                                                                */: i" D, z) r& f+ d
  691. /*                                                                                                                                                */: V1 a, R' H0 f
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */4 O# ]* b) h' I% r
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */! L& X6 Q1 B- X- j3 }+ Z
  694. /*         unless AAI is programming the last address or last address of                */& s0 [1 c" S" {8 ]
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    5 N% n0 ~& B4 f/ G
  696. /*                                                                                                                                                */  ~7 V& M. Y' P% e1 ?- u+ t( W
  697. /* Input:                                                                                                                                */
    1 D2 `: g4 {& H( q+ P9 g, u2 Q! `
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # p7 }- D* _6 H2 N
  699. /*                byte1:                1st byte to be programmed                                                        */
    + m5 O+ v2 {2 D# F) O4 j  G" i& x
  700. /*      byte1:                2nd byte to be programmed                                                        *// I% K* |% `7 p5 ]
  701. /*                                                                                                                                                */
    & b/ n% z8 P( R: \' E: r0 A: S# m
  702. /* Returns:                                                                                                                                */
    + \1 K, w& I# I% y# x0 C5 {" p6 }/ i
  703. /*                Nothing                                                                                                                        */
    4 y* F; w# {; k9 s- c3 w. G
  704. /*                                                                                                                                                */
    1 y9 R  c" C- _+ A0 C. }6 f
  705. /************************************************************************/" U# I* E$ X- V  n" X, C5 s5 g
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    9 L! O2 _7 i0 Z
  707. {
    # Z; Y1 U- ^6 l# h
  708.         CE_Low();                                        /* enable device */
    / r" H! |3 [2 X8 r9 _
  709.         Send_Byte(0xAD);                        /* send AAI command */
    : G3 |4 H! e9 C, n+ ~0 P1 w! V# i
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! X/ t# ^! u. N6 o- D4 s
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " I4 J, N* W0 c
  712.         Send_Byte(Dst & 0xFF);
    ( {  ?9 r/ h6 T- o
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        - J' x6 R+ B! C6 s0 F! \7 f3 Z" [
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 j5 K0 d6 [& S, f0 V. e. O# }: V
  715.         CE_High();                                        /* disable device */7 p+ ~' `3 U: |3 p, C9 d, E# A, _' k
  716. }
    & N! y6 |* h: ^, m5 D3 d

  717. " ^7 ], ?, C. ?# R) r) L) _4 z
  718. /************************************************************************/
    . o: [1 I9 j& Q' z. N2 N
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */- ~9 E' f1 u3 f$ K0 g0 M% M
  720. /*                                                                                                                                                */
    ! u, y9 H$ \8 A1 [) p
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/8 {; C# U7 D4 o8 p- N% |$ X; Y! z  Y
  722. /* the device:  1st data byte will be programmed into the initial                 */% L$ F7 I& w! l( d
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    3 e2 Y# y% ^& a- J
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */% N# S2 @6 |. U1 T2 Y
  725. /* is used after Auto_Address_IncA.                                                                                */  k6 w  I$ i. @
  726. /* Assumption:  Address being programmed is already erased and is NOT        */* K) h/ R$ e5 o% p- S& Q7 b* i
  727. /*                                block protected.                                                                                */
    " n. w7 i: g7 J" X0 v/ c
  728. /*                                                                                                                                                */
    . E- w- Q8 ]9 c2 u
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * c7 Q, I+ C- K& W
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */* O7 y5 A& ^% K5 L; ^9 C7 \6 u
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    & U( ?) g3 r6 P
  732. /*          to exit AAI mode unless AAI is programming the last address or                */1 \5 U3 ~- P% J$ B
  733. /*         last address of unprotected block, which automatically exits                 */- H+ L) g% E- W
  734. /*         AAI mode.                                                                                                                        */7 Z+ \7 T" w0 u3 g
  735. /*                                                                                                                                                */+ _% m. Y6 X% _0 ]0 X  g# P7 ]
  736. /* Input:                                                                                                                                */& ]' a7 W4 n) D  d
  737. /*                                                                                                                                                */
    ! w- Q+ p2 v: _! R  u
  738. /*                byte1:                1st byte to be programmed                                                        */
    ) E0 t& @; M( U+ Y- Q: Q
  739. /*                byte2:                2nd byte to be programmed                                                        */
    . l% M, g( g5 ?: R" D7 `8 {3 b
  740. /*                                                                                                                                      */# k- {% I, s8 T; ^$ o
  741. /*                                                                                                                                                */
    - ^  C( ?8 V5 s& L
  742. /* Returns:                                                                                                                                */
    $ Q4 T( {& ?0 c7 g% j* M0 U
  743. /*                Nothing                                                                                                                        */' l% `  i# i4 T( k
  744. /*                                                                                                                                                */; O# u% Z* w* U! H* e
  745. /************************************************************************/
    - R! h) A- c! c5 T+ w9 }
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    6 O0 m' ^. U! Q2 y9 Z' ~* ^
  747. {( r; R8 N+ F) c  ]$ M) y! `4 ^
  748.         CE_Low();                                        /* enable device */
    + j8 v9 N* e; ?% d
  749.         Send_Byte(0xAD);                        /* send AAI command */
    ( O" j, G8 h, y: ^) j9 B2 Q
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    : Z; G, J3 _) w; O
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */, o& W8 |- o% C9 x; G% i( I' L$ F
  752.         CE_High();                                        /* disable device */
    : f: T7 Y* G- n8 X- E
  753. }
    - b2 a5 `% P9 Q" @. e5 u

  754. & c% D0 _5 P2 w* l6 w3 Y
  755. /************************************************************************/! j7 ]# Z6 g7 n, ^( P, i& e0 p
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ( P4 x* e) E% `6 S4 H. w
  757. /*                                                                                                                                                */
    4 H' t8 u. Q! Q* L2 c) ]$ q
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */. ]) R0 Y, P) B( t+ q9 m& r+ ^
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */& c" i4 M) g# t
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */! u4 @' ]+ b2 X) Z
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */$ b' h2 F, ~9 Y
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    4 `: x: [8 M6 m% k: h
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    * ~+ F* }6 T$ @9 |
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */1 c, g0 K7 n' \9 n% P
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    . g. @' i8 c, L& d
  766. /*                                block protected.                                                                                */- a, h( F7 _- @# |- P
  767. /*                                                                                                                                                */
    , h7 a8 _+ Z6 F4 Q" q9 g/ R4 E
  768. /*                                                                                                                                                */' s) X8 ~6 T  t
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 y5 w1 o0 m0 q" a
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    1 _) P7 U3 ?% T5 K+ S' H& ^- o6 u
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    0 ^* ^3 s, p0 h9 v% G2 d+ x) F* x6 Q
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    4 T( a' V! k, `
  773. /*         last address of unprotected block, which automatically exits                 */1 \2 V: q0 c; T1 t  Y2 ]. y
  774. /*         AAI mode.                                                                                                                        */' }/ W. r! ]0 \% t6 o( R
  775. /*                                                                                                                                                */+ y- w. G* X2 o+ t9 F/ `
  776. /* Input:                                                                                                                                */
    3 x9 r8 w$ i8 q) F! \9 f0 y
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 m5 Y+ I" b" Q8 V
  778. /*                byte1:                1st byte to be programmed                                                        */* D' A3 J8 G( V' k* L0 [
  779. /*      byte1:                2nd byte to be programmed                                                        */' x$ V0 X; y$ @) ?
  780. /*                                                                                                                                                */
    5 J# T; L2 P8 b; \' H: A% J- x  M
  781. /* Returns:                                                                                                                                */( X" j; S( ?% N/ |" |" o& K! t# r2 h
  782. /*                Nothing                                                                                                                        */; S$ v- |8 o$ y1 g  s1 z/ l/ D
  783. /*                                                                                                                                                */3 G1 a  m+ P) a- ]( |
  784. /************************************************************************// ~; V, r0 W6 i$ Q) [: g4 X% n4 b
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & g+ p0 {+ j0 U* S' n4 Z; j% N% n
  786. {
    , \) _& b  k3 p$ b% O! p1 ]0 G- q+ a
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    1 t* g- K+ H  S# M9 @8 M

  788. , i2 {  p5 K/ Y/ S  ^0 Y% [( |
  789.         CE_Low();                                        /* enable device */9 S' \' }, U, ]+ I+ X  [- ~
  790.         Send_Byte(0xAD);                        /* send AAI command */
    1 ]8 r3 }5 J8 {
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 o* g. r) }, z9 p! J& [9 L% q
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 \; [4 `) E0 x7 y! O
  793.         Send_Byte(Dst & 0xFF);3 S. e: f% D# Y6 x  W, h
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    : ]/ _5 s- l4 t; n' B( k8 {
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    # t3 k$ ?, s' i; r. N
  796.         CE_High();                                        /* disable device */
    * L8 ]: m& }* _9 y% l
  797.         5 a; h5 o6 E0 N! A9 p
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */' i6 r& e3 l5 e! \' }' Z& p

  799. 5 D' I* |/ j0 F: y' b
  800. }7 y- x3 D% l" j3 [
  801. 0 H. L* A$ Y  I* u  |
  802. /************************************************************************/
    * ]$ z" k! c8 @: s1 X, _
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    % l8 P9 Y  L5 m' s, b) o- @( l! I
  804. /*                                                                                                                                                */
    ( l$ E$ k0 l9 w4 `/ ^, E1 z1 w6 M
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */- v. h  U  ~8 V; g2 T$ c4 ~1 m2 g
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
      u" \# E& U% H3 p( E5 @
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    . p7 x9 d. o; `3 ~4 T5 {
  808. /* the device.  The 1st data byte will be programmed into the initial   */+ X$ d3 k$ l. T% H2 X
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */) {9 V! W. [- o1 t; X4 R
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    - \6 ~# w- F9 X  G
  811. /* used after Auto_Address_IncA.                                                                                */1 j9 a- m. ^; H: g
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    . u7 T8 E  }7 h2 e, M
  813. /*                                block protected.                                                                                */
    : {+ [  ]" \9 E) @
  814. /*                                                                                                                                                */3 b5 D/ R$ _: r$ s! ^0 o
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         *// X* f' i7 ~$ m! K
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */- V3 q+ r2 }7 @8 W/ z& J
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */3 ^8 Z6 e* R  n; ?
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ; h) d( x& U% ]& G7 {$ ^, n
  819. /*         last address of unprotected block, which automatically exits                 */
    7 n: j& k5 k/ @( o8 I: ~# F3 |7 `
  820. /*         AAI mode.                                                                                                                        */5 p; s+ K. A; k* B& [/ x7 n
  821. /*                                                                                                                                                */
    9 d* W( X7 q2 j5 r* v9 q" r
  822. /* Input:                                                                                                                                */
    ) v+ K- s) o) T
  823. /*                                                                                                                                                */& L$ i/ L# Z7 V6 w! u: Y
  824. /*                byte1:                1st byte to be programmed                                                        */1 b; b+ S) N2 E+ I
  825. /*                byte2:                2nd byte to be programmed                                                        */
    7 G$ ^0 m( n8 }* y& j' |
  826. /*                                                                                                                                      */
    ; E7 p3 D& G7 W. k
  827. /*                                                                                                                                                */
    : q: M3 s6 Z" X1 `/ s" N+ G% t
  828. /* Returns:                                                                                                                                */- C; H8 L; ~* L" A
  829. /*                Nothing                                                                                                                        */7 U4 L! U5 G6 {" [$ h
  830. /*                                                                                                                                                */
      i/ r6 ~/ D1 w; Z
  831. /************************************************************************/
    & Y4 w9 D6 N1 `; r# p
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    " j0 q7 V& }1 r2 i+ |8 ^. i; _
  833. {0 W% r$ V: H* C2 ^4 o
  834.         CE_Low();                                /* enable device */& P3 Z( \5 t: V2 U4 L4 H; [( e
  835.         Send_Byte(0xAD);                /* send AAI command */
    : P  B9 t; D. Z, W
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    9 y2 ^9 ]+ v) H; w5 {2 E6 d
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */) ?5 t* b. P: r7 {/ C6 U* i* D
  838.         CE_High();                                /* disable device */
    2 x) p& i* u9 e  g
  839. ! A- P( U, j6 i1 E
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    8 G9 C! I4 J; i/ r$ U% M9 L6 f

  841. 5 M6 S2 u: h3 u6 _( e# i: v: m" w
  842.         WRDI();                                 /* Exit AAI before executing DBSY */  M, g$ a  i+ z8 d3 d
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    4 Q8 _4 P) O9 Y( i: e/ ^5 c
  844. }' V: K7 y  n2 i& S8 d
  845. , ^& E8 z; J# U( U2 K4 E
  846. /************************************************************************/
    3 G5 w/ M+ |1 X. C, Y
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    : D: z9 a0 F0 o- r9 W2 {# L
  848. /*                                                                                                                                                */0 F5 Y1 N3 D- I1 T1 q
  849. /* This procedure erases the entire Chip.                                                                */* D$ E: h1 l/ m. X
  850. /*                                                                                                                                                */
    " p. h( m! A7 r$ k, B& O. O8 p) ?) H
  851. /* Input:                                                                                                                                */1 i1 ]8 d2 k5 I3 B$ O  p! P# a  r9 d# e
  852. /*                None                                                                                                                        */3 ?* a* \* @5 w
  853. /*                                                                                                                                                */! N& [; ^( V; b7 W% W
  854. /* Returns:                                                                                                                                */
    " M/ Z3 L0 P4 @9 p
  855. /*                Nothing                                                                                                                        */. N* K  `0 v( ~
  856. /************************************************************************/
    " ^: c4 P6 i. y/ C
  857. void Chip_Erase()1 s% W3 ^9 a' G  k
  858. {                                                1 A% H1 L+ Q% d# Z0 Z: Q0 W: N. t
  859.         CE_Low();                                /* enable device */  N1 e& h" e" X3 w. }6 X4 g
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    # v9 I' W  T/ |5 y9 i; _
  861.         CE_High();                                /* disable device */  B; u' u8 H4 u( ^4 B' U0 s
  862. }8 q- q  n$ Z" Z% @9 E7 I0 q
  863. $ L& Q9 q9 D5 D( k& }' G
  864. /************************************************************************/) ^# H; P# O) L# C
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    . V( `5 V1 H- \  c
  866. /*                                                                                                                                                */' [. m+ ~8 m1 A1 ^8 @
  867. /* This procedure Sector Erases the Chip.                                                                */
      }* ^. z5 i& K" X+ _" H
  868. /*                                                                                                                                                */
      c/ h7 s. G! @# x6 m' n$ W
  869. /* Input:                                                                                                                                */. Y5 N9 I% A# N
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ' V, r& G4 p) d5 y
  871. /*                                                                                                                                                */
    8 u: b, X/ t. t  B$ Q$ ?- j
  872. /* Returns:                                                                                                                                */9 G* G. f: k4 ~& u! c" ?$ s% n
  873. /*                Nothing                                                                                                                        */
    5 E; E' {( b0 X( k
  874. /************************************************************************/
    : x. g* x, N  B) K) O
  875. void Sector_Erase(unsigned long Dst)
    . H8 u- v$ [: E6 T  A6 H3 _: A, ^- A
  876. {& d% s5 t$ `( E+ _! R

  877. 2 J8 [7 V4 O7 O/ \# Y" B" z$ _, \6 a

  878. 6 S8 b0 K2 _2 J/ ^% P* b
  879.         CE_Low();                                        /* enable device */' o$ U, R8 K% P1 a
  880.         Send_Byte(0x20);                        /* send Sector Erase command */$ D1 W# l# e* i  \8 x8 \, A
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  o# b5 w3 F8 s8 A8 o
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
      B# a& d2 ?1 Y3 ?
  883.         Send_Byte(Dst & 0xFF);
    6 s' h6 t7 S7 V+ O. ]' O* w. ^
  884.         CE_High();                                        /* disable device */
    ' `5 `3 E! V6 _
  885. }        6 T& Q' o" f& X* _: x/ Y

  886. ' u$ M; K5 |: ]' r% _0 s8 x
  887. /************************************************************************/0 h0 y, R2 J6 ^8 I! ~
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */( D' e" c6 [3 I3 z
  889. /*                                                                                                                                                */9 E9 a" r6 Y& U' f9 u9 p- p8 \  S! I
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    4 _9 ]. Y; q& w" y& z- Q, g
  891. /*                                                                                                                                                */9 n& {4 C2 H* l) y
  892. /* Input:                                                                                                                                */
    7 ~" t  N4 l9 U! Y+ t+ ?3 J
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      g' R, X0 y, A% K9 @
  894. /*                                                                                                                                                */
    2 Y1 y/ Y- y9 X7 m1 c
  895. /* Returns:                                                                                                                                */1 d: e9 C* d: r3 D! K: E8 Z& W7 }4 l
  896. /*                Nothing                                                                                                                        */
    , K. n6 c: L) j; ?& P' Y. ?5 [- W
  897. /************************************************************************/
    ) f# i* U3 ^6 P" }
  898. void Block_Erase_32K(unsigned long Dst)
    ( I3 k. Y0 l6 G) |( i
  899. {% l3 L# p' a: q
  900.         CE_Low();                                        /* enable device */- _* E* c+ ?% S
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    8 i0 e* s. _5 Y: b! P
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 l- k$ w) y2 z# C; ^$ v
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 e; c2 b5 U5 J. b5 w' q
  904.         Send_Byte(Dst & 0xFF);. i3 d# F5 }: X. w# y
  905.         CE_High();                                        /* disable device */9 R! X, _. `9 i5 G8 A
  906. }
    + R4 c0 T# ^( v

  907. / \, L2 ]" B; o0 ~
  908. /************************************************************************/5 {3 F; v  w8 G% X5 \9 M
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    " C; h( L; A# F/ c) j  N
  910. /*                                                                                                                                                */4 U: A% P& ^0 |
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ; z- O# X& J1 r$ W3 U* K) e4 K/ M- `* [
  912. /*                                                                                                                                                */
    3 A% ~* T3 V8 s
  913. /* Input:                                                                                                                                *// P; e( W% O6 r& Y' y8 X
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , G7 I9 _# C* t( l. h  W
  915. /*                                                                                                                                                */
    : C2 t4 N1 A* b/ f! a; p2 T
  916. /* Returns:                                                                                                                                */0 [! q. J5 Q" R6 @. X
  917. /*                Nothing                                                                                                                        */
    / P, k. c( n3 O- _$ J2 }. Q
  918. /************************************************************************/- t4 N' e; M5 f2 n. ^. D$ u& w
  919. void Block_Erase_64K(unsigned long Dst)$ a( {' Z2 d* o$ A( D; f
  920. {
    8 q/ W" g1 `# x
  921.         CE_Low();                                        /* enable device */0 B' T# E0 T* Y. ]4 j2 [3 a
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    % d9 ^. p3 d3 N( i: f% R% q; G
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * y0 m# V7 \! h; {
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));( B5 b/ r( T& Y% \2 O9 Y( q+ \0 c5 W: D! O
  925.         Send_Byte(Dst & 0xFF);! v7 @% B! o2 ~/ v/ Y& B& B' u1 K
  926.         CE_High();                                        /* disable device */6 o1 _! R9 x0 Q$ d5 ?, O
  927. }
    + F; i8 t$ Y6 O: m* f

  928. 7 Z( l0 R9 W1 p6 j: b9 f2 u4 C
  929. /************************************************************************/
    0 t4 s- F/ E2 I5 _8 j
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    4 }' P3 M; G+ V) p* C3 b
  931. /*                                                                                                                                                */
    + s- f1 d. c$ N2 C
  932. /* This procedure waits until device is no longer busy (can be used by        */
    : t$ J8 t9 r9 Y
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */( ~) Y! s0 l, b# i
  934. /*                                                                                                                                                */
    + X9 ]+ d6 B) ~. r5 \  {' J
  935. /* Input:                                                                                                                                */
    " U0 q  r0 O" {+ a, d
  936. /*                None                                                                                                                        */
    , M5 u& E$ p" i  `! N
  937. /*                                                                                                                                                */
    ! c( _; O- x' K* Q, ]
  938. /* Returns:                                                                                                                                */: V2 z# M  f  _5 z1 x! j' Z
  939. /*                Nothing                                                                                                                        */
    ( b0 B% X6 m: y+ v) s: c$ ]3 i7 w. n
  940. /************************************************************************/# f" Z2 G* R" l1 I* ^. i& u( u- ^
  941. void Wait_Busy()# p  s' X9 [/ O) F9 ~6 U
  942. {
    $ I& H( r* i- @) Q: k
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    & V! G; h' K3 ?0 q9 Q! }
  944.                 Read_Status_Register();
    $ ^( N: J5 \  [' k! V; q/ L/ |
  945. }
      w' V( s! x# ^
  946. 9 Q1 ?! U+ `3 Q$ F
  947. /************************************************************************/7 z$ ^8 }/ d/ o0 \/ A
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    7 U4 |" _3 O' T- [; h  K
  949. /*                                                                                                                                                */  W2 ^" S& q9 B# N
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    ( I7 T' }& ~5 X: v, H( R9 {
  951. /*                                                                                                                                                */8 V" @! w2 \( w( @  U+ B0 u
  952. /* Input:                                                                                                                                */% @" q  h$ ?5 i' p$ X
  953. /*                None                                                                                                                        */
    " Y& k- J7 v1 B0 ~- V  z7 ^
  954. /*                                                                                                                                                */
    $ ]- b% c- b: y) M
  955. /* Returns:                                                                                                                                */
    6 {! z' e: z5 B; B: L4 Q
  956. /*                Nothing                                                                                                                        */! G8 e& W$ O( j9 j9 b3 Z
  957. /************************************************************************/$ T! d7 o  g- h3 a: t
  958. void Wait_Busy_AAI()
    1 V! k- v% X' }  s+ w! u$ h  R0 n
  959. {
      d; B0 @- L! V" N8 I) ^
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */: i6 l* q+ G9 z& ~  o+ C' O. r" c
  961.                 Read_Status_Register();& B: d  i  E. d" V$ c. s. A
  962. }
    / f' t  W4 N' `2 M6 C8 o/ X( x7 r: I
  963. 1 C6 Y2 L9 n% W0 W7 m  e# N. |
  964. /************************************************************************/
    * w; `# N* i% r1 K! m: \
  965. /* PROCEDURE: WREN_Check                                                                                                */
    % k/ a9 `  h1 c2 b" B7 ~  |
  966. /*                                                                                                                                                */: ]5 x% J" N% K
  967. /* This procedure checks to see if WEL bit set before program/erase.        */$ ~3 p: d6 m1 r& C# V+ p& N
  968. /*                                                                                                                                                */1 a/ f" r" b+ }
  969. /* Input:                                                                                                                                */
    % t9 s' p* ]+ [% }( I9 _
  970. /*                None                                                                                                                        */. C1 J8 ^( K$ V
  971. /*                                                                                                                                                */" [8 h9 ]% J% E! Z
  972. /* Returns:                                                                                                                                */' |6 k7 n# ^3 l1 B) M
  973. /*                Nothing                                                                                                                        */
    / W; w9 y; D& D& I
  974. /************************************************************************/
    ( N- e- N9 j0 H( J; W4 D
  975. void WREN_Check()( }, S6 J. N1 m# p8 J
  976. {/ c7 B: Q3 R- y) o
  977.         unsigned char byte;
    & \% S. J5 R8 ]% p
  978.         byte = Read_Status_Register();        /* read the status register */" r8 b. o; M" c  {( h5 J9 B0 Z1 M* M. g
  979.         if (byte != 0x02)                /* verify that WEL bit is set */& X. b- v4 {- D* J
  980.         {
    ; v* s* \" q9 d# X
  981.                 while(1)
    1 a. S  B' F9 n) y
  982.                         /* add source code or statements for this file */  c8 n  R/ R  j+ R  n& P
  983.                         /* to compile                                  */5 e8 n9 l3 O6 |" R& ]) p) ?9 T
  984.                         /* i.e. option: insert a display to view error on LED? */) r( J* E$ P& E, T! E3 I& T
  985.                  
    , c9 w* ]" a: @9 j9 z
  986.         }
    ( u. a7 K& \" ?4 g
  987. }
    " d" {+ p6 L& ]) D; U

  988. 0 A, ^4 x; G+ c$ T
  989. /************************************************************************/& Q6 }) P$ n6 y7 Y9 P/ K2 V# J
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ) Y# s( v; E5 A% e6 N* Y( z; J- C* G
  991. /*                                                                                                                                                */
    6 _/ D8 b( W+ x! E& h) _1 n
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    8 j1 B, f/ h9 W
  993. /*                                                                                                                                                *// U1 v+ Y% k% W& b: E( B3 F% J
  994. /* Input:                                                                                                                                */
    - e1 V; f* m4 z* K6 d9 ^
  995. /*                None                                                                                                                        */
    ) [! N$ p6 d. V$ L, Q
  996. /*                                                                                                                                                */
    7 f% H4 b1 T0 x2 ]8 U
  997. /* Returns:                                                                                                                                */6 o& x! \6 n! A0 _
  998. /*                Nothing                                                                                                                        */( O0 g+ C3 V9 e. g( S! q* c
  999. /************************************************************************/
      u  c: f7 W" a. d. b* @+ m
  1000. void WREN_AAI_Check()
    4 o8 l8 A( l1 Z+ O
  1001. {6 I( \) r/ H+ s3 H6 q" X
  1002.         unsigned char byte;" W7 S7 k2 W8 [  M
  1003.         byte = Read_Status_Register();        /* read the status register *// i! b- k9 B5 I9 Z
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    : T8 U8 x& r& a) Y( _( t& Y  @
  1005.         {
    5 Z# C7 J  {# g/ k/ O* {
  1006.                 while(1)                8 [- v! \: Q2 p1 J. m' s. U& g
  1007.                         /* add source code or statements for this file */  `+ M  z! o) |& x
  1008.                         /* to compile                                  */+ Y2 i! h9 }' O; n
  1009.                         /* i.e. option: insert a display to view error on LED? */
    7 l) {5 w7 [. J

  1010. ' m2 b2 a9 z. e$ s( v
  1011.         }
    1 X% g2 C, p4 i. x/ D  z: O
  1012. }
    - u/ m; J3 ~0 }5 n  C

  1013. - d( P% [( ?: B5 m/ p* @
  1014. /************************************************************************/$ D7 |, T. U  M$ O" m: _
  1015. /* PROCEDURE: Verify                                                                                                        */
    6 {& G* y6 ?2 K8 C
  1016. /*                                                                                                                                                */
    - s5 l9 ?9 J. {. T$ c7 z/ {
  1017. /* This procedure checks to see if the correct byte has be read.                */
    - C2 E! n" _; A# \- E' @  t
  1018. /*                                                                                                                                                */  e; k6 ^' `: l6 O" V" h: ^
  1019. /* Input:                                                                                                                                */
    4 b4 p, Q; a) R% |+ d+ \/ z% Q
  1020. /*                byte:                byte read                                                                                        */. H: M; A: A$ `, b: O4 l
  1021. /*                cor_byte:        correct_byte that should be read                                        */6 q# S" y* U9 _- n. u! O; a# X
  1022. /*                                                                                                                                                */
    + P3 n, i, y1 _0 W% k* G" F0 p
  1023. /* Returns:                                                                                                                                */
    - |5 A/ Z# z4 y3 A0 c# r9 B7 ?
  1024. /*                Nothing                                                                                                                        */: V. T) c5 M" L0 i* i
  1025. /************************************************************************/
    . O' a- v" J6 R$ c
  1026. void Verify(unsigned char byte, unsigned char cor_byte)3 e* ^; S; O6 t; Z3 T' @
  1027. {
      B0 D2 T& a. r) e1 K' `
  1028.         if (byte != cor_byte)
    - y1 E+ D; O7 n6 m) E$ C4 N! v, i
  1029.         {- s5 {6 |" R; s
  1030.                 while(1)
    , _2 E! e" ?# s9 E: B
  1031.                         /* add source code or statement for this file */
    8 Q( ^8 e6 v' I0 c6 p+ S
  1032.                         /* to compile                                  */9 m0 z" U$ z5 |, N7 r
  1033.                         /* i.e. option: insert a display to view error on LED? */
    5 ^& T* f& m! E3 h! Q5 K9 o8 J$ i
  1034.                 % \: p: t# A5 n' W
  1035.         }: g3 B3 E4 z+ y: c4 U% D; J- I3 f
  1036. }. i2 k" s/ l; L
  1037. ' l- r* v1 [( [8 Y& ~" [/ L
  1038. 6 H6 \2 ?# d! z; J4 q  x' g. s
  1039. int main()
    7 \1 J8 m6 e0 l4 W8 q7 ^6 S- u9 A
  1040. {- W6 V( G. C' \9 B% V& Y0 a

  1041. & g, J9 t- j( n: N/ Q. @3 J
  1042. return 0;5 M+ h4 X) e+ x
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
4 R* J. q0 }$ P, G+ f  `3 ~   main()
8 C8 z3 P. G+ ~( s* t   里面怎么是空的呢?- x" F: N4 N9 B& N' r
   发一份给我吧) ^/ t* Y4 @" c# M" L  a1 r2 a( D
mail:luyijun2005@hotmail.com
! B% ^0 D) b' @咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
3 v, g5 [, D, h5 Q
* M) m+ U' q9 t7 Y5 ~! j) l[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
1 H- q( `. m. \6 ]0 s" EEC的代码在哪跑,你看DS的说明,每个EC都不同的。6 d( u+ Y+ U$ {* I
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
- `: ^1 p* ?5 U/ O上面几个问题是你没看任何东西而白问。$ _5 \& f2 M! w$ p; ?
, M, l) P7 s5 f0 D- b( b: A$ `
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

( y, P  d. b7 M6 R  T关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!# {$ c$ D& `9 X" R
. M' J2 P$ m6 a5 K& v/ Z4 i
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
8 B; q: q: a- G. P: J2 C) t
; y( J$ A5 w5 Y关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
! S5 q* ~$ T& ?; C" `; b; H# k2 E) I8 X3 I) ]  E9 q
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
0 Q6 Y0 d- J7 R) |% j) Q似乎要把SPI能support 到最大,这EC chip应该有好卖点! J% F% B6 p+ O9 s- r( c
BIOS功能要不要强大,也就决定了SPI Flach的大小
& Y( R. q9 z9 z) @8 i7 ^3 L+ P我是这么想的~让OEM去决定要挂多大!
) d8 `4 A% q9 v: y% M8 T, f如果我司有BIOS工程师就好了~哈9 T3 |4 r- N" u- P
WPCE775应该算很新的东西,来看它支持到多大?( G: T5 e) I9 G7 _! [3 Z- |

1 B, A2 [( |( o' s# u  E另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
% P' q7 P# b1 \- _$ `* u5 w+ e其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
  O9 S. ^- l$ @  L( v9 t3 o" y5 V0 z7 k3 Z, v& i# u# z4 ]
这份driver收下~希望以后有用到
! w4 N% W- G* S. j谢谢bini大大9 n9 v. M9 m' S" e5 L8 t

: n# ?9 e* O3 x; e% F2 U  G* t很新很新的新手,如有错误请指正 (准备看第二家的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()* M6 m  }# N& e' v
{7 p/ q* m4 D: S) p+ ], A/ F& W
        unsigned char temp = 0;
2 b4 ^$ r! Z$ e; \3 }! i        CE_Low();1 _/ O' W2 S+ H! K
    while (temp == 0x00)        /* waste time until not busy */
, L8 M3 m' k: M1 `                temp = SO;
) s3 w1 a8 @" L, p5 M0 p        CE_High();
8 n% ]$ n$ D1 D. b! E* T  I}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
  L5 {- ^! \; _" t{
" T( ]& v" Y7 g. i8 ~        
% T% r, m; X! j8 j! q- k7 H        unsigned char i = 0;$ d5 h( j& ]3 F. V+ D$ T! _
        for (i = 0; i < 8; i++)
# X- K, ^3 \3 e4 R! m; D( F1 I        {8 d. |- D) m3 d* o& N: {) G
               
1 P2 {& \: ~- p( g                if ((out & 0x80) == 0x80)        /* check if MSB is high */
0 t/ Q4 M9 ]+ E9 n. ?7 ?" G                        SI = 1;+ ?) _8 K0 _2 a$ y9 E2 Y- N
                else3 |% t3 D6 C; ?
                        SI = 0;                                /* if not, set to low */
8 p) A8 r. M$ i2 ~2 I- N( x+ M 问              SCK = 1;                                /* toggle clock high */1 l, M  f' G/ ]/ ^7 T) O; U5 M
   题            out = (out << 1);                /* shift 1 place for next bit */
8 j( j% i( Y+ v& C( `/ r                SCK = 0;                                /* toggle clock low */7 n6 X) V' P% Q6 Z( d
        }0 s9 e, _. p7 _9 _! o) `( `2 L6 \
}3 n" R. s2 u! r' v+ O3 D
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-16 07:16 , Processed in 0.035482 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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