找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54997|回复: 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/ {# E7 m3 Q' M* D" ]3 ^7 u
  2. 2 i) C4 u6 b# K1 ~( D
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory" `/ |5 c) F2 @5 a

  4. ! [* t, t6 D  Y. U' ~. O, M
  5. November 4th, 2005, Rev. 1.0
    $ `8 M: C9 U" H( R+ x
  6. 3 P2 i1 r5 }$ D9 n
  7. ABOUT THE SOFTWARE# G/ X, p$ Y0 Z' t6 U; _
  8. This application note provides software driver examples for SST25VF080B,9 l4 B/ O$ Z# [3 f) A
  9. Serial Flash. Extensive comments are included in each routine to describe
    1 R6 U0 ]: D! Z  r3 m- Y6 n
  10. the function of each routine.  The interface coding uses polling method - a+ t% @3 D1 \9 {
  11. rather than the SPI protocol to interface with these serial devices.  The) Q# g* }2 u% v. I
  12. functions are differentiated below in terms of the communication protocols; F- M0 Y. I- K; K
  13. (uses Mode 0) and specific device operation instructions. This code has been - P& r- S2 Q" H8 b
  14. designed to compile using the Keil compiler.0 @2 L* R1 V2 E; o$ q" H, u& h
  15. - o8 x: _/ ]5 V; O) P7 X

  16. ! X# R6 M: L7 @* d" Y
  17. ABOUT THE SST25VF080B7 Q, [( y2 c  K3 E" `" r* w
  18. ! x* T4 u% p% U9 R2 _
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    ! s/ f/ ]% x- ]
  20. conjunction with this application note for a complete understanding ( ~4 D* h0 m: {: A" y
  21. of the device.- Z" E3 t4 _+ G4 B+ B0 N/ \! n' q* {
  22. , T1 f" V4 O  V

  23. - z7 w0 m/ t' o# J- ^
  24. Device Communication Protocol(pinout related) functions:
    6 O. Y0 z6 I0 g& a+ `7 _7 ~
  25. 8 p2 C: ~6 x6 ~( g8 S5 p- l! @
  26. Functions                                    Function
    1 B8 u. |! ]; q" _! W6 d
  27. ------------------------------------------------------------------
    3 N) W- h# j; K& r3 |  W& Y8 I
  28. init                                        Initializes clock to set up mode 0.  f0 {& s! d: \& \; Y8 p. Q
  29. Send_Byte                                Sends one byte using SI pin to send and
    6 @$ Y7 l3 i9 K+ {( l  Z- x
  30.                                                 shift out 1-bit per clock rising edge
    2 y' H+ g- X' R9 p7 L& T3 t# O
  31. Get_Byte                                Receives one byte using SO pin to receive and shift + K3 X$ o. c3 J& p" J
  32.                                                 in 1-bit per clock falling edge! U$ L3 b' p7 j4 c! V
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    ; w% T3 J, d% P3 }$ M7 E
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    % X9 G4 F% @2 J5 o+ X* q' b% x
  35. CE_Low                                        Clears Chip Enable of the serial flash to low0 a4 h8 Z$ a7 `6 T. N6 N
  36. Hold_Low                                Clears Hold pin to make serial flash hold/ o% I6 z- U! V: t( c2 Z+ h4 I
  37. Unhold                                        Unholds the serial flash
    4 J! ?4 ~2 |/ L  T% S. Y0 l5 x
  38. WP_Low                                        Clears WP pin to make serial flash write protected4 z3 Z& u: L9 h5 A! f# X
  39. UnWP                                        Disables write protection pin
    1 x( A2 A1 I. a9 v, s( c6 v+ \5 r- _: i

  40. 0 O# r; K/ T; q& [3 z1 F+ s4 e
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code$ z& g& o* u: K& |" J5 w! H
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your  c0 J7 }5 F7 _( J# m% D9 k  B
  43. software which should reflect your hardware interfaced.            b2 i( L1 ]& Y$ H6 R7 K: M6 N

  44. ( M* q# A5 N) C" G3 F

  45. 9 R2 X4 e+ T1 z6 Z- P; M
  46. Device Operation Instruction functions:; n# U7 b) a8 j3 H2 ]( e( F1 Z4 `
  47. / _. ^1 E9 ^. }
  48. Functions                                    Function" t. b; e! \# |) w+ ~* W1 x1 f
  49. ------------------------------------------------------------------& Z: H. X% s% V
  50. Read_Status_Register        Reads the status register of the serial flash  s6 l7 r: u0 u; y% `$ K+ p
  51. EWSR                                        Enables the Write Status Register& _: z4 ^5 B6 C% ~9 g/ n! \
  52. WRSR                                        Performs a write to the status register1 [$ q% i9 b, ^# P9 f+ A; u. V' B
  53. WREN                                        Write enables the serial flash
    0 L+ ?$ v# @* u# ~+ E2 r
  54. WRDI                                        Write disables the serial flash$ P2 t( g# a8 i4 ?
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    " V8 S7 H+ {) s1 s/ i8 J
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    % |0 c8 l9 h& p( n
  57. Read_ID                                        Reads the manufacturer ID and device ID
    4 X" p$ t+ r. H, }" }* a; L0 u
  58. Jedec_ID_Read                        Reads the Jedec ID
    9 s9 b& V* b0 C$ v% z
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    / H. q' P. v2 E+ d! W9 O3 w8 M5 b
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)* k5 H% ?$ f9 }  K! u
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)  |( J/ H# W  X* T
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)! O) J1 T1 O( Q  I5 j" m/ g
  63. Byte_Program                        Program one byte to the serial flash
    3 j  I0 v+ Z& D  W+ Y' D6 Y- u
  64. Auto_Add_IncA                        Initial Auto Address Increment process/ d6 ]: t) w. @3 d0 U
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    , y9 {. {+ L. J2 a
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    - |* I) B4 w: ]  M; M
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY+ z" ~7 }, a8 ^) L  x& G  b; S
  68. Chip_Erase                                Erases entire serial flash  q6 N, Y, W1 k' w  `$ c
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash! V) M: ]+ ^% K8 c
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    8 A- N2 N8 q7 n: B, L' J
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash( v7 {/ \/ H& \- z! n
  72. Wait_Busy                                Polls status register until busy bit is low
    ( C) \! F, n1 T  H- x& r
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming1 s8 U6 {# e7 }; A0 w
  74. WREN_Check                                Checks to see if WEL is set
    ; @7 F) j. [. l! k7 @
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    3 V- E; ]  m6 N+ f4 i
  76. ; {: W4 G! M. z, u

  77.   F! r  y1 z7 Y
  78. " T1 F: d/ l% N
  79.                                                                      3 H3 ~' |! f: R. }9 D+ G; K% R
  80. "C" LANGUAGE DRIVERS
    . w# V3 K7 H$ c" A5 f/ [  j& ?2 \

  81. 3 G& g, M, B5 ~1 J
  82. /********************************************************************/3 R4 F6 h0 @' x  G% U& I
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */( ~2 G- C0 J1 M& p
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    ' Q$ i3 i/ _( E* [- v+ K
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    0 v) _9 {% a+ ^- }' X$ ^. c+ _% `+ l
  86. /*                                                                  */
    1 k/ l- O8 R1 d* r
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    7 w5 G* F" h, o( K
  88. /*                                                                  */
    1 k% @/ q; C5 o
  89. /*                                                                                                                                        */  X$ b; ?; g, Y5 U! F, [5 A
  90. /********************************************************************/
    3 X4 \" v' W& e1 n7 x
  91. - A) _+ `0 @& C5 a; D. x% ~' P
  92. #include <stdio.h>
    9 d" p) D7 Q+ f9 N2 r3 g. }
  93. #include <stdlib.h>
    6 X# Z. ^* n: o/ K- z$ V& r
  94. 0 m2 j) u- q3 j: I2 G, n4 J
  95. /* Function Prototypes */# p: T, s* t& P5 t9 g( f3 k$ Y

  96. / `% g1 ~3 P5 v. ~
  97. void init();; K5 [, v- m1 k8 `$ U
  98. void Send_Byte(unsigned char out);
    - F3 N# h0 [5 n, E
  99. unsigned char Get_Byte();
    6 W2 m& N9 O4 B! v+ m$ ~* _3 M/ a
  100. void Poll_SO();
    , @) ?; X8 l1 Y7 }( E
  101. void CE_High();# X* q4 O/ D( R
  102. void CE_Low();. C# @  ^# v, R( @, x) n7 L6 o5 M
  103. void Hold_Low();$ S3 P% n0 Z: y. Z2 I
  104. void Unhold();
    ( `9 l8 H& Y, x/ O* o$ U' }
  105. void WP_Low();' j6 u9 b& ^3 U
  106. void UnWP();
    8 O& T, }3 b/ a' r6 F8 y& g( f
  107. unsigned char Read_Status_Register();
    4 r7 f1 X; c- @; v
  108. void EWSR();8 U  o- d. e$ b7 n- |5 K1 S
  109. void WRSR(byte);
    ! n0 U. z4 g  ^- o* X; i9 X# u
  110. void WREN();
    2 |) ]5 U  F% ?) }  R3 h% w
  111. void WRDI();' o' J+ `; {2 x/ d8 ]2 W
  112. void EBSY();2 P& @, W& H; K$ h8 \+ P) N
  113. void DBSY();
    " G# c$ _' w0 M& r7 }5 S
  114. unsigned char Read_ID(ID_addr);
    1 Y! \6 s6 z* c. d4 j
  115. unsigned long Jedec_ID_Read();
    ) V3 t  D' Y3 M: o1 \! X0 @
  116. unsigned char Read(unsigned long Dst);
    ( v1 O  p: x1 e* N+ B
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    " N- M' C4 N/ Y7 h' n9 O% ^
  118. unsigned char HighSpeed_Read(unsigned long Dst); 1 c$ t" ]9 a2 g# L0 c+ l$ J3 ^
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);6 O1 V1 D' w# n& `
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    " k( ]* X, o  S' o' v* q
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);9 R0 P, p1 z& Q" ^
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);/ I9 ~+ o9 o. L! t! W% \
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);  \- J: j( W, F5 W5 C/ {" E
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    ! X6 P& Q* s0 x' L. @: G; [. B
  125. void Chip_Erase();* u  w6 H- x, G5 x) ]( d( \$ m8 c2 _
  126. void Sector_Erase(unsigned long Dst);) x. S; o9 \# i- o
  127. void Block_Erase_32K(unsigned long Dst);  c$ M- G6 P9 n2 F' z+ V
  128. void Block_Erase_64K(unsigned long Dst);7 W1 [8 E: w8 }) f5 h8 @, G
  129. void Wait_Busy();* U8 j* v! \  l% U$ I8 ~3 I# e
  130. void Wait_Busy_AAI();
    5 o5 ]) \) O$ b: q7 ~9 X* G/ c
  131. void WREN_Check();
    - h8 a- g. O/ _) X8 S4 D( U
  132. void WREN_AAI_Check();
    8 g, e- w3 g, O5 B
  133. & }/ `! L$ F- I* a1 p: a
  134. void Verify(unsigned char byte, unsigned char cor_byte);5 I( m3 m7 C0 a( F' u8 a

  135. - H% D) E6 B$ N4 h
  136. unsigned char idata upper_128[128];                /* global array to store read data */& [. i* b. X0 V  D
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    9 ?: ?& j) ^" L& ~( G; V6 Y! U

  138. ; X( t$ G8 c; K* _4 J0 T) Q6 t
  139. /************************************************************************/7 T, C! H/ E8 y: m
  140. /* PROCEDURE: init                                                                                                                */
    & Z- g4 V+ N7 ^5 B4 R- b
  141. /*                                                                                                                                                */6 }* m, j5 Q" Z+ H- q
  142. /* This procedure initializes the SCK to low. Must be called prior to         */( r( f' o8 @# V' _' d, X. B0 w
  143. /* setting up mode 0.                                                                                                        */
    - T/ a7 B! K2 @' ^
  144. /*                                                                                                                                                */
    - t8 ]: R+ J7 }$ t8 c. b7 R
  145. /* Input:                                                                                                                                */
    ! T8 ^" ~& O$ M$ i/ j# ]% u
  146. /*                None                                                                                                                        */
    8 K4 d2 b4 g1 h/ n6 [& g' E; d1 d- [
  147. /*                                                                                                                                                */- u  F! v+ t" P; o
  148. /* Output:                                                                                                                                */8 l3 Z) |/ }! {7 O/ d- x/ l
  149. /*                SCK                                                                                                                                */7 K4 I9 ^) N/ C2 n$ O
  150. /************************************************************************/
    * z" j9 }% n8 g( i7 c/ z# G
  151. void init()3 w( D% _+ C9 d% w% T
  152. {4 T8 C  E( ~# p# v# K3 h$ {, P
  153.         SCK = 0;        /* set clock to low initial state */
    ! d; E- d# K5 D- o  [
  154. }% T0 b9 {/ R& N8 t! h6 v
  155. ) U1 a& y# c$ N6 ^1 R4 |" o; r, \
  156. /************************************************************************/
    " [8 _% R3 j, [6 x" q
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    & e! J* Q. \7 l
  158. /*                                                                                                                                                */; h  x$ u& F0 \' T5 n3 b6 _8 U
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    : ^5 V1 @# |4 o" C
  160. /* edge on the the SI pin(LSB 1st).                                                                                */" v+ H) g7 F. c  V/ N7 a
  161. /*                                                                                                                                                */) i& G: t. h: [8 @4 |% w" U
  162. /* Input:                                                                                                                                */- r! d1 {, I# E
  163. /*                out                                                                                                                                */( }4 g8 o) {  H8 t' M
  164. /*                                                                                                                                                */3 Y" A! [+ x' k5 S- [
  165. /* Output:                                                                                                                                */
    ; n" F4 `; u' G5 A( t, Q# h
  166. /*                SI                                                                                                                                */
    ) N8 F, J" c/ n0 d! a3 Z
  167. /************************************************************************/8 f$ ^9 V# I8 D$ X
  168. void Send_Byte(unsigned char out)' b# x5 E4 \  R- {6 j$ [
  169. {
    ; n$ D& B! a$ m8 |: @
  170.        
    / ~; y( t3 B$ N7 m3 D- Q& X
  171.         unsigned char i = 0;
      M7 e0 A) x1 z, M2 N5 P5 f8 |, _; T
  172.         for (i = 0; i < 8; i++)
    2 n, q5 B: b; x7 E6 J
  173.         {2 n6 p' o: x# Z1 ~2 f! r' E% b) P
  174.                
    8 W' s4 ~( p7 `  b) K0 G# I3 J
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    + j7 {( [' X5 Q& _) q! a- [7 g
  176.                         SI = 1;
    " |/ N# ~- O0 H9 A
  177.                 else
    & U9 _  g% t0 x  n
  178.                         SI = 0;                                /* if not, set to low */
    1 P, S0 x4 R5 B. Q
  179.                 SCK = 1;                                /* toggle clock high */' K8 R" Q# m! e1 o9 i0 m" k
  180.                 out = (out << 1);                /* shift 1 place for next bit */- Y) z, o0 r3 y- s6 U7 O
  181.                 SCK = 0;                                /* toggle clock low */
    ! _4 `0 l% }! E7 g* m, I
  182.         }; g9 N' D' @7 l- M
  183. }, D' N8 [7 A- q) `
  184. & m& z' S# y+ b
  185. /************************************************************************/1 h; X; t* ~$ S, ]5 Q! x9 T
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    " G. C6 Q# V% N
  187. /*                                                                                                                                                */! q  Q  b  `+ ]; q  _/ @1 N, S
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    - K2 P2 l0 `- V& I7 e
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    9 a* a* P2 z$ ~9 P' k
  190. /*                                                                                                                                                */8 x# Q2 q* |: K% J' y/ y
  191. /* Input:                                                                                                                                *// ]6 B( A: D5 g, l
  192. /*                SO                                                                                                                                */
    " ?' X8 Y1 |; z
  193. /*                                                                                                                                                */: |9 B" o/ U9 [) _- A* T0 o/ M, {
  194. /* Output:                                                                                                                                */% c/ X& w: J+ |; ~- G; U
  195. /*                None                                                                                                                        */
    $ _: e' g. f, j' I! ~( Z3 b# w
  196. /************************************************************************/
    0 l; t4 r% f, W3 C! w- u/ ]
  197. unsigned char Get_Byte()/ j" S3 Y# V' T/ F: V
  198. {8 @" w, c( r* }. K& n' s: d
  199.         unsigned char i = 0, in = 0, temp = 0;8 f  N0 {+ {0 i
  200.         for (i = 0; i < 8; i++)8 x* P6 F0 T$ S: P  y+ \# m
  201.         {
    % ]" ?2 ]  ^) G0 }1 {3 d$ [
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    ) B( W1 p: M. Q% y- q0 @0 P
  203.                 temp = SO;                        /* save input */
    , v, ?0 ^5 k  o- H9 [
  204.                 SCK = 1;                        /* toggle clock high */, s) b9 ~8 Y1 H5 z' U: x" L  Y
  205.                 if (temp == 1)                        /* check to see if bit is high */3 J5 ~) Z5 }- M, @( C$ a' w% b
  206.                         in = in | 0x01;                /* if high, make bit high */. w6 M. r8 d; J; E% L

  207. 0 r* N( `4 }: h; l
  208.                 SCK = 0;                        /* toggle clock low */& d% E$ ~. H% y: W7 q# F9 M

  209. + Z% w% O2 y( Q. T9 J
  210.         }- Y$ k$ V0 s' K1 T
  211.         return in;
    % R- z0 ~" s5 J0 [7 T! v" n; ~, q
  212. }% D* }0 x) U$ I

  213. . |! w6 ~( D: t% d$ T  ~' P+ A& V- c
  214. /************************************************************************/
    + ^$ S' Q9 [# B* T( q% m( q$ s4 z
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ) a& r' Q* J. I4 x* w) r
  216. /*                                                                                                                                                */* l: Y* r5 x( z, p8 S- ]
  217. /* This procedure polls for the SO line during AAI programming                  */
      M0 x+ N$ ~4 B* S  d6 }
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    6 @& U. W) f) c8 L
  219. /* is completed                                                                                                                        */) |+ V) N% X3 @- p8 r+ e
  220. /*                                                                                                                                                */
    5 I1 \2 I  ^3 g3 g
  221. /* Input:                                                                                                                                */
    # e: v2 f- f1 l
  222. /*                SO                                                                                                                                */) p( N; z4 i& D8 b% N  ]
  223. /*                                                                                                                                                */: f/ D$ K4 c6 v, X( h0 j% A
  224. /* Output:                                                                                                                                */" R/ @8 |' m' V& |9 d, v; W- T1 b
  225. /*                None                                                                                                                        */
    3 U" R4 d" w; t* [2 o; q
  226. /************************************************************************/( }, r' F0 t2 ^+ Y) Y& I$ O
  227. void Poll_SO()
    ; H' }3 T- V5 f) \9 f* z
  228. {
    8 B( G, y0 {( r
  229.         unsigned char temp = 0;
    ) k# Y7 i0 j/ k: L5 H* @" C: l' f8 B( U+ q
  230.         CE_Low();0 _# s, |# ^4 T  L
  231.     while (temp == 0x00)        /* waste time until not busy */5 n% _* B, `# }2 g# T! r, b
  232.                 temp = SO;
    / g3 t6 o- G5 P" f$ Y
  233.         CE_High();
    2 y$ `% g; J4 c  p7 ^
  234. }  P% S  |2 P" [5 L

  235. * }+ ]% ^) W* i4 d* g; a
  236. /************************************************************************/- B) R8 S$ \* m6 m8 Y, O
  237. /* PROCEDURE: CE_High                                                                                                        */
    - X4 N6 s4 x" {' t
  238. /*                                                                                                                                                */
    9 b4 J  P1 D, C3 ^
  239. /* This procedure set CE = High.                                                                                */+ }) h! ?% V4 w" y" f
  240. /*                                                                                                                                                */& i. g$ G; @6 N
  241. /* Input:                                                                                                                                */1 f  @8 q3 h; i0 O
  242. /*                None                                                                                                                        */" Z8 s5 q+ E7 q0 k
  243. /*                                                                                                                                                */
    5 `* _% F* |3 L8 S4 Z% ^/ D+ N
  244. /* Output:                                                                                                                                */
    ! j1 D4 x9 _9 F- z2 f+ j& p
  245. /*                CE                                                                                                                                */" P- P2 S4 J3 B9 g
  246. /*                                                                                                                                                */
    & a4 P8 o, A. V* u
  247. /************************************************************************/
    , w  A+ R! e2 e! ?8 J
  248. void CE_High()
    7 E! X4 u  M. F' R* q  K
  249. {% k$ U# m# _/ H/ H0 U/ x
  250.         CE = 1;                                /* set CE high */& b# J3 z% N# o4 `* m& W+ x4 U
  251. }
    0 f5 ]2 Z5 g  T! P3 I9 c7 z

  252. 2 h6 x6 S1 A4 b% Y" I# _7 V
  253. /************************************************************************/
    9 p; [" u7 ?" [& a  M. h
  254. /* PROCEDURE: CE_Low                                                                                                        */! u( s& k( R# m3 E+ b& J' w
  255. /*                                                                                                                                                */
    % a3 k4 K1 s- ~: ~. Q# C
  256. /* This procedure drives the CE of the device to low.                                          */
    2 f( r: t. N; l/ W$ {; F8 M
  257. /*                                                                                                                                                */
    1 C, x9 o  v5 ?0 k3 S
  258. /* Input:                                                                                                                                */' N' k% E- P* t
  259. /*                None                                                                                                                        *// d& _" ~. K( P
  260. /*                                                                                                                                                */
    / E" W- ^0 g. K  a+ Y
  261. /* Output:                                                                                                                                */* p; N, {8 O% L! @% }
  262. /*                CE                                                                                                                                */
    $ }% S$ A1 M) h. X4 n. j
  263. /*                                                                                                                                                */
    - Q2 |. u6 N! c0 y
  264. /************************************************************************/( O5 t: ]5 ?. ~8 @+ c5 }
  265. void CE_Low() & Y' B( b# }; T' o2 b
  266. {        2 \: @1 ^: v, ?( |
  267.         CE = 0;                                /* clear CE low */
    7 A4 ~4 m3 l, p- h. |2 L* h/ b
  268. }6 E% n# Q$ R6 j/ q* u
  269. ( y- K& G5 W$ T4 [2 `# Y1 [
  270. /************************************************************************/
    # y! Y- g9 g2 w
  271. /* PROCEDURE: Hold()                                                                                                        */
    ; \/ W9 a) E/ K  H  ^$ C
  272. /*                                                                                                                                                */+ Q6 ]* d& Z" ?, Q7 b& _
  273. /* This procedure clears the Hold pin to low.                                                        */( T2 ^4 P& g2 R7 K+ Q' q! \/ e
  274. /*                                                                                                                                                */
    ; a2 D6 u  y7 ?6 \% H+ K9 _- I& S
  275. /* Input:                                                                                                                                */
    * _0 U, F- c! f. h2 O& _  f) a/ F
  276. /*                None                                                                                                                        */4 d7 ?* S7 h) I/ l- Q8 }
  277. /*                                                                                                                                                */: t8 ~! K% h7 T8 p" p" O
  278. /* Output:                                                                                                                                */
    8 r! s( S' L. V( u* i9 M+ ~
  279. /*                Hold                                                                                                                        */
    # W  \  K: ]) {
  280. /************************************************************************/0 A# Z9 f/ t/ T# R* z4 e
  281. void Hold_Low()9 P8 m6 Z2 V# @4 O. O
  282. {" t: _! O$ l1 Y+ o6 `$ G
  283.         Hold = 0;                        /* clear Hold pin */
    3 K" N& |8 X& b/ w6 @9 P6 O
  284. }& B+ F, ?, H' S' j

  285. 3 Y% T5 ?8 F& a( G
  286. /************************************************************************/* n) L: P3 C2 N4 p& g
  287. /* PROCEDURE: Unhold()                                                                                                        */. M, o( U' I. w3 [# m& q) r& l( s
  288. /*                                                                                                                                                */3 N+ z1 g' P! s
  289. /* This procedure sets the Hold pin to high.                                                        */
    6 K+ Q0 c/ ]1 z* T! p- @
  290. /*                                                                                                                                                */
    % p* o9 w2 Z6 x3 \# n7 n% X  Y
  291. /* Input:                                                                                                                                */+ K; [) ^1 Z+ m: ]3 {5 L# i
  292. /*                None                                                                                                                        */. o  ^) w6 h+ s
  293. /*                                                                                                                                                */
    + d! L: v- ^$ ~7 t/ X) z5 Q3 {9 K
  294. /* Output:                                                                                                                                */, S( I* Z, k* n( o' I! F4 B3 H
  295. /*                Hold                                                                                                                        */
    7 H; `8 Z: L' R, e3 O
  296. /************************************************************************/0 u/ f' Z% t- \3 a( u  {# C4 J
  297. void Unhold()/ A8 _% J6 \3 ~+ q6 k" O. T' T, ^
  298. {
    3 s9 z* z9 a& z6 z: ~7 s" J
  299.         Hold = 1;                        /* set Hold pin */
    9 u5 a5 J! _% k( S; K4 C9 H
  300. }% V! ]5 ?7 X0 v7 n/ U$ \/ s7 g

  301. $ b. t+ l3 u. r0 `/ W# f
  302. /************************************************************************/8 `/ a3 x( ^6 `8 B2 P) q" n
  303. /* PROCEDURE: WP()                                                                                                                */
    9 O* M- z2 F+ U. B4 k! U
  304. /*                                                                                                                                                */
    7 T8 ]* R- n5 x8 r$ ?( a! f: r
  305. /* This procedure clears the WP pin to low.                                                                *// G- h+ p" N. J& l. u  W
  306. /*                                                                                                                                                */
    - ^; ~5 k" r# P/ b4 E7 U' ~% w3 B
  307. /* Input:                                                                                                                                */1 Y/ D3 t0 \: |/ e/ X8 _
  308. /*                None                                                                                                                        */5 [: [% i8 j2 x) @; c4 J
  309. /*                                                                                                                                                */
    2 @+ D7 [1 e( N; A! N
  310. /* Output:                                                                                                                                */- D1 f5 x" N  l3 M$ E! Z; }5 w# _
  311. /*                WP                                                                                                                                */( e9 [2 W; S' I( A  B
  312. /************************************************************************/; O1 ?: E" L* w
  313. void WP_Low()
    " |. I+ D3 k; k% w
  314. {
      C& W6 b; o3 E9 l
  315.         WP = 0;                                /* clear WP pin */. D! c% }) v% |' {3 Q; h
  316. }/ [& ^8 \+ a* K) Z8 A3 X4 m( d* T+ ]

  317. , ^# J) v5 Y( E7 J* t% n, f8 }
  318. /************************************************************************/
    1 ~  C+ P& h: `1 Y: C
  319. /* PROCEDURE: UnWP()                                                                                                        */7 j( \$ M: Y* u
  320. /*                                                                                                                                                */
    0 F+ @+ R( l" u
  321. /* This procedure sets the WP pin to high.                                                                */
    : F% C+ [! S. n
  322. /*                                                                                                                                                */( u! z+ z  a' e. S0 B( y$ \
  323. /* Input:                                                                                                                                */
    & @/ Q( x& ?2 w6 ~9 u( {
  324. /*                None                                                                                                                        */( z- ]5 n. z% M* Q2 C% U
  325. /*                                                                                                                                                */: U0 u6 c& U) i# T- l$ n7 l$ j
  326. /* Output:                                                                                                                                */
    / ^* b* ^. p! }' q  }- W
  327. /*                WP                                                                                                                                */' f; F8 {0 S% v2 {2 Y
  328. /************************************************************************/
    ! R3 z: W( }4 W3 d
  329. void UnWP()
    + W% M6 ?7 Z% `* C& Q; ?
  330. {( K4 _. `' s8 N4 k% G: ]
  331.         WP = 1;                                /* set WP pin */
    4 h$ L7 N1 C. q
  332. }
    3 f" f7 ^: Y# A9 R
  333. & Q+ E8 D1 b" {7 O) w
  334. /************************************************************************/
    9 u# v  d; X1 I3 h; L% ~5 [
  335. /* PROCEDURE: Read_Status_Register                                                                                */5 z' K3 ]& E, n3 i; L0 s
  336. /*                                                                                                                                                */
    * v8 s/ ]8 R3 S0 T7 B  [
  337. /* This procedure read the status register and returns the byte.                */! h0 S/ e# t8 t( `( {: y( f
  338. /*                                                                                                                                                */
    * O* ]6 V; C* X% u% u
  339. /* Input:                                                                                                                                */% R: b+ g8 e& r
  340. /*                None                                                                                                                        */
    $ W- s1 _, ?  g7 s, J' h: f
  341. /*                                                                                                                                                */1 l; L3 D1 o# Y$ D8 W  c/ w- c
  342. /* Returns:                                                                                                                                */
    / Z0 u: U' u& ?6 m# t( Q
  343. /*                byte                                                                                                                        */
    7 q' V: r/ S% x  T  B
  344. /************************************************************************/& j+ m  A4 Z" V7 t
  345. unsigned char Read_Status_Register()  j& ~+ t4 q$ l  u; [4 D+ r" ~  x
  346. {
    . G1 K. k' N' D/ \) b
  347.         unsigned char byte = 0;! i* L, R  f2 j3 O! b9 N
  348.         CE_Low();                                /* enable device */
    $ X& T! \& W+ n; I3 E) e
  349.         Send_Byte(0x05);                /* send RDSR command */
    # J) R" u- o- K% x/ |
  350.         byte = Get_Byte();                /* receive byte */
    3 f) k  p& Y' t1 B. L2 V
  351.         CE_High();                                /* disable device */
    , [% i. C" S! H
  352.         return byte;/ ^4 }* m0 i3 g% N* g
  353. }
    ) f+ T) p. O- G* M4 F, `% d

  354. ( B8 @# w' s! P- N% i. d/ t9 {
  355. /************************************************************************/- h3 [  t! D! T% d% R. ^) L
  356. /* PROCEDURE: EWSR                                                                                                                */3 J8 }) r( L# ^0 ^/ d
  357. /*                                                                                                                                                */" s. i" M" F; K1 f8 m
  358. /* This procedure Enables Write Status Register.                                                  */
    # K) d2 H0 j3 v; z
  359. /*                                                                                                                                                */! R5 }# \  L* Y! r5 M- M$ T" }
  360. /* Input:                                                                                                                                */1 Q5 S; z4 I* S8 u  p0 C" s( J
  361. /*                None                                                                                                                        */7 c* @7 |4 W; {/ w$ r  o5 Q
  362. /*                                                                                                                                                */; X  F3 B+ ?' }4 a3 U
  363. /* Returns:                                                                                                                                */- C, F- l* v$ h8 R+ F! l8 j$ r
  364. /*                Nothing                                                                                                                        */
    ( R3 c* B: u# L9 o
  365. /************************************************************************/
    ! z- F6 [/ Q; R* h' c
  366. void EWSR()$ e1 a# W- K. s( _
  367. {1 S* P" N0 W/ Q5 p" c6 \
  368.         CE_Low();                                /* enable device */
    9 _- F5 R/ ~4 h/ k2 C+ t* j
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    # V# @2 d  v/ d; [$ ~
  370.         CE_High();                                /* disable device */
    $ x/ G" I, j! I' J. Z, A
  371. }, u9 [/ c0 n" V8 x" C- H6 e7 {# @
  372. 6 s7 i* t- n, P' ^
  373. /************************************************************************/2 i5 v; h1 ~: P* [7 ]# N0 i
  374. /* PROCEDURE: WRSR                                                                                                                */
    3 I4 Y+ t  I+ ]; q! j0 f5 v* }# J
  375. /*                                                                                                                                                */
    6 J  C) ~$ x- U, r& i0 ]
  376. /* This procedure writes a byte to the Status Register.                                        */
    1 Z* W  x9 y- m& a/ L9 U" E$ x
  377. /*                                                                                                                                                */* k. ]- _' p1 A1 R0 K! Z
  378. /* Input:                                                                                                                                */
    / {/ t0 V# T/ N5 d& A7 Q2 s. r; @
  379. /*                byte                                                                                                                        */: Y$ n3 }& F3 }1 T' n
  380. /*                                                                                                                                                */
    6 `4 f1 R2 ~( U# H' E! W
  381. /* Returns:                                                                                                                                */
    4 ]# m0 {+ {) |7 U
  382. /*                Nothing                                                                                                                        */
    1 O. }9 Q2 p+ j$ ]$ u- F9 Z) x0 k
  383. /************************************************************************/  m* Y8 C6 }" L/ B) ^
  384. void WRSR(byte)- P: W0 b9 D+ k# E) D$ O- |
  385. {
    ) `2 ]4 n) E3 J3 P. D3 V
  386.         CE_Low();                                /* enable device */! ?1 e1 N8 S# P1 k$ J
  387.         Send_Byte(0x01);                /* select write to status register */# H8 p9 C7 A' {9 t6 s
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    5 q7 {& D) t' w. @# }( @! s$ _; a
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    " D, J8 B! ~7 |5 [3 t+ Z
  390.         CE_High();                                /* disable the device */. h  d( Y8 r  o4 u1 D" z
  391. }; F, d; v1 r2 x) m3 I7 Y2 d
  392. / g' K1 t! q, e0 i4 W/ M" w4 R2 Q" s
  393. /************************************************************************/- Y% n) \, y6 U7 E3 p7 k
  394. /* PROCEDURE: WREN                                                                                                                */: P2 g: M7 `- Z# C8 ~; u
  395. /*                                                                                                                                                */
    2 j3 T: \2 s7 d0 H* W$ i
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */1 k. A0 h4 m3 r  r# l
  397. /* to Enables Write Status Register.                                                                        */
      ~8 k; Y- G) X% l# Q' s
  398. /*                                                                                                                                                */2 j" z8 I+ m! g
  399. /* Input:                                                                                                                                */( `" \4 Q2 R( z& x, s: w! t
  400. /*                None                                                                                                                        */
    & p8 q3 a) y6 b) H& }
  401. /*                                                                                                                                                */
    + K/ l0 i. Q9 I  W6 z+ `: m/ B3 v% a. p
  402. /* Returns:                                                                                                                                */
    7 v/ c2 h' n9 g2 s
  403. /*                Nothing                                                                                                                        */
    - Y. |7 w0 f1 X
  404. /************************************************************************/
    1 x4 g# ]$ [% M% e% j/ }5 s
  405. void WREN()
    # `1 X# G: `3 b- D
  406. {& ~6 R% |4 U; u0 ]8 y# R4 J7 R
  407.         CE_Low();                                /* enable device */
    2 P* n0 y, f, \
  408.         Send_Byte(0x06);                /* send WREN command */4 T; \1 P# t/ C- m0 I" X: ?
  409.         CE_High();                                /* disable device */+ T( }$ [1 j# I4 O
  410. }" u# a2 A+ h2 W* P' Q- A& S

  411. ( k& \2 j) J+ e4 A. S# ?' l
  412. /************************************************************************/% u1 ], H  j2 `8 g( o; R1 l
  413. /* PROCEDURE: WRDI                                                                                                                */) M2 c3 R4 c% v* L! m! v0 i) }
  414. /*                                                                                                                                                */: F8 j$ v. V- h  ?; G2 B1 ^
  415. /* This procedure disables the Write Enable Latch.                                                */
    . F$ L' |$ s8 a' r0 ?
  416. /*                                                                                                                                                */8 k8 D2 R3 W! i" w% e7 ]
  417. /* Input:                                                                                                                                */; X8 g7 {! g3 v+ P3 B  `; s
  418. /*                None                                                                                                                        */6 o/ G# ^. m( w% U# x4 [. n
  419. /*                                                                                                                                                */
    3 t) Z8 g# \; R5 r5 M4 I9 f; n: h, ~
  420. /* Returns:                                                                                                                                */' d# x+ ^2 Q; @: X7 j( p
  421. /*                Nothing                                                                                                                        */
    ) \( l1 ~7 f6 L2 v/ Y3 S; [
  422. /************************************************************************/
    1 b, m# ?1 m  A: }6 ^
  423. void WRDI()
    . l7 E2 g5 L: @6 T' z5 P8 n3 H
  424. {& n. s! U8 C- l3 W
  425.         CE_Low();                                /* enable device */
    - r7 W* x9 P9 C( E
  426.         Send_Byte(0x04);                /* send WRDI command */, K) F2 w3 \$ k# W$ a0 p6 `
  427.         CE_High();                                /* disable device */+ x8 M/ B# ]2 z; ~$ O
  428. }' x: g3 b2 d2 ]

  429. 4 G, a7 S+ W5 b4 \5 E! q1 y! ]
  430. /************************************************************************/
    + P2 m' d! N3 I7 @* o! A( a. O0 T+ A
  431. /* PROCEDURE: EBSY                                                                                                                */3 P! I0 o# }/ K5 ?
  432. /*                                                                                                                                                */+ ]/ ?8 s% d" Z
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    ) |# q  u2 h. J
  434. /* programming.                                                                                                                        */
    ' I9 p: [5 K$ `6 p  {% U  G
  435. /*                                                                                                                                                */
    : M5 z# Q- Y9 S( d6 `) i
  436. /* Input:                                                                                                                                */, N/ o# I1 A( H6 q- q4 U& s( i
  437. /*                None                                                                                                                        */
    . G4 f- u% g6 a' h4 j+ ], P
  438. /*                                                                                                                                                */
    8 B# p* B7 D9 c: A' i* ~* i: P
  439. /* Returns:                                                                                                                                */; H: B/ j: n! L! w. |. T& [
  440. /*                Nothing                                                                                                                        */# w4 U/ q8 [" Z. R3 \
  441. /************************************************************************/
    & F' X8 ]. W% K
  442. void EBSY()
    4 _7 Y5 o3 N+ V4 E+ k2 d5 N
  443. {
    / ~2 j( p1 u+ L/ M" O* E& F3 \0 g% D
  444.         CE_Low();                                /* enable device */7 m2 [: N# f9 F# _7 u4 {- o
  445.         Send_Byte(0x70);                /* send EBSY command */
    5 o/ Q- P* v: a& e: T
  446.         CE_High();                                /* disable device */+ ?7 T9 Q# W6 H" H
  447. }
    ' C( ?  D" e; j, o

  448. ( G& }7 t! u, [& l/ D( Q4 S, t
  449. /************************************************************************/
    , V; v+ J' u) d9 O" f$ F
  450. /* PROCEDURE: DBSY                                                                                                                */
    ; s  q& o% M7 g/ _3 x9 |- [9 V# I6 d
  451. /*                                                                                                                                                */
    * @( J  Y# ?+ J, a/ G' _5 j
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */  W2 Z5 F+ M8 O% B. c
  453. /* programming.                                                                                                                        */4 Z. Q$ O2 d; ~3 @
  454. /*                                                                                                                                                */8 A% M$ H2 b" C4 G8 O8 N
  455. /* Input:                                                                                                                                */
    / B, ~& E( y) _! ~# Y9 o+ I8 u
  456. /*                None                                                                                                                        */4 r+ g' N& D# ]) z6 g( |* x. f
  457. /*                                                                                                                                                */
    & u3 P% H$ @# w8 u7 }
  458. /* Returns:                                                                                                                                */
    5 ^, g  x) U$ z/ X
  459. /*                Nothing                                                                                                                        */
    0 x1 r* ^2 S( c. l0 l! [5 ]
  460. /************************************************************************/6 [* W. V6 g1 u2 I# E/ t/ z+ w" M/ T
  461. void DBSY()
    6 V1 G6 m$ F2 J' z% g; I* b
  462. {
    ) t+ t. C# }1 Q( ?6 v& A6 z
  463.         CE_Low();                                /* enable device */
    0 {1 _4 K9 X% _9 M4 x! W
  464.         Send_Byte(0x80);                /* send DBSY command */# z. y" g  j; i& k
  465.         CE_High();                                /* disable device */
    " j8 @& W8 `3 x( L
  466. }
    ' i+ n5 H0 n/ K, _8 ~  w: P

  467. 2 _6 B; G% Y6 K
  468. /************************************************************************/; w* {" O0 X) U: G, `) x8 |4 ?0 m* L
  469. /* PROCEDURE: Read_ID                                                                                                        */
    $ l) d/ |' T6 w; ^, d$ A. D
  470. /*                                                                                                                                                */
    6 p2 l& @; Z: Z
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    . j: [& m8 I" u6 t) b& w
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    7 B% i6 Z0 J. S: _$ e7 L- K6 Y# I
  473. /* It is up to the user to give the last byte ID_addr to determine      */% D5 S/ U/ Z6 P2 L  A
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    ) [$ o# Q# g) D
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    : [" j& i. W; A% Q& u1 J9 b
  476. /* variable byte.                                                                                                                */
    ) M& N4 u. v. c6 @7 U) S
  477. /*                                                                                                                                                */# I8 v5 E: H. c- K  _6 I0 O6 v" U: H. M
  478. /* Input:                                                                                                                                */  Q8 g* S8 l/ }- J) w/ e9 k
  479. /*                ID_addr                                                                                                                        */
    " A0 Y  T0 X: `4 O) e- S
  480. /*                                                                                                                                                */) C, P6 m' j2 m1 B/ h/ G7 b# |
  481. /* Returns:                                                                                                                                */6 b  S' Q0 \" n2 a$ v* H
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    3 w$ D" K: `( E) A; y1 S
  483. /*                                                                                                                                                */
    ' `6 W2 h4 D7 j& A& U( x
  484. /************************************************************************/
    3 o4 V1 K% X7 h
  485. unsigned char Read_ID(ID_addr)
    & p: ^9 G2 _; T& b1 }' ^
  486. {% k$ l! {$ e& M$ T6 L
  487.         unsigned char byte;; ?$ E' ?) P4 r6 \; q: i1 y: u
  488.         CE_Low();                                /* enable device */; v- ?6 o8 h- B8 O! i6 y* T. v
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */) R, u1 t) W- @$ |
  490.     Send_Byte(0x00);                /* send address */
    2 b6 l) N1 [) ~4 [
  491.         Send_Byte(0x00);                /* send address */. q- k# {, t8 B- Q' U" r
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    9 g& r# S, H8 a7 r; S; b% h! P$ m
  493.         byte = Get_Byte();                /* receive byte */
    ) `# p- C$ @# ?. t* C8 i! X
  494.         CE_High();                                /* disable device */
    / g# A* j! w/ B! q
  495.         return byte;
    . \8 _9 D5 X3 B$ `+ U: T: s
  496. }! N" x3 T5 J$ S3 K  _

  497. 5 H5 C+ ^) L: J4 [
  498. /************************************************************************/( {9 V! W3 y3 ]" G
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    9 c5 X7 B" g) j) X0 e! y1 T
  500. /*                                                                                                                                                */: C7 m+ U' V( w
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    : B, n5 F& O4 Z$ ^9 T, D3 e
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */  W3 l( H: h4 M  @( F: E
  503. /* Please see the product datasheet for details.                                                  */2 D4 I, F! O. q/ F6 h/ m
  504. /*                                                                                                                                                */
    $ b% A1 O+ P; n& i
  505. /* Input:                                                                                                                                */
    ' |0 o5 V( X4 F8 R* e; Z
  506. /*                None                                                                                                                        */, l, L8 j7 u+ j
  507. /*                                                                                                                                                */, [, Q3 W' h( N/ m$ M' {) l
  508. /* Returns:                                                                                                                                */8 V* y3 s1 j. O: O
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */2 a  f6 ]' X7 k9 _
  510. /*                 and Device ID (8Eh)                                                                                        */
    6 S+ o% n1 p4 m+ g
  511. /*                                                                                                                                                */3 ~7 G- D+ g4 ?3 C# L
  512. /************************************************************************/( v7 h# f' V0 Y, p6 a3 T, E2 z. z
  513. unsigned long Jedec_ID_Read() 8 G- E) H9 ^" w8 [! @4 f
  514. {2 Y6 M% L& u9 u4 Y8 z
  515.         unsigned long temp;5 W$ Y. o+ B: G8 X! Y
  516.        
    , p" C' i' Y: e+ D5 B1 o$ l& G7 l
  517.         temp = 0;
    % h8 G8 {; O1 T4 \! ~3 F( t, H
  518. 6 a$ Y0 H" W" {! F) m' ]3 ~* m
  519.         CE_Low();                                        /* enable device */
    + p! q1 V" C( v
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    0 R, B8 k, D3 J) f
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    - @8 M+ j7 S$ d
  522.         temp = (temp | Get_Byte()) << 8;       
    " g+ B/ P4 Q& `$ m
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    % }5 A+ C" \" B* e/ ?# Q6 X) f
  524.         CE_High();                                                        /* disable device */
    ; f0 u: `* v, }$ M  e' ^
  525. , `$ O; e$ x0 t1 ]
  526.         return temp;
    ( j' t: [( s: p. a0 x$ Q
  527. }" n: R  H/ x. h: J; l
  528. / ]. F' @9 B6 x
  529. /************************************************************************/
    7 u2 |8 i8 q4 T
  530. /* PROCEDURE:        Read                                                                                                        */( q' G3 d8 E& I( J; O7 b) ~9 U
  531. /*                                                                                                                                                */               
    , k% l$ e( v) t/ o; A
  532. /* This procedure reads one address of the device.  It will return the         */
    , J: B- y. d1 w) }/ D
  533. /* byte read in variable byte.                                                                                        */1 C. v9 O/ [8 n
  534. /*                                                                                                                                                */3 L, H# r; d0 p* P% B; |$ M, t
  535. /*                                                                                                                                                */
      B% E  n* a6 A/ w3 n4 r% w
  536. /*                                                                                                                                                */4 v" [' q7 X; ?& w, B3 o' P( O
  537. /* Input:                                                                                                                                */
    ! h" F3 [/ \& A! b
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */9 K+ ?) O' ?" r% W* Z8 h" G  E" q
  539. /*                                                                                                                                      */0 ~4 p. {& B$ G6 `
  540. /*                                                                                                                                                */. q5 Y1 n, G! P( b! O2 i# ~
  541. /* Returns:                                                                                                                                */
    3 N% [; {  z2 Z/ _
  542. /*                byte                                                                                                                        */
    - H) F$ }/ m5 W5 @- I
  543. /*                                                                                                                                                */
    2 i" y/ V" C) S+ n  N
  544. /************************************************************************/
    8 Z- j- L2 T, U/ ^$ s6 _* u
  545. unsigned char Read(unsigned long Dst)
    * e  ?) ~" Z+ O# O1 Q! f
  546. {
    ) ^2 H6 \- y$ d0 w4 Z' T
  547.         unsigned char byte = 0;        # z, U6 M; [% i& y. e' R

  548. + w! \1 `7 h. r* l+ J4 U+ X0 y- B' p: l
  549.         CE_Low();                                /* enable device */0 t4 L. N, S& {3 J, m/ H
  550.         Send_Byte(0x03);                 /* read command */
    % s& s" o" n$ D  l) h" ]- Q
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */0 K7 }: E+ q; a3 _5 N
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));4 d( m/ K: H' V4 F% T1 N! q' N
  553.         Send_Byte(Dst & 0xFF);
    ; x9 U) D! D8 Q
  554.         byte = Get_Byte();, E, ]+ E( x' h, @) p* ]5 X* _
  555.         CE_High();                                /* disable device */
    3 n/ y$ a" J- {& B
  556.         return byte;                        /* return one byte read */) y+ r0 H2 C( [; f! t
  557. }  E0 U; ?4 B  G( P

  558. . n$ L' J4 i  C$ {- s1 q
  559. /************************************************************************/6 ]& w. U# R' T
  560. /* PROCEDURE:        Read_Cont                                                                                                */3 X$ G* G( G, I  A5 V$ d
  561. /*                                                                                                                                                */               
    6 F+ e. k  y8 u% I
  562. /* This procedure reads multiple addresses of the device and stores                */
    # U. e1 j9 r/ j! _* S, v0 b
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    , p  X4 N8 j; D" O3 N/ m4 b
  564. /*                                                                                                                                                */. k7 b: x6 ?2 l
  565. /* Input:                                                                                                                                */0 r) ^9 O5 ]+ s% ?
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: W8 [' x& _; T5 C; K
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */% V" u, U; h% ~( N* {1 [
  568. /*                                                                                                                                                */* o$ o" v$ G4 E
  569. /* Returns:                                                                                                                                */
    + Q- T$ `% j4 ]( p3 h( ~
  570. /*                Nothing                                                                                                                        */8 ?) e" d# U( V* [; f# K0 L, S( Q) C
  571. /*                                                                                                                                                *// ^% ^8 R1 K9 g; d% X# _8 n
  572. /************************************************************************/
    ' n; h+ F/ k8 G& U
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    - }$ c1 Y& E& x
  574. {( ^7 T$ s- P. Y  g. F
  575.         unsigned long i = 0;1 B) ^) U, N7 X$ v/ |$ o
  576.         CE_Low();                                        /* enable device */
    : n% P; H+ {" G) z1 w! r* J
  577.         Send_Byte(0x03);                         /* read command */
    7 }2 G1 P' ]. P" z3 }3 I. y! A- T
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 u9 y* W# j: b; R
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));9 {% V% l  y# o
  580.         Send_Byte(Dst & 0xFF);6 `7 _# i; x. W3 L! p$ @
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */  v6 m& m8 @- P% F0 Q4 a
  582.         {1 D4 u6 T/ g% W9 i9 I( c
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */" M: k3 s. u) M; H& Y, A8 h! C4 R
  584.         }) c) J1 c5 h, L. q; V  J% Q: i
  585.         CE_High();                                        /* disable device */
    3 a' g- M# e* j% U! l* B

  586. 0 X' Q8 c4 P, X; U0 ]9 e
  587. }" ^( @* G0 ]- b9 z
  588. : i* r/ C7 g/ g% H, g; p
  589. /************************************************************************/
    9 T* [3 ~4 E) H8 e, O, R
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
      \$ e% _7 u3 T7 h8 |
  591. /*                                                                                                                                                */               
    7 E" F$ @2 e! |- V8 Y7 N% J
  592. /* This procedure reads one address of the device.  It will return the         */) W& ]* M- B$ x" [. f$ S
  593. /* byte read in variable byte.                                                                                        */4 Z& K& {4 [" n0 L1 n9 L) m7 E! h4 k
  594. /*                                                                                                                                                */5 `! T% X+ {: U: P5 \
  595. /*                                                                                                                                                */, `  u1 ^4 |) x# B, g
  596. /*                                                                                                                                                */
    7 o" k& P) f/ t$ E5 M( n7 X
  597. /* Input:                                                                                                                                */0 m1 P+ U0 p4 {# _$ {+ t) |
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    : P8 l4 C: N4 j2 D$ @: k  J
  599. /*                                                                                                                                      */
    & |/ a& u+ ?6 L2 ?; y5 g1 C
  600. /*                                                                                                                                                */! r$ f5 _. {. t: g5 f+ N
  601. /* Returns:                                                                                                                                */( K$ L" [+ ?$ K) U! y6 g: A
  602. /*                byte                                                                                                                        */) y7 s; `4 |6 V- S0 K+ Q  M& s5 u
  603. /*                                                                                                                                                */
    % x! U' x0 b  W5 R9 ?
  604. /************************************************************************/# T3 x2 I! d. l, q/ {( m; [
  605. unsigned char HighSpeed_Read(unsigned long Dst) ; n$ [" O9 L3 E/ v) R$ g- Y
  606. {
    / C: v+ B! J/ ~: ^& k
  607.         unsigned char byte = 0;        ; x& O& R' L0 f3 X6 V. ]
  608. 5 O# f6 F+ s& J* @( P9 w" @
  609.         CE_Low();                                /* enable device */8 y8 w4 q) T* e: L* N4 k
  610.         Send_Byte(0x0B);                 /* read command */
    / n9 P! L0 U5 A! j/ K8 L; x
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ; w# [) z+ c/ [4 z) Y. P! ^
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));5 U8 o; Y( d  j7 h+ Q) c" e
  613.         Send_Byte(Dst & 0xFF);2 F% i+ v3 M6 D) l8 p
  614.         Send_Byte(0xFF);                /*dummy byte*/9 L7 y$ [7 w( ]* Y+ Q* t
  615.         byte = Get_Byte();* G9 ~% E0 v% n" m" {* h8 @6 M
  616.         CE_High();                                /* disable device */; B5 q* |+ ]/ H' k/ i0 y( F
  617.         return byte;                        /* return one byte read */
    ; v& ]; D( J5 w& _/ a$ e7 L9 R  S
  618. }0 T8 k4 c# b: ]
  619. $ E- V9 h: x: y7 d# B  G3 K
  620. /************************************************************************/
    4 T5 i- W2 R4 A
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    0 l7 ^) v  P7 W7 Z! @
  622. /*                                                                                                                                                */               
    " ~1 T  O/ |& ~1 b
  623. /* This procedure reads multiple addresses of the device and stores                */: K8 `5 S+ k% n
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    0 |1 z+ Q5 u/ w5 \+ v
  625. /*                                                                                                                                                */
    % Q* _) A3 `1 r4 n* \$ |4 B
  626. /* Input:                                                                                                                                */5 d, |- z' P' F6 l
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */  G. o9 a: G' A- e5 I
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */2 f+ H; y- M5 p! Q* |
  629. /*                                                                                                                                                */
    ) ]2 h3 Y# E7 P* s) M
  630. /* Returns:                                                                                                                                */
    7 {7 c. w; L* O; O' a: J6 d: u
  631. /*                Nothing                                                                                                                        */
    3 M" d. Q0 S8 x- m6 `! e
  632. /*                                                                                                                                                */
    7 S8 u) f0 K: g8 N2 X8 |" \
  633. /************************************************************************/, g5 b; w5 q% K
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)" l: W- w+ U/ T& C6 X
  635. {
    , N6 w$ G6 U7 I1 v6 H6 U
  636.         unsigned long i = 0;  h/ L/ z4 @- D( F
  637.         CE_Low();                                        /* enable device */
    $ ]- x+ V, U1 ~8 i% w. E
  638.         Send_Byte(0x0B);                         /* read command */4 T- T0 Z8 \) ~& A0 f. `. K) W* F
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */" b7 x# u% p+ k/ z3 G$ W
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " k  L  V1 _9 V' w! D$ V
  641.         Send_Byte(Dst & 0xFF);" j" X/ B' s% u% [) `
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ! h  R6 z( q! q7 {% B
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */+ l( m) Z1 X2 P. ]
  644.         {" {2 y5 z4 b' ^- c
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */0 ?2 }! Z$ V, x% g& c& @. O3 d6 |! h
  646.         }2 G; G3 z1 G! Z- a6 I9 V7 P1 g! b
  647.         CE_High();                                /* disable device */
    : x% F6 c7 L$ a3 T5 p
  648. }
    6 O( t. t' ^4 z+ V7 ]

  649. / I* L/ u/ b5 B1 q7 z9 ~
  650. /************************************************************************/
    - q$ i3 E- V* r0 F* r+ d
  651. /* PROCEDURE:        Byte_Program                                                                                        */8 U: m4 B9 \3 N
  652. /*                                                                                                                                                */- b& y# [8 g" P3 V/ s% P
  653. /* This procedure programs one address of the device.                                        */
    ! W  H+ w) @5 g6 r3 x
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    & V0 S* u* X5 A
  655. /* block protected.                                                                                                                */( _+ u6 C* H6 N& g2 W3 y9 {& ?; [
  656. /*                                                                                                                                                */# x- ]) ^& K1 M1 h" H) b, I
  657. /*                                                                                                                                                */
    7 X  x6 R- x7 C% n+ u) Z
  658. /*                                                                                                                                                */+ t- V: _" Q" @
  659. /* Input:                                                                                                                                */
    + H' B0 J5 l  u* S: B
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # J9 C; `7 w+ a- m
  661. /*                byte:                byte to be programmed                                                                */
    1 p: d  V6 W, K& o3 Y7 f$ S
  662. /*                                                                                                                                      */8 _3 ]4 j1 Q4 t& H$ S
  663. /*                                                                                                                                                */
    9 N' v2 t1 x8 @. v
  664. /* Returns:                                                                                                                                */) v5 z$ T# V. j- \: A
  665. /*                Nothing                                                                                                                        */7 U& @: g8 x2 Y. z0 n
  666. /*                                                                                                                                                */; u# ]8 E8 D* M) u8 l  F; w
  667. /************************************************************************/
    9 L# J) A, ]% K" }) \. \9 ~
  668. void Byte_Program(unsigned long Dst, unsigned char byte)8 m# M6 }/ s" p( ?4 {
  669. {
    5 F6 x& w5 r, h" L$ |  N
  670.         CE_Low();                                        /* enable device */
    , C4 a+ M( T% |: D* d- \1 v( e
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    # c6 |, A* F, r0 d
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */1 {' g2 g; U+ J: d$ J4 v4 l
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    9 f5 h" s6 S, M
  674.         Send_Byte(Dst & 0xFF);
    - P% W2 M( V. ]( V
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    4 a4 H2 \& m: W. n7 y3 u6 R
  676.         CE_High();                                        /* disable device */
    ! \. k1 ~. n6 c% k
  677. }% f% V7 n$ j3 O3 r+ N

  678. 8 R9 x% e( O2 l3 N" \1 |
  679. /************************************************************************/
    & j, B6 @$ @" c* O/ m* t% }# s
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ) R. K7 K3 w' r7 V/ }; v, K
  681. /*                                                                                                                                                */! b# x: V3 {4 m& x$ R
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    . a" q3 j7 r% k- y1 M# L1 o
  683. /* the device:  1st data byte will be programmed into the initial                 */
    . \- r9 d- {; ]
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ! }+ X' i( h3 s1 v
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */+ n* L5 Z# O$ E; C& }8 c
  686. /* is used to to start the AAI process.  It should be followed by                 */& H% W. o6 W/ x  C
  687. /* Auto_Add_IncB.                                                                                                                */
    - [: s+ Y; m2 v; K" g4 s! F
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) n5 l7 W# c8 Y% Y; Z8 ]
  689. /*                                block protected.                                                                                */( F6 t  k0 W3 q/ U, D1 ?$ W
  690. /*                                                                                                                                                */7 T% ?" T8 L8 x# [' ]& r
  691. /*                                                                                                                                                */) ^) b4 m% p/ x# s. s8 X- ?
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    ; X# b- A1 a- j4 r; K) a! i
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    1 l) [) F# {# Z
  694. /*         unless AAI is programming the last address or last address of                */# y; W  Y1 m  W. o# D) d5 R# s
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    3 i$ |  R1 u9 x! Z0 n; U) @/ I
  696. /*                                                                                                                                                */
    3 C3 ?8 K4 m  K7 s3 g2 J8 K
  697. /* Input:                                                                                                                                */7 W1 Z9 q8 a4 V* {5 B1 S
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 j9 `- F: z7 Z9 Q% D
  699. /*                byte1:                1st byte to be programmed                                                        */
    4 c; k. Y3 F; `  l3 D! d! n  f
  700. /*      byte1:                2nd byte to be programmed                                                        */% {* O2 u1 M, i/ n
  701. /*                                                                                                                                                */, H' b" m; @, @' P2 i! \3 k! s9 M4 Z
  702. /* Returns:                                                                                                                                */( Y& [5 i9 f2 Q# F' t" P
  703. /*                Nothing                                                                                                                        */1 [$ C; u) `; A4 K2 z
  704. /*                                                                                                                                                */; z8 M3 e$ a2 M/ g5 w9 J
  705. /************************************************************************/  v4 x  H2 r! l7 f
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ; \) E6 w: k+ I4 N0 x
  707. {* B0 ^, ~+ ~* p5 P2 H( D* m
  708.         CE_Low();                                        /* enable device */0 }: L) [& p8 w; t( g) t# w2 S/ m
  709.         Send_Byte(0xAD);                        /* send AAI command */! f2 x# F* V9 r4 B" Z: ~2 p
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 A9 {* p6 ?3 v
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : g6 M' |4 M& ^$ w3 |+ f
  712.         Send_Byte(Dst & 0xFF);
    7 \8 m+ y( ^- E9 N3 O) B; ?7 [
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    1 q+ J0 ~8 ^: \+ V( V  [
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    0 Q. e: K3 m/ y4 }; j; x& I
  715.         CE_High();                                        /* disable device */
    . _5 P1 H( J$ V& m
  716. }
    ! o9 @! g$ {2 b$ ?* l' C
  717. 7 P# E: O$ B# v& Y: o0 I  c
  718. /************************************************************************// y( [1 v8 e$ k) w. U! \$ h# @
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ) P4 U3 G1 E- f( A# O
  720. /*                                                                                                                                                */9 L. u: }, I- u. w1 W: e
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, |5 }6 ]) T/ S% C5 ~) [
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ! a# I) a( q5 N
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */( C$ r  c1 t' q/ n; d
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    - ~% \0 t( x% W) P' `
  725. /* is used after Auto_Address_IncA.                                                                                */( p2 O% D9 y4 @3 X) J: M
  726. /* Assumption:  Address being programmed is already erased and is NOT        */6 D: q' b' w: v' \8 Z/ D9 m4 d5 _
  727. /*                                block protected.                                                                                */+ d  H8 U! r5 ^% J
  728. /*                                                                                                                                                */. V% C, D4 d9 e8 {6 N& x7 G
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */3 N  B7 l% y. l9 w! d4 O  J3 G. w
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */( |# o5 T2 T9 n  K# M( R
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! \: T$ y& X' z& ^
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    $ L; |  P; q. I; W* P$ N
  733. /*         last address of unprotected block, which automatically exits                 */9 q% s- S) R0 f" @$ r1 b; S
  734. /*         AAI mode.                                                                                                                        */% s3 ~* V5 j- D/ r! O8 |
  735. /*                                                                                                                                                */: i, z7 `3 G. ^8 H, \- X( |
  736. /* Input:                                                                                                                                */. ?# {' g5 i) h. F! C  i5 {
  737. /*                                                                                                                                                */
    , d: P" I8 L7 @8 u% M) V9 w
  738. /*                byte1:                1st byte to be programmed                                                        */, k$ [. p) {- [1 h% N; O& d
  739. /*                byte2:                2nd byte to be programmed                                                        */
    , S, h3 e! E& U; W! a
  740. /*                                                                                                                                      */6 Q/ w, m0 v* ?, I
  741. /*                                                                                                                                                */7 F7 ~: R6 f( z  [' i1 X) u
  742. /* Returns:                                                                                                                                */
    7 z+ P: Y( y5 Q" u
  743. /*                Nothing                                                                                                                        */
    : y: W8 J' v9 X
  744. /*                                                                                                                                                */
    9 ~8 F" [5 X2 i( G
  745. /************************************************************************/% M' k& K% V. H1 A; W: y
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    0 X& T; i# S. j. j
  747. {
    0 q  z3 ]3 ^7 {% Y" I/ T5 E
  748.         CE_Low();                                        /* enable device */
    + Q4 F9 u6 n# \' H6 G0 L3 I3 T
  749.         Send_Byte(0xAD);                        /* send AAI command */
    6 j0 }2 r, R& {' q( K
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    8 T6 M5 Q! i4 ^+ p: K
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 I# D6 ]3 e7 T' i( ?) n, {5 l; f
  752.         CE_High();                                        /* disable device */& e5 k+ e, b& o! |
  753. }6 w2 d) B. S; f0 u
  754. 5 L1 I$ q  K) U3 z
  755. /************************************************************************/& F* R) d% B  T5 W
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */$ B( I$ @0 j4 a( {
  757. /*                                                                                                                                                */
    * Z3 t: T* o6 _% K2 u
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */8 j- }( @1 d. Y% m( x. p  p" T
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */2 p+ ~8 U3 ]. x; f" s
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */. y! R7 K# q  q, c) O- {+ u# x
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */* u- D3 t$ F2 z2 }$ n" _
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */4 \8 @2 M& Q- O$ _
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ! g3 n/ O' F$ w; ]* t
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */+ D& e/ s. x* M! O4 U/ I! r0 V
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 O  n2 r3 \. y/ ?" a  v  n: G7 `
  766. /*                                block protected.                                                                                */
    1 H2 o1 d0 D# V  _- V
  767. /*                                                                                                                                                */
    & q: i+ r. E) u* i5 d9 j) h
  768. /*                                                                                                                                                */
    7 h9 _$ I& i" h7 j3 n
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */# G) X) `  `- K! x# k1 ~% N
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ; p7 t4 {# t6 z
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */+ K3 Z+ n+ ~3 ]5 G/ b
  772. /*          to exit AAI mode unless AAI is programming the last address or                */6 c/ Y$ x* S. J8 x. N' K8 K
  773. /*         last address of unprotected block, which automatically exits                 */
    4 O" ~$ n3 D. i% m/ r
  774. /*         AAI mode.                                                                                                                        */9 `& g! Z$ X& \
  775. /*                                                                                                                                                */
    ! R7 ~9 T4 M8 |5 o
  776. /* Input:                                                                                                                                */% t: ~: W0 ^. d" V
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) v% N0 Y5 q) u, v1 L
  778. /*                byte1:                1st byte to be programmed                                                        */
    9 Q# h! U, Y" B: s; M
  779. /*      byte1:                2nd byte to be programmed                                                        */
    6 D8 p/ N3 A0 P+ S, J
  780. /*                                                                                                                                                */9 ^. w% ]! B6 E) D) O4 _( _2 M
  781. /* Returns:                                                                                                                                */
    3 N7 s# B" Q1 S& `5 j
  782. /*                Nothing                                                                                                                        */! ?" Z* L7 _! `4 T4 H6 c  x
  783. /*                                                                                                                                                */
    * r: m8 s2 k+ C7 U; I* s2 i6 t2 ~
  784. /************************************************************************/4 K" y+ p; H8 l  B* u
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & Z5 X+ j- @; q4 c: j
  786. {) P( G7 h5 ^" G  {3 ]# a
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        2 _- T# L1 F7 L$ t. a# c
  788. 7 F  U5 {  ^( O4 p
  789.         CE_Low();                                        /* enable device */
    0 G/ q, x' X/ R1 j
  790.         Send_Byte(0xAD);                        /* send AAI command */
    2 ]: k8 `8 }( T1 A2 v$ \
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    3 w% R. E5 l  ~- y9 a+ t
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " @, i; c: P$ L" D) f. v
  793.         Send_Byte(Dst & 0xFF);
    6 N' h9 c( y8 U; M9 e' t/ i  i1 Q
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    2 m, `0 s3 C( ~2 K5 u
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ! r6 \. H. \: b7 ]: ^  Q
  796.         CE_High();                                        /* disable device */# r! h* E4 D5 \, ?4 x9 S/ L9 |/ \4 _
  797.        
    : N& G: L0 Q& u
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */' P( A, f4 D& z+ t4 U1 o
  799. ; ], E6 B+ X( M1 c. T- R2 R/ H
  800. }
    , @1 U2 `. R( Q  r) f

  801. 8 _( c* i& c; O, C
  802. /************************************************************************/, [" F5 v$ S$ k6 \% _! U
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */) ^5 ?2 ]/ j+ l8 K
  804. /*                                                                                                                                                */
    7 G8 [9 m" }) u" J" q$ o1 i
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */: b# ]( l; g7 ^! |, @; e
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */, Y2 z' P- ~3 r! b4 [
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    7 q9 B5 L  L5 ?! k
  808. /* the device.  The 1st data byte will be programmed into the initial   */: g2 s8 T# N5 E4 @& F" W7 T& q5 e
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */; Z- z% }1 a9 ?0 D
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */' p( J! o7 Y# n/ e& t( _6 m
  811. /* used after Auto_Address_IncA.                                                                                */5 g# d4 c- \" l( N8 w! w* W
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    2 N3 P& \% x2 n4 D# l
  813. /*                                block protected.                                                                                */3 a$ Q4 F9 o, u( V
  814. /*                                                                                                                                                */
    8 N+ L2 L8 v9 \5 }* l# X% E) c
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * Y* ]( o5 B; [4 a# ^! c% B; I5 c7 F
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */$ ]( }. d3 H5 W) U- q, B  ^; c1 f( @
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    6 S/ |, ]; m7 ^1 D. P
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    1 `+ H, e. L& H, I" z
  819. /*         last address of unprotected block, which automatically exits                 */
    & G6 e* `4 k) V# {/ w
  820. /*         AAI mode.                                                                                                                        */
    6 d6 W" q. d8 }- {
  821. /*                                                                                                                                                */8 m' E. X: P: R
  822. /* Input:                                                                                                                                */
    - a' _- p6 j8 N& S3 a9 L
  823. /*                                                                                                                                                */
    5 E0 `, p: H1 @) h$ r( k
  824. /*                byte1:                1st byte to be programmed                                                        */! ^/ |9 i4 h, s' l+ f
  825. /*                byte2:                2nd byte to be programmed                                                        */: E3 b7 `& t# M8 J2 y, Z2 \0 ^
  826. /*                                                                                                                                      */
    ; ]5 ~9 y4 M6 P0 ?# ]
  827. /*                                                                                                                                                */
    * I, T6 M9 m+ o: b8 x. U9 A
  828. /* Returns:                                                                                                                                */( G, L4 l- a8 y$ m9 m* }% P) Z( W
  829. /*                Nothing                                                                                                                        */
    / t: G. K, N( V, }, b8 w
  830. /*                                                                                                                                                */! m- i3 g. o. z  i& [; D/ G, L
  831. /************************************************************************/
    , {- H* E- I$ q$ F
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ( a" T2 w: d& u$ k1 Y% V6 a: n2 e( O! g
  833. {0 ?8 A1 \" y4 ?
  834.         CE_Low();                                /* enable device *// S/ r8 ~" j/ Z% C6 ?) H: E
  835.         Send_Byte(0xAD);                /* send AAI command */, g4 q. j6 P/ a7 I
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */! B) z" {& f3 g1 N& y. ^# @
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    # N4 R/ Q9 j) s  u" W8 r6 v* l
  838.         CE_High();                                /* disable device */
    . z# W& s+ U7 M* L. }

  839. ! {$ {( R, X% a+ z2 E
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    , Q0 T1 `* h- ~' l7 h/ c' @7 i

  841. & O4 f9 l! n# {4 O
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    / k+ E/ z# P" b1 N# {* s4 K" F' U8 N
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */& T$ t9 l; Z* p7 x2 P
  844. }/ |# q( j7 c- v# e3 l/ B0 t

  845. - t1 H/ G4 H" q
  846. /************************************************************************/
    9 m4 {6 i5 F8 a3 w
  847. /* PROCEDURE: Chip_Erase                                                                                                */7 d; [4 L, f. O  O# ]4 Z' c
  848. /*                                                                                                                                                */, N5 q" ^/ }) l( z8 F, B
  849. /* This procedure erases the entire Chip.                                                                */2 v' v! @6 k: G( m4 O3 y, z
  850. /*                                                                                                                                                */$ O+ E8 V3 @# B# B
  851. /* Input:                                                                                                                                */
    4 u/ @& u% i0 O( X1 A
  852. /*                None                                                                                                                        */
    , L" b% t# M6 b* U/ B+ A
  853. /*                                                                                                                                                */* p- C. R4 |, L! |5 ]- U) w
  854. /* Returns:                                                                                                                                */
    $ i2 P& f+ y1 _
  855. /*                Nothing                                                                                                                        */: D, M0 m4 M6 Q) p) ]% t
  856. /************************************************************************/
    ; q( q# m4 \8 @8 X
  857. void Chip_Erase()
    4 R+ {  R- K: L7 `. e3 ]8 p
  858. {                                               
    ( s& z4 o/ p0 N
  859.         CE_Low();                                /* enable device */
    4 @/ z  q  Y% p
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    9 i  d* N% e" @
  861.         CE_High();                                /* disable device */
    % d3 A1 I* k0 ^* F
  862. }
    * A) O2 X- X% x5 B/ q4 G7 r

  863. 4 F& z2 m# J5 n7 q' a
  864. /************************************************************************/
    ! J$ _; m* Y' E, [
  865. /* PROCEDURE: Sector_Erase                                                                                                */8 Y8 F. |$ T/ G* b5 ^
  866. /*                                                                                                                                                */
    " a. U9 T( o( `1 ~& ^& N$ E2 [
  867. /* This procedure Sector Erases the Chip.                                                                */& n1 ~! H. p5 h$ A$ P
  868. /*                                                                                                                                                */
    % _+ h; P3 N# x% l4 ?  o8 {6 I
  869. /* Input:                                                                                                                                */
    # R3 H" [  _7 r& [0 g
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 O# }5 D6 g* f9 I/ R
  871. /*                                                                                                                                                */  J7 a" W! t% x/ p0 ?6 V. K* l
  872. /* Returns:                                                                                                                                */
    7 O( @. O" `! Q$ a) ?
  873. /*                Nothing                                                                                                                        */
    - b$ B% v! F0 n3 K2 k
  874. /************************************************************************/
    : Q$ |9 f/ @' {( T2 q+ M! `. X
  875. void Sector_Erase(unsigned long Dst)
    - h5 R' \0 f2 h( f8 I5 e
  876. {6 L3 ]- O' E! I, A: P/ W$ a" N
  877. 5 S' E$ z9 p; ~3 z% `. [
  878. " j! l  }; p; s
  879.         CE_Low();                                        /* enable device */
    # r7 V. |5 V* z4 ~
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    $ G# k* x& o) s# E; `
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */- j4 j( ]8 \# k7 [0 ]/ @- ^. h
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));: x* F/ \" q  h
  883.         Send_Byte(Dst & 0xFF);4 k( f6 {" `; {& H1 K8 ?3 F0 u
  884.         CE_High();                                        /* disable device */
    # ^5 R: x) a& i' @+ ]+ M
  885. }       
    0 ~& z& G6 X* I/ i2 Z5 V8 M
  886. : [, K  M% M  b  x8 d0 ]( K
  887. /************************************************************************/
    ! t3 A# \1 z( L
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ; d/ B/ t+ f- P
  889. /*                                                                                                                                                */
    ' ?# e# H; e# D  _$ {# o
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    * {  H. Z& a, k0 |' |1 ?. J
  891. /*                                                                                                                                                */, W& r% d( ?5 ^
  892. /* Input:                                                                                                                                */
    6 @5 P. O- p: ]# Z% B# v- Q
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 N1 Y# V7 u6 D  K. |
  894. /*                                                                                                                                                */
    2 s0 m' F, u: Q( O3 W7 `: z
  895. /* Returns:                                                                                                                                */
    ) a; c) \# [5 I8 o" N+ v! l$ ~
  896. /*                Nothing                                                                                                                        */  S) Q7 P8 Y/ a
  897. /************************************************************************/
    7 q8 C/ M, z" o0 v. m) e
  898. void Block_Erase_32K(unsigned long Dst)
    2 S9 U# Q' V# \% e/ t' i. ~2 \
  899. {0 D4 U) A; |. }  u7 x
  900.         CE_Low();                                        /* enable device */
    / l, n; v0 s4 {" I9 U" l
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */, A" }; ]  S& m$ a* V
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + j, J; w& E8 h! J0 d. d! _; \, u
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));& ?% a4 I7 l/ B  u% F% X; [
  904.         Send_Byte(Dst & 0xFF);
    ( r' l* a3 p3 q& A; ?1 o
  905.         CE_High();                                        /* disable device */1 x3 m% m, F8 ~8 G
  906. }; [: W6 N( J: m. X4 w
  907. ' B" N( u% Z$ I8 Z* v
  908. /************************************************************************/
    6 e, ?* w6 z  J' O3 x$ w3 v
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */, `  `  Z, |7 d+ t2 c- @1 i  @# W) K
  910. /*                                                                                                                                                */. c, b7 j, x( a* U+ A; W6 y4 k
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    2 L7 ~2 e6 c' I. D
  912. /*                                                                                                                                                */
    " c, u6 t( p3 @5 l
  913. /* Input:                                                                                                                                */  v/ w3 N0 {) h. Z7 W- n
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. E, e& a+ I& E$ L, d6 T: Q
  915. /*                                                                                                                                                */
    # x4 B: W) r$ D) `3 g( B; u
  916. /* Returns:                                                                                                                                */- m7 n$ ^0 Q' T/ F5 O, K# s
  917. /*                Nothing                                                                                                                        */
    ' i/ g" k6 C3 C) [9 W+ k
  918. /************************************************************************/' \% J. @1 T9 W
  919. void Block_Erase_64K(unsigned long Dst)
    9 ?# f& G+ Z* J8 `
  920. {% w0 f( ?0 P8 f& f  A: G$ T% l& {
  921.         CE_Low();                                        /* enable device */
    - |! [3 A1 a; L( T
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */$ u/ \9 E5 W, z; g
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! r9 V5 x2 k) ]" Q  {* |3 A
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % y* u( I0 f0 c& j3 s
  925.         Send_Byte(Dst & 0xFF);, o1 f. F0 M; Q# L! g
  926.         CE_High();                                        /* disable device */
    ) E/ `) B1 l9 ^  o* e% S$ t
  927. }
    9 @* [$ x1 l$ n% f  y( c% e

  928. ) T! Q6 E$ {( J7 C/ G( H
  929. /************************************************************************/
    - X; q* z5 m* Q, M/ s! N
  930. /* PROCEDURE: Wait_Busy                                                                                                        */2 F3 R  K1 `' M: f  X' i
  931. /*                                                                                                                                                */
    9 D/ o3 L4 v8 V. h% n. f7 G
  932. /* This procedure waits until device is no longer busy (can be used by        */- ^) C0 m  Z, D- F+ x# m
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ) ^2 f, v  i  F
  934. /*                                                                                                                                                */( u0 A, f/ l9 Z3 y) I, b4 h5 G3 G
  935. /* Input:                                                                                                                                */
    ' h" k3 C. k6 p  T( G, |! _7 q
  936. /*                None                                                                                                                        */
    $ g0 T/ z2 `: X8 P- c% R
  937. /*                                                                                                                                                */3 x8 R* R5 f7 v- R  s$ B  C
  938. /* Returns:                                                                                                                                *// V! }. w3 O6 t3 r8 b
  939. /*                Nothing                                                                                                                        */6 y" x+ X& q. o: G7 I4 o* ~. Y
  940. /************************************************************************/) m. I; C$ d# c% K' Y1 [
  941. void Wait_Busy(); a; i9 U# k$ y
  942. {' u( C# l! C/ I9 o6 L
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    8 C- K- g7 j6 D; i4 h# s
  944.                 Read_Status_Register();
    ; c  ?$ c6 r. q" G1 a
  945. }
    ) @# T; b, ?5 v8 T% S

  946. + O0 f) |; c8 |2 l$ h
  947. /************************************************************************/
    & n4 q( m+ b% y  [% B
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    " w' H' v' i7 V3 u
  949. /*                                                                                                                                                */2 D. f& \, L6 Z- R
  950. /* This procedure waits until device is no longer busy for AAI mode.        */$ e# n# g$ Y& `! p
  951. /*                                                                                                                                                */
    9 ~! ?* G& w) I) h/ m5 r+ s  x2 V
  952. /* Input:                                                                                                                                */8 t1 D! E- F$ ?" j
  953. /*                None                                                                                                                        */: g" q  K, W4 O
  954. /*                                                                                                                                                */
    ; U8 X! q+ r- Z
  955. /* Returns:                                                                                                                                */3 m, v5 ?' w2 f% w$ ^
  956. /*                Nothing                                                                                                                        */
      E6 I7 G3 A4 q7 |) Z
  957. /************************************************************************/
    7 n* X  ?! b& ^: q7 }6 l$ T
  958. void Wait_Busy_AAI()
    . b% F7 M) v3 C- Z
  959. {
    + i# l! M3 ~+ J: e( u
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */1 X* C7 g! i$ |% d) d7 U
  961.                 Read_Status_Register();
    0 [- T3 F+ T- a9 q# h; ^8 `
  962. }2 v# I7 X% S/ @- q5 G2 x
  963. ) }, U5 o8 p2 w# ^: ^* O( l
  964. /************************************************************************/) U* J. H( W3 o
  965. /* PROCEDURE: WREN_Check                                                                                                */
    + ]/ U, |! j) T$ x+ w
  966. /*                                                                                                                                                */; N! P, q3 a. ^8 N( K0 C
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    & ?2 S7 N8 a: o
  968. /*                                                                                                                                                */
    ' e% n6 T! ]) N. k0 Z
  969. /* Input:                                                                                                                                */
    + n5 V, ]! Z% G' @" E1 e( ?
  970. /*                None                                                                                                                        */
    " z# ~7 e+ i& V" [1 \
  971. /*                                                                                                                                                */
    0 N" @' p0 e; t$ {( l' R$ N
  972. /* Returns:                                                                                                                                */7 P6 W' b! A% ^, r$ R" Q  ?# q
  973. /*                Nothing                                                                                                                        */6 Y1 U" b" W" c8 I
  974. /************************************************************************/8 f: T+ Q9 C7 G# A& }4 ^# I9 P; v2 T
  975. void WREN_Check()
    2 B1 t$ o7 z$ a9 P4 Q
  976. {. D% A" S' K1 x; e% r
  977.         unsigned char byte;
    # B' a8 a& z9 F
  978.         byte = Read_Status_Register();        /* read the status register */
    # Q# Q1 m6 J0 k4 E$ @. e7 U% i
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    5 S, }- r) a2 P0 D8 f2 L1 Z
  980.         {+ i. N8 K' e! r0 T; j% o, B
  981.                 while(1)  \/ b- d/ s4 ^" X
  982.                         /* add source code or statements for this file */8 E9 {/ F1 _5 w+ e
  983.                         /* to compile                                  */
    + [0 b% O: ~. Q/ Y
  984.                         /* i.e. option: insert a display to view error on LED? */6 m$ U- e: h- |) X) m% f
  985.                  
    " w/ S. Q$ e4 {1 G8 r
  986.         }" Y  B4 W! X) r- T
  987. }) b5 l1 F% k! v0 @
  988. 8 Q$ T( b8 Q3 p, p6 o
  989. /************************************************************************/; o/ Y1 F6 c; h. f: O$ B
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */! Y" Z$ x- b4 h  @  f/ e. A: s
  991. /*                                                                                                                                                */
    . d5 S. f0 c( @0 A  t% U$ c
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */  L4 s7 c) E2 s8 g' [
  993. /*                                                                                                                                                */7 E1 ~) O7 K7 |  \1 ]8 J3 v
  994. /* Input:                                                                                                                                */& W0 ?/ r( p+ @* ~. |
  995. /*                None                                                                                                                        */- ?8 u0 k8 c/ W- U# [& a' g
  996. /*                                                                                                                                                */) O, S& x/ ^! F2 _& \' ?
  997. /* Returns:                                                                                                                                */2 \4 E& V% D7 g$ n( i
  998. /*                Nothing                                                                                                                        */% J% }' h* _: ?" L9 B( s6 [6 ?" X
  999. /************************************************************************/. X& j5 X+ J9 E* {2 }3 [4 p
  1000. void WREN_AAI_Check()% |2 S  \" }; V. b
  1001. {
    9 @* l" Z; r% L2 j2 m; ^
  1002.         unsigned char byte;
    6 H+ |- W/ O! L0 ]* N+ ]. H* U* u
  1003.         byte = Read_Status_Register();        /* read the status register */
    , Y, }$ O* \) ?
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    % u2 v7 s0 y% i
  1005.         {
    9 r2 E9 V; G- T: D% J4 _
  1006.                 while(1)               
    - k- N5 N7 |. Y* O1 R
  1007.                         /* add source code or statements for this file */
    4 @4 _/ a. A0 A' t3 Q
  1008.                         /* to compile                                  */" {/ o3 V$ o0 {  h
  1009.                         /* i.e. option: insert a display to view error on LED? */0 N0 O5 k! }2 ?9 [" i
  1010. 8 {% k6 z* d+ a( {
  1011.         }
    + r( u" t4 w" T1 u$ |' b
  1012. }  K- s4 z- d4 O7 e1 N

  1013. ! H6 J- w' u! R3 z. f: G8 F* F& ]
  1014. /************************************************************************/
    0 i  L4 k9 W% [* n2 g0 K
  1015. /* PROCEDURE: Verify                                                                                                        */
    ( f: K! I, H9 L9 g1 U) {% Q
  1016. /*                                                                                                                                                */
    2 j! t/ l1 ~$ H5 X; Z% y( {
  1017. /* This procedure checks to see if the correct byte has be read.                */
    4 ^) i/ J7 G% y( d7 n% }
  1018. /*                                                                                                                                                */0 ~- y- w" m9 m7 \
  1019. /* Input:                                                                                                                                */
    1 {( |# S. e7 b6 h# e8 R
  1020. /*                byte:                byte read                                                                                        */9 h5 Q; C# Y; b
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    0 m6 ^! T# d5 {: A, H
  1022. /*                                                                                                                                                */# H% c3 Z1 P, Y. L
  1023. /* Returns:                                                                                                                                */; ?$ w$ T  K" _2 L! }
  1024. /*                Nothing                                                                                                                        */
    % z' {7 X0 _" Z" i3 t8 a: j7 `
  1025. /************************************************************************/: o) t+ k2 `: b
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    " S3 U, E3 b* p: I
  1027. {
    % U" ^) h8 C, R' r4 p- P9 o
  1028.         if (byte != cor_byte)
    5 C0 l0 l3 j* d1 L: `0 v8 Q
  1029.         {  i/ K0 @5 M8 P4 [8 T1 i" Z
  1030.                 while(1)
    7 U* h8 @* G$ u
  1031.                         /* add source code or statement for this file */0 l5 m3 i( d$ d6 R+ e* i& w) z
  1032.                         /* to compile                                  */
    / K" G# G% r5 P4 z3 w, I" S' |( D
  1033.                         /* i.e. option: insert a display to view error on LED? */
    / e' M% g3 h& a. x" t
  1034.                
    0 x6 p" l, t/ a* t, E% T7 L
  1035.         }, |; P5 C0 v- R9 }4 p; L. F3 A
  1036. }
    9 l# P; {5 w! }* S- x
  1037. 0 [0 `( c  T: t3 f
  1038. 3 h/ l, a) V" ?+ I9 q1 ~+ G
  1039. int main()
    ( ?& B% \) x% G5 R4 e& X
  1040. {
    4 e, G2 R% n' Q, o

  1041. ; m) [: H$ I# V$ J
  1042. return 0;
    : s9 Y) Y6 O7 u" p- C$ g4 M
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:* c. f# J8 f2 a4 I' D% @- P
   main(), [9 L4 M/ b: {2 `
   里面怎么是空的呢?
$ {* s8 i2 y- E/ n* n% ]   发一份给我吧
: g$ ?4 h( ]8 S3 }1 pmail:luyijun2005@hotmail.com
, A  _% i* g5 S& E  [6 C5 B% m咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。9 D4 G+ O! c- q! a: k, C$ N! S; P
7 U$ I0 ~1 S# N) n3 K4 O$ K  v
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
2 i. B) n) t# |0 U8 uEC的代码在哪跑,你看DS的说明,每个EC都不同的。! {+ `7 E& O5 E9 f
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?8 `2 ^: b4 t4 I( ]- S0 H0 j
上面几个问题是你没看任何东西而白问。
* r9 v1 K4 ?( O7 c& V3 U- I
3 v9 h( C+ C6 B" g9 t/ F8 A至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。8 `# O1 |% N, T5 i5 K  s/ _" a

  A  G& X) w: |7 i关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
% {% a% t: ~* v  _. L
0 t  p0 N0 l, q  G关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
3 w1 Z2 G2 _: B8 x$ P6 t+ X! ]5 N6 D5 S
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
3 o: @( V2 R3 E! y$ G
* t6 k: l. L  C+ q. r不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
( f3 s8 h/ {6 {2 L% T/ c; s似乎要把SPI能support 到最大,这EC chip应该有好卖点- E$ |# R4 @- ]" [* N
BIOS功能要不要强大,也就决定了SPI Flach的大小9 B0 B, X" h( _8 R
我是这么想的~让OEM去决定要挂多大!
, t6 A: U4 K6 H* D* i! ]) j如果我司有BIOS工程师就好了~哈
4 n0 B! ~: m& c& K2 PWPCE775应该算很新的东西,来看它支持到多大?! R1 h- K2 K6 M$ P) p
2 N& l' o' ~: w7 Q, a& u& S
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte! s; ?8 K- x  Y+ G0 [$ Z( b
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.% `  Y4 d, m0 I( ~6 I6 z
# z8 i3 \9 P& t' g9 B3 k" f
这份driver收下~希望以后有用到
+ T5 f! i# {. _/ J( O' n% M6 g- O谢谢bini大大
/ q( }* A; X- v2 B7 B
( P; ?8 k; `$ s- y/ u4 N. U很新很新的新手,如有错误请指正 (准备看第二家的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()
0 S% |$ y5 o# J% Z8 n' o; F3 A{, i* ~! ]  l' p2 |
        unsigned char temp = 0;
: p) x0 u+ H9 }. [' S/ A        CE_Low();, h9 w4 z2 W. B8 ]5 \
    while (temp == 0x00)        /* waste time until not busy */. f- M1 G" w7 K8 h
                temp = SO;
) I3 W, {0 R6 r7 C! `( ?4 [        CE_High();
0 j' ~5 S4 n% @6 r4 F}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
& q" d& v& ]- A# l{: O" ]3 E1 r+ B/ J
        
3 |. d5 `2 l& i3 t: z2 v1 V$ E; z        unsigned char i = 0;# V4 Z* Y; z; a+ J. Y0 a
        for (i = 0; i < 8; i++)) c/ K; Y  L4 h& f
        {
: ]( N. n, M# E& f) e$ a- d                2 d  v5 @' ], A: F/ d) o
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
; h+ r; m, K% J2 [                        SI = 1;% ]2 @: H0 D" X+ s
                else! Q3 P2 B0 l' i9 P
                        SI = 0;                                /* if not, set to low */
  h5 A; f; z+ Q7 }: {( v 问              SCK = 1;                                /* toggle clock high */
% H! L8 {/ I# ]  q- D   题            out = (out << 1);                /* shift 1 place for next bit *// F" r# l, }! u7 c0 X$ T
                SCK = 0;                                /* toggle clock low */
9 @. u! d* T, O# Q        }/ x. a) |: I! r' S: b' q" \# S
}* l0 Z( d- A5 \6 Y. Y! q, N5 L* c
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-1 04:10 , Processed in 0.061149 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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