找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55250|回复: 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
    4 k% j5 B( ^, Q- b
  2. ( Z- z2 I9 k3 O. `* d9 S
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory& R0 m) }, C, f% E, |7 R

  4. - B0 P3 H8 d1 w, ^" p' L
  5. November 4th, 2005, Rev. 1.0
      h& B, e9 j' g' d% I: N4 L  ]

  6. + {" l  P% I3 p0 N7 d5 G1 q! o
  7. ABOUT THE SOFTWARE
    3 v: A3 f! c. h- y
  8. This application note provides software driver examples for SST25VF080B,
    % v& F9 U6 s7 q6 u% v; C
  9. Serial Flash. Extensive comments are included in each routine to describe ( Q, W) D) D8 n( _4 ~- o
  10. the function of each routine.  The interface coding uses polling method
    ( x7 o& ^# T: l9 o
  11. rather than the SPI protocol to interface with these serial devices.  The
    7 n! k" K4 N! l. T6 n
  12. functions are differentiated below in terms of the communication protocols- u/ L$ r! l6 O9 I& \
  13. (uses Mode 0) and specific device operation instructions. This code has been : q& J: Q2 ~5 b% K) E6 w6 ^
  14. designed to compile using the Keil compiler.
    + Y5 X2 z2 q+ H( @

  15. - ^9 @- B" g) j( g, |6 x

  16. 0 S( {6 S3 Q  Q/ v- a2 P0 W+ J
  17. ABOUT THE SST25VF080B
    ' {8 C: p9 \; O. x3 q- ^
  18. ) p4 Y4 [( m% g8 X
  19. Companion product datasheets for the SST25VF080B should be reviewed in * g. i2 T$ ~; J5 p0 t
  20. conjunction with this application note for a complete understanding + |0 v$ E+ N+ ^
  21. of the device.) m9 o. j6 W( i! U" R) P
  22. # o- @+ B! G* v) S
  23. 9 P, G3 U6 Q) I5 z0 j1 T7 J. A8 j
  24. Device Communication Protocol(pinout related) functions:% |0 a: A( S2 F3 j6 h3 o+ R
  25. 5 F# }. V! @: ^1 X
  26. Functions                                    Function
    4 K4 C+ B0 D, u. l
  27. ------------------------------------------------------------------
    8 x' K! U5 a7 ~2 Z# r/ W1 _1 V7 i
  28. init                                        Initializes clock to set up mode 0.
    , z+ H- T9 e" Y$ o
  29. Send_Byte                                Sends one byte using SI pin to send and
    9 ^# b9 U/ N0 Z( e4 v: q
  30.                                                 shift out 1-bit per clock rising edge  m. o% p, f0 `
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    3 p2 b2 n% ~6 p* ^6 J+ [
  32.                                                 in 1-bit per clock falling edge% C2 U4 L2 z5 c: u4 ~
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    ! S1 T* B. R# \7 S3 C
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    $ B- [4 d3 b4 K5 R6 F; G% a! _
  35. CE_Low                                        Clears Chip Enable of the serial flash to low5 e. g% R7 J7 v# r0 O9 ~6 V
  36. Hold_Low                                Clears Hold pin to make serial flash hold& i9 Y/ F2 i  |  c
  37. Unhold                                        Unholds the serial flash4 M3 A4 J3 c* b( ]( |8 i
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ' W0 a: P6 q, m3 e7 W8 k
  39. UnWP                                        Disables write protection pin
    ( x' X# N/ l( [% Z0 l! `
  40. 6 I. ]3 a! E9 O' {7 m# Q  r
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code6 j- F7 H; L2 A( c( @6 i
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    ) k+ ^' l. T2 Y( @+ u8 j7 \# K: A
  43. software which should reflect your hardware interfaced.          
      n/ |! _0 U9 {0 ?# q6 B
  44. & m4 i: U. T+ \( F- K9 }
  45. - A* Z4 `- I- e! o0 `2 z/ {- C1 u
  46. Device Operation Instruction functions:4 @' a$ ]9 W- V) }$ l
  47. & L  v+ _! U' W$ j. d/ T
  48. Functions                                    Function
    1 Z$ Q, F7 a2 S+ \8 ]
  49. ------------------------------------------------------------------
    & I4 A- v4 K3 q, H8 \
  50. Read_Status_Register        Reads the status register of the serial flash
    + w. f9 m! Q5 S2 o$ Z. Q
  51. EWSR                                        Enables the Write Status Register
    ! Z3 h; `: B5 A
  52. WRSR                                        Performs a write to the status register
    ; l- m# P' @' _7 i) }0 E
  53. WREN                                        Write enables the serial flash
    - |. Y8 _  A# \& D1 k% y
  54. WRDI                                        Write disables the serial flash3 b9 N# l. w9 \& J
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming+ Q" h  R, ], k2 z
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming" X4 [( o: i5 t( A8 X
  57. Read_ID                                        Reads the manufacturer ID and device ID
    : m- u  K* L2 X8 Z% E3 v
  58. Jedec_ID_Read                        Reads the Jedec ID, f# b' M' P- Y& J9 j' k0 C6 @
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    & J" E. C! F& J( m7 j6 Q/ P9 N  Z
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    , o! I) c9 @' S
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    / F* n* f9 j. ?5 `" q
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    % `4 K# ^/ C6 k% ^( I2 v
  63. Byte_Program                        Program one byte to the serial flash
    * M9 O7 u1 T5 J) Z5 q+ G- b+ y
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    0 `3 O: g8 I. t4 f, y5 Y# }5 U
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    / q  P: j( X7 [  N/ e6 y
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    , p4 z+ Q( C6 z2 I6 A2 F0 A' F- V
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY9 |- F1 S. @! U! r. X# r; Q
  68. Chip_Erase                                Erases entire serial flash
    7 ]2 j1 ?! ~! [3 q( E8 q% L
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    6 f2 d( f+ ?. f) T" V0 Q
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash2 Q" V3 C* z7 J) K
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash- J# S% g- A8 z0 f. p9 k6 ?0 d
  72. Wait_Busy                                Polls status register until busy bit is low
    4 [% P8 c5 ]0 b" j
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    0 s, ]" v% t+ O+ C7 R4 z6 Y" E/ S
  74. WREN_Check                                Checks to see if WEL is set* I  }+ d2 h9 @0 H, h
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    $ a# ~& [0 o2 [
  76. , e' u0 P: q# m- J5 n. p' L9 A
  77. - @) s. z0 D' `, K
  78.   M5 m4 Q; |2 J* l
  79.                                                                      5 @% p2 |1 R6 I( T
  80. "C" LANGUAGE DRIVERS & V5 r5 F; W& f; g' ]- A. w

  81. 9 O& Y5 I) g: g2 D( _8 s: i
  82. /********************************************************************/
    / f- ?1 X2 ^/ D
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    6 V. B. I  c  r( z* S: S
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */1 M' s1 C5 f$ D. u. `& T4 |( [) X" s' p
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    ; V9 L9 }( F9 s; |' z
  86. /*                                                                  */
    ; s3 b* _8 ?: }* q2 ], x# l/ I
  87. /* Revision 1.0, November 4th, 2005                                                                          */   1 c$ G" n' N, J& U# `/ R" c9 }
  88. /*                                                                  */7 E  I' I) N% i. ~% N: A
  89. /*                                                                                                                                        */. C: c3 r& B3 a; E4 Q
  90. /********************************************************************/# f' v) _3 ?* v: h

  91. + _4 E. ]' M) a9 U7 ^' E0 j
  92. #include <stdio.h>: a' e4 O  o/ ]2 x! K' w
  93. #include <stdlib.h>9 \' j! ?  y0 w" n; V

  94. ' `/ @. o7 K& I& q3 t- O1 m# @
  95. /* Function Prototypes */
    6 R& k! X* j( [
  96. $ W" w$ k' Z; r: l( k/ I8 U; f
  97. void init();
    1 i# |3 v0 R& [9 x1 s! G
  98. void Send_Byte(unsigned char out);3 f2 R) z# _: t: ]" h
  99. unsigned char Get_Byte();
    / M3 b) i% q1 _/ t3 f
  100. void Poll_SO();
    . W) }0 |" ]. I
  101. void CE_High();
    & W) b+ ?* H# u6 x$ Y/ {6 O0 g
  102. void CE_Low();: R4 ?& L. ^( \4 j
  103. void Hold_Low();; z. g- g* [3 D" _( ~3 X2 e
  104. void Unhold();+ G+ F6 Y4 Q' Z  M6 O
  105. void WP_Low();
    , ~6 N8 \$ M, G- N
  106. void UnWP();" B% i: k, ^% ~  [
  107. unsigned char Read_Status_Register();% C* N2 j( U/ T, `
  108. void EWSR();+ m0 y% E3 ^9 T2 K) w
  109. void WRSR(byte);
    8 B, h6 M" G* E( W0 A( g. b
  110. void WREN();) K1 j# m1 j3 W) k4 K2 s
  111. void WRDI();
    ) \$ x) s1 B" |& |
  112. void EBSY();
    - L* U5 T. D9 G0 {
  113. void DBSY();
    5 L& o5 x, x8 J; `
  114. unsigned char Read_ID(ID_addr);
    ; r/ C. G3 J" G6 _1 f. F8 D
  115. unsigned long Jedec_ID_Read();
    / V) j6 Q+ W3 v+ w7 o9 G/ l
  116. unsigned char Read(unsigned long Dst);
    6 N1 L9 `+ t2 @9 z
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    0 j) c, Y% @, a8 m8 J7 W: m
  118. unsigned char HighSpeed_Read(unsigned long Dst); 5 m) n8 r& V+ a, x5 g' E
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);6 ?, ~: D1 u1 p
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    8 L& F, O+ A! ?7 d" X
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    8 x1 `. k; u' z' n7 H' H
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    & B2 _( m( |# Z1 U. H& H
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);! {) L0 _. x- c* L! e
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);: j" z3 z. e& t( }: N* V% \$ x
  125. void Chip_Erase();- Y0 C: N3 Q* r% k! v
  126. void Sector_Erase(unsigned long Dst);
    % a, `" ^) h/ ^8 {( I
  127. void Block_Erase_32K(unsigned long Dst);- h! Q& R) s3 ?* ]' C
  128. void Block_Erase_64K(unsigned long Dst);- W+ _/ [$ I6 S6 ?
  129. void Wait_Busy();, s) V( ~4 g& ?: F2 Z
  130. void Wait_Busy_AAI();
    2 n) W/ x$ @0 o9 y8 J' o& }9 E
  131. void WREN_Check();
    ) A( D" O8 Z) @( R
  132. void WREN_AAI_Check();# r1 s5 \+ H8 t+ L0 _6 V
  133. . l2 Z( _. Q) q! Y% ~6 ~9 k  ?' {
  134. void Verify(unsigned char byte, unsigned char cor_byte);+ E+ j6 C: p! K* f
  135. - o& I4 T0 Y. r  P0 v
  136. unsigned char idata upper_128[128];                /* global array to store read data */) |- `# L6 P/ m0 S5 Q: w  k& a9 L
  137.                                                                                 /* to upper RAM area from 80H - FFH */) A: C2 D2 w' m! I& a3 H( U& A3 i
  138. . z/ {1 ?5 l" b$ ]* c( f: g5 i
  139. /************************************************************************/, |  x4 u" i7 y% C; ?) d+ K. P
  140. /* PROCEDURE: init                                                                                                                */: }& b, ?5 [/ a6 O2 S+ d% \7 B& i
  141. /*                                                                                                                                                */. Q6 `- m9 a! l# V, K1 D
  142. /* This procedure initializes the SCK to low. Must be called prior to         */3 L3 i  m( X3 _" g
  143. /* setting up mode 0.                                                                                                        */
    % s' X1 _+ G; J
  144. /*                                                                                                                                                */+ j/ U* y/ F3 c6 Z: J4 U- H, e
  145. /* Input:                                                                                                                                */9 t, {3 [$ Q/ i0 ]' _; @$ J! f3 f& c8 e
  146. /*                None                                                                                                                        */% H! g. `3 o0 K7 o" y% E2 n9 t6 \9 r
  147. /*                                                                                                                                                */
    ( d& ^  R4 ^% Y9 D4 [& b6 R' |
  148. /* Output:                                                                                                                                */
    7 E' r+ j2 i6 P5 Y4 l. `7 S
  149. /*                SCK                                                                                                                                */
    3 j% C4 m  ]5 @% ?
  150. /************************************************************************/2 \. j( G0 R8 p5 r
  151. void init()0 E& |2 L& H  E+ Q% R
  152. {
    : W- r4 h; y+ E" J
  153.         SCK = 0;        /* set clock to low initial state */
    5 @$ E) C" o2 u& X
  154. }5 K# n5 j! z7 G8 K) t+ W

  155. / `  Y2 j9 I! K! b- W
  156. /************************************************************************/; F- W+ A, \+ W3 ]3 g( N
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    - W/ `" R. ]6 L: L1 q# E- l8 l
  158. /*                                                                                                                                                */
    ( S, y& n; U! q& v; O( E7 r
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */8 b. v& \7 U- Y! m) l6 m1 k
  160. /* edge on the the SI pin(LSB 1st).                                                                                */2 v2 @  w* `' G# @
  161. /*                                                                                                                                                */) I# G* ^; a) W3 u
  162. /* Input:                                                                                                                                */9 E9 F: @; K% z8 \. |
  163. /*                out                                                                                                                                */
    ( S* \6 h! s1 A: p! m- s  S! x
  164. /*                                                                                                                                                */
    ' d$ G4 A1 q3 v  A5 o$ B9 E
  165. /* Output:                                                                                                                                */8 A# C0 A/ C# I2 }0 Q% ]# Q) _2 {4 j
  166. /*                SI                                                                                                                                */
    & q) H* h% [' ]. G5 _' s* V. t
  167. /************************************************************************/
    # p  K9 H" C2 |# |$ y
  168. void Send_Byte(unsigned char out)4 l. K+ o7 Q$ Y$ U  W$ n( @2 }
  169. {
    $ o0 z$ `* p1 A
  170.         - S6 x- y3 Q* I' P* _. L6 c* D7 `
  171.         unsigned char i = 0;
    # L5 q$ X. z9 |% O0 {% c' u" c4 k! s
  172.         for (i = 0; i < 8; i++)4 Y8 ?/ v& v! B
  173.         {
    8 R& ]8 O, b1 u$ I7 ]! I8 y
  174.                 ' P7 u/ B- \0 l, r. t! `& w9 W% o# N0 P
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */, {" W( q. N; f: u/ E! r2 \* s1 J
  176.                         SI = 1;
    ! S& l% m3 D6 r
  177.                 else
    4 W# n0 H) B$ _  X, Q$ w
  178.                         SI = 0;                                /* if not, set to low */
    ' e% {' ?, M: q" j% `9 u
  179.                 SCK = 1;                                /* toggle clock high */
    ' j8 d1 Y; D4 e9 Z1 u
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    ! n- D, H: Z; S- i; Z  _
  181.                 SCK = 0;                                /* toggle clock low */+ D' I$ x0 Z8 ~" x! ~
  182.         }
    * V( ^; A: E2 [. [% d; R
  183. }$ l% W5 i) I: c
  184.   v5 O% n' y; F# U; w
  185. /************************************************************************/. }# L  R6 g( Y
  186. /* PROCEDURE: Get_Byte                                                                                                        */! ^) y& x% u) f4 `) q& w
  187. /*                                                                                                                                                */
    1 T, y2 S* w9 Q& }+ r6 O4 d
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */- n6 P  K' N/ P( n; `, X" E  v
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    & z- m* ?4 e- c
  190. /*                                                                                                                                                */7 _* d/ n4 S' F  ^) U( V
  191. /* Input:                                                                                                                                */
    : l# i6 k+ T+ i
  192. /*                SO                                                                                                                                */; I& a3 o; S1 a' B% D- Q2 |
  193. /*                                                                                                                                                */
    % h, L; v, g1 d" e2 w& p, f
  194. /* Output:                                                                                                                                */( k( \: J8 F! M9 }# U, d
  195. /*                None                                                                                                                        */
    / H1 }' n  u! k+ k& |) ~! E
  196. /************************************************************************/
    % @/ z; g" K, L/ n% B$ {+ u, e  v, D
  197. unsigned char Get_Byte()
    ) a2 C( c" y' y, q1 N0 G
  198. {! N9 L8 ^$ I+ S  [8 r8 t
  199.         unsigned char i = 0, in = 0, temp = 0;
    8 G" K# ?/ T2 |. U+ E$ d( }
  200.         for (i = 0; i < 8; i++)
    % d. z! w6 C3 f0 F4 L# E$ x
  201.         {) K8 G! P3 G4 M+ e
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    4 B5 c, Z: h" c4 \
  203.                 temp = SO;                        /* save input */. W+ D+ l$ B; t$ @: f; L/ \
  204.                 SCK = 1;                        /* toggle clock high */$ o, }  H  Y8 V) d! L7 p' Y8 h
  205.                 if (temp == 1)                        /* check to see if bit is high */
    * I+ y# Y# b! X
  206.                         in = in | 0x01;                /* if high, make bit high */
      W: Y+ t( u% [3 a/ i

  207. 8 u" `2 x3 g5 @$ ^5 T. f5 o# Y( l
  208.                 SCK = 0;                        /* toggle clock low */+ o7 Z+ |( I3 z/ W+ O

  209. & g1 @6 o1 K" w0 G, H4 F
  210.         }
    - G) F- w: K* `& d! B6 Y
  211.         return in;1 ~, L5 W' G8 P* A+ d
  212. }% n; J4 ~! M( B! O8 _* T+ f

  213. ! v/ S2 q% |% s, V" S6 J
  214. /************************************************************************/
    8 F; b9 N* Q/ @7 l! J0 q7 i" K
  215. /* PROCEDURE: Poll_SO                                                                                                        */# z$ @6 i0 N% d# w2 Y2 w8 I
  216. /*                                                                                                                                                */' L8 q0 t/ q( P. i; d/ W/ y& [
  217. /* This procedure polls for the SO line during AAI programming                  */
    % y* Z( y/ y! `0 f
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    6 r' X2 }; f* y9 l  [" l6 b
  219. /* is completed                                                                                                                        */
    5 q) h  ~% b, e1 m) i8 g1 z4 `6 v
  220. /*                                                                                                                                                */
    & j( {+ j) Q6 ]  @5 {' M$ ?
  221. /* Input:                                                                                                                                */
    2 K4 F- }8 q. |) x! Z
  222. /*                SO                                                                                                                                */" E7 |( d. C+ p+ L/ ~% s! R/ Z
  223. /*                                                                                                                                                */- i& A* S/ T" i* |5 N8 ~. k
  224. /* Output:                                                                                                                                */6 u* j- y& z2 |$ _  K9 ^
  225. /*                None                                                                                                                        */
    8 G* g, q9 ?. c( r6 N5 l; z
  226. /************************************************************************// q! H: E; g+ F2 @7 h9 f3 X' l
  227. void Poll_SO()
    ! W% ]+ ^$ Z$ S7 r) M5 v
  228. {; W+ O& L7 g5 E
  229.         unsigned char temp = 0;; Q0 d8 B2 x; ?" A( ]! N
  230.         CE_Low();
    5 ], U1 x% H: t
  231.     while (temp == 0x00)        /* waste time until not busy */
    * p. |4 z0 a1 F* P  [8 Z7 Y
  232.                 temp = SO;
    # J: g  Z5 M1 {( Y% c+ M4 e
  233.         CE_High();
    7 ]* e) @4 Y) \  F# S, P+ {
  234. }$ `6 k' B1 _: U, ^% e* R
  235. ; g: x: n. o1 |: D9 x; x0 w: n+ v
  236. /************************************************************************/
    1 G$ R: X; s% N! ~6 t) Q2 }
  237. /* PROCEDURE: CE_High                                                                                                        */  A8 n2 B7 j$ l9 B5 p/ p/ U. u
  238. /*                                                                                                                                                */
    % M) L/ @$ I6 K' a/ t. H
  239. /* This procedure set CE = High.                                                                                */4 h- ]+ _# C, H/ {, I5 M
  240. /*                                                                                                                                                */1 ~* h6 {% [4 g+ y
  241. /* Input:                                                                                                                                */3 D* E9 f8 y: a/ Y) F7 _* N
  242. /*                None                                                                                                                        */0 f: o' i* B8 C$ e/ U
  243. /*                                                                                                                                                */
    6 \) p% F/ P' s2 ^$ w, n! q( n
  244. /* Output:                                                                                                                                */
    ; j# f/ _; c  P- Q' m* ?2 Y% x
  245. /*                CE                                                                                                                                */9 i% t  E9 v9 v1 c' J& y/ [
  246. /*                                                                                                                                                */, `3 X+ M. N9 W" B1 c
  247. /************************************************************************/
    0 k3 R8 |' W; m
  248. void CE_High()
    ) }& }: S6 c9 j, w, M8 O
  249. {
    ! A+ l. s, a0 N
  250.         CE = 1;                                /* set CE high */
    ( O" ]6 |; W- ]1 |  Q/ J
  251. }6 h, Y( g. P4 I; g
  252. : `- {$ s. Z/ P! i
  253. /************************************************************************/2 \6 d. j* N9 @0 c0 L9 ~
  254. /* PROCEDURE: CE_Low                                                                                                        */  _9 `7 M. t2 s3 i2 o6 Y. T
  255. /*                                                                                                                                                */
    6 |$ J# l  j4 J1 ?- C
  256. /* This procedure drives the CE of the device to low.                                          */" `2 s6 r" V) c7 o" B+ \
  257. /*                                                                                                                                                */
      ?# J' e( V" ], h! s
  258. /* Input:                                                                                                                                */# g& L. C6 W3 H% M. _5 e% _' X
  259. /*                None                                                                                                                        */- X) J) K# K8 i4 c7 x
  260. /*                                                                                                                                                */
    1 ^4 D+ Q& e$ ]6 j5 f% `. l
  261. /* Output:                                                                                                                                */+ r" Z1 P/ Y' y- C6 A# r  g. w9 [
  262. /*                CE                                                                                                                                */) ^9 R% s0 T0 i3 t! R5 a7 ~
  263. /*                                                                                                                                                */
    ) j5 m, K% T5 }/ e& K
  264. /************************************************************************/& W: ]0 \' |, j+ Y- y- ~4 ~4 ^
  265. void CE_Low()
    & H2 A% p4 R" r! G9 C
  266. {        & ~( d6 A* C& b! q5 a# c
  267.         CE = 0;                                /* clear CE low */
    & k- D! `9 o5 A1 G( J/ S% u
  268. }/ u  p( R. t9 I

  269.   @! u4 w* a# H& V- V0 [- q
  270. /************************************************************************/
    , V% D6 V4 F2 h  d
  271. /* PROCEDURE: Hold()                                                                                                        */
    7 r) ^) }" D6 S$ i
  272. /*                                                                                                                                                */
    9 Y& s2 ~4 `/ e) N4 j
  273. /* This procedure clears the Hold pin to low.                                                        */
    ( k1 R% x7 M) L/ K" D0 w. j
  274. /*                                                                                                                                                */
    0 ^# C  k+ n% J4 q4 V& O$ q. ^
  275. /* Input:                                                                                                                                */
    , H, a+ y: W$ a3 g; _* K
  276. /*                None                                                                                                                        */3 s( p8 l& T. n5 g# W
  277. /*                                                                                                                                                */
    + H2 M' J9 K) l- M! l
  278. /* Output:                                                                                                                                */
    ' W8 w% h6 ?3 }1 c+ z! p- V& D8 g: a
  279. /*                Hold                                                                                                                        */3 ~3 Q( O6 _2 Y8 I
  280. /************************************************************************/
    + q3 \) m) J+ q
  281. void Hold_Low()
    ' T. R3 f. \5 N
  282. {( d' \6 P* d# ^9 D, C4 M. r. `, C3 O
  283.         Hold = 0;                        /* clear Hold pin */6 J/ s0 v/ ^; |: |
  284. }
    ) t( {4 Z8 A$ V+ a) m5 a
  285. 1 _  H* W9 t% t% H6 l6 i* }; D
  286. /************************************************************************/- q* z& Q) A! {8 y" O' @
  287. /* PROCEDURE: Unhold()                                                                                                        */( a7 W* ~2 z9 o! {0 T5 @( g
  288. /*                                                                                                                                                */
    * ~  {- j9 @& N5 J' h
  289. /* This procedure sets the Hold pin to high.                                                        */
    . n# q  Q% e# W+ e1 C0 b5 y
  290. /*                                                                                                                                                */1 ^6 W% o( n4 Z3 X8 i9 Z5 n! c# Q
  291. /* Input:                                                                                                                                */
    / Z+ ]1 Z4 G& r# t! r
  292. /*                None                                                                                                                        */
    ; x, L8 t( j+ f' j8 r
  293. /*                                                                                                                                                */# T8 c; c8 H! K- ]1 ?$ u7 `
  294. /* Output:                                                                                                                                */* U$ ]' c5 i, X* \' O8 c
  295. /*                Hold                                                                                                                        */5 {) ]; p( h; O+ }9 s6 S
  296. /************************************************************************/
    $ k( j, A! k5 u( J- ?; K2 B
  297. void Unhold()
    4 S% {1 {8 d# D
  298. {
    # J" {) E; t' T" l' K0 P
  299.         Hold = 1;                        /* set Hold pin */- h  N* k5 J+ ^+ q; O
  300. }1 n( K6 P, O* {; u! Q8 ?
  301. % }! h, K. V* H5 i9 g+ G# F9 F% D1 |
  302. /************************************************************************/
    + K& u% i* p& R# n
  303. /* PROCEDURE: WP()                                                                                                                */
    / U  |3 T5 R5 ^. N4 ^: |4 X" O
  304. /*                                                                                                                                                */
    ( s6 o4 {! `  w4 {+ e% ?
  305. /* This procedure clears the WP pin to low.                                                                */
    , \4 R3 P, s+ e% k
  306. /*                                                                                                                                                */  V- s4 ^) R5 c& c% Z$ }
  307. /* Input:                                                                                                                                */& `* |# {7 Q" q# P& D$ H
  308. /*                None                                                                                                                        */2 l* V4 ~# `4 ^; W) p- h& W% g( P- Q
  309. /*                                                                                                                                                */- [3 n+ t( g/ |9 |4 F& K
  310. /* Output:                                                                                                                                */
    : G, n  [; w9 t, M/ [7 i* T( l
  311. /*                WP                                                                                                                                */
    % F$ S# _! Y  W8 E0 A. |
  312. /************************************************************************/
    ' K/ C  c) G" |8 V' s& _+ s
  313. void WP_Low()
    & L$ I6 L1 J) `- {  d8 x& @0 a
  314. {
    / ]) H* X  m/ C, u
  315.         WP = 0;                                /* clear WP pin */
    9 d1 N+ e6 s/ x1 ^9 G; O+ [
  316. }! K. d" l, e6 w% {' H4 g
  317. 6 m& Z! S; H* u. ]! b" J
  318. /************************************************************************/+ H+ V5 G  U  d: F- C
  319. /* PROCEDURE: UnWP()                                                                                                        */
    ! e9 K" O4 h! V; u$ S
  320. /*                                                                                                                                                */5 K" b1 ]3 Y# y+ F9 m6 G
  321. /* This procedure sets the WP pin to high.                                                                */
    # P5 }/ o2 v$ L
  322. /*                                                                                                                                                */* L( Y! a6 T- X  p* V. c- a; \
  323. /* Input:                                                                                                                                */) T. P4 ~, w6 z
  324. /*                None                                                                                                                        */* O* t. p% O4 n$ a  d0 y
  325. /*                                                                                                                                                */
      Z- C+ R3 |1 G& h0 x
  326. /* Output:                                                                                                                                */9 Y, j* c2 `8 u; X! ]4 b% I" o1 B
  327. /*                WP                                                                                                                                */
    2 V9 v4 ?  n( A4 e9 O. V
  328. /************************************************************************/  e, o6 w/ l; G" e% a- C5 F3 |6 D
  329. void UnWP()& @) a+ t; Q; a/ O$ K7 [9 c
  330. {& Z* d5 g" R! V% d" {% L' b* v
  331.         WP = 1;                                /* set WP pin */1 z: d- v7 M" ]& b
  332. }
    3 ]* S9 w, v+ p+ n* N- N3 j- t

  333. * c" U. _6 j* W
  334. /************************************************************************/
    + f( u5 S2 v$ V) s' J1 y% l
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ; \2 d# F3 i& h4 n+ ^( j3 g
  336. /*                                                                                                                                                */
    7 r  S  ~0 j1 Z$ H# `6 G' y
  337. /* This procedure read the status register and returns the byte.                */! N9 i6 P* X/ H
  338. /*                                                                                                                                                */
    " \9 \9 I9 X* Q
  339. /* Input:                                                                                                                                */9 r5 \) u. _- z2 W7 g/ Z+ p
  340. /*                None                                                                                                                        */, E/ {: g3 R7 `1 h- P1 z: p- C
  341. /*                                                                                                                                                */
    5 p/ O1 c0 K- S4 ?" k' y! N
  342. /* Returns:                                                                                                                                */
    ' L; i. f1 E8 J2 W
  343. /*                byte                                                                                                                        */
    5 y' ?/ o+ A5 c% |& f
  344. /************************************************************************/
    9 I! `. O. M/ h" O
  345. unsigned char Read_Status_Register(). d( m# o) u- Z& [1 X  p( d
  346. {
    2 a" p; t% T# i# b8 y' J0 g) @8 T& }
  347.         unsigned char byte = 0;+ \3 ?+ Z1 {  f. e% \$ W1 P8 ^
  348.         CE_Low();                                /* enable device */4 s+ b( N* N/ W. n
  349.         Send_Byte(0x05);                /* send RDSR command */" w- _" }* U+ i1 D
  350.         byte = Get_Byte();                /* receive byte */
    9 u1 f" [; n* R  k" {2 Q: r
  351.         CE_High();                                /* disable device */
    + |: V+ ~4 o5 G$ M4 a# F: x9 K/ x9 B
  352.         return byte;
    . v. b0 Y) r, S& O: U( M
  353. }+ v1 c9 C3 J, f, i" V

  354. # e/ m0 O$ |$ D# v* s4 s  c
  355. /************************************************************************/( n8 I# ~# @% d) D: W
  356. /* PROCEDURE: EWSR                                                                                                                */5 X+ J4 o6 c; e$ G
  357. /*                                                                                                                                                */
    3 ~, R! E" D# ]  u1 S+ l
  358. /* This procedure Enables Write Status Register.                                                  */  y6 O0 J8 t& O; }  o7 f: S
  359. /*                                                                                                                                                */
    & q  n& f! ~$ M" R
  360. /* Input:                                                                                                                                */
    & D  l: E. e" [: @! n
  361. /*                None                                                                                                                        */
    3 I( h, I! R- t9 m! i! U
  362. /*                                                                                                                                                */
    " [5 }+ u2 j4 f- t" `
  363. /* Returns:                                                                                                                                */% `* t0 L) i6 f* A& ?, G4 M
  364. /*                Nothing                                                                                                                        */
    ' i! a' J' h7 N0 Q% V/ S$ G* b2 Y
  365. /************************************************************************/8 K, Z" \! B& h+ _& ]
  366. void EWSR()4 L8 N4 S5 L+ {" y: L2 d1 `1 x* y
  367. {
    & h/ q" v. b" _  X+ K9 Y& m$ A
  368.         CE_Low();                                /* enable device */
    3 t7 P( A5 d: I: _* X- _
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    3 X" l, B" E" J! d/ e
  370.         CE_High();                                /* disable device *// R9 W/ I, J0 G. v( G+ j# K
  371. }  k: J' }0 z5 k/ d5 b

  372. $ R7 W* M8 D! s/ G4 B- s
  373. /************************************************************************/
    : a: a6 Z& ]1 d& R: c& U6 `# q8 Q
  374. /* PROCEDURE: WRSR                                                                                                                */
    ' Y7 ?3 J& d/ C
  375. /*                                                                                                                                                */
    9 Q. l) ~4 _* H" g: U) }
  376. /* This procedure writes a byte to the Status Register.                                        */- V) ]& v( W1 H8 T
  377. /*                                                                                                                                                */0 \! p; d6 n! _4 r0 J- _; D- x
  378. /* Input:                                                                                                                                */9 x' y5 J# h* ]3 t* K" O0 c, D
  379. /*                byte                                                                                                                        */
    % i' w- v1 M* A9 k: g# l
  380. /*                                                                                                                                                */
    + X( B* U$ x9 l- b
  381. /* Returns:                                                                                                                                */
    " Y. G8 ^7 k" e& U; y
  382. /*                Nothing                                                                                                                        */
    + Q- F8 c9 P) `! b! o. f
  383. /************************************************************************/( S. \! X' q$ }$ ^6 o! @
  384. void WRSR(byte)
    6 g; X* ~& t8 I. S" f7 s
  385. {" G  }* w4 n* \- t- x* p* w% b4 p
  386.         CE_Low();                                /* enable device */9 h4 G' z7 l6 L
  387.         Send_Byte(0x01);                /* select write to status register */
      Y6 J' p( l. _& D( ]2 [
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    6 a2 Z& V3 Z7 X) ?6 U, r
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */7 L/ A4 r9 \6 v3 u3 m' [  a
  390.         CE_High();                                /* disable the device */5 s# Y9 _. r1 {1 y
  391. }
    & A2 L2 b1 Q* ?! V" A: z

  392. # ~) P( c" b+ A$ Y$ t! \* s4 m
  393. /************************************************************************/8 j+ M) ^& a9 N4 U- [) I/ n! n
  394. /* PROCEDURE: WREN                                                                                                                */
    ; b5 a& n, c0 w3 a3 s3 g
  395. /*                                                                                                                                                */# m5 W# F. I0 R0 V3 g
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    : n- t) E8 h/ `
  397. /* to Enables Write Status Register.                                                                        */4 K7 a% ?4 g; S2 F2 k6 V- h* X
  398. /*                                                                                                                                                */
    9 \! Z4 c! R' x6 q# ^7 `
  399. /* Input:                                                                                                                                */- W4 j- q! E' V8 ?7 ]0 Y; f
  400. /*                None                                                                                                                        */. d" b6 r$ Y3 c9 _% P8 t! D1 \1 N
  401. /*                                                                                                                                                */
    + x. G; l! O' C
  402. /* Returns:                                                                                                                                */6 R* D: T+ U4 a3 H/ \5 t. e
  403. /*                Nothing                                                                                                                        */
    * e/ r( S. m& W% Y/ ]# s5 P
  404. /************************************************************************/
    0 v: Y, |% Q# q5 D+ Z' V
  405. void WREN()
    1 B0 Y+ O, {. L$ h5 x* Y. X2 |) V: z
  406. {
    , i, u* g1 W8 E5 X0 e6 [) _" m
  407.         CE_Low();                                /* enable device */$ m3 e4 |- Z5 p5 O3 b. ]2 v# e
  408.         Send_Byte(0x06);                /* send WREN command */+ l" P$ \. |$ r
  409.         CE_High();                                /* disable device */% B9 [! u2 F7 X
  410. }3 `8 L% j2 }: F: b
  411. , K% J: Z+ Y' ~1 }  |5 d% C
  412. /************************************************************************/! N: V" A* s4 m# `% H- |
  413. /* PROCEDURE: WRDI                                                                                                                */
    6 p; l$ _3 T+ }. C  O; D. X, m
  414. /*                                                                                                                                                */
    4 V8 M6 e6 G/ Y& h
  415. /* This procedure disables the Write Enable Latch.                                                */
    3 G! H4 ~1 j. X9 Y" [( Z0 E
  416. /*                                                                                                                                                */5 s7 F( ^9 J4 K' h2 B/ m
  417. /* Input:                                                                                                                                */
    / b+ E; _* \- s; y+ c
  418. /*                None                                                                                                                        */9 j) Q' c% Z+ f( r  K9 g
  419. /*                                                                                                                                                */+ Q' P3 |& A' `5 r$ e0 l
  420. /* Returns:                                                                                                                                */
    * d7 b9 F: N) v6 S2 Z. H0 D
  421. /*                Nothing                                                                                                                        */
    8 z3 }  D) h& [8 B
  422. /************************************************************************/( I9 G; Q3 _  A0 _
  423. void WRDI(). N, I. l/ K* c/ @1 _& K: o
  424. {! \+ k1 J7 _. V2 z2 o
  425.         CE_Low();                                /* enable device */
    + T# q* t) ?" Z& R8 a
  426.         Send_Byte(0x04);                /* send WRDI command */& L( d' \" D. D) c: A3 t0 V
  427.         CE_High();                                /* disable device */
    5 t7 {: \1 y5 @
  428. }
      y4 C* V" p5 m4 S5 M3 a: j1 {% v
  429. 9 y9 {9 `  z! Q. H& ~
  430. /************************************************************************/
    " ~$ N3 u) N: b" E' l  f
  431. /* PROCEDURE: EBSY                                                                                                                */0 {; T1 T8 l/ E9 c! Y8 Z; S7 T$ F
  432. /*                                                                                                                                                */, `' i4 }" D# n( U
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    ! V$ ^6 k. [" |0 q4 Y
  434. /* programming.                                                                                                                        */  ?5 o: H$ q. W. `: \; x
  435. /*                                                                                                                                                */
    : J( d  Z2 j( G4 q) I1 z
  436. /* Input:                                                                                                                                */( M$ ?' W  b- O8 G& A' f# H
  437. /*                None                                                                                                                        *// `- M/ {  g* s# G& w% U4 n9 G4 K
  438. /*                                                                                                                                                */0 W! a* A8 n7 D/ @
  439. /* Returns:                                                                                                                                */
    4 [' Y/ }' ?% Z8 ^
  440. /*                Nothing                                                                                                                        */
    9 D: i8 L3 d; T; }6 C: o, h; B
  441. /************************************************************************/
    " E: ~. g  y/ U9 w- X
  442. void EBSY()
    ; u$ S7 a  U" Y9 C5 w& {
  443. {
    5 @* ?- t1 a9 T5 J  l
  444.         CE_Low();                                /* enable device */
    2 z! k3 R6 d% o: Y+ j) p( O2 f
  445.         Send_Byte(0x70);                /* send EBSY command */2 i9 [' `6 [6 K
  446.         CE_High();                                /* disable device */
    " b' z  f% z" t' e" h2 [
  447. }1 l6 c, }; ?4 m; O1 {

  448. : B6 ]: @, j7 h5 _2 L& A% Z
  449. /************************************************************************/
    ' l+ Y# I" a- l  |8 ]
  450. /* PROCEDURE: DBSY                                                                                                                */) q7 G* g8 A8 D- k) B8 \7 i
  451. /*                                                                                                                                                */7 J5 A$ x9 P% S0 F% M% H: k" E5 L
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    . y+ \; F* q  M9 e
  453. /* programming.                                                                                                                        */1 J7 M1 ]1 T, @, D6 C, j: x
  454. /*                                                                                                                                                */3 n0 p# t4 G  G$ C2 e+ F
  455. /* Input:                                                                                                                                */
    4 \2 _! M& {2 j$ G  V
  456. /*                None                                                                                                                        */
    / I  Y" O2 S* }
  457. /*                                                                                                                                                */
      O. S+ U% S0 K5 \
  458. /* Returns:                                                                                                                                */( ?$ H9 v) D1 X+ U
  459. /*                Nothing                                                                                                                        */
    7 |' O4 o2 @. I: }& ]; g' A2 e
  460. /************************************************************************/
    * V8 ]5 F9 f/ g4 a
  461. void DBSY(), ]3 x( h( U" C" h
  462. {
    . Y: x/ Z- D8 y. r2 K
  463.         CE_Low();                                /* enable device */
    7 o$ o/ |7 c% }6 T* i3 W
  464.         Send_Byte(0x80);                /* send DBSY command */! b" A" e; {0 K
  465.         CE_High();                                /* disable device */! f: s3 J: f9 X! x2 i
  466. }
    3 E' A, P$ D9 j3 A3 A* @2 G$ S$ T; S  K
  467. . T( D/ {( y! J
  468. /************************************************************************/, d$ W1 Q. V+ s) L+ C
  469. /* PROCEDURE: Read_ID                                                                                                        */1 v8 H) B" g; P5 p$ l8 N
  470. /*                                                                                                                                                */
    0 }' w6 F! ~( J7 T2 ?8 i% @
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */5 g% T+ D) ]  C& P  Q$ n
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */0 z5 W6 G! A" k' y
  473. /* It is up to the user to give the last byte ID_addr to determine      */. R+ u( [- s; m7 m8 l1 @
  474. /* whether the device outputs manufacturer's ID first, or device ID         */0 X( d1 D. j) ?) p. H6 k3 u. U
  475. /* first.  Please see the product datasheet for details.  Returns ID in */; D4 ~' I+ Y' e2 C
  476. /* variable byte.                                                                                                                */5 }5 S! o& ^( I
  477. /*                                                                                                                                                */% t# L  e7 t3 Z
  478. /* Input:                                                                                                                                */
    4 I, {( W8 ]  \
  479. /*                ID_addr                                                                                                                        */' e- s* m- h* K" x- c1 t% n
  480. /*                                                                                                                                                */
    2 P) `# l- F. T) v1 M
  481. /* Returns:                                                                                                                                */' g, r9 s- `# i, ]3 l
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */+ T! C1 o# }; h( a1 b* E
  483. /*                                                                                                                                                */
      S- y7 o, l8 L1 z
  484. /************************************************************************/
    9 t3 }# D) \* u4 p; V# C
  485. unsigned char Read_ID(ID_addr)$ E0 U8 \6 l& M+ j
  486. {
    * y* ~- ?3 b( P5 V
  487.         unsigned char byte;, R# n$ f: w3 m9 @% ^
  488.         CE_Low();                                /* enable device */7 _! F4 \$ {% F
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    ( n4 H/ q6 ]6 Q$ F
  490.     Send_Byte(0x00);                /* send address */
    ! \9 K/ m+ \" r5 w( w6 f  P
  491.         Send_Byte(0x00);                /* send address */( r+ Q+ {( |; |8 E) y* C' P6 N& Z
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */9 l/ k, y! V& ?, E( i3 ~
  493.         byte = Get_Byte();                /* receive byte */
    / U' _2 ~  t$ U( |& i
  494.         CE_High();                                /* disable device */7 l7 _: `3 C% \8 y# Z! F
  495.         return byte;
    ) |0 ]; ]- L& M$ r7 l
  496. }4 z+ U$ ^7 R$ e- m1 j1 c% k

  497. ) ?, t! N: k1 n- `' U) \  C
  498. /************************************************************************/& h" J. P, I+ o
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    / c) X* |% R& e9 w" z
  500. /*                                                                                                                                                */" {  A( C/ A" D" h- x
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    & p; L4 P  F: H
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */2 b+ J% x% _! Y+ K$ b
  503. /* Please see the product datasheet for details.                                                  */
    0 |- F0 U% H6 |. }1 N9 r
  504. /*                                                                                                                                                */
    " F4 N* p4 C! n
  505. /* Input:                                                                                                                                */
    0 o# @3 {; u7 M" J$ B5 V% K
  506. /*                None                                                                                                                        */
    , v, Q$ X: w' R$ a/ Z3 U; c& g1 p
  507. /*                                                                                                                                                */' i9 r. G- g1 i0 V% W) ?- O6 a
  508. /* Returns:                                                                                                                                */
    ! N4 Q6 u1 `5 i6 n8 l5 h+ k
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */5 P$ \3 n5 T( R  O5 h5 Z* s
  510. /*                 and Device ID (8Eh)                                                                                        */, `8 ?+ W; A% `9 Q6 ]$ P, I
  511. /*                                                                                                                                                */4 ?2 n9 L0 ^8 N- _
  512. /************************************************************************/
    ! C1 W% P+ d+ m4 ?  h
  513. unsigned long Jedec_ID_Read()
    9 f8 C" V1 \- o0 e, }9 {; G
  514. {: x$ d# t7 K: Q+ Q; Q
  515.         unsigned long temp;
    # V  _" @* n) V* V9 c/ Q2 |( i
  516.        
    ( c+ `& [5 U3 P6 R3 f# u
  517.         temp = 0;
    3 @; V. g/ S. O  n, h, U8 K

  518.   h; [: ?# g% Q* p1 o! b% M3 W7 L+ X, n
  519.         CE_Low();                                        /* enable device */* o4 R' f$ m; ~( x: O: S0 a, S
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */1 B3 `2 ^2 r; X: Z  P( W$ t
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */* g! H0 S' ?) I) V/ S8 |2 g" l4 k
  522.         temp = (temp | Get_Byte()) << 8;        ( }0 C  J4 X+ E$ |
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */! B% E" k+ E5 q7 s4 V4 y2 J% E
  524.         CE_High();                                                        /* disable device */, V; U" r& n" T% y2 c
  525. ) A+ N1 Q& D, N$ s
  526.         return temp;$ |* W1 _- J5 z1 [1 o
  527. }- T2 O& y! s! v/ ?

  528. 0 k8 U' q% `# J& {* ^2 M7 Z
  529. /************************************************************************/) T, S$ R' ^5 A0 E
  530. /* PROCEDURE:        Read                                                                                                        */- r, b" k1 t1 u  t
  531. /*                                                                                                                                                */               
    ' G9 v7 t) |& |- f" }
  532. /* This procedure reads one address of the device.  It will return the         */
    ; N) ^' W  X/ Y+ b, R. m
  533. /* byte read in variable byte.                                                                                        */1 p# A! \& S. r. L  |
  534. /*                                                                                                                                                */4 O  i' ?! ~2 b4 |- `! x' O' Z
  535. /*                                                                                                                                                */
    . v. u, w) b( {. C
  536. /*                                                                                                                                                */
    - g2 M/ ?2 V, W5 S5 X  S
  537. /* Input:                                                                                                                                */
    7 r0 p7 j9 @3 C
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    8 s0 R3 f2 }6 J$ K4 ?5 Y
  539. /*                                                                                                                                      */0 ]# `& R2 o3 s$ X. m2 n
  540. /*                                                                                                                                                */' k9 t) q6 S+ R6 K
  541. /* Returns:                                                                                                                                */
    # K" g" k5 m" W- [5 {
  542. /*                byte                                                                                                                        */
    5 k% |2 k6 n/ v7 S. s% W0 X* s
  543. /*                                                                                                                                                */) h/ ]+ S& y# A# _' T
  544. /************************************************************************/8 B$ b, v2 H5 r! m3 v4 H
  545. unsigned char Read(unsigned long Dst)
    9 B1 Q# |: b; U. B, }- ]
  546. {9 U1 V+ Y8 B  y& B' u) O
  547.         unsigned char byte = 0;        ! E, n2 T* x# r

  548. : ?; c5 C; Q) }$ o% c
  549.         CE_Low();                                /* enable device */
    6 ~1 D4 m4 g  A3 S0 j* v
  550.         Send_Byte(0x03);                 /* read command */
    & l# |: y; X' ?, o; x( ]& W! m+ [
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */) E) O0 S  F# i( J- ?! ^! p$ m
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));/ `& M$ [& |. m5 K9 H$ @0 C4 v
  553.         Send_Byte(Dst & 0xFF);
    9 p+ y# P; h" \7 _3 {0 O
  554.         byte = Get_Byte();- N$ w  R' G8 \5 d! d& p% s5 R, H* ~
  555.         CE_High();                                /* disable device */
    + j$ e7 }* v3 q+ y+ Z$ |/ W
  556.         return byte;                        /* return one byte read */) T% U# C: s1 l+ }* ]: {2 e
  557. }
    & S: Y3 P# `. G* I* X

  558. 1 l( H- Y; s/ E( h
  559. /************************************************************************/& v; X' n$ ^& _& h1 E
  560. /* PROCEDURE:        Read_Cont                                                                                                */# u3 U, j& e% S6 Z
  561. /*                                                                                                                                                */               
    * v5 ~  n& M( n7 C- [
  562. /* This procedure reads multiple addresses of the device and stores                */) ~2 S9 }4 h# G2 W8 H
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ; S2 W) S3 c( C* w8 j4 P1 u5 {0 V
  564. /*                                                                                                                                                */
    6 ~% C' T4 v' q1 U8 i. O4 }$ F8 Q3 X
  565. /* Input:                                                                                                                                */
    7 j0 n3 k& Z- u: o) b( y; E0 V0 J
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, f' g1 r  H$ h
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */7 r3 i/ F. Y9 e8 l% ~
  568. /*                                                                                                                                                */
    2 c3 k2 z) T: ~% [7 k
  569. /* Returns:                                                                                                                                */; ^9 p1 m8 o2 B; c9 P2 u9 `
  570. /*                Nothing                                                                                                                        */3 W  E/ o9 e5 C! o
  571. /*                                                                                                                                                *// i' U5 ~6 x- R, B; g1 S
  572. /************************************************************************/
    % @6 z  u! S) `7 e
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    0 b, s* X* B! }/ Z
  574. {! W% o4 m: C0 n8 N
  575.         unsigned long i = 0;
    : r/ R. `! X' J! S  b6 Y) v
  576.         CE_Low();                                        /* enable device */
    ! y/ E8 E+ e7 N. J- j7 N
  577.         Send_Byte(0x03);                         /* read command */+ t* T: k- L  H
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    " |! M5 F1 V7 ]8 b6 E/ Q" k
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));# a% q2 S  s+ l0 b: E, e) U
  580.         Send_Byte(Dst & 0xFF);. T- y/ ^3 z: \# S6 O, V
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 m$ i$ J! I8 ^9 V. E8 B% ?
  582.         {. W9 k) k( g8 v
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */2 T1 H# {& I# S: e: R; t: ~
  584.         }
    4 X. q2 \) f& w
  585.         CE_High();                                        /* disable device */
    ( v& P6 f3 s" M

  586. 0 d* a. F0 M1 S  }9 ?5 y8 B3 X
  587. }& x* Z) e: P; c  N9 Z; M

  588. 4 F8 j& L9 F: l' n2 n) X
  589. /************************************************************************/& f% D4 H. l& `" |
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */2 O% R, Y5 y: P/ v6 x" m( Z* ?" A
  591. /*                                                                                                                                                */                ' }' ~1 k+ {% g9 g2 G3 a7 R* O
  592. /* This procedure reads one address of the device.  It will return the         */
    1 C- W- l8 |: P" _- q; @
  593. /* byte read in variable byte.                                                                                        */
    3 X$ |4 X& h% r; O& V( K' }' Q" x
  594. /*                                                                                                                                                */. Q; A, \3 @  c# Z4 }
  595. /*                                                                                                                                                */0 I# n1 h2 J9 U1 Y& E/ f
  596. /*                                                                                                                                                */
    5 Y4 W) [4 X1 {9 L
  597. /* Input:                                                                                                                                */+ H: W$ W( U! m6 d
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */3 }; A# s& T  Z0 k: L9 ~  n+ H: f
  599. /*                                                                                                                                      */! J& K- @* ^8 g; e" z+ [& @
  600. /*                                                                                                                                                */
    4 |2 d( T- ]) w+ O4 u" O* h2 ]! p
  601. /* Returns:                                                                                                                                */
    " |7 }* D- ]- W  `( r
  602. /*                byte                                                                                                                        */
    4 Z/ g5 V6 b8 O" Q2 {7 F
  603. /*                                                                                                                                                */
    ' U7 B" q, h5 y1 H5 f  V
  604. /************************************************************************/0 j$ F( |+ A0 z
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    2 D% _! w4 y& ]
  606. {; o1 R$ {+ e8 B2 e
  607.         unsigned char byte = 0;        # v8 ~1 s8 F, y* n2 d+ }9 ^

  608. 1 }- K& C; U! d3 q6 [! G) B6 k  C: |
  609.         CE_Low();                                /* enable device */
    $ h  @3 j) w: ^% z# \1 l+ B
  610.         Send_Byte(0x0B);                 /* read command */# x; u; B9 I! {; d* n+ ^# e  L
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */2 ?9 ~! y& K! h$ a' Q! V0 l
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));* D  Y, C8 t" i- W5 L
  613.         Send_Byte(Dst & 0xFF);
    ! c4 I, O! R$ X* U, d) M
  614.         Send_Byte(0xFF);                /*dummy byte*/
    " i% w$ k8 i; ~0 m: Z  m9 ^. p3 h
  615.         byte = Get_Byte();( S$ d$ \* x- a1 K' P4 X3 q
  616.         CE_High();                                /* disable device */
    / W4 F3 ]! O! _# A. Z3 }
  617.         return byte;                        /* return one byte read */
    ! X! h' D- J0 h0 z
  618. }. r5 B& B/ W/ g# j( D  q

  619. 8 S. E- ?. t3 s" Q  |1 J: _8 a7 u7 x
  620. /************************************************************************/
    . n. w  A9 q; a5 c( F: l
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    % P# V! }* D7 D& I: w
  622. /*                                                                                                                                                */                ; {; o0 m) T! O
  623. /* This procedure reads multiple addresses of the device and stores                */
    $ W: q& ?3 a1 c4 g4 y+ K  p2 Y' I! F
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    " ^" d- P9 D2 d5 e7 W6 P
  625. /*                                                                                                                                                */
    . \) c7 M! O4 e8 |
  626. /* Input:                                                                                                                                */
    3 {5 z' L" m$ {7 l5 v2 Z1 h
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. r$ F6 b- p$ o% ?* j: w: I3 l/ ^
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 ~% h; ?: Q$ R8 o" v0 O/ |4 ?% `0 r1 J  {
  629. /*                                                                                                                                                */
    2 a' n- Y7 D  _* U/ M6 ?4 J
  630. /* Returns:                                                                                                                                */3 m$ A6 l' t3 u- U. z  U9 g
  631. /*                Nothing                                                                                                                        */) R' Y9 a4 q' y4 H5 G
  632. /*                                                                                                                                                */
    + ]) _7 }% L; z" f. j( s7 A
  633. /************************************************************************/
    4 {1 v% A, ^' O: J% Q
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    4 X. O, p3 x) |& i
  635. {
    + Q% K  x0 z6 u
  636.         unsigned long i = 0;
    , i9 V( g/ h( T4 A
  637.         CE_Low();                                        /* enable device */1 o6 |7 |" X8 z- v- Q6 o5 J
  638.         Send_Byte(0x0B);                         /* read command */  X* I' A& _# G9 W) r; |2 ~
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, u# W) z3 |9 i+ @
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * q- G% a2 _3 ^7 \- r8 B5 l4 _
  641.         Send_Byte(Dst & 0xFF);1 ~* o+ l4 `! X/ ^) \+ k
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    + n) [6 B8 Q' Y
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */0 `7 H9 y& i) x
  644.         {
    ' a* U$ N! j) l# B9 o; d+ d
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ( ~* d2 ]) t0 x6 v. G/ r
  646.         }
    1 Z$ Z3 k* Z6 v. |/ j* O
  647.         CE_High();                                /* disable device */$ ]8 `) w& j/ a% t9 a, m2 g6 v: o
  648. }
    - @% F4 M- y2 T/ q/ q) P
  649. ! l: w) e6 m; S! p  W( ?- G% y! R
  650. /************************************************************************/0 {' x* b; d* Z. R: `, X* z* I' `
  651. /* PROCEDURE:        Byte_Program                                                                                        */9 k5 F( b! D; t8 v# l2 I+ {
  652. /*                                                                                                                                                */1 j4 ]7 ~1 f+ p9 B. z! }$ V
  653. /* This procedure programs one address of the device.                                        */
    0 P6 P" h1 H1 {) `8 |
  654. /* Assumption:  Address being programmed is already erased and is NOT        */0 x+ [7 a4 ]. K3 ~. Z, z/ [
  655. /* block protected.                                                                                                                */$ q$ J1 K0 c7 P7 Y! l( `3 M5 c6 I
  656. /*                                                                                                                                                */# x8 z* Y" L- D" [
  657. /*                                                                                                                                                */  `/ E' @! o% y- t
  658. /*                                                                                                                                                */
    . s1 Y3 j, U! Y* h& f; i
  659. /* Input:                                                                                                                                */
    : Q5 P2 m1 S( y: r7 Z" j% w5 p, T
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ T, d0 }' M( w) Q
  661. /*                byte:                byte to be programmed                                                                */: `7 G& E$ M. j% H8 _0 m
  662. /*                                                                                                                                      */% M0 Q) |; l9 a$ y
  663. /*                                                                                                                                                */
    : P. y" N; A6 N( D3 f1 u/ ?. g
  664. /* Returns:                                                                                                                                */# v0 Y5 r, O, t6 J
  665. /*                Nothing                                                                                                                        */! n3 s5 A# n" h; e, V( H3 N0 s
  666. /*                                                                                                                                                */
    4 E+ d& X4 n3 Q3 N% l& \) s( l
  667. /************************************************************************/
    * q" g/ z, P" y) a" T
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    # }0 |$ z" U% I: d3 s* e
  669. {
    : L% M: c% U3 F, r; Q
  670.         CE_Low();                                        /* enable device */
    " U% E# [/ e3 r1 j$ D; j
  671.         Send_Byte(0x02);                         /* send Byte Program command */& F0 g: t$ z1 R1 k# p$ H- J" b( f
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    / S5 w. c5 A, g% k
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));$ X- b# N$ Z2 @1 q0 }! r, ^
  674.         Send_Byte(Dst & 0xFF);
    . I/ t+ O% c8 r. D
  675.         Send_Byte(byte);                        /* send byte to be programmed */- M* O( l; Z- z0 B; S
  676.         CE_High();                                        /* disable device */. W& o/ j4 ^* L
  677. }  r/ H. D: r5 m% D( p- R1 W
  678. 9 v8 v( ~: l$ \4 q# c, j$ ~
  679. /************************************************************************/
    $ R1 ]9 i% Y0 L3 E  {/ X
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */( X2 g3 N0 n8 I
  681. /*                                                                                                                                                */
    1 _/ b& U* O1 y4 P9 m8 P6 S( Q
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    5 _+ Q- q+ B; F5 g2 u
  683. /* the device:  1st data byte will be programmed into the initial                 */. r! H7 V! z! s0 @& @0 ~
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    9 t, b! p) ~5 b
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */6 s. H5 d  N& U4 C' g  `
  686. /* is used to to start the AAI process.  It should be followed by                 */  @& d8 X$ d/ {/ |, ~( o* H4 A: `$ I0 i
  687. /* Auto_Add_IncB.                                                                                                                */# J1 p' x6 P* c/ C  l- m5 w( N; O
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    6 }+ a$ D" ?: ~$ {) C
  689. /*                                block protected.                                                                                */+ E9 E3 i+ |2 `( r
  690. /*                                                                                                                                                */
    ' _/ f' n% y% w9 A
  691. /*                                                                                                                                                */
    $ S9 g; @1 W' ^; M9 o& l
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */- `0 ^: e6 Z4 }
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */! l" a) s5 _0 q+ {: t4 l
  694. /*         unless AAI is programming the last address or last address of                */
    2 l, C( Q' i  ^
  695. /*          unprotected block, which automatically exits AAI mode.                                */6 T+ Q% v# h) ]: V1 N
  696. /*                                                                                                                                                */+ K; a) O0 q! G; `8 G5 O5 R' S
  697. /* Input:                                                                                                                                */
    - M0 F  B9 @' @+ Q! p
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 _1 F: `; p! t
  699. /*                byte1:                1st byte to be programmed                                                        */( t; K! x0 s1 ^' A7 L
  700. /*      byte1:                2nd byte to be programmed                                                        */' _+ p& R8 D+ L5 @
  701. /*                                                                                                                                                */7 F. T& I, d8 R5 R4 ]
  702. /* Returns:                                                                                                                                */$ C, I1 r/ Y/ F" w
  703. /*                Nothing                                                                                                                        */
    * o. g5 Z; c% W, l; l
  704. /*                                                                                                                                                */
    6 T2 w3 x4 x- `; j8 H# X+ L
  705. /************************************************************************/) b+ T: v# {+ m% B, b1 b
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ' N* T2 M9 t# V" y! R
  707. {& t4 M# ?5 m$ I; y
  708.         CE_Low();                                        /* enable device */
    : C, K3 {$ h' Y  t# D# T
  709.         Send_Byte(0xAD);                        /* send AAI command */) D- v* \) f9 ~0 v
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */; c7 h1 `) D+ ^  g+ N4 H
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * W$ W3 w+ M) Z5 B# K
  712.         Send_Byte(Dst & 0xFF);
    # y4 X2 Z9 c- M7 E- H, s0 ~) N
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + M1 M2 S% C) k# J# B
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */. l5 P1 r# u7 S2 s: v6 i/ z0 P. Q
  715.         CE_High();                                        /* disable device */
    $ ?" H* g" F, @. |9 j) [
  716. }/ @: c- F9 d$ y' u' e

  717. & i9 p9 M8 {+ P0 e* r
  718. /************************************************************************/
    " t# u5 O9 s1 l! M1 R& G
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    $ L4 D; n( A0 k+ j4 [9 y
  720. /*                                                                                                                                                */
    7 j7 i. k7 u/ `# f) r1 L
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    + `( g: A2 [  @2 R
  722. /* the device:  1st data byte will be programmed into the initial                 */
    / B/ c) h5 k$ M, Y, m4 ?& ]
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    * O1 c& ~8 _* Z+ D0 y8 _: Z
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    3 v0 B# O3 Y" f# N& ^$ y. \: C' Z" V# v
  725. /* is used after Auto_Address_IncA.                                                                                */
    $ t1 h$ [9 c  r, p- ~
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' O& d6 k6 _' M  b) b; h% l3 Z
  727. /*                                block protected.                                                                                */
    / `- W4 J% b& y4 C4 \% m9 i. D
  728. /*                                                                                                                                                */2 f- z2 k1 ^2 L) L5 |  \
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */6 u5 H3 E/ p: f) c) Z  m$ U
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */2 i6 l& c$ ]( D* w+ n: w) K
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ( k# v6 z! q" L1 K& ^
  732. /*          to exit AAI mode unless AAI is programming the last address or                */) }' G- w6 {# f$ E1 O
  733. /*         last address of unprotected block, which automatically exits                 */
    2 I" G! ^" Z$ r$ O
  734. /*         AAI mode.                                                                                                                        */
    ' o1 m& K3 J( Q+ s
  735. /*                                                                                                                                                */' F( h, j5 o- E7 H
  736. /* Input:                                                                                                                                */& e6 T) M! K5 X7 b6 A/ u, f
  737. /*                                                                                                                                                */
    2 @/ |. V. V* f3 Y# m$ e
  738. /*                byte1:                1st byte to be programmed                                                        */
    2 S& I, s, m& q+ q% I8 `; Z7 V
  739. /*                byte2:                2nd byte to be programmed                                                        */3 C7 _4 D; m0 R$ K8 `
  740. /*                                                                                                                                      */" L5 Q" _( C- |+ a  J8 \0 t2 a
  741. /*                                                                                                                                                */
    . z( D7 R, O& R' e# \' ?: t
  742. /* Returns:                                                                                                                                */" A1 w* `& ?/ W
  743. /*                Nothing                                                                                                                        */0 [2 `. a" s( k* l; _
  744. /*                                                                                                                                                */
    6 x# n# x, k* O% c- U% k+ R
  745. /************************************************************************// H$ [; l1 o5 p. a% h8 z
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)7 O) t; G( K6 K
  747. {. N1 [2 b& i( W* C9 O
  748.         CE_Low();                                        /* enable device */
    4 T0 S9 C. G2 w# W5 i
  749.         Send_Byte(0xAD);                        /* send AAI command */; ~) H4 v1 e& R" c& S, p6 w6 O
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */  I7 {; }$ _. C* y7 Y
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    + u! t/ W& l1 K6 Q
  752.         CE_High();                                        /* disable device */
    * D0 }% X6 U9 Y$ Z/ {* c$ D
  753. }4 j: m+ W5 W3 j: [9 s
  754. 8 b( q& A* }. |0 G6 q8 e
  755. /************************************************************************/0 }. G6 y! H7 M6 g) B! p
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    , H+ {- b* M4 `7 s2 K9 N
  757. /*                                                                                                                                                */
    " E+ X+ U: c9 z# o, x. q, o
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */( L6 f- X! o* v  `' N9 `
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    % k: a4 w$ T3 A; x; A% Z
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */% y8 P# \' B: \$ |9 F; w
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    : b0 N, Z/ R1 m
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    % l1 Y* t9 P: f# ?0 g4 n2 W+ k9 ~/ X
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ' M$ O3 [0 u+ i, ]% R. n
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */$ q$ T% \: ]5 I+ {8 ?  r
  765. /* Assumption:  Address being programmed is already erased and is NOT        */  L0 e) t& U! a, }* ^' g
  766. /*                                block protected.                                                                                */
    ' u3 _; P. e: b8 G
  767. /*                                                                                                                                                */" L' T* Y/ L) Q
  768. /*                                                                                                                                                */6 B& @5 ^. ?" J% ]6 [& @
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    6 w1 h' M: q: v- c
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */$ i* p- b" N" m7 |2 N% D' H7 u
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        *// S! ~# ?7 a% X7 W( H( k  t$ [
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    ; h8 n9 {* q! ^
  773. /*         last address of unprotected block, which automatically exits                 */- s9 l  h% S* t4 S! `- N, G
  774. /*         AAI mode.                                                                                                                        */
    , o8 I+ N# }% l0 }0 E% S$ N
  775. /*                                                                                                                                                */" j) g* p7 u# o
  776. /* Input:                                                                                                                                */
    % [2 I2 L- p7 }4 C7 V# }  o
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 L* i  k0 f/ |9 V# u7 X
  778. /*                byte1:                1st byte to be programmed                                                        */
    & w' t6 e: `7 m+ V+ Z4 H% ^( |
  779. /*      byte1:                2nd byte to be programmed                                                        */" f- ?: Y+ T, W( s1 J
  780. /*                                                                                                                                                */
    . A2 Q# r0 R1 {) ~1 W
  781. /* Returns:                                                                                                                                */
    " G9 J* J: c, u5 B8 x* \3 Z
  782. /*                Nothing                                                                                                                        */6 [  s: k! _7 Y
  783. /*                                                                                                                                                */0 I/ l7 c/ m. w( B
  784. /************************************************************************/. s+ s% A- \( F0 N! R
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    3 j% w# J9 ]0 U$ w0 u
  786. {& d  }& |7 B1 Z' ~( e
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ! c, c1 [) v3 m3 D/ B! M
  788. 8 l+ Q* l$ Z' X% T
  789.         CE_Low();                                        /* enable device */
    ; b8 A* S' c9 ~, j
  790.         Send_Byte(0xAD);                        /* send AAI command */% z& ?+ R, U1 o' w
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */; c/ I! x8 O0 `3 b2 A
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));+ D% Q" E) W! x% \* G  n
  793.         Send_Byte(Dst & 0xFF);4 x3 V( @% R; x! m
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        , w# o7 j. \" ?$ ?2 q1 W! \
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    $ W5 x% U0 j& `& y3 j5 H
  796.         CE_High();                                        /* disable device */
    $ s! u2 e1 ~3 q' H
  797.        
    ! E0 l3 z; O; j2 e; f/ t
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */! J0 x0 x2 \, o( p+ W6 e" ?
  799. + P/ q! k& }4 X9 r, B, E! G
  800. }
    % F6 c4 V& G8 I# ~
  801. / x  D. B! \+ Z* [- y
  802. /************************************************************************/
    + p7 V8 z3 U" S/ c% D3 _9 R3 K
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */% E, w9 T# i% j3 A
  804. /*                                                                                                                                                */0 r0 S1 {* i! R0 S! r9 M
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    7 ^0 O# {6 a7 x; h' k! C
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    $ K  p- a7 p: G) l- M' u3 t
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    - S" c; L. v0 Q
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    , N4 H# X2 ^7 W, n
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    # l2 S7 E! f9 O/ |
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    ' s- W5 b% j9 _
  811. /* used after Auto_Address_IncA.                                                                                */
    1 r1 v) A4 W; x& r! g6 o: o
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    & C; [! H9 k& W- M& S: V2 b# |2 J
  813. /*                                block protected.                                                                                */
    8 k, I: N. e, B& D% V! }+ h0 w- C, a
  814. /*                                                                                                                                                */
    9 Q. y6 n3 ~8 d
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */1 Z5 T! J$ D/ Q" ^7 g
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    & X! Y/ I$ a. T0 j8 l- u
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        *// ?& d5 \( G. X, j- V# k' z
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    2 U5 e& f2 z' a3 ]$ h3 m
  819. /*         last address of unprotected block, which automatically exits                 */! N7 t$ {+ \" a3 N! G: J
  820. /*         AAI mode.                                                                                                                        */2 n0 d: T0 T8 F( e9 H
  821. /*                                                                                                                                                */
    4 d: f9 z8 F# E- q! `6 b; A/ V! @
  822. /* Input:                                                                                                                                */$ y# q1 D+ t$ V. A2 w  k7 m. k& a  k
  823. /*                                                                                                                                                */
    3 `5 p7 k0 t, s6 E3 C" T3 P
  824. /*                byte1:                1st byte to be programmed                                                        */
    - B9 Q% k9 C+ t. [  N
  825. /*                byte2:                2nd byte to be programmed                                                        */" p+ r2 ?: L6 _$ C- g
  826. /*                                                                                                                                      */
    , {+ |4 s) M! F& \- j
  827. /*                                                                                                                                                */
    : _/ [3 s% d+ _& b; ^* t7 M2 v9 V  U
  828. /* Returns:                                                                                                                                */
    ; Z# [% I/ g# w! R( |, J1 @
  829. /*                Nothing                                                                                                                        */
    # t6 p9 e+ G9 Q( Q, l( K
  830. /*                                                                                                                                                */
    ( g5 y# V# H' E+ ?8 c
  831. /************************************************************************/
    1 G% B9 C4 _8 {
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)$ b4 b, ^8 F$ H, `) @
  833. {
    # [" M+ @: y0 \2 Z
  834.         CE_Low();                                /* enable device */% J) }- z8 p: s' m! a5 ^
  835.         Send_Byte(0xAD);                /* send AAI command */
    7 H- A. [3 c! g8 x5 s/ O
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ; `/ Y0 P2 Z8 }8 j% U  ^
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ; P- t/ o( R; w  a' z, V& \
  838.         CE_High();                                /* disable device */1 k6 J' [9 W$ i
  839. & v6 `! u! k# o2 g$ C2 j2 k
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    0 u6 _' Y0 N6 `& @! `

  841. & `4 F; S3 i# I& W' |
  842.         WRDI();                                 /* Exit AAI before executing DBSY */9 F) U) ~( O3 {+ \2 W  D
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */8 \: }6 T# C) W; v
  844. }& @/ f1 [' Y/ P
  845. 8 V. ]# E6 H. f- x; K! D3 m; w2 p
  846. /************************************************************************/# z* J2 i% f6 ?* a. q9 p
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    , d6 n+ }& l. ?
  848. /*                                                                                                                                                */+ i/ t; A2 R. B* X& {: a1 Q
  849. /* This procedure erases the entire Chip.                                                                */
    " k' u, O4 a( j. H: ]: P
  850. /*                                                                                                                                                */. Z6 d: D* z; @: R
  851. /* Input:                                                                                                                                */
    * {2 l& }! h( A. B
  852. /*                None                                                                                                                        */9 {8 h7 ?1 d- `0 L; H1 `7 H
  853. /*                                                                                                                                                */$ |  |5 ~4 ~6 b1 C
  854. /* Returns:                                                                                                                                */, v5 ~% `; y, F& \' b- P
  855. /*                Nothing                                                                                                                        */% Z% M( j- A/ J4 F* D8 y! ]: W! @
  856. /************************************************************************/  E7 m/ v3 O3 B3 _- w' ~
  857. void Chip_Erase()
      Z( g; ^; a$ k6 P8 _$ u
  858. {                                               
    % l2 a, Q8 z' y1 d  K+ C
  859.         CE_Low();                                /* enable device */% k) s* T. H- f7 f$ ^
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */3 \3 E! V4 c6 N
  861.         CE_High();                                /* disable device */
    ' Q. q* `3 `  i* _& v1 D9 s" Q
  862. }2 Z5 p; u$ o5 Y, b/ m/ v
  863. ; t( x' G' ]# }
  864. /************************************************************************/
    " X$ I2 o' q2 |( [! b3 H  A5 W
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ( f  o& {- @- W
  866. /*                                                                                                                                                */
    ! j$ d+ z1 g% `
  867. /* This procedure Sector Erases the Chip.                                                                */7 E  K4 x% P  ^" r7 K
  868. /*                                                                                                                                                */
    1 n9 G# }' z; \% P0 N$ E4 L/ ]5 T' g2 X
  869. /* Input:                                                                                                                                */" y2 `- s1 h3 j7 I8 i, u! @4 p5 y2 V
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */! K6 o4 k+ S9 }2 i
  871. /*                                                                                                                                                */
    , {) U9 B/ v5 D' o3 c) ^
  872. /* Returns:                                                                                                                                *// K9 L' h+ A9 m* l7 `& K$ v* z
  873. /*                Nothing                                                                                                                        */" ^8 L1 Z. ^  @6 N8 o
  874. /************************************************************************/
    & `4 w3 ~6 p- p2 r/ R1 l/ `5 i
  875. void Sector_Erase(unsigned long Dst)2 U1 ~( \0 N' M/ V
  876. {
    + l6 m) Q  t8 e. b$ l8 n! `* h6 }
  877. 5 h0 Q; \6 e# K- w4 h

  878. ' {/ m2 z5 B! T. M0 H0 @. ~, f
  879.         CE_Low();                                        /* enable device */
    8 ?& O/ z  Z! J0 i! M/ b2 v
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    . @4 {) b' C! X3 [; Y3 D, h
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 P3 U6 i3 m  w8 d/ J: d
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));, m, K' ?. x+ {1 G
  883.         Send_Byte(Dst & 0xFF);
      ]/ o# Z+ f- Z
  884.         CE_High();                                        /* disable device */: @) Q% y% r0 i$ `3 U
  885. }        2 o4 c9 Q* N9 F$ t
  886. 3 ?7 H8 }; I& c, c- _0 J+ t
  887. /************************************************************************/8 r( B' E. [: G' M
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ) v' j8 I3 O8 i/ e; ~) ]. w8 ~7 N
  889. /*                                                                                                                                                */
    ! }3 C6 B$ C- t6 h0 d, O
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    2 a1 v9 w) y' m2 Z/ N8 k& V
  891. /*                                                                                                                                                */9 ]& I) p9 a! V) E' j
  892. /* Input:                                                                                                                                */3 l$ \5 @! e( ^3 L5 v
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ; F) @5 X# b! }, w
  894. /*                                                                                                                                                */, O/ s6 G; N* |
  895. /* Returns:                                                                                                                                */+ H6 R! }9 Z! C
  896. /*                Nothing                                                                                                                        */
    $ ^! R, p1 H& n7 j- e" m
  897. /************************************************************************/
    , b  X1 D1 X* D7 \1 n' n7 ]8 A
  898. void Block_Erase_32K(unsigned long Dst)) j/ E1 g5 ?& J' [0 B, G
  899. {4 c  _( P) L$ I" \; O/ e
  900.         CE_Low();                                        /* enable device */
    5 L: `/ {, Z4 U& d+ R
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */+ `% X% q; X; G" f
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 B2 U2 o) v  [5 Q: z9 C% O
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + u, ^! \6 y) b4 ~; a: t+ e+ M
  904.         Send_Byte(Dst & 0xFF);3 L6 r* B4 ]+ S# _" \
  905.         CE_High();                                        /* disable device */
    2 m# L) S' H6 ]- B# C% a. e
  906. }
    7 v: V" M& G1 q6 k) y/ M

  907. : d' U$ Q" d0 l- {! @& T, f
  908. /************************************************************************/
    ' W. M* z% j/ F8 p0 ], o) `
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    & ?* A8 _! X5 F$ n: ]
  910. /*                                                                                                                                                */
    0 _% r, M3 l& r* f
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ; Y) |6 X% n; M6 I( `
  912. /*                                                                                                                                                */
    2 t7 d# x1 G1 T' C: l. ~
  913. /* Input:                                                                                                                                */
    * _. h* a# L- }9 }8 h8 `5 V
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * J/ H7 G2 z* j& O7 x# d" l  u; {
  915. /*                                                                                                                                                */6 y; |% L$ e4 f* S0 |
  916. /* Returns:                                                                                                                                */
      v" F5 F: ~: O; R
  917. /*                Nothing                                                                                                                        */* {2 f7 r5 a* W$ N6 T2 v. G
  918. /************************************************************************/
    ' f& ]1 a5 J9 t' @
  919. void Block_Erase_64K(unsigned long Dst)" ^2 B: ?0 j# ^9 F" w
  920. {7 M1 J& h" k+ G1 r' x* K3 h
  921.         CE_Low();                                        /* enable device */
    & ]( k2 P) d# X6 i
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */% f: r+ e: K4 c; M
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 P1 I! y5 p: Y2 U( R  |- n
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 x- \; g7 X& b
  925.         Send_Byte(Dst & 0xFF);% P0 Z$ v! T% a/ k# K
  926.         CE_High();                                        /* disable device */6 ~" k9 g% F7 w/ j" `6 X
  927. }1 C" g; N. M( O0 S) v
  928. 7 t2 Q) I& H& @4 E
  929. /************************************************************************/) X# R  s$ F2 l% x% l" C
  930. /* PROCEDURE: Wait_Busy                                                                                                        */2 k1 N7 _( p9 P1 x- v/ k' e6 `! Z
  931. /*                                                                                                                                                */6 Y: B# w4 k2 ~5 W7 y3 a) l0 R0 j3 r
  932. /* This procedure waits until device is no longer busy (can be used by        */
    5 @: s& e3 o. ?3 g) J- g: J
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */7 S3 P4 q, E5 F3 ?; E
  934. /*                                                                                                                                                */
    2 J' g* X' s! H8 ^2 v3 L* i. r6 m! f
  935. /* Input:                                                                                                                                */8 [( M( R1 I9 e5 `
  936. /*                None                                                                                                                        */
    $ Y1 Y, D8 D" ^3 I2 L( p2 A- Z
  937. /*                                                                                                                                                */
    + v- _+ P3 y/ h5 E
  938. /* Returns:                                                                                                                                */
      [& R) [; |' l# p
  939. /*                Nothing                                                                                                                        */
    ) d# t1 B% W% ^; H, V2 _, ?. ?; g0 ?
  940. /************************************************************************/
    % b; M) \. \( M1 _3 |! t
  941. void Wait_Busy()
    6 N- H& N1 e7 l
  942. {
    : J8 S" e  A$ F: P. _
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    & m" s$ y$ f% ]; V* q& H  N
  944.                 Read_Status_Register();! Y; A, i0 [, @$ n2 k
  945. }
    : M* S( ~" S$ E) I1 y
  946. ' [9 V9 ]  s7 n4 ]7 f2 q+ B
  947. /************************************************************************/
    , A5 S. P) p1 O- _" V: O/ E; ]& ?
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    7 Q- o% [5 X4 K" j, O4 A7 t2 ^
  949. /*                                                                                                                                                */9 K  M0 m% y+ J6 s0 ^
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    " B- m( w- b  p8 r' R- @$ r
  951. /*                                                                                                                                                */+ f) q% X3 x% u2 L9 E5 L+ P
  952. /* Input:                                                                                                                                */
    ; K9 h; M4 G/ V. E# N- Q& l- h
  953. /*                None                                                                                                                        */
    5 a% L% z3 H3 V
  954. /*                                                                                                                                                */; u5 I+ F6 u, x* \' @
  955. /* Returns:                                                                                                                                */
    ! F- e+ b3 n' ^/ k8 [
  956. /*                Nothing                                                                                                                        */
    : G3 Z4 s  \6 E4 h0 b' Q& y
  957. /************************************************************************/
      c  R% e5 ?% ?
  958. void Wait_Busy_AAI()
    6 }5 M: `) D! o6 ~8 \4 |" S
  959. {5 P7 g' j3 u( O
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */# R/ m& j, N, {1 \$ H$ ]2 ~
  961.                 Read_Status_Register();9 |3 M' J6 M( D0 l4 Q
  962. }2 Q1 q' l0 o6 V% D- @0 k

  963. ! m) G7 k0 Y; i  S: S+ N+ x# g7 U( L
  964. /************************************************************************/
      c5 U6 j' m, l' Z. {5 R7 k# k
  965. /* PROCEDURE: WREN_Check                                                                                                */
      D$ v+ L4 c5 c
  966. /*                                                                                                                                                */
    . m9 v" D; z% q8 N
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    1 y, C1 O3 t; L# b, ^
  968. /*                                                                                                                                                */
    % H$ j$ Y1 o* O1 V4 }# D
  969. /* Input:                                                                                                                                */
    # m- q/ g  p; \6 `7 m$ G4 F
  970. /*                None                                                                                                                        */
    - Q2 d5 G& T9 z6 l* F
  971. /*                                                                                                                                                */, K* |) X) h* y. x; r) n9 t& ]
  972. /* Returns:                                                                                                                                */% P7 I/ w2 r3 V) S/ Z
  973. /*                Nothing                                                                                                                        */
    5 F! l$ l9 l0 M0 u' j
  974. /************************************************************************/' g$ c- W0 F+ {/ O. H
  975. void WREN_Check()8 k/ L* r, Z2 c+ A1 }4 b# h
  976. {" m: p: I# l- p5 O
  977.         unsigned char byte;
    * T% P; w6 [8 q6 J6 k2 z/ c/ k: P3 o
  978.         byte = Read_Status_Register();        /* read the status register */
    8 ^7 u1 x4 Z& C+ ^  b
  979.         if (byte != 0x02)                /* verify that WEL bit is set */3 a4 h' E2 Z- ^; i
  980.         {
    ( R# @' ?0 Y2 @4 S* m
  981.                 while(1)
    " @; s# ^* O/ v- _1 |/ F5 q. _/ K! b( S
  982.                         /* add source code or statements for this file */
    5 q' T# W9 T" y; b/ t0 Q
  983.                         /* to compile                                  */6 r# D0 z$ Y) L8 J( K7 x. @' I
  984.                         /* i.e. option: insert a display to view error on LED? */
      R5 L1 u0 y& t( b# _
  985.                  
      q( g- y$ t& J" N! [( B" N7 D
  986.         }
    / d! V6 e& V. n- v
  987. }6 i/ `7 N& @4 k' P: O
  988.   q- z2 d5 l0 D5 b
  989. /************************************************************************/
    ; n; K; g6 X$ c) K' G7 a
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    : P* Y- q1 ?% m
  991. /*                                                                                                                                                */1 m5 w6 [7 G# v& {/ h* Q) ~
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    % Q" `1 h# z6 t' [! J
  993. /*                                                                                                                                                */7 V9 {. q( M3 O( }! \3 @
  994. /* Input:                                                                                                                                */3 Z" D, a4 q/ S( I$ i7 C, M4 l4 N8 N: n! n
  995. /*                None                                                                                                                        */8 D! k5 d# x( u& v) L- W! _
  996. /*                                                                                                                                                */
    / I0 w7 r3 m5 B. E! G
  997. /* Returns:                                                                                                                                */
    & z: D# x: R  L. ^
  998. /*                Nothing                                                                                                                        */8 I+ e2 o: \) j9 t# i9 ]. |
  999. /************************************************************************/
    ) X# p3 y' a& a6 i* J1 v& H* g/ g0 q( B
  1000. void WREN_AAI_Check()
    ; B6 b+ _2 k9 w" p1 l! D
  1001. {
    3 }- k+ P# G5 k3 v0 r
  1002.         unsigned char byte;" K4 o, Y" d- K
  1003.         byte = Read_Status_Register();        /* read the status register */  f7 ]: y9 r2 B" n. i
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */4 f0 k: Z' B$ |9 f1 D+ E
  1005.         {7 [7 b' T, R* x) x0 V
  1006.                 while(1)               
    + p; I5 M2 Z3 V+ n# O: E$ G- ^
  1007.                         /* add source code or statements for this file */
    $ B' }5 L) g0 u, t' L3 H* v
  1008.                         /* to compile                                  */
    + X! Q, n+ W& a  `( |7 M* c
  1009.                         /* i.e. option: insert a display to view error on LED? */7 r5 M2 M5 Q6 a- \6 r, w
  1010. ' p8 b7 e' Z! @
  1011.         }
    * \9 }- q& j0 V# d% r/ `) k( d4 t+ H) r- U0 i
  1012. }  U! w% V% H% s, x& i

  1013. & l) g5 N$ n, V( n" y
  1014. /************************************************************************/
    0 U: c! s) Q) K; H$ q
  1015. /* PROCEDURE: Verify                                                                                                        */
    9 Z8 b; z+ ~  i  G& `. J
  1016. /*                                                                                                                                                */
    * l; T+ }* s, R  v$ a, L/ p- `
  1017. /* This procedure checks to see if the correct byte has be read.                */4 {' h1 O3 ^9 t$ S1 j
  1018. /*                                                                                                                                                */
    & O% _' B6 c  w) G  j% @" e
  1019. /* Input:                                                                                                                                */
      t/ \& ?! `" o
  1020. /*                byte:                byte read                                                                                        *// U+ d5 r1 }! V+ o% L7 ]
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    : |6 x0 N/ j- o9 B
  1022. /*                                                                                                                                                */
    & i0 d; Y/ o. k- ?* p+ }
  1023. /* Returns:                                                                                                                                */7 _% k4 F( D  h# N5 j! V6 g
  1024. /*                Nothing                                                                                                                        */
    - ]0 n2 f, G( \$ N0 V$ e
  1025. /************************************************************************/
    7 Z3 j' ~9 R& M: U/ }5 N* J" u, L" P
  1026. void Verify(unsigned char byte, unsigned char cor_byte)3 \! [8 w  f8 b
  1027. {
    ! T* h. x4 D4 X2 o" J
  1028.         if (byte != cor_byte)
    , x: C6 [6 T: c/ `0 e4 g
  1029.         {
    ( N' Y) y' ]* q9 a
  1030.                 while(1)
    8 v0 h8 H" a, \( a4 f
  1031.                         /* add source code or statement for this file */
    3 a/ o/ `6 ?( N' ]4 }7 T
  1032.                         /* to compile                                  */( o7 J+ R: v% t; x0 J
  1033.                         /* i.e. option: insert a display to view error on LED? */
    / X" y  \: s+ Y! a" I0 p. C) n
  1034.                
    ; p% [% i3 ^3 v$ w- \
  1035.         }
    8 v% I' q7 x0 u# }
  1036. }
    # n% P* x9 q0 s( n" c

  1037. $ j* f4 b8 Y! {6 _  \- }1 N
  1038.   l$ p' T. m+ P* I
  1039. int main()
    0 u* o& k% C4 D+ E
  1040. {( M& w' f1 U: h

  1041. 6 ?9 V) F$ V3 a! a$ J' H; I
  1042. return 0;
    6 z' Z0 l* b3 Q. m! a( ]+ {
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
6 M7 N, W' u4 Z. `9 ^   main()
# H( ?2 n  M; t, w# a+ k- G1 H   里面怎么是空的呢?2 X! J" ~- u/ u9 P/ A
   发一份给我吧2 r. \0 V2 _/ X+ }$ V9 B7 K
mail:luyijun2005@hotmail.com$ d; `6 J4 H5 s  i$ D# D! f
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
, B3 H! U# I0 U3 z1 a- J) H, u5 H3 ~. e- G7 T
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。# P5 H# x5 h( C3 X0 ^9 V4 q; M
EC的代码在哪跑,你看DS的说明,每个EC都不同的。& ?$ {$ D  G- y* I
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
- n( ?4 L; [- |+ I7 h/ R6 ^2 g上面几个问题是你没看任何东西而白问。! ~% M: c( R) N; B8 |
1 |" T: k' h! `
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
5 U/ l& n" y# _
( S/ }6 n: S/ i  L- Q关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!. i) D0 X8 _7 j
' Q9 k' |0 R$ R
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”; l5 X) j/ v: [5 M4 o9 f! r2 w
/ \' i* M3 T8 R! b) `; K/ n
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
7 x3 F; s' F7 p" r: }4 y  h( x# Y6 t
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样$ p% T7 H1 b% m* @
似乎要把SPI能support 到最大,这EC chip应该有好卖点9 D, {& a$ r& _
BIOS功能要不要强大,也就决定了SPI Flach的大小
2 r6 z: C! G$ ^% o5 t. X# f. P我是这么想的~让OEM去决定要挂多大!5 N. h3 H) k6 t# V" A" ^7 g- u, f! k
如果我司有BIOS工程师就好了~哈
" D8 l) }2 n! U/ }, AWPCE775应该算很新的东西,来看它支持到多大?
! ^5 m( y1 z5 n( G, ~7 k# l" j0 F0 Y$ L
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte5 @) k3 U! d1 A; S8 F/ w
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
0 R6 K5 w* ^# }: |2 c% ^( c
; G% i) \* L* }这份driver收下~希望以后有用到
- t1 `* s9 N; E9 [  [" N谢谢bini大大
& P0 ^; U- R/ d, }, {
/ W- v. Q; u/ y$ H/ L/ m很新很新的新手,如有错误请指正 (准备看第二家的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()3 `/ r9 Z) }; g* r  _
{
* k. k; c- \- c- C8 ]        unsigned char temp = 0;' i. _8 `1 L1 Q  _( t$ @
        CE_Low();0 w1 i$ g( n+ P- n# m  O# l
    while (temp == 0x00)        /* waste time until not busy */6 d) g/ g+ q0 L, ~+ t
                temp = SO;
