找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55338|回复: 13

[Software Driver]SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver
    4 n( t& x+ N; ~/ }
  2. % g& R- t$ R# _( F
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    3 M: e) `9 y5 V
  4. # {0 p  s1 {9 Y, @1 \  r  E
  5. November 4th, 2005, Rev. 1.02 b9 D) A1 H2 O+ J! f9 r
  6.   V* U% x+ x5 Y' }
  7. ABOUT THE SOFTWARE
    & F: C( \8 h4 s  Q+ G) g9 n
  8. This application note provides software driver examples for SST25VF080B,
    & H  u" A. E, U4 E1 w
  9. Serial Flash. Extensive comments are included in each routine to describe
    4 r/ C8 i& \( z& t4 a; P, Q
  10. the function of each routine.  The interface coding uses polling method " l/ |; t; x, j/ u% [
  11. rather than the SPI protocol to interface with these serial devices.  The
    # s9 r1 g# h9 [; T% f, i+ Z
  12. functions are differentiated below in terms of the communication protocols+ \5 r  H' i6 g# l% N
  13. (uses Mode 0) and specific device operation instructions. This code has been
    " `* F* s& v2 ^7 `
  14. designed to compile using the Keil compiler.
    9 ?3 I0 P% E7 y3 l4 J
  15. ( m' q6 w& s( w! a! y

  16. % c: H2 |. O( y8 i3 V/ W
  17. ABOUT THE SST25VF080B. t4 \- s/ G9 s8 a/ m/ M8 N
  18. ; Y; Q: G) u+ D7 T" m
  19. Companion product datasheets for the SST25VF080B should be reviewed in & T5 k* K/ z( {
  20. conjunction with this application note for a complete understanding % y: H- n0 K5 _% \
  21. of the device.
    5 U2 ]3 \8 R, j) ~5 a

  22. - f) G' m6 o! b0 J( P) w

  23.   ]8 I; Z' t- `  [5 z2 H, A
  24. Device Communication Protocol(pinout related) functions:+ ]5 Z* S6 E. ?
  25. % o8 q, x/ F- h6 H; f1 C! w! x( |
  26. Functions                                    Function$ r( }* j2 ~+ j8 Y5 x6 M
  27. ------------------------------------------------------------------: I7 z1 T. z/ s! l4 A6 D
  28. init                                        Initializes clock to set up mode 0.
    0 j; B# n- K+ A% p% x8 ^
  29. Send_Byte                                Sends one byte using SI pin to send and / o% W5 M: ~1 c4 g/ k
  30.                                                 shift out 1-bit per clock rising edge0 X5 ]/ [9 |7 s( h  H3 j' M, n
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    ( g3 E. {5 z; Z7 G: o& u
  32.                                                 in 1-bit per clock falling edge
    / ^) ^9 N0 g/ N" d% x) ~- H% a
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming( _% M, @/ j9 U/ B* z: G
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high" D) d$ K0 q8 I* g* R5 ^( w
  35. CE_Low                                        Clears Chip Enable of the serial flash to low  c! G$ B% d- r8 z. `0 {
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    ! T& N- S7 l) ?( E! @6 O4 c
  37. Unhold                                        Unholds the serial flash" {& a' O  J/ Z! K9 x
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    0 x: h6 |& n3 T
  39. UnWP                                        Disables write protection pin
    ) r& w8 |0 x5 r5 X9 }

  40. + G' O$ m) d/ o; i1 t7 T, y
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code' w/ X, E1 r/ x) |. @
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your7 M8 n9 |5 \% b; J3 g: t
  43. software which should reflect your hardware interfaced.          + X% A9 B! T+ l1 U- W) f
  44. # |1 `- p+ u; n) A: `
  45. 0 X+ e" H" l6 P+ {! J' h3 j
  46. Device Operation Instruction functions:
    ' `2 I+ T7 h6 d
  47. ' k- U; z! z' m+ X' M# ~
  48. Functions                                    Function4 n1 [1 I% J- \, J3 g$ H9 T7 B9 ?1 L
  49. ------------------------------------------------------------------2 q% _% t: ?+ n: m: s2 g$ N
  50. Read_Status_Register        Reads the status register of the serial flash3 }+ ]% W5 l- a3 [+ c6 _5 x
  51. EWSR                                        Enables the Write Status Register
    9 Y3 Q2 |; L& n! `2 ?. c
  52. WRSR                                        Performs a write to the status register0 W  u7 F2 g" g
  53. WREN                                        Write enables the serial flash9 L: {) F0 J1 E2 M
  54. WRDI                                        Write disables the serial flash
    * c/ t+ `3 e. U) B+ P
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    / Y9 o" r2 Y) x& S8 e
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    ; |" x  w! f% H) b2 u* F4 T/ G9 K3 U
  57. Read_ID                                        Reads the manufacturer ID and device ID
      ^! V7 K$ {3 A5 \
  58. Jedec_ID_Read                        Reads the Jedec ID3 q/ z9 \7 Y1 _' w! n: H. u
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    1 D3 O3 s! B- c. F( f- w; P( ~
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    " M7 j4 c% Z: d; I( w# M
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)- x3 u1 g0 l$ w" N9 L6 Z
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    1 i, n; {( Z5 v& ^  j, I" C
  63. Byte_Program                        Program one byte to the serial flash' a1 Y+ c% h# {4 ~( s* d! W3 l
  64. Auto_Add_IncA                        Initial Auto Address Increment process0 g6 ?6 n5 Z& D- Z: i3 x
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    " G- _8 {) ]! ]8 S$ R
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    # G+ o5 M8 w8 H7 ]# q  R
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    ' I7 ]& \9 a  E" i$ r
  68. Chip_Erase                                Erases entire serial flash
    " a" [' Q1 j9 t) D
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash# b8 y( F, M1 X% w' g" w7 i
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash; {7 R. j% J8 P
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    ; B2 H; F' x" N
  72. Wait_Busy                                Polls status register until busy bit is low
    ( Y& @1 L. R% A* i6 s5 Q6 @
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming% m$ t% A/ J5 Y# @
  74. WREN_Check                                Checks to see if WEL is set5 X% a( ]4 w/ D
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set" t- e6 J8 h2 V& x9 W- h
  76. 9 Q8 c* g) h& \& R5 ^
  77. . G/ h. U5 m( j) F2 L. w- W
  78. + F7 }# Z/ A5 N- N6 ]+ i( S
  79.                                                                      
    ) x: L& c: S2 c$ r; @5 T
  80. "C" LANGUAGE DRIVERS
    * V1 l3 @1 [( t- a

  81. 0 @/ v  n7 Y  m; x2 ^9 _! Q# B
  82. /********************************************************************/
    2 b. @% U  r6 I' q
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            *// ^6 F% J/ q; a9 i: @
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    ( i+ E. P: v2 n, L7 {
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */# @' s. U; J4 e& P2 F. g' U
  86. /*                                                                  */% b2 w. a+ ], \/ f+ x
  87. /* Revision 1.0, November 4th, 2005                                                                          */   & k! p& y* e, D* T) s$ J
  88. /*                                                                  */  p; L; g- G( {
  89. /*                                                                                                                                        */2 O3 W! B: q- h; Q6 O" Y
  90. /********************************************************************/- O) ^' i& _; y- f3 C+ Q
  91. ; I* h5 S0 A  G1 L* M
  92. #include <stdio.h>! ^4 o5 H  w+ ]6 u$ m- F* K
  93. #include <stdlib.h>5 o; T2 w6 Y; E* B: k. s  L4 E& ~

  94. 5 [9 l8 v/ t9 ~. C" B
  95. /* Function Prototypes */9 d; `* J* J0 J6 Y

  96. 4 ]; _1 g4 t; c% V, A
  97. void init();
    " C% X& y# n0 M7 @5 E: `' L  N8 F
  98. void Send_Byte(unsigned char out);+ V! a6 p* N  x( T/ X
  99. unsigned char Get_Byte();
    5 w4 c. u" N% M$ k- O( [% ^
  100. void Poll_SO();
    ' o6 K! R5 }2 k3 F9 e0 N9 k5 u
  101. void CE_High();* X) E: x  \" ]/ |
  102. void CE_Low();- k( w7 e" c$ U( Q0 p' O
  103. void Hold_Low();
    7 Q" h0 r* L, U2 s% n! W
  104. void Unhold();' m' J7 m: R4 P! v# z5 R! C
  105. void WP_Low();, b& Y! {3 S* B8 \/ t
  106. void UnWP();6 _" ?- a/ R& U. s
  107. unsigned char Read_Status_Register();- A, |8 P9 m4 D) V/ Z5 I0 {
  108. void EWSR();2 T+ o3 e# o, [
  109. void WRSR(byte);
    , F9 n# k0 Z# F3 p5 |
  110. void WREN();! y# E% s) U: z2 ?
  111. void WRDI();
    ) ^( T8 T. \% B3 m' @, S9 {4 n- b. T
  112. void EBSY();# L/ o& y, u. z* W2 h2 c6 {+ v
  113. void DBSY();2 H# ^2 p7 B% M# C5 f3 P. W/ s
  114. unsigned char Read_ID(ID_addr);2 a/ K6 B& F$ H3 d8 v
  115. unsigned long Jedec_ID_Read(); # Z. P9 X* C2 |: g: q8 y& X
  116. unsigned char Read(unsigned long Dst);  z1 B( I3 w6 r( Z
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);* F3 {  l+ N% R, s! l
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    # }# K& l( z1 T, P
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    8 d1 L) X& q( _: k# Q' H
  120. void Byte_Program(unsigned long Dst, unsigned char byte);/ x+ T( ~" g6 ~
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);$ v6 D1 i& r/ G! E! m
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    * g) p( s2 e# ^  m( p; u6 r
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);8 M% u, B2 V' w2 f+ X4 E" _& ~
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    & \$ C5 N( `& e9 w
  125. void Chip_Erase();
    3 O9 |  N7 N' y( Q1 f
  126. void Sector_Erase(unsigned long Dst);/ @  Z' t5 J/ H. X
  127. void Block_Erase_32K(unsigned long Dst);: v  B8 w+ g0 }; C+ w  }
  128. void Block_Erase_64K(unsigned long Dst);
    - ?2 m, a! h! X$ B- [  ^2 I5 O* a
  129. void Wait_Busy();
    1 M+ J; ~& |& _
  130. void Wait_Busy_AAI();) _6 \' Z/ v3 l1 P  X/ G
  131. void WREN_Check();! J5 X" H# i; ?: P
  132. void WREN_AAI_Check();
    . `: `8 q2 U& \/ w' G; F( N

  133. & L; I  C' r0 a. T4 S: ~8 {4 [
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    6 A: @# m: F3 u  Q7 X( ?% o8 G* J

  135. ' B4 N4 ]* ]: k; f% ]4 M9 p# p  M
  136. unsigned char idata upper_128[128];                /* global array to store read data */1 e3 Y9 x8 \; G
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    9 v4 z7 u; ~3 F* l  a) _

  138. 9 e/ b0 W: y+ v* L7 L& r7 a
  139. /************************************************************************/0 P$ S$ T; M+ t0 j
  140. /* PROCEDURE: init                                                                                                                */
    7 l# `# V" O. e( [/ E
  141. /*                                                                                                                                                */
    3 B; r7 ~- a9 w6 Z; E$ y
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    8 h0 G5 m( A# f' C% V1 d, P1 h
  143. /* setting up mode 0.                                                                                                        */1 u4 s7 e/ D  A; B- Q
  144. /*                                                                                                                                                */& K4 T% ?" ]2 E6 z& j0 w
  145. /* Input:                                                                                                                                */
    % K- D1 ^9 r, _2 @3 `' g8 Q
  146. /*                None                                                                                                                        */$ s3 B: y6 D6 I7 {4 B, R: T6 ^) [
  147. /*                                                                                                                                                */( E  |5 _  J: u7 `5 w) C
  148. /* Output:                                                                                                                                */
    3 G+ u* E( S9 r
  149. /*                SCK                                                                                                                                */, }$ r/ y2 `2 b* l
  150. /************************************************************************/
    . A# T) b. b, s5 e  `( T& U& N
  151. void init()  c& h9 U) C( d; P$ K4 d! o1 |: t
  152. {. D9 N* H+ q9 i' j  ?. x  A% F
  153.         SCK = 0;        /* set clock to low initial state */
    + r- n6 ?- T, d
  154. }- E/ [- t  w/ M7 |! G3 w

  155. - [2 q  Z% \2 c5 L
  156. /************************************************************************/0 f# w7 S- F" y) H4 }0 a! j# i
  157. /* PROCEDURE: Send_Byte                                                                                                        */. ]7 o5 E0 C, O0 D# o' @6 }
  158. /*                                                                                                                                                */
    " c: x2 ?3 ?& z% h/ v" R
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */2 K2 C. W4 k$ G1 K
  160. /* edge on the the SI pin(LSB 1st).                                                                                */2 ^1 f5 z. |, c; o
  161. /*                                                                                                                                                */
    " |: h3 [; m/ h# ~, n4 a' Y- z- C. z. E
  162. /* Input:                                                                                                                                */; j) S) i8 g0 i: d/ ~% b
  163. /*                out                                                                                                                                */. [" C! b7 L6 h+ g$ n
  164. /*                                                                                                                                                */' q8 E( ^" G( L* ^& |
  165. /* Output:                                                                                                                                */
    5 ^& m+ B6 c2 }/ A
  166. /*                SI                                                                                                                                */# o& y! _9 n$ C6 a3 u, h- X
  167. /************************************************************************/
      @* d' R+ [( Y; F2 L; Z8 l
  168. void Send_Byte(unsigned char out)  K! p& m4 y- \$ n
  169. {( I9 K9 D+ c1 [' \( {6 A0 v6 ^
  170.        
    + t1 Z2 y% Q- K3 @
  171.         unsigned char i = 0;6 W2 R  M3 I" E& H' X3 S
  172.         for (i = 0; i < 8; i++)0 Z6 K' ^0 K6 V+ ~3 U" q' S
  173.         {
    / u% I7 Y9 V5 j9 G8 d
  174.                 1 J- C6 T/ E- x
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */" u* Y* ]/ ~# E9 J6 n, i
  176.                         SI = 1;3 S; N1 A4 l/ Z; Y$ G; j* K# X! C& N
  177.                 else
    9 }. g: C. f- H7 e4 o+ D4 `5 i
  178.                         SI = 0;                                /* if not, set to low */; Y* k9 x# v+ o5 U. U
  179.                 SCK = 1;                                /* toggle clock high */) Z3 D- B4 t' k5 e
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    7 ?; q- S$ m4 f/ z/ ]
  181.                 SCK = 0;                                /* toggle clock low */
    8 G7 D( |2 k/ S5 n2 z; y& P; P
  182.         }9 S0 ~# P% \- t9 m
  183. }" s/ X& e  |( }6 \5 l

  184. " O# N% D8 h% o. T+ s) }
  185. /************************************************************************/( z' }& x/ x( y. y; |
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    ! p' L5 ?, u6 x, J
  187. /*                                                                                                                                                */
    : q, X$ ]; @, y- V. {
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    6 _3 L$ f; F9 U1 k
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    7 h$ `5 y1 B1 f8 N
  190. /*                                                                                                                                                */, Q# d2 q+ U" ^/ Z' F& `
  191. /* Input:                                                                                                                                */
    / L4 R; ]' e( l7 x3 f6 i
  192. /*                SO                                                                                                                                */, c# e& H; y0 X: d! W* P
  193. /*                                                                                                                                                */  Z! \4 j( V, W" t
  194. /* Output:                                                                                                                                */
    & c( }: c4 p: b) r& j) I
  195. /*                None                                                                                                                        */
    . T, z2 v/ g+ i4 Y7 `+ p
  196. /************************************************************************/
    4 k/ p$ ]# \1 q; N) c. D
  197. unsigned char Get_Byte()& \7 n: Y% E' b9 J5 N# W0 R8 k; y
  198. {
    5 U% |# M$ w# e$ n9 ~
  199.         unsigned char i = 0, in = 0, temp = 0;
    ) r# g6 s7 }% e  I/ h  D
  200.         for (i = 0; i < 8; i++)+ n1 V" H: R0 s
  201.         {
      D4 E* Y) Z9 N$ e" r; ]' _$ U
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    4 o! R: V7 R6 T( Y* R  D
  203.                 temp = SO;                        /* save input */
    0 q: [0 q" ]+ E. d: b5 _( T1 X1 `
  204.                 SCK = 1;                        /* toggle clock high */
    / d% G6 s6 t. P% t+ @8 N" S
  205.                 if (temp == 1)                        /* check to see if bit is high */
    3 d6 s7 I1 x6 v3 v' y
  206.                         in = in | 0x01;                /* if high, make bit high */
    $ ^; r7 r) v9 v" c* J

  207. * G2 r  t5 n2 C; ?3 s) h
  208.                 SCK = 0;                        /* toggle clock low */
    ; S: H! w) z+ J
  209. 7 r1 `, M- E$ W5 g
  210.         }
    ( |- v7 Z. b1 X- z, W  R
  211.         return in;5 [* Z( j4 q5 H! `* M4 q
  212. }
    3 C3 T4 Y, C9 @( a6 T
  213. ! {/ K" s" f( l
  214. /************************************************************************/
    " c/ t' n# q) k+ T( y9 {$ c7 S5 V
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ; K7 ]$ l* P, M9 }$ f' |& B% q' c
  216. /*                                                                                                                                                */; G2 E" K' Q) A/ O: b* H' |( Q
  217. /* This procedure polls for the SO line during AAI programming                  */2 g' n! J( `9 l+ O% }; a! u$ C6 z
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/, b4 Y- ^/ u4 v
  219. /* is completed                                                                                                                        */% ~/ [  p' x* f' P# u+ ]
  220. /*                                                                                                                                                *// u, a2 H7 @- e0 c7 ^# A: A
  221. /* Input:                                                                                                                                */
    6 k7 p( s* o* L- `4 r
  222. /*                SO                                                                                                                                */3 S4 @9 U& Z% T( I' u; x
  223. /*                                                                                                                                                */
    - _& C. ~- Y* D8 V3 {5 B; m
  224. /* Output:                                                                                                                                */
    1 v' U; A) H+ R8 Q1 Z
  225. /*                None                                                                                                                        */! e% |/ Z3 c$ s
  226. /************************************************************************/; E; n! Q4 L6 R1 P( k
  227. void Poll_SO()
    . P" b: w- `  w$ U3 Y
  228. {
    " g6 z: ^8 m2 D, H4 `
  229.         unsigned char temp = 0;& {% h9 {2 T- {4 n6 E
  230.         CE_Low();
    5 [* |- P7 ^: W  x5 [1 _
  231.     while (temp == 0x00)        /* waste time until not busy */
    ; u% k. R& _$ @
  232.                 temp = SO;' c5 [5 Y: Q" S$ H% _
  233.         CE_High();
    . I) B4 ~0 E, O
  234. }
    + X6 D$ q' m$ i/ F' s4 P( d

  235. ) A3 a5 x- u! x- W5 w: a
  236. /************************************************************************/  ^- S8 ^, s; o7 W6 |
  237. /* PROCEDURE: CE_High                                                                                                        */( m7 l% U7 \" Z/ J
  238. /*                                                                                                                                                */7 g8 D& r& @" z7 m2 f5 O
  239. /* This procedure set CE = High.                                                                                */
    , v/ s" ~5 u% w  j6 Y! k
  240. /*                                                                                                                                                */
    - A4 {" f" |8 G4 t
  241. /* Input:                                                                                                                                */7 e, p( @0 Z  q4 v
  242. /*                None                                                                                                                        */
    ! [2 Y) g7 F9 `% n
  243. /*                                                                                                                                                */# e; n2 J+ O# ?
  244. /* Output:                                                                                                                                */
    " q  n$ p. t/ M1 n0 t/ a
  245. /*                CE                                                                                                                                */
    4 |2 O- |* j$ [) ~
  246. /*                                                                                                                                                */! f) O( J$ v0 m0 f$ N1 z3 ~
  247. /************************************************************************/4 T. P7 O8 C1 O, f4 Y$ Y# Y  J
  248. void CE_High()
    7 ~3 J8 `( G9 z! R' u
  249. {
    8 S* R1 r& K$ r; |, P- b
  250.         CE = 1;                                /* set CE high */8 l- P# y0 h/ d2 F  T6 w' a0 q
  251. }
    9 q8 s0 @2 S: I* S2 U
  252. ! i3 x; k. k  s
  253. /************************************************************************/
    6 ^+ J# V. q" |! V2 I
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ' D% G& C# O+ F' F
  255. /*                                                                                                                                                */
    6 e" q6 |, L  H0 f
  256. /* This procedure drives the CE of the device to low.                                          */: z  D% [+ U% Q& O6 h
  257. /*                                                                                                                                                */
    $ n4 p) a0 B7 ~
  258. /* Input:                                                                                                                                */& T3 j' k1 G( |1 }- K4 X
  259. /*                None                                                                                                                        */
    ; c4 T: W2 Z2 }. A
  260. /*                                                                                                                                                */
    * t- Q/ r5 Y) E: x
  261. /* Output:                                                                                                                                */2 H' Q: {7 a, `% K" ?: g3 x* z
  262. /*                CE                                                                                                                                */' w6 _# ^" {2 d0 T; Q1 v  r
  263. /*                                                                                                                                                */: @7 Q$ R3 }3 i; t5 y. L2 h: {) }
  264. /************************************************************************/2 o2 X! z1 a' A, N2 m# _8 K/ ^9 F
  265. void CE_Low() $ q7 n0 |- {) ^" l
  266. {        : a% W; D8 Y" G" l) Y6 b
  267.         CE = 0;                                /* clear CE low */) F3 h( U6 W) a' q
  268. }2 ?* U# j4 |, a+ h

  269. ! w8 {2 b- W% A# G8 T" g' t
  270. /************************************************************************/
    ! w. Q& [. I8 w  |2 I$ u" G
  271. /* PROCEDURE: Hold()                                                                                                        */
    5 p3 v  Y2 K9 e
  272. /*                                                                                                                                                */
    ( l7 h/ C( X$ L4 s
  273. /* This procedure clears the Hold pin to low.                                                        */0 ]5 Z6 n- J5 p3 H, m. T1 T
  274. /*                                                                                                                                                */0 h% f' [6 T) q4 i/ D
  275. /* Input:                                                                                                                                */) z0 f3 P4 K- ]/ B2 W
  276. /*                None                                                                                                                        */
    & X- V" c% U& N0 x
  277. /*                                                                                                                                                */" c/ @6 s; F  c4 S: @
  278. /* Output:                                                                                                                                */
    ' B. F! `2 }9 Q6 _9 E% W
  279. /*                Hold                                                                                                                        */6 C9 |8 ?8 T$ h. \, G# w* I
  280. /************************************************************************/
    + X0 z: r& L) W- V  N, {
  281. void Hold_Low()
    % O3 Y9 S4 x; l  A4 }" S
  282. {
    ! b$ d! U, k6 w% c
  283.         Hold = 0;                        /* clear Hold pin */# k# F) `1 E! k( N+ P& A0 {
  284. }
    & p* d9 ]* y# C9 E9 B: k

  285. - {' v" a; ?$ x- Q* W" C
  286. /************************************************************************/% f. l* l/ D! U0 h/ O1 ^- o* C
  287. /* PROCEDURE: Unhold()                                                                                                        */, Q# }0 n2 c1 P( H5 S* |0 P  N
  288. /*                                                                                                                                                */
    ' ?# Q' O2 |& c/ z' m0 u
  289. /* This procedure sets the Hold pin to high.                                                        */5 f* y. @$ k5 d: `& `  h& |
  290. /*                                                                                                                                                */& U( S" }; E; b9 W
  291. /* Input:                                                                                                                                */
    & e- W2 K, I- Z% k3 z) f
  292. /*                None                                                                                                                        */3 ]1 _& ?) u7 }  l. A
  293. /*                                                                                                                                                */
    * B& b' ]% R. J3 a8 w( }1 n
  294. /* Output:                                                                                                                                */
    - c& B! T3 y- _
  295. /*                Hold                                                                                                                        */
    6 A3 F) Q- J0 ~& Y! e
  296. /************************************************************************/5 N/ Q! |  M) P2 k9 V
  297. void Unhold()
    $ Z  S9 b1 P7 N9 W& T
  298. {- V( j, p' l: s4 k1 o* _# c
  299.         Hold = 1;                        /* set Hold pin */4 `! _% T3 G. ^9 Z! I3 J9 ^
  300. }8 k7 {( P4 `  ^) b

  301. 0 b$ \: g2 T) B$ U6 `- v! t
  302. /************************************************************************/
    5 n  w( N; Z2 ]+ z/ z; ^+ ]- D
  303. /* PROCEDURE: WP()                                                                                                                */
    ; ]1 w  o0 J3 O" B( E+ R7 s/ G
  304. /*                                                                                                                                                */& a( R' N5 ]3 q4 |( ^4 v
  305. /* This procedure clears the WP pin to low.                                                                */
    $ D" c7 l+ _6 l" Z
  306. /*                                                                                                                                                */6 M1 t! P0 @+ H. K' u: a+ c
  307. /* Input:                                                                                                                                */
    ; ]+ ]% j5 e- [3 v. ]! o5 f
  308. /*                None                                                                                                                        */
    + V( u  B: X$ O, ]& ]2 f
  309. /*                                                                                                                                                */
    6 _/ w# D) e! b3 _2 C
  310. /* Output:                                                                                                                                */
    ) H6 t! J  d- k8 E$ Y* x
  311. /*                WP                                                                                                                                */  V1 ~: d  @4 C; {6 q$ z% d3 B
  312. /************************************************************************/7 w0 }/ R9 N) f
  313. void WP_Low()
    $ ]* f/ y. B4 c  Q0 T! e' W- x; x
  314. {
    5 D' |) o0 ?! W4 C7 O; E
  315.         WP = 0;                                /* clear WP pin */
    2 w" W  j4 z: U! U3 ~
  316. }
    $ S" k+ I& I! z% ?
  317. 4 I" T. d5 w) M
  318. /************************************************************************/! y5 x! Z* u  T
  319. /* PROCEDURE: UnWP()                                                                                                        */5 E! W" r  R% I1 y) [
  320. /*                                                                                                                                                */9 i7 K/ e% D9 J# `
  321. /* This procedure sets the WP pin to high.                                                                */
    * x9 `! E' \2 I: N# _6 s; z
  322. /*                                                                                                                                                */
    / k& {0 @8 y% c% b( c
  323. /* Input:                                                                                                                                */
    ( Q2 ^( z7 P* d) [# J5 F. y* v. c
  324. /*                None                                                                                                                        */, }9 F2 Z. G' H, k7 q& n% l
  325. /*                                                                                                                                                */; @- g% b, X: I% n( v
  326. /* Output:                                                                                                                                */: o5 w( _! W6 z
  327. /*                WP                                                                                                                                */
    3 d9 Q. j6 {  `
  328. /************************************************************************/, {% Z$ Z3 S9 V4 |
  329. void UnWP()
    7 D0 D2 x2 t& m% w5 l4 h. q& H
  330. {" y) j! A" V# n
  331.         WP = 1;                                /* set WP pin */
    ! }  U2 B7 T' a
  332. }% ^8 V0 E+ R! s

  333. ; V8 _% q3 Q6 C+ i
  334. /************************************************************************/2 ~* F" c! J* K
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    8 C/ A5 r* ~6 x$ R% P3 O$ r( @
  336. /*                                                                                                                                                */$ h2 R+ J8 t+ l- }0 ^
  337. /* This procedure read the status register and returns the byte.                */
      o6 j& l1 |/ q  M( }; L; I
  338. /*                                                                                                                                                */$ L- b6 Y  G3 W( d, x
  339. /* Input:                                                                                                                                */
    : R# y, _. V% R( o% y/ h
  340. /*                None                                                                                                                        */
    ' a* k2 h8 s6 Q( I
  341. /*                                                                                                                                                */4 K9 ^3 _, i3 ^
  342. /* Returns:                                                                                                                                */; z2 Z- N2 U3 p2 p; g8 c. f
  343. /*                byte                                                                                                                        */
    ( m. D' o% J" g
  344. /************************************************************************/
    3 k! s, |) l# c8 d9 h
  345. unsigned char Read_Status_Register()1 E% k% r2 d- W  L4 {
  346. {7 h& J% \/ j, `8 V  l& \
  347.         unsigned char byte = 0;( H( {1 Z! j6 e2 a1 n
  348.         CE_Low();                                /* enable device */
    6 L% m3 M. f) s$ i; _. u7 R( _
  349.         Send_Byte(0x05);                /* send RDSR command *// ^+ L  R5 Z" |  i7 `8 v
  350.         byte = Get_Byte();                /* receive byte */
    3 ]4 D% Y, l: N* o* o
  351.         CE_High();                                /* disable device */
      |" t  R$ i, a1 l
  352.         return byte;
    5 T/ U* E) n5 q: S# S
  353. }8 B+ S6 f8 z  G- s$ n: p$ `2 f
  354. 3 e3 e& O$ p( D, P1 g! T
  355. /************************************************************************/& I  K: v" |0 N# I6 P0 y
  356. /* PROCEDURE: EWSR                                                                                                                */4 ]3 F& j3 S% y1 G6 R
  357. /*                                                                                                                                                */
    6 F# K7 s/ e3 T+ \. Y
  358. /* This procedure Enables Write Status Register.                                                  */
    ) E/ ]- N& r) C. e3 T1 L
  359. /*                                                                                                                                                */
    ) g+ o4 q/ W! O5 i- p
  360. /* Input:                                                                                                                                */
    ) r9 {; s- f% D  P
  361. /*                None                                                                                                                        */
    4 P+ \( ^; T" R0 F
  362. /*                                                                                                                                                */
    : M, C5 V+ F0 Q9 [9 z, G( b
  363. /* Returns:                                                                                                                                */) Z# E/ C4 I2 ^* m7 G  r. p3 S
  364. /*                Nothing                                                                                                                        */
    : H3 Q8 f2 b. e$ y8 x0 L4 u  E
  365. /************************************************************************/
    $ v% {! i0 r5 z8 ]  J
  366. void EWSR()
    $ [% s7 e6 r2 ?# ~0 y
  367. {
    - u& V) N$ z# c
  368.         CE_Low();                                /* enable device */% t; x. X+ m4 c& {& {
  369.         Send_Byte(0x50);                /* enable writing to the status register *// S9 o7 U3 ?) A" s- o7 F- `/ b
  370.         CE_High();                                /* disable device */8 E/ I) v. ~2 w, F, c
  371. }% H5 k0 b+ ^0 M; k! X
  372.   M' s+ S& U$ U2 ~7 j
  373. /************************************************************************/1 b% A' K! p2 D! R& P/ `% e$ z6 t
  374. /* PROCEDURE: WRSR                                                                                                                */6 F6 f' |7 Q9 x0 n0 `
  375. /*                                                                                                                                                */
    ; U5 B7 w! k$ Q4 A8 {1 }$ c
  376. /* This procedure writes a byte to the Status Register.                                        */6 a  V# b5 @7 D( _, h7 r; b
  377. /*                                                                                                                                                */( p& O4 F- U9 w/ a' m4 S
  378. /* Input:                                                                                                                                */, k; a4 U/ ~% m  f9 J" ~2 P) V
  379. /*                byte                                                                                                                        */
    6 f/ d4 ?/ N5 _: b$ c$ w; {
  380. /*                                                                                                                                                */
    1 d" B" H) p- u# j/ [1 D3 m5 J0 u
  381. /* Returns:                                                                                                                                */% u+ {" C' K: K2 o  \: d
  382. /*                Nothing                                                                                                                        */
    * P3 A6 o; {4 ]6 I; e) Z
  383. /************************************************************************/. J( e6 O6 v2 b& a( ~
  384. void WRSR(byte)
    - B- g0 I" l" v6 w- r$ u+ A+ {
  385. {
    & v4 S7 W4 b' _! ?" ^( b
  386.         CE_Low();                                /* enable device */
    9 q2 }* c9 X8 I, p5 H1 w: g# K
  387.         Send_Byte(0x01);                /* select write to status register */9 H/ g% |8 Q7 w8 S7 y- u
  388.         Send_Byte(byte);                /* data that will change the status of BPx , Z) r  n# r* ]* n; T
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */. \" |3 a  l- U$ n9 N
  390.         CE_High();                                /* disable the device */
    " O. ]6 v# X4 B
  391. }
    # i! P( I; n2 j; D

  392. . I# x5 ]1 d1 i4 Q
  393. /************************************************************************/) s( m2 A9 J4 Q2 q% H, R5 ~" U# @2 L
  394. /* PROCEDURE: WREN                                                                                                                */
    ! S9 }3 X) t) ]$ c8 i6 n
  395. /*                                                                                                                                                */, t+ l# K* k6 H3 R$ ]
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */; F' H1 u- b( b* V" h/ v3 j
  397. /* to Enables Write Status Register.                                                                        */
    ! f# _* ^$ `  j
  398. /*                                                                                                                                                */( R  v5 C. I* ~6 Z- L0 m7 w/ a
  399. /* Input:                                                                                                                                */
    1 W$ C- X2 y2 d4 I, `8 m
  400. /*                None                                                                                                                        */$ u# b7 c: C( J* j
  401. /*                                                                                                                                                */0 t5 l( f$ l3 S& J1 G4 V1 P
  402. /* Returns:                                                                                                                                */7 d3 P$ o: `2 j" L* O
  403. /*                Nothing                                                                                                                        */; _- w2 T! N" h( X8 q" H4 ]9 h" p
  404. /************************************************************************/, @5 p, c9 {8 ]1 A! g9 a$ W7 |( k
  405. void WREN()
    2 E" M6 s0 e6 P( y, |
  406. {' {: {& X0 x8 P7 Y. F4 v! B
  407.         CE_Low();                                /* enable device */
    4 P) I) x. W- s* _
  408.         Send_Byte(0x06);                /* send WREN command */, V8 o( M7 ~9 K
  409.         CE_High();                                /* disable device */# P  ^* V" ?$ u9 b1 w/ r
  410. }8 ]0 J! w# N4 r0 W4 R3 M2 i
  411. - H" v) S1 B- T
  412. /************************************************************************/
    0 @% r. ?- c6 x% w0 `5 B
  413. /* PROCEDURE: WRDI                                                                                                                */1 Y  P- y- @7 u. I+ F
  414. /*                                                                                                                                                */  h! F/ D8 W8 E/ A  b2 F/ b, X* W
  415. /* This procedure disables the Write Enable Latch.                                                */
    ' ^- i* }; k7 X
  416. /*                                                                                                                                                */+ F2 j3 E5 p" s4 o1 C
  417. /* Input:                                                                                                                                */& U( z& \# P( }" W4 v3 w
  418. /*                None                                                                                                                        */# b2 R* N- [8 y
  419. /*                                                                                                                                                */
    # Y! D% H0 i8 U4 d% v6 q) I
  420. /* Returns:                                                                                                                                */' e# A! b5 R5 i+ T  j- \/ L
  421. /*                Nothing                                                                                                                        */
    4 D+ A; }7 [3 P
  422. /************************************************************************/
    8 M/ z9 F: S6 _6 s7 T
  423. void WRDI()
      |1 b& i9 t$ U- {8 f) S
  424. {
    ; w, i) t! p* k/ y0 V+ M
  425.         CE_Low();                                /* enable device */! ]7 I! b, T5 q
  426.         Send_Byte(0x04);                /* send WRDI command */% @5 N9 @$ m3 k
  427.         CE_High();                                /* disable device */
    : R( ]. U0 h( m3 v: @
  428. }- i3 K1 d9 B! X: S) b. c3 L
  429. 2 O; D/ n. X+ g. I- c
  430. /************************************************************************/9 s6 b. E' K9 e* }  G2 D
  431. /* PROCEDURE: EBSY                                                                                                                */8 z2 n- [, t; K& \3 H& p! l
  432. /*                                                                                                                                                */$ I. ?2 I5 M$ h. R" ?6 \( K; g0 e
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    , [" d4 @; N; G  s& b- o, s# @# m
  434. /* programming.                                                                                                                        */! ^$ }' T' X+ x6 P& W& P
  435. /*                                                                                                                                                */
    3 t$ E- o6 Y7 x/ x6 g- P
  436. /* Input:                                                                                                                                */3 Y* L# V- d2 w. J
  437. /*                None                                                                                                                        */
    - k: u' J1 j+ c+ Y+ t& L
  438. /*                                                                                                                                                */4 P" Z' @0 \3 P* d- N8 I
  439. /* Returns:                                                                                                                                */# f! x$ Z: j* Y8 l. F
  440. /*                Nothing                                                                                                                        */( v3 T) H" P3 `% D
  441. /************************************************************************/
    . h; n* Z9 t9 Z/ ~- f$ x* a# F) q
  442. void EBSY()
    . K& Y* D8 ~, X  z5 ]% ~) J
  443. {! F; X- v! ]5 i
  444.         CE_Low();                                /* enable device */
    + K$ r3 k) R5 I8 j/ n& ?& y
  445.         Send_Byte(0x70);                /* send EBSY command */+ s/ n0 a$ H- f! N6 F; g& Y
  446.         CE_High();                                /* disable device */  W' n; O. X% h( E
  447. }2 W- |9 |% L% m

  448. 6 f! ~9 `( h* }; G* R0 b! [+ U
  449. /************************************************************************/' x, K) @$ P/ `9 |
  450. /* PROCEDURE: DBSY                                                                                                                */
    ) G/ g5 _$ R  P6 z2 [* c* J' E
  451. /*                                                                                                                                                */; K+ I% f5 X' e8 H* k/ f
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ) U; Y5 Y! s  e# y! }
  453. /* programming.                                                                                                                        */) Y! \' r1 k, j, K% x: |+ J
  454. /*                                                                                                                                                */
    8 K! ^- x2 A/ T) y
  455. /* Input:                                                                                                                                */! M* Y+ P9 C* z& G# \: _: q
  456. /*                None                                                                                                                        */
    1 }% q1 J( w- r7 k# [
  457. /*                                                                                                                                                */+ P) q# n) j1 Y5 `
  458. /* Returns:                                                                                                                                */
    9 D9 K% x8 u5 j, ?3 D1 ]
  459. /*                Nothing                                                                                                                        */3 \9 M! X" k( Q
  460. /************************************************************************/1 |! d$ n. p3 i$ e6 E
  461. void DBSY(). P+ T# r" n* Y
  462. {: p3 i2 x* M; q* p. C/ O$ u
  463.         CE_Low();                                /* enable device */
    ) {$ |! M* z7 Z! q
  464.         Send_Byte(0x80);                /* send DBSY command */
    ) v3 F8 S$ i: o8 K' E
  465.         CE_High();                                /* disable device */$ I" g& G# ?5 M5 z( J# f" C0 X
  466. }7 F/ x, i, z8 o, U; t$ v, R

  467. ) L" L7 {! _9 F+ ?) H
  468. /************************************************************************/4 q0 z9 d/ y; b  Z! ]3 Y  m" h
  469. /* PROCEDURE: Read_ID                                                                                                        */1 x3 U- \- B- L; s3 `
  470. /*                                                                                                                                                */
    0 V1 s& S6 m: `; S* F2 Y
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */4 B1 I, _9 `1 F: H" [4 z
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ' D8 }6 U* L% ]" a
  473. /* It is up to the user to give the last byte ID_addr to determine      */0 z( i$ S! |; |4 m! J
  474. /* whether the device outputs manufacturer's ID first, or device ID         */6 h9 m- t# K& i. a6 E
  475. /* first.  Please see the product datasheet for details.  Returns ID in */: f/ b: w- [/ s* E/ W5 t- ]
  476. /* variable byte.                                                                                                                */
    : c, K! Z7 J* X" w+ Z$ ^6 ?
  477. /*                                                                                                                                                */
    : A% U( Q7 Z9 b4 L
  478. /* Input:                                                                                                                                */+ o( T2 S; U6 a4 E9 o
  479. /*                ID_addr                                                                                                                        */
    ) B( j5 n# \+ @/ j$ q# j6 J  D
  480. /*                                                                                                                                                */% h: |# J5 P. s2 @+ ?7 H# o2 Y
  481. /* Returns:                                                                                                                                */
    9 T$ {- _0 N2 ]6 K" n+ I, V
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */8 D( ~) U# P! u/ N% P
  483. /*                                                                                                                                                */
    . d, U3 j$ H( C: b% ~" E
  484. /************************************************************************/
    # h' ~7 q; q7 Y) A
  485. unsigned char Read_ID(ID_addr)
    6 D; Q& S6 `9 `# C
  486. {9 ^' f8 Q+ `; h+ ~; {
  487.         unsigned char byte;1 l) |: I9 u2 a' Y  N1 K
  488.         CE_Low();                                /* enable device */7 ^" j" Y) p- H0 y/ l
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    & W" d: r( l9 ]
  490.     Send_Byte(0x00);                /* send address */  M3 A- |, G2 o+ l+ C5 q% R
  491.         Send_Byte(0x00);                /* send address */8 M% B  C' |7 G+ ~2 t5 v8 i6 V6 E5 _2 W
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    2 `/ g( H- H3 n* {/ m; A$ O* g
  493.         byte = Get_Byte();                /* receive byte */; C. I% e% ^' {, r7 o
  494.         CE_High();                                /* disable device */: ]* G$ A* }5 T% y
  495.         return byte;2 _( c- i) p; N5 t$ R  A. C) {
  496. }
    + ?" o% S: E1 P  J# p; E
  497. ' [/ A  e2 Y. I* ^4 Z
  498. /************************************************************************/% m; C& U' V( D$ |& O
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */1 X9 J& h  Y( ^, g
  500. /*                                                                                                                                                */
    / G" K8 f! `# ?  j3 F) Z
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */. E1 L. M% H! l# D4 B6 M
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */  G3 T" J$ R/ v
  503. /* Please see the product datasheet for details.                                                  */
    8 X7 Z. F; A4 T/ e
  504. /*                                                                                                                                                */
    % |; F' E) P/ {; B! K, N, a
  505. /* Input:                                                                                                                                */( ]7 F! l) E$ D# k; p6 h0 Z
  506. /*                None                                                                                                                        */
    ) b: K1 H9 B: }7 J
  507. /*                                                                                                                                                */6 G$ q' ?  L& J- n% s2 ?$ B
  508. /* Returns:                                                                                                                                */
    + R5 ]& s+ d! h7 F( e9 c+ D
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */+ A4 q0 e* r7 E. V1 W" l" w
  510. /*                 and Device ID (8Eh)                                                                                        */, ?6 c& h% f, y! Z- ]
  511. /*                                                                                                                                                */
    " e8 x# ~* n$ {. H# |
  512. /************************************************************************/
    $ v8 z4 C# _4 I! i% }
  513. unsigned long Jedec_ID_Read() 6 N% T3 d0 O; `' A6 X- Y
  514. {6 W+ _8 ~) A, u' A
  515.         unsigned long temp;* V9 g  w. q' i1 \3 h
  516.         : P8 p$ H0 j9 s; }
  517.         temp = 0;
    8 P, {, z6 j* _1 h
  518. " S: Q* V0 }1 I% z) b7 Q
  519.         CE_Low();                                        /* enable device */
    3 [2 b5 L  v; N
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    * f/ i$ w* k6 h, Q
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
      e8 X' v. Q6 v+ o" w  l% R0 `
  522.         temp = (temp | Get_Byte()) << 8;       
    1 k+ \6 z4 b3 d0 x. j$ a4 ?
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    6 L; \5 @6 G  H. J3 s
  524.         CE_High();                                                        /* disable device */: {' Z; I' R) _! ]
  525.   U. O5 W( o$ \2 w% y
  526.         return temp;( J7 j# k+ B2 ~6 W
  527. }
    * B1 P% k+ w' r; u  m( b; T

  528. 9 S$ x5 K8 x0 G$ h4 F
  529. /************************************************************************/+ u. f" D# O* ?8 K* r, ]- c
  530. /* PROCEDURE:        Read                                                                                                        */0 ]- k; n2 }3 V* x8 E
  531. /*                                                                                                                                                */                  _9 V9 a% T1 }1 ~: [
  532. /* This procedure reads one address of the device.  It will return the         */
    0 U8 s4 ~  o& w8 y& F
  533. /* byte read in variable byte.                                                                                        */
    . |  o- B: n1 [  R$ c' N: t
  534. /*                                                                                                                                                */3 b1 a" B! b4 i4 Z) A4 H! L5 S
  535. /*                                                                                                                                                */1 J8 n  A2 `+ J, o
  536. /*                                                                                                                                                */3 Z; M  |( O, f( J: }/ U
  537. /* Input:                                                                                                                                */
    3 W# t2 m) D  {4 Y$ X. m
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ) O; B- S* u! D* N( d4 N
  539. /*                                                                                                                                      */5 v% M7 a, _) W
  540. /*                                                                                                                                                */
    - F  r2 K2 `  N5 h- l* V( L& s
  541. /* Returns:                                                                                                                                */: T6 c7 Y8 w& H
  542. /*                byte                                                                                                                        */
    $ s1 ^: r8 K! f) O5 ^( v
  543. /*                                                                                                                                                */5 j0 Q! `5 i) Y  e9 b
  544. /************************************************************************/  \# i5 W, \5 n4 ]
  545. unsigned char Read(unsigned long Dst)
    6 h0 E7 N- L' I8 @3 u' @' E+ h
  546. {
    7 Q7 v0 ^) |% N) W
  547.         unsigned char byte = 0;        ' A; c: L' g2 E  q2 z
  548. 9 X% }; U0 z3 [: l2 C
  549.         CE_Low();                                /* enable device */
    8 ~# y) k! U$ G
  550.         Send_Byte(0x03);                 /* read command */5 t1 d( a- p2 T; }! X$ i/ ^! q
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# n; F7 x( g6 o! r! H6 e; ?
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / G. z0 C6 N; q7 J( P4 d: d% o
  553.         Send_Byte(Dst & 0xFF);
    % o$ h$ R. w& h
  554.         byte = Get_Byte();
    0 @( Y1 @8 B+ ]+ H/ a' d7 j
  555.         CE_High();                                /* disable device */
    0 n  n% S. Q% r, V4 {/ r
  556.         return byte;                        /* return one byte read */, Q" x  s" ?8 M. z2 o; |
  557. }: }: Y, L+ M* e' @% Q/ R+ W3 q, E

  558. & _  ~7 H$ u" Y
  559. /************************************************************************/
    6 S5 p. @+ k% Z4 H
  560. /* PROCEDURE:        Read_Cont                                                                                                */9 T# Z( f# c: G0 g
  561. /*                                                                                                                                                */                * ^* P$ M0 M2 s5 [9 R. g
  562. /* This procedure reads multiple addresses of the device and stores                */+ ^" `7 D& n+ {
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/9 m7 m, }7 L  T) A
  564. /*                                                                                                                                                */$ Y8 |8 W/ s$ s7 K$ i
  565. /* Input:                                                                                                                                */0 r5 B" c0 R4 e0 U7 |# T  ^& Y
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 i( h( ]) b8 }. t" c& \- |: L6 ?6 y
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ; N- g9 @& i/ k# z, J* \3 w, p
  568. /*                                                                                                                                                */$ i  V$ q6 m3 ]* _( R0 T
  569. /* Returns:                                                                                                                                */
    & v* H" a+ p% ~" Y4 @2 j! w! k
  570. /*                Nothing                                                                                                                        */
    0 f3 n/ e& i( f# j; T" a4 D
  571. /*                                                                                                                                                */
    * _. k/ m+ a: s
  572. /************************************************************************/
    2 J) g: l+ u) t/ V( i$ _8 K: N
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)! w3 B- Q' y3 I8 N5 e0 ~3 E# S
  574. {
    8 a' G8 a  H- h2 y( c) a# L1 a
  575.         unsigned long i = 0;
    ) h. i# A2 m( Z. k
  576.         CE_Low();                                        /* enable device */1 Q' X0 b% V7 M
  577.         Send_Byte(0x03);                         /* read command */
    5 b3 [: C2 y' y
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */8 i. X' Z5 y0 ]& D0 S
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));$ y! S3 j# R. A# _5 V9 G+ _; r# S
  580.         Send_Byte(Dst & 0xFF);
    9 P8 Q# F: j# ~
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */+ Y; Q! z# B& z3 L# o( R
  582.         {
      A+ ~6 s' V6 {- y
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */. w0 C) w+ d" }, n
  584.         }
    8 W+ D$ ?4 D" D
  585.         CE_High();                                        /* disable device */! O) z4 j1 M* t; U  d' G

  586. ' z) k9 X2 [4 J: O$ j6 v1 x
  587. }6 ]2 w2 a+ P2 ~" U
  588.   I+ P' V/ ^! G& b# U( d2 b; x
  589. /************************************************************************/) q8 ^6 l3 D0 F8 V% w3 L9 @
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    & K3 {9 ^, h- P8 d% |8 j
  591. /*                                                                                                                                                */                8 w( W( E3 h' L3 Q
  592. /* This procedure reads one address of the device.  It will return the         */6 D: I0 Q. L" ]
  593. /* byte read in variable byte.                                                                                        */) P+ |# _) y& a! g+ A
  594. /*                                                                                                                                                */
    # M% d; U/ z; B# w2 C
  595. /*                                                                                                                                                */
    # e- s" _" p' \9 C- ]4 [
  596. /*                                                                                                                                                */0 H+ t6 t" p+ B4 m/ v7 A
  597. /* Input:                                                                                                                                */
    ) v+ l( ^$ @& U6 B* l% h: o. T$ n# d
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */" D# F9 B& D  A. k2 p
  599. /*                                                                                                                                      */
    0 r9 C8 ~1 O; r# L6 u
  600. /*                                                                                                                                                */
    ( d- C+ L# [5 H  ~% X; I* ?$ Y- P
  601. /* Returns:                                                                                                                                */" G7 U8 {) `/ s6 Q2 E  y- w2 `
  602. /*                byte                                                                                                                        */
    # T" V( g+ T. U1 w. {/ I
  603. /*                                                                                                                                                */6 C) j- m) H% i: b
  604. /************************************************************************/" Z" N; n9 D& o# F. H& C: _; h
  605. unsigned char HighSpeed_Read(unsigned long Dst) 8 d; d2 v; F2 @) H9 w
  606. {, a: [- _+ D, W6 w( n$ h
  607.         unsigned char byte = 0;        5 O+ ]7 i: b. |; F) K
  608. / O& G9 ?* q& M' {! V4 \9 {2 u
  609.         CE_Low();                                /* enable device */
    # J. ~; _! k: t0 W9 s
  610.         Send_Byte(0x0B);                 /* read command */6 p0 w! C/ ~: T8 z& ?& T0 L1 P) X
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */3 t' s, M& U4 \; r. p) u, @
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));9 f1 X3 v) b5 E$ X: M% ]+ s; f
  613.         Send_Byte(Dst & 0xFF);1 w1 X# [& d& @% D3 B) L
  614.         Send_Byte(0xFF);                /*dummy byte*/
    5 M7 r: _4 m  O
  615.         byte = Get_Byte();
    # C7 K" d8 [% e% A# ^8 F: W9 s8 x0 n
  616.         CE_High();                                /* disable device */
    " n& n8 y  u) [6 Q" @1 I
  617.         return byte;                        /* return one byte read */
    $ c# N, [  u4 [6 ?4 }- N
  618. }8 n, {) p# @# H! r$ H

  619. ! x. Q$ B: U: J/ ?7 q8 |3 t7 P
  620. /************************************************************************/
    1 D! e& U4 I& a- D4 y( x  |! ]! F
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */% q- R  @+ X/ r$ a% g! b* z
  622. /*                                                                                                                                                */               
    ; i1 k% \0 Q% R/ F2 _8 h3 v
  623. /* This procedure reads multiple addresses of the device and stores                */& }8 ^' [  q" [
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/3 |, D) ~8 ], m! ~9 C" e
  625. /*                                                                                                                                                */
    ! r: M. [* y  O5 z6 p* H8 q3 c: d' P
  626. /* Input:                                                                                                                                */
    1 Q: D2 U$ D4 \' s
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 s8 [* e$ L+ {& @1 o. d- E
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # T# v8 P1 b) _" K- l2 g9 L1 h" }
  629. /*                                                                                                                                                */; u$ t: @7 e- O1 F0 D- W
  630. /* Returns:                                                                                                                                */3 {5 X  Q( t& C: G
  631. /*                Nothing                                                                                                                        */
    . R5 b2 Z) D) n# o4 @
  632. /*                                                                                                                                                */# W& m! Z# L' q% Y
  633. /************************************************************************/' M3 f% |# R- f
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes), `( e7 h% W' O1 G
  635. {
    / g: @4 S7 W$ }9 |; A: `: I
  636.         unsigned long i = 0;
      @2 `9 E3 P! b/ r
  637.         CE_Low();                                        /* enable device */* U0 W4 @6 }- Y/ Z6 M6 R) I; r
  638.         Send_Byte(0x0B);                         /* read command */
    $ f- E  X# R0 V5 K
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' k& y# i$ k2 `" \! a$ n' t
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; q+ y+ k& t  r2 k3 ?
  641.         Send_Byte(Dst & 0xFF);
    1 l. p- Y& q% M" ~
  642.         Send_Byte(0xFF);                        /*dummy byte*/# @9 T3 K- B- W, I
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    : R  y; x) V5 c- O. b- C# ]) B
  644.         {( }1 w. e% n0 z
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    & v3 h2 R4 ~  q0 C6 I% H! x
  646.         }- I2 ?+ Q5 O8 O6 F
  647.         CE_High();                                /* disable device */) j3 N+ v% w7 t, o, i
  648. }
    - W6 K3 Z5 W3 U
  649. , ], B0 W0 L+ ?5 ^# a: F, M% E. }
  650. /************************************************************************/( a3 ]0 V5 ^$ s8 m: j% c7 U! g
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    7 f" Y( \0 F% I! ?
  652. /*                                                                                                                                                */
      F) @  ^3 z# C3 S, h
  653. /* This procedure programs one address of the device.                                        */
    : K, x1 h- ~6 N
  654. /* Assumption:  Address being programmed is already erased and is NOT        */: y' Z' @- `9 o& l
  655. /* block protected.                                                                                                                */
    * N: L4 T5 k' U( J" q
  656. /*                                                                                                                                                */
    3 m$ J: |1 s5 V  V' G, x
  657. /*                                                                                                                                                */
      R" A) [. v( s- I- P
  658. /*                                                                                                                                                */
    9 j/ b9 P4 E5 v+ g' G5 z
  659. /* Input:                                                                                                                                */
    - a7 ]' O3 ^3 @) q# e
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / }6 Y! y% r) a* O
  661. /*                byte:                byte to be programmed                                                                */8 ?" h% w8 O2 J7 k7 z
  662. /*                                                                                                                                      */
    ) j. i5 T; M& c; `% l: h3 Z
  663. /*                                                                                                                                                */
    ! {* Y+ p) u& g7 [+ f4 D
  664. /* Returns:                                                                                                                                */) W- ^% J0 b# w) v! H+ x
  665. /*                Nothing                                                                                                                        */
    # d3 d' ~; K3 ?" l+ R' N2 q
  666. /*                                                                                                                                                */% y: L* j6 Y1 C. G9 s" {1 {
  667. /************************************************************************/% t7 C1 a9 G7 l7 `; [
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    8 q$ H- i+ s( B4 H& Z+ m+ n: M
  669. {) w* x2 N3 J/ r- `  r
  670.         CE_Low();                                        /* enable device */1 \3 i) ?0 V% r+ b7 v2 `3 W
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    & R  v* ~" H0 B1 f' i
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    . _  B/ s" U7 l* t: }! d( Z
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 M7 k, `2 d" P+ `+ N  {
  674.         Send_Byte(Dst & 0xFF);
    ( T2 m; G  O( g
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    ; [/ L- E7 E0 C  Q8 q
  676.         CE_High();                                        /* disable device */
    - m0 i# O  \: F* J6 i4 b! f
  677. }
    6 q# h* T5 q1 V2 s

  678. 1 P- |2 f5 ^# J7 o# M) Z# i
  679. /************************************************************************/, ^7 \0 H6 j0 Z6 M* J2 A
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        *// W. d& q" m% ?& J" X
  681. /*                                                                                                                                                */7 ^" X2 y: z3 i) Z! y
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/9 u" M/ @7 n' ?' W
  683. /* the device:  1st data byte will be programmed into the initial                 */
    % K6 g9 g. ~5 e, G2 \6 y- r; {
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    : K6 r! h* n" h1 g' J
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    , }% b6 U% p- T; f
  686. /* is used to to start the AAI process.  It should be followed by                 */
    ! C: Y& l! x' {: T% w* |
  687. /* Auto_Add_IncB.                                                                                                                */, B' v$ ^5 t4 W6 F9 q, i
  688. /* Assumption:  Address being programmed is already erased and is NOT        */3 n% z0 U% p, z7 g" E
  689. /*                                block protected.                                                                                */
    2 }# W2 n1 K: o& H2 t% V
  690. /*                                                                                                                                                */
    7 r5 B" e+ P: c4 y  s
  691. /*                                                                                                                                                */. L0 O, B0 Z4 f3 ~
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */! t) C2 g) n1 Y) W% O
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */& n0 O; J8 _. w
  694. /*         unless AAI is programming the last address or last address of                */
    9 d% B$ r7 U5 ?/ M3 s7 o" ^
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    2 D  E% b+ K) N6 Q. q2 S- Q
  696. /*                                                                                                                                                */; u; }6 p7 a; @
  697. /* Input:                                                                                                                                */" q, O+ \$ k7 h' O+ Y# \, }  q9 z1 s
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 m$ J3 }% x, R. e( ~& ^) k9 x
  699. /*                byte1:                1st byte to be programmed                                                        */% Z) r; ^3 n" q! x& _) J
  700. /*      byte1:                2nd byte to be programmed                                                        */
    4 o& v2 {( ^3 m! t9 T) l
  701. /*                                                                                                                                                */
    $ D( f! l  e4 e0 D8 D0 I' X8 Y
  702. /* Returns:                                                                                                                                */
    : K% l' ?1 [% U  T( e0 K6 h/ n/ j7 W
  703. /*                Nothing                                                                                                                        */
    4 T5 D/ B3 T8 _0 p4 d
  704. /*                                                                                                                                                */
    & L6 @9 c* y8 D4 Q+ a! ~+ }
  705. /************************************************************************/" R( Q; w6 U$ b+ X! E4 g6 }
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    8 S. ^/ S1 O; p& \5 Y) O
  707. {
    . t; s+ @* g+ n
  708.         CE_Low();                                        /* enable device */  E& n* P0 i5 D) [0 k# y4 I* o
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ' R! W1 J! Q+ e1 r4 C' u! K
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , M# W" ~- h6 D! l8 g: u
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));$ b7 e/ {$ k5 S1 p
  712.         Send_Byte(Dst & 0xFF);
    % Y. a, S! N( Y- N, v, L2 X  \
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        " S" y/ q6 k* g+ v9 G" V+ S5 \
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    - i2 g+ T" i2 C! w
  715.         CE_High();                                        /* disable device */6 s) d/ T# Q3 [, p
  716. }
    9 Z! ]& U8 C4 A' W$ w% ^$ n
  717. 1 q: \* D5 Z$ X% n
  718. /************************************************************************/4 }7 f# B& t7 Q- b" ]
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */' d' M& ^3 S& I: |
  720. /*                                                                                                                                                */
    : i! K- X' ]+ k. q
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/  v7 W3 `0 u0 G- L
  722. /* the device:  1st data byte will be programmed into the initial                 */- ~7 I' l8 `% X  Y4 z5 g
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    3 x. l7 I1 X6 U+ f% s6 V1 ^
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    * }1 b  o; l* g8 {( R
  725. /* is used after Auto_Address_IncA.                                                                                */' n; C+ R9 y4 F. ^4 v
  726. /* Assumption:  Address being programmed is already erased and is NOT        */( A8 x% r3 g( c$ a$ _6 }0 b
  727. /*                                block protected.                                                                                */  D4 ^+ E6 F/ l7 g
  728. /*                                                                                                                                                */
    ( c  ?. H& ]( D7 V9 V
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    1 ^% ?  l0 e3 X+ f$ ?
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    6 H7 Y/ m* f6 h$ v& V
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        *// Y# S- z: A" ?/ |, t2 y& z
  732. /*          to exit AAI mode unless AAI is programming the last address or                */) j6 O4 S" i' ^$ x
  733. /*         last address of unprotected block, which automatically exits                 */
    ( u$ p2 Y. [' j6 k7 Q
  734. /*         AAI mode.                                                                                                                        */9 y* k2 j6 o2 W" a! K
  735. /*                                                                                                                                                */3 l& S7 O( v( G2 \! q( z
  736. /* Input:                                                                                                                                */" U2 K6 z# w1 o2 |& G' l: Y
  737. /*                                                                                                                                                */& A* T7 e* [$ d1 }6 E0 g+ |' h; O
  738. /*                byte1:                1st byte to be programmed                                                        */
    1 z9 S$ _- z9 ^( j9 f; e& t, x8 E
  739. /*                byte2:                2nd byte to be programmed                                                        */
    ' Y4 q4 l% R8 G* ~  d
  740. /*                                                                                                                                      */
    , b& |" b- c. Y" _! c0 m
  741. /*                                                                                                                                                */
    # i8 Y; G" x& I( H; }. G
  742. /* Returns:                                                                                                                                */
    # w( V8 \( u9 n
  743. /*                Nothing                                                                                                                        */
    ; t! l) p, D# _# f7 a
  744. /*                                                                                                                                                */
    / F% Z9 e6 g  z5 _# y
  745. /************************************************************************/
    3 I. {4 Q" B: r0 v% ]. r% S
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)+ G, a' _# D* T$ l
  747. {! B' K# N2 {% }. B3 m3 O
  748.         CE_Low();                                        /* enable device */  u1 |+ D: D. t) f- G6 o) Z
  749.         Send_Byte(0xAD);                        /* send AAI command */
    2 \$ @+ J4 e$ M" n
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ! n8 S% `1 q* t3 n& H
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    3 W' d- b+ F: Q* `/ B8 u
  752.         CE_High();                                        /* disable device */
    6 _" S$ O. M# O1 m
  753. }
    1 Y0 \7 p* x, d9 l& {

  754. % L% t4 ]# K3 V: E, G- Z: d
  755. /************************************************************************/
    ' O1 [" t/ `: Q0 y0 m$ t8 K. G
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    0 T, r% s! m' x3 I4 l
  757. /*                                                                                                                                                */: Z( q" f; [2 z% q
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it *// g; H! Z/ @7 F/ M/ A2 h
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    + y7 d# z! L, c8 x
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    & u5 [& d4 Q9 x: V' A, B3 G, N% u
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    4 J- g+ ~( H: w- d0 q' y
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */& j+ ~% Z8 ]. t- i3 g  t) m
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    7 g' Y) N+ `6 w3 Q$ k; b- @
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    # y# K$ Z  l, s% r9 b
  765. /* Assumption:  Address being programmed is already erased and is NOT        */1 `+ k7 b8 c7 d4 e4 n8 h* x$ R
  766. /*                                block protected.                                                                                */
    ) I6 t/ D3 q1 [" O7 G& \
  767. /*                                                                                                                                                */
    . |7 I5 _9 l9 I' j8 u& ^0 V
  768. /*                                                                                                                                                */1 I% _% }# b% ^* U7 `
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    % B$ ]8 O% B! Y$ q" N% \/ Z6 W. @
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    . s# o0 w1 }2 \5 M; R
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    1 V( p2 e; W% |4 ]
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    1 d+ `! f8 \; k. m, Y; v4 M
  773. /*         last address of unprotected block, which automatically exits                 */( D: L# w! Q$ _
  774. /*         AAI mode.                                                                                                                        */
    3 H, {( ^0 {7 C% Q/ H8 L
  775. /*                                                                                                                                                */
    & {2 L4 J6 x9 p& ]: |
  776. /* Input:                                                                                                                                */$ U+ L! ?: `1 p
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : ^9 T# w( [& w8 |6 T. }, @% Z8 X9 ]
  778. /*                byte1:                1st byte to be programmed                                                        */
    ( }/ a* Q9 }, R: h
  779. /*      byte1:                2nd byte to be programmed                                                        */, y: z# b0 v0 w$ K
  780. /*                                                                                                                                                */5 v6 r# N2 l2 [6 M, R8 v
  781. /* Returns:                                                                                                                                */
    ( g* b0 `4 G7 O+ ~! n: f# ?+ e
  782. /*                Nothing                                                                                                                        */
    * n) V( V' v- c6 _
  783. /*                                                                                                                                                */
    % H& G2 {% n8 m+ D9 @6 L+ X& R" v
  784. /************************************************************************/: F6 {, g9 G8 _) K( U1 f
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
      b. T4 X" g: R* S" v3 y* _
  786. {
    ; z6 J  a# d7 f& X# W# x
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        0 d/ L3 P: b  e
  788. 0 Q% I+ |* u* S! I  Z
  789.         CE_Low();                                        /* enable device */
    6 p* p; `# |" A  w, n
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ' q% A4 @( C& ]4 j
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & D1 I, {# f  D3 ?: z  }
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));! L. r/ ]3 V! n3 r( Q( s
  793.         Send_Byte(Dst & 0xFF);
    # I  E% q9 M+ t
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        2 X( {* W8 ~7 V$ j  I% p- y1 `
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , \5 e  G1 `; `
  796.         CE_High();                                        /* disable device */- [! v/ y) d5 x( l+ y% v& X" {
  797.         2 _7 V5 v8 V8 Z# ?& B. V
  798.         Poll_SO();                                        /* polls RY/BY# using SO line *// n  f7 x9 R: A6 u
  799. 0 k$ H2 M4 d  f; K% [
  800. }! D7 o( w" [5 w9 E5 t
  801. ; f# H* Y; V# }. j4 [' o
  802. /************************************************************************/
    $ L7 O: y; q% o/ s0 O! ^- p
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    ; ?  V) |& i+ ^+ {- Q- P# C
  804. /*                                                                                                                                                */
    ' S3 A1 o2 t  L* o
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    , e# ?) {) g9 j$ k3 l
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */" q7 u. \2 U& b; S2 Z$ F0 P- y
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    " P# v4 A) b+ Y" n, g; s
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    : ?" v3 b8 g# ~/ V  c8 G' V
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        *// q( D0 E) x% R& X
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    + p( V+ d$ v3 I+ v4 {+ G- L; _
  811. /* used after Auto_Address_IncA.                                                                                */
    2 w' _* u% r2 T1 x/ e$ Z
  812. /* Assumption:  Address being programmed is already erased and is NOT        */; @/ e8 n& J2 B  r* R. G( o
  813. /*                                block protected.                                                                                */2 G3 x1 |; G( Q  f2 i* p+ x
  814. /*                                                                                                                                                */
    . }5 g8 B9 w% n( x6 X6 W, p
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */" _" a' d0 l& s; @
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */! L4 {3 x% m1 k& ?/ R  F/ z( E
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    - s( t3 |3 F/ ]" T# r) e
  818. /*          to exit AAI mode unless AAI is programming the last address or                */$ x+ [/ Y. A; C  `& e0 K. Y, f& s+ o
  819. /*         last address of unprotected block, which automatically exits                 */: K3 W* j) n) I  H6 M5 M6 v1 I
  820. /*         AAI mode.                                                                                                                        */
    7 N: |6 y% S2 Q8 X- @+ `" I
  821. /*                                                                                                                                                */5 m6 S# @' C/ I* _6 j% [  c
  822. /* Input:                                                                                                                                */
    , K4 U, Z$ Z( o) h
  823. /*                                                                                                                                                */
    - F: E- w: @8 S! r$ X
  824. /*                byte1:                1st byte to be programmed                                                        */
    " Z  j1 a) U& h. t6 D0 k
  825. /*                byte2:                2nd byte to be programmed                                                        */
    + o0 \- O2 [" S8 d
  826. /*                                                                                                                                      */# k7 t; ~4 d+ i  W, T7 G+ K1 Z7 x0 b
  827. /*                                                                                                                                                */$ R2 I8 o! \1 a& `7 k
  828. /* Returns:                                                                                                                                */4 _; A9 k# V3 d' q
  829. /*                Nothing                                                                                                                        */
    8 H- M- M' n* R8 R1 f( _9 ~
  830. /*                                                                                                                                                */7 @9 A2 B9 t8 _7 n
  831. /************************************************************************/4 X& W' @0 S# s& ~' ~. I
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    & _$ i$ b: z/ @) j6 \* b
  833. {
    2 c- d+ M6 S. b4 U+ ^3 U) o8 V
  834.         CE_Low();                                /* enable device */
    # _3 V0 f1 Y8 s, v1 }
  835.         Send_Byte(0xAD);                /* send AAI command */
    - R" D! p' h0 e8 }& j: B' c* r
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    7 ^$ o& x( w5 t& n/ H* j
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    . b) {3 Q! h8 w  r! m3 {
  838.         CE_High();                                /* disable device */
    : c0 c' ]% T0 h* o

  839. 1 t0 _7 ]4 p+ A& U
  840.         Poll_SO();                                /* polls RY/BY# using SO line */0 d6 S4 V* b* T. O. z3 v

  841.   e: S' `* |/ k! h5 Z) {
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
      [- `1 K# |/ e, S0 Z* G
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    ' E, a+ `- |/ Q8 H
  844. }
    8 e& x$ _6 ?' `* m6 e

  845. ; N- c! P5 b7 U# k; p$ i2 q( j
  846. /************************************************************************/
    6 [+ v( M0 ]6 H9 {+ r
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    : E# F9 ~4 F: r  J( S( z
  848. /*                                                                                                                                                */
    4 y; U$ G% M4 v1 [! V5 S' }
  849. /* This procedure erases the entire Chip.                                                                */
    ) E8 \# f7 q8 m( h
  850. /*                                                                                                                                                */$ ^/ C, E5 H4 U/ T7 G
  851. /* Input:                                                                                                                                */
    0 {- k: ~  a: Z% m8 N/ \
  852. /*                None                                                                                                                        */
    # ]! @- k- d- ^/ o1 _0 A3 c
  853. /*                                                                                                                                                */
    , M2 T6 ]7 O/ z; b. F" I
  854. /* Returns:                                                                                                                                */: K1 D' X+ ?6 }( ~
  855. /*                Nothing                                                                                                                        */- y( {+ D# E; o! V# N8 Z, s' c1 \  c) T0 T
  856. /************************************************************************/8 b  D  n9 r1 Y! H( S5 q
  857. void Chip_Erase(): D! T, V0 N$ h% F. D( P9 Y) F7 [) d
  858. {                                                - X/ p$ r  X: @: @, X$ I7 g
  859.         CE_Low();                                /* enable device */
    , P9 n! i+ p# R
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    + N7 p  q2 e/ w. g% v
  861.         CE_High();                                /* disable device */
    ; K* [0 ]3 u, d. ~3 `
  862. }
    $ A5 m, {/ C8 f7 X  F, }: ]

  863. % Z. l$ ], q4 i: |0 `+ d
  864. /************************************************************************/  ^7 [* n  j1 S; h" _6 s
  865. /* PROCEDURE: Sector_Erase                                                                                                */: [7 x" R+ l! m2 T, L  H
  866. /*                                                                                                                                                */
    " q) i( ?0 A; j
  867. /* This procedure Sector Erases the Chip.                                                                */+ `' `$ I! p" ]. O- C) ]- @
  868. /*                                                                                                                                                */
    8 Y5 E5 A2 T0 t% p3 d/ [: ]4 f
  869. /* Input:                                                                                                                                */3 |& v# J$ r. [
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& R* V* d* |+ ?3 z2 h( e
  871. /*                                                                                                                                                */
      k0 s% A3 u# m0 b
  872. /* Returns:                                                                                                                                */5 N) h% _' U2 w* H9 c
  873. /*                Nothing                                                                                                                        */
    . T, z" r9 c% t5 L( E6 W
  874. /************************************************************************/
    . L6 ^3 r% N) K% z/ O
  875. void Sector_Erase(unsigned long Dst)
    1 H/ [4 V# V; w, P0 F" M
  876. {
    9 w* H: o' R7 `& k, k4 D8 P
  877. ! L# G1 o) @0 h: T7 ^9 O) P
  878. , N2 Q. M+ O( R+ M7 D; w
  879.         CE_Low();                                        /* enable device */
    - Z9 |& y) T" m4 F
  880.         Send_Byte(0x20);                        /* send Sector Erase command */& V) i( v- n/ {' r# j: T6 x
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + m9 e+ Q: O$ `
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));  K( q& g$ p! c" P
  883.         Send_Byte(Dst & 0xFF);7 `7 q6 x4 n' S0 b+ @* r
  884.         CE_High();                                        /* disable device */& _0 V9 H0 I; ^/ }+ p
  885. }       
    ( [2 @; w2 }" E$ D8 G/ H. h

  886. ' \5 F: [& z9 B9 i( Y
  887. /************************************************************************/1 C1 P$ T/ J  ]! ]6 T1 Y% N+ x. I
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ; |& Y9 [0 z' p* X' t3 t
  889. /*                                                                                                                                                */+ b* K8 F' o0 ]) {6 t' d# `
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    6 e+ i- [/ o4 V" `% E2 k- h4 ?
  891. /*                                                                                                                                                */
    % D9 a8 B% n# H5 z2 C  i
  892. /* Input:                                                                                                                                */* Y8 t- U+ ^: Z- \
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# L6 C+ y% b5 A1 \
  894. /*                                                                                                                                                */
    8 f6 L: y" J& T7 c5 `5 g. z
  895. /* Returns:                                                                                                                                */2 A" ]) K& k' A2 [
  896. /*                Nothing                                                                                                                        */
    9 {6 L$ V" z$ [' M) K
  897. /************************************************************************/2 y3 J1 E( h5 r/ Y
  898. void Block_Erase_32K(unsigned long Dst)+ P3 l/ w. O2 k+ b3 g3 ]
  899. {, [$ X/ f2 b- J: B
  900.         CE_Low();                                        /* enable device */
    - A# T3 {/ G6 W) r5 o4 |! v( F+ f8 x. D
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */# O$ i3 ?3 x- v$ d
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */: }- i% q/ @# Q
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % h) K; @* M+ G& a6 i( [
  904.         Send_Byte(Dst & 0xFF);
    ( ]8 A& k+ H9 a2 j  k' p% Z
  905.         CE_High();                                        /* disable device */6 z4 t) ]2 G1 d. H) S% A; D
  906. }
    8 }' j2 i- J: |, n3 y6 ^, x  [

  907. ) N- ~: b# X5 ^( p( O
  908. /************************************************************************/
    9 ?& t5 ~9 C+ X( |
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    , v6 L- c0 J& Y' R8 x' m) F) _
  910. /*                                                                                                                                                */
    " \' s- C# p+ v3 R9 B. t& c
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    5 r4 E/ q0 @7 V3 E  ?; }
  912. /*                                                                                                                                                */* n0 C, N1 y8 [, b& a
  913. /* Input:                                                                                                                                */1 v1 Z; L7 l# d/ ?5 D
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 _: q2 ?+ j- P/ @
  915. /*                                                                                                                                                */" p% _0 z. A5 [) u
  916. /* Returns:                                                                                                                                */
    7 ^' `7 t0 E, i. @" B
  917. /*                Nothing                                                                                                                        */! ~, q" }3 N! j$ y  W6 I, A" [7 j
  918. /************************************************************************/
    , k5 ?4 W, p$ M: j1 |- Q
  919. void Block_Erase_64K(unsigned long Dst)
    + k, ]+ |/ w1 [" G' _5 r7 `
  920. {+ l% `0 \# m1 T8 k2 L8 R; z
  921.         CE_Low();                                        /* enable device */
    ; T0 c" p$ u; ]* N
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */( V- C9 G. A# O
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 g8 Z* {- D3 l, w/ \5 r
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 M, ~' X2 t  _7 b( O* @" A! h8 d
  925.         Send_Byte(Dst & 0xFF);
    ; y3 i1 R, {# n( r' }# m) e3 W+ m
  926.         CE_High();                                        /* disable device */! J) R  c: c4 N5 A: {! y" k6 v& `
  927. }: s* ^9 {" u$ S& ?: e1 d0 C/ D4 p0 @
  928. 1 x% |* W/ X: N" C+ @& d& G3 a$ A
  929. /************************************************************************/
    % H3 x* D  y+ q
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    % z: ]! f( [' c" I' ^0 R. f
  931. /*                                                                                                                                                */
      f$ ~! v6 @7 ^- Q. `! ]
  932. /* This procedure waits until device is no longer busy (can be used by        */
    " i( J! P3 p- E
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */7 J6 J, g" H: y# w
  934. /*                                                                                                                                                */
    - x! Z1 S3 y0 |6 r, u5 g# _: F# E
  935. /* Input:                                                                                                                                */7 E# C0 z5 F5 I& n4 @% I  Q
  936. /*                None                                                                                                                        */
    0 E4 B, F' k6 G' x/ O& ]$ C
  937. /*                                                                                                                                                */, X' o9 e! k2 o; w, t
  938. /* Returns:                                                                                                                                */9 Z+ L3 Z, Q1 _, l
  939. /*                Nothing                                                                                                                        */* A8 X3 ]; G6 T
  940. /************************************************************************/
    ! D" y) g6 s, p0 E0 `) b
  941. void Wait_Busy()
    7 y3 ^3 T4 v- p
  942. {, }' H, W/ h# ^" g
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    % G& O  X7 I7 }
  944.                 Read_Status_Register();
    0 ?( M, f" E- Y; W$ `, O5 v" P$ Z
  945. }' N* P2 Q8 @* p- k: y! K
  946. " m4 _5 m0 K5 `$ h. U# Z
  947. /************************************************************************/5 b( b5 Z) O# x$ }- S$ |
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    / k: \9 C& \' ?7 n! R
  949. /*                                                                                                                                                */8 H+ s% Y4 v5 D+ i/ ^
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    $ M3 B+ L- y' ?1 X# M) \9 n
  951. /*                                                                                                                                                */  b( W- m( ^0 c3 k5 F& l
  952. /* Input:                                                                                                                                */! l) d6 Q  i5 o0 o6 |( K
  953. /*                None                                                                                                                        */
    * S- K& Q  C' K% Q9 u, c9 l2 @5 s
  954. /*                                                                                                                                                */
    / I* C! B8 e2 [, a9 D0 N
  955. /* Returns:                                                                                                                                */+ H  I9 [* K* k9 L( @( r" U! O
  956. /*                Nothing                                                                                                                        */
    8 Y2 H% c6 v5 ?* |/ ~$ v9 h3 e
  957. /************************************************************************/
    3 j  V5 r" G9 u8 q# n
  958. void Wait_Busy_AAI()
    ' J) C! g7 \; J
  959. {9 T- M! z. ?/ d; X
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    . N% J$ z1 x$ w4 a* C" r) u
  961.                 Read_Status_Register();
    * H9 u( b6 s& y1 Y% x5 {
  962. }. c0 J1 m2 {& U  m! O9 l7 B9 y

  963. + m% X$ n$ r4 \0 O8 `  a; B9 E
  964. /************************************************************************/
    * Q5 C2 f1 o) E$ [' A4 v' t3 ~7 V
  965. /* PROCEDURE: WREN_Check                                                                                                */
    + J) B; |9 D! {
  966. /*                                                                                                                                                */
    ) ]4 O4 I2 W. V1 V; ~
  967. /* This procedure checks to see if WEL bit set before program/erase.        */& R3 `. E+ F( u( c" R+ r6 T
  968. /*                                                                                                                                                */8 O+ P) C  {/ v, h
  969. /* Input:                                                                                                                                */: W% y7 R8 r8 `4 z, ~& S' [7 J2 X
  970. /*                None                                                                                                                        */
    4 c# H- e8 A. G- L1 x6 X9 B
  971. /*                                                                                                                                                */
    8 B1 R. J2 b+ p; U
  972. /* Returns:                                                                                                                                */3 K) X, d5 Q$ }+ B
  973. /*                Nothing                                                                                                                        */
    # k+ l$ M( t9 b& a  _
  974. /************************************************************************/
    ! E, A8 |$ D, r1 l' q
  975. void WREN_Check()
    2 c' U/ T. P+ O+ _
  976. {
    , {/ s( g% W0 q/ o; S
  977.         unsigned char byte;
    1 F# {, s4 |* v6 r
  978.         byte = Read_Status_Register();        /* read the status register */0 a/ f% U2 I. J6 L
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    * {- `( |( v- j# L* N$ Z
  980.         {7 J5 R3 }5 U1 p
  981.                 while(1)
    9 z4 e9 k: I* I7 W) d5 b) s2 k& F: {
  982.                         /* add source code or statements for this file */
    " Z4 Z) V8 i+ P& w% e2 E
  983.                         /* to compile                                  */
    0 ~/ q' a% v4 F$ F" X
  984.                         /* i.e. option: insert a display to view error on LED? */# h( h  L# a4 {; l+ n' i
  985.                  * Y" J* j: [5 B- U+ X' A: O" l
  986.         }7 \6 R( w. f# h4 P8 Y9 D, h
  987. }! `' Y+ a' a1 s+ c9 \& s# ~

  988. # V: W/ c* a# z9 D' z- B/ w
  989. /************************************************************************/. h+ S9 B' u! b0 u, C* W: R8 g
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    + H' d9 B5 c+ V4 [7 A. Q* {
  991. /*                                                                                                                                                */. x$ r* O7 U  ~$ @- g( N
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */; j$ B4 |$ |0 F& X# v$ ], y
  993. /*                                                                                                                                                */, K' j1 {) f# o# Y5 i3 A
  994. /* Input:                                                                                                                                */8 M" d  S1 }4 k( n5 T
  995. /*                None                                                                                                                        */
    - C6 W. A6 L' ?9 q/ v6 ~' I
  996. /*                                                                                                                                                */2 P0 l8 j- c" ~- _6 U% j0 H
  997. /* Returns:                                                                                                                                */
    2 o) `7 G( L5 I3 l8 z
  998. /*                Nothing                                                                                                                        */
    * \# o3 X3 c+ _( V5 [; a6 w
  999. /************************************************************************/: S: l$ l0 P( p' ^: D  ~# u& D
  1000. void WREN_AAI_Check()
    # N, m' Z  `2 z  w& k+ O7 g
  1001. {+ k7 F6 V) `8 V# y$ P0 W
  1002.         unsigned char byte;7 S$ G" M1 h! D+ k
  1003.         byte = Read_Status_Register();        /* read the status register */. [, o1 W+ }9 Z, M$ ^
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    1 k  N4 y! [' Q6 y$ a
  1005.         {% J2 P% x& ^+ \4 [+ f3 l6 C* v
  1006.                 while(1)                $ I$ y- |, a! W+ `( c
  1007.                         /* add source code or statements for this file */
    2 ^5 j' F3 U9 Z! ]" T
  1008.                         /* to compile                                  */
    + X1 e) {9 T2 V' ~/ c" J" @
  1009.                         /* i.e. option: insert a display to view error on LED? */
    . S8 k8 T. f  {: l4 J: I. `
  1010. 9 I4 v: \6 z2 D! {/ R- A# Q
  1011.         }8 q8 e! u0 ]# {2 q: G. s6 ^
  1012. }3 C5 D( Z8 Q2 o$ g4 L* j
  1013.   K# [. Y" J. ~7 Q
  1014. /************************************************************************/
    0 X4 ?8 A) _8 G( P
  1015. /* PROCEDURE: Verify                                                                                                        */
    ' s1 V! j- L9 U* m8 ~
  1016. /*                                                                                                                                                */
    ) t2 T/ e& K. b/ O8 \
  1017. /* This procedure checks to see if the correct byte has be read.                */
    . c' c5 v1 r5 @' j% N# r) C
  1018. /*                                                                                                                                                */( V2 b8 B- x7 H. p+ _
  1019. /* Input:                                                                                                                                */
      g7 ?+ c) n6 m: B( D+ S
  1020. /*                byte:                byte read                                                                                        */, Q  u: R% ]( Q8 J( \
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    2 p* r  @: `" ?, m# ]9 }: M
  1022. /*                                                                                                                                                */7 {" H4 ?# D& n: u  b
  1023. /* Returns:                                                                                                                                */
    $ Z& l; [+ W# Z7 L
  1024. /*                Nothing                                                                                                                        */  x, B7 E  a  `- K2 Z
  1025. /************************************************************************/
    1 y# R/ k, i+ k+ w% Q
  1026. void Verify(unsigned char byte, unsigned char cor_byte)7 J" j, R# c' B
  1027. {+ m" i. {$ B1 y
  1028.         if (byte != cor_byte)
    ( Y+ b& s7 z9 t' a  P+ d
  1029.         {" E0 A0 ~9 N6 W
  1030.                 while(1)
    , n1 E; d. F! g* q8 @! v6 b9 h
  1031.                         /* add source code or statement for this file */
    . k4 ]) D% `$ [; b$ x* t
  1032.                         /* to compile                                  */
    2 j+ C# {9 {, `; W' {8 y0 d
  1033.                         /* i.e. option: insert a display to view error on LED? */
    9 j6 ~/ N9 |% m5 w( `
  1034.                
    " q0 [1 D- p; Q8 T. A% ~4 R- h7 R
  1035.         }
    . _* l7 |" r) p
  1036. }) |. @( u, ]+ T$ Z' k3 R( E

  1037. 7 z0 N; Q2 Y4 W$ P4 F3 I
  1038. " {% {) m' k0 ?" O  E% I7 Y- A
  1039. int main()2 u% N/ o% o! E
  1040. {
    * j( @" t$ k5 b0 o

  1041. . n1 q) [5 {# \3 Q1 s& x% b0 E
  1042. return 0;
    ! x8 R, \& v5 l" C- h; X7 F
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:2 O- V3 i' Z# o+ j0 T
   main()/ c7 I* @% @& G2 x
   里面怎么是空的呢?  F4 O& u6 y) H- M: J
   发一份给我吧# i+ D! f  t3 [+ G# Z5 p
mail:luyijun2005@hotmail.com# p/ k6 y/ n; m" G& r8 |
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。* z+ _) q# n* B5 E+ S

3 l* K' u5 l* C) n[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。8 y# q. w/ F. u) }( z
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
& i- u2 h# m% C/ S% ]1 ?: eOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
' E/ O: S0 l7 P9 W上面几个问题是你没看任何东西而白问。
8 i$ O( G% ^0 b$ E" c
7 N; \. f: W* E至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
' V* ^5 ]9 H4 r/ A7 m' u$ q
7 f' Y% g4 I$ |0 K# U9 x关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
" Q& j; ~& L/ F" ?3 W4 F: G& T( K3 M# Z/ t4 O8 G# S6 t
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
2 _/ b" h7 o+ k4 n, m* V7 J( M( v" ~  @6 z. J  x8 L6 C9 z
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...7 r* D6 j( y2 L
' p4 Q8 r) o- a( k- f: @6 U9 _& s! h
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
8 p. P5 S. J; @7 _' ]似乎要把SPI能support 到最大,这EC chip应该有好卖点' R9 d# k9 z# ~( T& K# W0 Z
BIOS功能要不要强大,也就决定了SPI Flach的大小+ x: _2 `3 y4 `" i7 u
我是这么想的~让OEM去决定要挂多大!& I" n# ~+ R  g$ A* r/ R; `
如果我司有BIOS工程师就好了~哈  r! j% X8 Z& j, ^, [- V" h9 z
WPCE775应该算很新的东西,来看它支持到多大?
) y3 a* p+ E, ], h6 P- R
4 }4 U" A% T( u: s, O' ?, ?, i- D另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte  t' ?2 [$ |( A; u8 l0 {
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
* b1 B5 E5 `6 {, s
2 y6 L- j( T8 p! L7 d; i' P. P( N这份driver收下~希望以后有用到
( n& `8 O) j; n0 p  F: m- B谢谢bini大大3 `, w3 m9 q* i/ K& R
1 t% s/ @: k; p: L
很新很新的新手,如有错误请指正 (准备看第二家的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()  j3 ?  L* A" y1 y% Z# q  @" _4 a
{
1 `' E7 D$ Q: P$ b; ~/ W        unsigned char temp = 0;# l) U- z' G  K4 n$ _  y
        CE_Low();
0 z3 w5 U. ~3 n! B0 R( t    while (temp == 0x00)        /* waste time until not busy */
4 G6 W; I2 |$ G3 t' K                temp = SO;' J5 Z5 H5 H8 K( Z8 D6 U
        CE_High();
1 J6 Z) m6 [/ [6 _1 z! h2 b$ O}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)$ L% C+ O" Q3 ?/ b. j
{* i8 V" j2 n; ?; B# f
        : i& O0 d' a2 [% a+ I: P
        unsigned char i = 0;0 I5 ?; B* \9 z) K0 e
        for (i = 0; i < 8; i++)
/ E. e4 B& J5 ~5 f+ ^' F        {
. n* [; q6 ~  j3 p' z/ B               
7 Z1 S3 c& s5 z3 A3 u9 c                if ((out & 0x80) == 0x80)        /* check if MSB is high */
; m7 t* `  z& T% S4 G3 p8 u4 N                        SI = 1;% W! e! }: p) v5 n: n
                else/ j3 G7 ~8 n! ^1 w8 B9 s
                        SI = 0;                                /* if not, set to low */
$ j$ P1 B. _6 d3 O/ d- F 问              SCK = 1;                                /* toggle clock high */+ b+ z; U3 p7 X
   题            out = (out << 1);                /* shift 1 place for next bit */
. B3 l: B% B' p+ v3 a5 n                SCK = 0;                                /* toggle clock low */
* P* s+ U3 R+ _8 I2 O. p        }" f; f: L, g$ Z/ w  N
}+ O3 l! @/ ?! N. c0 T
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-25 14:09 , Processed in 0.119111 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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