找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 53815|回复: 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
    ! E; L0 k5 f. D% F! R  K- U

  2. ) x- |0 a7 q7 L* b
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    4 z: F2 Y. ^# ]( [- a, W. c" w4 V

  4. 4 B, L; g  B+ g' a
  5. November 4th, 2005, Rev. 1.0) j5 y& N4 V6 Z( \4 \

  6. 3 K/ ^& Q0 E4 g* Z+ K2 m6 E
  7. ABOUT THE SOFTWARE& g8 E# f5 e' y
  8. This application note provides software driver examples for SST25VF080B,) [# D7 Q1 z/ S+ f
  9. Serial Flash. Extensive comments are included in each routine to describe 8 u: m; w. ?* N) N
  10. the function of each routine.  The interface coding uses polling method
    - O" s+ |! p4 r
  11. rather than the SPI protocol to interface with these serial devices.  The1 R2 x* x% C/ i! A5 o
  12. functions are differentiated below in terms of the communication protocols: r0 r6 Q) H+ U6 T% r
  13. (uses Mode 0) and specific device operation instructions. This code has been
    + ]4 j1 \6 \& `/ r% a
  14. designed to compile using the Keil compiler.
    0 |9 q. B) }7 Z# }5 o( k

  15. 8 z% `) A' R0 m! Q8 ?: {

  16. 3 X( Q/ c0 q1 V3 E+ C* J. }
  17. ABOUT THE SST25VF080B$ z, Y- b0 ^6 E
  18. 7 _0 Q% h4 Z6 i3 G  |6 k
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    0 ]" k7 a8 i% I/ C2 |# ~+ m# A. |* u
  20. conjunction with this application note for a complete understanding
    ' q& e7 H0 @$ ?7 G8 M
  21. of the device.
    , `( C+ d% X& _* G. P; L& A
  22. + e9 j/ `5 r7 Z3 Y  s
  23.   E- \5 t& n( I
  24. Device Communication Protocol(pinout related) functions:
      z6 {2 Y8 g$ o, c6 y

  25. / m+ b/ k% }7 ?4 c& _& C
  26. Functions                                    Function
    5 `/ W! M& {; u# c% ^- H' V: Q" P5 E
  27. ------------------------------------------------------------------% r" f9 F: ?, W9 U/ `0 u
  28. init                                        Initializes clock to set up mode 0.1 t* z% c. L) J! j$ k
  29. Send_Byte                                Sends one byte using SI pin to send and 6 k0 E( S5 t8 x2 r
  30.                                                 shift out 1-bit per clock rising edge
    6 E* N" Z" J1 b5 [, ~
  31. Get_Byte                                Receives one byte using SO pin to receive and shift . f4 l9 l) {  `
  32.                                                 in 1-bit per clock falling edge
    3 _" ~# x4 N# R2 o% ?9 y
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    / ~- a" o0 k& _& ~+ o* f- K& n
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high2 V! F6 N& M  ^( c% z0 w/ v
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    ) C/ m9 D/ I# A* L& m
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    * T0 Z8 X9 a6 ]( q; j
  37. Unhold                                        Unholds the serial flash! j+ E2 r8 t( _9 z) S  _
  38. WP_Low                                        Clears WP pin to make serial flash write protected: d1 e& O" l" P- |
  39. UnWP                                        Disables write protection pin
    ) B% R9 u/ R) `8 p2 J# R
  40. ' ]$ X9 Q: T  Y: B8 q/ O& c% E
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ) X8 ~+ p; M# k0 F6 U3 Y8 F
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    6 W% u7 M# B  k
  43. software which should reflect your hardware interfaced.          
    $ m6 v$ s5 b' v- K( O6 O! J
  44. " v$ ^' `- c8 L' W  z% y

  45. " c  L& ^, J# B0 H/ ?5 P
  46. Device Operation Instruction functions:
    5 A: e6 w5 R5 a4 t  r

  47. : `; |8 D) H: p# P
  48. Functions                                    Function. D7 ?" v, `; G9 \) M
  49. ------------------------------------------------------------------
    + d$ c5 p. [9 l% K0 w
  50. Read_Status_Register        Reads the status register of the serial flash
    6 D( ]; M1 A0 ]$ b7 I; `. ^
  51. EWSR                                        Enables the Write Status Register
    1 g' A# x; R( [% X2 |  S
  52. WRSR                                        Performs a write to the status register
    2 W; _  s; H/ G: N  K
  53. WREN                                        Write enables the serial flash7 c7 ]/ j) w. z
  54. WRDI                                        Write disables the serial flash
    ) i5 u" J5 t: `9 d% m& V, h: D
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    % Z- z. S" b$ c% ?7 o2 A# m
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    ) {: k' e! t! I" [$ z
  57. Read_ID                                        Reads the manufacturer ID and device ID( ^& a8 M" g3 f5 ?9 R- p
  58. Jedec_ID_Read                        Reads the Jedec ID+ y! F7 i; l8 e+ ~
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    7 a; m4 P9 r( u, R: P
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    , }6 z% j% V/ @
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)) l1 ]+ H( E- p& E+ L
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    , a. G( o) O( [5 N) N& s
  63. Byte_Program                        Program one byte to the serial flash
    9 V4 B  t% \( C2 k! P8 @/ j9 A% }& m
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ) E3 V: V: ^2 U* r
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    $ f& ~( I; `* W8 D( V
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ! @* t! ?* @1 C' b2 v7 r, k) I
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY- w, ^, @9 \3 K1 e& `: t
  68. Chip_Erase                                Erases entire serial flash
    5 M  c& t) G% h2 g4 g
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash5 H8 `" s" r. d6 ]
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash- p+ Y1 \. e, K- Y7 f! L
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash( _0 @4 c/ f. E3 z3 Z4 Y' q* E- C
  72. Wait_Busy                                Polls status register until busy bit is low
    # N) i5 p1 X5 \7 @7 c
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    2 t3 q2 l8 n* p, ^( @
  74. WREN_Check                                Checks to see if WEL is set+ q: e4 G' ]( w8 W+ U
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set) w. w3 D% Y9 M# O" H, O# w" R1 _

  76. 3 I# s  V; R( w5 D2 d
  77. 4 V8 J1 |; u3 }3 j5 F1 O4 M

  78.   P( ?1 V8 u0 e( I
  79.                                                                      9 Y8 {! P& _) U; C! [4 ]5 ^  c+ D/ k
  80. "C" LANGUAGE DRIVERS " Y4 P5 |: E' j9 B% n
  81. 2 U4 D- g, J; U5 r) d
  82. /********************************************************************// ]( p( ]; `2 Q) v: H' p) e/ ]
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */8 B8 I5 S  V# C8 @* j% f
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */1 h1 d2 y  W( L$ G, N' r+ `8 ~; A
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */5 K( m' X8 [3 g# ]) w
  86. /*                                                                  */
    ( r% l* ~# K- z& t9 m& C. w
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    % L8 ?( _& N. P. Q. h
  88. /*                                                                  */
    + Y5 e1 |" O; A4 w5 A3 [$ p- |
  89. /*                                                                                                                                        */: E  O& V& l. g/ L! |, L
  90. /********************************************************************/1 E& G% A# ^# Q' U7 g& L- u) N

  91. 8 |8 V* X. w% z0 x! R. u
  92. #include <stdio.h>% O# z+ S' ]: X- O- H% D" K- O
  93. #include <stdlib.h>
    8 \1 c9 G# N" e4 Z3 b: R

  94. 7 }8 V$ ?( H7 n1 y0 \9 p
  95. /* Function Prototypes */
    2 \" f7 T, j0 I$ D- S

  96. . W# ?- [9 T2 n; P
  97. void init();4 a! j$ o4 n9 H' M* r7 R: x% D
  98. void Send_Byte(unsigned char out);
    % N4 ]1 w1 n# ]: S; P+ P
  99. unsigned char Get_Byte();5 @4 ~6 J6 w7 [
  100. void Poll_SO();
    " k# {3 G$ D1 L) O7 S
  101. void CE_High();
    ; J- K7 R, u5 Z7 i  }
  102. void CE_Low();4 z% b7 r" `! V- ?3 g$ E- \9 B
  103. void Hold_Low();( \- v$ ~6 S/ w3 n2 `+ }" d4 S; @
  104. void Unhold();
    6 ?; `; `5 o, W, g! |6 C6 l8 L$ Y
  105. void WP_Low();
    ! ?4 ^' Y9 |! W9 b  ]
  106. void UnWP();
    9 ]$ f, b" d, q2 t+ {
  107. unsigned char Read_Status_Register();
    6 f  R- u2 X1 ~  o, Z% B7 d0 X0 |2 ]% T
  108. void EWSR();8 T' M& E4 w4 o6 y. O
  109. void WRSR(byte);
    0 Z' w: x1 S3 }7 G4 s2 T
  110. void WREN();
    7 v+ ~7 ^" r6 X. a" M; g# T0 H
  111. void WRDI();6 q3 Q, {3 a' {( p
  112. void EBSY();
    * Q* w0 _" ?7 H6 g, M( ~5 \0 n: D
  113. void DBSY();
    ( U; t% D& a  n" {; J# R2 q. f
  114. unsigned char Read_ID(ID_addr);1 A% h; w( e$ U. c/ y8 x! r
  115. unsigned long Jedec_ID_Read(); , Y: C4 L; Z. s8 R3 Y
  116. unsigned char Read(unsigned long Dst);
    ' e+ A5 U9 x9 I! j& ?9 {2 F
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ) e, T0 `- v9 P8 r
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    % J) L4 N  E- e( V( F1 Z
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);- h6 e. g" h  F7 X0 A
  120. void Byte_Program(unsigned long Dst, unsigned char byte);% K: L! V# ~0 v3 P2 q
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);. {" A4 N, Y; Z) O2 s
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);9 p+ U8 V& U( y( P0 R) A
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);! R- Q: q  N3 ]1 O& o* X7 A
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    + y* Y: C8 @( \1 }9 k0 Q2 t
  125. void Chip_Erase();+ q! D: p7 \% p, M* q! C4 O
  126. void Sector_Erase(unsigned long Dst);
    ' h' c# F/ K  Y
  127. void Block_Erase_32K(unsigned long Dst);6 y, K% g. j* e
  128. void Block_Erase_64K(unsigned long Dst);
      N6 C$ F. U& Q
  129. void Wait_Busy();6 s! Z/ e* \' A9 J# A
  130. void Wait_Busy_AAI();
    3 e4 y4 C6 I0 U9 `
  131. void WREN_Check();
    $ t$ C( k4 h3 Z2 Y
  132. void WREN_AAI_Check();$ e3 s% J) d( E4 k4 b3 s% @  R

  133. * ?. `7 A: {- j/ C9 U; G
  134. void Verify(unsigned char byte, unsigned char cor_byte);# x& b7 f+ h' T1 g' a( J# c

  135.   K+ D: z, z7 l7 O
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    & v6 _  k/ Z- o/ J( E
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    2 X$ z1 ?9 f/ d0 v% H3 v" v
  138. " g9 \) t9 n' O1 a& q
  139. /************************************************************************/5 ?4 ^' v6 y/ b, o
  140. /* PROCEDURE: init                                                                                                                */
    5 H* N" D2 o  s" j  [! y
  141. /*                                                                                                                                                */
    - Q: M9 v! c/ Y1 ~# L
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    8 X/ H1 K7 F% F5 Y
  143. /* setting up mode 0.                                                                                                        */( X, z; A( K6 x6 ^( }: x3 s# o
  144. /*                                                                                                                                                *// {. }" E( F0 [& S
  145. /* Input:                                                                                                                                */9 G2 E! P1 B4 ^; h5 }0 R
  146. /*                None                                                                                                                        */
    , D' \5 }" C6 N3 `2 Y7 g0 o% T! u
  147. /*                                                                                                                                                */
    : o# a9 ]! u% L( f& ^
  148. /* Output:                                                                                                                                */' ~$ K3 q$ ]7 D" F' f# V
  149. /*                SCK                                                                                                                                */: q# X3 p: p$ j
  150. /************************************************************************/
    * n# F8 o. v+ u) i4 Q1 M! w
  151. void init()
    7 k7 y- Y  t# n, R8 D0 Z
  152. {  F" f" H" ~( }4 ~
  153.         SCK = 0;        /* set clock to low initial state */% `- v7 ?" F; X5 c2 Y+ z, N/ [. e) e
  154. }
    + m; l. S& T6 @, K* l4 k* K8 E
  155. * N0 u; k- G3 [3 l3 q
  156. /************************************************************************/
    1 @( {, Y" O; Z! p
  157. /* PROCEDURE: Send_Byte                                                                                                        */, _" x8 R% M7 `
  158. /*                                                                                                                                                */
    & I6 ~6 ?* ^0 ?& ^0 j. e
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */8 G3 s. R* g" g1 a# M
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    ) g1 Y1 |6 M. s
  161. /*                                                                                                                                                */
    " p" g( @8 Z  k% Q0 s, j
  162. /* Input:                                                                                                                                */- f. s3 r+ O1 j( z9 D( f! ^
  163. /*                out                                                                                                                                */; \2 I  D* P7 w  U( R$ i6 B& V
  164. /*                                                                                                                                                */
    ) O7 f2 J4 b. H; y5 o
  165. /* Output:                                                                                                                                */, G2 \+ \0 K" ?% ]7 a. U
  166. /*                SI                                                                                                                                */
    9 o. ~; ?  b6 e) L
  167. /************************************************************************/
    % |; e: ]. T' g% }4 o
  168. void Send_Byte(unsigned char out)8 t4 G3 T- _: c5 M% ^  }2 `9 k9 v
  169. {$ \/ n% L! K# o, X% m; T
  170.        
    / O+ _5 n& Z2 k' y3 l, A4 w; _
  171.         unsigned char i = 0;& i1 A* G/ s9 v! P7 r
  172.         for (i = 0; i < 8; i++)8 R2 O" V' d+ S0 k4 v! d- w
  173.         {
    ) p3 T) C) N& [; g# r
  174.                 3 X0 M7 B  l5 R; Y
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    8 @" r( ]3 l, Q- n
  176.                         SI = 1;
    6 C, z. E" D1 r
  177.                 else* B/ h- i' I  R# {% U
  178.                         SI = 0;                                /* if not, set to low */
    " o( v' S8 ~- y$ r2 Q& u+ M( q
  179.                 SCK = 1;                                /* toggle clock high */
    . U+ I) J1 J# T. S, S8 R& f. u
  180.                 out = (out << 1);                /* shift 1 place for next bit */( q, s  S, C+ L/ b8 R8 j
  181.                 SCK = 0;                                /* toggle clock low */# q) k! v3 l0 `( O9 x
  182.         }) g. @( y$ F0 y, v
  183. }* ]7 E, `( \3 E

  184. . C" K% x$ T1 i! H
  185. /************************************************************************/7 l* B/ I5 U; i+ U. l6 W
  186. /* PROCEDURE: Get_Byte                                                                                                        */2 a& c* ~+ D! I5 W0 J
  187. /*                                                                                                                                                */& m2 U7 t, k0 u( w
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ; Q+ Q7 a& e0 [5 \( e  t
  189. /* edge on the SO pin(LSB 1st).                                                                                        */4 t2 }6 e$ F: W' F, ^
  190. /*                                                                                                                                                *// Y5 o9 m9 W3 |, w# ?2 R
  191. /* Input:                                                                                                                                */- G" m/ A/ a( F4 f: e( P
  192. /*                SO                                                                                                                                */# q' B! [5 `( N* B" @, S& p5 k
  193. /*                                                                                                                                                */; B: J1 k1 T9 {* {( G
  194. /* Output:                                                                                                                                */7 v4 `: W/ G" W5 d9 s# y
  195. /*                None                                                                                                                        */$ X. a/ ?# q9 B  M* `
  196. /************************************************************************/* p* X8 G2 Y# _# S
  197. unsigned char Get_Byte()
    4 b8 r1 R$ e: W" r6 d
  198. {
    7 g+ T6 _  u! }
  199.         unsigned char i = 0, in = 0, temp = 0;: S+ S. }1 V# D; ]) z
  200.         for (i = 0; i < 8; i++)2 @- O7 T% O7 w+ {/ k/ z& r
  201.         {' N# Z1 c* D- I0 `6 y5 y
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */% s: i# g1 M1 h+ b
  203.                 temp = SO;                        /* save input */
    0 ]5 G( }. u/ S1 d8 U2 r
  204.                 SCK = 1;                        /* toggle clock high */
      {2 T7 e6 B* Y7 c
  205.                 if (temp == 1)                        /* check to see if bit is high */8 G' R0 S8 h0 n0 \3 p( O: E. }
  206.                         in = in | 0x01;                /* if high, make bit high */6 ^3 l5 x" O/ i; m
  207. * O! Z: [, x# @# N
  208.                 SCK = 0;                        /* toggle clock low */6 U3 s) O9 V" j

  209.   a1 X# y: T0 m; e3 e1 }+ |. o2 q
  210.         }
    2 E, d- I. b1 h1 D
  211.         return in;
    , W' Q+ e; ^: L
  212. }+ A0 L$ ]5 z2 E2 O+ e3 i
  213. ; }5 J4 g  J: G
  214. /************************************************************************/
    ; ?. c* H' a+ N5 b
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    " U6 {7 J+ d" t, s
  216. /*                                                                                                                                                */
    2 g4 p& V7 G1 g0 i$ ~
  217. /* This procedure polls for the SO line during AAI programming                  */+ d8 ^) |6 C7 j% U0 q; w3 L4 x
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/: s2 ]8 R& n  Q) k  s0 `0 m3 {9 y
  219. /* is completed                                                                                                                        */" {6 S  }# u. d3 S2 H( w
  220. /*                                                                                                                                                */+ `1 |* p# A3 E* v5 ^" a; u
  221. /* Input:                                                                                                                                */: X7 \/ Y4 m% ?, Q& F! o' X, D9 b
  222. /*                SO                                                                                                                                */, @9 T2 e' N$ }- Y9 p6 z
  223. /*                                                                                                                                                */# a+ B3 T! v& {2 ?; t
  224. /* Output:                                                                                                                                */9 G2 W7 i" A, i: m6 E# z' l3 o: V
  225. /*                None                                                                                                                        */7 x4 n' z0 p- A$ ^# A& F; y( A
  226. /************************************************************************/
    0 N9 c3 M  y% Q8 g% e
  227. void Poll_SO()
    6 ?, q, M, g$ B+ z. |
  228. {
    % R8 a4 s8 W" z! Z6 T
  229.         unsigned char temp = 0;
    $ l" @5 y! d+ a
  230.         CE_Low();' B2 F" @6 d8 }' ^6 j9 y0 ]3 U
  231.     while (temp == 0x00)        /* waste time until not busy */
    # z7 ~1 c/ Y6 u3 T3 \
  232.                 temp = SO;$ }5 I* ^' v, F! @5 F8 @9 o
  233.         CE_High();
    8 s/ Q, P7 U9 K& ^
  234. }8 o- p8 M. h" d+ y1 l
  235. : u( d6 l0 T( [7 h; a5 w" Q- a; }
  236. /************************************************************************/
    % q; y" m6 m9 M. I) T) n" e
  237. /* PROCEDURE: CE_High                                                                                                        */
    , Q* l8 I+ a7 p% H# P
  238. /*                                                                                                                                                */
    & v' A4 \7 [& A2 o( \7 J: u
  239. /* This procedure set CE = High.                                                                                */, m0 L. J( h  |: G/ L5 _5 n* y* T
  240. /*                                                                                                                                                */
    0 p/ A0 u# B  F; C7 b
  241. /* Input:                                                                                                                                */7 v  m' R2 e! g: a" F
  242. /*                None                                                                                                                        */
    8 u) }) J- M% _# `8 C; e9 A" b; t
  243. /*                                                                                                                                                */" w* m; M" a$ q4 ^
  244. /* Output:                                                                                                                                */
    1 _& U9 g8 D+ e4 U) j) E7 o; {
  245. /*                CE                                                                                                                                */$ b- e$ P7 V8 T8 A' p. r2 p
  246. /*                                                                                                                                                */
    . c3 W# v' v) U; H% w9 T( ~
  247. /************************************************************************/" }- |! S  S4 L1 ~+ ]) S0 @
  248. void CE_High()   Z- b$ D& G4 H* d# A
  249. {# e% X$ A  k* ^$ v- Z9 h
  250.         CE = 1;                                /* set CE high */7 q: `9 l) r! `& N% _6 H. }5 t  [- N
  251. }7 [- E9 Z. p$ Q8 `1 l

  252. 1 X0 |3 y; U1 _8 {! [9 X, L6 n
  253. /************************************************************************/9 \! N/ C0 F: V( P, f
  254. /* PROCEDURE: CE_Low                                                                                                        */* H! ?  c" j, }: M
  255. /*                                                                                                                                                */
    5 _! w  K0 l, h* g4 q
  256. /* This procedure drives the CE of the device to low.                                          */4 {" v' b6 I3 X# r& f% q, [9 R
  257. /*                                                                                                                                                */6 R! ^; L; ^2 R5 {* r* \9 f& G
  258. /* Input:                                                                                                                                */" J3 ~2 L) o& M
  259. /*                None                                                                                                                        */
    9 {9 t3 b1 L! m/ {: ?" `" V
  260. /*                                                                                                                                                */5 b; H3 m+ r4 H7 e3 j. x1 ~; ]* A5 o
  261. /* Output:                                                                                                                                *// A1 l0 h: U$ l" s. ^
  262. /*                CE                                                                                                                                */+ W+ E/ {: `5 L5 d6 f9 _
  263. /*                                                                                                                                                */8 F# v! v3 P" i* M  U& u
  264. /************************************************************************/
    4 ~3 _( b( b7 M+ ?
  265. void CE_Low()
    0 A, g5 f' x; s+ q* U
  266. {        9 n! B! U9 t# N
  267.         CE = 0;                                /* clear CE low */& i3 [* N2 [$ P$ D
  268. }
    5 G* l4 C0 s0 }: ^: ?* f
  269. ; U( G5 ?& Q* U$ \, ?, _
  270. /************************************************************************/$ w* O+ }4 L, B4 ?/ b
  271. /* PROCEDURE: Hold()                                                                                                        */9 ~' H& j; O: ^7 I
  272. /*                                                                                                                                                */1 k: v  A, n/ j" [* M" b# \' P
  273. /* This procedure clears the Hold pin to low.                                                        */
    " |& }. y# }  h; s- {1 |
  274. /*                                                                                                                                                */2 O( I( P; \) t8 Y2 _  v% K% P* x
  275. /* Input:                                                                                                                                */
    * P# l% O7 L* [: e' d* ~
  276. /*                None                                                                                                                        */
    # q+ W* S5 h  h  w# F
  277. /*                                                                                                                                                *// _4 }" [$ r3 _  N- Z' `( P' h
  278. /* Output:                                                                                                                                */
    2 ~2 k7 H+ j% ]9 Y4 Q
  279. /*                Hold                                                                                                                        */
    ( w; @/ ]$ P* X  ]$ x# x& P8 m! s
  280. /************************************************************************/
    2 d+ r+ [1 U5 C4 _  v
  281. void Hold_Low()* B+ V4 {' \  C0 r  [: z& G; p
  282. {& @; e, W/ \$ r& t! q9 Y( f
  283.         Hold = 0;                        /* clear Hold pin */, f6 V) {+ @  u" O" T
  284. }0 p' z7 e+ b( T' Q) C
  285. 3 _$ o. s7 t, T& b' Y0 K7 \
  286. /************************************************************************/
    " U( ?' R: `  w  g0 f) V
  287. /* PROCEDURE: Unhold()                                                                                                        */
    : |" m1 D) z2 M2 c' o  U
  288. /*                                                                                                                                                */8 B3 o' O8 w% z" @8 O( G7 L
  289. /* This procedure sets the Hold pin to high.                                                        */1 Y( H' J8 C( @8 F
  290. /*                                                                                                                                                */( `9 D' U; P' d( y5 i
  291. /* Input:                                                                                                                                */. ?8 w. C4 y! g4 L% y: H& T
  292. /*                None                                                                                                                        */2 _& H. B7 X: U
  293. /*                                                                                                                                                */$ J& X" L' ~( K
  294. /* Output:                                                                                                                                */
    3 l/ q7 g: j$ o$ i+ v4 z* k& h, x0 c
  295. /*                Hold                                                                                                                        */4 g, c# v5 n/ ?  J
  296. /************************************************************************/% x5 H: G7 `* g/ F* J$ K" e
  297. void Unhold()) _& @* t& r) W0 Z, R2 H$ N  H
  298. {1 }3 o. t% ^. Y8 y! G
  299.         Hold = 1;                        /* set Hold pin */
    / T7 v9 e" o6 r$ w
  300. }
    % G: P2 o! G, p' ~
  301. 2 T6 k9 n: S1 ^0 }( F5 t9 z
  302. /************************************************************************/
    ' O. ~9 M7 v3 W) y
  303. /* PROCEDURE: WP()                                                                                                                */) l8 F% h7 C, |
  304. /*                                                                                                                                                */% d( {+ `! ?' M. D7 i/ \$ ^8 G5 G
  305. /* This procedure clears the WP pin to low.                                                                */' C+ `/ @/ x0 t; J) J
  306. /*                                                                                                                                                */8 E! R, z5 \. m* v) K, l
  307. /* Input:                                                                                                                                */
    " x& F' j) @" Z( N- Y  _( ^" ?/ O
  308. /*                None                                                                                                                        */0 a; g- ^0 O; b" m' c, v' R
  309. /*                                                                                                                                                */7 f- t# |6 v3 M- O% q5 b* j
  310. /* Output:                                                                                                                                */- d& g: _! L& w4 s0 R
  311. /*                WP                                                                                                                                */
    ; e. B) N/ x) B7 m; V1 \
  312. /************************************************************************/
    * K/ L, P! R' m3 K; e
  313. void WP_Low()
    * `6 C* ], o4 v+ w7 B/ K# ]7 s
  314. {7 \+ w7 W1 }2 M
  315.         WP = 0;                                /* clear WP pin */. ~$ m( ^! n# p- K( i
  316. }1 O# r7 @' R% A! ?3 Y0 a, @

  317. $ {& b7 v& ~5 D2 e+ m
  318. /************************************************************************/+ |$ z5 `& e  |3 l% S2 }" u
  319. /* PROCEDURE: UnWP()                                                                                                        */, g' V3 U, @6 X8 z" r- h6 t1 @
  320. /*                                                                                                                                                */
    4 I% o0 t( X1 u( u
  321. /* This procedure sets the WP pin to high.                                                                */+ y* D4 N$ d# J- {. r  z2 O
  322. /*                                                                                                                                                */
    / f- N) Y2 ~+ _. a0 |
  323. /* Input:                                                                                                                                */' K; U" E. I8 y+ y' f
  324. /*                None                                                                                                                        */2 d; E9 ?: U1 ]/ a% F: s3 J2 G
  325. /*                                                                                                                                                */3 K- U1 U4 E# G; {' ~" l" z- `  T
  326. /* Output:                                                                                                                                */4 ~- w; T$ b6 B7 d; \% Z% A
  327. /*                WP                                                                                                                                */
    " j( E5 D3 ]9 r, y) j& }4 K
  328. /************************************************************************/
    9 `- t4 s8 Q& o% x# |2 M( L- p
  329. void UnWP(): T" i: S% H: C" J3 N
  330. {1 j& l" ?) ^- I0 p
  331.         WP = 1;                                /* set WP pin *// {: t5 ~4 u; }- ]6 o! ~( {% D
  332. }
    9 `1 _8 _! H* M/ m& a3 \) b
  333. ' r# a7 R) }4 L; F/ P, w( F; F# x
  334. /************************************************************************/- t% U* A% J! b5 Y
  335. /* PROCEDURE: Read_Status_Register                                                                                */# Y6 z2 B. ?3 i/ S- U: Q
  336. /*                                                                                                                                                */! T4 O8 h* E0 B1 T- i6 \* V2 A9 ~* k
  337. /* This procedure read the status register and returns the byte.                */$ X" O* ~/ n1 _& i- T
  338. /*                                                                                                                                                */
    " k1 N$ ~. W8 X9 _' }* h% G" v
  339. /* Input:                                                                                                                                */
    " L& R( \( |( L" c5 n) J& z
  340. /*                None                                                                                                                        */
    - n8 J8 e" {% i. l, v( p+ J; n# y$ [
  341. /*                                                                                                                                                */( ?6 P8 [/ {. A& O4 b& V2 V
  342. /* Returns:                                                                                                                                */
    : M5 ^: ?8 U) D8 b) Z3 z) t  U: X
  343. /*                byte                                                                                                                        */5 k* u. ^) ]" W4 F+ P! l
  344. /************************************************************************/( I) v- K' t# G2 d  E% q
  345. unsigned char Read_Status_Register()2 R# a: g) C$ j6 u3 u
  346. {1 X# Z% g% p  v- q. K, C
  347.         unsigned char byte = 0;5 C$ Q9 y. B/ y4 N
  348.         CE_Low();                                /* enable device */4 {: v% R9 \" K% O  q
  349.         Send_Byte(0x05);                /* send RDSR command */
    ; C% m) F) L4 q( e
  350.         byte = Get_Byte();                /* receive byte */
    ' x5 C8 ?' U% R  C; m6 C+ k( ~% S3 P) N
  351.         CE_High();                                /* disable device */
    * r- a  j" C  d# h" X: o* ]
  352.         return byte;/ I# `4 y; n5 U; {  Y5 j# m1 v) L
  353. }* \& ?6 c. i8 o( ]

  354.   U  Q$ R3 Q$ |9 n6 T5 _
  355. /************************************************************************/
    $ [! c4 a% @7 _1 X
  356. /* PROCEDURE: EWSR                                                                                                                */7 @! i6 u$ {0 z3 {' m" ^" I0 A( m' z; O
  357. /*                                                                                                                                                */) u8 `; E( Y* z% z1 v
  358. /* This procedure Enables Write Status Register.                                                  */
      C6 ?5 C3 m2 o: C
  359. /*                                                                                                                                                */
    / y$ g9 ~- ]  p  a3 n
  360. /* Input:                                                                                                                                */8 a7 E+ `& y8 A, ]5 \" M
  361. /*                None                                                                                                                        */* k- c! j1 f8 R% z; p( U
  362. /*                                                                                                                                                */  W+ _# S$ y, z2 K
  363. /* Returns:                                                                                                                                */, ^* @% b; M+ T9 i! D- ~7 O
  364. /*                Nothing                                                                                                                        */+ D: o# m  ^( D9 s0 R. d
  365. /************************************************************************/
    & L) K9 E1 }9 Z; M7 }
  366. void EWSR()
    7 e& U, d: q: r, P
  367. {
    $ l# v7 P; e, Z
  368.         CE_Low();                                /* enable device */
    ( ]9 [0 N4 r  v
  369.         Send_Byte(0x50);                /* enable writing to the status register */. d( s& R+ M1 i+ a6 a2 W
  370.         CE_High();                                /* disable device *// [$ D- K2 N2 L) j7 Z8 h
  371. }
    1 G! h* `9 {- {2 y& b$ ?3 w
  372. " C. S% Y6 W3 ~$ H, v6 b
  373. /************************************************************************/
    & i6 [, V1 B2 l7 `* V" Z* e& W5 {
  374. /* PROCEDURE: WRSR                                                                                                                */
    # k3 g) }0 G) z) U- Z, D
  375. /*                                                                                                                                                */
    / r% v- m. R" P- @
  376. /* This procedure writes a byte to the Status Register.                                        */- r" n- W6 E" b9 G) w9 A$ ~
  377. /*                                                                                                                                                */0 i; p& t! Y  s0 Z- {
  378. /* Input:                                                                                                                                */& Y& P' @! f. H& O- ?& P
  379. /*                byte                                                                                                                        */& b+ n1 z$ I/ u: T7 ~
  380. /*                                                                                                                                                */
    1 @$ K8 l+ F4 q# R
  381. /* Returns:                                                                                                                                */
    * f' M4 A9 K, J- \. L& |# w+ Z
  382. /*                Nothing                                                                                                                        */( h0 O& p2 v0 U, G
  383. /************************************************************************/' \1 w! ^1 j3 O; J0 R
  384. void WRSR(byte)
    " h/ a* t& V+ P( i& R7 ^7 m
  385. {
    4 ]( E2 X4 |! ^# F- y) c5 G6 u
  386.         CE_Low();                                /* enable device *// s8 N; A* i. I, x" k1 p
  387.         Send_Byte(0x01);                /* select write to status register */+ ]5 h( y, B# n6 k& \/ v
  388.         Send_Byte(byte);                /* data that will change the status of BPx # O; ?( H: U. t0 W
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    & i( T- i2 n, s* u
  390.         CE_High();                                /* disable the device */
    7 |* l, _: I* V1 W- y* V% ~& I- y
  391. }7 c; a# p) k1 M& d

  392. # {8 W! |5 K9 A7 s2 Y1 x6 T
  393. /************************************************************************/) e. }$ L0 u% S% L6 ~- R) |3 _. c
  394. /* PROCEDURE: WREN                                                                                                                */
    8 U; l2 m. z7 b: E8 N* {1 ]
  395. /*                                                                                                                                                */- ~/ L. ], C- b; W8 F7 [; U
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */* e- k! ~" C- {% z  \* Q
  397. /* to Enables Write Status Register.                                                                        */: T" l( l( e( C
  398. /*                                                                                                                                                */
    " @; j2 r( Q% l  ?  a1 i
  399. /* Input:                                                                                                                                */
    8 M9 E7 M  _2 h/ Q8 j
  400. /*                None                                                                                                                        */
    ; p* v* h6 x" \
  401. /*                                                                                                                                                */
    9 G* s$ T3 E7 d/ \6 [) m
  402. /* Returns:                                                                                                                                */4 O, g7 Z" `) Q6 J' L
  403. /*                Nothing                                                                                                                        */
    ' C3 n/ q" T9 b" Q- m1 p8 Q% a
  404. /************************************************************************/  d  f( D; Q" N( C
  405. void WREN()
    ; g$ g; c1 @) C7 q& b
  406. {
    * r, K/ ~2 W: _, I# g1 h; k3 a
  407.         CE_Low();                                /* enable device */
    ( W9 I0 j) s2 n8 U  f
  408.         Send_Byte(0x06);                /* send WREN command */
    . h  O; f3 m" {7 I7 f. f
  409.         CE_High();                                /* disable device */" C' w; V8 i, x: g4 E& M2 x% H. B
  410. }
    4 C# J% |- b4 x; `$ D: I) m  K! w

  411. ; }0 i1 n/ ~& y
  412. /************************************************************************/
    3 c3 \2 X6 G& m2 Z+ t! d
  413. /* PROCEDURE: WRDI                                                                                                                */
    : H& e8 }; I6 \& ?4 A* ?9 ?
  414. /*                                                                                                                                                */
    0 ]) `4 E" e6 I+ Y8 u4 {- d0 Y
  415. /* This procedure disables the Write Enable Latch.                                                */. ?- E  g6 c* E7 Z+ |" l
  416. /*                                                                                                                                                */
    ( `9 _6 O  W$ u, z/ C* R
  417. /* Input:                                                                                                                                */; I& q7 [; ^9 X7 \  z
  418. /*                None                                                                                                                        */
    : L2 G* @$ B! J6 Y& A  V
  419. /*                                                                                                                                                */
    ' Y$ z/ W, x8 v6 a0 _+ j
  420. /* Returns:                                                                                                                                */, N8 H. j  D7 o7 }
  421. /*                Nothing                                                                                                                        */
    * Y5 S, y$ k. A: I9 Q) K# Q
  422. /************************************************************************/" j- J0 }( I; S3 V* G; [
  423. void WRDI()* a0 e! k4 k/ j# O7 Y: @
  424. {
      f; Z2 I% c  P- S2 W8 C" n
  425.         CE_Low();                                /* enable device */
    $ _; e5 V& y. |/ D& }0 e% Z* Q
  426.         Send_Byte(0x04);                /* send WRDI command */
    / @; N, d% ~% Q8 r" n3 i3 e4 e
  427.         CE_High();                                /* disable device */
    % |- t8 v9 t; n' R
  428. }+ Y" E- K4 C9 Y9 u( k' z( w( }
  429. 0 M7 q7 O3 o3 C! P/ d, ^8 L
  430. /************************************************************************/) m+ l" J' `0 }  D7 N/ p
  431. /* PROCEDURE: EBSY                                                                                                                */
    $ {$ T5 Z( N/ R$ a
  432. /*                                                                                                                                                */( S' F% {2 a' w# ?- c3 H
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */3 A  r* k6 O9 f2 g5 |5 U
  434. /* programming.                                                                                                                        */! H- \: v7 W5 C' n9 v# _
  435. /*                                                                                                                                                */( @& x& n3 _7 F8 w0 o( @# E
  436. /* Input:                                                                                                                                */: m: s) [! S, f4 m
  437. /*                None                                                                                                                        */
    0 i8 g$ {# T6 s( N( B7 M# m0 K
  438. /*                                                                                                                                                */- g) ]5 f! t# o7 v
  439. /* Returns:                                                                                                                                */
    2 ]" I% `2 e) M# ?
  440. /*                Nothing                                                                                                                        */
    ( |: i! l/ j6 v7 {+ `6 V& ^
  441. /************************************************************************/1 D8 ?# _& L3 b5 u4 ~. x1 P2 H0 ?5 f
  442. void EBSY()
    # x$ ~8 Z. Y; ^, T1 i0 Z
  443. {( v0 u- @: @4 n. v. b
  444.         CE_Low();                                /* enable device */
    " I+ q! T  _# X& G1 g3 P
  445.         Send_Byte(0x70);                /* send EBSY command */
    ' T: W5 F# r* k+ K0 H  }* V0 o
  446.         CE_High();                                /* disable device */% p/ I8 t1 {) s  ]  \9 }  y
  447. }& X! T* C* D, u* X2 w
  448. * c5 @6 ]( n4 t9 o+ B. O8 j4 |
  449. /************************************************************************/6 Z& e& C5 [3 L/ c, @* N
  450. /* PROCEDURE: DBSY                                                                                                                */
    ( f  {  g. s" n6 O6 l" c
  451. /*                                                                                                                                                */
    2 o4 x3 F8 }8 Z$ V6 X
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */8 K4 [: ?+ j: J4 C" |# l
  453. /* programming.                                                                                                                        */' W, g2 T! g3 @/ B3 J) z
  454. /*                                                                                                                                                */
    6 l3 C) l1 ]9 p
  455. /* Input:                                                                                                                                */; D  }/ Z( t/ T. Z# p" M+ Z
  456. /*                None                                                                                                                        */
    0 t* Y5 v# J, C6 ]2 J' D+ [# i+ |) \
  457. /*                                                                                                                                                *// X/ D; \* i4 V, R' G; m
  458. /* Returns:                                                                                                                                */& m4 U' T5 a, \6 K7 S; ]) K
  459. /*                Nothing                                                                                                                        */) Q) u2 K5 N$ A; ~+ c! @! ^
  460. /************************************************************************/
    ' {1 {; ^9 J' A0 K1 y
  461. void DBSY()( k8 L3 q, m* R$ d6 j# h7 }
  462. {/ H! e. ~( k- M: _- m1 u
  463.         CE_Low();                                /* enable device */! c! D8 T! ~. P# w" j
  464.         Send_Byte(0x80);                /* send DBSY command */
    5 C# t% h  e( s( s
  465.         CE_High();                                /* disable device */* B6 Y8 B8 |) ?/ O% F
  466. }
    , l7 x- L' ?$ h. V+ }+ U
  467. 0 U, l& Y; i/ W1 o, H! y
  468. /************************************************************************/
    4 ?# g9 a/ q! ], Q# R
  469. /* PROCEDURE: Read_ID                                                                                                        */
    , F! r( O2 b# H& T/ w' [% O' Z
  470. /*                                                                                                                                                */
    0 Y7 @; K6 k  h) O
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    9 E' x8 g0 }5 T% L# n# a! B. ^
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    / S& _' D+ w: k. D7 ^- m6 {
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ( H' y1 v4 z9 @  E; l' s
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    / f* A8 h. D/ e- R* q1 l! y9 `
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ' f$ V/ ^" K0 E9 H) Q3 H* l8 ^; S
  476. /* variable byte.                                                                                                                */
    ) p4 l. I* {; T$ _" S: p
  477. /*                                                                                                                                                */! o3 L& y+ E" E  c: e, i& F
  478. /* Input:                                                                                                                                */7 e$ h: G$ ]* h/ `
  479. /*                ID_addr                                                                                                                        */9 x% {# h% p# G- e8 T" y$ ]( T
  480. /*                                                                                                                                                */
    6 ~& E5 B& P: E8 _& d! W
  481. /* Returns:                                                                                                                                */
    - d' e3 j  t$ z1 Z! E, Z
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */( e+ t: \7 _) t9 b3 x- r
  483. /*                                                                                                                                                */
    0 U5 d8 Y( n9 E
  484. /************************************************************************/4 e2 ~7 p' o' O1 U
  485. unsigned char Read_ID(ID_addr)
      Z9 \8 \) u7 R3 J! h5 F' Q
  486. {9 B! p2 g, U( A/ B9 k2 [! W5 g
  487.         unsigned char byte;& s* J/ u( i' W2 k
  488.         CE_Low();                                /* enable device */
    & {  G4 ~# K) @& P
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */7 f  s- d* ^6 [
  490.     Send_Byte(0x00);                /* send address */( k7 f1 @: g, H3 d1 u3 B: \% q' b$ O- z
  491.         Send_Byte(0x00);                /* send address */( D$ J6 A: t- b6 R) `
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */7 N" }5 p9 J. P, w
  493.         byte = Get_Byte();                /* receive byte */
    1 C( F! N6 p! S
  494.         CE_High();                                /* disable device */
    ' e5 t: g1 E' F1 W* Q+ Q  h
  495.         return byte;
    2 r3 D+ `; z( @& E1 g
  496. }
    , \5 A% G( @+ v+ B
  497. 1 F! N  D4 A; y5 e# n5 K: K# t
  498. /************************************************************************/
    & W- `, X0 Z  C2 s' ^% h* x
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */8 K. i/ n/ y. F# Q+ p1 i
  500. /*                                                                                                                                                */2 l$ G* _+ R- I7 t- j
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */9 i, t% r- x8 R* I
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ' o: |: ^' T& q0 P6 \* d. U
  503. /* Please see the product datasheet for details.                                                  */5 _1 G- c  X7 o  M
  504. /*                                                                                                                                                */
    # D, n+ l* t; l+ h  O0 V; F
  505. /* Input:                                                                                                                                */
    1 a. D  ?( K: O
  506. /*                None                                                                                                                        */9 |) @2 t' M) B* `/ u" |
  507. /*                                                                                                                                                */5 W: R3 S) ^  B. m' V0 x  c1 d1 m
  508. /* Returns:                                                                                                                                */. J; f& A6 F6 V' r5 }2 F0 d
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */0 Z5 \, r# F6 \- T# R0 M
  510. /*                 and Device ID (8Eh)                                                                                        */
    + L' y( e% w" E7 L3 ]! z
  511. /*                                                                                                                                                */" E# K; e1 u& L. a3 b
  512. /************************************************************************/
    . K, L6 p. U+ W' h4 z8 E" D
  513. unsigned long Jedec_ID_Read() ' k3 @# V  E$ y0 N" H4 X7 k
  514. {1 o) W6 s" B1 {+ ~% o
  515.         unsigned long temp;
    , J; ~* V8 A" j- y1 `7 e
  516.        
    ( B% \! n9 e+ m8 A/ h! Z1 \! u
  517.         temp = 0;
    $ n5 }! a- D/ y# p( A, S$ Q2 P$ ~
  518. $ [4 {5 v! \& q$ M- P" z
  519.         CE_Low();                                        /* enable device */
    0 R* K  h2 Z& p4 w
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    & t7 K4 e$ v. l" A7 E; F
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte *// ~- v& v$ ^$ D5 W
  522.         temp = (temp | Get_Byte()) << 8;        * l. [+ m1 Q$ X
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    , L- ?# ?# Q! _$ X' A
  524.         CE_High();                                                        /* disable device */
    1 P+ O' y3 \7 ?- E  g2 ?( u: y$ j; J
  525. 2 x& ^8 ]2 P- L/ v
  526.         return temp;
    4 W- s0 d% r, i( v% Y, f) \
  527. }
    7 ~: y  a1 i) `$ a( g. L$ x( _
  528. 1 E- |! @3 j* l" O& A; G
  529. /************************************************************************/
      t( o4 b4 b6 h1 k4 x
  530. /* PROCEDURE:        Read                                                                                                        */
    ) V* d9 J0 u+ P3 K% S3 ]& H/ U
  531. /*                                                                                                                                                */                8 ?1 u) g/ V' G7 L5 `. X# i
  532. /* This procedure reads one address of the device.  It will return the         */
    + k& v- [; V( j. H
  533. /* byte read in variable byte.                                                                                        */
    * D+ ^6 o' b& G$ O: ^3 {" x! n9 U. d
  534. /*                                                                                                                                                */. I5 [$ p! a0 ]* t* |& l1 w) o+ H& l
  535. /*                                                                                                                                                *// |8 c2 }' N7 G; }3 b
  536. /*                                                                                                                                                */  J# l2 q7 P4 E2 t) w
  537. /* Input:                                                                                                                                */% \# Q5 }8 {) a1 o# V, E6 B
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */* F! `) m% w4 s# L8 E5 K$ X3 A  {
  539. /*                                                                                                                                      */
    ) g% A0 B3 w; w. i# T# B- o
  540. /*                                                                                                                                                */3 u8 y4 S+ y/ k" i" x  O6 h
  541. /* Returns:                                                                                                                                */
    % i7 i& R" i/ ~* g. u5 J
  542. /*                byte                                                                                                                        */) w  w' ?, ^' B0 Z0 ~9 w3 q% L
  543. /*                                                                                                                                                */
    3 R/ W! e! q0 k. a4 K9 _7 ~1 d/ z
  544. /************************************************************************/1 E; S3 T* }9 T- b! l' B
  545. unsigned char Read(unsigned long Dst) ; C; b1 Z5 t* {0 d5 p
  546. {
    6 Q" N7 P' L; e  S, I0 G8 r
  547.         unsigned char byte = 0;       
    * ?- W* _2 G3 M! V! T

  548. # p0 K% s/ V4 S) L- M( m5 R
  549.         CE_Low();                                /* enable device */) A5 c  Z9 l% [1 S7 f7 o7 `# D( @
  550.         Send_Byte(0x03);                 /* read command */
    : J& Q0 t" c- M0 A2 i8 }4 z& M) }
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# I# n! ?/ ]3 d; E5 g$ z: _/ Y# K$ J
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));( }# Q4 J+ Q# n( h
  553.         Send_Byte(Dst & 0xFF);
    ! @% |( P$ V( s) A8 S4 ?/ D
  554.         byte = Get_Byte();8 ]' E6 q# T+ H" M0 d; b) B
  555.         CE_High();                                /* disable device */
    5 G1 y- O# \, X( ]+ Q8 I/ F
  556.         return byte;                        /* return one byte read */
    ! l; G# J0 y3 w% d' v1 q! V0 O  I" E
  557. }
    . r, W! a1 ~5 q& p! M3 E

  558. " J, A+ r8 f* B0 f5 f
  559. /************************************************************************/
    0 o# p6 a9 T+ f$ [, S& e4 p
  560. /* PROCEDURE:        Read_Cont                                                                                                */# K( ]# k& T# _3 ]& H' p3 Q9 K
  561. /*                                                                                                                                                */               
    9 Z( M7 C8 C+ B. y4 P  Z% \
  562. /* This procedure reads multiple addresses of the device and stores                */) F* X) }$ ~- l9 v1 @& [
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/: e- _' U6 R: E2 R) d7 H1 _
  564. /*                                                                                                                                                */# y& f: {6 [" S4 [: X. o
  565. /* Input:                                                                                                                                */  F% X9 C( I3 V7 t8 I- I' \# c6 u
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      M3 {4 ?6 p3 X6 _
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */5 A! S2 F. |: i/ E9 r: _
  568. /*                                                                                                                                                */: w& S3 E  O7 s/ E
  569. /* Returns:                                                                                                                                */+ E" P& K1 z( a5 r  O+ x7 i9 o- A
  570. /*                Nothing                                                                                                                        */4 t5 b$ x* t% o% A) G/ m+ @
  571. /*                                                                                                                                                */
    ; u8 q# `* E. g: m2 S, _+ P
  572. /************************************************************************/
    ) R5 e2 i' o% J. S  \
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    % `! o; w/ B7 o9 N7 @# D4 b7 X
  574. {0 h# B  H) e' R9 `- P/ y, z! D
  575.         unsigned long i = 0;) e; C9 W9 \) R& C. O+ h# v
  576.         CE_Low();                                        /* enable device */# v" h/ O' }0 d1 X
  577.         Send_Byte(0x03);                         /* read command */# m3 R1 r: ?& T# ~
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 P4 I8 y! m% l* {  F
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 h- D' B' [) {  j: V2 c
  580.         Send_Byte(Dst & 0xFF);" |; z; Z9 C. G$ l3 \
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */# n, S8 I2 }2 g% e
  582.         {
    ( ^( C2 e" f5 i0 D
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */% }' W- E+ p% o" k
  584.         }
    4 q2 a: n' F' ]% U3 Y1 E
  585.         CE_High();                                        /* disable device */- {# l$ W# C( t" `# o- ^

  586. # k: y' C- s8 d/ y3 `4 [$ Y5 @$ J, X
  587. }
    ! J/ W4 a- n: \. A9 ~, \) N

  588. ( B; e. i$ O: l3 F  {6 c
  589. /************************************************************************/
    5 p- L- Z) I4 u/ u, A( ^- O# E
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */0 z5 Y9 T: P2 ^& B8 P
  591. /*                                                                                                                                                */                $ J- K' q  b. J/ b
  592. /* This procedure reads one address of the device.  It will return the         */8 G4 z1 S8 J3 B" |" P& W5 P
  593. /* byte read in variable byte.                                                                                        */
    - L3 V* ~8 q+ H  g- p/ L. X
  594. /*                                                                                                                                                */% }  {6 B/ D. g# c5 q) X- N
  595. /*                                                                                                                                                */
    4 k3 k/ ?# E- b( L2 N
  596. /*                                                                                                                                                */9 R/ c1 b) g# Q: r" w# X0 c! C
  597. /* Input:                                                                                                                                */+ l, g7 a/ k0 s/ |0 J- U1 a- _
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */& c% w# M" c# o3 i- H. l
  599. /*                                                                                                                                      *// G  ]/ {9 e' ~4 b; f6 T6 e
  600. /*                                                                                                                                                */- x/ T& q! N/ m, k' W
  601. /* Returns:                                                                                                                                */" ^3 k+ Y' l3 E& l8 u
  602. /*                byte                                                                                                                        */
    1 I, L9 L+ d1 \. F) J3 |9 x. m
  603. /*                                                                                                                                                */; V" N, \2 D# d
  604. /************************************************************************/) |1 J% D0 h- B  M
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    : F% ^& q) T7 y, w
  606. {. Z# y+ _) [. N" z' @3 G& D. w* T& g4 ~
  607.         unsigned char byte = 0;        ; R" u  q2 ]$ O1 |
  608. . v) g5 ?+ D4 g+ y
  609.         CE_Low();                                /* enable device */
    8 \5 e/ b9 ?7 L3 u6 a
  610.         Send_Byte(0x0B);                 /* read command */8 T5 S, z3 A) j0 F, a2 B
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes *// c' R! w8 C$ i) H
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + U6 |: v# a$ U( N- C' z( G
  613.         Send_Byte(Dst & 0xFF);8 K2 |8 k; S, v+ @% b) g; y$ a
  614.         Send_Byte(0xFF);                /*dummy byte*/$ ?/ ~! Y, b# q" s0 e
  615.         byte = Get_Byte();# ]& |7 L: A. ]4 ]
  616.         CE_High();                                /* disable device */
      K6 P3 q1 D, M7 M6 K2 ^% B, ^
  617.         return byte;                        /* return one byte read */
    6 y# d8 g% a1 Q3 o! ~% e
  618. }
    2 U. s3 Y/ ?, K/ K
  619. - X# Y! u; C6 p0 t+ Q; S
  620. /************************************************************************/
    * G  y/ z! o: m! K# {+ P' Z
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */' t7 M  \) X- j& X2 t/ B
  622. /*                                                                                                                                                */                ; a6 g5 l  w1 [/ j1 K. S/ @  |" F) `
  623. /* This procedure reads multiple addresses of the device and stores                */; V4 a* a; R. u. Y7 E& X" R
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/$ s- A, h$ x4 ?& g# |( F
  625. /*                                                                                                                                                */
    3 E/ Y6 S3 \; q
  626. /* Input:                                                                                                                                */( B1 _* z, |7 F  \( y' D
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */8 [5 D& u" A% w( @, z; {: }7 t
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    / F) U( h0 q% M# M+ c
  629. /*                                                                                                                                                */, w# u, r0 n5 H0 {  I
  630. /* Returns:                                                                                                                                */
    3 [( L' c/ P/ d' d& b9 F
  631. /*                Nothing                                                                                                                        */
    4 P. y$ I( l$ \7 O6 I  X* e5 [
  632. /*                                                                                                                                                */1 l  c* T. p$ ~# l
  633. /************************************************************************/3 q& Q$ x0 a( L4 v+ D, J
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)! M/ ~4 J$ ]5 {1 R
  635. {
    0 ?0 T  L* ~9 z3 @( X
  636.         unsigned long i = 0;
    8 \  q! Z6 D+ ~/ P" s
  637.         CE_Low();                                        /* enable device */5 s/ d6 o) C6 K6 S8 J& V
  638.         Send_Byte(0x0B);                         /* read command */# q8 b1 V2 b# A6 m. G) }
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % d" c% O. ~2 }' l2 M
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 }8 L& `0 t( i5 s( c% |  x: W
  641.         Send_Byte(Dst & 0xFF);# n: b3 B) ?9 @2 |( r/ F
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    8 l% r' q" M4 y/ q0 P
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */8 P5 Z8 e" b0 d* d
  644.         {
    6 f, G: ]4 J8 @" n8 P$ c4 ?0 _' y
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */$ G* K4 D# X1 z( o/ b) e- F+ T1 t* Y* {
  646.         }; q/ l+ e2 A# T
  647.         CE_High();                                /* disable device */+ l5 v& _/ Y6 s* q, p" b& K
  648. }
    ; ]: S+ o/ l/ Z8 \2 S, g! w

  649. . d, n0 D! Z0 f! z; d1 k. g6 @
  650. /************************************************************************/- O2 p( T+ u/ k" [5 P6 m. q
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    " N3 d/ ^1 X8 N% g( L
  652. /*                                                                                                                                                */
    7 Z7 m1 m6 V8 a! o# _. f
  653. /* This procedure programs one address of the device.                                        */) T# y; J/ X3 S+ s' ?, x
  654. /* Assumption:  Address being programmed is already erased and is NOT        */; j8 y& q- M& s; c
  655. /* block protected.                                                                                                                */: ~8 u! G2 m/ O; _6 s9 g5 m' d4 ?
  656. /*                                                                                                                                                */
    8 \3 R1 W, B( D( c0 y
  657. /*                                                                                                                                                */
    1 V7 S* u2 G/ |; d* G9 l
  658. /*                                                                                                                                                */
    . Z/ C( K. m' S! R( |7 J
  659. /* Input:                                                                                                                                */" C7 k" i* b- ^  S  L
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# q4 h' K/ s# O. h2 Q2 p( t
  661. /*                byte:                byte to be programmed                                                                */0 v/ t* Z! ~& d8 T7 E" ]( q, o
  662. /*                                                                                                                                      */2 G0 q4 Y( I; q; b+ Y8 u
  663. /*                                                                                                                                                */2 T3 r$ R+ M! ^/ [% H2 z) ~: `- E& ^4 |
  664. /* Returns:                                                                                                                                */
    9 J6 @) K: K; C
  665. /*                Nothing                                                                                                                        */1 k) c2 ?% H. E& L& W( F1 e' g* I
  666. /*                                                                                                                                                */
    4 I( T: G- M" i
  667. /************************************************************************/
    % l$ w& H9 e! Y! q3 g. ~
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    % H! W" D3 Y. w% k# q: f
  669. {/ p5 x2 Y- U9 V$ }
  670.         CE_Low();                                        /* enable device */
    % R* ~4 w, q0 ?% ?3 l. g1 Y- U3 [
  671.         Send_Byte(0x02);                         /* send Byte Program command */' E3 B0 c) w1 R* X7 s+ M
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    " M9 c7 U3 T% t" X) ^6 Q3 C  L
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 |7 S$ p2 A5 \
  674.         Send_Byte(Dst & 0xFF);; e# E6 P/ J  s+ Q& P9 u
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    ! q7 }, m/ s7 S: O
  676.         CE_High();                                        /* disable device */$ G- k6 b' p6 \: O5 f
  677. }' a' A# n- L8 j% _1 V' e

  678. , \6 Z5 ]+ D, d4 H. x
  679. /************************************************************************/$ w$ d5 V: a5 K+ u
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */, D" h8 p! Y/ L8 t" }$ A, Z. W
  681. /*                                                                                                                                                */
    6 B- ^- P1 l  T# J2 v. ?/ `
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/" _7 b7 a/ X/ T$ U
  683. /* the device:  1st data byte will be programmed into the initial                 */
    * B( p9 H) ^# p! U! w; G
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */; D; ~: K; y( [8 J" u; T
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
      z# T% J3 b: h
  686. /* is used to to start the AAI process.  It should be followed by                 */" J# C) o( J% \
  687. /* Auto_Add_IncB.                                                                                                                */# f1 s/ S; F  i2 K) f- S
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 o5 k! u( P% S4 P
  689. /*                                block protected.                                                                                */' p! K3 p8 E! O. Z3 S3 E
  690. /*                                                                                                                                                */
    ) |2 s  Z/ K, r- v. }# O5 G7 U
  691. /*                                                                                                                                                */
    . t( Z2 @& r0 p3 n3 H- m
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    ! q' q0 a# N5 J$ @' u. u$ [% G
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    * s6 s* f; c* v+ ~( O
  694. /*         unless AAI is programming the last address or last address of                */: k8 m1 [& J% C7 A6 l( d  G) l/ z
  695. /*          unprotected block, which automatically exits AAI mode.                                */; m5 o# R* M& G4 ~( [
  696. /*                                                                                                                                                */6 S) f+ ~3 r2 a; j
  697. /* Input:                                                                                                                                */
    8 Y! U* Y8 h" E4 H9 F% m
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 Q9 W1 n; K" [7 ], K: f
  699. /*                byte1:                1st byte to be programmed                                                        *// X7 T- L& _8 Z" Z6 p0 M$ u
  700. /*      byte1:                2nd byte to be programmed                                                        */
    * j4 V( ^7 a  s- u- c2 G
  701. /*                                                                                                                                                */9 N# \5 c! p. c1 W% P% K, I+ v( [  S
  702. /* Returns:                                                                                                                                */
    ! Z6 W1 [5 ^8 I& _
  703. /*                Nothing                                                                                                                        */) O0 _4 m0 F' k5 ]. [& ^
  704. /*                                                                                                                                                */; V+ Z) S/ E; K  u! \
  705. /************************************************************************// l# f2 c2 B' ^/ `9 }
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    / Z: ^$ e4 D; L; |5 x
  707. {2 E9 B! f1 l% k2 R  S" [0 O
  708.         CE_Low();                                        /* enable device */
    - h$ W  |0 Q. d  _/ |4 Q
  709.         Send_Byte(0xAD);                        /* send AAI command */
    0 y* g( p( t* u7 `! h
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! p1 `) T# S1 _) b* l
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));# `3 w6 p# ~0 d1 q. u, D3 R/ F
  712.         Send_Byte(Dst & 0xFF);
    , d9 ]# U8 d4 s) w1 t: L
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    4 m5 ~! R6 j0 \/ Q+ ~7 b
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */1 x% [: r+ r9 _6 V: u: \
  715.         CE_High();                                        /* disable device */
    1 n0 _4 ]+ u4 H+ v1 k& o5 N& v  t
  716. }
      S3 `, y* {6 i: f2 t
  717. / [; ^8 O6 Z7 \0 t
  718. /************************************************************************/9 t3 [2 [3 i8 S: p9 {$ j; s
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    " Q0 \5 M, J* y& F7 c5 G
  720. /*                                                                                                                                                */
    3 P- g# h+ D& ?! a5 H9 }8 a! u
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/+ _( {4 v& D2 [; r9 a) k
  722. /* the device:  1st data byte will be programmed into the initial                 */
    6 ?, S% _% O9 y) f+ p% I5 {
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    3 y* T8 v" d" s8 }7 n2 i0 C
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */! q. n0 y- {0 _- P/ z* l
  725. /* is used after Auto_Address_IncA.                                                                                */$ {6 u# u7 l1 S; [4 w8 u
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    6 A! }; r7 [) P6 n7 H3 {/ n
  727. /*                                block protected.                                                                                */
    / A8 q# O" a/ B: \2 Q$ I# W
  728. /*                                                                                                                                                */& |' S) D6 W" r; M+ \9 W8 Q
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */% G9 y0 M* p8 O8 C! w  u  Q) z6 x! ]
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    : ~3 ^' }8 i% E7 q$ _, z5 Z
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */6 i+ x& i/ O# \# U' W. j9 {: P
  732. /*          to exit AAI mode unless AAI is programming the last address or                */* l4 P. H4 R% o# c  I& O& U
  733. /*         last address of unprotected block, which automatically exits                 */
    3 y: C; o3 z/ A; c
  734. /*         AAI mode.                                                                                                                        */8 T6 X6 K3 S2 [
  735. /*                                                                                                                                                */6 c, C' E* v# i1 f5 t9 h" r$ S
  736. /* Input:                                                                                                                                */' `  j" M, ^* t7 }8 J
  737. /*                                                                                                                                                */
    7 p% y4 N# s3 L
  738. /*                byte1:                1st byte to be programmed                                                        */
    0 d8 R! f" W$ p. F/ p" d
  739. /*                byte2:                2nd byte to be programmed                                                        */
    - J6 E9 n: r4 t' t: x% M
  740. /*                                                                                                                                      */
    ; Y% K8 d: Z) h5 U( s$ Q' b: P
  741. /*                                                                                                                                                */
    : A6 ~9 D1 r' z& E. R- B
  742. /* Returns:                                                                                                                                */
    , a2 D) T* O9 e
  743. /*                Nothing                                                                                                                        */
    2 j- D+ `  C7 D) h
  744. /*                                                                                                                                                */
    $ w# ^5 Z! ^& z8 h6 }
  745. /************************************************************************/$ Q6 v7 ^1 \6 j6 w) K% K( `6 t
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)4 [' c- ~) M1 f0 {* k' c
  747. {* y8 Q, S4 S/ |: n
  748.         CE_Low();                                        /* enable device */
    # i. }/ O. a+ o+ x7 A! ]6 N
  749.         Send_Byte(0xAD);                        /* send AAI command */% a/ j+ Q( j" X3 W7 {
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    / H# V4 I6 K* k$ D
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , K) Z1 e' o  ?9 Q1 I
  752.         CE_High();                                        /* disable device */
    * e* s2 ~0 _1 `& [& W
  753. }
    ) @0 A/ a8 t4 G

  754. 5 {( ^8 s+ K1 u* B8 W1 h- D$ X
  755. /************************************************************************/9 k, R+ N2 ^4 Z( S% V$ {
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */& c& c( H+ Z% l' s8 ~% a
  757. /*                                                                                                                                                */; `( ]" c8 f% b6 }: T4 O+ c! ]$ y& x
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    7 Y1 k# @/ B4 N8 m9 N
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */- `! w) _' W: L! p4 T% k2 T# b
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    2 G" g& w+ k# z5 R# C
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    # E$ k- z$ V$ z" O8 G
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */9 v1 `" i' Z4 B( E% {# M. [: `+ g
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  *// ~% Y# r( f# D! [4 G0 S+ B
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */5 H  K' \- h4 h" q, c
  765. /* Assumption:  Address being programmed is already erased and is NOT        */' c  V( C( b7 y  B  ~" K: K$ S
  766. /*                                block protected.                                                                                */
    9 W; w8 B5 v$ Z+ ~3 v
  767. /*                                                                                                                                                */' E, R0 M+ ~( K* i4 w- T! p4 r5 w
  768. /*                                                                                                                                                */# y% m. j8 n) b  \4 y; d% S
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    - f$ g* {" n% B5 o# H
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    7 j" Y# w( X! b
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */4 Q- }4 }, K9 W# E
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    : O! n6 o: K; x' p4 i$ I
  773. /*         last address of unprotected block, which automatically exits                 */! z7 |3 s3 K! X. r9 [
  774. /*         AAI mode.                                                                                                                        */
    8 L. b' L: }0 b! Q8 M
  775. /*                                                                                                                                                */
    / B% A: @+ O. C, q5 `5 n1 E- R2 V3 s0 Q
  776. /* Input:                                                                                                                                */
    , `, x' N1 o' _/ G
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & O7 E9 ]4 @0 l5 F* @) R1 @9 W
  778. /*                byte1:                1st byte to be programmed                                                        */3 ~4 A9 j# ~9 h& g: W
  779. /*      byte1:                2nd byte to be programmed                                                        */: d# i* m/ u5 i! Y
  780. /*                                                                                                                                                */
    # W$ A% Q1 ~5 ^# F3 P0 ^
  781. /* Returns:                                                                                                                                */
    ' g) p6 x( ]! E) H) N
  782. /*                Nothing                                                                                                                        */
    ; a, j  n# H# o* W7 [( Q- o! i+ R
  783. /*                                                                                                                                                */. h. o% Q* b+ T* L
  784. /************************************************************************/
    0 y% I+ \/ j, G% o7 X& E
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    % M  c* B' I, t" i5 m7 l
  786. {
    1 t" u1 }0 `9 d6 ]+ v
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        5 T* ]3 g9 ~7 r% u) k! H

  788. 8 R& ^, q& g- }, \6 T: [6 @
  789.         CE_Low();                                        /* enable device */) ^. X! c# K) V
  790.         Send_Byte(0xAD);                        /* send AAI command */# z$ E: G0 K( |+ C) R# Q; T: a
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( e+ z1 N3 E' F3 Z# s
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));: i. m8 }  [  n1 O: c
  793.         Send_Byte(Dst & 0xFF);
    6 t2 d5 K; i: S4 J# w9 k- k8 F# e
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    7 Q, f6 ?1 y1 ^4 O
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    * f' L7 l5 P4 C8 I5 `+ _# `
  796.         CE_High();                                        /* disable device */
    % L9 W4 f% N. `5 f6 r
  797.         2 _; Z0 [" D# h1 p' }& a8 k# U
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    & Z! t. R1 _' n
  799. 3 e% D3 S, C% w, {7 R
  800. }
    9 k1 }) v5 N% K# L/ l9 K2 |) R9 d
  801. . K# v; M% x8 o- `
  802. /************************************************************************/+ z" u0 H9 m/ f
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */2 B7 g' v" S& h0 `
  804. /*                                                                                                                                                */
    ) S; ]' k2 A" A+ y/ U$ }9 c
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    9 M8 ]5 P4 M+ Y0 T; I0 W
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    0 @. V: ^# X2 {  v) W
  807. /* AAI programmming is completed.  It programs consecutive addresses of */3 o* ~' S$ K* o* _: G: V: F( G& u* Q
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    / @. f+ [3 g% B) L; Y$ [' Q0 f
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    / e/ T) S% @9 Q: R. J' \
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    ( C0 H" c' P1 f! L8 h
  811. /* used after Auto_Address_IncA.                                                                                */
    ( [3 B# g& |3 j- c$ L# D
  812. /* Assumption:  Address being programmed is already erased and is NOT        */. \8 s; u0 t8 W9 ^1 k, ^+ w4 p& `9 K
  813. /*                                block protected.                                                                                */2 i( N/ @4 Z( d7 r; e
  814. /*                                                                                                                                                */
    5 n; r0 g: K5 z3 A1 H
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    $ }6 C# B- _2 X0 H/ w7 B4 z) r- q5 f
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */9 e2 T1 B8 C7 k5 L
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */- V' ~! H, P: X$ ~% v8 d  D
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    3 n) A5 l+ t; b  L1 z; E
  819. /*         last address of unprotected block, which automatically exits                 */
    / b( n+ k3 k- Q/ U6 I5 D
  820. /*         AAI mode.                                                                                                                        */# k6 Y% H4 z/ B8 S0 W! q) u7 n
  821. /*                                                                                                                                                */: ^0 ]' @: k0 K
  822. /* Input:                                                                                                                                */' l- E  q4 [# r1 L2 o- y
  823. /*                                                                                                                                                */, r" f' _, @9 T
  824. /*                byte1:                1st byte to be programmed                                                        */) s' n' O: `+ Q) s6 e( s
  825. /*                byte2:                2nd byte to be programmed                                                        */# K" K1 G# N0 h% j: H4 s4 `* Z/ @7 n& y
  826. /*                                                                                                                                      */
    3 C9 O) @- _7 u( T0 N/ Z: Z
  827. /*                                                                                                                                                */! N' U7 v: E  l$ v
  828. /* Returns:                                                                                                                                */
    " |  B. f$ ^( _1 {- u1 |
  829. /*                Nothing                                                                                                                        */1 a8 b' d! w; B
  830. /*                                                                                                                                                */
    : i8 f& T& M0 n7 Z! _3 h' j6 l
  831. /************************************************************************/
    " w5 D& F$ M5 U& I6 G4 x
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)( m9 h# {, T% ?/ n1 S- f' O/ O0 m
  833. {! @6 c. q  j+ {- _. ^% w
  834.         CE_Low();                                /* enable device */
    * x! o0 [& o5 W6 y! n
  835.         Send_Byte(0xAD);                /* send AAI command */  i7 N- k7 P3 s6 T, B% y& E
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    0 u: V: J9 P; F/ }+ P4 I
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */! e1 c. K' |% t% D
  838.         CE_High();                                /* disable device */
    6 m) U1 t4 n6 v$ |' e; H

  839. 6 p* c  r, o7 g6 h
  840.         Poll_SO();                                /* polls RY/BY# using SO line */! P9 V1 C7 J, k' ^" l* K" p
  841. " Q& i& G' n# r8 D. r* |
  842.         WRDI();                                 /* Exit AAI before executing DBSY */' T- `; y& R* H
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */; l; p; \% R- i# I" N
  844. }
    % z7 F2 ?0 z% u/ u* E; T
  845. $ L6 B/ F4 g$ R
  846. /************************************************************************/* D2 g7 J- R7 W" A
  847. /* PROCEDURE: Chip_Erase                                                                                                */' D5 L" l' X% D7 r& J- C* k
  848. /*                                                                                                                                                */
    7 t( g0 h$ g. F
  849. /* This procedure erases the entire Chip.                                                                */
    * E3 s+ F0 v; |% D/ p
  850. /*                                                                                                                                                */, ]  r5 |5 \$ I  D) V( Z( F
  851. /* Input:                                                                                                                                */1 L! T# O3 \( A! ?" F* x
  852. /*                None                                                                                                                        */8 B4 f5 C! M5 w$ s
  853. /*                                                                                                                                                */& j' q0 e. L2 J* O2 p: g, z1 a
  854. /* Returns:                                                                                                                                */
    , t- [" }; @0 d' b/ R3 P+ o0 N
  855. /*                Nothing                                                                                                                        */
    # T) d' ?( w; z6 ?
  856. /************************************************************************/4 v, n, {2 R5 n! |+ {
  857. void Chip_Erase()- h8 k$ V1 A3 V, f, I4 Q& Y+ e+ D
  858. {                                               
    ) T4 `1 y$ ~; G. S1 K
  859.         CE_Low();                                /* enable device *// X  ]; |, q# f4 `( J! K
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */: Y$ o% A& H9 m) s
  861.         CE_High();                                /* disable device */
    : [: k/ h$ T# B5 [, b, Y
  862. }
    ! P+ p4 c* h3 n  f6 Q/ }; @6 h
  863. 1 U6 B+ ~+ {! o' v3 b* i' S4 p
  864. /************************************************************************/; a1 @  O; _3 G5 D4 r& o
  865. /* PROCEDURE: Sector_Erase                                                                                                */% \7 g* A/ N+ Q. k% U* |, F! Y
  866. /*                                                                                                                                                */0 Q, X8 G) I: o2 y: U  j
  867. /* This procedure Sector Erases the Chip.                                                                */- t$ y: F' P6 M0 J9 I$ Q" I' S
  868. /*                                                                                                                                                */- W" P& \5 E& k) u  f
  869. /* Input:                                                                                                                                */
    , g  a4 V3 N) [3 x3 `
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      Z. X* T+ g8 z
  871. /*                                                                                                                                                */3 {, ^. n" A' Q8 I! x
  872. /* Returns:                                                                                                                                */% \0 p, D- g! s7 o% g
  873. /*                Nothing                                                                                                                        */
    8 |7 O$ @0 Y+ ~% Z) f' I: v. G
  874. /************************************************************************/
    , ^4 S9 Z* I: z! I
  875. void Sector_Erase(unsigned long Dst)) c  |5 e* a8 m2 ^
  876. {, k) T* t! w  k0 i% }5 V+ F: p- [
  877. / P+ k. U5 e! w! n
  878. " @) j" N* H3 e# |6 k, z
  879.         CE_Low();                                        /* enable device */
    6 k& j, U% Y: c# x  y
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    ) w2 J+ ~, E* w& F
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' B3 g* t  h& a3 r
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));  g1 B, g; K- c3 P. N
  883.         Send_Byte(Dst & 0xFF);' Z4 ^, H9 O7 b( k
  884.         CE_High();                                        /* disable device */
    6 F6 p/ |5 g9 T! Z5 j
  885. }        + R2 n  k, B) d5 {( `
  886. % P2 W0 g+ G6 V  b4 v, x! O5 H
  887. /************************************************************************/
    . F% U7 ~3 G; r3 a  _
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */! [0 w( \7 x; o1 j+ j, G; x
  889. /*                                                                                                                                                */" N; r+ @: ]7 v& }/ d' i' l
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */8 v+ U- ~* N0 [
  891. /*                                                                                                                                                */' g: `2 d1 n% F5 X: I
  892. /* Input:                                                                                                                                */
    2 m; w# m8 c6 Q& g
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! ~/ U3 V% e' l+ o
  894. /*                                                                                                                                                */
    $ w  F3 h* `- {  |% {+ b( a
  895. /* Returns:                                                                                                                                */2 q$ N% I+ T) E8 [7 s
  896. /*                Nothing                                                                                                                        */
    : I! ?7 D; h. ?% B5 P
  897. /************************************************************************/" M" B+ R- Y/ o& R: J
  898. void Block_Erase_32K(unsigned long Dst)
    8 d. k* n0 ~: D, ]5 @4 E
  899. {
    + r# @- D% a. e* p- O5 [
  900.         CE_Low();                                        /* enable device */
    ; R. D" h, r3 u9 ^: q# W: j
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */; T) f$ G& z9 ^+ d
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # c9 J: t0 g  Z- a( H6 T
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));3 n) s7 s; p* \8 N% c7 j" [
  904.         Send_Byte(Dst & 0xFF);
    1 b( H% w0 Y+ a' z# V% C
  905.         CE_High();                                        /* disable device */2 \3 I9 F/ W) z: _+ P3 d/ ?
  906. }4 Z' S6 K- k: A/ d9 B) J

  907. ( _9 c+ W7 E" m. c, T7 |# m
  908. /************************************************************************/
    ) z: A/ ~) B3 m" D
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */. p7 b( i$ G* g$ }, u
  910. /*                                                                                                                                                */
    - V; x$ _1 X& {9 M+ {4 ~: m
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    * ^2 b" ?3 k5 x3 Y3 Q
  912. /*                                                                                                                                                */
    2 z: [3 Q4 S( d: r, L( C
  913. /* Input:                                                                                                                                */: F  _  }2 t# d  a% k% F, }
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( m# y' K5 Y4 Z. e* ^: n- S
  915. /*                                                                                                                                                */+ m* d! s3 G7 J# L( `! `
  916. /* Returns:                                                                                                                                */$ n7 \& _/ N/ P5 |5 J, D
  917. /*                Nothing                                                                                                                        */5 p9 i8 w( F0 n" _' g7 k
  918. /************************************************************************/' T9 T/ K$ Z3 s6 s8 `
  919. void Block_Erase_64K(unsigned long Dst)
    / R1 c: Z3 `* T" w1 B! q
  920. {; P: n" z; {0 W- B
  921.         CE_Low();                                        /* enable device */
    ! m6 g5 q+ Q* F4 _
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    8 J) s* s; O) ?; ~5 _9 Z
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# M3 y1 t/ H# h6 j& @: F) v& f. b
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));5 `/ I8 W2 g! [* C) V1 e' y7 w
  925.         Send_Byte(Dst & 0xFF);
      k* X/ ?) _6 M, @5 c. B& V
  926.         CE_High();                                        /* disable device */6 A& @1 i$ a7 U. A" x
  927. }
    / D. F* F) v- x) d# e1 i0 i0 R
  928. 2 i. d7 l* I9 [+ Y6 J
  929. /************************************************************************/) `) x0 ^) g' J# j
  930. /* PROCEDURE: Wait_Busy                                                                                                        */9 Y+ h# x1 q, H2 {& O9 G- A
  931. /*                                                                                                                                                */
    , T5 O9 s+ l3 r& @. j% R! M; Y
  932. /* This procedure waits until device is no longer busy (can be used by        *// y9 b* ~3 L0 z6 j' G8 [
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */4 \# [! r/ z' K& F: D
  934. /*                                                                                                                                                */
    - l' t# ]  J0 ^% K
  935. /* Input:                                                                                                                                */9 ]' F" E' \5 M: {
  936. /*                None                                                                                                                        */
    6 }0 v9 I6 V0 E5 D/ n
  937. /*                                                                                                                                                */6 i' X1 x/ G- ?: e: X2 h, Y
  938. /* Returns:                                                                                                                                */
    . `. i$ ]' `4 r& L. @  `: h( c
  939. /*                Nothing                                                                                                                        */
    7 O& e/ K! O. E# |
  940. /************************************************************************/" G  P3 i/ s) E2 b7 y% [, J$ \
  941. void Wait_Busy()5 z: n" l7 X3 u& J' c- Q- p8 Z
  942. {
    7 @# g5 J( a% {+ b- T* l& l/ y
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */* U+ N; j. l$ z5 ]
  944.                 Read_Status_Register();- u% |. C6 z& x8 a& P; K5 A9 j
  945. }
    8 |) c1 J1 g. n  g$ u. k1 k! F/ Z/ v
  946. 1 {9 s. k& |" T; f8 K+ M
  947. /************************************************************************/2 I2 R; W& ]: E
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */, M8 y  U( p2 {, r& d
  949. /*                                                                                                                                                */
    3 h& s  z9 m; P5 ^- T
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    + a3 d  U' t1 V) M. y% u
  951. /*                                                                                                                                                */
    4 w( b2 I$ n" [7 i
  952. /* Input:                                                                                                                                */1 Z) o& r- ^& e( u
  953. /*                None                                                                                                                        */8 F: n2 t( N% Q" [. r7 P/ n- ]
  954. /*                                                                                                                                                */8 S1 F% _$ e# v; y
  955. /* Returns:                                                                                                                                */
    - j9 M( L9 C3 j% ]4 X  q4 }
  956. /*                Nothing                                                                                                                        */' Y: t* u9 a& q8 J! D
  957. /************************************************************************/
    6 S! Y9 _7 @; x# ~% H& _( ]+ Z
  958. void Wait_Busy_AAI()
    4 d; D( |6 G7 z: w
  959. {/ U& r1 ~$ C1 A  x# V7 E6 @" H
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */! |# Y' F1 ~" i
  961.                 Read_Status_Register();
      F" p: f9 `9 z3 o
  962. }
    - L8 ^% Y: s  u" }# l

  963. * Q( g7 H" Z' T/ |& s/ M: w. p
  964. /************************************************************************/7 ?) a( }# [4 ?
  965. /* PROCEDURE: WREN_Check                                                                                                */. D" Q7 T8 o7 R# y  I$ w  z+ c. W
  966. /*                                                                                                                                                */
    4 i) b, \8 U5 @/ g) n: E
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    ' z7 w7 n# j+ O. i1 a* b: O( r
  968. /*                                                                                                                                                */" y" v! c  F/ e) S
  969. /* Input:                                                                                                                                */
    # a5 U" p( S  P* w7 J  ~) X
  970. /*                None                                                                                                                        */( K. e; `- O) q* }; |3 Q
  971. /*                                                                                                                                                */
    9 p5 P7 s: x, D# A7 d+ m% m* q' U
  972. /* Returns:                                                                                                                                */) ^  @( U( \3 o# z" G& T
  973. /*                Nothing                                                                                                                        */) b; V7 ^5 e2 R& J1 h. h
  974. /************************************************************************/
    + q4 }" O5 Q+ D& K: D
  975. void WREN_Check()
    6 h3 o  p% f2 X: e
  976. {0 @3 w- N. K. t# R
  977.         unsigned char byte;
    $ h. R3 t$ Z$ W/ X. R9 A" p
  978.         byte = Read_Status_Register();        /* read the status register */
    1 ?/ r% z  h2 L# k. Q
  979.         if (byte != 0x02)                /* verify that WEL bit is set */% O, X, a! n9 e" U+ E/ i/ V1 N
  980.         {# g) |# h1 ^* N& t& i4 ]0 F
  981.                 while(1)1 L3 }! G( S; Y/ h
  982.                         /* add source code or statements for this file */2 v+ N5 ~# \' h, h4 M! r& d% E& i
  983.                         /* to compile                                  */
    * s4 D  E- u( c8 [3 W/ l% S
  984.                         /* i.e. option: insert a display to view error on LED? */
    : B; _$ ?2 V( U5 b; U1 d6 H1 b# M
  985.                  ( G/ H/ v4 u5 p1 m
  986.         }/ h* M8 v  N/ J9 Q* V' d+ @
  987. }- l& Z5 P8 ^, n& ^; S4 T4 o

  988. 9 \& g- V( T5 @4 Z+ t: w
  989. /************************************************************************/' N7 Z7 |6 D5 H( f* [8 n2 b7 T
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    2 K1 d9 V% ?  r' \7 D3 |
  991. /*                                                                                                                                                */
    7 {/ w- `" n" z9 a: G0 |! P2 U
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */2 l9 ~7 T$ w. J3 ?. s
  993. /*                                                                                                                                                */& H  w0 w/ O/ Z. O: A' D9 I
  994. /* Input:                                                                                                                                */5 g1 S- ^0 U9 T
  995. /*                None                                                                                                                        */; p& f9 k/ g. B
  996. /*                                                                                                                                                */
    3 a' L  J. t1 k( Q# ^& }
  997. /* Returns:                                                                                                                                */
    5 m: Q" O4 z! R
  998. /*                Nothing                                                                                                                        */" N1 Y) @* f' @
  999. /************************************************************************// d) d$ ~7 z' E
  1000. void WREN_AAI_Check()0 A2 I* b, }/ f2 U( ?" C: s$ y
  1001. {" a" {0 @/ O/ S9 t1 k9 r: O2 z, ^# s
  1002.         unsigned char byte;
    0 }  n) `2 `4 ]) K! l
  1003.         byte = Read_Status_Register();        /* read the status register *// M( F6 ?! T4 {% }) ]$ I
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */; a' F- H! X9 t0 j8 i" D
  1005.         {+ X6 |. a" f( a" w9 x# [
  1006.                 while(1)               
    0 r9 r$ ^* o' N/ ^
  1007.                         /* add source code or statements for this file */
    - }% G/ o, y. R- H) m* o6 `/ j1 [
  1008.                         /* to compile                                  */1 @5 ?" `% U1 c* [) N
  1009.                         /* i.e. option: insert a display to view error on LED? */
    + H; K* A# L; D

  1010. ; c$ z. H6 `- f# G& L
  1011.         }# v4 k& o9 B) R! T0 L5 }
  1012. }
    6 {; `! l+ [  y

  1013. 1 d+ _, Q- H8 T) e* `9 M' f
  1014. /************************************************************************/) `2 f" F' |" j- t" w7 l) }
  1015. /* PROCEDURE: Verify                                                                                                        */
    : H; `# I+ g$ a2 b0 |! X" G
  1016. /*                                                                                                                                                */$ _, y5 P; K2 j/ q. B- b9 ~: k
  1017. /* This procedure checks to see if the correct byte has be read.                */
    $ t0 ?3 ?/ T0 }
  1018. /*                                                                                                                                                */
      W& [  i' C, @
  1019. /* Input:                                                                                                                                */
    3 \# P( f: F: ~; v0 j7 v  r8 J
  1020. /*                byte:                byte read                                                                                        *// R; {" V& \+ e+ r- g
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    " H; J) T) q  i7 J& w# d4 k- l7 o
  1022. /*                                                                                                                                                */
    ! @; ^/ t) k( [, r/ F% R3 T3 b
  1023. /* Returns:                                                                                                                                */
    % H2 a9 Y- q% D& \+ \+ @7 w" r* d
  1024. /*                Nothing                                                                                                                        */" j) }0 ?. N0 @# f9 m# b
  1025. /************************************************************************/
    ! T1 n  b" e+ |# `4 {) j$ E$ K
  1026. void Verify(unsigned char byte, unsigned char cor_byte)( ]2 H* C* _) Z- j0 H& S" h4 P' U
  1027. {: z3 D, n5 f, v7 W4 t5 @* W
  1028.         if (byte != cor_byte)* [6 ?/ g! H. I5 Z; L, e9 d6 b1 V1 M
  1029.         {1 T) Y7 B! m' W# s2 u1 O
  1030.                 while(1)' D: e* r4 s2 y# D" @1 Z1 i
  1031.                         /* add source code or statement for this file */4 M8 t8 w$ \6 _5 ]3 v
  1032.                         /* to compile                                  */
    ; }$ g8 X* t4 g% }
  1033.                         /* i.e. option: insert a display to view error on LED? */2 n  X; r1 h2 u' F* L
  1034.                
    / r8 P3 [8 i. c9 l0 x$ Y) V
  1035.         }
    ! L5 z8 B8 M6 p% |/ K# l3 _) r
  1036. }6 p# Q, `2 s  q/ ^3 y6 S% E

  1037. & ^3 w0 A+ s# G+ c+ M* `4 J5 J- L
  1038. 1 n- Z& S& C6 w7 I1 p
  1039. int main()2 L2 H8 |8 j& E# x, q+ m
  1040. {
    . Y7 Y% W1 g) y

  1041. / i; r; c1 O5 F! \0 E  u0 X1 Q
  1042. return 0;% e! B7 g; e' ~9 o1 M7 q" K
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
/ I8 M4 \8 M! G" u   main()4 P2 q# Q3 c9 Q. R8 c1 X
   里面怎么是空的呢?