! |' M4 Z" U8 U) P( W        CE_High();, j; ], D5 m# P9 j" Q
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)! ~6 W; [& f# f3 W- M: t1 g
{# e& B4 Q$ [7 |' h) T2 B5 k
        
7 t6 @7 a/ H( c6 `        unsigned char i = 0;
0 r' X- `, S: _% }/ x6 I        for (i = 0; i < 8; i++)
$ H, s% T7 _" y/ i4 q7 d        {" ^, f1 {) x* L( n
                , C" ~5 b- V  d# @4 N: {7 E) [( }
                if ((out & 0x80) == 0x80)        /* check if MSB is high */+ ~1 ?6 [2 t; `; Y
                        SI = 1;2 T0 m* X5 x! W: L: L0 Z
                else2 ]9 w5 c# ]7 I/ R- U
                        SI = 0;                                /* if not, set to low */6 A% Z8 t2 H9 S: @
问              SCK = 1;                                /* toggle clock high */
; Y- ~/ [: }8 m9 ]7 C1 W: }# A* {4 d, g   题            out = (out << 1);                /* shift 1 place for next bit */% T4 A2 x( e  {( I0 L
                SCK = 0;                                /* toggle clock low */: M9 a" J6 s# {
        }
& R1 [3 f  Z3 u1 P, `4 O}" K" z! I, q6 j( ?  J* w+ ~
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-19 21:54 , Processed in 0.076434 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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