找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55156|回复: 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- S6 J2 }7 `7 v/ A' _6 R
  2. & R* y) l" b3 v& q7 t$ A8 ?
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    1 T* e6 C* N( T& L* {9 a; v

  4. ( T* j9 K) x: L3 @  H( w
  5. November 4th, 2005, Rev. 1.0( m! A4 u, }8 h3 \( x/ k" G% B

  6. - r( S. x. k9 m
  7. ABOUT THE SOFTWARE
    3 @0 H1 [) o3 L( ?8 ?5 f
  8. This application note provides software driver examples for SST25VF080B,
      \, Z/ S' }  A
  9. Serial Flash. Extensive comments are included in each routine to describe . I" y/ g- x' h# g  D) Z8 q
  10. the function of each routine.  The interface coding uses polling method 2 t2 K) Z% N2 O6 s
  11. rather than the SPI protocol to interface with these serial devices.  The
    0 [, _$ ?: {  L7 s% `% _
  12. functions are differentiated below in terms of the communication protocols: _: j- s, \0 Q0 f/ V
  13. (uses Mode 0) and specific device operation instructions. This code has been 8 y" J, U6 y: {2 }- _* k
  14. designed to compile using the Keil compiler.
    & m; O5 L2 f( }5 S' B. ~& m/ R3 `5 r
  15. ! e0 _! ~- a2 r; C! m

  16. 1 ~" G" Q" e" s2 Y
  17. ABOUT THE SST25VF080B
    8 H+ {3 d7 H) W$ C/ m
  18. / P8 m7 l+ \9 o- ?% W. j
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    6 F" l& W% {7 [# R  x5 D
  20. conjunction with this application note for a complete understanding % e. n  r( C# H
  21. of the device.
    4 H3 |8 V4 E& l. k  e  }# r
  22. . _; n' @% \7 I  I- A# c$ {
  23. ) f9 B  l/ T( l6 \( M2 @. b
  24. Device Communication Protocol(pinout related) functions:  [& i7 [- J( z% }0 x0 g* e
  25. ' U* D9 c" A. H6 z$ U
  26. Functions                                    Function, X3 }2 [  y1 t# X, K" L. F
  27. ------------------------------------------------------------------: _$ l0 q4 d( E% f& e+ V' a8 `
  28. init                                        Initializes clock to set up mode 0.
    . R6 D! e2 L  y, P5 Q* G
  29. Send_Byte                                Sends one byte using SI pin to send and ( N$ T7 C, z$ T# `+ D+ t
  30.                                                 shift out 1-bit per clock rising edge
    - F' M6 R0 I) C3 U0 |3 [
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 8 g5 V* e1 z* F2 v0 y: t
  32.                                                 in 1-bit per clock falling edge
    4 `- t8 \, R) W" u# P7 }6 l
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    / n. U" o) z2 T* w) @' m- [; _
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high8 L! z& v$ w6 T8 b1 s5 A. a$ o
  35. CE_Low                                        Clears Chip Enable of the serial flash to low% [; v8 s- p1 |% n! ]; i' k3 W* B
  36. Hold_Low                                Clears Hold pin to make serial flash hold8 W3 h  i0 W7 l9 O1 d
  37. Unhold                                        Unholds the serial flash6 l, j; q4 \1 [( M! m9 R
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ) s; N3 Y! ]8 k% l# E9 ^6 s
  39. UnWP                                        Disables write protection pin
    6 _( S  H2 p! h7 A
  40. , D9 P% Z* {3 n) w$ U. g& ~6 B! E
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code* W# ?, _: C, h, w
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your+ l' C9 V( Y' B5 t
  43. software which should reflect your hardware interfaced.          
    $ l0 |- b2 j0 S' w0 P3 t: q, w* S' F

  44. 6 m+ B2 r, T& l/ N

  45. 0 Y7 `1 u. {2 k6 f6 F, U: C( N0 U3 v
  46. Device Operation Instruction functions:$ P8 m/ K( M9 ~( i2 D3 j
  47. $ D9 F" Z  P* |  w3 c8 `- c
  48. Functions                                    Function
    6 |) i& F: I. K$ A9 r1 R
  49. ------------------------------------------------------------------
    " e+ M  Y3 Q4 L6 h  ~4 }
  50. Read_Status_Register        Reads the status register of the serial flash& O4 E9 _# h8 K% N7 h# O" T+ ^& U; h
  51. EWSR                                        Enables the Write Status Register
    / x6 c$ t: H3 m0 ?, k2 @
  52. WRSR                                        Performs a write to the status register
    % M/ V" [( E3 [, I* T0 m8 n
  53. WREN                                        Write enables the serial flash6 J6 V2 W9 d3 d5 Q; K. U1 L
  54. WRDI                                        Write disables the serial flash
      Q1 E' G3 N- n4 H6 ]
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    6 {3 T9 w! H" Z. ~, [
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming% @6 m( U5 u. o) f3 R
  57. Read_ID                                        Reads the manufacturer ID and device ID
    : g' D/ b9 B  Z4 K6 q" c2 `+ y
  58. Jedec_ID_Read                        Reads the Jedec ID$ t7 t$ E. X" l' h5 k. S1 H
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency). i: D& Z# r! h. ?# R4 h
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    1 x  O2 b& S& g9 \& a9 I' i
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    # v# ^* i, N$ Y' r
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    + z) O1 q3 ^! k$ I% t. r# T6 Y
  63. Byte_Program                        Program one byte to the serial flash7 {, K5 M: Q5 x) c1 h
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    3 z  F" Y6 O$ k- z( G
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation4 K; i1 ?  R5 N- S
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    1 ~+ _: p2 B9 @& h$ U/ S' X
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY4 A$ h6 P5 Q/ n3 O
  68. Chip_Erase                                Erases entire serial flash. t% A  W" o. o7 {& W
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    " Y2 @* Z7 C  K) f
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    / \; D9 ]3 d8 |- \4 S7 U, w- H9 D
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    0 E2 l7 i* ?8 u
  72. Wait_Busy                                Polls status register until busy bit is low
    - \( e4 C8 {% O3 Y
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    % r7 X. u6 b& ~: W+ W& y
  74. WREN_Check                                Checks to see if WEL is set
    $ C( I1 T# I" Q. u$ W
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    ; P: z8 S8 I- j' P
  76. ! Z' _" {0 z" v9 E# L5 R
  77. 9 ~+ E  t2 j% U
  78. : J3 I  t/ P6 b: {9 L
  79.                                                                      3 [0 x1 \0 D) w; V9 ^
  80. "C" LANGUAGE DRIVERS 1 t# D8 {! V3 S( x5 B& p' ?6 q

  81. ' k, b: A0 \  V4 ]: p, @
  82. /********************************************************************/
    8 l" d- i! Y4 \, @2 \2 ^3 ^
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    - o8 d9 ^- R: G# l+ M
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    , K/ Z+ L2 r2 U; _3 a  [- e
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    ( ^+ g; V8 V$ n4 c1 W, _5 U
  86. /*                                                                  */
    7 k' G) U0 H: C9 |- l( y/ c. ?+ p- F/ L
  87. /* Revision 1.0, November 4th, 2005                                                                          */   & u/ S  v6 b: ]; x* R3 x
  88. /*                                                                  */
    + n4 d& b# I8 f/ ~+ ?5 J
  89. /*                                                                                                                                        */
    $ ?& g( E. a, G7 ?9 ^
  90. /********************************************************************/
    . u& o, Z; S. s# X* W- @

  91. - K: Y" c3 m7 }6 h/ H* l0 @
  92. #include <stdio.h>
    / f9 ~! u: d' u+ w9 S9 y
  93. #include <stdlib.h>
    ) i* S* s+ j) n8 E" n
  94. ! e" J5 ]- s+ e8 ^: Y
  95. /* Function Prototypes */* F& V: W' W- a& l2 k/ D, Q& I

  96. . e& A7 ~/ P( j# q0 l
  97. void init();+ d5 x7 u2 A! |
  98. void Send_Byte(unsigned char out);
    & v$ K. j0 y% F4 n" ~
  99. unsigned char Get_Byte();9 B) z  o; C" j' W+ ^
  100. void Poll_SO();; G' L3 {! a2 _7 [; i1 e+ n
  101. void CE_High();
    4 B" b* X2 U" V# j1 |" r
  102. void CE_Low();" N" Q; c6 G3 z7 f
  103. void Hold_Low();
    ) b" `( B  d8 F3 Y
  104. void Unhold();2 {8 A' s4 @5 e# z2 b# \
  105. void WP_Low();
    % Y+ X: i5 M+ k# t3 w
  106. void UnWP();
    2 u2 d& n" r7 R; D0 L0 `
  107. unsigned char Read_Status_Register();1 \- D; ~6 n' N+ n% z1 }
  108. void EWSR();
    4 l' j4 `/ F% ]. }0 h2 M  ^
  109. void WRSR(byte);
    ( I. c7 ?. e6 \0 L& X8 J' G9 i
  110. void WREN();$ s6 _5 S& j% G3 e- L1 H/ K
  111. void WRDI();3 b. s+ g' ]8 C9 l/ B; D0 K
  112. void EBSY();
    8 r$ q% G% p9 V& t8 `9 v
  113. void DBSY();
    ' S$ a. X) W6 h
  114. unsigned char Read_ID(ID_addr);  H. Q+ |$ Y3 c! v" t0 R- `  |8 L3 Z
  115. unsigned long Jedec_ID_Read(); 9 k1 r( |/ l3 _- Y! ]+ g0 Q
  116. unsigned char Read(unsigned long Dst);
    & E% {3 x9 x- r9 y& N- G
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);! r4 b! j7 c8 n' h4 b. r
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ! H) G6 x* M0 F& }2 _
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);3 @7 q* O5 s1 S- k9 k1 f
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    0 H8 q& j! s, `9 m9 f/ u
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);8 [/ I5 R; b' r0 Z2 m) c
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);/ ?; U0 W3 y' Q4 ?$ J0 U* t( y
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    " V* z$ i- i5 i8 i3 j" [
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);  F  T$ ]/ ?" _
  125. void Chip_Erase();
    , N- W; }# k+ Q  i- X$ L- k
  126. void Sector_Erase(unsigned long Dst);
    ! c: Z! {1 p* k) ^
  127. void Block_Erase_32K(unsigned long Dst);; B9 A( v6 y0 f9 v* z
  128. void Block_Erase_64K(unsigned long Dst);
    $ t0 D6 {! m0 N0 C8 M) p; i7 }
  129. void Wait_Busy();, Q# W1 ~& H  m8 A" B7 X: V
  130. void Wait_Busy_AAI();
    # O! W: d2 g- _
  131. void WREN_Check();) A. m! S+ _* _) b$ E
  132. void WREN_AAI_Check();
    ! X( a* @# U0 e3 v4 Z' z% m

  133. . z) J; b  u/ o
  134. void Verify(unsigned char byte, unsigned char cor_byte);8 j( c$ r5 n& q& x5 Y/ b

  135. / P  R& J- H5 n5 O' k
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    5 {1 w0 Q7 V6 `! ~* S# x2 A0 L
  137.                                                                                 /* to upper RAM area from 80H - FFH */( y" e4 B/ S' a7 ~' D6 u

  138. 6 ]+ u: k+ D9 A4 q8 G7 J
  139. /************************************************************************/8 y( b. m$ E" c' ?7 s
  140. /* PROCEDURE: init                                                                                                                */
    ( `- h, m4 |8 f+ W1 g) i
  141. /*                                                                                                                                                */
    * }" D) M6 D  A  F' F- ?+ y
  142. /* This procedure initializes the SCK to low. Must be called prior to         */2 p& L* d$ @5 @$ @+ ?! s6 Z! V
  143. /* setting up mode 0.                                                                                                        */3 c" a8 B1 s1 G' T" e
  144. /*                                                                                                                                                */7 Q( ]. O/ k5 @4 ~
  145. /* Input:                                                                                                                                */
    , P2 O- J( V# ?
  146. /*                None                                                                                                                        */0 w3 N" a9 o6 e+ I8 F
  147. /*                                                                                                                                                */! G0 K( E! A: N( u: ~1 R9 b
  148. /* Output:                                                                                                                                */
    % |" b) F, k  l  j7 O6 E6 p- o. I; w
  149. /*                SCK                                                                                                                                */
    * {  H" B! e8 I* D9 A9 o( I, z6 S8 q
  150. /************************************************************************/  _8 `- C* S- `9 \% Z
  151. void init()
    6 e: Y) h( G7 h3 s$ m
  152. {
    - J2 E8 k2 [( W/ I  _5 L% r% O1 ?
  153.         SCK = 0;        /* set clock to low initial state */
    , b% a8 l- j1 f" n5 J3 O
  154. }
    . T  g; T" k8 S7 i
  155. / i3 {, S2 w0 n, |3 B1 B$ m
  156. /************************************************************************/. X5 B3 N! c/ L  l  a8 n1 K
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    ! m2 I* x# z! c3 L  s; P
  158. /*                                                                                                                                                */+ m4 o' V% ]: h/ i2 k/ F4 g' ]
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    & r8 D* I+ N) {4 v! X; P0 u5 M
  160. /* edge on the the SI pin(LSB 1st).                                                                                */! U. w: L6 J* Y; e
  161. /*                                                                                                                                                */
    9 p* z: t4 c$ p$ }5 s1 j
  162. /* Input:                                                                                                                                */
    4 n6 h/ |7 a" n) G6 v: X5 ^. B
  163. /*                out                                                                                                                                */0 |+ U& n) `; `7 |
  164. /*                                                                                                                                                */3 d. A" C8 k6 i, G$ L& w
  165. /* Output:                                                                                                                                */
    ' V$ Z( \4 Q- R  \$ X
  166. /*                SI                                                                                                                                */% S! m! [% S1 s7 R* A; \
  167. /************************************************************************/9 `5 d" X; r7 E
  168. void Send_Byte(unsigned char out)
    ; ~% ~, c; e" r9 Z' s& Y+ L
  169. {3 u. k3 @9 _4 [8 y
  170.        
    ; S, D. \# k* F  n) x# J
  171.         unsigned char i = 0;" J/ ]) o, R  N# s# |2 J! J* O4 K
  172.         for (i = 0; i < 8; i++)
    6 `# B+ L7 [1 s4 F3 ~: L
  173.         {# S. \! y# y! f6 M1 e! b
  174.                
    2 O" N2 w3 R2 v/ R$ e1 U
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    ! d3 p/ B3 D) e9 G
  176.                         SI = 1;
    " B  m% [; h7 x. O! h
  177.                 else
    . G7 F. }8 V" d
  178.                         SI = 0;                                /* if not, set to low */- L& T7 S4 [; L- Z
  179.                 SCK = 1;                                /* toggle clock high */
    . d7 v% J) X1 V' H/ b
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    1 t# j: V7 ^) I- L) K
  181.                 SCK = 0;                                /* toggle clock low */# Y- a! d! Z2 Y( U1 p6 r7 I# m
  182.         }
    1 E( l0 r& w' {0 t4 D2 x2 v2 L9 R9 o
  183. }
    % y* q/ p# o& p; u! s. m
  184. 8 d" ^7 a( C; q" @- l8 w1 E9 _$ s
  185. /************************************************************************/7 s6 b0 B+ Y: {' x$ F
  186. /* PROCEDURE: Get_Byte                                                                                                        */4 M. W2 ]1 p: t4 ?
  187. /*                                                                                                                                                */  [' g! _; l3 D" ^: }" @: g
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    7 z9 c: V5 v: L. F6 _5 [0 [% a& g/ x0 E
  189. /* edge on the SO pin(LSB 1st).                                                                                        */7 @6 r/ Q5 e+ x4 {% ~: O5 T6 x
  190. /*                                                                                                                                                */+ F8 c; K5 K1 Z8 N8 L
  191. /* Input:                                                                                                                                */9 [1 N. Y' P/ B4 ~( b; E, n+ D
  192. /*                SO                                                                                                                                */
    1 ~; V$ v" \! d/ b# H( H# H
  193. /*                                                                                                                                                */
    , ~: ~1 O1 a# w- \
  194. /* Output:                                                                                                                                */+ I2 C" X" N1 \
  195. /*                None                                                                                                                        */5 C+ e- Q, B1 G9 }$ d) d- N1 H
  196. /************************************************************************/
    ; D  Y' R) z: x
  197. unsigned char Get_Byte()
    . b3 t% R% o/ i
  198. {9 k# X% e7 A: i
  199.         unsigned char i = 0, in = 0, temp = 0;
    & }- G) a' y  O3 V. f
  200.         for (i = 0; i < 8; i++)* m7 j4 i: Y) s6 u6 z! n
  201.         {
    / Z) [+ {" E6 ?
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */: A$ h  B  X+ V5 Z( O
  203.                 temp = SO;                        /* save input */
    $ j0 @; _+ l* U6 [: w8 l/ `
  204.                 SCK = 1;                        /* toggle clock high */9 c/ c! c9 z- K4 s& {. ~6 r+ C
  205.                 if (temp == 1)                        /* check to see if bit is high */5 r- ^: u% z& q7 m2 X
  206.                         in = in | 0x01;                /* if high, make bit high */0 T6 ~; A, y7 [" D+ Z8 a* A
  207. " I; n5 {! o1 V5 u% p
  208.                 SCK = 0;                        /* toggle clock low */; P& ?+ ~5 n: R% H- ?+ ~0 C
  209. - E' |  y( T& G" z
  210.         }# n, ~, }8 U/ ]6 d0 M
  211.         return in;
    6 _* j6 D) J# t, d; g3 V
  212. }
    1 H5 j; y& H# c' O

  213. 5 X4 [9 o- x4 f6 f3 O
  214. /************************************************************************/) I" `5 `1 o/ n$ M
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    2 K) Y' H! G7 N) n& y. [
  216. /*                                                                                                                                                */
    + v) f/ U, c' f, F! ]
  217. /* This procedure polls for the SO line during AAI programming                  */
    2 r( c; U/ j0 `4 d! s
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/" N6 @" D- o# C
  219. /* is completed                                                                                                                        */
    % H# G" \0 p9 S) ~. o
  220. /*                                                                                                                                                */
    8 F3 w+ r, z. r; A! L3 a
  221. /* Input:                                                                                                                                */
    . J+ [! N( r3 _0 `+ [. d9 Z
  222. /*                SO                                                                                                                                */
    " K0 Z4 B. K- Y, r9 [$ D1 }8 c7 W
  223. /*                                                                                                                                                */
    ' Q( }6 [' s! w5 O! C
  224. /* Output:                                                                                                                                */* B3 I& t# {+ x
  225. /*                None                                                                                                                        */% s0 D1 r0 e5 i2 ~! [9 l7 ]6 d
  226. /************************************************************************/1 F1 Y& q# k+ L, x0 y
  227. void Poll_SO()* Y6 N, b$ _( I# G* j
  228. {
    + J  A  {) O$ l
  229.         unsigned char temp = 0;
    5 {* p: E3 ]" V. X
  230.         CE_Low();9 n5 x6 ^* D& ~5 l' |
  231.     while (temp == 0x00)        /* waste time until not busy */
    ' s) r- o) \& t0 x
  232.                 temp = SO;/ o; @, i, G: p
  233.         CE_High();
      ], _3 G; i- d2 b# M, i# C
  234. }
    ( S7 c7 ]5 \6 p! u' W! [8 f

  235. & x9 V! V4 h: R1 o- l4 O) ^
  236. /************************************************************************/: [# [4 O" W" U6 B+ f0 Z
  237. /* PROCEDURE: CE_High                                                                                                        */. f+ _4 U2 {- @; A' i
  238. /*                                                                                                                                                */" \2 T) P7 o6 Q4 M9 _1 H
  239. /* This procedure set CE = High.                                                                                */7 K; e5 R, m( f" ~) U! H1 W: I
  240. /*                                                                                                                                                */
    $ l; l! ~" N7 A3 [- e, e9 N
  241. /* Input:                                                                                                                                */
    / [/ |7 ?! Q# g0 C7 d% g  |' p3 C8 [
  242. /*                None                                                                                                                        */
    " k" V5 l; n, K% S3 }% j
  243. /*                                                                                                                                                */* X' N6 j, j5 c
  244. /* Output:                                                                                                                                */+ U3 c+ t9 r9 v8 n2 U& S0 l
  245. /*                CE                                                                                                                                */; U: t; _$ V' M4 f8 g3 `
  246. /*                                                                                                                                                */
    & v, E, U3 v) m+ o7 c8 i
  247. /************************************************************************/
    * k. b5 B8 X+ `' m8 v
  248. void CE_High()
    + |4 l4 {/ I! k5 @8 [( U
  249. {
    4 f" @, T, j5 H# {# |. c. Z5 V
  250.         CE = 1;                                /* set CE high */
    4 v! [. d" _# r# a" ?# L# o
  251. }1 j7 w4 C5 }( b1 F" M, c& Y: ~1 B
  252. 2 ^# t/ F+ S' U; u
  253. /************************************************************************/4 F: D0 q+ a7 W+ @0 A! @
  254. /* PROCEDURE: CE_Low                                                                                                        */
      R: U5 d. T$ z+ X& l1 N
  255. /*                                                                                                                                                */7 p; E2 n* h0 ~. M- K9 R; J
  256. /* This procedure drives the CE of the device to low.                                          */) z+ E5 T8 W$ ]1 O% O6 J
  257. /*                                                                                                                                                */
    " {. O* ^; b! |( {1 {+ A. j
  258. /* Input:                                                                                                                                */6 a8 k" D% w% F+ O4 d( m
  259. /*                None                                                                                                                        */
    : r$ O- {9 _  l1 Y3 _  L
  260. /*                                                                                                                                                */
    ( _+ V& j7 F/ J. ~( ]
  261. /* Output:                                                                                                                                *// j6 |: k" h4 s; d. N
  262. /*                CE                                                                                                                                */  |5 c/ A; F; Y# U
  263. /*                                                                                                                                                */
    / a1 r, Q8 b) b: q$ D: Q* x, V8 d
  264. /************************************************************************/
    1 N9 f( @+ n' F- H: U. q+ P1 J
  265. void CE_Low()
    ! o: C9 B! m. R1 E, i& p
  266. {        # a( [5 V2 Y/ N0 c+ w; T) l* `
  267.         CE = 0;                                /* clear CE low */+ W: ]% f9 b$ C" C  S
  268. }
    , b( z! @2 x0 {$ y

  269. $ r" W1 I: n! w
  270. /************************************************************************/
    & i$ `$ a* ~/ N% Q
  271. /* PROCEDURE: Hold()                                                                                                        */, i- _* C: `$ A7 v, I6 X
  272. /*                                                                                                                                                */  c5 t% g8 G( n& j- b, P% _
  273. /* This procedure clears the Hold pin to low.                                                        */2 F, l3 y, R! c
  274. /*                                                                                                                                                */
    + T& R8 }: C; E' q$ G2 m, R
  275. /* Input:                                                                                                                                */
    % g+ X- t7 I# ^4 M7 E% Y
  276. /*                None                                                                                                                        */1 f+ E9 h1 d  s4 @6 R- f0 k% ?
  277. /*                                                                                                                                                */
    2 E. S# S0 y# C
  278. /* Output:                                                                                                                                */
    5 S$ M& w6 d+ O5 z3 s, H
  279. /*                Hold                                                                                                                        */
    ; ^7 r, W" K8 @
  280. /************************************************************************/4 C  U6 I( _! p4 f. a! f7 h4 m
  281. void Hold_Low()8 p( R5 f( o0 F
  282. {
    5 A' p4 b' E8 ~3 \
  283.         Hold = 0;                        /* clear Hold pin */3 I( b+ L0 M7 n7 Y
  284. }
    - E4 p# H7 I+ [* |) n9 x
  285. ( P' U4 x) ]  h
  286. /************************************************************************/4 P# B8 Q0 H6 P- I: F
  287. /* PROCEDURE: Unhold()                                                                                                        */
    # q& u4 f5 Y+ K, Q( Y; D# x
  288. /*                                                                                                                                                */4 f1 H) o( P* Q
  289. /* This procedure sets the Hold pin to high.                                                        */5 k+ J) O" c7 U. n
  290. /*                                                                                                                                                */
    % N7 L. x$ S  ?; X$ d
  291. /* Input:                                                                                                                                */8 {4 \  M6 T9 }  ]! J1 L
  292. /*                None                                                                                                                        */
    6 X5 K& [! h0 ?
  293. /*                                                                                                                                                */
      i7 ~2 m/ O) E7 F9 I3 Y( t
  294. /* Output:                                                                                                                                */, a( z3 r' n- D) S2 L  Q
  295. /*                Hold                                                                                                                        */  Y/ X% [; C& ^- {
  296. /************************************************************************/
    & k! k9 Y2 |% ^5 r
  297. void Unhold()4 Y! [: j& p* n: ?
  298. {) w: x4 _+ j  X8 x- G
  299.         Hold = 1;                        /* set Hold pin */, E$ H. b- M8 ?" [) \
  300. }
    4 g+ n9 a! h4 _) F* {
  301. * ?+ l3 q! |6 b4 y0 z" f5 ]$ ~  I; {
  302. /************************************************************************/& w! E2 y  q6 t3 m% e$ Z
  303. /* PROCEDURE: WP()                                                                                                                */
    + J/ P$ n6 X) D; R4 k. ~: ]4 X- ]
  304. /*                                                                                                                                                */
    ; j. f% k, v( K% B4 z
  305. /* This procedure clears the WP pin to low.                                                                */
    4 _3 ]5 b8 D1 g$ G8 n
  306. /*                                                                                                                                                */
    5 k2 q- j$ F% t' a+ }9 r+ R! r
  307. /* Input:                                                                                                                                */
    # c' p; }- [. M! z' \( a& _  _  N
  308. /*                None                                                                                                                        */' M  F7 h0 Z! g$ ~+ w1 [! l
  309. /*                                                                                                                                                */% }( F' z1 o7 ]2 _( S0 E
  310. /* Output:                                                                                                                                */0 i, E: W8 [5 n  P! Z  o& E
  311. /*                WP                                                                                                                                */: o# t4 L6 W6 U4 w6 `: K/ ]. k  c
  312. /************************************************************************/1 F' U  H% I4 \. @3 N
  313. void WP_Low()% Z* S( g. n' f: W) [* d
  314. {; |  M3 g& ~! b  G: r$ O
  315.         WP = 0;                                /* clear WP pin */
    . C7 w7 ~' A. i2 h0 ]  b
  316. }
    5 `! V: r* I1 _. {

  317. 3 g4 f* j. k' A: B6 K; t0 \/ `
  318. /************************************************************************/! [8 H, T- z# f
  319. /* PROCEDURE: UnWP()                                                                                                        */
    1 \$ G. i  {4 D2 Q2 {
  320. /*                                                                                                                                                */
    ; l' @  J' c* d9 _4 {% y5 i: I2 j
  321. /* This procedure sets the WP pin to high.                                                                */. L8 A) m9 i: b2 f
  322. /*                                                                                                                                                */
    . ~) L7 \0 X4 j; L6 w" ~0 Z7 y3 P
  323. /* Input:                                                                                                                                */4 @) F  r1 g! T# q8 N+ Z0 d
  324. /*                None                                                                                                                        */
    # [8 s; o7 s; g+ I
  325. /*                                                                                                                                                */
    % g3 w4 T+ d4 Z* [! P& b
  326. /* Output:                                                                                                                                */
    3 X6 R  j" v; q# ?$ T7 U, ~1 ]9 ?- y
  327. /*                WP                                                                                                                                */5 G3 n8 f5 g9 c) }9 Y) i
  328. /************************************************************************/
    1 I; `+ q( C" U& c  r# Q
  329. void UnWP()
      W7 o. D$ o9 L) p3 j* [) `2 J
  330. {9 n' E( b( g' t& N; _
  331.         WP = 1;                                /* set WP pin */1 H' S; m2 _' k9 q
  332. }
    2 w0 {% C; u& T/ t
  333. / m7 T5 J, a5 Q; @2 g5 t
  334. /************************************************************************/
    / Z6 w, @5 W' `/ S2 }/ f# m; h
  335. /* PROCEDURE: Read_Status_Register                                                                                */5 f5 Z. `( f$ {4 L% R* t
  336. /*                                                                                                                                                */
    5 c: |1 E  F$ M2 v+ B1 A2 f
  337. /* This procedure read the status register and returns the byte.                */
    & {  U0 w, O: _4 ^
  338. /*                                                                                                                                                */- P8 a8 L6 |# }+ n
  339. /* Input:                                                                                                                                */8 B$ p. Q7 {' d* ]- ~& O; V
  340. /*                None                                                                                                                        */5 U; j! r' C" j% N& C* L+ K5 m9 c
  341. /*                                                                                                                                                */" f/ |% z+ L/ L4 A) [
  342. /* Returns:                                                                                                                                */  p5 p  L- t$ L% A# g9 G" `/ r+ R
  343. /*                byte                                                                                                                        */# r; [0 h/ W& W
  344. /************************************************************************/0 Z* J, n4 _# q% J1 `6 ?1 c* L
  345. unsigned char Read_Status_Register()
    + i0 b- S7 R6 v. N
  346. {4 V, H  c& Q9 W3 i
  347.         unsigned char byte = 0;
    3 o5 l' K( N0 W' B
  348.         CE_Low();                                /* enable device */
    % d) A$ [% g% |" h  a: I) ]
  349.         Send_Byte(0x05);                /* send RDSR command */
    7 u4 l6 K; _1 b! G: f0 P
  350.         byte = Get_Byte();                /* receive byte */* }2 s; |4 ?3 J
  351.         CE_High();                                /* disable device */
    9 `! U; q; \( w. _- G! h& ]
  352.         return byte;2 r% F' e5 u  m2 w- T) I) c! e6 D
  353. }
    5 [" Q/ N! f# F  \9 H
  354. . t& i4 E- |0 _2 \
  355. /************************************************************************/
    4 ^8 g2 F9 K. \7 ]" Z! {, i
  356. /* PROCEDURE: EWSR                                                                                                                */
    ; V- Q4 h$ G: i9 n9 r
  357. /*                                                                                                                                                */
    ' ], d" d4 T3 A( ?5 h6 j
  358. /* This procedure Enables Write Status Register.                                                  */( p# e' j: L9 E9 n$ \" A
  359. /*                                                                                                                                                */
    0 d* g6 @& `- Q3 m3 @
  360. /* Input:                                                                                                                                */
    0 w0 ?# r0 ^7 H' ~% L: A
  361. /*                None                                                                                                                        */" Z! s; q5 i/ A
  362. /*                                                                                                                                                */! d1 a- S& J  g# |  d2 W7 U
  363. /* Returns:                                                                                                                                */' h/ q1 Q  N/ _9 k( L8 R* l
  364. /*                Nothing                                                                                                                        */
    2 [% [7 m2 F/ E6 r# X/ m
  365. /************************************************************************/0 a, _9 {* O2 c
  366. void EWSR()# X' I$ w: a& r; Z5 ]
  367. {
    ; n  ^9 _0 Z8 s. w2 d2 q
  368.         CE_Low();                                /* enable device */
    ( e: f8 @8 W3 u( B4 }. C7 y% m. ^  W* K
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    ) K. Z- A$ B- i. m  M2 l
  370.         CE_High();                                /* disable device */
    ) m+ N! U+ B7 N- u
  371. }
    : t* C! ~7 A/ O- s  y" S1 w
  372. ( |% f. [& }# [7 @8 d) S
  373. /************************************************************************/# ]& i5 p, M: m; z. S
  374. /* PROCEDURE: WRSR                                                                                                                */# f- ~5 u! j, ^) ?( q9 H6 w- A
  375. /*                                                                                                                                                */
    # D! H: ~# J  C+ v
  376. /* This procedure writes a byte to the Status Register.                                        */9 i0 W; H6 t4 h) C5 g+ P, R
  377. /*                                                                                                                                                */: D+ S4 t6 T3 X& V& l
  378. /* Input:                                                                                                                                */
    ! K5 o# u' X% z
  379. /*                byte                                                                                                                        */
    ; I) J, \, D4 C8 A
  380. /*                                                                                                                                                */% }% ?( T2 z3 n1 b3 H* z+ G
  381. /* Returns:                                                                                                                                */
    7 N# M; h4 A; D* l$ B! l
  382. /*                Nothing                                                                                                                        */! g0 I* i6 o; n1 _4 r& _
  383. /************************************************************************/, A6 S3 W) W- T6 E3 F$ D2 M& k
  384. void WRSR(byte)
    ' _: K3 j; ]$ K6 f  A% `1 M" G
  385. {
    % ^* q: ]! W7 b& ]! F: H- s
  386.         CE_Low();                                /* enable device */% N2 F' d! l' {6 |6 v7 ]& F
  387.         Send_Byte(0x01);                /* select write to status register */, Y2 @* T5 T8 B; K! ?8 Z! I
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    * \6 H. }2 v  {7 W! \) y
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    $ I7 e! Z" n. O8 K5 T6 k! Q$ [
  390.         CE_High();                                /* disable the device */
    $ d- H9 Q2 O" q4 l6 n3 p/ ]
  391. }
    3 X4 U- F  k- t& i( k8 ^; x

  392. & `+ B' r. y1 G  p
  393. /************************************************************************/
    " @* m' V  X! ~2 Q+ L3 f( l
  394. /* PROCEDURE: WREN                                                                                                                */
    : u) `6 Q, ~9 k9 j+ W
  395. /*                                                                                                                                                */
      `! B2 r* _) d' m% K
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */" C& F( x! E: `; b5 Y, I
  397. /* to Enables Write Status Register.                                                                        */
      t! \! F$ g  R) y4 }$ z
  398. /*                                                                                                                                                */
    2 B5 L4 a# A3 J/ ^3 v
  399. /* Input:                                                                                                                                */
    7 `+ C8 A$ ^* p+ _: T& V
  400. /*                None                                                                                                                        */
    7 S5 r( ~) B/ M% i
  401. /*                                                                                                                                                */
    % m# s9 r7 q6 B
  402. /* Returns:                                                                                                                                */. ]6 E; B6 J3 @5 \+ O* c9 m2 j
  403. /*                Nothing                                                                                                                        */  {  \  J+ V, g: g
  404. /************************************************************************/
    : M( `4 E" T6 f2 @$ m1 N
  405. void WREN()
    ) {, F" q9 }  n& a
  406. {
    ( R' D5 n7 R  |- @: z# r. e: O# M
  407.         CE_Low();                                /* enable device */9 t" Z  V- e( O8 w
  408.         Send_Byte(0x06);                /* send WREN command */( w( p' C8 D- V% g  {
  409.         CE_High();                                /* disable device */# A. j( Z' o' e. n. r+ N
  410. }6 {' b5 t* O/ y

  411. ( h# B; b7 S- J- w( ^' k4 _, L
  412. /************************************************************************/# n, S9 c, T/ V& p4 e0 h
  413. /* PROCEDURE: WRDI                                                                                                                */
    . ]; D( v/ t! r
  414. /*                                                                                                                                                */
    ; j5 D7 Q0 ~/ ~7 Z; G6 Y
  415. /* This procedure disables the Write Enable Latch.                                                */4 D7 ]4 Q" N$ \8 U1 x( ]5 o5 ]
  416. /*                                                                                                                                                */8 I" Q) J8 o8 y* h4 Y& P. M
  417. /* Input:                                                                                                                                */
    * }5 f" X7 O/ Y. F
  418. /*                None                                                                                                                        */
    # D0 N. O+ f4 [' d1 U1 W
  419. /*                                                                                                                                                */0 A) I& c" |& q" U. I( Q) p
  420. /* Returns:                                                                                                                                */) j# L! c* A) D! g
  421. /*                Nothing                                                                                                                        */0 Y" ^& c3 Q3 [! \/ \& q/ N* h
  422. /************************************************************************/
      u. g5 d* }6 y, e1 D0 ?0 [
  423. void WRDI()
    * Y$ d: Z& m: r: {; R9 _7 R# S# q# r% f
  424. {
    . n/ D& o/ m( J0 @
  425.         CE_Low();                                /* enable device */
    1 g/ @' g, k5 i
  426.         Send_Byte(0x04);                /* send WRDI command */
    ! H7 k* f# B7 q, O6 F$ c
  427.         CE_High();                                /* disable device */
    5 p+ R) }8 t; W# \
  428. }
    4 m2 l3 G' }1 D6 _8 o! T

  429. 3 S5 K1 A" H6 \( Q$ |3 ~% ?
  430. /************************************************************************/0 O& U! a) h3 S- j. D
  431. /* PROCEDURE: EBSY                                                                                                                */, |5 p& g( `) N! `+ }7 r
  432. /*                                                                                                                                                */% p+ A  U. T; }3 y8 A, v
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    1 R5 w7 r4 O# Q  V4 q5 c
  434. /* programming.                                                                                                                        */
    % R7 u* k$ U$ Y( ?6 P/ G. e# x
  435. /*                                                                                                                                                */
    & \( {0 N' K( F# r7 _
  436. /* Input:                                                                                                                                */
    1 ^4 T% u2 n; c" L( d) Q: ~
  437. /*                None                                                                                                                        */1 H2 M  |3 w3 r' p4 @1 B+ [
  438. /*                                                                                                                                                */
    6 j2 P$ ?5 f7 E3 _
  439. /* Returns:                                                                                                                                */
    0 |) u; D& t; z3 s
  440. /*                Nothing                                                                                                                        */: A% V& X& a6 a6 c
  441. /************************************************************************/8 M  r  ?, Z$ L: _' ]6 d6 m0 C
  442. void EBSY()/ x6 Y: X, Z- x5 Z* }! a
  443. {/ d6 Q8 y% Z+ z( v/ p+ s, p
  444.         CE_Low();                                /* enable device */
    : N9 H  j2 C+ I/ r
  445.         Send_Byte(0x70);                /* send EBSY command */7 R9 h. `) k" v! |: a2 S
  446.         CE_High();                                /* disable device */
    - P+ Z, x% C8 d# X3 l; j
  447. }9 Q. I' f0 H; z. `8 G3 Z$ _

  448. : a4 M9 m; ]. Q. S
  449. /************************************************************************/$ a5 }$ b. n. ]6 X# `/ C( `
  450. /* PROCEDURE: DBSY                                                                                                                */& o  n9 U1 r! e- x5 |4 A& N
  451. /*                                                                                                                                                */9 e) s- b: D: i3 `# d- T2 o
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */* ^. M. y9 y/ ]. ~2 ~! Z7 f8 t
  453. /* programming.                                                                                                                        */
    * \% F0 O) y9 w
  454. /*                                                                                                                                                */# \; v* z8 `8 V5 e( @) e
  455. /* Input:                                                                                                                                */0 _4 M. g2 M/ {: z- G4 o2 I
  456. /*                None                                                                                                                        */
    $ E! P  {0 w% F
  457. /*                                                                                                                                                */" q, W* x; @# E) P) t8 o. u
  458. /* Returns:                                                                                                                                */
    % K8 y* A8 ~' }2 [, N
  459. /*                Nothing                                                                                                                        */
    6 P) C; {9 C$ g- U! O+ u
  460. /************************************************************************/$ F" j  x6 K. c* M$ \2 A. z
  461. void DBSY(); R. e& m8 `6 Z( A; e, @
  462. {
    # o" p0 _5 I+ [" k" z' ?
  463.         CE_Low();                                /* enable device */
    & j, f. L5 w$ @, P! P
  464.         Send_Byte(0x80);                /* send DBSY command */$ w. m8 E" I6 f7 I( ~
  465.         CE_High();                                /* disable device */, O: ~$ y* `3 |9 a
  466. }4 F0 U. j: R+ t% m& i. G, ]

  467. 5 y7 k' @% ^9 h: T$ q4 L# p, x
  468. /************************************************************************/4 _  g0 S  Q0 z
  469. /* PROCEDURE: Read_ID                                                                                                        */( `8 D! R: c. A1 ]
  470. /*                                                                                                                                                */
    6 \: b/ O, M5 i3 u: g
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */9 L5 r; |/ Q& N; A. Y
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */! e- s1 |7 U( h9 H* \8 L
  473. /* It is up to the user to give the last byte ID_addr to determine      */" Z8 t2 _# W8 B& D
  474. /* whether the device outputs manufacturer's ID first, or device ID         */; @+ K6 c+ q1 d, F5 c
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    " A9 \8 u6 s! h0 M$ Z/ W
  476. /* variable byte.                                                                                                                */4 {7 Q" r9 w1 K; y5 v3 n
  477. /*                                                                                                                                                */, y/ `. ]9 T& J# l
  478. /* Input:                                                                                                                                */
    6 `) B4 Z5 F* y# U4 r* [* L
  479. /*                ID_addr                                                                                                                        */% q. L+ A% O4 Z- D) Q4 l
  480. /*                                                                                                                                                */
    + i7 |9 E1 x$ d1 M7 ], M
  481. /* Returns:                                                                                                                                */
    ' Y  ^5 b0 S% v6 l  e1 b4 {! i, ]
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    - b) `/ ?4 H- W% M$ `$ t
  483. /*                                                                                                                                                */- M" B  R* E' `) {( E+ |
  484. /************************************************************************/6 J, A* k' g" ^' r
  485. unsigned char Read_ID(ID_addr)1 }" K; `# J- _( q* p3 g
  486. {( P+ F" p  i2 n" J' h
  487.         unsigned char byte;8 W3 Z" O/ a3 K' Y* H( }
  488.         CE_Low();                                /* enable device */) O/ i5 x& g$ q2 @0 q( u0 ?
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */0 E9 f1 A' D! y; p
  490.     Send_Byte(0x00);                /* send address */$ X* C$ z) M8 V4 v# \1 T( v
  491.         Send_Byte(0x00);                /* send address */8 [; B3 b  }3 D! l7 ]* L+ L9 ~. @2 ]
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ! \: K! l% a3 h! k* L
  493.         byte = Get_Byte();                /* receive byte */* C) w8 \7 j6 S' P0 C! [7 {
  494.         CE_High();                                /* disable device *// ^. L+ k( e7 i! O! O1 U
  495.         return byte;
    % y1 ^: ]6 a; ?1 S$ {
  496. }1 J. p' p6 y1 j# T5 B* W
  497. 3 N9 J: j9 M7 x( z  {4 Z& O
  498. /************************************************************************/3 t5 R5 e6 p9 b; a
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */- i* Z" r' B& ^) b
  500. /*                                                                                                                                                */
    % v8 c" X$ a3 \+ h6 F
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */) ]$ x' j  S  l% @9 x9 [
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    9 d: U. Z# @1 t# j
  503. /* Please see the product datasheet for details.                                                  */
      z  d! [; d! P
  504. /*                                                                                                                                                */
    ) b% ?! M; t, W' t( V
  505. /* Input:                                                                                                                                */
    + z+ ^8 \7 j, y, b2 k
  506. /*                None                                                                                                                        */1 C; y; {; l& }+ L, Z: i  M9 E; O" q. p
  507. /*                                                                                                                                                */. g" _$ R5 P) g6 c
  508. /* Returns:                                                                                                                                */! O6 ?6 g, w% P
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    * V4 D1 c: e: q+ I3 Y" _
  510. /*                 and Device ID (8Eh)                                                                                        */7 F6 j4 j& P9 }) v; V) k$ K
  511. /*                                                                                                                                                */1 Y! a; h3 J- |1 \  H
  512. /************************************************************************/. K9 q9 _3 t. {8 y0 ^
  513. unsigned long Jedec_ID_Read() * h: e6 {' N9 p$ T, w
  514. {7 a3 Q) x, ^6 f' D
  515.         unsigned long temp;0 }$ j% S) e+ e# I9 g7 E0 P
  516.         5 b, m! }, ?* M; ]6 @7 ~# U
  517.         temp = 0;2 P+ J! L7 I- |3 H* B
  518. + i2 a# r. i2 Z& J5 o2 t
  519.         CE_Low();                                        /* enable device */
    ( F5 m  x2 q* G5 ^0 K9 m
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    8 D, ?5 C5 y1 J: s/ M9 X8 Y/ h# r
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */% F5 S# M% ~% F7 Y+ z
  522.         temp = (temp | Get_Byte()) << 8;        7 B" d6 w, {9 D
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    ! T6 A& _" A5 W: m; ^
  524.         CE_High();                                                        /* disable device */
    - @6 C8 U1 W9 h& ^# N5 Y1 \

  525. 0 p# q( n8 Y4 s" Q9 s; t
  526.         return temp;. k. Z# ]( ?3 C" r* T1 h# r
  527. }
    & h( D4 c- x  R- t: \  a) o
  528. , v3 X0 C# D/ m  w3 Q$ e
  529. /************************************************************************/
    - Y* x4 Z. ~: d2 h+ t/ y6 W
  530. /* PROCEDURE:        Read                                                                                                        */! D( ?; e/ [: P, n1 l& N
  531. /*                                                                                                                                                */                - T: h' G: r% P# }
  532. /* This procedure reads one address of the device.  It will return the         */
    ( T" a3 a5 U' {3 M8 s2 N( ^: @
  533. /* byte read in variable byte.                                                                                        */
    0 d. e" n& S2 L1 ?4 \
  534. /*                                                                                                                                                */
    , W. K5 N3 r) w" R& j$ A, d3 b
  535. /*                                                                                                                                                */
    4 |1 W& I9 l+ `9 U! s4 `. W
  536. /*                                                                                                                                                */" |! o, r0 j/ w% I3 Z  \& _, w" X
  537. /* Input:                                                                                                                                */
    5 B. d- J; R5 a  J- F3 M, ^; D
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    6 X; ~/ @. G1 q! z' [# B$ O
  539. /*                                                                                                                                      */, N) x* t; ?3 ?+ K* d, v
  540. /*                                                                                                                                                */
    ' O) A7 m/ |  P; H" w  y9 n
  541. /* Returns:                                                                                                                                */6 x2 B4 g0 Q) z: w& v
  542. /*                byte                                                                                                                        */4 H: E( X" `. z, j$ Z
  543. /*                                                                                                                                                */
    : l  Q6 {" B6 ^! G" T
  544. /************************************************************************/; y$ |; J' `5 A4 W. v
  545. unsigned char Read(unsigned long Dst) 9 ~" D9 W6 d0 ^3 {( o$ f
  546. {
    " P( F+ U& r$ E4 o7 `$ c  v
  547.         unsigned char byte = 0;       
    6 n& E% t( t6 W' K% K$ ~# T2 V
  548. . K" x3 G! U( f; S1 A
  549.         CE_Low();                                /* enable device */; V* N  G2 D! A' _1 P
  550.         Send_Byte(0x03);                 /* read command */8 m% ]+ P4 q6 Y1 p# Y% M
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */1 ]0 R4 [; y' u* G0 q+ I) t
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 R) T) l6 U+ U
  553.         Send_Byte(Dst & 0xFF);3 b- ]- S4 ^* x; M# V7 y+ F' w1 [
  554.         byte = Get_Byte();
    % C6 l) Q& C' u; b
  555.         CE_High();                                /* disable device */
    0 i  P7 J! |2 H4 r! B: H+ T( Z
  556.         return byte;                        /* return one byte read */  F1 S: W" i' ^* w
  557. }
    ) k7 K; _, M, b1 k" Q3 H, `* I
  558. + o( W7 Z2 p1 u- J: L8 ^) j" P, r
  559. /************************************************************************/
    ) o5 ]  q* J6 c7 H$ P6 |$ Y
  560. /* PROCEDURE:        Read_Cont                                                                                                */* h. {+ M, R. k5 W) [
  561. /*                                                                                                                                                */               
    6 f8 u" f2 }" O% \8 K! I
  562. /* This procedure reads multiple addresses of the device and stores                */) c3 I) p% j' e" i$ |3 Y9 w+ m  ~
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/  m" M7 t: v( l, G7 D8 v
  564. /*                                                                                                                                                */; k+ |1 b9 w2 |6 C4 d
  565. /* Input:                                                                                                                                */- I. l$ Z9 y4 j; `6 V
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    . Y. H" ~" ]! y$ ^  a
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */+ V$ J3 r- a2 r  ~6 j6 g' ~
  568. /*                                                                                                                                                */
    & Q* w, R1 J, B. v% `2 _) y5 n
  569. /* Returns:                                                                                                                                */
    ' A3 p7 u: ~% ~
  570. /*                Nothing                                                                                                                        */; g) |( ]9 i7 g& b' ]& R
  571. /*                                                                                                                                                */4 A7 z4 y6 ^+ }% _* D
  572. /************************************************************************/( h7 e4 A& y3 Y- B/ A& w/ V
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ( T& y$ z' w" f  S7 [* t+ e9 t
  574. {# }1 ?) R. v3 d8 w
  575.         unsigned long i = 0;+ A( A6 d% w- f- N3 d  i
  576.         CE_Low();                                        /* enable device */
    , g4 d$ ]1 _8 P% W1 P' o6 c
  577.         Send_Byte(0x03);                         /* read command */: a- i/ k) J" ^  d& \1 I
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */- r2 ~8 ~/ F! X& C) U
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 i5 G( Y- l. }7 K2 x, A
  580.         Send_Byte(Dst & 0xFF);- Z5 Q- d( {! K& s. G: n6 l5 T
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */. l1 M# Z1 X' K7 D# L4 d- G
  582.         {
    6 w4 Y1 @* Y+ b! g. }
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    3 |8 l1 T# f* G+ ^
  584.         }
    / J% P* |' Z* B9 v$ x
  585.         CE_High();                                        /* disable device */
    : N9 N, @$ c! V8 W$ d4 C

  586. 9 w/ J0 x% E0 ]7 l0 V4 g
  587. }& A* @) t0 L6 Q% j5 I
  588. 9 w$ F- g" V( y! X6 x' w/ F
  589. /************************************************************************/. N) p. g3 S% g# G1 [% E0 ]
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */. U: ?4 f, [" r0 h* }" d
  591. /*                                                                                                                                                */                : O- Y" t/ ~3 R" f5 ?# k" M* l- I* o
  592. /* This procedure reads one address of the device.  It will return the         */
    & a2 v( U' {1 Q& H7 c
  593. /* byte read in variable byte.                                                                                        */3 C9 u8 Z7 X# X) i
  594. /*                                                                                                                                                */
    + [. E$ V5 T& D/ A% a2 @
  595. /*                                                                                                                                                */
    ) s6 b+ C$ b5 Q6 y9 e  u% q
  596. /*                                                                                                                                                */
    8 k+ d. c. t( s, k+ n/ G6 k; Q
  597. /* Input:                                                                                                                                */
    ( O- Q# P5 _. k( Q8 u" @) ]) x) ~2 T
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    0 U( s) x2 X) i) V7 e0 m' _
  599. /*                                                                                                                                      */8 S) @1 ~  s& N9 @9 e
  600. /*                                                                                                                                                */7 S- k: F% f- g% D; ^2 O
  601. /* Returns:                                                                                                                                */
    $ J7 k0 M$ Q! g# }! U* ?
  602. /*                byte                                                                                                                        */
    % r5 s3 K+ z, k: i. o; M0 Z" g( M
  603. /*                                                                                                                                                */1 {, w) U. {. v. n) f* r, g
  604. /************************************************************************/, r, a5 |: d9 C2 x
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    3 y4 ?$ {. [& Z" J
  606. {4 d4 a3 {! l* G1 |: W1 B' D6 d% b
  607.         unsigned char byte = 0;        8 \" P5 Q! c$ ~! R9 }

  608. 3 p' J* g: G1 @2 G/ K: p
  609.         CE_Low();                                /* enable device *// t8 H8 i( \* j: A4 u* I
  610.         Send_Byte(0x0B);                 /* read command */
    / j9 Z1 l" t" |, u
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */' y; O% I+ r4 m2 @
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + J* x! _0 K1 n9 q2 `
  613.         Send_Byte(Dst & 0xFF);8 t( c9 g# d6 K  |- S, t- [& ?" R& `
  614.         Send_Byte(0xFF);                /*dummy byte*/" q. s& P4 w' V6 e3 A
  615.         byte = Get_Byte();3 T7 r' B7 q, [
  616.         CE_High();                                /* disable device */4 ~* g8 P+ A2 r& k4 ^2 q
  617.         return byte;                        /* return one byte read */
    # R, E. v$ F9 s9 i! z" }
  618. }0 Z* `8 k* ~. I- R; j( y6 R
  619. 3 v' L* \- V/ T) r& y0 k
  620. /************************************************************************/
    2 r+ M6 U, Q$ o, n/ S4 j- d
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */0 @  J! z$ Q9 G
  622. /*                                                                                                                                                */                ) Q" D% v. k" O! |  z) k
  623. /* This procedure reads multiple addresses of the device and stores                */% t0 t" J9 o+ V  z  |! L
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/( c3 O: p' R3 D. y+ H
  625. /*                                                                                                                                                */% x& ]$ h6 X( K1 y2 ~
  626. /* Input:                                                                                                                                */
    1 ]% o; ^, c# ]0 d
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& R3 Y# G- D5 `- C" o9 s4 U
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    3 c3 y/ l5 s' R' q  L
  629. /*                                                                                                                                                */! J! t  @$ W+ G8 [; V
  630. /* Returns:                                                                                                                                */
      O3 J# O3 B. C2 g3 p% m& Q
  631. /*                Nothing                                                                                                                        */
      x' K2 t$ i  @! u. a+ n& ~9 `
  632. /*                                                                                                                                                */
    & `; J% C3 E6 z& ?
  633. /************************************************************************/: x7 l& q/ q5 d3 K' m7 f
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)4 z! m0 R* Y7 i' R* h
  635. {' |$ i$ z" I3 P. }0 ~
  636.         unsigned long i = 0;3 o2 ]- ^3 x* h" w; L# t
  637.         CE_Low();                                        /* enable device */& D+ ~# F# C/ O# M0 z
  638.         Send_Byte(0x0B);                         /* read command */
    ( x3 k( S, W4 i% G# Z( b; l
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, Q; O  ~* b" _# y( ^. z
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * K7 K, v: Y- q, ^! q+ H- ?
  641.         Send_Byte(Dst & 0xFF);
    / P! |3 U$ G( q
  642.         Send_Byte(0xFF);                        /*dummy byte*/! s: C) b1 P' ^4 v8 n: x
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */+ H  i; ^, n* x
  644.         {
    2 ^* f$ O% Q) c7 N1 o3 T; X  K
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */0 M. V' ]0 `7 I$ E% f, t" Z
  646.         }1 \/ r& ~& U% `
  647.         CE_High();                                /* disable device */; P! j& {  {4 w5 n7 o: u* T
  648. }% l4 R6 Z' v* X& `

  649. & Y! o2 V3 q  j# s( C( q% X" q
  650. /************************************************************************/
    + v3 _. j; U" X9 ]/ R" _
  651. /* PROCEDURE:        Byte_Program                                                                                        */  S+ `. v; l) |. t1 U! h" j0 l. D
  652. /*                                                                                                                                                */) A) Y8 ~% D8 d
  653. /* This procedure programs one address of the device.                                        */
    5 d/ E& F- O, N
  654. /* Assumption:  Address being programmed is already erased and is NOT        */7 N& T: c+ }  h! R3 V
  655. /* block protected.                                                                                                                */
    % n, v& b" j& c! D! v2 ~. i
  656. /*                                                                                                                                                */
    ) C0 k5 D7 f: l
  657. /*                                                                                                                                                */' q$ A6 V% v/ t* B  x: b8 R
  658. /*                                                                                                                                                */1 l. n! I4 e8 P0 E7 ~
  659. /* Input:                                                                                                                                */" }3 `# A6 g2 ^% q) T$ A" Z& f2 O
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    3 @8 f3 I# f2 [) I
  661. /*                byte:                byte to be programmed                                                                */
    % E+ @! E  c- `
  662. /*                                                                                                                                      */( W6 o. i; \% Q; _6 ]& ~. l
  663. /*                                                                                                                                                */
    * k. _/ T! t) h4 e1 p$ d
  664. /* Returns:                                                                                                                                */
    + \/ s. R" f+ z  L+ i
  665. /*                Nothing                                                                                                                        */0 g; a' D: R8 i" m2 i0 W7 K8 r) _
  666. /*                                                                                                                                                */; ]6 Q/ \0 B+ S! I5 K
  667. /************************************************************************/9 d* @# N  V+ d0 I7 A6 B3 U
  668. void Byte_Program(unsigned long Dst, unsigned char byte)$ y4 C9 q# x* ^4 o* H6 W
  669. {
    0 a7 o; y( r# A2 C/ f/ H0 w
  670.         CE_Low();                                        /* enable device */5 d* l9 y2 D3 n9 j
  671.         Send_Byte(0x02);                         /* send Byte Program command */% y5 W; u- l/ h3 y+ j- {- X/ s
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    7 P/ {2 K! \1 `* A) ~
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));) \, E* u/ H8 d% e: u
  674.         Send_Byte(Dst & 0xFF);
    1 D- x8 ~# m! e3 T! o/ R  R5 g
  675.         Send_Byte(byte);                        /* send byte to be programmed */$ t' i) p- o  {  I# \) k: d
  676.         CE_High();                                        /* disable device */9 |- F* J+ w: R+ C
  677. }
    5 ?- `9 Z; C( N4 f8 a* L7 m

  678. 3 G* n! e& w7 X1 |" b& p3 _5 l
  679. /************************************************************************/
    ) V* f2 O. l0 ?
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    $ U* ]- M0 R+ D# N( E# @2 {. q! V
  681. /*                                                                                                                                                */
      c7 R% P% G7 T. k8 L! W
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    5 n" Y" x5 H' s" I+ T( {
  683. /* the device:  1st data byte will be programmed into the initial                 *// b# ~: A  z0 p% R' X6 ?) Z2 e
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */9 B; y* v: ^4 J, A, T, ^
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    & L2 a2 F  i  p7 x+ v3 o: p6 [
  686. /* is used to to start the AAI process.  It should be followed by                 */; c7 p' R7 s. B1 }  U  W# ]
  687. /* Auto_Add_IncB.                                                                                                                */
    & X/ F+ W9 w4 T: i9 Q
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 x  V. ]7 _) x# ?7 u* x- B* Q
  689. /*                                block protected.                                                                                */
    : i1 j& [, u3 o: P7 d8 r+ L
  690. /*                                                                                                                                                */
    5 {; P4 C. K1 [- e* u
  691. /*                                                                                                                                                */4 [: n) Y2 O% B! n, K, O
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */* ~  _* N& e* B* s* {! ]6 S5 m
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */, m7 a' D5 @% R
  694. /*         unless AAI is programming the last address or last address of                */
    8 ]+ ^! W6 Z: J. g7 ]
  695. /*          unprotected block, which automatically exits AAI mode.                                */1 f' m1 _7 J$ S$ w) P/ e7 \
  696. /*                                                                                                                                                */, X7 H4 {* r# N! }6 d
  697. /* Input:                                                                                                                                */
    , @* X1 D$ R0 L. }0 @0 e0 h
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % g4 d6 z( t* c$ k8 @1 y. P& x. c
  699. /*                byte1:                1st byte to be programmed                                                        */( c6 e" ~- L; r8 ?  E' r, M* }
  700. /*      byte1:                2nd byte to be programmed                                                        */3 G2 [) m" u( l
  701. /*                                                                                                                                                */! e1 @& P$ t* y( F9 s; x
  702. /* Returns:                                                                                                                                */( s, c1 h. |/ M1 w
  703. /*                Nothing                                                                                                                        */
    " A' R- s: ~- M" A5 b
  704. /*                                                                                                                                                */
    + W1 h; C! D; x
  705. /************************************************************************/5 F& l' q9 T  e8 I0 p4 E  d) p  W" ^
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! [' _; t! I4 h; c& g3 O3 Y& Q
  707. {* }$ F* z7 o( E8 N$ k
  708.         CE_Low();                                        /* enable device */
    6 Y* m8 U- n. q. \3 m; a
  709.         Send_Byte(0xAD);                        /* send AAI command */
    3 a1 n5 q7 f8 F/ S
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */- k% ]( n7 }; U8 z/ D$ Y2 g1 R5 g
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));' X/ K& C4 M) B2 P0 i( w+ E
  712.         Send_Byte(Dst & 0xFF);) T& U" S$ E: P7 _. L. |! G
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ) H2 u- n5 z- ~- s/ s
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
      p# ?7 H0 e: _' g6 n
  715.         CE_High();                                        /* disable device */  U3 x3 [) W; P- T/ x
  716. }
    " a& ^" `, b: X6 ^. ?

  717. % d& v) d) t# s, y7 f
  718. /************************************************************************/4 E: Q8 G+ e& I5 n; X/ |4 ?
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
      A, H- Z# t1 k9 ~& E
  720. /*                                                                                                                                                */7 a0 s0 E$ y$ }; a, f9 d
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/# g  Q( X# _& p% g5 [
  722. /* the device:  1st data byte will be programmed into the initial                 */1 i* K; n5 ~8 P
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    1 ~" X( d1 x0 C, i( w
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    0 V0 z  t8 T: Y7 C8 L
  725. /* is used after Auto_Address_IncA.                                                                                */
    - B( J' R. D- o2 K1 g
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    2 g' b2 @$ ^0 v! y% _
  727. /*                                block protected.                                                                                */! D' A) _$ r- [
  728. /*                                                                                                                                                */% ^" h: b+ t  N( ?  C4 q9 O+ X0 S( i
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */" [8 n0 p( D  b0 a0 o& F
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */) U- {) f" k- x# h
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ b, Q) e! f( d  [  |2 @0 e6 W
  732. /*          to exit AAI mode unless AAI is programming the last address or                */0 M9 J5 U& j- E+ L* M7 k
  733. /*         last address of unprotected block, which automatically exits                 */! z! d* L% e; R* z6 T
  734. /*         AAI mode.                                                                                                                        */
    : B/ Q0 X1 ~8 j; z: N6 K% S, u. A+ b
  735. /*                                                                                                                                                */
    7 X1 F9 _. [# d/ O" p7 [# V
  736. /* Input:                                                                                                                                */
    . F- S$ `# y' L
  737. /*                                                                                                                                                */$ ~, a9 I- I% }2 T. e) Z# Q! u
  738. /*                byte1:                1st byte to be programmed                                                        */
    " ^5 n+ ~! h8 o
  739. /*                byte2:                2nd byte to be programmed                                                        */
      }4 ~. b! k/ \! y+ Y$ o/ z
  740. /*                                                                                                                                      */
    3 N: `& \# x) x
  741. /*                                                                                                                                                */% G! n, o6 Y+ g; s
  742. /* Returns:                                                                                                                                */
    * _# c' b6 P& m) a/ h
  743. /*                Nothing                                                                                                                        */% z1 @1 `0 M# e2 z2 v- R
  744. /*                                                                                                                                                */# t# Q9 j" Y! l3 b$ a# c
  745. /************************************************************************/
    ( x* g, S' h. d7 a* d
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)+ b* Z' }9 J) y, e
  747. {
    / m5 V# q; ^: F" b8 V, P
  748.         CE_Low();                                        /* enable device */
    . |0 w" G) z; b* W' t% ^& r& J5 b
  749.         Send_Byte(0xAD);                        /* send AAI command */
    9 u" |* _# p9 S2 R; l( F
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ; l/ G, E9 l3 h5 |
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    & S% [0 z- p( [7 s, g6 u
  752.         CE_High();                                        /* disable device */
    - M  e1 H6 ~1 `- C6 D/ \" c
  753. }
    " t2 {0 l+ q  n8 y
  754. . f. L( h" d# p; R1 g
  755. /************************************************************************/
      P4 P) q7 D, U/ @
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
      `- X: s0 d, t: W9 X
  757. /*                                                                                                                                                */  y" d) [& z2 k! @  u$ W) U% O
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */3 a' s* J5 F. x# `
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */1 q5 T8 Y$ L8 m1 V: \$ [. Y% f
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */! r" x5 V$ x% A- F' L6 [
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */' Q7 O8 r& g/ r, L' W6 N
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    9 q$ R4 W. W# I( l. e+ ?: ~! q
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */6 i) H! x1 h" Y: v! O2 S( }( m
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; x, ]' P+ m, K" _& D' g
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 k# N! z. D0 {( J, P9 C
  766. /*                                block protected.                                                                                */, Q) M! M' C  J1 F  z
  767. /*                                                                                                                                                */
    + L. U3 r% I8 B
  768. /*                                                                                                                                                */+ w3 Z) h( w- R' |2 z
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */$ P0 x3 Y3 c$ G# r* M
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */& l- {, l( L* h( ^$ A( o
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    9 _) w2 |$ p) Z9 B% O! N1 [4 k7 U
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    $ J- k* R! k- A4 a/ G) P" `
  773. /*         last address of unprotected block, which automatically exits                 */
    + Z6 \/ w; o+ k# Y
  774. /*         AAI mode.                                                                                                                        */# t3 h+ {3 J' q4 E6 z- `" v) E( H
  775. /*                                                                                                                                                */
    4 v9 n2 G9 `) T
  776. /* Input:                                                                                                                                */4 q1 B0 Q% n( C# I8 B" n. f; Y0 ^
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 j# |+ D6 t0 l. M# ^* K! l
  778. /*                byte1:                1st byte to be programmed                                                        */8 ?- A4 B) J* V
  779. /*      byte1:                2nd byte to be programmed                                                        */; U0 @' V9 y8 b& ^
  780. /*                                                                                                                                                */( |- K: p: o" W# h
  781. /* Returns:                                                                                                                                */1 R. c; Y; q2 P" i
  782. /*                Nothing                                                                                                                        */
    / _" ?, }- g$ G, Q0 s- O, R* V5 n! ~% P
  783. /*                                                                                                                                                */9 w' p& R' D! U' a9 F
  784. /************************************************************************/
    ' @/ y+ c* a9 U2 O
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)- B5 C6 |+ O8 ?% X8 c9 t) T  N4 z7 m) Y
  786. {
    4 m' B: }6 U5 I; h' h
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ! x1 f2 `. {; k" W) t! b
  788. ; T* R  ^+ ]" L1 v! Z2 z3 k
  789.         CE_Low();                                        /* enable device */8 G4 k# I* [( r" b; w
  790.         Send_Byte(0xAD);                        /* send AAI command */+ C0 l; q, }2 c& b
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */" q; r$ o! U9 b8 w( `. e
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));! d- p: C( W* \" j) Q; l6 T
  793.         Send_Byte(Dst & 0xFF);
    . v5 I) ~0 w3 ]0 M/ C& Z4 [2 L
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    # U$ a' S  b+ W* f$ ?# \  \- \
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */% J6 B% W7 ?. Y6 Z( o) a0 u( T3 D1 ?
  796.         CE_High();                                        /* disable device */3 \- @; m/ _: E# f  R  c1 s* M
  797.        
    2 |! w0 V, @9 j1 y2 a
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    2 |+ J- Y# B2 r

  799. 0 y% ?. C8 F# k: a8 U) q
  800. }$ Z% P$ [- {: E: ^% q

  801. , X' v& C8 Y; {
  802. /************************************************************************/
    5 l- V6 s1 S7 X3 I( _
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */' D' `* p( O# G3 S8 ]# L9 b# `
  804. /*                                                                                                                                                */( Z+ e. i; l) }+ f
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */, _. x4 r4 }& I$ m" ]
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    $ F5 h  j7 Z, `
  807. /* AAI programmming is completed.  It programs consecutive addresses of */: d% i+ Q! l! M7 i) A- v
  808. /* the device.  The 1st data byte will be programmed into the initial   */1 D: [/ j* B9 T8 n  _
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */+ H( j5 ]8 X, H+ _6 N+ {+ [
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */2 x7 K% V3 d! _$ ~% T' U( Z
  811. /* used after Auto_Address_IncA.                                                                                */
    " O2 `# `, M1 F8 E' I7 M
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 \- f0 p$ `: p3 b7 t
  813. /*                                block protected.                                                                                */; J: ]3 C& \- E+ @, x
  814. /*                                                                                                                                                */
    ( f! m$ T5 W. e/ S/ u; a' ?
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    7 P2 k6 l' D, z) c( b
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */! s- _: S0 H" L, S0 p0 B  b- v" T1 y$ X
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    " D5 F' L- @; e$ }9 [. w, R/ q' w
  818. /*          to exit AAI mode unless AAI is programming the last address or                */) v" u% g( W" u3 y, T2 u5 p
  819. /*         last address of unprotected block, which automatically exits                 */
    ( Q4 d; M; k4 [3 E. O/ F! D
  820. /*         AAI mode.                                                                                                                        */
    4 G+ j8 m. v4 r/ o% P% u
  821. /*                                                                                                                                                */% d+ I2 \2 W+ W. `, Z1 x4 i+ d( i) q
  822. /* Input:                                                                                                                                */
    2 a$ t) I! [: _& e, f
  823. /*                                                                                                                                                */
    ( E4 x9 s8 e0 {$ ^5 ~% \
  824. /*                byte1:                1st byte to be programmed                                                        */
    ) p7 u; s" t1 Z( t0 v7 |
  825. /*                byte2:                2nd byte to be programmed                                                        */9 K$ x2 V3 s8 z
  826. /*                                                                                                                                      */+ R) M6 A  y* u0 ]4 h' s2 G
  827. /*                                                                                                                                                */; r0 J+ L2 U% S& Q8 r
  828. /* Returns:                                                                                                                                */
    + o  Q( j- Z  n( {8 t
  829. /*                Nothing                                                                                                                        */
    & A: I+ X6 _! L; X# }
  830. /*                                                                                                                                                */9 x( n. d+ h# x. W( P1 b0 ?9 U& E& o
  831. /************************************************************************/, d+ M. {* U, _" o3 E
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ) i$ \8 \1 O2 E0 y
  833. {
    . Y$ q# p; ]& l
  834.         CE_Low();                                /* enable device */
    2 B4 S. U! T0 k
  835.         Send_Byte(0xAD);                /* send AAI command */
    5 J8 Q6 ?) b( |# V
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ' g! o& u* N* ^8 ], Y+ }# z
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */% ^4 b# Y- A7 n& C5 s
  838.         CE_High();                                /* disable device */$ V5 b0 m6 O. @

  839. ) t' l/ K- T4 m. l
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    , s/ V% L- v0 x  |$ f+ S1 }" @
  841. % r  L3 h; a- e! g! |8 C) j: o4 O
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    ! `8 U: i% g5 Q( t1 M% f, R
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */' L6 X! L  M- V& X6 {
  844. }
    ; c/ s  Y+ B6 x+ q

  845. 4 j3 Y" s) B6 B4 {4 P! \( q3 f/ A
  846. /************************************************************************/0 z9 D8 t: W+ A" Y3 o
  847. /* PROCEDURE: Chip_Erase                                                                                                */, }, I( H& B0 X9 w
  848. /*                                                                                                                                                */2 e- Z! B8 @+ v
  849. /* This procedure erases the entire Chip.                                                                */5 c1 y/ d0 |. [! r  R" i
  850. /*                                                                                                                                                */
    # E, `4 X7 I" P' `) R- W
  851. /* Input:                                                                                                                                */9 G! |  J/ u0 j4 x
  852. /*                None                                                                                                                        */( Q+ B6 [. S3 D2 ^0 Q8 c
  853. /*                                                                                                                                                */
    $ x; c. N- N: U
  854. /* Returns:                                                                                                                                */
    2 w* x- @9 R3 c* ^8 L* `" L
  855. /*                Nothing                                                                                                                        */* ]9 T) L0 N: C9 P
  856. /************************************************************************/
    : W0 ]# p$ W! l4 Z9 E+ M  v3 N
  857. void Chip_Erase()5 L; e; M" ~* r8 a- H% Q& _
  858. {                                               
    5 {0 T5 z9 @. I7 Y* B  v
  859.         CE_Low();                                /* enable device */' X5 O3 z: D, v
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */9 a4 S& @) T( z! l* x3 B$ O5 w- Y5 ?. E
  861.         CE_High();                                /* disable device */
    2 N4 e6 _! r  N8 j; f* T- U
  862. }
    3 m/ `9 i- V% r/ X8 K) s) g
  863. ' J# [* ]" \) }( _$ W3 h" D( m
  864. /************************************************************************// T  i. `9 |- S7 \# {& T
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ; `% ]7 R3 J% V& o
  866. /*                                                                                                                                                */. ~) M, c0 |( E
  867. /* This procedure Sector Erases the Chip.                                                                */
    " ^. O, _/ s  q6 h, C
  868. /*                                                                                                                                                */3 ^9 S' N) C4 \7 v- A7 f0 F( b
  869. /* Input:                                                                                                                                */. ~) @0 x2 v, |" K0 r# G4 D( S
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 U/ T5 \! I# o$ v; k3 J$ z7 V
  871. /*                                                                                                                                                */; J) t! ^4 g% h; N% y
  872. /* Returns:                                                                                                                                */8 Y1 R! M) s! l+ I
  873. /*                Nothing                                                                                                                        */! I9 b+ J4 K8 V8 U. A; N1 L
  874. /************************************************************************/5 U0 ~& O& S5 ]) ?5 R6 Q' i
  875. void Sector_Erase(unsigned long Dst)
    9 W. c- L7 R% S! ]
  876. {
    # I4 |9 d. p9 ~, r9 p. L7 K2 q- q% [8 L

  877. " N7 D7 w2 X5 c6 @$ X
  878. 3 u  n; t! }- ^) S& Z4 u7 E" B
  879.         CE_Low();                                        /* enable device */
    2 v  j, s# l8 B8 i0 `
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    9 d! y0 a# o# g' _! j# t1 ~
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ G4 d; ^$ e9 z  g; ?" |
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));8 o0 x4 I( d8 d6 ~. u! ~
  883.         Send_Byte(Dst & 0xFF);
    . H; v* x5 r% F  T
  884.         CE_High();                                        /* disable device */% q* _6 i) t; _3 _+ c9 c
  885. }       
    3 {* M& l0 o! D! S0 K
  886. ! F. o$ {& R) K6 ?# E
  887. /************************************************************************/+ ]) W8 M$ \( i5 x* E; T, f. L
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    / P5 {' p2 T. j6 M7 K8 Y  Y
  889. /*                                                                                                                                                */4 l: g: @* ?0 t! K  N% f+ d
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    ( Z4 L7 m+ J# l2 o1 q. _) g
  891. /*                                                                                                                                                */
    3 b2 r2 K* k) u; z, |8 o
  892. /* Input:                                                                                                                                */% Q9 h6 _7 z$ a6 c
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// A; {5 o+ [1 a6 \$ f7 l0 S, p
  894. /*                                                                                                                                                */
    5 c+ Z$ h1 J4 d$ `+ D
  895. /* Returns:                                                                                                                                */+ O8 z( K4 \& |$ H8 ]: R
  896. /*                Nothing                                                                                                                        */
    % ?4 U: }4 C9 g* h0 D* s0 W0 Q
  897. /************************************************************************/5 O, U, w1 ]. \
  898. void Block_Erase_32K(unsigned long Dst)  Z* S" x% w( c9 E
  899. {! z" y( Y9 F! V- i: E8 N  l/ R
  900.         CE_Low();                                        /* enable device */4 h7 b& }; f$ T% w9 b# J4 u
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ) {9 u( j+ U, F* Y
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! x5 X, f; J% E! x; O" x2 {. x. S$ w
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));& X( {" k1 M/ @% Q
  904.         Send_Byte(Dst & 0xFF);7 p0 E0 |, c  A$ V8 x+ i4 A! ?
  905.         CE_High();                                        /* disable device */& a% {1 G  p- o  j! [
  906. }& v6 w8 w! n2 @8 Q3 [6 f( |

  907. ( k+ Z8 A0 o0 J3 }: W# e
  908. /************************************************************************/; _5 c$ {+ X0 s6 K/ p6 |
  909. /* PROCEDURE: Block_Erase_64K                                                                                        *// F0 K. w3 j5 C
  910. /*                                                                                                                                                */
    ; p$ f" ]- s7 e. B+ p
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    9 T4 Z7 J3 \. x1 }0 Y5 ^0 `, D3 @: v3 S
  912. /*                                                                                                                                                */
    1 ]# b5 T- v5 c" a
  913. /* Input:                                                                                                                                */
    ' R7 I, o. y! t% Q3 H! d$ F7 N
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* e2 S2 h4 c9 A7 t
  915. /*                                                                                                                                                */
    1 D% m) Y9 I! U( j2 B* O# x
  916. /* Returns:                                                                                                                                */+ g/ M  U) s) b! [/ E
  917. /*                Nothing                                                                                                                        */- @5 b* [  o: }8 b) t
  918. /************************************************************************/
    1 A  J8 q* P& {5 Q4 |- u) I
  919. void Block_Erase_64K(unsigned long Dst)
    & ]) l: o6 n9 r% u' R5 f
  920. {/ u6 M9 }6 `' |" h$ u; S
  921.         CE_Low();                                        /* enable device */
    " N9 f3 x+ j2 s1 N
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */! g3 l7 W0 |' ?" Z
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 p( y8 P5 i" _
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 N; [( Q- |& z3 P
  925.         Send_Byte(Dst & 0xFF);
    8 P4 A) T3 E+ P5 |% p
  926.         CE_High();                                        /* disable device */6 F# T  Y. \3 V" Q0 f  _
  927. }1 [3 i- L- N) h
  928. " I& [8 H! E& Q: b% H+ S
  929. /************************************************************************/
    2 k0 t( a7 l, @9 S; L6 {+ ?
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    : a2 K6 Z' F1 D! g' J0 f3 k# d
  931. /*                                                                                                                                                */
    / X6 ]# \! s. c: K. O, p2 ]6 l
  932. /* This procedure waits until device is no longer busy (can be used by        */
    - E8 P2 C+ b& O  i! c9 l/ j4 [# r
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    7 j+ `- p! _' r) x4 \5 B
  934. /*                                                                                                                                                */
    ) _, W6 A" V. s8 C6 @( X
  935. /* Input:                                                                                                                                */
    ( p& C$ w: h2 f( W* H; ~' f
  936. /*                None                                                                                                                        */
    / s- d2 I1 d2 z1 l$ a/ c
  937. /*                                                                                                                                                */
    * s+ g, u4 L4 w  \/ v
  938. /* Returns:                                                                                                                                */
    : G; _; x- X/ E& v
  939. /*                Nothing                                                                                                                        */
    ! c7 U% f' t& Y2 w* M( H
  940. /************************************************************************/
      x4 R: u4 S; n) n/ Z. x! ^
  941. void Wait_Busy()
    5 o" _6 C6 `1 j/ R& W0 K: |/ T4 G
  942. {$ ?" W: s$ e5 G- k* Y! F' f
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */1 t+ G8 v* R+ H8 X* f
  944.                 Read_Status_Register();8 t4 [+ @; v0 T% H5 Z; v& }" F, Y
  945. }
    5 T! G. L1 \& Y2 _

  946. / a0 O/ ?! z' M& Y5 d
  947. /************************************************************************/
    6 k0 F# A. o/ j) ~3 T6 ?& S
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    0 _- q8 s+ f/ }; w
  949. /*                                                                                                                                                */
    ; I. Z# X9 Z, D; s
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    9 k3 a; t+ c* l. K  }  l
  951. /*                                                                                                                                                */
    / z9 d- Y2 \1 v' z
  952. /* Input:                                                                                                                                */
    ! U! U; ^- R( l6 x/ o/ |
  953. /*                None                                                                                                                        */
    3 v  e  _& c5 S+ [4 x
  954. /*                                                                                                                                                */
    : H8 C: h  s3 L
  955. /* Returns:                                                                                                                                */
    % V6 b, n  w/ H4 N
  956. /*                Nothing                                                                                                                        */& \, d+ b5 {* D7 D' e
  957. /************************************************************************/* B) [9 s8 U( @* c7 `  j* j, [5 e
  958. void Wait_Busy_AAI()% _( `$ S0 W' q8 V; }
  959. {
    $ y% l! V7 }: L9 G9 B  k
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    ( F) n( Q, N' t" }
  961.                 Read_Status_Register();
    # l/ a( W# M% H2 f+ p
  962. }
    . T7 V+ r: n# G! F+ P% m
  963. 8 S7 f8 x2 t4 D0 E& K
  964. /************************************************************************/+ n- _6 r* R" N8 P2 p1 ]) m
  965. /* PROCEDURE: WREN_Check                                                                                                */8 L) F* ?* Y5 b
  966. /*                                                                                                                                                */
    5 g% F& W# G6 D: }$ R/ v  \
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
      Y8 m  @' e) O  e! p4 O
  968. /*                                                                                                                                                */
    + m/ S% ?0 b' n5 l
  969. /* Input:                                                                                                                                */
    6 y7 T/ l$ ~, Q- V4 i
  970. /*                None                                                                                                                        */0 e. B5 x1 W: A0 H
  971. /*                                                                                                                                                */0 V+ r# U, Y9 K" @4 O) f
  972. /* Returns:                                                                                                                                */
      H$ w# K- o; t  v) U  u
  973. /*                Nothing                                                                                                                        */
    5 _% @" R: z9 H5 e0 \9 ?* [
  974. /************************************************************************/3 W* k, K8 |  v
  975. void WREN_Check()
    3 z. O5 I1 P% R/ P% v' |3 G" {0 y
  976. {
    & a; P9 Y4 F5 Y- ]" ]( \3 B$ w
  977.         unsigned char byte;3 V- [5 p4 {3 f* R
  978.         byte = Read_Status_Register();        /* read the status register */* r2 y  c' U( s& {* T2 N
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    4 k' ]( i6 [% G' O6 }' K' P! C
  980.         {
    & A+ D  R$ H5 W, t0 G3 N! _
  981.                 while(1)3 F7 w, o8 ?" Z! Z0 F+ E
  982.                         /* add source code or statements for this file */$ u0 r- S2 b1 w3 l* A" ?
  983.                         /* to compile                                  */
    5 M  G/ i) i- E
  984.                         /* i.e. option: insert a display to view error on LED? */
    2 \/ U; _$ p$ s8 l
  985.                  1 t0 Z! h& e# p8 T8 y5 }7 v# R( f
  986.         }
    7 d8 ~8 _* U- C7 @8 K2 F2 P( N
  987. }
    , \8 j% d) H, G+ X+ [
  988. + n) b/ c: t& S; J) N, u
  989. /************************************************************************/. ]2 K: ^( Z9 \& B
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */3 W; ?0 {$ p0 ^5 j, F$ ?
  991. /*                                                                                                                                                */
    . O" R# \3 U: K4 R3 v& y$ Q
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */2 M1 x$ ^- `  r/ w1 l, n: a
  993. /*                                                                                                                                                */
    ! s& U. w/ ^% _/ P2 R' f( G! M
  994. /* Input:                                                                                                                                */
    ! g! X6 Y$ U9 y6 \# [
  995. /*                None                                                                                                                        */
    / D. Y: v  p7 q2 ?5 _
  996. /*                                                                                                                                                */( w0 s- M7 e7 q7 x0 i9 U# @
  997. /* Returns:                                                                                                                                */
    ( e1 u! c! w% \" W3 B  m0 _
  998. /*                Nothing                                                                                                                        */: g1 M& |) n$ T1 z' u8 B
  999. /************************************************************************/
    3 n) z' w& Z) }$ [7 a! P/ u
  1000. void WREN_AAI_Check()9 `8 V0 @2 N- j" b' P
  1001. {
    & \  I& i- j5 Z) t, j  O( ]: x
  1002.         unsigned char byte;
    3 @' X" O; V& ^3 S) {
  1003.         byte = Read_Status_Register();        /* read the status register */
    . @) r3 N9 C6 n/ E% z
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */8 p$ I1 K/ S! G& x+ p# \# h
  1005.         {
    ( ~3 L% C$ K- q3 g
  1006.                 while(1)               
    2 I  a7 t% s4 w
  1007.                         /* add source code or statements for this file */" o# o- Y9 q6 c% m3 i7 k3 |
  1008.                         /* to compile                                  */
    ( F, y& P: P9 v: ^+ j) e
  1009.                         /* i.e. option: insert a display to view error on LED? */
    , @1 ~: r3 u0 f7 y6 H+ x8 W
  1010. 5 c* Q) ^7 z$ K
  1011.         }# O$ K4 X; {; o3 ^
  1012. }
    ) I$ m7 _6 \' k5 q" T/ Q5 Q7 F

  1013. , g& {! u' ^* U! }( w+ n
  1014. /************************************************************************/
    2 v% }5 Z, s, r. b$ d( P8 D8 x
  1015. /* PROCEDURE: Verify                                                                                                        */* {6 Y) ^% C+ s  O# p) x" e
  1016. /*                                                                                                                                                */
    + u1 s8 |* `5 Q9 l" K
  1017. /* This procedure checks to see if the correct byte has be read.                */$ b; L7 z" ^. b* c
  1018. /*                                                                                                                                                */
    0 S3 h$ Z6 ^6 V
  1019. /* Input:                                                                                                                                */- Q: W% L- m! V' |3 @8 a; r" ?# r
  1020. /*                byte:                byte read                                                                                        */
    9 v: Y- Q+ i! ~
  1021. /*                cor_byte:        correct_byte that should be read                                        */: e% `0 m. |: o' J! u
  1022. /*                                                                                                                                                */% Z2 {9 e  }: f4 s0 g/ c  B( f1 S$ _
  1023. /* Returns:                                                                                                                                */7 I# L/ v' ?( i# k/ j1 B7 p3 @
  1024. /*                Nothing                                                                                                                        */+ ?9 ^6 F$ T8 x2 r# ?! |
  1025. /************************************************************************/" R. t3 Z2 L0 B& i& V# b% o
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    * U2 p( G3 l2 p
  1027. {, [% v4 d" R* _# C( s6 w
  1028.         if (byte != cor_byte)5 x# y; R+ a& G! e4 z1 k+ M
  1029.         {5 i) a3 G6 ^+ \  R* F$ U
  1030.                 while(1)
    5 r  M/ A; x; z% E/ E
  1031.                         /* add source code or statement for this file */
    - F* m% D. L" S. t' D' {" H
  1032.                         /* to compile                                  */& J: e4 }$ x% c! d" h: t
  1033.                         /* i.e. option: insert a display to view error on LED? */7 \- Y5 d/ s1 D
  1034.                 6 P9 v/ h" J( _# N2 M
  1035.         }
    9 i5 I& V; ~! G7 b+ m, S: T) v
  1036. }+ S$ u9 V8 Y, K, |: ]
  1037. & I, h% V2 R% d, M- s) O
  1038. # y& k" H2 n' T2 X
  1039. int main()5 L2 t- e$ ?7 m8 B/ V4 P* O- ^) u
  1040. {
    % Y# i  }  S% \/ w# m

  1041. , \( }4 K  f1 }1 L( r" O9 z) @) u
  1042. return 0;$ q3 d7 c9 ~, c) H/ V0 n' p3 n. X7 O
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:2 b6 Y" @) w; k: `  @8 F
   main()# p! s" q- ?3 y6 T2 s6 S  G+ ]$ I
   里面怎么是空的呢?