, q% B5 X/ r- ]6 J3 N! Y: T0 g- }  N   发一份给我吧9 J" x2 r# j' }: @, i1 ~$ F% x
mail:luyijun2005@hotmail.com
" {( T. K9 n, l( F) ^" g4 A$ x7 U咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
2 k+ t' M- \$ q. P, j3 {4 m- x! r% _
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
& ^2 I+ r' d0 N$ Y$ fEC的代码在哪跑,你看DS的说明,每个EC都不同的。
% \) B: X# i9 s2 @# P4 e* S/ BOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?0 S# X* `; X8 M/ A" K
上面几个问题是你没看任何东西而白问。
$ _4 O3 Y( X7 H# F9 m2 r6 |7 g
4 H6 E% u! S( ]4 L4 a7 p; c+ g至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
+ B. e5 B4 V+ }. w+ f
! W7 l7 {- p# b关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!& r. y3 T+ Y: ^) R0 k7 M, u- A8 \
" D' U' w7 E* d8 U4 f& W" f
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
3 j, G2 s* P  D% R; X" d* l5 u. O4 o% m+ }3 [$ W$ H* d# }
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...& _# Y2 f; ^3 J+ [4 T, G: _; B
6 W1 Y* \/ s2 Z8 u* G
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样4 ?5 }- M2 ]1 A# ~
似乎要把SPI能support 到最大,这EC chip应该有好卖点
: P, q& {+ l: c5 c- g* QBIOS功能要不要强大,也就决定了SPI Flach的大小/ k5 b2 b# @- [% I2 x0 ]* H; j
我是这么想的~让OEM去决定要挂多大!8 F( N: E4 X% _3 x% W  ]0 d
如果我司有BIOS工程师就好了~哈
' {0 X- A  S6 [4 T/ F% f! mWPCE775应该算很新的东西,来看它支持到多大?9 y5 Q- \9 D" b# h
9 L$ o+ g: _; M! D$ M  s0 @& L
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte7 T, h1 N0 t9 D) p* L2 @3 n" {6 i9 G
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
9 v, ?# J) r4 F! x, [- C# l" j9 Q$ E
这份driver收下~希望以后有用到7 ~1 g/ M) {6 \
谢谢bini大大- H2 s  v+ {8 n+ ~5 }) w7 ~