% j: |+ Z% I4 C, c8 Y; `1 u; O   发一份给我吧
& z4 r* D3 l6 O& }* B8 j: mmail:luyijun2005@hotmail.com/ `3 ~4 K5 o' O3 U; ?4 T8 m2 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才能执行。5 ~5 {$ H/ ~, z4 S/ Z& r+ Z

8 ^# W7 D' T) x9 g, b[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
+ c/ B* V! C- d; }; EEC的代码在哪跑,你看DS的说明,每个EC都不同的。
& Q, k/ |( i# i4 S  D" OOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
! }+ y% A% h- |8 F1 a$ W上面几个问题是你没看任何东西而白问。
- ~! g* @% j7 z  r4 F: x
4 w- G1 y4 ^& k! }; @# W至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

; j5 l! {- n, i关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!7 r* Q. b- c$ W$ }8 p0 }- C

. I: z, r0 R, A; c5 ?( g7 I  k关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”! {; I- f7 }8 q+ J/ N! u0 z! P

3 Q7 w: D* ~) x关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...3 E; x+ w5 D8 b- S! ?' ]% ?' b
' K8 [( w; o; t4 `- k# W
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
5 M) h  x4 c2 \# Q- q) v* i9 D% n似乎要把SPI能support 到最大,这EC chip应该有好卖点( {$ ?; j3 I4 o) W% A0 L
BIOS功能要不要强大,也就决定了SPI Flach的大小
7 m7 S. _2 D  e4 F; T我是这么想的~让OEM去决定要挂多大!3 F+ n$ M, n, b) @  ~
如果我司有BIOS工程师就好了~哈
/ B- {8 i: C2 o* `0 z; bWPCE775应该算很新的东西,来看它支持到多大?9 b: V% o7 K, U: {- c
4 |* ^' r3 h4 N; l$ Z
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
% {) N0 {" B$ f" N其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
+ u- `9 Z& D+ o0 H1 E1 b5 ]$ i, }( t9 m
这份driver收下~希望以后有用到" \- }' e, R3 x4 C' {% h
谢谢bini大大
8 ^7 x" L: b# B0 G& J7 W7 Z1 \5 P, {) a. }) z5 h1 y- y. w
很新很新的新手,如有错误请指正 (准备看第二家的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()
; K6 J* J# n. ~; e/ h4 Y{9 R$ U: i" I* m2 [
        unsigned char temp = 0;
1 O0 u! C# n1 B4 Z        CE_Low();4 L$ E! n: A( L4 T. K! r# @$ v
    while (temp == 0x00)        /* waste time until not busy */5 R) B- L& p5 m( e) e3 @2 a
                temp = SO;
: U2 h3 h, S' W; ]( o1 Z        CE_High();" ]) y1 F- J2 @, w5 }. M
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)! |& ^5 u" C/ H. X- X9 A7 N
{
6 k% R6 X1 d) f: ~* R# _        
& d3 Q$ c4 ~0 v5 W        unsigned char i = 0;
0 ]1 Q( q1 i" S3 ?# b        for (i = 0; i < 8; i++)' g; h9 x( ?" i5 G. \/ D( [+ e
        {
( J: _6 i# R, B- i$ j                ; k" c. k  A' c4 Y
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
2 {  ?- A$ F$ d- T9 o$ D& B                        SI = 1;; R& J' a# W& t2 o; `
                else
; D4 t9 {4 B# Y+ s6 ?) f                        SI = 0;                                /* if not, set to low */
3 @3 _- v$ O  e( a% {: x: G4 i2 q 问              SCK = 1;                                /* toggle clock high */7 G& m7 e3 W. l  k& b
   题            out = (out << 1);                /* shift 1 place for next bit */
" w- ~7 W% p+ G+ d8 v( y& m' \                SCK = 0;                                /* toggle clock low */
' H/ n' |  Y2 f. d. p        }; g: J" s4 h7 Z7 k: K
}; a( T: B" \8 `
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-5 12:49 , Processed in 0.090188 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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