* s; O3 h/ L  p很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

发表于 2009-7-18 15:16:34 | 显示全部楼层
我也有份汇编的DOS下的烧写代码,SST 1MB的 flash可以用。我不知道为什么AFUDOS为什么不能工作,AMI好象没有发送94 CMD下来,AFUDOS直接就说不支持。搞的下BIOS非要自己写个程序,烦的很啊。
回复

使用道具 举报

发表于 2009-8-13 10:59:30 | 显示全部楼层
前端时间小弟也在windows系统下写了一个并口到SST25VF080B的烧写程序......
回复

使用道具 举报

发表于 2009-8-17 16:47:36 | 显示全部楼层

这个函数看不懂Poll_SO()

void Poll_SO()
3 X* u/ o. x4 v{% k- H4 o8 |4 r. K+ S+ E
        unsigned char temp = 0;
8 Y) c8 K% }, h$ Q, }        CE_Low();5 p1 J# ~  G0 p+ s( d
    while (temp == 0x00)        /* waste time until not busy */. [0 k# _& o8 u/ i; u+ x& t
                temp = SO;
' a8 _! v0 X# R        CE_High();
& \* D: Y, ~7 x; K}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
( Q% A2 f  l$ \1 I, I6 K/ s+ g/ g9 L5 t{
0 D8 H6 [# j8 q- |" H        * Q, q7 K5 [1 ]6 [
        unsigned char i = 0;0 G* n4 |: B4 M5 e0 G' q
        for (i = 0; i < 8; i++)
% H; y) Q& C" w( E! J4 _        {
8 ]5 B3 L! ^" J+ X                : H7 C4 l+ i# n, f' `* T
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
. Q$ z1 b4 x+ ]- |0 k                        SI = 1;
' L/ P3 u' d6 N/ U, T' f                else
7 a" j( N# t8 y2 k: ^' F1 {                        SI = 0;                                /* if not, set to low */8 D# U- B' v4 L
问              SCK = 1;                                /* toggle clock high */8 A& @# w/ N! b
   题            out = (out << 1);                /* shift 1 place for next bit */" c  e  Y$ p; L0 t) k& _; w
                SCK = 0;                                /* toggle clock low */# H; M) X! T6 y/ k
        }
' r1 i' b/ t$ i3 ~" c0 d2 F}
8 }3 G( [5 W: O/ I8 [. o 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-2-19 06:22 , Processed in 0.049096 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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